Line data Source code
1 : /* 2 : * Copyright (c) 2016 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 "base/regex.h" 9 : #include "bgp/bgp_peer_internal_types.h" 10 : #include "bgp/bgp_server.h" 11 : #include "bgp/bgp_table.h" 12 : #include "bgp/routing-instance/routing_instance.h" 13 : 14 : using contrail::regex; 15 : using contrail::regex_match; 16 : using contrail::regex_search; 17 : using std::string; 18 : using std::vector; 19 : 20 : // 21 : // Specialization of BgpShowHandler<>::CallbackCommon. 22 : // 23 : // Note that we check the page and iteration limits only after examining all 24 : // ribouts in all tables for a given routing instance. This simplifies things 25 : // and requires to only keep track of the next instance rather than the next 26 : // instance and next table. 27 : // 28 : template <> 29 2 : bool BgpShowHandler<ShowRibOutStatisticsReq, ShowRibOutStatisticsReqIterate, 30 : ShowRibOutStatisticsResp, ShowRibOutStatistics>::CallbackCommon( 31 : const BgpSandeshContext *bsc, Data *data) { 32 2 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit; 33 2 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit; 34 2 : RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr(); 35 : 36 2 : regex search_expr(data->search_string); 37 : RoutingInstanceMgr::const_name_iterator it1 = 38 2 : rim->name_clower_bound(data->next_entry); 39 4 : for (uint32_t iter_count = 0; it1 != rim->name_cend(); ++it1) { 40 2 : const RoutingInstance *rtinstance = it1->second; 41 2 : for (RoutingInstance::RouteTableList::const_iterator it2 = 42 2 : rtinstance->GetTables().begin(); 43 20 : it2 != rtinstance->GetTables().end(); ++it2, ++iter_count) { 44 18 : const BgpTable *table = it2->second; 45 18 : if (!regex_search(table->name(), search_expr)) 46 0 : continue; 47 18 : table->FillRibOutStatisticsInfo(&data->show_list); 48 : } 49 2 : if (data->show_list.size() >= page_limit) 50 0 : break; 51 2 : if (iter_count >= iter_limit) 52 0 : break; 53 : } 54 : 55 : // All done if we've looked at all instances. 56 2 : if (it1 == rim->name_cend() || ++it1 == rim->name_end()) 57 2 : return true; 58 : 59 : // Return true if we've reached the page limit, false if we've reached the 60 : // iteration limit. 61 0 : bool done = data->show_list.size() >= page_limit; 62 0 : SaveContextToData(it1->second->name(), done, data); 63 0 : return done; 64 2 : } 65 : 66 : // 67 : // Specialization of BgpShowHandler<>::FillShowList. 68 : // 69 : template <> 70 2 : void BgpShowHandler<ShowRibOutStatisticsReq, ShowRibOutStatisticsReqIterate, 71 : ShowRibOutStatisticsResp, ShowRibOutStatistics>::FillShowList( 72 : ShowRibOutStatisticsResp *resp, 73 : const vector<ShowRibOutStatistics> &show_list) { 74 2 : resp->set_ribouts(show_list); 75 2 : } 76 : 77 : // 78 : // Handler for ShowRibOutStatisticsReq. 79 : // 80 2 : void ShowRibOutStatisticsReq::HandleRequest() const { 81 2 : RequestPipeline::PipeSpec ps(this); 82 2 : RequestPipeline::StageSpec s1; 83 2 : TaskScheduler *scheduler = TaskScheduler::GetInstance(); 84 : 85 2 : s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); 86 : s1.cbFn_ = boost::bind(&BgpShowHandler< 87 : ShowRibOutStatisticsReq, 88 : ShowRibOutStatisticsReqIterate, 89 : ShowRibOutStatisticsResp, 90 2 : ShowRibOutStatistics>::Callback, _1, _2, _3, _4, _5); 91 : s1.allocFn_ = BgpShowHandler< 92 : ShowRibOutStatisticsReq, 93 : ShowRibOutStatisticsReqIterate, 94 : ShowRibOutStatisticsResp, 95 2 : ShowRibOutStatistics>::CreateData; 96 2 : s1.instances_.push_back(0); 97 2 : ps.stages_.push_back(s1); 98 2 : RequestPipeline rp(ps); 99 2 : } 100 : 101 : // 102 : // Handler for ShowRibOutStatisticsReqIterate. 103 : // 104 0 : void ShowRibOutStatisticsReqIterate::HandleRequest() const { 105 0 : RequestPipeline::PipeSpec ps(this); 106 0 : RequestPipeline::StageSpec s1; 107 0 : TaskScheduler *scheduler = TaskScheduler::GetInstance(); 108 : 109 0 : s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); 110 : s1.cbFn_ = boost::bind(&BgpShowHandler< 111 : ShowRibOutStatisticsReq, 112 : ShowRibOutStatisticsReqIterate, 113 : ShowRibOutStatisticsResp, 114 0 : ShowRibOutStatistics>::CallbackIterate, _1, _2, _3, _4, _5); 115 : s1.allocFn_ = BgpShowHandler< 116 : ShowRibOutStatisticsReq, 117 : ShowRibOutStatisticsReqIterate, 118 : ShowRibOutStatisticsResp, 119 0 : ShowRibOutStatistics>::CreateData; 120 0 : s1.instances_.push_back(0); 121 0 : ps.stages_.push_back(s1); 122 0 : RequestPipeline rp(ps); 123 0 : }