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