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

Generated by: LCOV version 1.14