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 "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 : // Fill in information for a table. 22 : // 23 9220 : static void FillRouteTableSummaryInfo(ShowRouteTableSummary *srts, 24 : const BgpSandeshContext *bsc, const BgpTable *table) { 25 9220 : srts->set_name(table->name()); 26 9220 : srts->set_deleted(table->IsDeleted()); 27 9220 : srts->set_deleted_at( 28 18440 : UTCUsecToString(table->deleter()->delete_time_stamp_usecs())); 29 9220 : srts->set_prefixes(table->Size()); 30 9220 : srts->set_primary_paths(table->GetPrimaryPathCount()); 31 9220 : srts->set_secondary_paths(table->GetSecondaryPathCount()); 32 9220 : srts->set_infeasible_paths(table->GetInfeasiblePathCount()); 33 9220 : srts->set_stale_paths(table->GetStalePathCount()); 34 9220 : srts->set_llgr_stale_paths(table->GetLlgrStalePathCount()); 35 9220 : srts->set_paths(srts->get_primary_paths() + srts->get_secondary_paths()); 36 9220 : srts->set_walk_requests(table->walk_request_count()); 37 9220 : srts->set_walk_again_requests(table->walk_again_count()); 38 9220 : srts->set_actual_walks(table->walk_count()); 39 9220 : srts->set_walk_completes(table->walk_complete_count()); 40 9220 : srts->set_walk_cancels(table->walk_cancel_count()); 41 9220 : size_t markers = 0; 42 9220 : srts->set_pending_updates(table->GetPendingRiboutsCount(&markers)); 43 9220 : srts->set_markers(markers); 44 9220 : srts->set_listeners(table->GetListenerCount()); 45 9220 : srts->set_walkers(table->walker_count()); 46 9220 : } 47 : 48 : // 49 : // Specialization of BgpShowHandler<>::CallbackCommon. 50 : // 51 : // Note that we check the page and iteration limits only after examining all 52 : // tables for a given routing instance. This simplifies things and requires 53 : // to only keep track of the next instance rather than the next instance and 54 : // next table. 55 : // 56 : template <> 57 1759 : bool BgpShowHandler<ShowRouteSummaryReq, ShowRouteSummaryReqIterate, 58 : ShowRouteSummaryResp, ShowRouteTableSummary>::CallbackCommon( 59 : const BgpSandeshContext *bsc, Data *data) { 60 1759 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit; 61 1759 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit; 62 1759 : RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr(); 63 : 64 1759 : regex search_expr(data->search_string); 65 : RoutingInstanceMgr::const_name_iterator it1 = 66 1759 : rim->name_clower_bound(data->next_entry); 67 2415 : for (uint32_t iter_count = 0; it1 != rim->name_cend(); ++it1) { 68 2370 : const RoutingInstance *rtinstance = it1->second; 69 2370 : for (RoutingInstance::RouteTableList::const_iterator it2 = 70 2370 : rtinstance->GetTables().begin(); 71 14900 : it2 != rtinstance->GetTables().end(); ++it2, ++iter_count) { 72 12530 : const BgpTable *table = it2->second; 73 18620 : if ((!regex_search(table->name(), search_expr)) && 74 6090 : (data->search_string != "deleted" || !table->IsDeleted())) { 75 3310 : continue; 76 : } 77 9220 : ShowRouteTableSummary srts; 78 9220 : FillRouteTableSummaryInfo(&srts, bsc, table); 79 9220 : data->show_list.push_back(srts); 80 9220 : } 81 2370 : if (data->show_list.size() >= page_limit) 82 170 : break; 83 2200 : if (iter_count >= iter_limit) 84 1544 : break; 85 : } 86 : 87 : // All done if we've looked at all instances. 88 1759 : if (it1 == rim->name_cend() || ++it1 == rim->name_end()) 89 160 : return true; 90 : 91 : // Return true if we've reached the page limit, false if we've reached the 92 : // iteration limit. 93 1599 : bool done = data->show_list.size() >= page_limit; 94 1599 : SaveContextToData(it1->second->name(), done, data); 95 1599 : return done; 96 1759 : } 97 : 98 : // 99 : // Specialization of BgpShowHandler<>::FillShowList. 100 : // 101 : template <> 102 250 : void BgpShowHandler<ShowRouteSummaryReq, ShowRouteSummaryReqIterate, 103 : ShowRouteSummaryResp, ShowRouteTableSummary>::FillShowList( 104 : ShowRouteSummaryResp *resp, 105 : const vector<ShowRouteTableSummary> &show_list) { 106 250 : resp->set_tables(show_list); 107 250 : } 108 : 109 : // 110 : // Handler for ShowRouteSummaryReq. 111 : // 112 170 : void ShowRouteSummaryReq::HandleRequest() const { 113 170 : RequestPipeline::PipeSpec ps(this); 114 170 : RequestPipeline::StageSpec s1; 115 170 : TaskScheduler *scheduler = TaskScheduler::GetInstance(); 116 : 117 170 : s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); 118 : s1.cbFn_ = boost::bind(&BgpShowHandler< 119 : ShowRouteSummaryReq, 120 : ShowRouteSummaryReqIterate, 121 : ShowRouteSummaryResp, 122 170 : ShowRouteTableSummary>::Callback, _1, _2, _3, _4, _5); 123 : s1.allocFn_ = BgpShowHandler< 124 : ShowRouteSummaryReq, 125 : ShowRouteSummaryReqIterate, 126 : ShowRouteSummaryResp, 127 170 : ShowRouteTableSummary>::CreateData; 128 170 : s1.instances_.push_back(0); 129 170 : ps.stages_.push_back(s1); 130 170 : RequestPipeline rp(ps); 131 170 : } 132 : 133 : // 134 : // Handler for ShowRouteSummaryReqIterate. 135 : // 136 150 : void ShowRouteSummaryReqIterate::HandleRequest() const { 137 150 : RequestPipeline::PipeSpec ps(this); 138 150 : RequestPipeline::StageSpec s1; 139 150 : TaskScheduler *scheduler = TaskScheduler::GetInstance(); 140 : 141 150 : s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); 142 : s1.cbFn_ = boost::bind(&BgpShowHandler< 143 : ShowRouteSummaryReq, 144 : ShowRouteSummaryReqIterate, 145 : ShowRouteSummaryResp, 146 150 : ShowRouteTableSummary>::CallbackIterate, _1, _2, _3, _4, _5); 147 : s1.allocFn_ = BgpShowHandler< 148 : ShowRouteSummaryReq, 149 : ShowRouteSummaryReqIterate, 150 : ShowRouteSummaryResp, 151 150 : ShowRouteTableSummary>::CreateData; 152 150 : s1.instances_.push_back(0); 153 150 : ps.stages_.push_back(s1); 154 150 : RequestPipeline rp(ps); 155 150 : }