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