Line data Source code
1 : /*
2 : * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #include <boost/foreach.hpp>
7 : #include <boost/assign/list_of.hpp>
8 :
9 : #include "base/regex.h"
10 : #include "bgp/bgp_server.h"
11 : #include "bgp/bgp_show_handler.h"
12 : #include "bgp/routing-instance/routing_instance.h"
13 : #include "bgp/routing-instance/route_aggregator.h"
14 : #include "bgp/routing-instance/route_aggregate_internal_types.h"
15 : #include "bgp/routing-instance/route_aggregate_types.h"
16 :
17 : using boost::assign::list_of;
18 : using contrail::regex;
19 : using contrail::regex_match;
20 : using contrail::regex_search;
21 : using std::string;
22 : using std::vector;
23 :
24 84 : static bool FillRouteAggregateInfoList(const BgpSandeshContext *bsc,
25 : bool summary, uint32_t page_limit, uint32_t iter_limit,
26 : const string &start_instance, const string &search_string,
27 : vector<AggregateRouteEntriesInfo> *are_list, string *next_instance) {
28 84 : regex search_expr(search_string);
29 84 : RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr();
30 : RoutingInstanceMgr::const_name_iterator it =
31 84 : rim->name_clower_bound(start_instance);
32 264 : for (uint32_t iter_count = 0; it != rim->name_cend(); ++it, ++iter_count) {
33 180 : RoutingInstance *rtinstance = it->second;
34 :
35 : vector<Address::Family> families =
36 180 : list_of(Address::INET)(Address::INET6);
37 900 : BOOST_FOREACH(Address::Family family, families) {
38 : const BgpTable *table =
39 360 : static_cast<const BgpTable *>(rtinstance->GetTable(family));
40 360 : if (!table)
41 284 : continue;
42 554 : if ((!regex_search(table->name(), search_expr)) &&
43 196 : (search_string != "deleted" || !table->IsDeleted())) {
44 196 : continue;
45 : }
46 :
47 : IRouteAggregator *iroute_aggregator =
48 162 : rtinstance->route_aggregator(family);
49 162 : if (!iroute_aggregator)
50 80 : continue;
51 82 : AggregateRouteEntriesInfo info;
52 82 : if (!iroute_aggregator->FillAggregateRouteInfo(&info, summary))
53 6 : continue;
54 76 : are_list->push_back(info);
55 82 : }
56 :
57 180 : if (are_list->size() >= page_limit)
58 0 : break;
59 180 : if (iter_count >= iter_limit)
60 0 : break;
61 180 : }
62 :
63 : // All done if we've looked at all instances.
64 84 : if (it == rim->name_cend() || ++it == rim->name_cend())
65 84 : return true;
66 :
67 : // Return true if we've reached the page limit, false if we've reached the
68 : // iteration limit.
69 0 : bool done = are_list->size() >= page_limit;
70 0 : *next_instance = it->second->name();
71 0 : return done;
72 84 : }
73 :
74 : //
75 : // Specialization of BgpShowHandler<>::CallbackCommon for regular introspect.
76 : //
77 : template <>
78 42 : bool BgpShowHandler<ShowRouteAggregateReq,
79 : ShowRouteAggregateReqIterate, ShowRouteAggregateResp,
80 : AggregateRouteEntriesInfo>::CallbackCommon(
81 : const BgpSandeshContext *bsc, Data *data) {
82 42 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
83 42 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
84 42 : string next_instance;
85 84 : bool done = FillRouteAggregateInfoList(bsc, false, page_limit, iter_limit,
86 42 : data->next_entry, data->search_string, &data->show_list,
87 : &next_instance);
88 42 : if (!next_instance.empty())
89 0 : SaveContextToData(next_instance, done, data);
90 42 : return done;
91 42 : }
92 :
93 : //
94 : // Specialization of BgpShowHandler<>::FillShowList for regular introspect.
95 : //
96 : template <>
97 38 : void BgpShowHandler<ShowRouteAggregateReq,
98 : ShowRouteAggregateReqIterate, ShowRouteAggregateResp,
99 : AggregateRouteEntriesInfo>::FillShowList(
100 : ShowRouteAggregateResp *resp,
101 : const vector<AggregateRouteEntriesInfo> &show_list) {
102 38 : resp->set_aggregate_route_entries(show_list);
103 38 : }
104 :
105 : //
106 : // Specialization of BgpShowHandler<>::CallbackCommon for summary introspect.
107 : //
108 : template <>
109 42 : bool BgpShowHandler<ShowRouteAggregateSummaryReq,
110 : ShowRouteAggregateSummaryReqIterate, ShowRouteAggregateSummaryResp,
111 : AggregateRouteEntriesInfo>::CallbackCommon(
112 : const BgpSandeshContext *bsc, Data *data) {
113 42 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
114 42 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
115 42 : string next_instance;
116 84 : bool done = FillRouteAggregateInfoList(bsc, true, page_limit, iter_limit,
117 42 : data->next_entry, data->search_string, &data->show_list,
118 : &next_instance);
119 42 : if (!next_instance.empty())
120 0 : SaveContextToData(next_instance, done, data);
121 42 : return done;
122 42 : }
123 :
124 : //
125 : // Specialization of BgpShowHandler<>::FillShowList for summary introspect.
126 : //
127 : template <>
128 38 : void BgpShowHandler<ShowRouteAggregateSummaryReq,
129 : ShowRouteAggregateSummaryReqIterate, ShowRouteAggregateSummaryResp,
130 : AggregateRouteEntriesInfo>::FillShowList(
131 : ShowRouteAggregateSummaryResp *resp,
132 : const vector<AggregateRouteEntriesInfo> &show_list) {
133 38 : resp->set_aggregate_route_entries(show_list);
134 38 : }
135 :
136 : //
137 : // Handler for ShowRouteAggregateReq.
138 : //
139 42 : void ShowRouteAggregateReq::HandleRequest() const {
140 42 : RequestPipeline::PipeSpec ps(this);
141 42 : RequestPipeline::StageSpec s1;
142 42 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
143 :
144 42 : s1.taskId_ = scheduler->GetTaskId("bgp::RouteAggregate");
145 : s1.cbFn_ = boost::bind(&BgpShowHandler<
146 : ShowRouteAggregateReq,
147 : ShowRouteAggregateReqIterate,
148 : ShowRouteAggregateResp,
149 42 : AggregateRouteEntriesInfo>::Callback, _1, _2, _3, _4, _5);
150 : s1.allocFn_ = BgpShowHandler<
151 : ShowRouteAggregateReq,
152 : ShowRouteAggregateReqIterate,
153 : ShowRouteAggregateResp,
154 42 : AggregateRouteEntriesInfo>::CreateData;
155 42 : s1.instances_.push_back(0);
156 42 : ps.stages_.push_back(s1);
157 42 : RequestPipeline rp(ps);
158 42 : }
159 :
160 : //
161 : // Handler for ShowRouteAggregateReqIterate.
162 : //
163 0 : void ShowRouteAggregateReqIterate::HandleRequest() const {
164 0 : RequestPipeline::PipeSpec ps(this);
165 0 : RequestPipeline::StageSpec s1;
166 0 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
167 :
168 0 : s1.taskId_ = scheduler->GetTaskId("bgp::RouteAggregate");
169 : s1.cbFn_ = boost::bind(&BgpShowHandler<
170 : ShowRouteAggregateReq,
171 : ShowRouteAggregateReqIterate,
172 : ShowRouteAggregateResp,
173 0 : AggregateRouteEntriesInfo>::CallbackIterate, _1, _2, _3, _4, _5);
174 : s1.allocFn_ = BgpShowHandler<
175 : ShowRouteAggregateReq,
176 : ShowRouteAggregateReqIterate,
177 : ShowRouteAggregateResp,
178 0 : AggregateRouteEntriesInfo>::CreateData;
179 0 : s1.instances_.push_back(0);
180 0 : ps.stages_.push_back(s1);
181 0 : RequestPipeline rp(ps);
182 0 : }
183 :
184 : //
185 : // Handler for ShowRouteAggregateSummaryReq.
186 : //
187 42 : void ShowRouteAggregateSummaryReq::HandleRequest() const {
188 42 : RequestPipeline::PipeSpec ps(this);
189 42 : RequestPipeline::StageSpec s1;
190 42 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
191 :
192 42 : s1.taskId_ = scheduler->GetTaskId("bgp::RouteAggregate");
193 : s1.cbFn_ = boost::bind(&BgpShowHandler<
194 : ShowRouteAggregateSummaryReq,
195 : ShowRouteAggregateSummaryReqIterate,
196 : ShowRouteAggregateSummaryResp,
197 42 : AggregateRouteEntriesInfo>::Callback, _1, _2, _3, _4, _5);
198 : s1.allocFn_ = BgpShowHandler<
199 : ShowRouteAggregateSummaryReq,
200 : ShowRouteAggregateSummaryReqIterate,
201 : ShowRouteAggregateSummaryResp,
202 42 : AggregateRouteEntriesInfo>::CreateData;
203 42 : s1.instances_.push_back(0);
204 42 : ps.stages_.push_back(s1);
205 42 : RequestPipeline rp(ps);
206 42 : }
207 :
208 : //
209 : // Handler for ShowRouteAggregateSummaryReqIterate.
210 : //
211 0 : void ShowRouteAggregateSummaryReqIterate::HandleRequest() const {
212 0 : RequestPipeline::PipeSpec ps(this);
213 0 : RequestPipeline::StageSpec s1;
214 0 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
215 :
216 0 : s1.taskId_ = scheduler->GetTaskId("bgp::RouteAggregate");
217 : s1.cbFn_ = boost::bind(&BgpShowHandler<
218 : ShowRouteAggregateSummaryReq,
219 : ShowRouteAggregateSummaryReqIterate,
220 : ShowRouteAggregateSummaryResp,
221 0 : AggregateRouteEntriesInfo>::CallbackIterate, _1, _2, _3, _4, _5);
222 : s1.allocFn_ = BgpShowHandler<
223 : ShowRouteAggregateSummaryReq,
224 : ShowRouteAggregateSummaryReqIterate,
225 : ShowRouteAggregateSummaryResp,
226 0 : AggregateRouteEntriesInfo>::CreateData;
227 0 : s1.instances_.push_back(0);
228 0 : ps.stages_.push_back(s1);
229 0 : RequestPipeline rp(ps);
230 0 : }
|