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

Generated by: LCOV version 1.14