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