LCOV - code coverage report
Current view: top level - bgp - bgp_sandesh.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 389 408 95.3 %
Date: 2026-11-09 02:10:49 Functions: 38 39 97.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include "bgp/bgp_sandesh.h"
       7             : 
       8             : #include <boost/assign/list_of.hpp>
       9             : #include <boost/foreach.hpp>
      10             : #include <sandesh/request_pipeline.h>
      11             : 
      12             : #include "bgp/bgp_multicast.h"
      13             : #include "bgp/bgp_mvpn.h"
      14             : #include "bgp/bgp_peer.h"
      15             : #include "bgp/bgp_peer_internal_types.h"
      16             : #include "bgp/bgp_server.h"
      17             : #include "bgp/bgp_session_manager.h"
      18             : #include "bgp/ermvpn/ermvpn_table.h"
      19             : #include "bgp/inet/inet_table.h"
      20             : #include "bgp/mvpn/mvpn_table.h"
      21             : #include "bgp/routing-instance/peer_manager.h"
      22             : #include "bgp/routing-instance/routing_instance.h"
      23             : 
      24             : using boost::assign::list_of;
      25             : using std::string;
      26             : using std::vector;
      27             : 
      28             : class ShowNeighborStatisticsHandler {
      29             : public:
      30             :     static bool CallbackS1(const Sandesh *sr,
      31             :         const RequestPipeline::PipeSpec ps, int stage, int instNum,
      32             :         RequestPipeline::InstData * data);
      33             :     static size_t FillBgpNeighborStatistics(
      34             :         const ShowNeighborStatisticsReq *req, BgpServer *bgp_server);
      35             : };
      36             : 
      37           5 : size_t ShowNeighborStatisticsHandler::FillBgpNeighborStatistics(
      38             :     const ShowNeighborStatisticsReq *req, BgpServer *bgp_server) {
      39           5 :     size_t count = 0;
      40             : 
      41           9 :     if (req->get_bgp_or_xmpp().empty() ||
      42           9 :         boost::iequals(req->get_bgp_or_xmpp(), "bgp")) {
      43           4 :         RoutingInstanceMgr *rim = bgp_server->routing_instance_mgr();
      44           4 :         if (!req->get_domain().empty()) {
      45           3 :             RoutingInstance *ri = rim->GetRoutingInstance(req->get_domain());
      46           3 :             PeerManager *pmgr = ri ? ri->peer_manager() : NULL;
      47           3 :             if (pmgr) {
      48           2 :                 count += pmgr->GetNeighborCount(req->get_up_or_down());
      49             :             }
      50             :         } else {
      51           1 :             RoutingInstanceMgr::RoutingInstanceIterator it = rim->begin();
      52           3 :             for (; it != rim->end(); it++) {
      53           2 :                 PeerManager *pmgr = it->second->peer_manager();
      54           2 :                 if (pmgr) {
      55           1 :                     count += pmgr->GetNeighborCount(req->get_up_or_down());
      56             :                 }
      57             :             }
      58             :         }
      59             :     }
      60             : 
      61           5 :     return count;
      62             : }
      63             : 
      64           5 : bool ShowNeighborStatisticsHandler::CallbackS1(
      65             :         const Sandesh *sr, const RequestPipeline::PipeSpec ps,
      66             :         int stage, int instNum, RequestPipeline::InstData *data) {
      67             :     const ShowNeighborStatisticsReq *req;
      68             :     BgpSandeshContext *bsc;
      69             : 
      70           5 :     req = static_cast<const ShowNeighborStatisticsReq *>(ps.snhRequest_.get());
      71           5 :     bsc = static_cast<BgpSandeshContext *>(req->client_context());
      72             : 
      73             :     // Retrieve number of BGP peers.
      74           5 :     size_t count = FillBgpNeighborStatistics(req, bsc->bgp_server);
      75             : 
      76             :     // Retrieve numner of XMPP agents.
      77           9 :     if (req->get_bgp_or_xmpp().empty() ||
      78           9 :             boost::iequals(req->get_bgp_or_xmpp(), "xmpp")) {
      79           2 :         bsc->ShowNeighborStatisticsExtension(&count, req);
      80             :     }
      81             : 
      82           5 :     ShowNeighborStatisticsResp *resp = new ShowNeighborStatisticsResp;
      83           5 :     resp->set_bgp_or_xmpp(req->get_bgp_or_xmpp());
      84           5 :     resp->set_up_or_down(req->get_up_or_down());
      85           5 :     resp->set_domain(req->get_domain());
      86           5 :     resp->set_count(count);
      87           5 :     resp->set_context(req->context());
      88           5 :     resp->Response();
      89             : 
      90           5 :     return true;
      91             : }
      92             : 
      93           5 : void ShowNeighborStatisticsReq::HandleRequest() const {
      94             :     // Use config task as we need to examine both bgp and xmpp data bases
      95             :     // to compute the number of neighbors. Both BGP and XMPP peers are
      96             :     // inserted/deleted under config task.
      97           5 :     RequestPipeline::StageSpec s1;
      98           5 :     s1.taskId_ = TaskScheduler::GetInstance()->GetTaskId("bgp::Config");
      99           5 :     s1.instances_.push_back(0);
     100           5 :     s1.cbFn_ = ShowNeighborStatisticsHandler::CallbackS1;
     101             : 
     102           5 :     RequestPipeline::PipeSpec ps(this);
     103           5 :     ps.stages_= list_of(s1)
     104           5 :         .convert_to_container<vector<RequestPipeline::StageSpec> >();
     105           5 :     RequestPipeline rp(ps);
     106           5 : }
     107             : 
     108             : class ClearBgpNeighborHandler {
     109             : public:
     110             :     static bool CallbackS1(const Sandesh *sr,
     111             :                            const RequestPipeline::PipeSpec ps, int stage,
     112             :                            int instNum, RequestPipeline::InstData * data);
     113             : };
     114             : 
     115          26 : bool ClearBgpNeighborHandler::CallbackS1(
     116             :         const Sandesh *sr, const RequestPipeline::PipeSpec ps,
     117             :         int stage, int instNum, RequestPipeline::InstData *data) {
     118             :     const ClearBgpNeighborReq *req;
     119             :     BgpSandeshContext *bsc;
     120             : 
     121          26 :     req = static_cast<const ClearBgpNeighborReq *>(ps.snhRequest_.get());
     122          26 :     bsc = static_cast<BgpSandeshContext *>(req->client_context());
     123          26 :     BgpPeer *peer = bsc->bgp_server->FindPeer(req->get_name());
     124             : 
     125          26 :     ClearBgpNeighborResp *resp = new ClearBgpNeighborResp;
     126          26 :     if (!bsc->test_mode()) {
     127           6 :         resp->set_success(false);
     128          20 :     } else if (peer) {
     129          12 :         peer->Clear(BgpProto::Notification::AdminReset);
     130          12 :         resp->set_success(true);
     131             :     } else {
     132           8 :         resp->set_success(false);
     133             :     }
     134          26 :     resp->set_context(req->context());
     135          26 :     resp->Response();
     136             : 
     137          26 :     return true;
     138             : }
     139             : 
     140             : // handler for 'clear bgp neighbor'
     141          26 : void ClearBgpNeighborReq::HandleRequest() const {
     142             :     // Use config task since neighbors are added/deleted under that task.
     143             :     // to compute the number of neighbors.
     144          26 :     RequestPipeline::StageSpec s1;
     145          26 :     s1.taskId_ = TaskScheduler::GetInstance()->GetTaskId("bgp::Config");
     146          26 :     s1.instances_.push_back(0);
     147          26 :     s1.cbFn_ = ClearBgpNeighborHandler::CallbackS1;
     148             : 
     149          26 :     RequestPipeline::PipeSpec ps(this);
     150          26 :     ps.stages_= list_of(s1)
     151          26 :         .convert_to_container<vector<RequestPipeline::StageSpec> >();
     152          26 :     RequestPipeline rp(ps);
     153          26 : }
     154             : 
     155             : class ShowMulticastManagerDetailHandler {
     156             : public:
     157             :     struct MulticastManagerDetailData : public RequestPipeline::InstData {
     158             :         vector<ShowMulticastTree> tree_list;
     159             :     };
     160             : 
     161           2 :     static RequestPipeline::InstData *CreateData(int stage) {
     162           2 :         return (new MulticastManagerDetailData);
     163             :     }
     164             : 
     165           8 :     static void FillMulticastLinkInfo(const McastForwarder *forwarder,
     166             :         ShowMulticastTreeLink *smtl) {
     167           8 :         smtl->set_address(forwarder->address().to_string());
     168           8 :         smtl->set_label(forwarder->label());
     169           8 :     }
     170             : 
     171           8 :     static void FillMulticastForwarderInfo(const McastForwarder *forwarder,
     172             :         ShowMulticastForwarder *smf) {
     173           8 :         smf->set_address(forwarder->address().to_string());
     174           8 :         smf->set_label(forwarder->label());
     175           8 :         smf->set_label_block(forwarder->label_block()->ToString());
     176           8 :         smf->set_router_id(forwarder->router_id().to_string());
     177           8 :         for (McastForwarderList::const_iterator it =
     178           8 :              forwarder->tree_links_.begin();
     179          16 :              it != forwarder->tree_links_.end(); ++it) {
     180           8 :             ShowMulticastTreeLink smtl;
     181           8 :             FillMulticastLinkInfo(*it, &smtl);
     182           8 :             smf->links.push_back(smtl);
     183           8 :         }
     184           8 :     }
     185             : 
     186           2 :     static void FillMulticastTreeInfo(const McastSGEntry *sg,
     187             :         ShowMulticastTree *smt) {
     188           2 :         smt->set_group(sg->group().to_string());
     189           2 :         smt->set_source(sg->source().to_string());
     190           6 :         for (uint8_t level = McastTreeManager::LevelFirst;
     191           6 :              level < McastTreeManager::LevelCount; ++level) {
     192           4 :             if (!sg->IsTreeBuilder(level))
     193           0 :                 continue;
     194           4 :             for (McastSGEntry::ForwarderSet::const_iterator it =
     195           4 :                  sg->forwarder_sets_[level]->begin();
     196          12 :                  it != sg->forwarder_sets_[level]->end(); ++it) {
     197           8 :                 ShowMulticastForwarder smf;
     198           8 :                 FillMulticastForwarderInfo(*it, &smf);
     199           8 :                 if (level == McastTreeManager::LevelNative) {
     200           6 :                     smt->level0_forwarders.push_back(smf);
     201             :                 } else {
     202           2 :                     smt->level1_forwarders.push_back(smf);
     203             :                 }
     204           8 :             }
     205             :         }
     206           2 :     }
     207             : 
     208           2 :     static void FillMulticastPartitionInfo(MulticastManagerDetailData *data,
     209             :             ErmVpnTable *table, int inst_id) {
     210           2 :         McastTreeManager *tm = table->GetTreeManager();
     211           2 :         McastManagerPartition *partition = tm->GetPartition(inst_id);
     212           2 :         for (McastManagerPartition::SGList::const_iterator it =
     213           2 :              partition->sg_list_.begin();
     214           4 :              it != partition->sg_list_.end(); it++) {
     215           2 :             ShowMulticastTree smt;
     216           2 :             FillMulticastTreeInfo(*it, &smt);
     217           2 :             data->tree_list.push_back(smt);
     218           2 :         }
     219           2 :     }
     220             : 
     221           2 :     static bool CallbackS1(const Sandesh *sr,
     222             :             const RequestPipeline::PipeSpec ps,
     223             :             int stage, int instNum,
     224             :             RequestPipeline::InstData *data) {
     225           2 :         int inst_id = ps.stages_[stage].instances_[instNum];
     226             : 
     227           2 :         MulticastManagerDetailData *mydata =
     228             :             static_cast<MulticastManagerDetailData *>(data);
     229             :         const ShowMulticastManagerDetailReq *req =
     230             :             static_cast<const ShowMulticastManagerDetailReq *>(
     231           2 :                 ps.snhRequest_.get());
     232             :         BgpSandeshContext *bsc =
     233           2 :             static_cast<BgpSandeshContext *>(req->client_context());
     234             :         DBTableBase *table =
     235           2 :             bsc->bgp_server->database()->FindTable(req->get_name());
     236           2 :         ErmVpnTable *mcast_table = dynamic_cast<ErmVpnTable *>(table);
     237           2 :         if (mcast_table && !mcast_table->IsVpnTable())
     238           2 :             FillMulticastPartitionInfo(mydata, mcast_table, inst_id);
     239             : 
     240           2 :         return true;
     241             :     }
     242             : 
     243           2 :     static void CombineMulticastPartitionInfo(
     244             :             const RequestPipeline::StageData *sd,
     245             :             vector<ShowMulticastTree> *tree_list) {
     246           4 :         for (size_t idx = 0; idx < sd->size(); idx++) {
     247             :             const MulticastManagerDetailData &data =
     248           2 :                 static_cast<const MulticastManagerDetailData &>(sd->at(idx));
     249           2 :             tree_list->insert(tree_list->end(),
     250             :                              data.tree_list.begin(), data.tree_list.end());
     251             :         }
     252           2 :     }
     253             : 
     254           2 :     static bool CallbackS2(const Sandesh *sr,
     255             :             const RequestPipeline::PipeSpec ps,
     256             :             int stage, int instNum,
     257             :             RequestPipeline::InstData *data) {
     258             :         const ShowMulticastManagerReq *req =
     259           2 :             static_cast<const ShowMulticastManagerReq *>(ps.snhRequest_.get());
     260           2 :         const RequestPipeline::StageData *sd = ps.GetStageData(0);
     261           2 :         vector<ShowMulticastTree> tree_list;
     262           2 :         CombineMulticastPartitionInfo(sd, &tree_list);
     263             : 
     264             :         ShowMulticastManagerDetailResp *resp =
     265           2 :             new ShowMulticastManagerDetailResp;
     266           2 :         resp->set_trees(tree_list);
     267           2 :         resp->set_context(req->context());
     268           2 :         resp->Response();
     269           2 :         return true;
     270           2 :     }
     271             : };
     272             : 
     273             : 
     274           2 : void ShowMulticastManagerDetailReq::HandleRequest() const {
     275           2 :     RequestPipeline::PipeSpec ps(this);
     276             : 
     277             :     // Request pipeline has 2 stages.
     278             :     // First stage to collect multicast manager stats.
     279             :     // Second stage to fill stats from stage 1 and respond to the request.
     280           2 :     RequestPipeline::StageSpec s1, s2;
     281           2 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     282             : 
     283           2 :     s1.taskId_ = scheduler->GetTaskId("db::DBTable");
     284           2 :     s1.allocFn_ = ShowMulticastManagerDetailHandler::CreateData;
     285           2 :     s1.cbFn_ = ShowMulticastManagerDetailHandler::CallbackS1;
     286           4 :     for (int i = 0; i < ErmVpnTable::kPartitionCount; i++) {
     287           2 :         s1.instances_.push_back(i);
     288             :     }
     289             : 
     290           2 :     s2.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
     291           2 :     s2.cbFn_ = ShowMulticastManagerDetailHandler::CallbackS2;
     292           2 :     s2.instances_.push_back(0);
     293             : 
     294           2 :     ps.stages_ = list_of(s1)(s2)
     295           2 :         .convert_to_container<vector<RequestPipeline::StageSpec> >();
     296           2 :     RequestPipeline rp(ps);
     297           2 : }
     298             : 
     299             : class ShowMvpnManagerDetailHandler {
     300             : public:
     301             :     struct MvpnManagerDetailData : public RequestPipeline::InstData {
     302             :         vector<ShowMvpnNeighbor> neighbors;
     303             :     };
     304             : 
     305           3 :     static RequestPipeline::InstData *CreateData(int stage) {
     306           3 :         return (new MvpnManagerDetailData);
     307             :     }
     308             : 
     309           1 :     static void FillMvpnNeighborInfo(const MvpnNeighbor *nbr,
     310             :         ShowMvpnNeighbor *snbr) {
     311           1 :         snbr->set_rd(nbr->rd().ToString());
     312           1 :         snbr->set_originator(nbr->originator().to_string());
     313           1 :         snbr->set_source_as(nbr->source_as());
     314           1 :     }
     315             : 
     316           2 :     static void FillMvpnNeighborsInfo(MvpnManagerDetailData *data,
     317             :             MvpnTable *table, int inst_id) {
     318           2 :         MvpnManager *tm = table->manager();
     319           2 :         if (!tm)
     320           0 :             return;
     321           2 :         std::shared_lock<std::shared_mutex> lock(tm->neighbors_mutex());
     322             : 
     323           4 :         BOOST_FOREACH(const MvpnManager::NeighborMap::value_type &val,
     324             :                       tm->neighbors()) {
     325           1 :             ShowMvpnNeighbor snbr;
     326           1 :             FillMvpnNeighborInfo(&val.second, &snbr);
     327           1 :             data->neighbors.push_back(snbr);
     328           1 :         }
     329           2 :     }
     330             : 
     331           3 :     static bool CallbackS1(const Sandesh *sr,
     332             :             const RequestPipeline::PipeSpec ps,
     333             :             int stage, int instNum,
     334             :             RequestPipeline::InstData *data) {
     335           3 :         int inst_id = ps.stages_[stage].instances_[instNum];
     336             : 
     337           3 :         MvpnManagerDetailData *mydata =
     338             :             static_cast<MvpnManagerDetailData *>(data);
     339             :         const ShowMvpnManagerDetailReq *req =
     340             :             static_cast<const ShowMvpnManagerDetailReq *>(
     341           3 :                 ps.snhRequest_.get());
     342             :         BgpSandeshContext *bsc =
     343           3 :             static_cast<BgpSandeshContext *>(req->client_context());
     344             :         DBTableBase *table =
     345           3 :             bsc->bgp_server->database()->FindTable(req->get_name());
     346           3 :         MvpnTable *mvpn_table = dynamic_cast<MvpnTable *>(table);
     347           3 :         if (mvpn_table && !mvpn_table->IsVpnTable())
     348           2 :             FillMvpnNeighborsInfo(mydata, mvpn_table, inst_id);
     349             : 
     350           3 :         ShowMvpnManagerDetailResp *resp = new ShowMvpnManagerDetailResp;
     351           3 :         resp->set_neighbors(mydata->neighbors);
     352           3 :         resp->set_context(req->context());
     353           3 :         resp->Response();
     354             : 
     355           3 :         return true;
     356             :     }
     357             : };
     358             : 
     359           3 : void ShowMvpnManagerDetailReq::HandleRequest() const {
     360           3 :     RequestPipeline::PipeSpec ps(this);
     361           3 :     RequestPipeline::StageSpec s1, s2;
     362           3 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     363             : 
     364           3 :     s1.taskId_ = scheduler->GetTaskId("db::DBTable");
     365           3 :     s1.allocFn_ = ShowMvpnManagerDetailHandler::CreateData;
     366           3 :     s1.cbFn_ = ShowMvpnManagerDetailHandler::CallbackS1;
     367           3 :     s1.instances_.push_back(0);
     368           3 :     ps.stages_ = list_of(s1)
     369           3 :         .convert_to_container<vector<RequestPipeline::StageSpec> >();
     370             : 
     371           3 :     RequestPipeline rp(ps);
     372           3 : }
     373             : 
     374             : class ShowMvpnProjectManagerDetailHandler {
     375             : public:
     376             :     struct MvpnProjectManagerDetailData : public RequestPipeline::InstData {
     377             :         vector<ShowMvpnState> states;
     378             :     };
     379             : 
     380           1 :     static RequestPipeline::InstData *CreateData(int stage) {
     381           1 :         return (new MvpnProjectManagerDetailData);
     382             :     }
     383             : 
     384           1 :     static void FillMvpnProjectStateInfo(const MvpnState *state,
     385             :                                          ShowMvpnState *st) {
     386           1 :         st->set_source(state->sg().source.to_string());
     387           1 :         st->set_group(state->sg().group.to_string());
     388           1 :         if (state->global_ermvpn_tree_rt()) {
     389           1 :             st->set_global_ermvpn_tree_rt(
     390           2 :                 state->global_ermvpn_tree_rt()->ToString());
     391             :         }
     392           1 :         if (state->spmsi_rt())
     393           0 :             st->set_spmsi_rt(state->spmsi_rt()->ToString());
     394           1 :         if (state->source_active_rt())
     395           0 :             st->set_source_active_rt(state->source_active_rt()->ToString());
     396             : 
     397           1 :         vector<string> spmsi_routes_received;
     398           1 :         BOOST_FOREACH(MvpnRoute *rt, state->spmsi_routes_received()) {
     399           0 :             spmsi_routes_received.push_back(rt->ToString());
     400             :         }
     401           1 :         st->set_spmsi_routes_received(spmsi_routes_received);
     402             : 
     403           1 :         vector<string> leafad_routes_attr_received;
     404           1 :         BOOST_FOREACH(const MvpnState::RoutesMap::value_type &val,
     405             :                       state->leafad_routes_attr_received()) {
     406           0 :             const PmsiTunnel *pmsi = val.second->pmsi_tunnel();
     407           0 :             if (pmsi) {
     408           0 :                 leafad_routes_attr_received.push_back(
     409           0 :                     pmsi->pmsi_tunnel().ToString());
     410             :             }
     411             :         }
     412           1 :         st->set_leafad_routes_attr_received(leafad_routes_attr_received);
     413           1 :         st->set_total_states(state->states()->size());
     414           1 :         st->set_project_manager(state->project_manager()->table()->name());
     415           1 :         st->set_refcount(state->refcount());
     416           1 :     }
     417             : 
     418           1 :     static void FillMvpnProjectPartitionInfo(MvpnProjectManagerDetailData *data,
     419             :             ErmVpnTable *table, int inst_id) {
     420           1 :         MvpnProjectManager *tm = table->mvpn_project_manager();
     421           1 :         if (!tm) return;
     422           1 :         MvpnProjectManagerPartition *partition = tm->GetPartition(inst_id);
     423           3 :         BOOST_FOREACH(MvpnState::StatesMap::value_type &val,
     424             :                       partition->states()) {
     425           1 :             ShowMvpnState st;
     426           1 :             FillMvpnProjectStateInfo(val.second, &st);
     427           1 :             data->states.push_back(st);
     428           1 :         }
     429             :     }
     430             : 
     431           1 :     static bool CallbackS1(const Sandesh *sr,
     432             :             const RequestPipeline::PipeSpec ps,
     433             :             int stage, int instNum,
     434             :             RequestPipeline::InstData *data) {
     435           1 :         int inst_id = ps.stages_[stage].instances_[instNum];
     436             : 
     437           1 :         MvpnProjectManagerDetailData *mydata =
     438             :             static_cast<MvpnProjectManagerDetailData *>(data);
     439             :         const ShowMvpnProjectManagerDetailReq *req =
     440             :             static_cast<const ShowMvpnProjectManagerDetailReq *>(
     441           1 :                 ps.snhRequest_.get());
     442             :         BgpSandeshContext *bsc =
     443           1 :             static_cast<BgpSandeshContext *>(req->client_context());
     444             :         DBTableBase *table =
     445           1 :             bsc->bgp_server->database()->FindTable(req->get_name());
     446           1 :         ErmVpnTable *ermvpn_table = dynamic_cast<ErmVpnTable *>(table);
     447           1 :         if (ermvpn_table && !ermvpn_table->IsVpnTable())
     448           1 :             FillMvpnProjectPartitionInfo(mydata, ermvpn_table, inst_id);
     449             : 
     450           1 :         return true;
     451             :     }
     452             : 
     453           1 :     static void CombineMvpnProjectPartitionInfo(
     454             :             const RequestPipeline::StageData *sd,
     455             :             vector<ShowMvpnState> *states) {
     456           2 :         for (size_t idx = 0; idx < sd->size(); idx++) {
     457             :             const MvpnProjectManagerDetailData &data =
     458           1 :                 static_cast<const MvpnProjectManagerDetailData &>(sd->at(idx));
     459           1 :             states->insert(states->end(),
     460             :                            data.states.begin(), data.states.end());
     461             :         }
     462           1 :     }
     463             : 
     464           1 :     static bool CallbackS2(const Sandesh *sr,
     465             :             const RequestPipeline::PipeSpec ps,
     466             :             int stage, int instNum,
     467             :             RequestPipeline::InstData *data) {
     468             :         const ShowMvpnProjectManagerReq *req =
     469             :             static_cast<const ShowMvpnProjectManagerReq *>(
     470           1 :                 ps.snhRequest_.get());
     471           1 :         const RequestPipeline::StageData *sd = ps.GetStageData(0);
     472           1 :         vector<ShowMvpnState> states;
     473           1 :         CombineMvpnProjectPartitionInfo(sd, &states);
     474             : 
     475             :         ShowMvpnProjectManagerDetailResp *resp =
     476           1 :             new ShowMvpnProjectManagerDetailResp;
     477           1 :         resp->set_states(states);
     478           1 :         resp->set_context(req->context());
     479           1 :         resp->Response();
     480           1 :         return true;
     481           1 :     }
     482             : };
     483             : 
     484             : 
     485           1 : void ShowMvpnProjectManagerDetailReq::HandleRequest() const {
     486           1 :     RequestPipeline::PipeSpec ps(this);
     487             : 
     488             :     // Request pipeline has 2 stages.
     489             :     // First stage to collect multicast manager stats.
     490             :     // Second stage to fill stats from stage 1 and respond to the request.
     491           1 :     RequestPipeline::StageSpec s1, s2;
     492           1 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     493             : 
     494           1 :     s1.taskId_ = scheduler->GetTaskId("db::DBTable");
     495           1 :     s1.allocFn_ = ShowMvpnProjectManagerDetailHandler::CreateData;
     496           1 :     s1.cbFn_ = ShowMvpnProjectManagerDetailHandler::CallbackS1;
     497           2 :     for (int i = 0; i < ErmVpnTable::kPartitionCount; i++) {
     498           1 :         s1.instances_.push_back(i);
     499             :     }
     500             : 
     501           1 :     s2.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
     502           1 :     s2.cbFn_ = ShowMvpnProjectManagerDetailHandler::CallbackS2;
     503           1 :     s2.instances_.push_back(0);
     504             : 
     505           1 :     ps.stages_ = list_of(s1)(s2)
     506           1 :         .convert_to_container<vector<RequestPipeline::StageSpec> >();
     507           1 :     RequestPipeline rp(ps);
     508           1 : }
     509             : 
     510             : class ShowRouteVrfHandler {
     511             : public:
     512             :     struct SearchRouteInVrfData : public RequestPipeline::InstData {
     513             :         vector<ShowRoute> routes;
     514             :     };
     515             : 
     516          36 :     static RequestPipeline::InstData *CreateData(int stage) {
     517          36 :         return (new SearchRouteInVrfData);
     518             :     }
     519             : 
     520          36 :     static bool CallbackS1(const Sandesh *sr,
     521             :             const RequestPipeline::PipeSpec ps,
     522             :             int stage, int instNum,
     523             :             RequestPipeline::InstData *data) {
     524          36 :         SearchRouteInVrfData *sdata = static_cast<SearchRouteInVrfData *>(data);
     525             :         const ShowRouteVrfReq *req =
     526          36 :             static_cast<const ShowRouteVrfReq *>(ps.snhRequest_.get());
     527             :         BgpSandeshContext *bsc =
     528          36 :             static_cast<BgpSandeshContext *>(req->client_context());
     529          36 :         RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr();
     530          36 :         RoutingInstance *ri = rim->GetRoutingInstance(req->get_vrf());
     531          36 :         if (!ri) return true;
     532          28 :         BgpTable *table = ri->GetTable(Address::INET);
     533          27 :         if (!table) return true;
     534          27 :         Ip4Prefix prefix(Ip4Prefix::FromString(req->get_prefix()));
     535          28 :         InetTable::RequestKey key(prefix, NULL);
     536             : 
     537             :         // Find route from the calling task instance specific db partition.
     538          28 :         InetRoute *route = static_cast<InetRoute *>(table->Find(&key, instNum));
     539          28 :         if (!route) return true;
     540           5 :         ShowRoute show_route;
     541           5 :         show_route.set_prefix(route->ToString());
     542           5 :         show_route.set_last_modified(duration_usecs_to_string(
     543           5 :                        UTCTimestampUsec() - route->last_change_at()));
     544           5 :         vector<ShowRoutePath> show_route_paths;
     545          15 :         for (Route::PathList::const_iterator it = route->GetPathList().begin();
     546          20 :              it != route->GetPathList().end(); it++) {
     547           5 :             const BgpPath *path = static_cast<const BgpPath *>(it.operator->());
     548           5 :             ShowRoutePath srp;
     549           5 :             srp.set_protocol("BGP");
     550           5 :             const BgpAttr *attr = path->GetAttr();
     551           5 :             if (attr->as_path() != NULL)
     552           5 :                 srp.set_as_path(attr->as_path()->path().ToString());
     553           5 :             srp.set_local_preference(attr->local_pref());
     554           5 :             if (path->GetPeer()) srp.set_source(path->GetPeer()->ToString());
     555           5 :             srp.set_last_modified(duration_usecs_to_string(
     556           5 :                     UTCTimestampUsec() - path->time_stamp_usecs()));
     557           5 :             srp.set_next_hop(attr->nexthop().to_string());
     558           5 :             srp.set_label(path->GetLabel());
     559           5 :             show_route_paths.push_back(srp);
     560           5 :         }
     561           5 :         show_route.set_paths(show_route_paths);
     562           5 :         sdata->routes.push_back(show_route);
     563           5 :         return true;
     564          28 :     }
     565             : 
     566           9 :     static bool CallbackS2(const Sandesh *sr,
     567             :             const RequestPipeline::PipeSpec ps,
     568             :             int stage, int instNum,
     569             :             RequestPipeline::InstData *data) {
     570           9 :         const RequestPipeline::StageData *sd = ps.GetStageData(0);
     571           9 :         ShowRoute route;
     572          25 :         for (size_t i = 0; i < sd->size(); i++) {
     573             :             const SearchRouteInVrfData &data =
     574          21 :                 static_cast<const SearchRouteInVrfData &>(sd->at(i));
     575          21 :             if (data.routes.size()) {
     576           5 :                 route = data.routes.front();
     577           5 :                 break;
     578             :             }
     579             :         }
     580             : 
     581           9 :         ShowRouteVrfResp *resp = new ShowRouteVrfResp;
     582           9 :         resp->set_route(route);
     583             :         const ShowRouteVrfReq *req =
     584           9 :             static_cast<const ShowRouteVrfReq *>(ps.snhRequest_.get());
     585           9 :         resp->set_context(req->context());
     586           9 :         resp->Response();
     587           9 :         return true;
     588           9 :     }
     589             : };
     590             : 
     591           9 : void ShowRouteVrfReq::HandleRequest() const {
     592           9 :     RequestPipeline::PipeSpec ps(this);
     593           9 :     BgpSandeshContext *bsc = static_cast<BgpSandeshContext *>(client_context());
     594             : 
     595             :     // Request pipeline has 2 stages.
     596             :     // First stage to search in different partition
     597             :     // Second stage to fill stats from stage 1 and respond to the request.
     598           9 :     RequestPipeline::StageSpec s1, s2;
     599           9 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     600             : 
     601           9 :     s1.taskId_ = scheduler->GetTaskId("db::DBTable");
     602           9 :     s1.allocFn_ = ShowRouteVrfHandler::CreateData;
     603           9 :     s1.cbFn_ = ShowRouteVrfHandler::CallbackS1;
     604          45 :     for (int i = 0; i < bsc->bgp_server->database()->PartitionCount(); i++) {
     605          36 :         s1.instances_.push_back(i);
     606             :     }
     607             : 
     608           9 :     s2.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
     609           9 :     s2.cbFn_ = ShowRouteVrfHandler::CallbackS2;
     610           9 :     s2.instances_.push_back(0);
     611             : 
     612           9 :     ps.stages_ = list_of(s1)(s2)
     613           9 :         .convert_to_container<vector<RequestPipeline::StageSpec> >();
     614           9 :     RequestPipeline rp(ps);
     615           9 : }
     616             : 
     617             : class ShowBgpServerHandler {
     618             : public:
     619           4 :     static bool CallbackS1(const Sandesh *sr,
     620             :             const RequestPipeline::PipeSpec ps, int stage, int instNum,
     621             :             RequestPipeline::InstData *data) {
     622             :         const ShowBgpServerReq *req =
     623           4 :             static_cast<const ShowBgpServerReq *>(ps.snhRequest_.get());
     624             :         BgpSandeshContext *bsc =
     625           4 :             static_cast<BgpSandeshContext *>(req->client_context());
     626             : 
     627           4 :         ShowBgpServerResp *resp = new ShowBgpServerResp;
     628           4 :         SocketIOStats peer_socket_stats;
     629           4 :         bsc->bgp_server->session_manager()->GetRxSocketStats(&peer_socket_stats);
     630           4 :         resp->set_rx_socket_stats(peer_socket_stats);
     631             : 
     632           4 :         bsc->bgp_server->session_manager()->GetTxSocketStats(&peer_socket_stats);
     633           4 :         resp->set_tx_socket_stats(peer_socket_stats);
     634             : 
     635           4 :         resp->set_context(req->context());
     636           4 :         resp->Response();
     637           4 :         return true;
     638           4 :     }
     639             : };
     640             : 
     641           4 : void ShowBgpServerReq::HandleRequest() const {
     642           4 :     RequestPipeline::PipeSpec ps(this);
     643             : 
     644             :     // Request pipeline has single stage to collect neighbor config info
     645             :     // and respond to the request
     646           4 :     RequestPipeline::StageSpec s1;
     647           4 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     648           4 :     s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
     649           4 :     s1.cbFn_ = ShowBgpServerHandler::CallbackS1;
     650           4 :     s1.instances_.push_back(0);
     651           4 :     ps.stages_ = list_of(s1)
     652           4 :        .convert_to_container<vector<RequestPipeline::StageSpec> >();
     653           4 :     RequestPipeline rp(ps);
     654           4 : }
     655             : 
     656        1522 : BgpSandeshContext::BgpSandeshContext()
     657        1522 :     : bgp_server(NULL),
     658        1522 :       xmpp_peer_manager(NULL),
     659        1522 :       test_mode_(false),
     660        1522 :       page_limit_(0),
     661        1522 :       iter_limit_(0) {
     662        1522 : }
     663             : 
     664         133 : void BgpSandeshContext::SetNeighborShowExtensions(
     665             :     const NeighborListExtension &show_neighbor,
     666             :     const NeighborStatisticsExtension &show_neighbor_statistics) {
     667         133 :     show_neighbor_ext_ = show_neighbor;
     668         133 :     show_neighbor_statistics_ext_ = show_neighbor_statistics;
     669         133 : }
     670             : 
     671         386 : bool BgpSandeshContext::ShowNeighborExtension(const BgpSandeshContext *bsc,
     672             :     bool summary, uint32_t page_limit, uint32_t iter_limit,
     673             :     const string &start_neighbor, const string &search_string,
     674             :     vector<BgpNeighborResp> *list, string *next_neighbor) const {
     675         386 :     if (!show_neighbor_ext_)
     676           0 :         return true;
     677         386 :     bool done = show_neighbor_ext_(bsc, summary, page_limit, iter_limit,
     678             :         start_neighbor, search_string, list, next_neighbor);
     679         386 :     return done;
     680             : }
     681             : 
     682           2 : void BgpSandeshContext::ShowNeighborStatisticsExtension(
     683             :     size_t *count, const ShowNeighborStatisticsReq *req) const {
     684           2 :     if (!show_neighbor_statistics_ext_)
     685           0 :         return;
     686           2 :     show_neighbor_statistics_ext_(count, this, req);
     687             : }
     688             : 
     689           5 : void BgpSandeshContext::SetPeeringShowHandlers(
     690             :     const PeeringReqHandler &show_peering_req_handler,
     691             :     const PeeringReqIterateHandler &show_peering_req_iterate_handler) {
     692           5 :     show_peering_req_handler_ = show_peering_req_handler;
     693           5 :     show_peering_req_iterate_handler_ = show_peering_req_iterate_handler;
     694           5 : }
     695             : 
     696           3 : void BgpSandeshContext::PeeringShowReqHandler(
     697             :     const ShowBgpPeeringConfigReq *req) {
     698           3 :     if (show_peering_req_handler_) {
     699           3 :        show_peering_req_handler_(this, req);
     700             :     } else {
     701           0 :         ShowBgpPeeringConfigResp *resp = new ShowBgpPeeringConfigResp;
     702           0 :         resp->Response();
     703             :     }
     704           3 : }
     705             : 
     706           0 : void BgpSandeshContext::PeeringShowReqIterateHandler(
     707             :     const ShowBgpPeeringConfigReqIterate *req_iterate) {
     708           0 :     if (show_peering_req_iterate_handler_) {
     709           0 :        show_peering_req_iterate_handler_(this, req_iterate);
     710             :     } else {
     711           0 :         ShowBgpPeeringConfigResp *resp = new ShowBgpPeeringConfigResp;
     712           0 :         resp->Response();
     713             :     }
     714           0 : }

Generated by: LCOV version 1.14