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