OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bgp_show_route.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "bgp/bgp_sandesh.h"
6 #include "bgp/bgp_show_route.h"
7 
8 #include <boost/assign/list_of.hpp>
9 #include <sandesh/request_pipeline.h>
10 
11 #include "base/regex.h"
12 #include "bgp/bgp_peer_internal_types.h"
13 #include "bgp/bgp_route.h"
14 #include "bgp/bgp_server.h"
15 #include "bgp/bgp_table.h"
17 
18 using boost::assign::list_of;
19 using std::unique_ptr;
20 using std::string;
21 using std::vector;
22 
23 static bool IsLess(const ShowRoute &lhs, const ShowRoute &rhs,
24  const BgpSandeshContext *bsc, const string &table_name) {
25  BgpTable *table = static_cast<BgpTable *>
26  (bsc->bgp_server->database()->FindTable(table_name));
27  if (!table) {
28  return false;
29  }
30  unique_ptr<DBEntry> lhs_entry = table->AllocEntryStr(lhs.get_prefix());
31  unique_ptr<DBEntry> rhs_entry = table->AllocEntryStr(rhs.get_prefix());
32 
33  Route *lhs_route = static_cast<Route *>(lhs_entry.get());
34  Route *rhs_route = static_cast<Route *>(rhs_entry.get());
35 
36  return lhs_route->IsLess(*rhs_route);
37 }
38 
39 static bool IsLess(const ShowRouteTable &lhs, const ShowRouteTable &rhs,
40  const BgpSandeshContext *bsc, const string &table_name) {
41  if (lhs.get_routing_instance() < rhs.get_routing_instance()) {
42  return true;
43  }
44  if (lhs.get_routing_instance() == rhs.get_routing_instance()) {
45  return lhs.get_routing_table_name() < rhs.get_routing_table_name();
46  }
47  return false;
48 }
49 
50 template <class T>
51 void MergeSort(vector<T> *result, vector<const vector<T> *> *input, int limit,
52  const BgpSandeshContext *bsc, const string &table_name);
53 
54 int MergeValues(ShowRoute *result, vector<const ShowRoute *> *input,
55  int limit, const BgpSandeshContext *bsc) {
56  assert(input->size() == 1);
57  *result = *input->at(0);
58  return 1;
59 }
60 
61 int MergeValues(ShowRouteTable *result, vector<const ShowRouteTable *> *input,
62  int limit, const BgpSandeshContext *bsc) {
63  vector<const vector<ShowRoute> *> list;
64  result->set_routing_instance(input->at(0)->get_routing_instance());
65  result->set_routing_table_name(input->at(0)->get_routing_table_name());
66  result->set_deleted(input->at(0)->get_deleted());
67  result->set_deleted_at(input->at(0)->get_deleted_at());
68  result->set_prefixes(input->at(0)->get_prefixes());
69  result->set_primary_paths(input->at(0)->get_primary_paths());
70  result->set_secondary_paths(input->at(0)->get_secondary_paths());
71  result->set_infeasible_paths(input->at(0)->get_infeasible_paths());
72  result->set_stale_paths(input->at(0)->get_stale_paths());
73  result->set_llgr_stale_paths(input->at(0)->get_llgr_stale_paths());
74  result->set_paths(input->at(0)->get_paths());
75  result->set_listeners(input->at(0)->get_listeners());
76 
77  int count = 0;
78  for (size_t i = 0; i < input->size(); ++i) {
79  if (input->at(i)->get_routes().size())
80  list.push_back(&input->at(i)->get_routes());
81  }
82  MergeSort(const_cast<vector<ShowRoute> *>(&result->get_routes()), &list,
83  limit ? limit - count : 0, bsc,
84  input->at(0)->get_routing_table_name());
85  count += result->get_routes().size();
86  return count;
87 }
88 
89 //
90 // Merge n number of vectors in result.
91 // Input is a vector of pointers to vector.
92 //
93 template <class T>
94 void MergeSort(vector<T> *result, vector<const vector<T> *> *input, int limit,
95  const BgpSandeshContext *bsc, const string &table_name) {
96  size_t size = input->size();
97  vector<size_t> index(size, 0);
98  int count = 0;
99  while (limit == 0 || count < limit) {
100  size_t best_index = size;
101  const T *best = NULL;
102  for (size_t i = 0; i < size; ++i) {
103  if (index[i] == input->at(i)->size())
104  continue;
105  if (best == NULL ||
106  IsLess(input->at(i)->at(index[i]), *best, bsc, table_name)) {
107  best = &input->at(i)->at(index[i]);
108  best_index = i;
109  continue;
110  }
111  }
112  if (best_index >= size)
113  break;
114  T table;
115  vector<const T *> list;
116  for (size_t j = best_index; j < size; ++j) {
117  if (index[j] == input->at(j)->size())
118  continue;
119  if (IsLess(input->at(j)->at(index[j]), *best, bsc, table_name) ||
120  IsLess(*best, input->at(j)->at(index[j]), bsc, table_name)) {
121  continue;
122  }
123  list.push_back(&input->at(j)->at(index[j]));
124  index[j]++;
125  }
126  count += MergeValues(&table, &list, limit ? limit - count : 0, bsc);
127  result->push_back(table);
128  }
129 }
130 
132 uint32_t ShowRouteHandler::GetMaxCount(bool test_mode) {
133  if (test_mode) {
134  return kUnitTestMaxCount;
135  } else {
136  return kMaxCount;
137  }
138 }
139 
140 ShowRouteHandler::ShowRouteHandler(const ShowRouteReq *req, int inst_id) :
141  req_(req), inst_id_(inst_id), prefix_expr_(req->get_prefix()) {
142 }
143 
144 // Search for interesting prefixes in a given table for given partition
146  vector<ShowRoute> *route_list, int count) {
147  if (inst_id_ >= table->PartitionCount())
148  return;
149  DBTablePartition *partition =
150  static_cast<DBTablePartition *>(table->GetTablePartition(inst_id_));
151  BgpRoute *route = NULL;
152 
153  if (table->name() == req_->get_start_routing_table()) {
154  unique_ptr<DBEntry> key =
155  table->AllocEntryStr(req_->get_start_prefix());
156  route = static_cast<BgpRoute *>(partition->lower_bound(key.get()));
157  } else {
158  route = static_cast<BgpRoute *>(partition->GetFirst());
159  }
160  for (int i = 0; route && (!count || i < count);
161  route = static_cast<BgpRoute *>(partition->GetNext(route)), ++i) {
162  if (!MatchPrefix(req_->get_prefix(), route,
163  req_->get_longer_match(),
164  req_->get_shorter_match()))
165  continue;
166  ShowRoute show_route;
167  route->FillRouteInfo(table, &show_route, req_->get_source(),
168  req_->get_protocol());
169  if (!show_route.get_paths().empty())
170  route_list->push_back(show_route);
171  }
172 }
173 
174 bool ShowRouteHandler::MatchPrefix(const string &expected_prefix,
175  BgpRoute *route, bool longer_match,
176  bool shorter_match) {
177  if (expected_prefix.empty())
178  return true;
179  if (!longer_match && !shorter_match)
180  return regex_search(route->ToString(), prefix_expr_);
181 
182  // Do longer match.
183  if (longer_match && route->IsMoreSpecific(expected_prefix))
184  return true;
185 
186  // Do shorter match.
187  if (shorter_match && route->IsLessSpecific(expected_prefix))
188  return true;
189 
190  return false;
191 }
192 
193 bool ShowRouteHandler::match(const string &expected, const string &actual) {
194  if (expected == "")
195  return true;
196  return expected == actual;
197 }
198 
200  return static_cast<RequestPipeline::InstData *>(new ShowRouteData);
201 }
202 
203 uint32_t ShowRouteHandler::GetMaxRouteCount(const ShowRouteReq *req) {
204  BgpSandeshContext *bsc =
205  static_cast<BgpSandeshContext *>(req->client_context());
206  uint32_t max_count =
208 
209  uint32_t route_count = req->get_count() + 1;
210  if (!req->get_count() || (req->get_count() > max_count)) {
211  // Set the count to our default if input is zero or too high
212  route_count = max_count + 1;
213  }
214  return route_count;
215 }
216 
217 // Get the information from req_iterate and fill into req
219  const ShowRouteReqIterate *req_iterate, ShowRouteReq *req) {
220  // First, set the context from the original request since we might return
221  // due to parsing errors.
222  req->set_context(req_iterate->context());
223 
224  // Format of route_info:
225  // UserRI||UserRT||UserPfx||NextRI||NextRT||NextPfx||count||longer_match||
226  // shorter_match
227  //
228  // User* values were entered by the user and Next* values indicate 'where'
229  // we need to start this iteration.
230  string route_info = req_iterate->get_route_info();
231  size_t sep_size = strlen(kIterSeparator);
232 
233  size_t pos1 = route_info.find(kIterSeparator);
234  if (pos1 == string::npos) {
235  return false;
236  }
237  string user_ri = route_info.substr(0, pos1);
238 
239  size_t pos2 = route_info.find(kIterSeparator, (pos1 + sep_size));
240  if (pos2 == string::npos) {
241  return false;
242  }
243  string user_rt = route_info.substr((pos1 + sep_size),
244  pos2 - (pos1 + sep_size));
245 
246  size_t pos3 = route_info.find(kIterSeparator, (pos2 + sep_size));
247  if (pos3 == string::npos) {
248  return false;
249  }
250  string user_prefix = route_info.substr((pos2 + sep_size),
251  pos3 - (pos2 + sep_size));
252 
253  size_t pos4 = route_info.find(kIterSeparator, (pos3 + sep_size));
254  if (pos4 == string::npos) {
255  return false;
256  }
257  string next_ri = route_info.substr((pos3 + sep_size),
258  pos4 - (pos3 + sep_size));
259 
260  size_t pos5 = route_info.find(kIterSeparator, (pos4 + sep_size));
261  if (pos5 == string::npos) {
262  return false;
263  }
264  string next_rt = route_info.substr((pos4 + sep_size),
265  pos5 - (pos4 + sep_size));
266 
267  size_t pos6 = route_info.find(kIterSeparator, (pos5 + sep_size));
268  if (pos6 == string::npos) {
269  return false;
270  }
271  string next_prefix = route_info.substr((pos5 + sep_size),
272  pos6 - (pos5 + sep_size));
273 
274  size_t pos7 = route_info.find(kIterSeparator, (pos6 + sep_size));
275  if (pos7 == string::npos) {
276  return false;
277  }
278  string count_str = route_info.substr((pos6 + sep_size),
279  pos7 - (pos6 + sep_size));
280 
281  size_t pos8 = route_info.find(kIterSeparator, (pos7 + sep_size));
282  if (pos8 == string::npos) {
283  return false;
284  }
285  string user_source = route_info.substr((pos7 + sep_size),
286  pos8 - (pos7 + sep_size));
287 
288  size_t pos9 = route_info.find(kIterSeparator, (pos8 + sep_size));
289  if (pos9 == string::npos) {
290  return false;
291  }
292  string user_protocol = route_info.substr((pos8 + sep_size),
293  pos9 - (pos8 + sep_size));
294 
295  size_t pos10 = route_info.find(kIterSeparator, (pos9 + sep_size));
296  if (pos10 == string::npos) {
297  return false;
298  }
299  string user_family = route_info.substr((pos9 + sep_size),
300  pos10 - (pos9 + sep_size));
301 
302  size_t pos11 = route_info.find(kIterSeparator, (pos10 + sep_size));
303  if (pos11 == string::npos) {
304  return false;
305  }
306  string longer_match = route_info.substr((pos10 + sep_size),
307  pos11 - (pos10 + sep_size));
308 
309  string shorter_match = route_info.substr(pos11 + sep_size);
310 
311  req->set_routing_instance(user_ri);
312  req->set_routing_table(user_rt);
313  req->set_prefix(user_prefix);
314  req->set_start_routing_instance(next_ri);
315  req->set_start_routing_table(next_rt);
316  req->set_start_prefix(next_prefix);
317  req->set_count(atoi(count_str.c_str()));
318  req->set_source(user_source);
319  req->set_protocol(user_protocol);
320  req->set_family(user_family);
321  req->set_longer_match(StringToBool(longer_match));
322  req->set_shorter_match(StringToBool(shorter_match));
323 
324  return true;
325 }
326 
327 bool ShowRouteHandler::CallbackS1Common(const ShowRouteReq *req, int inst_id,
328  ShowRouteData *mydata) {
329  uint32_t max_count = ShowRouteHandler::GetMaxRouteCount(req);
330 
331  ShowRouteHandler handler(req, inst_id);
332  BgpSandeshContext *bsc =
333  static_cast<BgpSandeshContext *>(req->client_context());
335 
336  string exact_routing_table = req->get_routing_table();
337  string exact_routing_instance;
338  string start_routing_instance;
339  if (exact_routing_table.empty()) {
340  exact_routing_instance = req->get_routing_instance();
341  } else {
342  exact_routing_instance =
343  RoutingInstance::GetVrfFromTableName(exact_routing_table);
344  }
345  if (exact_routing_instance.empty()) {
346  start_routing_instance = req->get_start_routing_instance();
347  } else {
348  start_routing_instance = exact_routing_instance;
349  }
350 
352  rim->name_lower_bound(start_routing_instance);
353  uint32_t count = 0;
354  while (i != rim->name_end()) {
355  if (!handler.match(exact_routing_instance, i->first)) {
356  break;
357  }
358  RoutingInstance::RouteTableList::const_iterator j;
359  if (req->get_start_routing_instance() == i->first) {
360  j = i->second->GetTables().
361  lower_bound(req->get_start_routing_table());
362  } else {
363  j = i->second->GetTables().begin();
364  }
365  for (; j != i->second->GetTables().end(); ++j) {
366  BgpTable *table = j->second;
367  if (!req->get_family().empty() && req->get_family() !=
369  continue;
370  }
371  if (!handler.match(req->get_routing_table(), table->name())) {
372  continue;
373  }
374  ShowRouteTable srt;
375  srt.set_routing_instance(i->first);
376  srt.set_routing_table_name(table->name());
377  srt.set_deleted(table->IsDeleted());
378  srt.set_deleted_at(
380 
381  // Encode routing-table stats.
382  srt.set_prefixes(table->Size());
383  srt.set_primary_paths(table->GetPrimaryPathCount());
384  srt.set_secondary_paths(table->GetSecondaryPathCount());
385  srt.set_infeasible_paths(table->GetInfeasiblePathCount());
386  srt.set_stale_paths(table->GetStalePathCount());
387  srt.set_llgr_stale_paths(table->GetLlgrStalePathCount());
388  srt.set_paths(srt.get_primary_paths() + srt.get_secondary_paths());
389 
390  vector<ShowTableListener> listeners;
391  table->FillListeners(&listeners);
392  srt.set_listeners(listeners);
393 
394  vector<ShowRoute> route_list;
395  handler.BuildShowRouteTable(table, &route_list,
396  max_count ? max_count - count : 0);
397  if (route_list.size() || table->IsDeleted()) {
398  srt.set_routes(route_list);
399  mydata->route_table_list.push_back(srt);
400  }
401  count += route_list.size();
402  if (count >= max_count) {
403  break;
404  }
405  }
406  if (count >= max_count) {
407  break;
408  }
409 
410  i++;
411  }
412 
413  return true;
414 }
415 
417  const RequestPipeline::PipeSpec ps,
418  int stage, int instNum, RequestPipeline::InstData *data) {
419  ShowRouteData *mydata = static_cast<ShowRouteData *>(data);
420  int inst_id = ps.stages_[stage].instances_[instNum];
421  const ShowRouteReq *req =
422  static_cast<const ShowRouteReq *>(ps.snhRequest_.get());
423 
424  return CallbackS1Common(req, inst_id, mydata);
425 }
426 
428  const RequestPipeline::PipeSpec ps,
429  int stage, int instNum, RequestPipeline::InstData *data) {
430  ShowRouteData *mydata = static_cast<ShowRouteData *>(data);
431  int inst_id = ps.stages_[stage].instances_[instNum];
432  const ShowRouteReqIterate *req_iterate =
433  static_cast<const ShowRouteReqIterate *>(ps.snhRequest_.get());
434 
435  ShowRouteReq *req = new ShowRouteReq;
436  bool success = ConvertReqIterateToReq(req_iterate, req);
437  if (success) {
438  CallbackS1Common(req, inst_id, mydata);
439  }
440  req->Release();
441  return true;
442 }
443 
444 string ShowRouteHandler::SaveContextAndPopLast(const ShowRouteReq *req,
445  vector<ShowRouteTable> *route_table_list) {
446  // If there are no output results for the input parameters, we dont need to
447  // save anything since there will be no subsequent iteration and there is
448  // nothing to pop off.
449  if (route_table_list->empty()) {
450  return string("");
451  }
452 
453  // Get the total number of routes that we have collected in this iteration
454  // after the mergesort.
455  uint32_t total_count = 0;
456  for (size_t i = 0; i < route_table_list->size(); ++i) {
457  total_count += route_table_list->at(i).get_routes().size();
458  }
459 
460  ShowRouteTable *last_route_table =
461  &route_table_list->at(route_table_list->size() - 1);
462  string next_batch;
463 
464  // We always attempt to read one extra entry (GetMaxRouteCount() adds 1).
465  // Case 1: (total_count > GetMaxRouteCount())
466  // This cannot happen since the merge sort has already trimmed the list to
467  // GetMaxRouteCount
468 
469  // Case 2: (total_count < GetMaxRouteCount())
470  // There are no more entries matching the input criteria and we are done.
471  if (total_count < ShowRouteHandler::GetMaxRouteCount(req)) {
472  return next_batch;
473  }
474 
475  // Case 3: (total_count == GetMaxRouteCount())
476  // If total_count is equal to GetMaxRouteCount(), we have at least 1 entry
477  // for the next round i.e. we are not done and we need to init next_batch
478  // with the right values from the extra entry and we also need to pop off
479  // the extra entry.
480 
481  int new_count;
482  bool next_round = true;
483  if (req->get_count()) {
484  // This is required for the last round if the user gave a count. Even
485  // though we have read an extra entry, we are done and we do not want
486  // to display any 'next_batch' http links.
487  new_count = req->get_count() - total_count + 1;
488  if (!new_count) {
489  next_round = false;
490  }
491  } else {
492  // If the user did not fill in the count, keep using zero.
493  new_count = req->get_count();
494  }
495 
496  if (next_round) {
497  ShowRoute last_route =
498  last_route_table->get_routes().at(
499  last_route_table->get_routes().size() - 1);
500  next_batch =
501  req->get_routing_instance() + kIterSeparator +
502  req->get_routing_table() + kIterSeparator +
503  req->get_prefix() + kIterSeparator +
504  last_route_table->get_routing_instance() + kIterSeparator +
505  last_route_table->get_routing_table_name() + kIterSeparator +
506  last_route.get_prefix() + kIterSeparator +
507  integerToString(new_count) + kIterSeparator +
508  req->get_source() + kIterSeparator +
509  req->get_protocol() + kIterSeparator +
510  req->get_family() + kIterSeparator +
511  BoolToString(req->get_longer_match()) + kIterSeparator +
512  BoolToString(req->get_shorter_match());
513  }
514 
515  // Pop off the last entry only after we have captured its values in
516  // 'next_batch' above.
517  const_cast<vector<ShowRoute> *>(
518  &last_route_table->get_routes())->pop_back();
519  if (last_route_table->get_routes().empty()) {
520  route_table_list->pop_back();
521  }
522 
523  return next_batch;
524 }
525 
526 void ShowRouteHandler::CallbackS2Common(const ShowRouteReq *req,
527  const RequestPipeline::PipeSpec ps,
528  ShowRouteResp *resp) {
529  BgpSandeshContext *bsc =
530  static_cast<BgpSandeshContext *>(req->client_context());
531  const RequestPipeline::StageData *sd = ps.GetStageData(0);
532  vector<ShowRouteTable> route_table_list;
533  vector<const vector<ShowRouteTable> *> table_lists;
534  for (size_t i = 0; i < sd->size(); ++i) {
535  const ShowRouteData &old_data =
536  static_cast<const ShowRouteData &>(sd->at(i));
537  if (old_data.route_table_list.size()) {
538  table_lists.push_back(&old_data.route_table_list);
539  }
540  }
541  MergeSort(&route_table_list, &table_lists,
542  ShowRouteHandler::GetMaxRouteCount(req), bsc, "");
543 
544  string next_batch = SaveContextAndPopLast(req, &route_table_list);
545  resp->set_next_batch(next_batch);
546 
547  // Save the table in the message *after* popping the last entry above.
548  resp->set_tables(route_table_list);
549 }
550 
552  const RequestPipeline::PipeSpec &ps, int stage, int instNum,
554  const ShowRouteReq *req =
555  static_cast<const ShowRouteReq *>(ps.snhRequest_.get());
556 
557  ShowRouteResp *resp = new ShowRouteResp;
558  CallbackS2Common(req, ps, resp);
559  resp->set_context(req->context());
560  resp->Response();
561  return true;
562 }
563 
565  const RequestPipeline::PipeSpec ps, int stage, int instNum,
567  const ShowRouteReqIterate *req_iterate =
568  static_cast<const ShowRouteReqIterate *>(ps.snhRequest_.get());
569 
570  ShowRouteResp *resp = new ShowRouteResp;
571  ShowRouteReq *req = new ShowRouteReq;
572  bool success = ConvertReqIterateToReq(req_iterate, req);
573  if (success) {
574  CallbackS2Common(req, ps, resp);
575  }
576  resp->set_context(req->context());
577  resp->Response();
578  req->Release();
579  return true;
580 }
581 
582 // handler for 'show route'
583 void ShowRouteReq::HandleRequest() const {
584  BgpSandeshContext *bsc = static_cast<BgpSandeshContext *>(client_context());
585 
586  RequestPipeline::PipeSpec ps(this);
587 
588  // Request pipeline has 2 stages. In first stage, we spawn one task per
589  // partition and generate the list of routes. In second stage, we look
590  // at the generated list and merge it so that we can send it back.
593  s1.taskId_ = scheduler->GetTaskId("db::DBTable");
595 
597  for (int i = 0; i < bsc->bgp_server->database()->PartitionCount(); ++i) {
598  s1.instances_.push_back(i);
599  }
600 
601  s2.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
604  s2.instances_.push_back(0);
605 
606  ps.stages_= list_of(s1)(s2)
607  .convert_to_container<vector<RequestPipeline::StageSpec> >();
608  RequestPipeline rp(ps);
609 }
610 
611 // handler for 'show route' that shows batches of routes, iteratively
612 void ShowRouteReqIterate::HandleRequest() const {
613  BgpSandeshContext *bsc = static_cast<BgpSandeshContext *>(client_context());
614 
615  RequestPipeline::PipeSpec ps(this);
616 
617  // Request pipeline has 2 stages. In first stage, we spawn one task per
618  // partition and generate the list of routes. In second stage, we look
619  // at the generated list and merge it so that we can send it back.
622 
623  s1.taskId_ = scheduler->GetTaskId("db::DBTable");
626  for (int i = 0; i < bsc->bgp_server->database()->PartitionCount(); ++i) {
627  s1.instances_.push_back(i);
628  }
629 
630  s2.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
633  s2.instances_.push_back(0);
634 
635  ps.stages_= list_of(s1)(s2)
636  .convert_to_container<vector<RequestPipeline::StageSpec> >();
637  RequestPipeline rp(ps);
638 }
RoutingInstanceList::iterator name_iterator
void FillRouteInfo(const BgpTable *table, ShowRouteBrief *show_route) const
Definition: bgp_route.cc:432
std::vector< int > instances_
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
static const uint32_t kUnitTestMaxCount
boost::ptr_vector< InstData > StageData
static RequestPipeline::InstData * CreateData(int stage)
contrail::regex prefix_expr_
static const uint32_t kMaxCount
BgpServer * bgp_server
Definition: bgp_sandesh.h:46
ShowRouteHandler(const ShowRouteReq *req, int inst_id)
DB * database()
Definition: bgp_server.h:200
virtual DBEntry * GetNext(const DBEntryBase *entry)
const uint64_t GetLlgrStalePathCount() const
Definition: bgp_table.h:169
virtual bool IsLessSpecific(const std::string &match) const
Definition: db_entry.h:34
Definition: route.h:14
static void CallbackS2Common(const ShowRouteReq *req, const RequestPipeline::PipeSpec ps, ShowRouteResp *resp)
RoutingInstanceMgr * routing_instance_mgr()
Definition: bgp_server.h:102
const ShowRouteReq * req_
static bool CallbackS1(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
int MergeValues(ShowRoute *result, vector< const ShowRoute * > *input, int limit, const BgpSandeshContext *bsc)
static std::string FamilyToTableString(Family family)
Definition: address.cc:67
static bool CallbackS1Iterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
bool match(const std::string &expected, const std::string &actual)
virtual Address::Family family() const =0
void FillListeners(std::vector< ShowTableListener > *listeners) const
Definition: db_table.cc:242
int GetTaskId(const std::string &name)
Definition: task.cc:856
static std::string SaveContextAndPopLast(const ShowRouteReq *req, std::vector< ShowRouteTable > *route_table_list)
bool IsDeleted() const
Definition: bgp_table.h:143
virtual size_t Size() const
Definition: db_table.cc:507
bool test_mode() const
Definition: bgp_sandesh.h:61
static uint32_t GetMaxCount(bool test_mode)
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
const uint64_t GetInfeasiblePathCount() const
Definition: bgp_table.h:165
void MergeSort(vector< T > *result, vector< const vector< T > * > *input, int limit, const BgpSandeshContext *bsc, const string &table_name)
static TaskScheduler * GetInstance()
Definition: task.cc:547
virtual std::string ToString() const =0
std::vector< StageSpec > stages_
static bool CallbackS2Iterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
virtual DBEntry * lower_bound(const DBEntryBase *entry)
const std::string & name() const
Definition: db_table.h:110
static bool CallbackS1Common(const ShowRouteReq *req, int inst_id, ShowRouteData *mydata)
static bool regex_search(const std::string &input, const regex &regex)
Definition: regex.h:25
static bool IsLess(const ShowRoute &lhs, const ShowRoute &rhs, const BgpSandeshContext *bsc, const string &table_name)
static bool ConvertReqIterateToReq(const ShowRouteReqIterate *req_iterate, ShowRouteReq *req)
bool MatchPrefix(const std::string &expected_prefix, BgpRoute *route, bool longer_match, bool shorter_match)
static std::string GetVrfFromTableName(const std::string table)
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:436
static bool CallbackS2(const Sandesh *sr, const RequestPipeline::PipeSpec &ps, int stage, int instNum, RequestPipeline::InstData *data)
const uint64_t GetPrimaryPathCount() const
Definition: bgp_table.h:161
virtual bool IsLess(const DBEntry &rhs) const =0
static uint32_t GetMaxRouteCount(const ShowRouteReq *req)
static char kIterSeparator[]
name_iterator name_lower_bound(const std::string &name)
LifetimeActor * deleter()
Definition: bgp_table.cc:1108
name_iterator name_end()
boost::shared_ptr< const SandeshRequest > snhRequest_
virtual void set_routing_instance(RoutingInstance *rtinstance)
Definition: bgp_table.cc:81
static int PartitionCount()
Definition: db.cc:32
virtual DBEntry * GetFirst()
virtual std::unique_ptr< DBEntry > AllocEntryStr(const std::string &key) const =0
const uint64_t delete_time_stamp_usecs() const
Definition: lifetime.h:138
static bool StringToBool(const std::string &in_string)
Definition: string_util.h:161
std::vector< ShowRouteTable > route_table_list
const StageData * GetStageData(int stage) const
virtual int PartitionCount() const
Definition: db_table.cc:420
virtual bool IsMoreSpecific(const std::string &match) const
Definition: db_entry.h:31
const uint64_t GetStalePathCount() const
Definition: bgp_table.h:168
void BuildShowRouteTable(BgpTable *table, std::vector< ShowRoute > *route_list, int count)
DBTableBase * FindTable(const std::string &name)
Definition: db.cc:68
static std::string BoolToString(const bool &val)
Definition: string_util.h:153
const uint64_t GetSecondaryPathCount() const
Definition: bgp_table.h:162
static std::string UTCUsecToString(uint64_t tstamp)
Definition: time_util.h:54