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