OpenSDN source code
bgp_table.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  * Copyright Contributors to the OpenSDN project
4  */
5 
6 #include "bgp/bgp_table.h"
7 
8 #include <boost/foreach.hpp>
9 
10 #include "sandesh/sandesh_trace.h"
11 #include "base/task_annotations.h"
12 #include "bgp/bgp_log.h"
13 #include "bgp/bgp_membership.h"
14 #include "bgp/bgp_peer.h"
15 #include "bgp/bgp_peer_types.h"
16 #include "bgp/bgp_ribout.h"
17 #include "bgp/bgp_ribout_updates.h"
18 #include "bgp/bgp_route.h"
19 #include "bgp/bgp_server.h"
20 #include "bgp/bgp_update.h"
21 #include "bgp/inet/inet_table.h"
27 #include "net/community_type.h"
28 
29 using std::make_pair;
30 using std::string;
31 
33  public:
34  explicit DeleteActor(BgpTable *table)
35  : LifetimeActor(table->rtinstance_->server()->lifetime_manager()),
36  table_(table) {
37  }
38  virtual ~DeleteActor() {
39  }
40  virtual bool MayDelete() const {
41  return table_->MayDelete();
42  }
43 
44  virtual void Shutdown() {
45  table_->Shutdown();
46  }
47 
48  // Make sure that all notifications have been processed and all db
49  // state have been cleared for all partitions, before we inform the
50  // parent instance that this table deletion process is complete.
51  virtual void Destroy() {
53  }
54 
55  private:
57 };
58 
59 BgpTable::BgpTable(DB *db, const string &name)
60  : RouteTable(db, name),
61  rtinstance_(NULL),
62  path_resolver_(NULL),
63  instance_delete_ref_(this, NULL) {
69 }
70 
71 //
72 // Remove the table from the instance dependents before attempting to
73 // destroy the DeleteActor which can have its Delete() method be called
74 // via the reference.
75 //
77  assert(path_resolver_ == NULL),
79 }
80 
82  rtinstance_ = rtinstance;
83  assert(rtinstance);
84  deleter_.reset(new DeleteActor(this));
85  instance_delete_ref_.Reset(rtinstance->deleter());
86 }
87 
89  return rtinstance_->server();
90 }
91 
92 const BgpServer *BgpTable::server() const {
93  return rtinstance_->server();
94 }
95 
96 //
97 // Find the RibOut for the given RibExportPolicy.
98 //
100  RibOutMap::iterator loc = ribout_map_.find(policy);
101  return (loc != ribout_map_.end()) ? loc->second : NULL;
102 }
103 
104 //
105 // Find or create the RibOut associated with the given RibExportPolicy.
106 // If a new RibOut is created, an entry for the pair gets added to the
107 // RibOutMap.
108 //
110  const RibExportPolicy &policy) {
111  RibOutMap::iterator loc = ribout_map_.find(policy);
112  if (loc == ribout_map_.end()) {
113  RibOut *ribout = new RibOut(this, sender, policy);
114  ribout_map_.insert(make_pair(policy, ribout));
115  return ribout;
116  }
117  return loc->second;
118 }
119 
120 //
121 // Delete the entry corresponding to the given RibExportPolicy from the
122 // RibOutMap. Also deletes the RibOut itself.
123 //
125  RibOutMap::iterator loc = ribout_map_.find(policy);
126  assert(loc != ribout_map_.end());
127  delete loc->second;
128  ribout_map_.erase(loc);
129 }
130 
131 // If both as2 and as4 aggregators are present then we need to choose one
133  if (attr->aggregator_as_num() && attr->aggregator_as4_num()) {
134  if (attr->aggregator_as_num() != AS_TRANS) {
135  // If as2 aggregator is not as_trans then we ignore as4 aggregator
136  // and ignore as4_path also
137  attr->set_as4_path(NULL);
138  attr->set_as4_aggregator(0, attr->aggregator_adderess());
139  } else {
140  // If as2 aggregator is as_trans then we use as4 aggregator
141  attr->set_aggregator(attr->aggregator_as4_num(),
142  attr->aggregator_adderess());
143  attr->set_as4_aggregator(0, attr->aggregator_adderess());
144  }
145  }
146 }
147 
148 void BgpTable::PrependLocalAs(const RibOut *ribout, BgpAttr *clone,
149  const IPeer* peer) const {
150  CheckAggregatorAttr(clone);
151  as_t local_as = ribout->local_as() ?:
152  clone->attr_db()->server()->local_autonomous_system();
153  if (!server()->enable_4byte_as())
154  return PrependAsToAsPath2Byte(clone, (as2_t)local_as);
155  if (ribout->as4_supported()) {
156  if (clone->aspath_4byte())
157  PrependAsToAsPath4Byte(clone, local_as);
158  else
159  CreateAsPath4Byte(clone, local_as);
160  } else {
161  if (!clone->as_path())
162  CreateAsPath2Byte(clone);
163  PrependAsToAsPath2Byte(clone, local_as);
164  }
165 }
166 
167 void BgpTable::RemovePrivateAs(const RibOut *ribout, BgpAttr *attr) const {
168  bool all = ribout->remove_private_all();
169  bool replace = ribout->remove_private_replace();
170  bool peer_loop_check = ribout->remove_private_peer_loop_check();
171 
172  const AsPathSpec &spec = attr->as_path()->path();
173  as_t peer_asn = peer_loop_check ? ribout->peer_as() : 0;
174  as_t replace_asn = 0;
175  if (replace) {
176  if (ribout->peer_type() == BgpProto::EBGP) {
177  replace_asn = server()->local_autonomous_system();
178  } else {
179  replace_asn = spec.AsLeftMostPublic();
180  }
181  }
182  if (replace_asn > AS2_MAX) {
183  if (!attr->as4_path())
184  CreateAs4Path(attr);
185  const As4PathSpec &spec = attr->as4_path()->path();
186  As4PathSpec *new_spec = spec.RemovePrivate(all, replace_asn, peer_asn);
187  attr->set_as4_path(new_spec);
188  delete new_spec;
189  replace_asn = AS_TRANS;
190  }
191  if (peer_asn > AS2_MAX)
192  peer_asn = AS_TRANS;
193 
194  AsPathSpec *new_spec = spec.RemovePrivate(all, replace_asn, peer_asn);
195  attr->set_as_path(new_spec);
196  delete new_spec;
197 }
198 
199 void BgpTable::RemovePrivate4ByteAs(const RibOut *ribout, BgpAttr *attr) const {
200  bool all = ribout->remove_private_all();
201  bool replace = ribout->remove_private_replace();
202  bool peer_loop_check = ribout->remove_private_peer_loop_check();
203 
204  const AsPath4ByteSpec &spec = attr->aspath_4byte()->path();
205  as_t peer_asn = peer_loop_check ? ribout->peer_as() : 0;
206  as_t replace_asn = 0;
207  if (replace) {
208  if (ribout->peer_type() == BgpProto::EBGP) {
209  replace_asn = server()->local_autonomous_system();
210  } else {
211  replace_asn = spec.AsLeftMostPublic();
212  }
213  }
214 
215  AsPath4ByteSpec *new_spec = spec.RemovePrivate(all, replace_asn, peer_asn);
216  attr->set_aspath_4byte(new_spec);
217  delete new_spec;
218 }
219 
220 void BgpTable::RemovePrivateAs4(const RibOut *ribout, BgpAttr *attr) const {
221  bool all = ribout->remove_private_all();
222  bool replace = ribout->remove_private_replace();
223  bool peer_loop_check = ribout->remove_private_peer_loop_check();
224 
225  const As4PathSpec &spec = attr->as4_path()->path();
226  as_t peer_asn = peer_loop_check ? ribout->peer_as() : 0;
227  as_t replace_asn = 0;
228  if (replace) {
229  if (ribout->peer_type() == BgpProto::EBGP) {
230  replace_asn = server()->local_autonomous_system();
231  } else {
232  replace_asn = spec.AsLeftMostPublic();
233  }
234  }
235 
236  As4PathSpec *new_spec = spec.RemovePrivate(all, replace_asn, peer_asn);
237  attr->set_as4_path(new_spec);
238  delete new_spec;
239 }
240 
241 //
242 // Process Remove Private information.
243 //
244 void BgpTable::ProcessRemovePrivate(const RibOut *ribout, BgpAttr *attr) const {
245  if (!ribout->IsEncodingBgp())
246  return;
247  if (!ribout->remove_private_enabled())
248  return;
249 
250  if (attr->as_path())
251  RemovePrivateAs(ribout, attr);
252  if (attr->aspath_4byte())
253  RemovePrivate4ByteAs(ribout, attr);
254  if (attr->as4_path())
255  RemovePrivateAs4(ribout, attr);
256 }
257 
258 //
259 // Process Remove Private information.
260 //
261 void BgpTable::ProcessAsOverride(const RibOut *ribout, BgpAttr *attr) const {
262  if (ribout->as_override() && !attr->IsAsPathEmpty()) {
263  as_t replace_as = ribout->local_as() ?:
264  attr->attr_db()->server()->local_autonomous_system();
265  if (attr->as_path()) {
266  const AsPathSpec &as_path = attr->as_path()->path();
267  // If peer_as is > 0xffff, it can't be in as_path
268  if (ribout->peer_as() <= AS2_MAX) {
269  if (replace_as > AS2_MAX) {
270  // if replace_as > 0xffff, as4_path should be created if
271  // not already there by copying data from as_path
272  if (!attr->as4_path()) {
273  CreateAs4Path(attr);
274  }
275  replace_as = AS_TRANS;
276  }
277  AsPathSpec *as_path_ptr = as_path.Replace(
278  ribout->peer_as(), replace_as);
279  attr->set_as_path(as_path_ptr);
280  delete as_path_ptr;
281  }
282  if (attr->as4_path()) {
283  As4PathSpec *as_path_ptr = attr->as4_path()->path().Replace(
284  ribout->peer_as(), replace_as);
285  attr->set_as4_path(as_path_ptr);
286  delete as_path_ptr;
287  }
288  }
289  if (attr->aspath_4byte()) {
290  const AsPath4ByteSpec &as_path = attr->aspath_4byte()->path();
291  AsPath4ByteSpec *as_path_ptr =
292  as_path.Replace(ribout->peer_as(), replace_as);
293  attr->set_aspath_4byte(as_path_ptr);
294  delete as_path_ptr;
295  }
296  }
297 }
298 
299 //
300 // Process Long Lived Graceful Restart state information.
301 //
302 // For LLGR_STALE paths, if the peer supports LLGR then attach LLGR_STALE
303 // community. Otherwise, strip LLGR_STALE community, reduce LOCAL_PREF and
304 // attach NO_EXPORT community instead.
305 //
306 void BgpTable::ProcessLlgrState(const RibOut *ribout, const BgpPath *path,
307  BgpAttr *attr, bool llgr_stale_comm) {
308  if (!server() || !server()->comm_db())
309  return;
310 
311  // Skip LLGR specific attributes manipulation for rtarget routes.
312  if (family() == Address::RTARGET)
313  return;
314 
315  // If the path is not marked as llgr_stale or if it does not have the
316  // LLGR_STALE community, then no action is necessary.
317  if (!path->IsLlgrStale() && !llgr_stale_comm)
318  return;
319 
320  // If peers support LLGR, then attach LLGR_STALE community and return.
321  if (ribout->llgr()) {
322  if (!llgr_stale_comm) {
325  attr->set_community(comm);
326  }
327  return;
328  }
329 
330  // Peers do not understand LLGR. Bring down local preference instead to
331  // make the advertised path less preferred.
332  attr->set_local_pref(0);
333 
334  // Remove LLGR_STALE community as the peers do not support LLGR.
335  if (llgr_stale_comm) {
338  attr->set_community(comm);
339  }
340 
341  // Attach NO_EXPORT community as well to make sure that this path does not
342  // exits local AS, unless it is already present.
343  if (!attr->community() ||
347  attr->set_community(comm);
348  }
349 }
350 
352  ExtCommunityDB *extcomm_db, BgpAttr *attr) const {
353  if (!ribout->ExportPolicy().default_tunnel_encap_list.empty()) {
355  BOOST_FOREACH(const string &encap_string,
357  TunnelEncap tunnel_encap(encap_string);
358  encap_list.push_back(tunnel_encap.GetExtCommunity());
359  }
360  ExtCommunityPtr ext_community = attr->ext_community();
361  ext_community =
363  ext_community.get(), encap_list);
364  attr->set_ext_community(ext_community);
365  }
366 }
367 
369  if (attr->as_path()) {
370  const AsPathSpec &as_path = attr->as_path()->path();
371  AsPathSpec *as_path_ptr = as_path.Add(asn);
372  attr->set_as_path(as_path_ptr);
373  delete as_path_ptr;
374  } else {
375  AsPathSpec as_path;
376  AsPathSpec *as_path_ptr = as_path.Add(asn);
377  attr->set_as_path(as_path_ptr);
378  delete as_path_ptr;
379  }
380 }
381 
383  if (asn <= AS2_MAX) {
384  if (attr->as_path() && attr->as4_path()) {
385  PrependAsToAs4Path(attr, asn);
386  }
387  return PrependAsToAsPath2Byte(attr, static_cast<as2_t>(asn & AS2_MAX));
388  }
389  if (attr->as_path() && !attr->as4_path()) {
390  CreateAs4Path(attr);
391  assert(attr->as_path()->path().path_segments.size() ==
392  attr->as4_path()->path().path_segments.size());
393  }
394  as2_t as_trans = AS_TRANS;
395  PrependAsToAsPath2Byte(attr, as_trans);
396  PrependAsToAs4Path(attr, asn);
397 }
398 
400  if (clone->aspath_4byte()) {
401  const AsPath4ByteSpec &as4_path = clone->aspath_4byte()->path();
402  AsPath4ByteSpec *as4_path_ptr = as4_path.Add(asn);
403  clone->set_aspath_4byte(as4_path_ptr);
404  delete as4_path_ptr;
405  } else {
406  AsPath4ByteSpec as_path;
407  AsPath4ByteSpec *as_path_ptr = as_path.Add(asn);
408  clone->set_aspath_4byte(as_path_ptr);
409  delete as_path_ptr;
410  }
411 }
412 
413 void BgpTable::PrependAsToAs4Path(BgpAttr* attr, as_t asn) const {
414  if (attr->as4_path()) {
415  const As4PathSpec &as4_path = attr->as4_path()->path();
416  As4PathSpec *as4_path_ptr = as4_path.Add(asn);
417  attr->set_as4_path(as4_path_ptr);
418  delete as4_path_ptr;
419  } else {
420  As4PathSpec as_path;
421  As4PathSpec *as_path_ptr = as_path.Add(asn);
422  attr->set_as4_path(as_path_ptr);
423  delete as_path_ptr;
424  }
425 }
426 
427 // Create as4_path by copying data from as_path
428 void BgpTable::CreateAs4Path(BgpAttr *attr) const {
429  if (!attr->as_path()) {
430  return;
431  }
432 
433  std::unique_ptr<As4PathSpec> new_as_path(new As4PathSpec);
434  const AsPathSpec &as_path = attr->as_path()->path();
435  for (size_t i = 0; i < as_path.path_segments.size(); i++) {
437  AsPathSpec::PathSegment *ps = as_path.path_segments[i];
439  for (size_t j = 0; j < ps->path_segment.size(); j++) {
440  as_t as = ps->path_segment[j];
441  ps4->path_segment.push_back(as);
442  }
443  new_as_path->path_segments.push_back(ps4);
444  }
445  attr->set_as4_path(new_as_path.get());
446 }
447 
448 // Check if aspath_4byte has any asn > 0xFFFF
449 bool BgpTable::Has4ByteAsn(BgpAttr *attr) const {
450  if (!attr->aspath_4byte())
451  return false;
452  const AsPath4ByteSpec &as_path4 = attr->aspath_4byte()->path();
453  for (size_t i = 0; i < as_path4.path_segments.size(); ++i) {
454  AsPath4ByteSpec::PathSegment *ps4 = as_path4.path_segments[i];
455  for (size_t j = 0; j < ps4->path_segment.size(); ++j) {
456  if (ps4->path_segment[j] > AS2_MAX)
457  return true;
458  }
459  }
460  return false;
461 }
462 
463 // Create as_path (and as4_path) from as_path4byte
465  std::unique_ptr<AsPathSpec> new_as_path(new AsPathSpec);
466  As4PathSpec *new_as4_path = NULL;
467  bool has_4byte_asn = Has4ByteAsn(attr);
468  if (has_4byte_asn)
469  new_as4_path = new As4PathSpec;
470  if (attr->aspath_4byte()) {
471  const AsPath4ByteSpec &as_path4 = attr->aspath_4byte()->path();
472  for (size_t i = 0; i < as_path4.path_segments.size(); i++) {
474  As4PathSpec::PathSegment *as4_ps = NULL;
475  AsPath4ByteSpec::PathSegment *ps4 = as_path4.path_segments[i];
477  if (has_4byte_asn) {
478  as4_ps = new As4PathSpec::PathSegment;
479  as4_ps->path_segment_type = ps4->path_segment_type;
480  }
481  for (size_t j = 0; j < ps4->path_segment.size(); ++j) {
482  as_t as4 = ps4->path_segment[j];
483  if (as4 > AS2_MAX) {
484  as2_t as_trans = AS_TRANS;
485  ps->path_segment.push_back(as_trans);
486  } else {
487  ps->path_segment.push_back(static_cast<as2_t>(
488  as4 & AS2_MAX));
489  }
490  if (has_4byte_asn)
491  as4_ps->path_segment.push_back(as4);
492  }
493  new_as_path->path_segments.push_back(ps);
494  if (has_4byte_asn)
495  new_as4_path->path_segments.push_back(as4_ps);
496  }
497  attr->set_aspath_4byte(NULL);
498  }
499  attr->set_as_path(new_as_path.get());
500  if (has_4byte_asn) {
501  attr->set_as4_path(new_as4_path);
502  delete new_as4_path;
503  }
504 }
505 
506 // Create aspath_4byte by merging as_path and as4_path
507 void BgpTable::CreateAsPath4Byte(BgpAttr *attr, as_t local_as) const {
508  int as2_count = attr->as_path_count();
509  int as4_count = attr->as4_path_count();
510  if (as2_count < as4_count) {
511  as4_count = 0;
512  attr->set_as4_path(NULL);
513  }
514  AsPath4ByteSpec::PathSegment *ps4 = NULL;
515  bool part_segment = false;
516  std::unique_ptr <AsPath4ByteSpec> aspath_4byte(new AsPath4ByteSpec);
517  if (attr->as_path()) {
518  const AsPathSpec &as_path = attr->as_path()->path();
519  int new_as_count = 0;
520  for (size_t i = 0; i < as_path.path_segments.size() &&
521  new_as_count < (as2_count - as4_count) ; ++i) {
523  AsPathSpec::PathSegment *ps = as_path.path_segments[i];
526  new_as_count++;
527  for (size_t j = 0; j < ps->path_segment.size(); ++j) {
528  as2_t as = ps->path_segment[j];
529  ps4->path_segment.push_back(as);
530  }
531  } else {
532  for (size_t j = 0; j < ps->path_segment.size() &&
533  new_as_count < (as2_count - as4_count); ++j) {
534  new_as_count++;
535  as2_t as = ps->path_segment[j];
536  ps4->path_segment.push_back(as);
537  }
538  if (new_as_count == (as2_count - as4_count)) {
539  if (attr->as4_path()) {
540  part_segment = true;
541  break;
542  }
543  }
544  }
545  aspath_4byte->path_segments.push_back(ps4);
546  }
547  if (attr->as4_path()) {
548  const As4PathSpec &as4_path = attr->as4_path()->path();
549  for (size_t i = 0; i < as4_path.path_segments.size(); ++i) {
550  if (!part_segment) {
552  }
553  part_segment = false;
554  As4PathSpec::PathSegment *ps = as4_path.path_segments[i];
557  new_as_count++;
558  for (size_t j = 0; j < ps->path_segment.size(); ++j) {
559  as2_t as = ps->path_segment[j];
560  ps4->path_segment.push_back(as);
561  }
562  } else {
563  for (size_t j = 0; j < ps->path_segment.size(); ++j) {
564  as_t as = ps->path_segment[j];
565  ps4->path_segment.push_back(as);
566  }
567  }
568  aspath_4byte->path_segments.push_back(ps4);
569  }
570  attr->set_as4_path(NULL);
571  }
572  attr->set_as_path(NULL);
573  }
574  if (local_as) {
575  std::unique_ptr<AsPath4ByteSpec> as_path_spec(aspath_4byte->Add(local_as));
576  attr->set_aspath_4byte(as_path_spec.get());
577  } else {
578  attr->set_aspath_4byte(aspath_4byte.get());
579  }
580 }
581 
583  const RibPeerSet &peerset) {
584  const BgpPath *path = route->BestPath();
585 
586  // Ignore if there is no best-path.
587  if (!path)
588  return NULL;
589 
590  // Don't advertise infeasible paths.
591  if (!path->IsFeasible())
592  return NULL;
593 
594  // Check whether the route is contributing route
596  return NULL;
597 
598  // Needs to be outside the if block so it's not destroyed prematurely.
599  BgpAttrPtr attr_ptr;
600  const BgpAttr *attr = path->GetAttr();
601 
602  RibPeerSet new_peerset = peerset;
603 
604  // LocalPref, Med and AsPath manipulation is needed only if the RibOut
605  // has BGP encoding. Similarly, well-known communities do not apply if
606  // the encoding is not BGP.
607  if (ribout->IsEncodingBgp()) {
608  // Handle well-known communities.
609  if (attr->community() != NULL &&
610  attr->community()->communities().size()) {
611  BOOST_FOREACH(uint32_t value, attr->community()->communities()) {
612  if (value == CommunityType::NoAdvertise)
613  return NULL;
614 
615  if ((ribout->peer_type() == BgpProto::EBGP) &&
616  ((value == CommunityType::NoExport) ||
617  (value == CommunityType::NoExportSubconfed))) {
618  return NULL;
619  }
620  }
621  }
622 
623  const IPeer *peer = path->GetPeer();
624  BgpAttr *clone = NULL;
625  bool llgr_stale_comm = attr->community() &&
627  if (ribout->peer_type() == BgpProto::IBGP) {
628  // Split horizon check.
629  if (peer && peer->CheckSplitHorizon(server()->cluster_id(),
630  ribout->cluster_id()))
631  return NULL;
632 
633  // Handle route-target filtering.
634  if (IsVpnTable() && attr->ext_community() != NULL) {
636  ribout, attr->ext_community(), peerset, &new_peerset);
637  if (new_peerset.empty())
638  return NULL;
639  }
640 
641  if (server()->cluster_id()) {
642  // Check if there is a loop in cluster_list
643  if (attr->cluster_list() && attr->cluster_list()->cluster_list()
644  .ClusterListLoop(server()->cluster_id())) {
645  return NULL;
646  }
647  }
648 
649  if (server()->cluster_id() && (family() != Address::RTARGET)) {
650  // route reflector should not reflect the route back to the peer
651  // from which it received that route, for non rtarget routes
652  // This is done by checking peer_router_id of all the feasible
653  // paths of this route
654  RibPeerSet route_peerset;
655  for (Route::PathList::iterator it= route->GetPathList().begin();
656  it != route->GetPathList().end(); it++) {
657  BgpPath *ipath = static_cast<BgpPath *>(it.operator->());
658  if (ipath->IsFeasible() && ipath->GetPeer()) {
659  const IPeer *ipeer = ipath->GetPeer();
660  const BgpPeer *bgp_peer = dynamic_cast<
661  const BgpPeer *>(ipeer);
662  if (bgp_peer)
663  route_peerset.set(bgp_peer->GetIndex());
664  }
665  }
666  RibOut::PeerIterator iter(ribout, new_peerset);
667  while (iter.HasNext()) {
668  int current_index = iter.index();
669  IPeerUpdate *peer = iter.Next();
670  const BgpPeer *bgp_peer = dynamic_cast<
671  const BgpPeer *>(peer);
672  if (bgp_peer && route_peerset.test(bgp_peer->GetIndex()))
673  new_peerset.reset(current_index);
674  }
675  if (new_peerset.empty())
676  return NULL;
677  }
678 
679  clone = new BgpAttr(*attr);
680 
681  // Retain LocalPref value if set, else set default to 100.
682  if (clone->local_pref() == 0)
683  clone->set_local_pref(100);
684 
685  // Check aggregator attributes to identify which ones to be used
686  CheckAggregatorAttr(clone);
687 
688  // Should not normally be needed for iBGP, but there could be
689  // complex configurations where this is useful.
690  ProcessRemovePrivate(ribout, clone);
691 
692  // Add Originator_Id if acting as route reflector and cluster_id
693  // is not present
694  if (server()->cluster_id()) {
695  if (clone->originator_id().is_unspecified()) {
696  if (peer && (peer->bgp_identifier() != 0)) {
698  peer->bgp_identifier()));
699  } else {
701  server()->bgp_identifier()));
702  }
703  }
704  if (attr->cluster_list()) {
705  const ClusterListSpec &cluster =
706  clone->cluster_list()->cluster_list();
707  ClusterListSpec *cl_ptr = new ClusterListSpec(
708  server()->cluster_id(), &cluster);
709  clone->set_cluster_list(cl_ptr);
710  delete cl_ptr;
711  } else {
712  ClusterListSpec *cl_ptr = new ClusterListSpec(
713  server()->cluster_id(), NULL);
714  clone->set_cluster_list(cl_ptr);
715  delete cl_ptr;
716  }
717  }
718  // If the route is locally originated i.e. there's no AsPath,
719  // then generate a Nil AsPath i.e. one with 0 length. No need
720  // to modify the AsPath if it already exists since this is an
721  // iBGP RibOut.
722  if (ribout->as4_supported() && !clone->aspath_4byte()) {
723  if (attr->as_path()) {
724  CreateAsPath4Byte(clone, 0);
725  } else {
726  AsPath4ByteSpec as_path;
727  clone->set_aspath_4byte(&as_path);
728  }
729  }
730  if (!ribout->as4_supported() && !clone->as_path()) {
731  if (attr->aspath_4byte()) {
732  CreateAsPath2Byte(clone);
733  } else {
734  AsPathSpec as_path;
735  clone->set_as_path(&as_path);
736  }
737  }
738  } else if (ribout->peer_type() == BgpProto::EBGP) {
739  // Don't advertise routes from non-master instances if there's
740  // no nexthop. The ribout has to be for bgpaas-clients because
741  // that's the only case with bgp peers in non-master instance.
743  ribout->nexthop().is_unspecified()) {
744  return NULL;
745  }
746 
747  // Handle route-target filtering.
748  if (IsVpnTable() && attr->ext_community() != NULL) {
750  ribout, attr->ext_community(), peerset, &new_peerset);
751  if (new_peerset.empty())
752  return NULL;
753  }
754 
755  // Sender side AS path loop check and split horizon within RibOut.
756  if (!ribout->as_override()) {
757  if (attr->IsAsPathLoop(ribout->peer_as()))
758  return NULL;
759  } else {
760  if (peer && peer->PeerType() == BgpProto::EBGP) {
761  ribout->GetSubsetPeerSet(&new_peerset, peer);
762  if (new_peerset.empty())
763  return NULL;
764  }
765  }
766 
767  clone = new BgpAttr(*attr);
768 
769  // Remove non-transitive attributes.
770  // Note that med is handled further down.
771  clone->set_originator_id(Ip4Address());
772  clone->set_cluster_list(NULL);
773 
774  // Update nexthop.
775  if (!ribout->nexthop().is_unspecified())
776  clone->set_nexthop(ribout->nexthop());
777 
778  // Reset LocalPref.
779  if (clone->local_pref())
780  clone->set_local_pref(0);
781 
782  // Reset Med if the path did not originate from an xmpp peer.
783  // The AS path is NULL if the originating xmpp peer is locally
784  // connected. It's non-NULL but empty if the originating xmpp
785  // peer is connected to another bgp speaker in the iBGP mesh.
786  if (clone->med() && !clone->IsAsPathEmpty())
787  clone->set_med(0);
788 
789  // Override the peer AS with local AS in AsPath.
790  ProcessAsOverride(ribout, clone);
791 
792  // Remove private processing must happen before local AS prepend.
793  ProcessRemovePrivate(ribout, clone);
794 
795  // Prepend the local AS to AsPath.
796  PrependLocalAs(ribout, clone, peer);
797  }
798 
799  assert(clone);
800 
801  // Update with the Default tunnel Encapsulation ordered List if
802  // configured on the peer.
803  // Note that all peers with the same list share the same Ribout, this is
804  // ensured by making the Default Encapsulation List part of the Rib
805  // Export policy.Note that, if there is Default Tunnel Encapsulation
806  // configuration any tunnel encapsulation present is removed.
807  ProcessDefaultTunnelEncapsulation(ribout, server()->extcomm_db(),
808  clone);
809 
810  ProcessLlgrState(ribout, path, clone, llgr_stale_comm);
811 
812  // Locate the new BgpAttrPtr.
813  attr_ptr = clone->attr_db()->Locate(clone);
814  attr = attr_ptr.get();
815  }
816 
817  UpdateInfo *uinfo = new UpdateInfo;
818  uinfo->target = new_peerset;
819  uinfo->roattr = RibOutAttr(route, attr, ribout->IsEncodingXmpp());
820  return uinfo;
821 }
822 
823 // Bgp Path selection..
824 // Based Attribute weight
825 bool BgpTable::PathSelection(const Path &path1, const Path &path2) {
826  const BgpPath &l_path = dynamic_cast<const BgpPath &> (path1);
827  const BgpPath &r_path = dynamic_cast<const BgpPath &> (path2);
828 
829  // Check the weight of Path
830  bool res = l_path.PathCompare(r_path, false) < 0;
831 
832  return res;
833 }
834 
836  return InputCommon(root, rt, path, path->GetPeer(), NULL,
837  DBRequest::DB_ENTRY_DELETE, NULL, path->GetPathId(), 0, 0, 0);
838 }
839 
841  const IPeer *peer, DBRequest *req,
843  uint32_t path_id, uint32_t flags, uint32_t label,
844  uint32_t l3_label) {
845  bool notify_rt = false;
846 
847  switch (oper) {
849  assert(rt);
850 
851  // The entry may currently be marked as deleted.
852  rt->ClearDelete();
853  if (peer)
854  peer->UpdateCloseRouteStats(family(), path, flags);
855 
856  // Check whether peer already has a path.
857  if (path != NULL) {
858  if ((path->GetAttr() != attrs.get()) ||
859  (path->GetFlags() != flags) ||
860  (path->GetLabel() != label) ||
861  (path->GetL3Label() != l3_label)) {
862  // Update Attributes and notify (if needed)
863  if (path->NeedsResolution())
864  path_resolver_->StopPathResolution(root->index(), path);
865  rt->DeletePath(path);
866  } else {
867  // Ignore duplicate update.
868  break;
869  }
870  }
871 
872  BgpPath *new_path;
873  new_path = new BgpPath(
874  peer, path_id, BgpPath::BGP_XMPP, attrs, flags, label, l3_label);
875 
876  // Start path resolution for the new path if
877  // (1) Path flag has ResolveNextHop set in which case the path will
878  // be resolved in the overlay routing table (or)
879  // (2) Fast convergence knob is enabled in which case the path will
880  // be marked for resolution in the underlay (default) routing table
881  // (3) Path resolution in this case is needed only for routes
882  // in the VRF routing tables and for INET, INET6 and EVPN
883  // address families.
884  bool fc_family = false;
885  if (family() == Address::INET || family() == Address::INET6 ||
886  family() == Address::EVPN) {
887  fc_family = true;
888  }
889  bool fc_enabled = (server()->IsNextHopCheckEnabled() &&
890  !rtinstance_->IsMasterRoutingInstance() && fc_family);
891  if (new_path->NeedsResolution() || fc_enabled) {
892  if (peer && !(peer->IsXmppPeer()) ) {
893  rt->add_peer_sources(peer->ToString());
894  }
895  Address::Family family = new_path->GetAttr()->nexthop_family();
896  BgpTable *table;
897  if (new_path->NeedsResolution()) {
898  table = rtinstance_->GetTable(family);
899  } else {
900  // Fast convergence knob is enabled.
901  // Update path flag to indicate need for resolution.
902  new_path->SetResolveNextHop();
903 
904  // Get the default table.
906  assert(mgr);
907  RoutingInstance *master_ri = mgr->GetDefaultRoutingInstance();
908  assert(master_ri);
909  table = master_ri->GetTable(family);
910  }
911  path_resolver_->StartPathResolution(rt, new_path, table);
912  }
913 
914  rt->InsertPath(new_path);
915  notify_rt = true;
916  break;
917  }
918 
920  if (rt && !rt->IsDeleted()) {
921  if (peer && !(peer->IsXmppPeer()) ) {
922  rt->del_peer_sources(peer->ToString());
923  }
924  BGP_LOG_ROUTE(this, const_cast<IPeer *>(peer), rt,
925  "Delete BGP path");
926 
927  // Remove the Path from the route
928  if (path->NeedsResolution())
929  path_resolver_->StopPathResolution(root->index(), path);
930  rt->DeletePath(path);
931  notify_rt = true;
932  }
933  break;
934  }
935 
936  default: {
937  assert(false);
938  break;
939  }
940  }
941  return notify_rt;
942 }
943 
945  DBRequest *req) {
946  const IPeer *peer = (static_cast<RequestKey *>(req->key.get()))->GetPeer();
947  RequestData *data = static_cast<RequestData *>(req->data.get());
948 
949  if (req->oper == DBRequest::DB_ENTRY_ADD_CHANGE && peer) {
950  // Skip if this peer is down.
951  if (!peer->IsReady())
952  return;
953 
954  // For xmpp peers, verify that agent is subscribed to the table and
955  // the route add is from the same incarnation of table subscription.
956  if (peer->IsXmppPeer() && peer->IsRegistrationRequired()) {
958  int instance_id = -1;
959  uint64_t subscription_gen_id = 0;
960  bool is_registered =
961  mgr->GetRegistrationInfo(const_cast<IPeer *>(peer), this,
962  &instance_id, &subscription_gen_id);
963  if ((!is_registered && (family() != Address::RTARGET)) ||
964  (is_registered &&
965  (subscription_gen_id != data->subscription_gen_id()))) {
966  return;
967  }
968  }
969  }
970 
971  // Create route if it's not already present in case of add/change.
972  BgpRoute *rt = TableFind(root, req->key.get());
973  if (!rt) {
974  if ((req->oper == DBRequest::DB_ENTRY_DELETE) ||
976  return;
977 
978  rt = static_cast<BgpRoute *>(Add(req));
979  static_cast<DBTablePartition *>(root)->Add(rt);
980  BGP_LOG_ROUTE(this, const_cast<IPeer *>(peer), rt,
981  "Insert new BGP path");
982  }
983 
984  if (req->oper == DBRequest::DB_ENTRY_NOTIFY) {
985  root->Notify(rt);
986  return;
987  }
988 
989  uint32_t path_id = 0;
990  uint32_t flags = 0;
991  uint32_t label = 0;
992  uint32_t l3_label = 0;
993  BgpPath *path = rt->FindPath(peer);
994  BgpAttrPtr attr = data ? data->attrs() : NULL;
995  if (req->oper == DBRequest::DB_ENTRY_ADD_CHANGE) {
996  assert(data);
997  const RequestData::NextHop &nexthop = data->nexthop();
998  if (nexthop.address_.is_v4())
999  path_id = nexthop.address_.to_v4().to_ulong();
1000  flags = nexthop.flags_;
1001  label = nexthop.label_;
1002  l3_label = nexthop.l3_label_;
1003 
1004  attr = GetAttributes(rt, attr, peer);
1005  } else {
1006  if (!path)
1007  return;
1008  path_id = path->GetPathId();
1009  }
1010 
1011  bool notify_rt = InputCommon(root, rt, path, peer, req, req->oper,
1012  attr, path_id, flags, label, l3_label);
1013  InputCommonPostProcess(root, rt, notify_rt);
1014 }
1015 
1017  BgpRoute *rt, bool notify_rt) {
1018  if (!notify_rt)
1019  return;
1020 
1021  if (rt->front() == NULL)
1022  root->Delete(rt);
1023  else
1024  root->Notify(rt);
1025 }
1026 
1027 bool BgpTable::MayDelete() const {
1028  CHECK_CONCURRENCY("bgp::Config");
1029 
1030  // Bail if the table has listeners.
1031  if (HasListeners()) {
1032  BGP_LOG_TABLE(this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
1033  "Paused table deletion due to pending listeners");
1034  return false;
1035  }
1036 
1037  // Bail if the table has walkers.
1038  if (HasWalkers()) {
1039  BGP_LOG_TABLE(this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
1040  "Paused table deletion due to pending walkers");
1041  return false;
1042  }
1043 
1044  // Bail if the table is not empty.
1045  size_t size = Size();
1046  if (size > 0) {
1047  BGP_LOG_TABLE(this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
1048  "Paused table deletion due to " << size <<
1049  " pending routes");
1050  return false;
1051  }
1052 
1053  // Check the base class at the end so that we add custom checks
1054  // before this if needed and to get more informative log message.
1055  if (!DBTableBase::MayDelete())
1056  return false;
1057 
1058  return true;
1059 }
1060 
1062  CHECK_CONCURRENCY("bgp::PeerMembership", "bgp::Config");
1063 }
1064 
1066  BGP_LOG_TABLE(this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
1067  "Received request for table deletion");
1068  deleter_->Delete();
1069 }
1070 
1071 //
1072 // Retry deletion of the table if it is pending.
1073 //
1075  if (!deleter()->IsDeleted())
1076  return;
1077  deleter()->RetryDelete();
1078 }
1079 
1081  return NULL;
1082 }
1083 
1085  if (path_resolver_)
1086  return;
1087  assert(!deleter()->IsDeleted());
1089 }
1090 
1092  if (!path_resolver_)
1093  return;
1094  delete path_resolver_;
1095  path_resolver_ = NULL;
1096 }
1097 
1098 size_t BgpTable::GetPendingRiboutsCount(size_t *markers) const {
1099  CHECK_CONCURRENCY("bgp::ShowCommand", "bgp::Config");
1100  size_t count = 0;
1101  *markers = 0;
1102 
1103  BOOST_FOREACH(const RibOutMap::value_type &value, ribout_map_) {
1104  const RibOut *ribout = value.second;
1105  for (int idx = 0; idx < DB::PartitionCount(); ++idx) {
1106  const RibOutUpdates *updates = ribout->updates(idx);
1107  for (int qid = RibOutUpdates::QFIRST; qid < RibOutUpdates::QCOUNT;
1108  ++qid) {
1109  count += updates->queue_size(qid);
1110  *markers += updates->queue_marker_count(qid);
1111  }
1112  }
1113  }
1114 
1115  return count;
1116 }
1117 
1119  return deleter_.get();
1120 }
1121 
1123  return deleter_.get();
1124 }
1125 
1126 void BgpTable::UpdatePathCount(const BgpPath *path, int count) {
1127  if (dynamic_cast<const BgpSecondaryPath *>(path)) {
1128  secondary_path_count_ += count;
1129  } else {
1130  primary_path_count_ += count;
1131  }
1132 
1133  if (!path->IsFeasible()) {
1134  infeasible_path_count_ += count;
1135  }
1136 
1137  if (path->IsStale()) {
1138  stale_path_count_ += count;
1139  }
1140 
1141  if (path->IsLlgrStale()) {
1142  llgr_stale_path_count_ += count;
1143  }
1144 }
1145 
1146 // Check whether the route is aggregate route
1147 bool BgpTable::IsAggregateRoute(const BgpRoute *route) const {
1148  return routing_instance()->IsAggregateRoute(this, route);
1149 }
1150 
1151 // Check whether the route is contributing route to aggregate route
1152 bool BgpTable::IsContributingRoute(const BgpRoute *route) const {
1153  return routing_instance()->IsContributingRoute(this, route);
1154 }
1155 
1157  vector<ShowRibOutStatistics> *sros_list) const {
1158  BOOST_FOREACH(const RibOutMap::value_type &value, ribout_map_) {
1159  const RibOut *ribout = value.second;
1160  ribout->FillStatisticsInfo(sros_list);
1161  }
1162 }
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:15
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:999
#define AS_TRANS
Definition: bgp_common.h:24
#define AS2_MAX
Definition: bgp_common.h:25
uint16_t as2_t
Definition: bgp_common.h:23
uint32_t as_t
Definition: bgp_common.h:22
#define BGP_LOG_FLAG_ALL
Definition: bgp_log.h:45
#define BGP_LOG_TABLE(table, level, flags, arg)
Definition: bgp_log.h:261
#define BGP_LOG_ROUTE(table, peer, route, arg)
Definition: bgp_log.h:248
Family
Definition: address.h:25
@ INET
Definition: address.h:27
@ EVPN
Definition: address.h:32
@ RTARGET
Definition: address.h:31
@ INET6
Definition: address.h:28
const As4PathSpec & path() const
Definition: bgp_aspath.h:444
const AsPath4ByteSpec & path() const
Definition: bgp_aspath.h:286
const AsPathSpec & path() const
Definition: bgp_aspath.h:128
BgpServer * server()
Definition: bgp_attr.h:1041
void set_aspath_4byte(AsPath4BytePtr aspath)
Definition: bgp_attr.cc:982
uint32_t local_pref() const
Definition: bgp_attr.h:892
const AsPath * as_path() const
Definition: bgp_attr.h:902
int as_path_count() const
Definition: bgp_attr.h:903
void set_community(CommunityPtr comm)
Definition: bgp_attr.cc:1002
const IpAddress & aggregator_adderess() const
Definition: bgp_attr.h:897
bool IsAsPathEmpty() const
Definition: bgp_attr.cc:1122
int as4_path_count() const
Definition: bgp_attr.h:915
void set_as_path(AsPathPtr aspath)
Definition: bgp_attr.cc:958
void set_med(uint32_t med)
Definition: bgp_attr.h:839
void set_as4_path(As4PathPtr aspath)
Definition: bgp_attr.cc:970
const ClusterList * cluster_list() const
Definition: bgp_attr.h:910
int IsAsPathLoop(as_t asn, uint8_t max_loop_count=0) const
Definition: bgp_attr.cc:1249
void set_local_pref(uint32_t local_pref)
Definition: bgp_attr.h:840
void set_as4_aggregator(as_t as_num, IpAddress address)
Definition: bgp_attr.h:846
uint32_t med() const
Definition: bgp_attr.h:891
const Community * community() const
Definition: bgp_attr.h:917
void set_cluster_list(const ClusterListSpec *spec)
Definition: bgp_attr.cc:994
as_t aggregator_as_num() const
Definition: bgp_attr.h:894
void set_aggregator(as_t as_num, IpAddress address)
Definition: bgp_attr.h:842
void set_nexthop(IpAddress nexthop)
Definition: bgp_attr.h:838
const ExtCommunity * ext_community() const
Definition: bgp_attr.h:918
Address::Family nexthop_family() const
Definition: bgp_attr.cc:1159
const AsPath4Byte * aspath_4byte() const
Definition: bgp_attr.h:905
as_t aggregator_as4_num() const
Definition: bgp_attr.h:895
void set_ext_community(ExtCommunityPtr extcomm)
Definition: bgp_attr.cc:1014
const Ip4Address & originator_id() const
Definition: bgp_attr.h:898
void set_originator_id(Ip4Address originator_id)
Definition: bgp_attr.h:850
BgpAttrDB * attr_db()
Definition: bgp_attr.h:934
const As4Path * as4_path() const
Definition: bgp_attr.h:914
bool GetRegistrationInfo(const IPeer *peer, const BgpTable *table, int *instance_id=NULL, uint64_t *subscription_gen_id=NULL) const
TypePtr Locate(Type *attr)
uint32_t GetLabel() const
Definition: bgp_path.h:90
uint32_t GetFlags() const
Definition: bgp_path.h:101
IPeer * GetPeer()
Definition: bgp_path.h:77
void SetResolveNextHop()
Definition: bgp_path.h:130
const uint32_t GetPathId() const
Definition: bgp_path.h:79
bool NeedsResolution() const
Definition: bgp_path.h:136
bool IsStale() const
Definition: bgp_path.h:108
bool IsFeasible() const
Definition: bgp_path.h:93
@ BGP_XMPP
Definition: bgp_path.h:40
const BgpAttr * GetAttr() const
Definition: bgp_path.h:88
uint32_t GetL3Label() const
Definition: bgp_path.h:91
int PathCompare(const BgpPath &rhs, bool allow_ecmp) const
Definition: bgp_path.cc:59
bool IsLlgrStale() const
Definition: bgp_path.h:111
int GetIndex() const
Definition: bgp_peer.h:207
const BgpPath * FindPath(BgpPath::PathSource src) const
Definition: bgp_route.cc:147
const BgpPath * BestPath() const
Definition: bgp_route.cc:48
void add_peer_sources(std::string val)
Definition: bgp_route.h:87
void del_peer_sources(std::string val)
Definition: bgp_route.h:88
void DeletePath(BgpPath *path)
Definition: bgp_route.cc:128
void InsertPath(BgpPath *path)
Definition: bgp_route.cc:62
RTargetGroupMgr * rtarget_group_mgr()
Definition: bgp_server.h:115
RoutingInstanceMgr * routing_instance_mgr()
Definition: bgp_server.h:107
bool IsNextHopCheckEnabled() const
Definition: bgp_server.cc:699
as_t local_autonomous_system() const
Definition: bgp_server.h:215
CommunityDB * comm_db()
Definition: bgp_server.h:191
BgpMembershipManager * membership_mgr()
Definition: bgp_server.h:180
DeleteActor(BgpTable *table)
Definition: bgp_table.cc:34
virtual void Shutdown()
Definition: bgp_table.cc:44
virtual void Destroy()
Definition: bgp_table.cc:51
virtual bool MayDelete() const
Definition: bgp_table.cc:40
virtual ~DeleteActor()
Definition: bgp_table.cc:38
virtual BgpAttrPtr GetAttributes(BgpRoute *rt, BgpAttrPtr attrp, const IPeer *peer)
Definition: bgp_table.h:197
void RemovePrivateAs4(const RibOut *ribout, BgpAttr *attr) const
Definition: bgp_table.cc:220
std::atomic< uint64_t > primary_path_count_
Definition: bgp_table.h:223
void PrependLocalAs(const RibOut *ribout, BgpAttr *attr, const IPeer *) const
Definition: bgp_table.cc:148
void RemovePrivate4ByteAs(const RibOut *ribout, BgpAttr *attr) const
Definition: bgp_table.cc:199
bool DeletePath(DBTablePartBase *root, BgpRoute *rt, BgpPath *path)
Definition: bgp_table.cc:835
virtual void set_routing_instance(RoutingInstance *rtinstance)
Definition: bgp_table.cc:81
size_t GetPendingRiboutsCount(size_t *markers) const
Definition: bgp_table.cc:1098
void ManagedDelete()
Definition: bgp_table.cc:1065
void LocatePathResolver()
Definition: bgp_table.cc:1084
bool IsContributingRoute(const BgpRoute *route) const
Definition: bgp_table.cc:1152
std::atomic< uint64_t > stale_path_count_
Definition: bgp_table.h:226
virtual bool IsVpnTable() const
Definition: bgp_table.h:110
BgpServer * server()
Definition: bgp_table.cc:88
bool IsAggregateRoute(const BgpRoute *route) const
Definition: bgp_table.cc:1147
void DestroyPathResolver()
Definition: bgp_table.cc:1091
void CreateAsPath4Byte(BgpAttr *attr, as_t local_as) const
Definition: bgp_table.cc:507
std::atomic< uint64_t > llgr_stale_path_count_
Definition: bgp_table.h:227
bool Has4ByteAsn(BgpAttr *attr) const
Definition: bgp_table.cc:449
boost::scoped_ptr< DeleteActor > deleter_
Definition: bgp_table.h:221
RoutingInstance * routing_instance()
Definition: bgp_table.h:148
void PrependAsToAsPath4Byte(BgpAttr *attr, as_t asn) const
Definition: bgp_table.cc:399
void ProcessRemovePrivate(const RibOut *ribout, BgpAttr *attr) const
Definition: bgp_table.cc:244
void ProcessDefaultTunnelEncapsulation(const RibOut *ribout, ExtCommunityDB *extcomm_db, BgpAttr *attr) const
Definition: bgp_table.cc:351
virtual void Input(DBTablePartition *root, DBClient *client, DBRequest *req)
Definition: bgp_table.cc:944
void PrependAsToAsPath2Byte(BgpAttr *attr, as_t asn) const
Definition: bgp_table.cc:382
void RibOutDelete(const RibExportPolicy &policy)
Definition: bgp_table.cc:124
virtual PathResolver * CreatePathResolver()
Definition: bgp_table.cc:1080
void UpdatePathCount(const BgpPath *path, int count)
Definition: bgp_table.cc:1126
void CreateAs4Path(BgpAttr *attr) const
Definition: bgp_table.cc:428
virtual bool MayDelete() const
Definition: bgp_table.cc:1027
void RemovePrivateAs(const RibOut *ribout, BgpAttr *attr) const
Definition: bgp_table.cc:167
void ProcessAsOverride(const RibOut *ribout, BgpAttr *attr) const
Definition: bgp_table.cc:261
RoutingInstance * rtinstance_
Definition: bgp_table.h:217
std::atomic< uint64_t > infeasible_path_count_
Definition: bgp_table.h:225
bool InputCommon(DBTablePartBase *root, BgpRoute *rt, BgpPath *path, const IPeer *peer, DBRequest *req, DBRequest::DBOperation oper, BgpAttrPtr attrs, uint32_t path_id, uint32_t flags, uint32_t label, uint32_t l3_label)
Definition: bgp_table.cc:840
~BgpTable()
Definition: bgp_table.cc:76
void Shutdown()
Definition: bgp_table.cc:1061
BgpTable(DB *db, const std::string &name)
Definition: bgp_table.cc:59
virtual void RetryDelete()
Definition: bgp_table.cc:1074
void CheckAggregatorAttr(BgpAttr *attr) const
Definition: bgp_table.cc:132
virtual bool IsRouteAggregationSupported() const
Definition: bgp_table.h:112
void PrependAsToAs4Path(BgpAttr *attr, as_t asn) const
Definition: bgp_table.cc:413
virtual BgpRoute * TableFind(DBTablePartition *rtp, const DBRequestKey *prefix)=0
static bool PathSelection(const Path &path1, const Path &path2)
Definition: bgp_table.cc:825
UpdateInfo * GetUpdateInfo(RibOut *ribout, BgpRoute *route, const RibPeerSet &peerset)
Definition: bgp_table.cc:582
RibOutMap ribout_map_
Definition: bgp_table.h:219
RibOut * RibOutFind(const RibExportPolicy &policy)
Definition: bgp_table.cc:99
void ProcessLlgrState(const RibOut *ribout, const BgpPath *path, BgpAttr *attr, bool llgr_stale_comm)
Definition: bgp_table.cc:306
void InputCommonPostProcess(DBTablePartBase *root, BgpRoute *rt, bool notify_rt)
Definition: bgp_table.cc:1016
std::atomic< uint64_t > secondary_path_count_
Definition: bgp_table.h:224
virtual Address::Family family() const =0
void FillRibOutStatisticsInfo(std::vector< ShowRibOutStatistics > *sros_list) const
Definition: bgp_table.cc:1156
bool IsDeleted() const
Definition: bgp_table.h:143
void CreateAsPath2Byte(BgpAttr *attr) const
Definition: bgp_table.cc:464
LifetimeRef< BgpTable > instance_delete_ref_
Definition: bgp_table.h:222
PathResolver * path_resolver_
Definition: bgp_table.h:218
LifetimeActor * deleter()
Definition: bgp_table.cc:1118
RibOut * RibOutLocate(BgpUpdateSender *sender, const RibExportPolicy &policy)
Definition: bgp_table.cc:109
BitSet & reset(size_t pos)
Definition: bitset.cc:137
bool empty() const
Definition: bitset.cc:166
BitSet & set(size_t pos)
Definition: bitset.cc:126
bool test(size_t pos) const
Definition: bitset.cc:147
const ClusterListSpec & cluster_list() const
Definition: bgp_attr.h:230
CommunityPtr RemoveAndLocate(const Community *src, const std::vector< uint32_t > &value)
Definition: community.cc:173
CommunityPtr AppendAndLocate(const Community *src, uint32_t value)
Definition: community.cc:134
const std::vector< uint32_t > & communities() const
Definition: community.h:68
bool ContainsValue(uint32_t value) const
Definition: community.cc:116
void ClearDelete()
Definition: db_entry.h:48
bool IsDeleted() const
Definition: db_entry.h:49
bool HasWalkers() const
Definition: db_table.h:129
bool HasListeners() const
Definition: db_table.cc:261
virtual bool MayDelete() const
Definition: db_table.cc:247
void Notify(DBEntryBase *entry)
void Delete(DBEntryBase *)
virtual size_t Size() const
Definition: db_table.cc:534
virtual DBEntry * Add(const DBRequest *req)
Definition: db_table.cc:430
Definition: db.h:25
static int PartitionCount()
Definition: db.cc:32
ExtCommunityPtr ReplaceTunnelEncapsulationAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &tunnel_encaps)
Definition: community.cc:969
std::vector< ExtCommunityValue > ExtCommunityList
Definition: community.h:156
Definition: ipeer.h:187
virtual uint32_t bgp_identifier() const =0
virtual const std::string & ToString() const =0
virtual bool CheckSplitHorizon(uint32_t cluster_id=0, uint32_t ribout_cid=0) const
Definition: ipeer.h:230
virtual bool IsReady() const =0
virtual bool IsRegistrationRequired() const =0
virtual BgpProto::BgpPeerType PeerType() const =0
virtual bool IsXmppPeer() const =0
virtual void UpdateCloseRouteStats(Address::Family family, const BgpPath *old_path, uint32_t path_flags) const =0
void RetryDelete()
Definition: lifetime.cc:74
void Reset(LifetimeActor *actor)
Definition: lifetime.h:83
void StopPathResolution(int part_id, const BgpPath *path)
void StartPathResolution(BgpRoute *route, const BgpPath *path, BgpTable *nh_table=NULL)
Definition: path.h:11
virtual void GetRibOutInterestedPeers(RibOut *ribout, const ExtCommunity *ext_community, const RibPeerSet &peerset, RibPeerSet *new_peerset)
size_t queue_size(int queue_id) const
size_t queue_marker_count(int queue_id) const
IPeerUpdate * Next()
Definition: bgp_ribout.h:273
bool HasNext() const
Definition: bgp_ribout.h:270
int index() const
Definition: bgp_ribout.h:278
bool IsEncodingBgp() const
Definition: bgp_ribout.h:333
RibOutUpdates * updates(int idx)
Definition: bgp_ribout.h:318
BgpProto::BgpPeerType peer_type() const
Definition: bgp_ribout.h:322
const RibExportPolicy & ExportPolicy() const
Definition: bgp_ribout.h:310
uint32_t cluster_id() const
Definition: bgp_ribout.h:349
void GetSubsetPeerSet(RibPeerSet *peerset, const IPeerUpdate *cpeer) const
Definition: bgp_ribout.cc:521
void FillStatisticsInfo(std::vector< ShowRibOutStatistics > *sros_list) const
Definition: bgp_ribout.cc:554
as_t local_as() const
Definition: bgp_ribout.h:324
bool llgr() const
Definition: bgp_ribout.h:326
bool remove_private_peer_loop_check() const
Definition: bgp_ribout.h:346
bool as_override() const
Definition: bgp_ribout.h:325
bool as4_supported() const
Definition: bgp_ribout.h:327
bool remove_private_all() const
Definition: bgp_ribout.h:342
const IpAddress & nexthop() const
Definition: bgp_ribout.h:329
as_t peer_as() const
Definition: bgp_ribout.h:323
bool remove_private_replace() const
Definition: bgp_ribout.h:343
bool IsEncodingXmpp() const
Definition: bgp_ribout.h:330
bool remove_private_enabled() const
Definition: bgp_ribout.h:339
const PathList & GetPathList() const
Definition: route.h:47
const Path * front() const
Definition: route.cc:17
RoutingInstance * GetDefaultRoutingInstance()
void DestroyDBTable(DBTable *table)
bool IsContributingRoute(const BgpTable *table, const BgpRoute *route) const
BgpServer * server()
LifetimeActor * deleter()
BgpTable * GetTable(Address::Family fmly)
bool IsMasterRoutingInstance() const
bool IsAggregateRoute(const BgpTable *table, const BgpRoute *route) const
const bytes_type & GetExtCommunity() const
Definition: tunnel_encap.h:29
boost::intrusive_ptr< const Community > CommunityPtr
Definition: community.h:112
boost::intrusive_ptr< const ExtCommunity > ExtCommunityPtr
Definition: community.h:451
std::vector< as_t > path_segment
Definition: bgp_aspath.h:375
As4PathSpec * Replace(as_t old_asn, as_t asn) const
Definition: bgp_aspath.cc:659
As4PathSpec * RemovePrivate(bool all, as_t asn, as_t peer_as) const
Definition: bgp_aspath.cc:681
std::vector< PathSegment * > path_segments
Definition: bgp_aspath.h:396
As4PathSpec * Add(as_t asn) const
Definition: bgp_aspath.cc:619
as_t AsLeftMostPublic() const
Definition: bgp_aspath.cc:534
std::vector< as_t > path_segment
Definition: bgp_aspath.h:215
AsPath4ByteSpec * Add(as_t asn) const
Definition: bgp_aspath.cc:393
std::vector< PathSegment * > path_segments
Definition: bgp_aspath.h:236
AsPath4ByteSpec * Replace(as_t old_asn, as_t asn) const
Definition: bgp_aspath.cc:433
AsPath4ByteSpec * RemovePrivate(bool all, as_t asn, as_t peer_as) const
Definition: bgp_aspath.cc:455
as_t AsLeftMostPublic() const
Definition: bgp_aspath.cc:308
std::vector< as2_t > path_segment
Definition: bgp_aspath.h:59
as2_t AsLeftMostPublic() const
Definition: bgp_aspath.cc:46
AsPathSpec * Replace(as2_t old_asn, as2_t asn) const
Definition: bgp_aspath.cc:207
AsPathSpec * Add(as2_t asn) const
Definition: bgp_aspath.cc:131
std::vector< PathSegment * > path_segments
Definition: bgp_aspath.h:80
AsPathSpec * RemovePrivate(bool all, as2_t asn, as2_t peer_as) const
Definition: bgp_aspath.cc:229
const NextHop & nexthop()
Definition: bgp_table.h:82
uint64_t subscription_gen_id() const
Definition: bgp_table.h:88
BgpAttrPtr & attrs()
Definition: bgp_table.h:83
bool ClusterListLoop(uint32_t cluster_id) const
Definition: bgp_attr.cc:224
DBOperation oper
Definition: db_table.h:43
@ DB_ENTRY_NOTIFY
Definition: db_table.h:41
@ DB_ENTRY_DELETE
Definition: db_table.h:40
@ DB_ENTRY_ADD_CHANGE
Definition: db_table.h:39
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:49
std::unique_ptr< DBRequestData > data
Definition: db_table.h:50
std::vector< std::string > default_tunnel_encap_list
RibOutAttr roattr
Definition: bgp_update.h:101
RibPeerSet target
Definition: bgp_update.h:104
#define CHECK_CONCURRENCY(...)