diff --git a/src/bgp/bgp_server.h b/src/bgp/bgp_server.h index 373a39c0d8d..d61f4dcf485 100644 --- a/src/bgp/bgp_server.h +++ b/src/bgp/bgp_server.h @@ -75,7 +75,7 @@ class BgpServer { BgpPeer *FindPeer(const std::string &name); void InsertPeer(TcpSession::Endpoint remote, BgpPeer *peer); void RemovePeer(TcpSession::Endpoint remote, BgpPeer *peer); - BgpPeer *FindPeer(TcpSession::Endpoint remote) const; + virtual BgpPeer *FindPeer(TcpSession::Endpoint remote) const; BgpPeer *FindNextPeer( TcpSession::Endpoint remote = TcpSession::Endpoint()) const; diff --git a/src/bgp/test/SConscript b/src/bgp/test/SConscript index 98ce9906c2a..b9bc8206d21 100644 --- a/src/bgp/test/SConscript +++ b/src/bgp/test/SConscript @@ -146,6 +146,9 @@ bgp_authentication_test = env.UnitTest('bgp_authentication_test', ['bgp_authentication_test.cc']) env.Alias('src/bgp:bgp_authentication_test', bgp_authentication_test) +bgp_bgpaas_test = env.UnitTest('bgp_bgpaas_test', ['bgp_bgpaas_test.cc']) +env.Alias('src/bgp:bgp_bgpaas_test', bgp_bgpaas_test) + bgp_condition_listener_test = env.UnitTest('bgp_condition_listener_test', ['bgp_condition_listener_test.cc']) env.Alias('src/bgp:bgp_condition_listener_test', bgp_condition_listener_test) @@ -565,6 +568,7 @@ yaml_test_env.Alias('bgp:bgp_yaml_config_manager_test', test_suite = [ bgp_attr_test, bgp_authentication_test, + bgp_bgpaas_test, bgp_condition_listener_test, bgp_config_listener_test, bgp_ifmap_config_manager_test, diff --git a/src/bgp/test/bgp_bgpaas_test.cc b/src/bgp/test/bgp_bgpaas_test.cc new file mode 100644 index 00000000000..306d7f09527 --- /dev/null +++ b/src/bgp/test/bgp_bgpaas_test.cc @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved. + */ + +#include +#include + +#include "base/task_annotations.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/inet/inet_table.h" +#include "bgp/test/bgp_server_test_util.h" +#include "control-node/control_node.h" +#include "io/test/event_manager_test.h" + +using namespace std; + +static string clientsConfigStr = +" \n" +" \n" +" \n" +"
127.0.0.1
\n" +" 64512 \n" +" 192.168.1.1 \n" +" __server_port__ \n" +" \n" +" \n" +" inet \n" +" \n" +" \n" +" inet6 \n" +" \n" +" \n" +" \n" +" \n" +" inet \n" +" \n" +" \n" +" inet6 \n" +" \n" +" \n" +"
\n" +" \n" +"
127.0.0.1
\n" +" 65001 \n" +" __vm1_port__ \n" +" 10.0.0.1 \n" +" \n" +" \n" +" inet \n" +" \n" +" \n" +" inet6 \n" +" \n" +" \n" +"
\n" +" \n" +"
127.0.0.1
\n" +" 65002 \n" +" __vm2_port__ \n" +" 10.0.0.2 \n" +" \n" +" \n" +" inet \n" +" \n" +" \n" +" inet6 \n" +" \n" +" \n" +"
\n" +"
\n" +; + +static string serverConfigStr = +" \n" +" \n" +" \n" +"
127.0.0.1
\n" +" 64512 \n" +" 192.168.1.1 \n" +" __server_port__ \n" +"
\n" +" \n" +" target:64512:1 \n" +" \n" +" bgpaas-server \n" +" 64512 \n" +" __server_port__ \n" +" \n" +" \n" +" inet \n" +" \n" +" \n" +" inet6 \n" +" \n" +" \n" +" \n" +" \n" +" inet \n" +" \n" +" \n" +" inet6 \n" +" \n" +" \n" +" \n" +" \n" +" bgpaas-client \n" +" 65001 \n" +"
127.0.0.1
\n" +" 11024 \n" +" \n" +" \n" +" inet \n" +" \n" +" \n" +" inet6 \n" +" \n" +" \n" +"
\n" +" \n" +" bgpaas-client \n" +" 65002 \n" +"
127.0.0.1
\n" +" 11025 \n" +" \n" +" \n" +" inet \n" +" \n" +" \n" +" inet6 \n" +" \n" +" \n" +"
\n" +"
\n" +"
\n" +; + +class BGPaaSTest : public ::testing::Test { +protected: + BGPaaSTest() : + server_session_manager_(NULL), vm1_session_manager_(NULL), + vm2_session_manager_(NULL) { + } + + 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_session_manager_ = server_->session_manager(); + server_session_manager_->Initialize(0); + BGP_DEBUG_UT("Created server at port: " << + server_session_manager_->GetPort()); + + vm1_session_manager_ = vm1_->session_manager(); + vm1_session_manager_->Initialize(0); + BGP_DEBUG_UT("Created server at port: " << + vm1_session_manager_->GetPort()); + + vm2_session_manager_ = vm2_->session_manager(); + vm2_session_manager_->Initialize(0); + BGP_DEBUG_UT("Created server at port: " << + vm2_session_manager_->GetPort()); + thread_->Start(); + BgpPeerTest::verbose_name(true); + } + + virtual void TearDown() { + task_util::WaitForIdle(); + server_->Shutdown(); + vm1_->Shutdown(); + task_util::WaitForIdle(); + vm2_->Shutdown(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_EQ(0, TcpServerManager::GetServerCount()); + + evm_->Shutdown(); + if (thread_.get() != NULL) + thread_->Join(); + BgpPeerTest::verbose_name(false); + } + + BgpPeerTest *WaitForPeerToComeUp(BgpServerTest *server, + const string &peerName) { + string u = BgpConfigParser::session_uuid("bgpaas-server", peerName, 1); + TASK_UTIL_EXPECT_NE(static_cast(NULL), + dynamic_cast( + server->FindPeerByUuid(BgpConfigManager::kMasterInstance, u))); + BgpPeerTest *peer = dynamic_cast( + server->FindPeerByUuid(BgpConfigManager::kMasterInstance, u)); + BGP_WAIT_FOR_PEER_STATE(peer, StateMachine::ESTABLISHED); + return peer; + } + + auto_ptr evm_; + auto_ptr thread_; + auto_ptr server_; + auto_ptr vm1_; + auto_ptr vm2_; + BgpSessionManager *server_session_manager_; + BgpSessionManager *vm1_session_manager_; + BgpSessionManager *vm2_session_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); + task_util::WaitForIdle(); + + server_->Configure(serverConfigStr); + WaitForPeerToComeUp(vm1_.get(), "vm1"); + WaitForPeerToComeUp(vm2_.get(), "vm2"); +} + +class TestEnvironment : public ::testing::Environment { + virtual ~TestEnvironment() { } +}; + +static void SetUp() { + BgpServer::Initialize(); + ControlNode::SetDefaultSchedulingPolicy(); + BgpServerTest::GlobalSetUp(); +} + +static void TearDown() { + BgpServer::Terminate(); + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + scheduler->Terminate(); +} + +int main(int argc, char **argv) { + bgp_log_test::init(); + ::testing::InitGoogleTest(&argc, argv); + ::testing::AddGlobalTestEnvironment(new TestEnvironment()); + SetUp(); + int result = RUN_ALL_TESTS(); + TearDown(); + return result; +} diff --git a/src/bgp/test/bgp_server_test_util.cc b/src/bgp/test/bgp_server_test_util.cc index 660b07b9e65..f9559e9ce8b 100644 --- a/src/bgp/test/bgp_server_test_util.cc +++ b/src/bgp/test/bgp_server_test_util.cc @@ -47,6 +47,8 @@ BgpServerTest::BgpServerTest(EventManager *evm, const string &localname, config_manager->Initialize(config_db_.get(), config_graph_.get(), localname); cleanup_config_ = false; + source_port_ = 0; + peer_lookup_disable_ = false; rtarget_group_mgr_->Initialize(); } @@ -58,6 +60,8 @@ BgpServerTest::BgpServerTest(EventManager *evm, const string &localname) config_graph_(new DBGraph()) { ConcurrencyScope scope("bgp::Config"); cleanup_config_ = true; + source_port_ = 0; + peer_lookup_disable_ = false; IFMapLinkTable_Init(config_db_.get(), config_graph_.get()); vnc_cfg_Server_ModuleInit(config_db_.get(), config_graph_.get()); bgp_schema_Server_ModuleInit(config_db_.get(), config_graph_.get()); @@ -276,7 +280,23 @@ void BgpPeerTest::BindLocalEndpoint(BgpSession *session) { BgpPeerKey peer_key; peer_key.endpoint.address( ip::address::from_string("127.0.0.1", err)); - peer_key.endpoint.port(server()->session_manager()->GetPort()); + + // Check if we need to map to source-port only lookup (for BGPaas Clients) + local_port = static_cast(server())->source_port(); + if (local_port) { + + // Place the configured source-port in the map, as the fake BGPaaS + // clients do not actually send packets with configured source-port + // as local-port. + peer_key.endpoint.port(local_port); + peer_key.endpoint.address(Ip4Address()); + local_endpoint.address(Ip4Address()); + } else { + + // Use server-port as the value (which is used later to find the proper + // bgp-peer in configuration. + peer_key.endpoint.port(server()->session_manager()->GetPort()); + } if (config_) { if (!config_->uuid().empty()) { @@ -284,7 +304,7 @@ void BgpPeerTest::BindLocalEndpoint(BgpSession *session) { peer_key.uuid = gen(config_->uuid()); } else { boost::uuids::nil_generator nil; - peer_key.uuid == nil(); + peer_key.uuid = nil(); } tbb::mutex::scoped_lock lock(peer_connect_map_mutex_); peer_connect_map_[local_endpoint] = peer_key; @@ -328,6 +348,11 @@ void PeerManagerTest::DestroyIPeer(IPeer *ipeer) { // BgpPeer *PeerManagerTest::PeerLookup( TcpSession::Endpoint remote_endpoint) const { + + // Check if port-based peer lookup is disabled. + if (static_cast(server())->peer_lookup_disable()) + return PeerManager::PeerLookup(remote_endpoint); + BgpPeerKey peer_key; bool present; @@ -362,6 +387,14 @@ BgpPeer *PeerManagerTest::PeerLookup( return loc->second; } +// Find peer based on remote-endpoint port (BGPaaS client) +BgpPeer *BgpServerTest::FindPeer(TcpSession::Endpoint remote_endpoint) const { + tbb::mutex::scoped_lock lock(peer_connect_map_mutex_); + if (peer_connect_map_.count(remote_endpoint) > 0) + remote_endpoint = peer_connect_map_.at(remote_endpoint).endpoint; + return BgpServer::FindPeer(remote_endpoint); +} + BgpInstanceConfigTest *BgpTestUtil::CreateBgpInstanceConfig( const string &name, const string import_targets, const string export_targets, diff --git a/src/bgp/test/bgp_server_test_util.h b/src/bgp/test/bgp_server_test_util.h index c892477e15d..b27bbbb7fe7 100644 --- a/src/bgp/test/bgp_server_test_util.h +++ b/src/bgp/test/bgp_server_test_util.h @@ -214,6 +214,7 @@ class BgpServerTest : public BgpServer { const std::string &uuid); BgpPeer *FindPeer(const char *routing_instance, const std::string &peername); + BgpPeer *FindPeer(TcpSession::Endpoint remote) const; BgpPeer *FindMatchingPeer(const std::string &routing_instance, const std::string &name); void DisableAllPeers(); @@ -235,6 +236,10 @@ class BgpServerTest : public BgpServer { } virtual std::string ToString() const; + uint16_t source_port() const { return source_port_; } + void set_source_port(uint16_t source_port) { source_port_ = source_port; } + bool peer_lookup_disable() const { return peer_lookup_disable_; } + void set_peer_lookup_disable(bool flag) { peer_lookup_disable_ = flag; } private: void PostShutdown(); @@ -243,6 +248,8 @@ class BgpServerTest : public BgpServer { boost::scoped_ptr config_db_; boost::scoped_ptr config_graph_; bool cleanup_config_; + uint16_t source_port_; + bool peer_lookup_disable_; }; typedef boost::shared_ptr BgpServerTestPtr;