From b7506d3016983630eed1741d68fd8919d0d234ec Mon Sep 17 00:00:00 2001 From: Ananth Suryanarayana Date: Fri, 11 Nov 2016 14:17:53 -0800 Subject: [PATCH] Add routes check to BGPaaS test Send routes from agent and verify that agent receive BGPaaS route only when the BGPaaS routes' nexthop is resolvable but not otherwise. Add the tests for IPv4 and IPv6 routes and also cover ecmp cases Partial-Bug: #1518047 Change-Id: I888bd401f854974ff1db804b9aab829f5b57bdc0 --- src/bgp/test/bgp_bgpaas_test.cc | 570 ++++++++++++++++++++++++++++++-- 1 file changed, 539 insertions(+), 31 deletions(-) diff --git a/src/bgp/test/bgp_bgpaas_test.cc b/src/bgp/test/bgp_bgpaas_test.cc index 306d7f09527..77d40e2eaa9 100644 --- a/src/bgp/test/bgp_bgpaas_test.cc +++ b/src/bgp/test/bgp_bgpaas_test.cc @@ -6,13 +6,17 @@ #include #include "base/task_annotations.h" +#include "control-node/test/network_agent_mock.h" #include "bgp/bgp_config_parser.h" #include "bgp/bgp_factory.h" #include "bgp/bgp_membership.h" #include "bgp/bgp_sandesh.h" #include "bgp/bgp_session_manager.h" +#include "bgp/bgp_xmpp_channel.h" #include "bgp/inet/inet_table.h" +#include "bgp/inet6/inet6_table.h" #include "bgp/test/bgp_server_test_util.h" +#include "bgp/xmpp_message_builder.h" #include "control-node/control_node.h" #include "io/test/event_manager_test.h" @@ -111,6 +115,8 @@ static string serverConfigStr = " 65001 \n" "
127.0.0.1
\n" " 11024 \n" +" 100.0.0.1\n" +" ::ffff:100.0.0.2\n" " \n" " \n" " inet \n" @@ -125,6 +131,8 @@ static string serverConfigStr = " 65002 \n" "
127.0.0.1
\n" " 11025 \n" +" 200.0.0.1\n" +" beef:beef::1\n" " \n" " \n" " inet \n" @@ -146,11 +154,10 @@ class BGPaaSTest : public ::testing::Test { } virtual void SetUp() { - evm_.reset(new EventManager()); - server_.reset(new BgpServerTest(evm_.get(), "local")); - vm1_.reset(new BgpServerTest(evm_.get(), "vm1")); - vm2_.reset(new BgpServerTest(evm_.get(), "vm2")); - thread_.reset(new ServerThread(evm_.get())); + server_.reset(new BgpServerTest(&evm_, "local")); + vm1_.reset(new BgpServerTest(&evm_, "vm1")); + vm2_.reset(new BgpServerTest(&evm_, "vm2")); + thread_.reset(new ServerThread(&evm_)); server_session_manager_ = server_->session_manager(); server_session_manager_->Initialize(0); @@ -166,23 +173,70 @@ class BGPaaSTest : public ::testing::Test { vm2_session_manager_->Initialize(0); BGP_DEBUG_UT("Created server at port: " << vm2_session_manager_->GetPort()); + xmpp_server_ = new XmppServerTest(&evm_, "bgp.contrail.com"); + channel_manager_.reset(new BgpXmppChannelManager(xmpp_server_, + server_.get())); + xmpp_server_->Initialize(0, false); thread_->Start(); - BgpPeerTest::verbose_name(true); } virtual void TearDown() { + agent_->SessionDown(); + agent_->Delete(); task_util::WaitForIdle(); server_->Shutdown(); + xmpp_server_->Shutdown(); vm1_->Shutdown(); task_util::WaitForIdle(); vm2_->Shutdown(); task_util::WaitForIdle(); + XmppShutdown(); + TASK_UTIL_EXPECT_EQ(0, TcpServerManager::GetServerCount()); - evm_->Shutdown(); + + evm_.Shutdown(); if (thread_.get() != NULL) thread_->Join(); - BgpPeerTest::verbose_name(false); + } + + void SetUpAgent() { + agent_ = new test::NetworkAgentMock(&evm_, "agent", + xmpp_server_->GetPort()); + agent_->SessionUp(); + TASK_UTIL_EXPECT_TRUE(agent_->IsEstablished()); + agent_->SubscribeAll("test", 1); + } + + void SetUpBGPaaSPeers() { + server_->set_peer_lookup_disable(true); + vm1_->set_source_port(11024); + vm2_->set_source_port(11025); + boost::replace_all(serverConfigStr, "__server_port__", + boost::lexical_cast(server_session_manager_->GetPort())); + boost::replace_all(clientsConfigStr, "__server_port__", + boost::lexical_cast(server_session_manager_->GetPort())); + boost::replace_all(clientsConfigStr, "__vm1_port__", + boost::lexical_cast(vm1_session_manager_->GetPort())); + boost::replace_all(clientsConfigStr, "__vm2_port__", + boost::lexical_cast(vm2_session_manager_->GetPort())); + vm1_->Configure(clientsConfigStr); + vm2_->Configure(clientsConfigStr); + task_util::WaitForIdle(); + + server_->Configure(serverConfigStr); + WaitForPeerToComeUp(vm1_.get(), "vm1"); + WaitForPeerToComeUp(vm2_.get(), "vm2"); + } + + void XmppShutdown() { + xmpp_server_->Shutdown(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_EQ(0, xmpp_server_->ConnectionCount()); + channel_manager_.reset(); + task_util::WaitForIdle(); + TcpServerManager::DeleteServer(xmpp_server_); + xmpp_server_ = NULL; } BgpPeerTest *WaitForPeerToComeUp(BgpServerTest *server, @@ -197,37 +251,489 @@ class BGPaaSTest : public ::testing::Test { return peer; } - auto_ptr evm_; - auto_ptr thread_; - auto_ptr server_; - auto_ptr vm1_; - auto_ptr vm2_; + void AddBgpInetRoute(BgpServerTest *server, + std::string prefix_str, std::string nexthop_str) { + Ip4Prefix prefix(Ip4Prefix::FromString(prefix_str)); + + int plen; + Ip4Address nexthop_addr; + Ip4PrefixParse(nexthop_str + "/32", &nexthop_addr, &plen); + BgpAttrNextHop nexthop(nexthop_addr); + + BgpAttrSpec attr_spec; + attr_spec.push_back(&nexthop); + + DBRequest req; + req.oper = DBRequest::DB_ENTRY_ADD_CHANGE; + req.key.reset(new InetTable::RequestKey(prefix, NULL)); + BgpAttrPtr attr = server->attr_db()->Locate(attr_spec); + req.data.reset(new InetTable::RequestData(attr, 0, 0)); + + RoutingInstance *rtinstance = static_cast( + server->routing_instance_mgr()->GetRoutingInstance( + BgpConfigManager::kMasterInstance)); + BgpTable *table = rtinstance->GetTable(Address::INET); + table->Enqueue(&req); + task_util::WaitForIdle(); + } + + void DeleteBgpInetRoute(BgpServer *server, std::string prefix_str) { + Ip4Prefix prefix(Ip4Prefix::FromString(prefix_str)); + + DBRequest req; + req.oper = DBRequest::DB_ENTRY_DELETE; + req.key.reset(new InetTable::RequestKey(prefix, NULL)); + + RoutingInstance *rtinstance = static_cast( + server->routing_instance_mgr()->GetRoutingInstance( + BgpConfigManager::kMasterInstance)); + BgpTable *table = rtinstance->GetTable(Address::INET); + table->Enqueue(&req); + task_util::WaitForIdle(); + } + + void AddBgpInet6Route(BgpServerTest *server, std::string prefix_str, + std::string nexthop_str) { + Inet6Prefix prefix(Inet6Prefix::FromString(prefix_str)); + + int plen; + Ip6Address nexthop_addr; + Inet6PrefixParse(nexthop_str + "/128", &nexthop_addr, &plen); + BgpAttrNextHop nexthop(nexthop_addr); + + BgpAttrSpec attr_spec; + attr_spec.push_back(&nexthop); + + DBRequest req; + req.oper = DBRequest::DB_ENTRY_ADD_CHANGE; + req.key.reset(new Inet6Table::RequestKey(prefix, NULL)); + BgpAttrPtr attr = server->attr_db()->Locate(attr_spec); + req.data.reset(new Inet6Table::RequestData(attr, 0, 0)); + + RoutingInstance *rtinstance = static_cast( + server->routing_instance_mgr()->GetRoutingInstance( + BgpConfigManager::kMasterInstance)); + BgpTable *table = rtinstance->GetTable(Address::INET6); + table->Enqueue(&req); + task_util::WaitForIdle(); + } + + void DeleteBgpInet6Route(BgpServerTest *server, std::string prefix_str) { + Inet6Prefix prefix(Inet6Prefix::FromString(prefix_str)); + + DBRequest req; + req.oper = DBRequest::DB_ENTRY_DELETE; + req.key.reset(new Inet6Table::RequestKey(prefix, NULL)); + + RoutingInstance *rtinstance = static_cast( + server->routing_instance_mgr()->GetRoutingInstance( + BgpConfigManager::kMasterInstance)); + BgpTable *table = rtinstance->GetTable(Address::INET6); + table->Enqueue(&req); + task_util::WaitForIdle(); + } + + void VerifyInetRouteCount(BgpServer *server, size_t expected) { + RoutingInstance *rtinstance = static_cast( + server->routing_instance_mgr()->GetRoutingInstance( + BgpConfigManager::kMasterInstance)); + BgpTable *table = rtinstance->GetTable(Address::INET); + TASK_UTIL_EXPECT_EQ(expected, table->Size()); + } + + void VerifyInetRoutePresence(BgpServer *server, + const std::string &prefix_str, + const std::string &nexthop_str) { + RoutingInstance *rtinstance = static_cast( + server->routing_instance_mgr()->GetRoutingInstance( + BgpConfigManager::kMasterInstance)); + BgpTable *table = rtinstance->GetTable(Address::INET); + Ip4Prefix prefix(Ip4Prefix::FromString(prefix_str)); + const InetTable::RequestKey key(prefix, NULL); + TASK_UTIL_EXPECT_NE(static_cast(NULL), + table->Find(&key)); + const BgpRoute *rt = dynamic_cast(table->Find(&key)); + const BgpPath *path = rt->FindPath(BgpPath::BGP_XMPP); + const IpAddress nexthop = path->GetAttr()->nexthop(); + EXPECT_EQ(nexthop_str, nexthop.to_string()); + } + + void VerifyInetRouteAbsence(BgpServer *server, + const std::string &prefix_str) { + RoutingInstance *rtinstance = static_cast( + server->routing_instance_mgr()->GetRoutingInstance( + BgpConfigManager::kMasterInstance)); + BgpTable *table = rtinstance->GetTable(Address::INET); + Ip4Prefix prefix(Ip4Prefix::FromString(prefix_str)); + const InetTable::RequestKey key(prefix, NULL); + TASK_UTIL_EXPECT_EQ(static_cast(NULL), + table->Find(&key)); + } + + void VerifyInet6RouteCount(BgpServer *server, size_t expected) { + RoutingInstance *rtinstance = static_cast( + server->routing_instance_mgr()->GetRoutingInstance( + BgpConfigManager::kMasterInstance)); + BgpTable *table = rtinstance->GetTable(Address::INET6); + TASK_UTIL_EXPECT_EQ(expected, table->Size()); + } + + void VerifyInet6RoutePresence(BgpServer *server, + const std::string &prefix_str, + const std::string &nexthop_str) { + RoutingInstance *rtinstance = static_cast( + server->routing_instance_mgr()->GetRoutingInstance( + BgpConfigManager::kMasterInstance)); + BgpTable *table = rtinstance->GetTable(Address::INET6); + Inet6Prefix prefix(Inet6Prefix::FromString(prefix_str)); + const Inet6Table::RequestKey key(prefix, NULL); + TASK_UTIL_EXPECT_NE(static_cast(NULL), + table->Find(&key)); + const BgpRoute *rt = dynamic_cast(table->Find(&key)); + const BgpPath *path = rt->FindPath(BgpPath::BGP_XMPP); + const IpAddress nexthop = path->GetAttr()->nexthop(); + EXPECT_EQ(nexthop_str, nexthop.to_string()); + } + + void VerifyInet6RouteAbsence(BgpServer *server, + const std::string &prefix_str) { + RoutingInstance *rtinstance = static_cast( + server->routing_instance_mgr()->GetRoutingInstance( + BgpConfigManager::kMasterInstance)); + BgpTable *table = rtinstance->GetTable(Address::INET6); + Inet6Prefix prefix(Inet6Prefix::FromString(prefix_str)); + const Inet6Table::RequestKey key(prefix, NULL); + TASK_UTIL_EXPECT_EQ(static_cast(NULL), + table->Find(&key)); + } + + void VerifyInetRoutePresence(test::NetworkAgentMock *agent, + std::string prefix, std::string nexthop1, + std::string nexthop2 = "") { + TASK_UTIL_EXPECT_NE( + static_cast(NULL), + agent->RouteLookup("test", prefix)); + const test::NetworkAgentMock::RouteEntry *item = + agent->RouteLookup("test", prefix); + size_t nexthop_count = nexthop2.empty() ? 1 : 2; + EXPECT_EQ(nexthop_count, item->entry.next_hops.next_hop.size()); + EXPECT_EQ(nexthop1, item->entry.next_hops.next_hop[0].address); + if (!nexthop2.empty()) + EXPECT_EQ(nexthop2, item->entry.next_hops.next_hop[1].address); + } + + void VerifyInet6RoutePresence(test::NetworkAgentMock *agent, + std::string prefix, std::string nexthop1, + std::string nexthop2 = "") { + TASK_UTIL_EXPECT_NE( + static_cast(NULL), + agent->Inet6RouteLookup("test", prefix)); + const test::NetworkAgentMock::RouteEntry *item = + agent->Inet6RouteLookup("test", prefix); + size_t nexthop_count = nexthop2.empty() ? 1 : 2; + EXPECT_EQ(nexthop_count, item->entry.next_hops.next_hop.size()); + EXPECT_EQ(nexthop1, item->entry.next_hops.next_hop[0].address); + if (!nexthop2.empty()) + EXPECT_EQ(nexthop2, item->entry.next_hops.next_hop[1].address); + } + + void VerifyInetRouteAbsence(test::NetworkAgentMock *agent, + std::string prefix) { + TASK_UTIL_EXPECT_EQ( + static_cast(NULL), + agent->RouteLookup("test", prefix)); + } + + void VerifyInet6RouteAbsence(test::NetworkAgentMock *agent, + std::string prefix) { + TASK_UTIL_EXPECT_EQ( + static_cast(NULL), + agent->Inet6RouteLookup("test", prefix)); + } + + EventManager evm_; + boost::scoped_ptr thread_; + boost::scoped_ptr server_; + boost::scoped_ptr vm1_; + boost::scoped_ptr vm2_; BgpSessionManager *server_session_manager_; BgpSessionManager *vm1_session_manager_; BgpSessionManager *vm2_session_manager_; + XmppServerTest *xmpp_server_; + test::NetworkAgentMock *agent_; + boost::scoped_ptr channel_manager_; }; TEST_F(BGPaaSTest, Basic) { - server_->set_peer_lookup_disable(true); - vm1_->set_source_port(11024); - vm2_->set_source_port(11025); - boost::replace_all(serverConfigStr, "__server_port__", - boost::lexical_cast(server_session_manager_->GetPort())); - boost::replace_all(clientsConfigStr, "__server_port__", - boost::lexical_cast(server_session_manager_->GetPort())); - boost::replace_all(clientsConfigStr, "__vm1_port__", - boost::lexical_cast(vm1_session_manager_->GetPort())); - boost::replace_all(clientsConfigStr, "__vm2_port__", - boost::lexical_cast(vm2_session_manager_->GetPort())); - cout << serverConfigStr << endl << endl << endl << endl; - cout << clientsConfigStr << endl; - vm1_->Configure(clientsConfigStr); - vm2_->Configure(clientsConfigStr); + SetUpBGPaaSPeers(); + SetUpAgent(); + + // Add routes with shared nexthop and also a unique one to vm1. + AddBgpInetRoute(vm1_.get(), "20.20.20.1/32", "1.1.1.1"); + AddBgpInet6Route(vm1_.get(), "dead:1::beef/128", "::ffff:1.1.1.1"); + + AddBgpInetRoute(vm1_.get(), "20.20.20.2/32", "1.1.1.2"); + AddBgpInet6Route(vm1_.get(), "dead:2::beef/128", "::ffff:1.1.1.3"); task_util::WaitForIdle(); - server_->Configure(serverConfigStr); - WaitForPeerToComeUp(vm1_.get(), "vm1"); - WaitForPeerToComeUp(vm2_.get(), "vm2"); + // Verify that unresolved bgp route is not received by the agent. + TASK_UTIL_EXPECT_EQ(0, agent_->route_mgr_->Count()); + VerifyInetRouteAbsence(agent_, "1.1.1.1/32"); + VerifyInetRouteAbsence(agent_, "1.1.1.2/32"); + VerifyInetRouteAbsence(agent_, "1.1.1.3/32"); + VerifyInetRouteAbsence(agent_, "20.20.20.1/32"); + VerifyInetRouteAbsence(agent_, "20.20.20.2/32"); + + TASK_UTIL_EXPECT_EQ(0, agent_->inet6_route_mgr_->Count()); + VerifyInet6RouteAbsence(agent_, "dead:1::beef/128"); + VerifyInet6RouteAbsence(agent_, "dead:2::beef/128"); + + // Verify that unresolved bgp route is not received by the bgpass peer vm2 + VerifyInetRouteCount(vm2_.get(), 0); + VerifyInetRouteAbsence(vm2_.get(), "1.1.1.1/32"); + VerifyInetRouteAbsence(vm2_.get(), "1.1.1.2/32"); + VerifyInetRouteAbsence(vm2_.get(), "1.1.1.3/32"); + VerifyInetRouteAbsence(vm2_.get(), "20.20.20.1/32"); + VerifyInetRouteAbsence(vm2_.get(), "20.20.20.2/32"); + + VerifyInet6RouteCount(vm2_.get(), 0); + VerifyInet6RouteAbsence(vm2_.get(), "dead:1::beef/128"); + VerifyInet6RouteAbsence(vm2_.get(), "dead:2::beef/128"); + + // Verify that unresolved bgp route is not received by the bgpass peer vm2 + // But locally added routes vm1 must be still present in its tables. + VerifyInetRouteCount(vm1_.get(), 2); + VerifyInetRouteAbsence(vm1_.get(), "1.1.1.1/32"); + VerifyInetRouteAbsence(vm1_.get(), "1.1.1.2/32"); + VerifyInetRouteAbsence(vm1_.get(), "1.1.1.3/32"); + VerifyInetRoutePresence(vm1_.get(), "20.20.20.1/32", "1.1.1.1"); + VerifyInetRoutePresence(vm1_.get(), "20.20.20.2/32", "1.1.1.2"); + + VerifyInet6RouteCount(vm1_.get(), 2); + VerifyInet6RoutePresence(vm1_.get(), "dead:1::beef/128", "::ffff:1.1.1.1"); + VerifyInet6RoutePresence(vm1_.get(), "dead:2::beef/128", "::ffff:1.1.1.3"); + + // Add a route to make bgp route's nexthop resolvable. + agent_->AddRoute("test", "1.1.1.1/32", "10.10.10.1"); + + // Verify that now resolved inet bgp route is indeed received by the agent. + TASK_UTIL_EXPECT_EQ(2, agent_->route_mgr_->Count()); + VerifyInetRoutePresence(agent_, "1.1.1.1/32", "10.10.10.1"); + VerifyInetRoutePresence(agent_, "20.20.20.1/32", "10.10.10.1"); + VerifyInetRouteAbsence(agent_, "20.20.20.2/32"); + + // Verify that now resolved inet bgp route is indeed received by vm2 with + // correct gateway-address as specified in the configuration. + VerifyInetRouteCount(vm2_.get(), 2); + VerifyInetRoutePresence(vm2_.get(), "1.1.1.1/32", "200.0.0.1"); + VerifyInetRoutePresence(vm2_.get(), "20.20.20.1/32", "200.0.0.1"); + VerifyInetRouteAbsence(vm2_.get(), "20.20.20.2/32"); + + // Verify that now resolved inet bgp route is indeed received by vm1. + VerifyInetRouteCount(vm1_.get(), 3); + VerifyInetRoutePresence(vm1_.get(), "1.1.1.1/32", "100.0.0.1"); + VerifyInetRoutePresence(vm1_.get(), "20.20.20.1/32", "1.1.1.1"); + VerifyInetRoutePresence(vm1_.get(), "20.20.20.2/32", "1.1.1.2"); + + // Verify that now resolved inet6 bgp route is indeed received by agent. + TASK_UTIL_EXPECT_EQ(1, agent_->inet6_route_mgr_->Count()); + VerifyInet6RoutePresence(agent_, "dead:1::beef/128", "10.10.10.1"); + VerifyInet6RouteAbsence(agent_, "dead:2::beef/128"); + + // Verify that now resolved inet6 bgp route is indeed received by vm2. + VerifyInet6RouteCount(vm2_.get(), 1); + VerifyInet6RoutePresence(vm2_.get(), "dead:1::beef/128", "beef:beef::1"); + VerifyInet6RouteAbsence(vm2_.get(), "dead:2::beef/128"); + + VerifyInet6RouteCount(vm1_.get(), 2); + VerifyInet6RoutePresence(vm1_.get(), "dead:1::beef/128", "::ffff:1.1.1.1"); + VerifyInet6RoutePresence(vm1_.get(), "dead:2::beef/128", "::ffff:1.1.1.3"); + + // Make other vm1 routes also now resolvable. + agent_->AddRoute("test", "1.1.1.2/32", "10.10.10.2"); + agent_->AddRoute("test", "1.1.1.3/32", "10.10.10.3"); + + // Verify that now resolved inet bgp route is indeed received by the agent. + TASK_UTIL_EXPECT_EQ(5, agent_->route_mgr_->Count()); + VerifyInetRoutePresence(agent_, "1.1.1.1/32", "10.10.10.1"); + VerifyInetRoutePresence(agent_, "1.1.1.2/32", "10.10.10.2"); + VerifyInetRoutePresence(agent_, "1.1.1.3/32", "10.10.10.3"); + VerifyInetRoutePresence(agent_, "20.20.20.1/32", "10.10.10.1"); + VerifyInetRoutePresence(agent_, "20.20.20.2/32", "10.10.10.2"); + + // Verify that now resolved inet bgp route is indeed received by vm2 with + // correct gateway-address as specified in the configuration. + TASK_UTIL_EXPECT_EQ(5, agent_->route_mgr_->Count()); + VerifyInetRouteCount(vm2_.get(), 5); + VerifyInetRoutePresence(vm2_.get(), "1.1.1.1/32", "200.0.0.1"); + VerifyInetRoutePresence(vm2_.get(), "1.1.1.2/32", "200.0.0.1"); + VerifyInetRoutePresence(vm2_.get(), "1.1.1.3/32", "200.0.0.1"); + VerifyInetRoutePresence(vm2_.get(), "20.20.20.1/32", "200.0.0.1"); + VerifyInetRoutePresence(vm2_.get(), "20.20.20.2/32", "200.0.0.1"); + + // Verify that now resolved inet bgp route is indeed received by vm1. + VerifyInetRouteCount(vm1_.get(), 5); + VerifyInetRoutePresence(vm1_.get(), "1.1.1.1/32", "100.0.0.1"); + VerifyInetRoutePresence(vm1_.get(), "1.1.1.2/32", "100.0.0.1"); + VerifyInetRoutePresence(vm1_.get(), "1.1.1.3/32", "100.0.0.1"); + VerifyInetRoutePresence(vm1_.get(), "20.20.20.1/32", "1.1.1.1"); + VerifyInetRoutePresence(vm1_.get(), "20.20.20.2/32", "1.1.1.2"); + + // Verify that now resolved inet6 bgp route is indeed received by agent. + TASK_UTIL_EXPECT_EQ(2, agent_->inet6_route_mgr_->Count()); + VerifyInet6RoutePresence(agent_, "dead:1::beef/128", "10.10.10.1"); + VerifyInet6RoutePresence(agent_, "dead:2::beef/128", "10.10.10.3"); + + // Verify that now resolved inet6 bgp route is indeed received by vm2. + VerifyInet6RouteCount(vm2_.get(), 2); + VerifyInet6RoutePresence(vm2_.get(), "dead:1::beef/128", "beef:beef::1"); + VerifyInet6RoutePresence(vm2_.get(), "dead:2::beef/128", "beef:beef::1"); + + VerifyInet6RouteCount(vm1_.get(), 2); + VerifyInet6RoutePresence(vm1_.get(), "dead:1::beef/128", "::ffff:1.1.1.1"); + VerifyInet6RoutePresence(vm1_.get(), "dead:2::beef/128", "::ffff:1.1.1.3"); + + // Add an inet6 route to vm2 and verify that vm1 receives it with correct + // ipv4-in-ipv6 next-hop. + AddBgpInet6Route(vm2_.get(), "feed:1::feed/128", "::ffff:1.1.1.1"); + VerifyInet6RouteCount(vm2_.get(), 3); + VerifyInet6RoutePresence(vm2_.get(), "feed:1::feed/128", "::ffff:1.1.1.1"); + VerifyInet6RouteCount(vm1_.get(), 3); + VerifyInet6RoutePresence(vm1_.get(), "feed:1::feed/128", "100.0.0.2"); + + // Delete the route just added above and verify their absence. + DeleteBgpInet6Route(vm2_.get(), "feed:1::feed/128"); + VerifyInet6RouteCount(vm2_.get(), 2); + VerifyInet6RouteAbsence(vm2_.get(), "feed:1::feed/128"); + VerifyInet6RouteCount(vm1_.get(), 2); + VerifyInet6RouteAbsence(vm1_.get(), "feed:1::feed/128"); + + // Add same inet and inet6 prefix to both bgpaas and verify ecmp nexthop + // in the agent. + AddBgpInetRoute(vm1_.get(), "30.20.20.1/32", "3.1.1.1"); + AddBgpInet6Route(vm1_.get(), "feed:2::feed/128", "::ffff:3.1.1.1"); + AddBgpInetRoute(vm2_.get(), "30.20.20.1/32", "4.1.1.1"); + AddBgpInet6Route(vm2_.get(), "feed:2::feed/128", "::ffff:4.1.1.1"); + agent_->AddRoute("test", "3.1.1.1/32", "30.10.10.2"); + agent_->AddRoute("test", "4.1.1.1/32", "40.10.10.2"); + + // Verify new inet routes added above along with ecmp next-hop. + TASK_UTIL_EXPECT_EQ(8, agent_->route_mgr_->Count()); + VerifyInetRoutePresence(agent_, "3.1.1.1/32", "30.10.10.2"); + VerifyInetRoutePresence(agent_, "4.1.1.1/32", "40.10.10.2"); + VerifyInetRoutePresence(agent_, "30.20.20.1/32", + "30.10.10.2", "40.10.10.2"); + + // Verify new inet6 route added above along with ecmp next-hop. + TASK_UTIL_EXPECT_EQ(3, agent_->inet6_route_mgr_->Count()); + VerifyInet6RoutePresence(agent_, "feed:2::feed/128", + "30.10.10.2", "40.10.10.2"); + + // Delete the ecmp routes added above and verify for their absence. + DeleteBgpInetRoute(vm1_.get(), "30.20.20.1/32"); + DeleteBgpInet6Route(vm1_.get(), "feed:2::feed/128"); + DeleteBgpInetRoute(vm2_.get(), "30.20.20.1/32"); + DeleteBgpInet6Route(vm2_.get(), "feed:2::feed/128"); + agent_->DeleteRoute("test", "3.1.1.1/32"); + agent_->DeleteRoute("test", "4.1.1.1/32"); + TASK_UTIL_EXPECT_EQ(5, agent_->route_mgr_->Count()); + VerifyInetRouteAbsence(agent_, "3.1.1.1/32"); + VerifyInetRouteAbsence(agent_, "4.1.1.1/32"); + VerifyInetRouteAbsence(agent_, "30.20.20.1/32"); + + TASK_UTIL_EXPECT_EQ(2, agent_->inet6_route_mgr_->Count()); + VerifyInet6RouteAbsence(agent_, "feed:2::feed/128"); + + // Delete agent route to make bgp route's nexthop not resolvable any more. + agent_->DeleteRoute("test", "1.1.1.1/32"); + + // Verify that some routes are now deleted as nexthop is not resolvable. + TASK_UTIL_EXPECT_EQ(3, agent_->route_mgr_->Count()); + VerifyInetRoutePresence(agent_, "1.1.1.2/32", "10.10.10.2"); + VerifyInetRoutePresence(agent_, "1.1.1.3/32", "10.10.10.3"); + VerifyInetRoutePresence(agent_, "20.20.20.2/32", "10.10.10.2"); + VerifyInetRouteAbsence(agent_, "1.1.1.1/32"); + VerifyInetRouteAbsence(agent_, "20.20.20.1/32"); + + VerifyInetRouteCount(vm2_.get(), 3); + VerifyInetRoutePresence(vm2_.get(), "1.1.1.2/32", "200.0.0.1"); + VerifyInetRoutePresence(vm2_.get(), "1.1.1.3/32", "200.0.0.1"); + VerifyInetRoutePresence(vm2_.get(), "20.20.20.2/32", "200.0.0.1"); + VerifyInetRouteAbsence(vm2_.get(), "1.1.1.1/32"); + VerifyInetRouteAbsence(vm2_.get(), "20.20.20.1/32"); + + VerifyInetRouteCount(vm1_.get(), 4); + VerifyInetRoutePresence(vm1_.get(), "1.1.1.2/32", "100.0.0.1"); + VerifyInetRoutePresence(vm1_.get(), "1.1.1.3/32", "100.0.0.1"); + VerifyInetRoutePresence(vm1_.get(), "20.20.20.1/32", "1.1.1.1"); + VerifyInetRoutePresence(vm1_.get(), "20.20.20.2/32", "1.1.1.2"); + VerifyInetRouteAbsence(vm1_.get(), "1.1.1.1/32"); + + TASK_UTIL_EXPECT_EQ(1, agent_->inet6_route_mgr_->Count()); + VerifyInet6RoutePresence(agent_, "dead:2::beef/128", "10.10.10.3"); + VerifyInet6RouteAbsence(agent_, "dead:1::beef/128"); + + VerifyInet6RouteCount(vm2_.get(), 1); + VerifyInet6RoutePresence(vm2_.get(), "dead:2::beef/128", "beef:beef::1"); + VerifyInet6RouteAbsence(vm2_.get(), "dead:1::beef/128"); + + VerifyInet6RouteCount(vm1_.get(), 2); + VerifyInet6RoutePresence(vm1_.get(), "dead:1::beef/128", "::ffff:1.1.1.1"); + VerifyInet6RoutePresence(vm1_.get(), "dead:2::beef/128", "::ffff:1.1.1.3"); + + // Delete other routes as well to make all bgp routes not resolvable any + // more. Now agent should have no route at all. + agent_->DeleteRoute("test", "1.1.1.2/32"); + agent_->DeleteRoute("test", "1.1.1.3/32"); + TASK_UTIL_EXPECT_EQ(0, agent_->route_mgr_->Count()); + VerifyInetRouteAbsence(agent_, "1.1.1.1/32"); + VerifyInetRouteAbsence(agent_, "1.1.1.2/32"); + VerifyInetRouteAbsence(agent_, "1.1.1.3/32"); + VerifyInetRouteAbsence(agent_, "20.20.20.1/32"); + VerifyInetRouteAbsence(agent_, "20.20.20.2/32"); + + TASK_UTIL_EXPECT_EQ(0, agent_->inet6_route_mgr_->Count()); + VerifyInet6RouteAbsence(agent_, "dead:1::beef/128"); + VerifyInet6RouteAbsence(agent_, "dead:2::beef/128"); + + VerifyInetRouteCount(vm2_.get(), 0); + VerifyInetRouteAbsence(vm2_.get(), "1.1.1.1/32"); + VerifyInetRouteAbsence(vm2_.get(), "1.1.1.2/32"); + VerifyInetRouteAbsence(vm2_.get(), "1.1.1.3/32"); + VerifyInetRouteAbsence(vm2_.get(), "20.20.20.1/32"); + VerifyInetRouteAbsence(vm2_.get(), "20.20.20.2/32"); + + VerifyInet6RouteCount(vm2_.get(), 0); + VerifyInet6RouteAbsence(vm2_.get(), "dead:1::beef/128"); + VerifyInet6RouteAbsence(vm2_.get(), "dead:2::beef/128"); + + // vm1 should still have the routes added to its tables at the beginning. + VerifyInetRouteCount(vm1_.get(), 2); + VerifyInetRoutePresence(vm1_.get(), "20.20.20.1/32", "1.1.1.1"); + VerifyInetRoutePresence(vm1_.get(), "20.20.20.2/32", "1.1.1.2"); + VerifyInetRouteAbsence(vm1_.get(), "1.1.1.1/32"); + VerifyInetRouteAbsence(vm1_.get(), "1.1.1.2/32"); + VerifyInetRouteAbsence(vm1_.get(), "1.1.1.3/32"); + + VerifyInet6RouteCount(vm1_.get(), 2); + VerifyInet6RoutePresence(vm1_.get(), "dead:1::beef/128", "::ffff:1.1.1.1"); + VerifyInet6RoutePresence(vm1_.get(), "dead:2::beef/128", "::ffff:1.1.1.3"); + + // Delete all BGPaaS routes addded earlier. + DeleteBgpInetRoute(vm1_.get(), "20.20.20.1/32"); + DeleteBgpInetRoute(vm1_.get(), "20.20.20.2/32"); + DeleteBgpInet6Route(vm1_.get(), "dead:1::beef/128"); + DeleteBgpInet6Route(vm1_.get(), "dead:2::beef/128"); + + // Verify that agent still has no route. + TASK_UTIL_EXPECT_EQ(0, agent_->route_mgr_->Count()); + TASK_UTIL_EXPECT_EQ(0, agent_->inet6_route_mgr_->Count()); + + // Verify that BGPaaS servers also have no routes. + VerifyInetRouteCount(vm2_.get(), 0); + VerifyInet6RouteCount(vm2_.get(), 0); + VerifyInetRouteCount(vm1_.get(), 0); + VerifyInet6RouteCount(vm1_.get(), 0); } class TestEnvironment : public ::testing::Environment { @@ -237,6 +743,8 @@ class TestEnvironment : public ::testing::Environment { static void SetUp() { BgpServer::Initialize(); ControlNode::SetDefaultSchedulingPolicy(); + BgpObjectFactory::Register( + boost::factory()); BgpServerTest::GlobalSetUp(); }