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