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 "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/bgp_table.h"
12 : #include "bgp/routing-instance/path_resolver.h"
13 : #include "bgp/routing-instance/routing_instance.h"
14 :
15 : using contrail::regex;
16 : using contrail::regex_match;
17 : using contrail::regex_search;
18 : using std::string;
19 : using std::vector;
20 :
21 : //
22 : // Fill in information for list of path resolvers.
23 : //
24 : // Allows regular and summary introspect to share code.
25 : //
26 16 : static bool FillPathResolverInfoList(const BgpSandeshContext *bsc,
27 : bool summary, uint32_t page_limit, uint32_t iter_limit,
28 : const string &start_instance, const string &search_string,
29 : vector<ShowPathResolver> *spr_list, string *next_instance) {
30 16 : regex search_expr(search_string);
31 16 : RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr();
32 : RoutingInstanceMgr::const_name_iterator it1 =
33 16 : rim->name_clower_bound(start_instance);
34 64 : for (uint32_t iter_count = 0; it1 != rim->name_cend();
35 48 : ++it1, ++iter_count) {
36 48 : const RoutingInstance *rtinstance = it1->second;
37 48 : for (RoutingInstance::RouteTableList::const_iterator it2 =
38 48 : rtinstance->GetTables().begin();
39 352 : it2 != rtinstance->GetTables().end(); ++it2, ++iter_count) {
40 304 : const BgpTable *table = it2->second;
41 528 : if ((!regex_search(table->name(), search_expr)) &&
42 224 : (search_string != "deleted" || !table->IsDeleted())) {
43 288 : continue;
44 : }
45 80 : const PathResolver *path_resolver = table->path_resolver();
46 80 : if (!path_resolver)
47 16 : continue;
48 64 : ShowPathResolver spr;
49 64 : path_resolver->FillShowInfo(&spr, summary);
50 112 : if (spr.get_path_count() == 0 &&
51 96 : spr.get_modified_path_count() == 0 &&
52 160 : spr.get_nexthop_count() == 0 &&
53 48 : spr.get_modified_nexthop_count() == 0)
54 48 : continue;
55 16 : spr_list->push_back(spr);
56 64 : }
57 48 : if (spr_list->size() >= page_limit)
58 0 : break;
59 48 : if (iter_count >= iter_limit)
60 0 : break;
61 : }
62 :
63 : // All done if we've looked at all instances.
64 16 : if (it1 == rim->name_cend() || ++it1 == rim->name_end())
65 16 : 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 = spr_list->size() >= page_limit;
70 0 : *next_instance = it1->second->name();
71 0 : return done;
72 16 : }
73 :
74 : //
75 : // Specialization of BgpShowHandler<>::CallbackCommon for regular introspect.
76 : //
77 : template <>
78 8 : bool BgpShowHandler<ShowPathResolverReq, ShowPathResolverReqIterate,
79 : ShowPathResolverResp, ShowPathResolver>::CallbackCommon(
80 : const BgpSandeshContext *bsc, Data *data) {
81 8 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
82 8 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
83 8 : string next_instance;
84 16 : bool done = FillPathResolverInfoList(bsc, false, page_limit, iter_limit,
85 8 : data->next_entry, data->search_string, &data->show_list,
86 : &next_instance);
87 8 : if (!next_instance.empty())
88 0 : SaveContextToData(next_instance, done, data);
89 8 : return done;
90 8 : }
91 :
92 : //
93 : // Specialization of BgpShowHandler<>::FillShowList for regular introspect.
94 : //
95 : template <>
96 8 : void BgpShowHandler<ShowPathResolverReq,
97 : ShowPathResolverReqIterate, ShowPathResolverResp,
98 : ShowPathResolver>::FillShowList(ShowPathResolverResp *resp,
99 : const vector<ShowPathResolver> &show_list) {
100 8 : resp->set_resolvers(show_list);
101 8 : }
102 :
103 : //
104 : // Specialization of BgpShowHandler<>::CallbackCommon for summary introspect.
105 : //
106 : template <>
107 8 : bool BgpShowHandler<ShowPathResolverSummaryReq,
108 : ShowPathResolverSummaryReqIterate, ShowPathResolverSummaryResp,
109 : ShowPathResolver>::CallbackCommon(
110 : const BgpSandeshContext *bsc, Data *data) {
111 8 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
112 8 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
113 8 : string next_instance;
114 16 : bool done = FillPathResolverInfoList(bsc, true, page_limit, iter_limit,
115 8 : data->next_entry, data->search_string, &data->show_list,
116 : &next_instance);
117 8 : if (!next_instance.empty())
118 0 : SaveContextToData(next_instance, done, data);
119 8 : return done;
120 8 : }
121 :
122 : //
123 : // Specialization of BgpShowHandler<>::FillShowList for summary introspect.
124 : //
125 : template <>
126 8 : void BgpShowHandler<ShowPathResolverSummaryReq,
127 : ShowPathResolverSummaryReqIterate, ShowPathResolverSummaryResp,
128 : ShowPathResolver>::FillShowList(ShowPathResolverSummaryResp *resp,
129 : const vector<ShowPathResolver> &show_list) {
130 8 : resp->set_resolvers(show_list);
131 8 : }
132 :
133 : //
134 : // Handler for ShowPathResolverReq.
135 : //
136 8 : void ShowPathResolverReq::HandleRequest() const {
137 8 : RequestPipeline::PipeSpec ps(this);
138 8 : RequestPipeline::StageSpec s1;
139 8 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
140 :
141 8 : s1.taskId_ = scheduler->GetTaskId("bgp::ResolverNexthop");
142 : s1.cbFn_ = boost::bind(&BgpShowHandler<
143 : ShowPathResolverReq,
144 : ShowPathResolverReqIterate,
145 : ShowPathResolverResp,
146 8 : ShowPathResolver>::Callback, _1, _2, _3, _4, _5);
147 : s1.allocFn_ = BgpShowHandler<
148 : ShowPathResolverReq,
149 : ShowPathResolverReqIterate,
150 : ShowPathResolverResp,
151 8 : ShowPathResolver>::CreateData;
152 8 : s1.instances_.push_back(0);
153 8 : ps.stages_.push_back(s1);
154 8 : RequestPipeline rp(ps);
155 8 : }
156 :
157 : //
158 : // Handler for ShowPathResolverReqIterate.
159 : //
160 0 : void ShowPathResolverReqIterate::HandleRequest() const {
161 0 : RequestPipeline::PipeSpec ps(this);
162 0 : RequestPipeline::StageSpec s1;
163 0 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
164 :
165 0 : s1.taskId_ = scheduler->GetTaskId("bgp::ResolverNexthop");
166 : s1.cbFn_ = boost::bind(&BgpShowHandler<
167 : ShowPathResolverReq,
168 : ShowPathResolverReqIterate,
169 : ShowPathResolverResp,
170 0 : ShowPathResolver>::CallbackIterate, _1, _2, _3, _4, _5);
171 : s1.allocFn_ = BgpShowHandler<
172 : ShowPathResolverReq,
173 : ShowPathResolverReqIterate,
174 : ShowPathResolverResp,
175 0 : ShowPathResolver>::CreateData;
176 0 : s1.instances_.push_back(0);
177 0 : ps.stages_.push_back(s1);
178 0 : RequestPipeline rp(ps);
179 0 : }
180 :
181 : //
182 : // Handler for ShowPathResolverSummaryReq.
183 : //
184 8 : void ShowPathResolverSummaryReq::HandleRequest() const {
185 8 : RequestPipeline::PipeSpec ps(this);
186 8 : RequestPipeline::StageSpec s1;
187 8 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
188 :
189 8 : s1.taskId_ = scheduler->GetTaskId("bgp::ResolverNexthop");
190 : s1.cbFn_ = boost::bind(&BgpShowHandler<
191 : ShowPathResolverSummaryReq,
192 : ShowPathResolverSummaryReqIterate,
193 : ShowPathResolverSummaryResp,
194 8 : ShowPathResolver>::Callback, _1, _2, _3, _4, _5);
195 : s1.allocFn_ = BgpShowHandler<
196 : ShowPathResolverSummaryReq,
197 : ShowPathResolverSummaryReqIterate,
198 : ShowPathResolverSummaryResp,
199 8 : ShowPathResolver>::CreateData;
200 8 : s1.instances_.push_back(0);
201 8 : ps.stages_.push_back(s1);
202 8 : RequestPipeline rp(ps);
203 8 : }
204 :
205 : //
206 : // Handler for ShowPathResolverSummaryReqIterate.
207 : //
208 0 : void ShowPathResolverSummaryReqIterate::HandleRequest() const {
209 0 : RequestPipeline::PipeSpec ps(this);
210 0 : RequestPipeline::StageSpec s1;
211 0 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
212 :
213 0 : s1.taskId_ = scheduler->GetTaskId("bgp::ResolverNexthop");
214 : s1.cbFn_ = boost::bind(&BgpShowHandler<
215 : ShowPathResolverSummaryReq,
216 : ShowPathResolverSummaryReqIterate,
217 : ShowPathResolverSummaryResp,
218 0 : ShowPathResolver>::CallbackIterate, _1, _2, _3, _4, _5);
219 : s1.allocFn_ = BgpShowHandler<
220 : ShowPathResolverSummaryReq,
221 : ShowPathResolverSummaryReqIterate,
222 : ShowPathResolverSummaryResp,
223 0 : ShowPathResolver>::CreateData;
224 0 : s1.instances_.push_back(0);
225 0 : ps.stages_.push_back(s1);
226 0 : RequestPipeline rp(ps);
227 0 : }
|