From 355b88abae1cc27f2f4c247ea929177b790464d6 Mon Sep 17 00:00:00 2001 From: Nischal Sheth Date: Fri, 20 Nov 2015 18:37:12 -0800 Subject: [PATCH] Extend introspect for config peering/neighbors to all instances Since BGPaaS configures peerings and neighbors in non-master instances, extend introspect for config peerings and neighbors to show objects in all instances. Highlights: - Fix syntax error in ShowBgpNeighborFamily sandesh definition - Move code for neighbors to bgp_show_config.cc - Move code for peerings to bgp_show_ifmap_peering_config.cc - Add level of indirection to avoid linking issues for peering show command. This is needed because YAML config does not have notion of peering. - Paginate output for peerings and neighbors while we're at it - Tweak tests so that they pass with the new code Change-Id: Ic5dc47a7684e80ac693aea1e2660abff783ce681 Partial-Bug: 1518047 --- src/bgp/SConscript | 2 + src/bgp/bgp_config_ifmap.h | 6 +- src/bgp/bgp_ifmap_sandesh.cc | 22 +++ src/bgp/bgp_ifmap_sandesh.h | 8 + src/bgp/bgp_peer.sandesh | 19 ++- src/bgp/bgp_peer_internal.sandesh | 9 +- src/bgp/bgp_sandesh.cc | 160 +++-------------- src/bgp/bgp_sandesh.h | 17 ++ src/bgp/bgp_show_config.cc | 158 +++++++++++++++++ src/bgp/bgp_show_ifmap_peering_config.cc | 161 ++++++++++++++++++ src/bgp/test/bgp_ifmap_config_manager_test.cc | 59 ++++++- src/control-node/main.cc | 2 + 12 files changed, 473 insertions(+), 150 deletions(-) create mode 100644 src/bgp/bgp_ifmap_sandesh.cc create mode 100644 src/bgp/bgp_ifmap_sandesh.h create mode 100644 src/bgp/bgp_show_ifmap_peering_config.cc diff --git a/src/bgp/SConscript b/src/bgp/SConscript index 01b740f3c63..9b3556ee684 100644 --- a/src/bgp/SConscript +++ b/src/bgp/SConscript @@ -82,6 +82,8 @@ libbgp_ifmap_config = env.Library('bgp_ifmap_config', 'bgp_config_ifmap.cc', 'bgp_config_listener.cc', 'bgp_config_parser.cc', + 'bgp_ifmap_sandesh.cc', + 'bgp_show_ifmap_peering_config.cc', ]) libbgp_xmpp = env.Library('bgp_xmpp', diff --git a/src/bgp/bgp_config_ifmap.h b/src/bgp/bgp_config_ifmap.h index 0eb730be92d..29dfbff96ae 100644 --- a/src/bgp/bgp_config_ifmap.h +++ b/src/bgp/bgp_config_ifmap.h @@ -81,6 +81,7 @@ class BgpIfmapPeeringConfig { const IFMapNode *node() const { return node_proxy_.node(); } BgpIfmapInstanceConfig *instance() { return instance_; } + const BgpIfmapInstanceConfig *instance() const { return instance_; } std::string name() const { return name_; } size_t size() const { return neighbors_.size(); } const autogen::BgpPeering *bgp_peering() const { @@ -208,9 +209,8 @@ class BgpIfmapInstanceConfig { BgpConfigManager::NeighborMapRange NeighborMapItems() const; - const NeighborMap &neighbors() const { - return neighbors_; - } + const NeighborMap &neighbors() const { return neighbors_; } + const PeeringMap &peerings() const { return peerings_; } void AddPeering(BgpIfmapPeeringConfig *peering); void DeletePeering(BgpIfmapPeeringConfig *peering); diff --git a/src/bgp/bgp_ifmap_sandesh.cc b/src/bgp/bgp_ifmap_sandesh.cc new file mode 100644 index 00000000000..1c89c4f4962 --- /dev/null +++ b/src/bgp/bgp_ifmap_sandesh.cc @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved. + */ +#include "bgp/bgp_ifmap_sandesh.h" + +#include "bgp/bgp_sandesh.h" + +class ShowBgpPeeringConfigReq; +class ShowBgpPeeringConfigReqIterate; + +extern void ShowBgpIfmapPeeringConfigReqHandler( + const BgpSandeshContext *bsc, + const ShowBgpPeeringConfigReq *req); +extern void ShowBgpIfmapPeeringConfigReqIterateHandler( + const BgpSandeshContext *bsc, + const ShowBgpPeeringConfigReqIterate *req_iterate); + +void RegisterSandeshShowIfmapHandlers(BgpSandeshContext *bsc) { + bsc->SetPeeringShowHandlers( + ShowBgpIfmapPeeringConfigReqHandler, + ShowBgpIfmapPeeringConfigReqIterateHandler); +} diff --git a/src/bgp/bgp_ifmap_sandesh.h b/src/bgp/bgp_ifmap_sandesh.h new file mode 100644 index 00000000000..4c1218b8b4e --- /dev/null +++ b/src/bgp/bgp_ifmap_sandesh.h @@ -0,0 +1,8 @@ +#ifndef BGP__BGP_IFMAP_SANDESH_H__ +#define BGP__BGP_IFMAP_SANDESH_H__ + +struct BgpSandeshContext; + +extern void RegisterSandeshShowIfmapHandlers(BgpSandeshContext *); + +#endif // BGP__BGP_IFMAP_SANDESH_H__ diff --git a/src/bgp/bgp_peer.sandesh b/src/bgp/bgp_peer.sandesh index 0fbe84d75f7..1909b829637 100644 --- a/src/bgp/bgp_peer.sandesh +++ b/src/bgp/bgp_peer.sandesh @@ -40,9 +40,9 @@ struct BgpNeighborRoutingTable { } struct ShowBgpNeighborFamily { - string family; - u32 loop_count; - u32 prefix_limit; + 1: string family; + 2: u32 loop_count; + 3: u32 prefix_limit; } struct BgpNeighborResp { @@ -440,6 +440,16 @@ struct ShowBgpPeeringConfig { 4: list sessions; } +response sandesh ShowBgpPeeringConfigResp { + 1: list peerings; + 2: optional string next_batch (link="ShowBgpPeeringConfigReqIterate", + link_title="next_batch"); +} + +request sandesh ShowBgpPeeringConfigReq { + 1: string search_string; +} + struct ShowBgpNeighborFamilyConfig { 1: string family; 2: i32 loop_count; @@ -468,9 +478,12 @@ struct ShowBgpNeighborConfig { response sandesh ShowBgpNeighborConfigResp { 1: list neighbors; + 2: optional string next_batch (link="ShowBgpNeighborConfigReqIterate", + link_title="next_batch"); } request sandesh ShowBgpNeighborConfigReq { + 1: string search_string; } struct BgpPeerInfoData { diff --git a/src/bgp/bgp_peer_internal.sandesh b/src/bgp/bgp_peer_internal.sandesh index b4e4202a4a7..82e7b38f5cb 100644 --- a/src/bgp/bgp_peer_internal.sandesh +++ b/src/bgp/bgp_peer_internal.sandesh @@ -94,9 +94,10 @@ request sandesh ShowBgpInstanceConfigReqIterate { 1: string iterate_info; } -response sandesh ShowBgpPeeringConfigResp { - 1: list peerings; +request sandesh ShowBgpPeeringConfigReqIterate { + 1: string iterate_info; } -request sandesh ShowBgpPeeringConfigReq { -} \ No newline at end of file +request sandesh ShowBgpNeighborConfigReqIterate { + 1: string iterate_info; +} diff --git a/src/bgp/bgp_sandesh.cc b/src/bgp/bgp_sandesh.cc index a5b34111245..d55b122b1d2 100644 --- a/src/bgp/bgp_sandesh.cc +++ b/src/bgp/bgp_sandesh.cc @@ -377,139 +377,6 @@ void ShowRouteVrfReq::HandleRequest() const { RequestPipeline rp(ps); } -class ShowBgpPeeringConfigHandler { -public: - static bool CallbackS1(const Sandesh *sr, - const RequestPipeline::PipeSpec ps, - int stage, int instNum, - RequestPipeline::InstData *data) { - const ShowBgpPeeringConfigReq *req = - static_cast(ps.snhRequest_.get()); - BgpSandeshContext *bsc = - static_cast(req->client_context()); - BgpConfigManager *bcm = bsc->bgp_server->config_manager(); - - vector peering_list; - typedef std::pair pair_t; - BOOST_FOREACH(pair_t item, bcm->NeighborMapItems( - BgpConfigManager::kMasterInstance)) { - ShowBgpPeeringConfig peering; - const BgpNeighborConfig *neighbor = item.second; - peering.set_instance_name(neighbor->instance_name()); - peering.set_name(neighbor->name()); - peering.set_neighbor_count(1); - - vector session_list; - ShowBgpSessionConfig session; - session.set_uuid(neighbor->uuid()); - vector attribute_list; - ShowBgpSessionAttributesConfig attribute; - attribute.set_address_families(neighbor->GetAddressFamilies()); - attribute_list.push_back(attribute); - session.set_attributes(attribute_list); - session_list.push_back(session); - peering.set_sessions(session_list); - peering_list.push_back(peering); - } - - ShowBgpPeeringConfigResp *resp = new ShowBgpPeeringConfigResp; - resp->set_peerings(peering_list); - resp->set_context(req->context()); - resp->Response(); - return true; - } -}; - -void ShowBgpPeeringConfigReq::HandleRequest() const { - RequestPipeline::PipeSpec ps(this); - - // Request pipeline has single stage to collect peering config info - // and respond to the request - RequestPipeline::StageSpec s1; - TaskScheduler *scheduler = TaskScheduler::GetInstance(); - s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); - s1.cbFn_ = ShowBgpPeeringConfigHandler::CallbackS1; - s1.instances_.push_back(0); - ps.stages_ = list_of(s1); - RequestPipeline rp(ps); -} - -class ShowBgpNeighborConfigHandler { -public: - static bool CallbackS1(const Sandesh *sr, - const RequestPipeline::PipeSpec ps, - int stage, int instNum, - RequestPipeline::InstData *data) { - const ShowBgpNeighborConfigReq *req = - static_cast(ps.snhRequest_.get()); - BgpSandeshContext *bsc = - static_cast(req->client_context()); - BgpConfigManager *bcm = bsc->bgp_server->config_manager(); - - vector nbr_list; - - typedef std::pair pair_t; - BOOST_FOREACH(pair_t item, bcm->NeighborMapItems( - BgpConfigManager::kMasterInstance)) { - const BgpNeighborConfig *neighbor = item.second; - ShowBgpNeighborConfig nbr; - nbr.set_instance_name(neighbor->instance_name()); - nbr.set_name(neighbor->name()); - nbr.set_admin_down(neighbor->admin_down()); - nbr.set_passive(neighbor->passive()); - Ip4Address localid(ntohl(neighbor->local_identifier())); - nbr.set_local_identifier(localid.to_string()); - nbr.set_local_as(neighbor->local_as()); - nbr.set_autonomous_system(neighbor->peer_as()); - Ip4Address peerid(ntohl(neighbor->peer_identifier())); - nbr.set_identifier(peerid.to_string()); - nbr.set_address(neighbor->peer_address().to_string()); - nbr.set_address_families(neighbor->GetAddressFamilies()); - nbr.set_hold_time(neighbor->hold_time()); - nbr.set_loop_count(neighbor->loop_count()); - nbr.set_last_change_at( - UTCUsecToString(neighbor->last_change_at())); - nbr.set_auth_type(neighbor->auth_data().KeyTypeToString()); - if (bsc->test_mode()) { - nbr.set_auth_keys(neighbor->auth_data().KeysToStringDetail()); - } - - vector family_attributes_list; - BOOST_FOREACH(const BgpFamilyAttributesConfig family_config, - neighbor->family_attributes_list()) { - ShowBgpNeighborFamilyConfig family_attributes; - family_attributes.family = family_config.family; - family_attributes.loop_count = family_config.loop_count; - family_attributes.prefix_limit = family_config.prefix_limit; - family_attributes_list.push_back(family_attributes); - } - nbr.set_family_attributes_list(family_attributes_list); - - nbr_list.push_back(nbr); - } - - ShowBgpNeighborConfigResp *resp = new ShowBgpNeighborConfigResp; - resp->set_neighbors(nbr_list); - resp->set_context(req->context()); - resp->Response(); - return true; - } -}; - -void ShowBgpNeighborConfigReq::HandleRequest() const { - RequestPipeline::PipeSpec ps(this); - - // Request pipeline has single stage to collect neighbor config info - // and respond to the request - RequestPipeline::StageSpec s1; - TaskScheduler *scheduler = TaskScheduler::GetInstance(); - s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); - s1.cbFn_ = ShowBgpNeighborConfigHandler::CallbackS1; - s1.instances_.push_back(0); - ps.stages_ = list_of(s1); - RequestPipeline rp(ps); -} - class ShowBgpServerHandler { public: static bool CallbackS1(const Sandesh *sr, @@ -580,3 +447,30 @@ void BgpSandeshContext::ShowNeighborStatisticsExtension( return; show_neighbor_statistics_ext_(count, this, req); } + +void BgpSandeshContext::SetPeeringShowHandlers( + const PeeringReqHandler &show_peering_req_handler, + const PeeringReqIterateHandler &show_peering_req_iterate_handler) { + show_peering_req_handler_ = show_peering_req_handler; + show_peering_req_iterate_handler_ = show_peering_req_iterate_handler; +} + +void BgpSandeshContext::PeeringShowReqHandler( + const ShowBgpPeeringConfigReq *req) { + if (show_peering_req_handler_) { + show_peering_req_handler_(this, req); + } else { + ShowBgpPeeringConfigResp *resp = new ShowBgpPeeringConfigResp; + resp->Response(); + } +} + +void BgpSandeshContext::PeeringShowReqIterateHandler( + const ShowBgpPeeringConfigReqIterate *req_iterate) { + if (show_peering_req_iterate_handler_) { + show_peering_req_iterate_handler_(this, req_iterate); + } else { + ShowBgpPeeringConfigResp *resp = new ShowBgpPeeringConfigResp; + resp->Response(); + } +} diff --git a/src/bgp/bgp_sandesh.h b/src/bgp/bgp_sandesh.h index cd57373a43d..35c72794099 100644 --- a/src/bgp/bgp_sandesh.h +++ b/src/bgp/bgp_sandesh.h @@ -14,6 +14,8 @@ class BgpNeighborResp; class BgpNeighborReq; class ShowBgpNeighborSummaryReq; class ShowNeighborStatisticsReq; +class ShowBgpPeeringConfigReq; +class ShowBgpPeeringConfigReqIterate; struct BgpSandeshContext : public SandeshContext { typedef boost::function NeighborStatisticsExtension; + typedef boost::function PeeringReqHandler; + typedef boost::function PeeringReqIterateHandler; + BgpSandeshContext(); void SetNeighborShowExtensions( const NeighborListExtension &show_neighbor, const NeighborStatisticsExtension &show_neighbor_statistics); + void SetPeeringShowHandlers( + const PeeringReqHandler &show_peering_req_handler, + const PeeringReqIterateHandler &show_peering_req_iterate_handler); + BgpServer *bgp_server; BgpXmppChannelManager *xmpp_peer_manager; @@ -39,6 +50,10 @@ struct BgpSandeshContext : public SandeshContext { void ShowNeighborStatisticsExtension(size_t *count, const ShowNeighborStatisticsReq *req) const; + void PeeringShowReqHandler(const ShowBgpPeeringConfigReq *req); + void PeeringShowReqIterateHandler( + const ShowBgpPeeringConfigReqIterate *req_iterate); + // For testing. bool test_mode() const { return test_mode_; } void set_test_mode(bool test_mode) { test_mode_ = test_mode; } @@ -53,6 +68,8 @@ struct BgpSandeshContext : public SandeshContext { uint32_t iter_limit_; NeighborListExtension show_neighbor_ext_; NeighborStatisticsExtension show_neighbor_statistics_ext_; + PeeringReqHandler show_peering_req_handler_; + PeeringReqIterateHandler show_peering_req_iterate_handler_; }; #endif /* BGP_SANDESH_H_ */ diff --git a/src/bgp/bgp_show_config.cc b/src/bgp/bgp_show_config.cc index 876d0cebb21..50663737f04 100644 --- a/src/bgp/bgp_show_config.cc +++ b/src/bgp/bgp_show_config.cc @@ -8,6 +8,7 @@ #include #include "bgp/bgp_config.h" +#include "bgp/bgp_config_ifmap.h" #include "bgp/bgp_peer_internal_types.h" #include "bgp/bgp_server.h" @@ -169,3 +170,160 @@ void ShowBgpInstanceConfigReqIterate::HandleRequest() const { ps.stages_.push_back(s1); RequestPipeline rp(ps); } + + +// +// Fill in information for a neighbor. +// +static void FillBgpNeighborConfigInfo(ShowBgpNeighborConfig *sbnc, + const BgpSandeshContext *bsc, const BgpNeighborConfig *neighbor) { + sbnc->set_instance_name(neighbor->instance_name()); + sbnc->set_name(neighbor->name()); + sbnc->set_admin_down(neighbor->admin_down()); + sbnc->set_passive(neighbor->passive()); + sbnc->set_local_identifier(neighbor->local_identifier_string()); + sbnc->set_local_as(neighbor->local_as()); + sbnc->set_autonomous_system(neighbor->peer_as()); + sbnc->set_identifier(neighbor->peer_identifier_string()); + sbnc->set_address(neighbor->peer_address().to_string()); + sbnc->set_address_families(neighbor->GetAddressFamilies()); + sbnc->set_hold_time(neighbor->hold_time()); + sbnc->set_loop_count(neighbor->loop_count()); + sbnc->set_last_change_at(UTCUsecToString(neighbor->last_change_at())); + sbnc->set_auth_type(neighbor->auth_data().KeyTypeToString()); + if (bsc->test_mode()) { + sbnc->set_auth_keys(neighbor->auth_data().KeysToStringDetail()); + } + + vector sbnfc_list; + BOOST_FOREACH(const BgpFamilyAttributesConfig family_config, + neighbor->family_attributes_list()) { + ShowBgpNeighborFamilyConfig sbnfc; + sbnfc.family = family_config.family; + sbnfc.loop_count = family_config.loop_count; + sbnfc.prefix_limit = family_config.prefix_limit; + sbnfc_list.push_back(sbnfc); + } + sbnc->set_family_attributes_list(sbnfc_list); +} + +// +// Specialization of BgpShowHandler<>::CallbackCommon. +// +template <> +bool BgpShowHandler::CallbackCommon( + const BgpSandeshContext *bsc, Data *data) { + uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit; + uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit; + const BgpConfigManager *bcm = bsc->bgp_server->config_manager(); + + BgpConfigManager::InstanceMapRange range = + bcm->InstanceMapItems(data->next_entry); + BgpConfigManager::InstanceMap::const_iterator it = range.first; + BgpConfigManager::InstanceMap::const_iterator it_end = range.second; + for (uint32_t iter_count = 0; it != it_end; ++it, ++iter_count) { + const BgpInstanceConfig *instance = it->second; + BOOST_FOREACH(BgpConfigManager::NeighborMap::value_type value, + bcm->NeighborMapItems(instance->name())) { + const BgpNeighborConfig *neighbor = value.second; + if (!data->search_string.empty() && + (neighbor->name().find(data->search_string) == string::npos)) { + continue; + } + + ShowBgpNeighborConfig sbnc; + FillBgpNeighborConfigInfo(&sbnc, bsc, neighbor); + data->show_list.push_back(sbnc); + } + if (data->show_list.size() >= page_limit) + break; + if (iter_count >= iter_limit) + break; + } + + // All done if we've looked at all instances. + if (it == it_end || ++it == it_end) + return true; + + // Return true if we've reached the page limit, false if we've reached the + // iteration limit. + bool done = data->show_list.size() >= page_limit; + SaveContextToData(it->second->name(), done, data); + return done; +} + +// +// Specialization of BgpShowHandler<>::FillShowList. +// +template <> +void BgpShowHandler::FillShowList( + ShowBgpNeighborConfigResp *resp, + const vector &show_list) { + resp->set_neighbors(show_list); +} + +// +// Handler for ShowBgpNeighborConfigReq. +// +void ShowBgpNeighborConfigReq::HandleRequest() const { + RequestPipeline::PipeSpec ps(this); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowBgpNeighborConfigReq, + ShowBgpNeighborConfigReqIterate, + ShowBgpNeighborConfigResp, + ShowBgpNeighborConfig>::Callback, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowBgpNeighborConfigReq, + ShowBgpNeighborConfigReqIterate, + ShowBgpNeighborConfigResp, + ShowBgpNeighborConfig>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} + +// +// Handler for ShowBgpNeighborConfigReqIterate. +// +void ShowBgpNeighborConfigReqIterate::HandleRequest() const { + RequestPipeline::PipeSpec ps(this); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowBgpNeighborConfigReq, + ShowBgpNeighborConfigReqIterate, + ShowBgpNeighborConfigResp, + ShowBgpNeighborConfig>::CallbackIterate, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowBgpNeighborConfigReq, + ShowBgpNeighborConfigReqIterate, + ShowBgpNeighborConfigResp, + ShowBgpNeighborConfig>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} + +// +// Handler for ShowBgpPeeringConfigReq. +// +void ShowBgpPeeringConfigReq::HandleRequest() const { + BgpSandeshContext *bsc = static_cast(client_context()); + bsc->PeeringShowReqHandler(this); +} + +// +// Handler for ShowBgpPeeringConfigReqIterate. +// +void ShowBgpPeeringConfigReqIterate::HandleRequest() const { + BgpSandeshContext *bsc = static_cast(client_context()); + bsc->PeeringShowReqIterateHandler(this); +} diff --git a/src/bgp/bgp_show_ifmap_peering_config.cc b/src/bgp/bgp_show_ifmap_peering_config.cc new file mode 100644 index 00000000000..97a18e7dba2 --- /dev/null +++ b/src/bgp/bgp_show_ifmap_peering_config.cc @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +#include "bgp/bgp_show_handler.h" + +#include + +#include "bgp/bgp_config_ifmap.h" +#include "bgp/bgp_peer_types.h" +#include "bgp/bgp_peer_internal_types.h" +#include "bgp/bgp_server.h" +#include "schema/bgp_schema_types.h" + +using std::string; +using std::vector; + +// +// Fill in information for a peering. +// +static void FillBgpPeeringConfigInfo(ShowBgpPeeringConfig *sbpc, + const BgpSandeshContext *bsc, const BgpIfmapPeeringConfig *peering) { + sbpc->set_instance_name(peering->instance()->name()); + sbpc->set_name(peering->name()); + sbpc->set_neighbor_count(peering->size()); + if (peering->bgp_peering()) { + vector sbsc_list; + for (vector::const_iterator sit = + peering->bgp_peering()->data().begin(); + sit != peering->bgp_peering()->data().end(); ++sit) { + ShowBgpSessionConfig sbsc; + sbsc.set_uuid(sit->uuid); + vector sbsac_list; + for (vector::const_iterator ait = + sit->attributes.begin(); ait != sit->attributes.end(); ++ait) { + ShowBgpSessionAttributesConfig sbsac; + sbsac.set_bgp_router(ait->bgp_router); + sbsac.set_address_families(ait->address_families.family); + sbsac_list.push_back(sbsac); + } + sbsc.set_attributes(sbsac_list); + sbsc_list.push_back(sbsc); + } + sbpc->set_sessions(sbsc_list); + } +} + +// +// Specialization of BgpShowHandler<>::CallbackCommon. +// +template <> +bool BgpShowHandler::CallbackCommon( + const BgpSandeshContext *bsc, Data *data) { + uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit; + uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit; + const BgpIfmapConfigManager *bcm = dynamic_cast( + bsc->bgp_server->config_manager()); + if (!bcm) + return true; + + BgpConfigManager::InstanceMapRange range = + bcm->InstanceMapItems(data->next_entry); + BgpConfigManager::InstanceMap::const_iterator it = range.first; + BgpConfigManager::InstanceMap::const_iterator it_end = range.second; + for (uint32_t iter_count = 0; it != it_end; ++it, ++iter_count) { + const BgpIfmapInstanceConfig *instance = + bcm->config()->FindInstance(it->first); + if (!instance) + continue; + BOOST_FOREACH(BgpIfmapInstanceConfig::PeeringMap::value_type value, + instance->peerings()) { + const BgpIfmapPeeringConfig *peering = value.second; + if (!data->search_string.empty() && + (peering->name().find(data->search_string) == string::npos)) { + continue; + } + + ShowBgpPeeringConfig sbpc; + FillBgpPeeringConfigInfo(&sbpc, bsc, peering); + data->show_list.push_back(sbpc); + } + if (data->show_list.size() >= page_limit) + break; + if (iter_count >= iter_limit) + break; + } + + // All done if we've looked at all instances. + if (it == it_end || ++it == it_end) + return true; + + // Return true if we've reached the page limit, false if we've reached the + // iteration limit. + bool done = data->show_list.size() >= page_limit; + SaveContextToData(it->second->name(), done, data); + return done; +} + +// +// Specialization of BgpShowHandler<>::FillShowList. +// +template <> +void BgpShowHandler::FillShowList( + ShowBgpPeeringConfigResp *resp, + const vector &show_list) { + resp->set_peerings(show_list); +} + +// +// Handler for ShowBgpPeeringConfigReq. +// Called via BgpSandeshContext::PeeringShowReqHandler. +// +void ShowBgpIfmapPeeringConfigReqHandler(const BgpSandeshContext *bsc, + const ShowBgpPeeringConfigReq *req) { + RequestPipeline::PipeSpec ps(req); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowBgpPeeringConfigReq, + ShowBgpPeeringConfigReqIterate, + ShowBgpPeeringConfigResp, + ShowBgpPeeringConfig>::Callback, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowBgpPeeringConfigReq, + ShowBgpPeeringConfigReqIterate, + ShowBgpPeeringConfigResp, + ShowBgpPeeringConfig>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} + +// +// Handler for ShowBgpPeeringConfigReqIterate. +// Called via BgpSandeshContext::PeeringShowReqIterateHandler. +// +void ShowBgpIfmapPeeringConfigReqIterateHandler(const BgpSandeshContext *bsc, + const ShowBgpPeeringConfigReqIterate *req_iterate) { + RequestPipeline::PipeSpec ps(req_iterate); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowBgpPeeringConfigReq, + ShowBgpPeeringConfigReqIterate, + ShowBgpPeeringConfigResp, + ShowBgpPeeringConfig>::CallbackIterate, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowBgpPeeringConfigReq, + ShowBgpPeeringConfigReqIterate, + ShowBgpPeeringConfigResp, + ShowBgpPeeringConfig>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} diff --git a/src/bgp/test/bgp_ifmap_config_manager_test.cc b/src/bgp/test/bgp_ifmap_config_manager_test.cc index 34390183d8f..102a33a189f 100644 --- a/src/bgp/test/bgp_ifmap_config_manager_test.cc +++ b/src/bgp/test/bgp_ifmap_config_manager_test.cc @@ -11,6 +11,7 @@ #include "base/test/task_test_util.h" #include "bgp/bgp_config_parser.h" #include "bgp/bgp_factory.h" +#include "bgp/bgp_ifmap_sandesh.h" #include "bgp/bgp_log.h" #include "bgp/bgp_peer_internal_types.h" #include "bgp/bgp_sandesh.h" @@ -1577,6 +1578,7 @@ TEST_F(BgpIfmapConfigManagerShowTest, ShowPeerings1) { TASK_UTIL_EXPECT_EQ(3, config_manager_->config()->PeeringCount()); BgpSandeshContext sandesh_context; + RegisterSandeshShowIfmapHandlers(&sandesh_context); sandesh_context.bgp_server = &server_; Sandesh::set_client_context(&sandesh_context); @@ -1590,8 +1592,7 @@ TEST_F(BgpIfmapConfigManagerShowTest, ShowPeerings1) { const BgpIfmapPeeringConfig *config = FindPeeringConfig(full_name); ASSERT_TRUE(config != NULL); ShowBgpPeeringConfig peering; - peering.set_name( - string(BgpConfigManager::kMasterInstance) + ":" + peering_name); + peering.set_name(config->name()); peering.set_instance_name(BgpConfigManager::kMasterInstance); peering.set_neighbor_count(config->size()); peering_list.push_back(peering); @@ -1633,20 +1634,64 @@ TEST_F(BgpIfmapConfigManagerShowTest, ShowPeerings2) { VerifyBgpSessions(config, session_mask); BgpSandeshContext sandesh_context; + RegisterSandeshShowIfmapHandlers(&sandesh_context); sandesh_context.bgp_server = &server_; Sandesh::set_client_context(&sandesh_context); vector peering_list; - for (size_t i = 0; i < config->size(); ++i) { + ShowBgpPeeringConfig peering; + peering.set_name(config->name()); + peering.set_instance_name(BgpConfigManager::kMasterInstance); + peering.set_neighbor_count(3); + peering_list.push_back(peering); + + bool validate_done = false; + Sandesh::set_response_callback( + boost::bind(ValidateShowPeeringResponse, _1, &validate_done, + peering_list)); + + ShowBgpPeeringConfigReq *show_req = new ShowBgpPeeringConfigReq; + show_req->HandleRequest(); + show_req->Release(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_TRUE(validate_done); + + boost::replace_all(content, "", ""); + boost::replace_all(content, "", ""); + EXPECT_TRUE(parser_.Parse(content)); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_EQ(1, config_manager_->config()->instances().size()); + TASK_UTIL_EXPECT_EQ(0, db_graph_.vertex_count()); +} + +TEST_F(BgpIfmapConfigManagerShowTest, ShowBGPaaSPeerings) { + string content; + content = FileRead("controller/src/bgp/testdata/config_test_36a.xml"); + EXPECT_TRUE(parser_.Parse(content)); + task_util::WaitForIdle(); + + TASK_UTIL_EXPECT_EQ(2, config_manager_->config()->PeeringCount()); + vector peering_list; + for (int idx = 1; idx <= 2; ++idx) { + char full_name[1024]; + snprintf(full_name, sizeof(full_name), "attr(%s:%s,%s:%s%d)", + "test", "BGPaaS", "test", "vm", idx); + TASK_UTIL_EXPECT_TRUE(FindPeeringConfig(full_name) != NULL); + const BgpIfmapPeeringConfig *config = FindPeeringConfig(full_name); + TASK_UTIL_EXPECT_EQ(1, config->size()); + ShowBgpPeeringConfig peering; - stringstream oss; - oss << BgpConfigManager::kMasterInstance << ":remote:" << i; - peering.set_name(oss.str()); - peering.set_instance_name(BgpConfigManager::kMasterInstance); + peering.set_name(config->name()); + peering.set_instance_name("test"); peering.set_neighbor_count(1); peering_list.push_back(peering); } + BgpSandeshContext sandesh_context; + RegisterSandeshShowIfmapHandlers(&sandesh_context); + sandesh_context.bgp_server = &server_; + Sandesh::set_client_context(&sandesh_context); + bool validate_done = false; Sandesh::set_response_callback( boost::bind(ValidateShowPeeringResponse, _1, &validate_done, diff --git a/src/control-node/main.cc b/src/control-node/main.cc index cc0ab6e0ba2..28dbd4fface 100644 --- a/src/control-node/main.cc +++ b/src/control-node/main.cc @@ -17,6 +17,7 @@ #include "bgp/bgp_config.h" #include "bgp/bgp_config_ifmap.h" #include "bgp/bgp_config_parser.h" +#include "bgp/bgp_ifmap_sandesh.h" #include "bgp/bgp_peer.h" #include "bgp/bgp_peer_types.h" #include "bgp/bgp_sandesh.h" @@ -547,6 +548,7 @@ int main(int argc, char *argv[]) { } BgpSandeshContext sandesh_context; + RegisterSandeshShowIfmapHandlers(&sandesh_context); RegisterSandeshShowXmppExtensions(&sandesh_context); Sandesh::set_send_rate_limit(options.sandesh_send_rate_limit()); if (sandesh_generator_init) {