Пример #1
0
std::unique_ptr<UnicastRoute>
makeUnicastRoute(std::string prefixStr, std::string nxtHop,
    AdminDistance distance=AdminDistance::MAX_ADMIN_DISTANCE) {
  std::vector<std::string> vec;
  folly::split("/", prefixStr, vec);
  EXPECT_EQ(2, vec.size());
  auto nr = std::make_unique<UnicastRoute>();
  nr->dest.ip = toBinaryAddress(IPAddress(vec.at(0)));
  nr->dest.prefixLength = folly::to<uint8_t>(vec.at(1));
  nr->nextHopAddrs.push_back(toBinaryAddress(IPAddress(nxtHop)));
  nr->adminDistance = distance;
  nr->__isset.adminDistance = true;
  return nr;
}
Пример #2
0
// Test for the ThriftHandler::syncFib method
TEST(ThriftTest, syncFib) {
  RouterID rid = RouterID(0);

  // Create a config
  cfg::SwitchConfig config;
  config.vlans.resize(1);
  config.vlans[0].id = 1;
  config.interfaces.resize(1);
  config.interfaces[0].intfID = 1;
  config.interfaces[0].vlanID = 1;
  config.interfaces[0].routerID = 0;
  config.interfaces[0].__isset.mac = true;
  config.interfaces[0].mac = "00:02:00:00:00:01";
  config.interfaces[0].ipAddresses.resize(3);
  config.interfaces[0].ipAddresses[0] = "10.0.0.1/24";
  config.interfaces[0].ipAddresses[1] = "192.168.0.19/24";
  config.interfaces[0].ipAddresses[2] = "2401:db00:2110:3001::0001/64";

  // Create a mock SwSwitch using the config, and wrap it in a ThriftHandler
  auto handle = createTestHandle(&config);
  auto sw = handle->getSw();
  sw->initialConfigApplied(std::chrono::steady_clock::now());
  sw->fibSynced();
  ThriftHandler handler(sw);

  //
  // Add a few BGP routes
  //

  auto cli1_nhop4 = "11.11.11.11";
  auto cli1_nhop6 = "11:11::0";
  auto cli2_nhop4 = "22.22.22.22";
  auto cli2_nhop6 = "22:22::0";
  auto cli3_nhop6 = "33:33::0";
  auto cli1_nhop6b = "44:44::0";

  // These routes will include nexthops from client 10 only
  auto prefixA4 = "7.1.0.0/16";
  auto prefixA6 = "aaaa:1::0/64";
  handler.addUnicastRoute(10, makeUnicastRoute(prefixA4, cli1_nhop4));
  handler.addUnicastRoute(10, makeUnicastRoute(prefixA6, cli1_nhop6));

  // This route will include nexthops from clients 10 and 20
  auto prefixB4 = "7.2.0.0/16";
  handler.addUnicastRoute(10, makeUnicastRoute(prefixB4, cli1_nhop4));
  handler.addUnicastRoute(20, makeUnicastRoute(prefixB4, cli2_nhop4));

  // This route will include nexthops from clients 10 and 20 and 30
  auto prefixC6 = "aaaa:3::0/64";
  handler.addUnicastRoute(10, makeUnicastRoute(prefixC6, cli1_nhop6));
  handler.addUnicastRoute(20, makeUnicastRoute(prefixC6, cli2_nhop6));
  handler.addUnicastRoute(30, makeUnicastRoute(prefixC6, cli3_nhop6));

  // These routes will not be used until fibSync happens.
  auto prefixD4 = "7.4.0.0/16";
  auto prefixD6 = "aaaa:4::0/64";

  //
  // Test the state of things before calling syncFib
  //

  // Make sure all the static and link-local routes are there
  auto tables2 = sw->getState()->getRouteTables();
  GET_ROUTE_V4(tables2, rid, "10.0.0.0/24");
  GET_ROUTE_V4(tables2, rid, "192.168.0.0/24");
  GET_ROUTE_V6(tables2, rid, "2401:db00:2110:3001::/64");
  GET_ROUTE_V6(tables2, rid, "fe80::/64");
  // Make sure the client 10&20&30 routes are there.
  GET_ROUTE_V4(tables2, rid, prefixA4);
  GET_ROUTE_V6(tables2, rid, prefixA6);
  GET_ROUTE_V4(tables2, rid, prefixB4);
  GET_ROUTE_V6(tables2, rid, prefixC6);
  // Make sure there are no more routes than the ones we just tested
  // plus the 1 default route that gets added automatically
  EXPECT_EQ(4 + 1, tables2->getRouteTable(rid)->getRibV4()->size());
  EXPECT_EQ(4 + 1, tables2->getRouteTable(rid)->getRibV6()->size());
  EXPECT_NO_ROUTE(tables2, rid, prefixD4);
  EXPECT_NO_ROUTE(tables2, rid, prefixD6);

  //
  // Now use syncFib to remove all the routes for client 10 and add
  // some new ones
  // Statics, link-locals, and clients 20 and 30 should remain unchanged.
  //

  auto newRoutes = std::make_unique<std::vector<UnicastRoute>>();
  UnicastRoute nr1 = *makeUnicastRoute(prefixC6, cli1_nhop6b).get();
  UnicastRoute nr2 = *makeUnicastRoute(prefixD6, cli1_nhop6b).get();
  UnicastRoute nr3 = *makeUnicastRoute(prefixD4, cli1_nhop4).get();
  newRoutes->push_back(nr1);
  newRoutes->push_back(nr2);
  newRoutes->push_back(nr3);
  handler.syncFib(10, std::move(newRoutes));

  //
  // Test the state of things after syncFib
  //

  // Make sure all the static and link-local routes are still there
  auto tables3 = sw->getState()->getRouteTables();
  GET_ROUTE_V4(tables3, rid, "10.0.0.0/24");
  GET_ROUTE_V4(tables3, rid, "192.168.0.0/24");
  GET_ROUTE_V6(tables3, rid, "2401:db00:2110:3001::/64");
  GET_ROUTE_V6(tables3, rid, "fe80::/64");

  // The prefixA* routes should have disappeared
  EXPECT_NO_ROUTE(tables3, rid, prefixA4);
  EXPECT_NO_ROUTE(tables3, rid, prefixA6);

  // The prefixB4 route should have client 20 only
  auto rt1 = GET_ROUTE_V4(tables3, rid, prefixB4);
  ASSERT_TRUE(rt1->getFields()
    ->nexthopsmulti.isSame(ClientID(20),
      RouteNextHopEntry(makeNextHops({cli2_nhop4}))));
  auto bestNextHops = rt1->getBestEntry().second->getNextHopSet();
  EXPECT_EQ(IPAddress(cli2_nhop4), bestNextHops.begin()->addr());

  // The prefixC6 route should have clients 20 & 30, and a new value for
  // client 10
  auto rt2 = GET_ROUTE_V6(tables3, rid, prefixC6);
  ASSERT_TRUE(rt2->getFields()
    ->nexthopsmulti.isSame(ClientID(20),
      RouteNextHopEntry(makeNextHops({cli2_nhop6}))));
  ASSERT_TRUE(rt2->getFields()
    ->nexthopsmulti.isSame(ClientID(30),
      RouteNextHopEntry(makeNextHops({cli3_nhop6}))));
  ASSERT_TRUE(rt2->getFields()
    ->nexthopsmulti.isSame(ClientID(10),
      RouteNextHopEntry(makeNextHops({cli1_nhop6b}))));

  // The prefixD4 and prefixD6 routes should have been created
  GET_ROUTE_V4(tables3, rid, prefixD4);
  GET_ROUTE_V6(tables3, rid, prefixD6);

  // Make sure there are no more routes (ie. the old ones were deleted)
  // + the one that gets added by default
  EXPECT_EQ(4 + 1, tables3->getRouteTable(rid)->getRibV4()->size());
  EXPECT_EQ(4 + 1, tables3->getRouteTable(rid)->getRibV6()->size());
}