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