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/routing-instance/rtarget_group_mgr.h"
11 :
12 : using contrail::regex;
13 : using contrail::regex_match;
14 : using contrail::regex_search;
15 : using std::string;
16 : using std::vector;
17 :
18 : //
19 : // Fill in information for list of rtarget groups.
20 : //
21 : // Allows regular, summary and peer introspect to share code.
22 : // Assumes that search_string is the peer name if match_peer is true.
23 : //
24 503 : static bool FillRtGroupInfoList(const BgpSandeshContext *bsc,
25 : bool summary, bool match_peer, uint32_t page_limit, uint32_t iter_limit,
26 : const string &start_rtarget_str, const string &search_string,
27 : vector<ShowRtGroupInfo> *srtg_list, string *next_rtarget_str) {
28 503 : RouteTarget rtarget;
29 :
30 : // Bail if start_rtarget_str is bad.
31 503 : if (!start_rtarget_str.empty()) {
32 385 : rtarget = RouteTarget::FromString(start_rtarget_str);
33 385 : if (rtarget.IsNull())
34 0 : return true;
35 : }
36 :
37 : // Bail if there's no peer specified when doing a peer introspect.
38 503 : if (match_peer && search_string.empty())
39 1 : return true;
40 :
41 502 : regex search_expr(search_string);
42 502 : const RTargetGroupMgr *rtgroup_mgr = bsc->bgp_server->rtarget_group_mgr();
43 502 : RTargetGroupMgr::const_iterator it = rtgroup_mgr->lower_bound(rtarget);
44 3694 : for (uint32_t iter_count = 0; it != rtgroup_mgr->end();
45 3192 : ++it, ++iter_count) {
46 3594 : const RtGroup *rtgroup = it->second;
47 3594 : if (!match_peer && !regex_search(rtgroup->ToString(), search_expr))
48 1623 : continue;
49 2053 : ShowRtGroupInfo srtg;
50 2053 : if (match_peer) {
51 106 : if (!rtgroup->HasInterestedPeer(search_string))
52 82 : continue;
53 24 : rtgroup->FillShowPeerInfo(&srtg);
54 1947 : } else if (summary) {
55 62 : rtgroup->FillShowSummaryInfo(&srtg);
56 : } else {
57 1885 : rtgroup->FillShowInfo(&srtg);
58 : }
59 1971 : srtg_list->push_back(srtg);
60 1971 : if (srtg_list->size() >= page_limit)
61 80 : break;
62 1891 : if (iter_count >= iter_limit)
63 322 : break;
64 2053 : }
65 :
66 : // All done if we've looked at all rtarget groups.
67 502 : if (it == rtgroup_mgr->end() || ++it == rtgroup_mgr->end())
68 137 : return true;
69 :
70 : // Return true if we've reached the page limit, false if we've reached the
71 : // iteration limit.
72 365 : bool done = srtg_list->size() >= page_limit;
73 365 : *next_rtarget_str = it->second->ToString();
74 365 : return done;
75 502 : }
76 :
77 : //
78 : // Specialization of BgpShowHandler<>::CallbackCommon for regular introspect.
79 : //
80 : template <>
81 494 : bool BgpShowHandler<ShowRtGroupReq, ShowRtGroupReqIterate,
82 : ShowRtGroupResp, ShowRtGroupInfo>::CallbackCommon(
83 : const BgpSandeshContext *bsc, Data *data) {
84 494 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
85 494 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
86 494 : string next_rtarget_str;
87 988 : bool done = FillRtGroupInfoList(bsc, false, false, page_limit, iter_limit,
88 494 : data->next_entry, data->search_string, &data->show_list,
89 : &next_rtarget_str);
90 494 : if (!next_rtarget_str.empty())
91 365 : SaveContextToData(next_rtarget_str, done, data);
92 494 : return done;
93 494 : }
94 :
95 : //
96 : // Specialization of BgpShowHandler<>::FillShowList for regular introspect.
97 : //
98 : template <>
99 156 : void BgpShowHandler<ShowRtGroupReq, ShowRtGroupReqIterate,
100 : ShowRtGroupResp, ShowRtGroupInfo>::FillShowList(
101 : ShowRtGroupResp *resp,
102 : const vector<ShowRtGroupInfo> &show_list) {
103 156 : resp->set_rtgroup_list(show_list);
104 156 : }
105 :
106 : //
107 : // Specialization of BgpShowHandler<>::CallbackCommon for summary introspect.
108 : //
109 : template <>
110 3 : bool BgpShowHandler<ShowRtGroupSummaryReq, ShowRtGroupSummaryReqIterate,
111 : ShowRtGroupSummaryResp, ShowRtGroupInfo>::CallbackCommon(
112 : const BgpSandeshContext *bsc, Data *data) {
113 3 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
114 3 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
115 3 : string next_rtarget_str;
116 6 : bool done = FillRtGroupInfoList(bsc, true, false, page_limit, iter_limit,
117 3 : data->next_entry, data->search_string, &data->show_list,
118 : &next_rtarget_str);
119 3 : if (!next_rtarget_str.empty())
120 0 : SaveContextToData(next_rtarget_str, done, data);
121 3 : return done;
122 3 : }
123 :
124 : //
125 : // Specialization of BgpShowHandler<>::FillShowList for summary introspect.
126 : //
127 : template <>
128 3 : void BgpShowHandler<ShowRtGroupSummaryReq, ShowRtGroupSummaryReqIterate,
129 : ShowRtGroupSummaryResp, ShowRtGroupInfo>::FillShowList(
130 : ShowRtGroupSummaryResp *resp,
131 : const vector<ShowRtGroupInfo> &show_list) {
132 3 : resp->set_rtgroup_list(show_list);
133 3 : }
134 :
135 : //
136 : // Specialization of BgpShowHandler<>::CallbackCommon for peer introspect.
137 : //
138 : template <>
139 6 : bool BgpShowHandler<ShowRtGroupPeerReq, ShowRtGroupPeerReqIterate,
140 : ShowRtGroupPeerResp, ShowRtGroupInfo>::CallbackCommon(
141 : const BgpSandeshContext *bsc, Data *data) {
142 6 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
143 6 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
144 6 : string next_rtarget_str;
145 12 : bool done = FillRtGroupInfoList(bsc, false, true, page_limit, iter_limit,
146 6 : data->next_entry, data->search_string, &data->show_list,
147 : &next_rtarget_str);
148 6 : if (!next_rtarget_str.empty())
149 0 : SaveContextToData(next_rtarget_str, done, data);
150 6 : return done;
151 6 : }
152 :
153 : //
154 : // Specialization of BgpShowHandler<>::FillShowList for peer introspect.
155 : //
156 : template <>
157 2 : void BgpShowHandler<ShowRtGroupPeerReq, ShowRtGroupPeerReqIterate,
158 : ShowRtGroupPeerResp, ShowRtGroupInfo>::FillShowList(
159 : ShowRtGroupPeerResp *resp,
160 : const vector<ShowRtGroupInfo> &show_list) {
161 2 : resp->set_rtgroup_list(show_list);
162 2 : }
163 :
164 : //
165 : // Handler for ShowRtGroupReq.
166 : //
167 109 : void ShowRtGroupReq::HandleRequest() const {
168 109 : RequestPipeline::PipeSpec ps(this);
169 109 : RequestPipeline::StageSpec s1;
170 109 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
171 :
172 109 : s1.taskId_ = scheduler->GetTaskId("bgp::RTFilter");
173 : s1.cbFn_ = boost::bind(&BgpShowHandler<
174 : ShowRtGroupReq,
175 : ShowRtGroupReqIterate,
176 : ShowRtGroupResp,
177 109 : ShowRtGroupInfo>::Callback, _1, _2, _3, _4, _5);
178 : s1.allocFn_ = BgpShowHandler<
179 : ShowRtGroupReq,
180 : ShowRtGroupReqIterate,
181 : ShowRtGroupResp,
182 109 : ShowRtGroupInfo>::CreateData;
183 109 : s1.instances_.push_back(0);
184 109 : ps.stages_.push_back(s1);
185 109 : RequestPipeline rp(ps);
186 109 : }
187 :
188 : //
189 : // Handler for ShowRtGroupReqIterate.
190 : //
191 110 : void ShowRtGroupReqIterate::HandleRequest() const {
192 110 : RequestPipeline::PipeSpec ps(this);
193 110 : RequestPipeline::StageSpec s1;
194 110 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
195 :
196 110 : s1.taskId_ = scheduler->GetTaskId("bgp::RTFilter");
197 : s1.cbFn_ = boost::bind(&BgpShowHandler<
198 : ShowRtGroupReq,
199 : ShowRtGroupReqIterate,
200 : ShowRtGroupResp,
201 110 : ShowRtGroupInfo>::CallbackIterate, _1, _2, _3, _4, _5);
202 : s1.allocFn_ = BgpShowHandler<
203 : ShowRtGroupReq,
204 : ShowRtGroupReqIterate,
205 : ShowRtGroupResp,
206 110 : ShowRtGroupInfo>::CreateData;
207 110 : s1.instances_.push_back(0);
208 110 : ps.stages_.push_back(s1);
209 110 : RequestPipeline rp(ps);
210 110 : }
211 :
212 : //
213 : // Handler for ShowRtGroupSummaryReq.
214 : //
215 3 : void ShowRtGroupSummaryReq::HandleRequest() const {
216 3 : RequestPipeline::PipeSpec ps(this);
217 3 : RequestPipeline::StageSpec s1;
218 3 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
219 :
220 3 : s1.taskId_ = scheduler->GetTaskId("bgp::RTFilter");
221 : s1.cbFn_ = boost::bind(&BgpShowHandler<
222 : ShowRtGroupSummaryReq,
223 : ShowRtGroupSummaryReqIterate,
224 : ShowRtGroupSummaryResp,
225 3 : ShowRtGroupInfo>::Callback, _1, _2, _3, _4, _5);
226 : s1.allocFn_ = BgpShowHandler<
227 : ShowRtGroupSummaryReq,
228 : ShowRtGroupSummaryReqIterate,
229 : ShowRtGroupSummaryResp,
230 3 : ShowRtGroupInfo>::CreateData;
231 3 : s1.instances_.push_back(0);
232 3 : ps.stages_.push_back(s1);
233 3 : RequestPipeline rp(ps);
234 3 : }
235 :
236 : //
237 : // Handler for ShowRtGroupSummaryReqIterate.
238 : //
239 0 : void ShowRtGroupSummaryReqIterate::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::RTFilter");
245 : s1.cbFn_ = boost::bind(&BgpShowHandler<
246 : ShowRtGroupSummaryReq,
247 : ShowRtGroupSummaryReqIterate,
248 : ShowRtGroupSummaryResp,
249 0 : ShowRtGroupInfo>::CallbackIterate, _1, _2, _3, _4, _5);
250 : s1.allocFn_ = BgpShowHandler<
251 : ShowRtGroupSummaryReq,
252 : ShowRtGroupSummaryReqIterate,
253 : ShowRtGroupSummaryResp,
254 0 : ShowRtGroupInfo>::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 ShowRtGroupPeerReq.
262 : //
263 6 : void ShowRtGroupPeerReq::HandleRequest() const {
264 6 : RequestPipeline::PipeSpec ps(this);
265 6 : RequestPipeline::StageSpec s1;
266 6 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
267 :
268 6 : s1.taskId_ = scheduler->GetTaskId("bgp::RTFilter");
269 : s1.cbFn_ = boost::bind(&BgpShowHandler<
270 : ShowRtGroupPeerReq,
271 : ShowRtGroupPeerReqIterate,
272 : ShowRtGroupPeerResp,
273 6 : ShowRtGroupInfo>::Callback, _1, _2, _3, _4, _5);
274 : s1.allocFn_ = BgpShowHandler<
275 : ShowRtGroupPeerReq,
276 : ShowRtGroupPeerReqIterate,
277 : ShowRtGroupPeerResp,
278 6 : ShowRtGroupInfo>::CreateData;
279 6 : s1.instances_.push_back(0);
280 6 : ps.stages_.push_back(s1);
281 6 : RequestPipeline rp(ps);
282 6 : }
283 :
284 : //
285 : // Handler for ShowRtGroupPeerReqIterate.
286 : //
287 0 : void ShowRtGroupPeerReqIterate::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::RTFilter");
293 : s1.cbFn_ = boost::bind(&BgpShowHandler<
294 : ShowRtGroupPeerReq,
295 : ShowRtGroupPeerReqIterate,
296 : ShowRtGroupPeerResp,
297 0 : ShowRtGroupInfo>::CallbackIterate, _1, _2, _3, _4, _5);
298 : s1.allocFn_ = BgpShowHandler<
299 : ShowRtGroupPeerReq,
300 : ShowRtGroupPeerReqIterate,
301 : ShowRtGroupPeerResp,
302 0 : ShowRtGroupInfo>::CreateData;
303 0 : s1.instances_.push_back(0);
304 0 : ps.stages_.push_back(s1);
305 0 : RequestPipeline rp(ps);
306 0 : }
|