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_evpn.h"
9 : #include "bgp/bgp_peer_internal_types.h"
10 : #include "bgp/bgp_server.h"
11 : #include "bgp/evpn/evpn_table.h"
12 : #include "bgp/routing-instance/routing_instance.h"
13 :
14 : using contrail::regex;
15 : using contrail::regex_match;
16 : using contrail::regex_search;
17 : using std::string;
18 : using std::vector;
19 :
20 : //
21 : // Used by EvpnManager::FillShowInfo for sorting.
22 : // Note that the declaration is auto-generated by sandesh compiler.
23 : //
24 0 : bool ShowEvpnMcastLeaf::operator<(const ShowEvpnMcastLeaf &rhs) const {
25 0 : return get_address() < rhs.get_address();
26 : }
27 :
28 : //
29 : // Fill in information for an evpn table.
30 : //
31 420 : static void FillEvpnTableInfo(ShowEvpnTable *sevt,
32 : const BgpSandeshContext *bsc, const EvpnTable *table, bool summary) {
33 420 : sevt->set_name(table->name());
34 420 : sevt->set_deleted(table->IsDeleted());
35 420 : sevt->set_deleted_at(
36 840 : UTCUsecToString(table->deleter()->delete_time_stamp_usecs()));
37 420 : sevt->set_mac_routes(table->mac_route_count());
38 420 : sevt->set_unique_mac_routes(table->unique_mac_route_count());
39 420 : sevt->set_im_routes(table->im_route_count());
40 420 : sevt->set_ip_routes(table->ip_route_count());
41 :
42 420 : if (summary || table->IsVpnTable() || !table->GetEvpnManager())
43 230 : return;
44 190 : table->GetEvpnManager()->FillShowInfo(sevt);
45 : }
46 :
47 : //
48 : // Fill in information for list of evpn tables.
49 : //
50 : // Allows regular and summary introspect to share code.
51 : //
52 82 : static bool FillEvpnTableInfoList(const BgpSandeshContext *bsc,
53 : bool summary, uint32_t page_limit, uint32_t iter_limit,
54 : const string &start_instance, const string &search_string,
55 : vector<ShowEvpnTable> *sevt_list, string *next_instance) {
56 82 : regex search_expr(search_string);
57 82 : RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr();
58 : RoutingInstanceMgr::const_name_iterator it =
59 82 : rim->name_clower_bound(start_instance);
60 612 : for (uint32_t iter_count = 0; it != rim->name_cend(); ++it, ++iter_count) {
61 580 : const RoutingInstance *rtinstance = it->second;
62 : const EvpnTable *table =
63 580 : static_cast<const EvpnTable *>(rtinstance->GetTable(Address::EVPN));
64 580 : if (!table)
65 160 : continue;
66 824 : if ((!regex_search(table->name(), search_expr)) &&
67 244 : (search_string != "deleted" || !table->IsDeleted())) {
68 160 : continue;
69 : }
70 420 : ShowEvpnTable sevt;
71 420 : FillEvpnTableInfo(&sevt, bsc, table, summary);
72 420 : sevt_list->push_back(sevt);
73 420 : if (sevt_list->size() >= page_limit)
74 26 : break;
75 394 : if (iter_count >= iter_limit)
76 24 : break;
77 420 : }
78 :
79 : // All done if we've looked at all instances.
80 82 : if (it == rim->name_cend() || ++it == rim->name_end())
81 38 : return true;
82 :
83 : // Return true if we've reached the page limit, false if we've reached the
84 : // iteration limit.
85 44 : bool done = sevt_list->size() >= page_limit;
86 44 : *next_instance = it->second->name();
87 44 : return done;
88 82 : }
89 :
90 : //
91 : // Specialization of BgpShowHandler<>::CallbackCommon for regular introspect.
92 : //
93 : template <>
94 41 : bool BgpShowHandler<ShowEvpnTableReq, ShowEvpnTableReqIterate,
95 : ShowEvpnTableResp, ShowEvpnTable>::CallbackCommon(
96 : const BgpSandeshContext *bsc, Data *data) {
97 41 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
98 41 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
99 41 : string next_instance;
100 82 : bool done = FillEvpnTableInfoList(bsc, false, page_limit, iter_limit,
101 41 : data->next_entry, data->search_string, &data->show_list,
102 : &next_instance);
103 41 : if (!next_instance.empty())
104 22 : SaveContextToData(next_instance, done, data);
105 41 : return done;
106 41 : }
107 :
108 : //
109 : // Specialization of BgpShowHandler<>::FillShowList for regular introspect.
110 : //
111 : template <>
112 24 : void BgpShowHandler<ShowEvpnTableReq, ShowEvpnTableReqIterate,
113 : ShowEvpnTableResp, ShowEvpnTable>::FillShowList(
114 : ShowEvpnTableResp *resp, const vector<ShowEvpnTable> &show_list) {
115 24 : resp->set_tables(show_list);
116 24 : }
117 :
118 : //
119 : // Specialization of BgpShowHandler<>::CallbackCommon for summary introspect.
120 : //
121 : template <>
122 41 : bool BgpShowHandler<ShowEvpnTableSummaryReq, ShowEvpnTableSummaryReqIterate,
123 : ShowEvpnTableSummaryResp, ShowEvpnTable>::CallbackCommon(
124 : const BgpSandeshContext *bsc, Data *data) {
125 41 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
126 41 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
127 41 : string next_instance;
128 82 : bool done = FillEvpnTableInfoList(bsc, true, page_limit, iter_limit,
129 41 : data->next_entry, data->search_string, &data->show_list,
130 : &next_instance);
131 41 : if (!next_instance.empty())
132 22 : SaveContextToData(next_instance, done, data);
133 41 : return done;
134 41 : }
135 :
136 : //
137 : // Specialization of BgpShowHandler<>::FillShowList for summary introspect.
138 : //
139 : template <>
140 24 : void BgpShowHandler<ShowEvpnTableSummaryReq, ShowEvpnTableSummaryReqIterate,
141 : ShowEvpnTableSummaryResp, ShowEvpnTable>::FillShowList(
142 : ShowEvpnTableSummaryResp *resp, const vector<ShowEvpnTable> &show_list) {
143 24 : resp->set_tables(show_list);
144 24 : }
145 :
146 : //
147 : // Handler for ShowEvpnTableReq.
148 : // Schedules the callback to run in Task ("db::DBTable", 0) so that multicast
149 : // data structures in EvpnManager can be accessed safely.
150 : //
151 16 : void ShowEvpnTableReq::HandleRequest() const {
152 16 : RequestPipeline::PipeSpec ps(this);
153 16 : RequestPipeline::StageSpec s1;
154 16 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
155 :
156 16 : s1.taskId_ = scheduler->GetTaskId("db::DBTable");
157 : s1.cbFn_ = boost::bind(&BgpShowHandler<
158 : ShowEvpnTableReq,
159 : ShowEvpnTableReqIterate,
160 : ShowEvpnTableResp,
161 16 : ShowEvpnTable>::Callback, _1, _2, _3, _4, _5);
162 : s1.allocFn_ = BgpShowHandler<
163 : ShowEvpnTableReq,
164 : ShowEvpnTableReqIterate,
165 : ShowEvpnTableResp,
166 16 : ShowEvpnTable>::CreateData;
167 16 : s1.instances_.push_back(0);
168 16 : ps.stages_.push_back(s1);
169 16 : RequestPipeline rp(ps);
170 16 : }
171 :
172 : //
173 : // Handler for ShowEvpnTableReqIterate.
174 : // Schedules the callback to run in Task ("db::DBTable", 0) so that multicast
175 : // data structures in EvpnManager can be accessed safely.
176 : //
177 16 : void ShowEvpnTableReqIterate::HandleRequest() const {
178 16 : RequestPipeline::PipeSpec ps(this);
179 16 : RequestPipeline::StageSpec s1;
180 16 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
181 :
182 16 : s1.taskId_ = scheduler->GetTaskId("db::DBTable");
183 : s1.cbFn_ = boost::bind(&BgpShowHandler<
184 : ShowEvpnTableReq,
185 : ShowEvpnTableReqIterate,
186 : ShowEvpnTableResp,
187 16 : ShowEvpnTable>::CallbackIterate, _1, _2, _3, _4, _5);
188 : s1.allocFn_ = BgpShowHandler<
189 : ShowEvpnTableReq,
190 : ShowEvpnTableReqIterate,
191 : ShowEvpnTableResp,
192 16 : ShowEvpnTable>::CreateData;
193 16 : s1.instances_.push_back(0);
194 16 : ps.stages_.push_back(s1);
195 16 : RequestPipeline rp(ps);
196 16 : }
197 :
198 : //
199 : // Handler for ShowEvpnTableSummaryReq.
200 : // Schedules the callback to run in Task ("db::DBTable", 0) so that multicast
201 : // data structures in EvpnManager can be accessed safely. This is not really
202 : // necessary for summary requests, but we do this for consistency with regular
203 : // requests.
204 : //
205 16 : void ShowEvpnTableSummaryReq::HandleRequest() const {
206 16 : RequestPipeline::PipeSpec ps(this);
207 16 : RequestPipeline::StageSpec s1;
208 16 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
209 :
210 16 : s1.taskId_ = scheduler->GetTaskId("db::DBTable");
211 : s1.cbFn_ = boost::bind(&BgpShowHandler<
212 : ShowEvpnTableSummaryReq,
213 : ShowEvpnTableSummaryReqIterate,
214 : ShowEvpnTableSummaryResp,
215 16 : ShowEvpnTable>::Callback, _1, _2, _3, _4, _5);
216 : s1.allocFn_ = BgpShowHandler<
217 : ShowEvpnTableSummaryReq,
218 : ShowEvpnTableSummaryReqIterate,
219 : ShowEvpnTableSummaryResp,
220 16 : ShowEvpnTable>::CreateData;
221 16 : s1.instances_.push_back(0);
222 16 : ps.stages_.push_back(s1);
223 16 : RequestPipeline rp(ps);
224 16 : }
225 :
226 : //
227 : // Handler for ShowEvpnTableSummaryReqIterate.
228 : // Schedules the callback to run in Task ("db::DBTable", 0) so that multicast
229 : // data structures in EvpnManager can be accessed safely. This is not really
230 : // necessary for summary requests, but we do this for consistency with regular
231 : // requests.
232 : //
233 16 : void ShowEvpnTableSummaryReqIterate::HandleRequest() const {
234 16 : RequestPipeline::PipeSpec ps(this);
235 16 : RequestPipeline::StageSpec s1;
236 16 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
237 :
238 16 : s1.taskId_ = scheduler->GetTaskId("db::DBTable");
239 : s1.cbFn_ = boost::bind(&BgpShowHandler<
240 : ShowEvpnTableSummaryReq,
241 : ShowEvpnTableSummaryReqIterate,
242 : ShowEvpnTableSummaryResp,
243 16 : ShowEvpnTable>::CallbackIterate, _1, _2, _3, _4, _5);
244 : s1.allocFn_ = BgpShowHandler<
245 : ShowEvpnTableSummaryReq,
246 : ShowEvpnTableSummaryReqIterate,
247 : ShowEvpnTableSummaryResp,
248 16 : ShowEvpnTable>::CreateData;
249 16 : s1.instances_.push_back(0);
250 16 : ps.stages_.push_back(s1);
251 16 : RequestPipeline rp(ps);
252 16 : }
|