LCOV - code coverage report
Current view: top level - bgp - bgp_show_routing_instance.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 162 163 99.4 %
Date: 2026-06-18 01:51:13 Functions: 11 11 100.0 %
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_show_handler.h"
       6             : 
       7             : #include <boost/foreach.hpp>
       8             : 
       9             : #include "base/regex.h"
      10             : #include "bgp/bgp_membership.h"
      11             : #include "bgp/bgp_peer.h"
      12             : #include "bgp/bgp_peer_internal_types.h"
      13             : #include "bgp/bgp_server.h"
      14             : #include "bgp/bgp_table.h"
      15             : #include "bgp/routing-instance/peer_manager.h"
      16             : #include "bgp/routing-instance/routing_instance.h"
      17             : #include "bgp/routing-policy/routing_policy.h"
      18             : 
      19             : using contrail::regex;
      20             : using contrail::regex_match;
      21             : using contrail::regex_search;
      22             : using std::string;
      23             : using std::vector;
      24             : 
      25             : //
      26             : // Fill in information for a table.
      27             : //
      28        1093 : static void FillRoutingInstanceTableInfo(ShowRoutingInstanceTable *srit,
      29             :     const BgpSandeshContext *bsc, const BgpTable *table) {
      30        1093 :     srit->set_name(table->name());
      31        1093 :     srit->set_deleted(table->IsDeleted());
      32        1093 :     srit->set_walk_requests(table->walk_request_count());
      33        1093 :     srit->set_walk_completes(table->walk_complete_count());
      34        1093 :     srit->set_walk_cancels(table->walk_cancel_count());
      35        1093 :     size_t markers = 0;
      36        1093 :     srit->set_pending_updates(table->GetPendingRiboutsCount(&markers));
      37        1093 :     srit->set_markers(markers);
      38        1093 :     srit->set_listeners(table->GetListenerCount());
      39        1093 :     srit->set_walkers(table->walker_count());
      40        1093 :     srit->set_prefixes(table->Size());
      41        1093 :     srit->set_primary_paths(table->GetPrimaryPathCount());
      42        1093 :     srit->set_secondary_paths(table->GetSecondaryPathCount());
      43        1093 :     srit->set_infeasible_paths(table->GetInfeasiblePathCount());
      44        1093 :     srit->set_stale_paths(table->GetStalePathCount());
      45        1093 :     srit->set_llgr_stale_paths(table->GetLlgrStalePathCount());
      46        1093 :     srit->set_paths(srit->get_primary_paths() + srit->get_secondary_paths());
      47        1093 : }
      48             : 
      49             : //
      50             : // Fill in information for an instance.
      51             : //
      52         423 : static void FillRoutingInstanceInfo(ShowRoutingInstance *sri,
      53             :     const BgpSandeshContext *bsc, const RoutingInstance *rtinstance,
      54             :     bool summary) {
      55         423 :     sri->set_name(rtinstance->name());
      56         423 :     sri->set_virtual_network(rtinstance->GetVirtualNetworkName());
      57         423 :     sri->set_vn_index(rtinstance->virtual_network_index());
      58         423 :     sri->set_vxlan_id(rtinstance->vxlan_id());
      59         423 :     sri->set_deleted(rtinstance->deleted());
      60         423 :     sri->set_deleted_at(
      61         846 :         UTCUsecToString(rtinstance->deleter()->delete_time_stamp_usecs()));
      62         423 :     vector<string> import_rt;
      63        1572 :     for (auto rt : rtinstance->GetImportList()) {
      64        1149 :         import_rt.push_back(rt.ToString());
      65             :     }
      66         423 :     sri->set_import_target(import_rt);
      67         423 :     vector<string> export_rt;
      68         806 :     for (auto rt : rtinstance->GetExportList()) {
      69         383 :         export_rt.push_back(rt.ToString());
      70             :     }
      71         423 :     sri->set_export_target(export_rt);
      72         423 :     sri->set_always_subscribe(rtinstance->always_subscribe());
      73         423 :     sri->set_allow_transit(rtinstance->virtual_network_allow_transit());
      74         423 :     sri->set_pbb_evpn_enable(rtinstance->virtual_network_pbb_evpn_enable());
      75             : 
      76         423 :     if (summary)
      77         210 :         return;
      78             : 
      79         213 :     const BgpMembershipManager *bmm = bsc->bgp_server->membership_mgr();
      80         213 :     vector<ShowRoutingInstanceTable> srit_list;
      81         213 :     const RoutingInstance::RouteTableList &tables = rtinstance->GetTables();
      82         213 :     for (RoutingInstance::RouteTableList::const_iterator it =
      83        1519 :         tables.begin(); it != tables.end(); ++it) {
      84        1093 :         ShowRoutingInstanceTable srit;
      85        1093 :         FillRoutingInstanceTableInfo(&srit, bsc, it->second);
      86        1093 :         bmm->FillRoutingInstanceTableInfo(&srit, it->second);
      87        1093 :         srit_list.push_back(srit);
      88        1093 :     }
      89         213 :     sri->set_tables(srit_list);
      90             : 
      91         213 :     vector<ShowInstanceRoutingPolicyInfo> policy_list;
      92         217 :     for (auto info : rtinstance->routing_policies()) {
      93           4 :         ShowInstanceRoutingPolicyInfo show_policy_info;
      94           4 :         RoutingPolicyPtr policy = info.first;
      95           4 :         show_policy_info.set_policy_name(policy->name());
      96           4 :         show_policy_info.set_generation(info.second);
      97           4 :         policy_list.push_back(show_policy_info);
      98           4 :     }
      99         213 :     sri->set_routing_policies(policy_list);
     100             : 
     101         213 :     const PeerManager *peer_manager = rtinstance->peer_manager();
     102         213 :     if (peer_manager) {
     103           7 :         vector<string> neighbors;
     104           7 :         for (const BgpPeer *peer = peer_manager->NextPeer(BgpPeerKey());
     105           7 :             peer != NULL; peer = peer_manager->NextPeer(peer->peer_key())) {
     106           0 :             neighbors.push_back(peer->peer_name());
     107             :         }
     108           7 :         sri->set_neighbors(neighbors);
     109           7 :     }
     110         633 : }
     111             : 
     112             : //
     113             : // Fill in information for list of instances.
     114             : //
     115             : // Allows regular and summary introspect to share code.
     116             : //
     117          85 : static bool FillRoutingInstanceInfoList(const BgpSandeshContext *bsc,
     118             :     bool summary, uint32_t page_limit, uint32_t iter_limit,
     119             :     const string &start_instance, const string &search_string,
     120             :     vector<ShowRoutingInstance> *sri_list, string *next_instance) {
     121          85 :     regex search_expr(search_string);
     122          85 :     RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr();
     123             :     RoutingInstanceMgr::const_name_iterator it =
     124          85 :         rim->name_clower_bound(start_instance);
     125         621 :     for (uint32_t iter_count = 0; it != rim->name_cend(); ++it, ++iter_count) {
     126         586 :         const RoutingInstance *rtinstance = it->second;
     127         586 :         if (!search_string.empty() &&
     128         833 :             (!regex_search(rtinstance->name(), search_expr)) &&
     129         247 :             (search_string != "deleted" || !rtinstance->deleted())) {
     130         163 :             continue;
     131             :         }
     132         423 :         ShowRoutingInstance sri;
     133         423 :         FillRoutingInstanceInfo(&sri, bsc, rtinstance, summary);
     134         423 :         sri_list->push_back(sri);
     135         423 :         if (sri_list->size() >= page_limit)
     136          26 :             break;
     137         397 :         if (iter_count >= iter_limit)
     138          24 :             break;
     139         423 :     }
     140             : 
     141             :     // All done if we've looked at all instances.
     142          85 :     if (it == rim->name_cend() || ++it == rim->name_end())
     143          41 :         return true;
     144             : 
     145             :     // Return true if we've reached the page limit, false if we've reached the
     146             :     // iteration limit.
     147          44 :     bool done = sri_list->size() >= page_limit;
     148          44 :     *next_instance = it->second->name();
     149          44 :     return done;
     150          85 : }
     151             : 
     152             : //
     153             : // Specialization of BgpShowHandler<>::CallbackCommon for regular introspect.
     154             : //
     155             : template <>
     156          44 : bool BgpShowHandler<ShowRoutingInstanceReq, ShowRoutingInstanceReqIterate,
     157             :     ShowRoutingInstanceResp, ShowRoutingInstance>::CallbackCommon(
     158             :     const BgpSandeshContext *bsc, Data *data) {
     159          44 :     uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
     160          44 :     uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
     161          44 :     string next_instance;
     162          88 :     bool done = FillRoutingInstanceInfoList(bsc, false, page_limit, iter_limit,
     163          44 :         data->next_entry, data->search_string, &data->show_list,
     164             :         &next_instance);
     165          44 :     if (!next_instance.empty())
     166          22 :         SaveContextToData(next_instance, done, data);
     167          44 :     return done;
     168          44 : }
     169             : 
     170             : //
     171             : // Specialization of BgpShowHandler<>::FillShowList for regular introspect.
     172             : //
     173             : template <>
     174          27 : void BgpShowHandler<ShowRoutingInstanceReq, ShowRoutingInstanceReqIterate,
     175             :     ShowRoutingInstanceResp, ShowRoutingInstance>::FillShowList(
     176             :     ShowRoutingInstanceResp *resp,
     177             :     const vector<ShowRoutingInstance> &show_list) {
     178          27 :     resp->set_instances(show_list);
     179          27 : }
     180             : 
     181             : //
     182             : // Specialization of BgpShowHandler<>::CallbackCommon for summary introspect.
     183             : //
     184             : template <>
     185          41 : bool BgpShowHandler<ShowRoutingInstanceSummaryReq,
     186             :     ShowRoutingInstanceSummaryReqIterate,
     187             :     ShowRoutingInstanceSummaryResp, ShowRoutingInstance>::CallbackCommon(
     188             :     const BgpSandeshContext *bsc, Data *data) {
     189          41 :     uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
     190          41 :     uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
     191          41 :     string next_instance;
     192          82 :     bool done = FillRoutingInstanceInfoList(bsc, true, page_limit, iter_limit,
     193          41 :         data->next_entry, data->search_string, &data->show_list,
     194             :         &next_instance);
     195          41 :     if (!next_instance.empty())
     196          22 :         SaveContextToData(next_instance, done, data);
     197          41 :     return done;
     198          41 : }
     199             : 
     200             : //
     201             : // Specialization of BgpShowHandler<>::FillShowList for summary introspect.
     202             : //
     203             : template <>
     204          24 : void BgpShowHandler<ShowRoutingInstanceSummaryReq,
     205             :     ShowRoutingInstanceSummaryReqIterate,
     206             :     ShowRoutingInstanceSummaryResp, ShowRoutingInstance>::FillShowList(
     207             :     ShowRoutingInstanceSummaryResp *resp,
     208             :     const vector<ShowRoutingInstance> &show_list) {
     209          24 :     resp->set_instances(show_list);
     210          24 : }
     211             : 
     212             : //
     213             : // Handler for ShowRoutingInstanceReq.
     214             : //
     215          19 : void ShowRoutingInstanceReq::HandleRequest() const {
     216          19 :     RequestPipeline::PipeSpec ps(this);
     217          19 :     RequestPipeline::StageSpec s1;
     218          19 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     219             : 
     220          19 :     s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
     221             :     s1.cbFn_ = boost::bind(&BgpShowHandler<
     222             :         ShowRoutingInstanceReq,
     223             :         ShowRoutingInstanceReqIterate,
     224             :         ShowRoutingInstanceResp,
     225          19 :         ShowRoutingInstance>::Callback, _1, _2, _3, _4, _5);
     226             :     s1.allocFn_ = BgpShowHandler<
     227             :         ShowRoutingInstanceReq,
     228             :         ShowRoutingInstanceReqIterate,
     229             :         ShowRoutingInstanceResp,
     230          19 :         ShowRoutingInstance>::CreateData;
     231          19 :     s1.instances_.push_back(0);
     232          19 :     ps.stages_.push_back(s1);
     233          19 :     RequestPipeline rp(ps);
     234          19 : }
     235             : 
     236             : //
     237             : // Handler for ShowRoutingInstanceReqIterate.
     238             : //
     239          16 : void ShowRoutingInstanceReqIterate::HandleRequest() const {
     240          16 :     RequestPipeline::PipeSpec ps(this);
     241          16 :     RequestPipeline::StageSpec s1;
     242          16 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     243             : 
     244          16 :     s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
     245             :     s1.cbFn_ = boost::bind(&BgpShowHandler<
     246             :         ShowRoutingInstanceReq,
     247             :         ShowRoutingInstanceReqIterate,
     248             :         ShowRoutingInstanceResp,
     249          16 :         ShowRoutingInstance>::CallbackIterate, _1, _2, _3, _4, _5);
     250             :     s1.allocFn_ = BgpShowHandler<
     251             :         ShowRoutingInstanceReq,
     252             :         ShowRoutingInstanceReqIterate,
     253             :         ShowRoutingInstanceResp,
     254          16 :         ShowRoutingInstance>::CreateData;
     255          16 :     s1.instances_.push_back(0);
     256          16 :     ps.stages_.push_back(s1);
     257          16 :     RequestPipeline rp(ps);
     258          16 : }
     259             : 
     260             : //
     261             : // Handler for ShowRoutingInstanceSummaryReq.
     262             : //
     263          16 : void ShowRoutingInstanceSummaryReq::HandleRequest() const {
     264          16 :     RequestPipeline::PipeSpec ps(this);
     265          16 :     RequestPipeline::StageSpec s1;
     266          16 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     267             : 
     268          16 :     s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
     269             :     s1.cbFn_ = boost::bind(&BgpShowHandler<
     270             :         ShowRoutingInstanceSummaryReq,
     271             :         ShowRoutingInstanceSummaryReqIterate,
     272             :         ShowRoutingInstanceSummaryResp,
     273          16 :         ShowRoutingInstance>::Callback, _1, _2, _3, _4, _5);
     274             :     s1.allocFn_ = BgpShowHandler<
     275             :         ShowRoutingInstanceSummaryReq,
     276             :         ShowRoutingInstanceSummaryReqIterate,
     277             :         ShowRoutingInstanceSummaryResp,
     278          16 :         ShowRoutingInstance>::CreateData;
     279          16 :     s1.instances_.push_back(0);
     280          16 :     ps.stages_.push_back(s1);
     281          16 :     RequestPipeline rp(ps);
     282          16 : }
     283             : 
     284             : //
     285             : // Handler for ShowRoutingInstanceSummaryReqIterate.
     286             : //
     287          16 : void ShowRoutingInstanceSummaryReqIterate::HandleRequest() const {
     288          16 :     RequestPipeline::PipeSpec ps(this);
     289          16 :     RequestPipeline::StageSpec s1;
     290          16 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     291             : 
     292          16 :     s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
     293             :     s1.cbFn_ = boost::bind(&BgpShowHandler<
     294             :         ShowRoutingInstanceSummaryReq,
     295             :         ShowRoutingInstanceSummaryReqIterate,
     296             :         ShowRoutingInstanceSummaryResp,
     297          16 :         ShowRoutingInstance>::CallbackIterate, _1, _2, _3, _4, _5);
     298             :     s1.allocFn_ = BgpShowHandler<
     299             :         ShowRoutingInstanceSummaryReq,
     300             :         ShowRoutingInstanceSummaryReqIterate,
     301             :         ShowRoutingInstanceSummaryResp,
     302          16 :         ShowRoutingInstance>::CreateData;
     303          16 :     s1.instances_.push_back(0);
     304          16 :     ps.stages_.push_back(s1);
     305          16 :     RequestPipeline rp(ps);
     306          16 : }

Generated by: LCOV version 1.14