OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 using boost::scoped_ptr;
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  scoped_ptr<As4PathSpec> new_as_path(new As4PathSpec);
431  const AsPathSpec &as_path = attr->as_path()->path();
432  for (size_t i = 0; i < as_path.path_segments.size(); i++) {
434  AsPathSpec::PathSegment *ps = as_path.path_segments[i];
436  for (size_t j = 0; j < ps->path_segment.size(); j++) {
437  as_t as = ps->path_segment[j];
438  ps4->path_segment.push_back(as);
439  }
440  new_as_path->path_segments.push_back(ps4);
441  }
442  attr->set_as4_path(new_as_path.get());
443  }
444 }
445 
446 // Check if aspath_4byte has any asn > 0xFFFF
447 bool BgpTable::Has4ByteAsn(BgpAttr *attr) const {
448  if (!attr->aspath_4byte())
449  return false;
450  const AsPath4ByteSpec &as_path4 = attr->aspath_4byte()->path();
451  for (size_t i = 0; i < as_path4.path_segments.size(); ++i) {
452  AsPath4ByteSpec::PathSegment *ps4 = as_path4.path_segments[i];
453  for (size_t j = 0; j < ps4->path_segment.size(); ++j) {
454  if (ps4->path_segment[j] > AS2_MAX)
455  return true;
456  }
457  }
458  return false;
459 }
460 
461 // Create as_path (and as4_path) from as_path4byte
463  scoped_ptr<AsPathSpec> new_as_path(new AsPathSpec);
464  As4PathSpec *new_as4_path = NULL;
465  bool has_4byte_asn = Has4ByteAsn(attr);
466  if (has_4byte_asn)
467  new_as4_path = new As4PathSpec;
468  if (attr->aspath_4byte()) {
469  const AsPath4ByteSpec &as_path4 = attr->aspath_4byte()->path();
470  for (size_t i = 0; i < as_path4.path_segments.size(); i++) {
472  As4PathSpec::PathSegment *as4_ps = NULL;
473  AsPath4ByteSpec::PathSegment *ps4 = as_path4.path_segments[i];
475  if (has_4byte_asn) {
476  as4_ps = new As4PathSpec::PathSegment;
477  as4_ps->path_segment_type = ps4->path_segment_type;
478  }
479  for (size_t j = 0; j < ps4->path_segment.size(); ++j) {
480  as_t as4 = ps4->path_segment[j];
481  if (as4 > AS2_MAX) {
482  as2_t as_trans = AS_TRANS;
483  ps->path_segment.push_back(as_trans);
484  } else {
485  ps->path_segment.push_back(static_cast<as2_t>(
486  as4 & AS2_MAX));
487  }
488  if (has_4byte_asn)
489  as4_ps->path_segment.push_back(as4);
490  }
491  new_as_path->path_segments.push_back(ps);
492  if (has_4byte_asn)
493  new_as4_path->path_segments.push_back(as4_ps);
494  }
495  attr->set_aspath_4byte(NULL);
496  }
497  attr->set_as_path(new_as_path.get());
498  if (has_4byte_asn)
499  attr->set_as4_path(new_as4_path);
500 }
501 
502 // Create aspath_4byte by merging as_path and as4_path
503 void BgpTable::CreateAsPath4Byte(BgpAttr *attr, as_t local_as) const {
504  int as2_count = attr->as_path_count();
505  int as4_count = attr->as4_path_count();
506  if (as2_count < as4_count) {
507  as4_count = 0;
508  attr->set_as4_path(NULL);
509  }
510  AsPath4ByteSpec::PathSegment *ps4 = NULL;
511  bool part_segment = false;
512  scoped_ptr<AsPath4ByteSpec> aspath_4byte(new AsPath4ByteSpec);
513  if (attr->as_path()) {
514  const AsPathSpec &as_path = attr->as_path()->path();
515  int new_as_count = 0;
516  for (size_t i = 0; i < as_path.path_segments.size() &&
517  new_as_count < (as2_count - as4_count) ; ++i) {
519  AsPathSpec::PathSegment *ps = as_path.path_segments[i];
522  new_as_count++;
523  for (size_t j = 0; j < ps->path_segment.size(); ++j) {
524  as2_t as = ps->path_segment[j];
525  ps4->path_segment.push_back(as);
526  }
527  } else {
528  for (size_t j = 0; j < ps->path_segment.size() &&
529  new_as_count < (as2_count - as4_count); ++j) {
530  new_as_count++;
531  as2_t as = ps->path_segment[j];
532  ps4->path_segment.push_back(as);
533  }
534  if (new_as_count == (as2_count - as4_count)) {
535  if (attr->as4_path()) {
536  part_segment = true;
537  break;
538  }
539  }
540  }
541  aspath_4byte->path_segments.push_back(ps4);
542  }
543  if (attr->as4_path()) {
544  const As4PathSpec &as4_path = attr->as4_path()->path();
545  for (size_t i = 0; i < as4_path.path_segments.size(); ++i) {
546  if (!part_segment) {
548  }
549  part_segment = false;
550  As4PathSpec::PathSegment *ps = as4_path.path_segments[i];
553  new_as_count++;
554  for (size_t j = 0; j < ps->path_segment.size(); ++j) {
555  as2_t as = ps->path_segment[j];
556  ps4->path_segment.push_back(as);
557  }
558  } else {
559  for (size_t j = 0; j < ps->path_segment.size(); ++j) {
560  as_t as = ps->path_segment[j];
561  ps4->path_segment.push_back(as);
562  }
563  }
564  aspath_4byte->path_segments.push_back(ps4);
565  }
566  attr->set_as4_path(NULL);
567  }
568  attr->set_as_path(NULL);
569  }
570  if (local_as) {
571  scoped_ptr<AsPath4ByteSpec> as_path_spec(aspath_4byte->Add(local_as));
572  attr->set_aspath_4byte(as_path_spec.get());
573  } else {
574  attr->set_aspath_4byte(aspath_4byte.get());
575  }
576 }
577 
579  const RibPeerSet &peerset) {
580  const BgpPath *path = route->BestPath();
581 
582  // Ignore if there is no best-path.
583  if (!path)
584  return NULL;
585 
586  // Don't advertise infeasible paths.
587  if (!path->IsFeasible())
588  return NULL;
589 
590  // Check whether the route is contributing route
592  return NULL;
593 
594  // Needs to be outside the if block so it's not destroyed prematurely.
595  BgpAttrPtr attr_ptr;
596  const BgpAttr *attr = path->GetAttr();
597 
598  RibPeerSet new_peerset = peerset;
599 
600  // LocalPref, Med and AsPath manipulation is needed only if the RibOut
601  // has BGP encoding. Similarly, well-known communities do not apply if
602  // the encoding is not BGP.
603  if (ribout->IsEncodingBgp()) {
604  // Handle well-known communities.
605  if (attr->community() != NULL &&
606  attr->community()->communities().size()) {
607  BOOST_FOREACH(uint32_t value, attr->community()->communities()) {
608  if (value == CommunityType::NoAdvertise)
609  return NULL;
610 
611  if ((ribout->peer_type() == BgpProto::EBGP) &&
612  ((value == CommunityType::NoExport) ||
613  (value == CommunityType::NoExportSubconfed))) {
614  return NULL;
615  }
616  }
617  }
618 
619  const IPeer *peer = path->GetPeer();
620  BgpAttr *clone = NULL;
621  bool llgr_stale_comm = attr->community() &&
623  if (ribout->peer_type() == BgpProto::IBGP) {
624  // Split horizon check.
625  if (peer && peer->CheckSplitHorizon(server()->cluster_id(),
626  ribout->cluster_id()))
627  return NULL;
628 
629  // Handle route-target filtering.
630  if (IsVpnTable() && attr->ext_community() != NULL) {
632  ribout, attr->ext_community(), peerset, &new_peerset);
633  if (new_peerset.empty())
634  return NULL;
635  }
636 
637  if (server()->cluster_id()) {
638  // Check if there is a loop in cluster_list
639  if (attr->cluster_list() && attr->cluster_list()->cluster_list()
640  .ClusterListLoop(server()->cluster_id())) {
641  return NULL;
642  }
643  }
644 
645  if (server()->cluster_id() && (family() != Address::RTARGET)) {
646  // route reflector should not reflect the route back to the peer
647  // from which it received that route, for non rtarget routes
648  // This is done by checking peer_router_id of all the feasible
649  // paths of this route
650  RibPeerSet route_peerset;
651  for (Route::PathList::iterator it= route->GetPathList().begin();
652  it != route->GetPathList().end(); it++) {
653  BgpPath *ipath = static_cast<BgpPath *>(it.operator->());
654  if (ipath->IsFeasible() && ipath->GetPeer()) {
655  const IPeer *ipeer = ipath->GetPeer();
656  const BgpPeer *bgp_peer = dynamic_cast<
657  const BgpPeer *>(ipeer);
658  if (bgp_peer)
659  route_peerset.set(bgp_peer->GetIndex());
660  }
661  }
662  RibOut::PeerIterator iter(ribout, new_peerset);
663  while (iter.HasNext()) {
664  int current_index = iter.index();
665  IPeerUpdate *peer = iter.Next();
666  const BgpPeer *bgp_peer = dynamic_cast<
667  const BgpPeer *>(peer);
668  if (bgp_peer && route_peerset.test(bgp_peer->GetIndex()))
669  new_peerset.reset(current_index);
670  }
671  if (new_peerset.empty())
672  return NULL;
673  }
674 
675  clone = new BgpAttr(*attr);
676 
677  // Retain LocalPref value if set, else set default to 100.
678  if (clone->local_pref() == 0)
679  clone->set_local_pref(100);
680 
681  // Check aggregator attributes to identify which ones to be used
682  CheckAggregatorAttr(clone);
683 
684  // Should not normally be needed for iBGP, but there could be
685  // complex configurations where this is useful.
686  ProcessRemovePrivate(ribout, clone);
687 
688  // Add Originator_Id if acting as route reflector and cluster_id
689  // is not present
690  if (server()->cluster_id()) {
691  if (clone->originator_id().is_unspecified()) {
692  if (peer && (peer->bgp_identifier() != 0)) {
694  peer->bgp_identifier()));
695  } else {
697  server()->bgp_identifier()));
698  }
699  }
700  if (attr->cluster_list()) {
701  const ClusterListSpec &cluster =
702  clone->cluster_list()->cluster_list();
703  ClusterListSpec *cl_ptr = new ClusterListSpec(
704  server()->cluster_id(), &cluster);
705  clone->set_cluster_list(cl_ptr);
706  delete cl_ptr;
707  } else {
708  ClusterListSpec *cl_ptr = new ClusterListSpec(
709  server()->cluster_id(), NULL);
710  clone->set_cluster_list(cl_ptr);
711  delete cl_ptr;
712  }
713  }
714  // If the route is locally originated i.e. there's no AsPath,
715  // then generate a Nil AsPath i.e. one with 0 length. No need
716  // to modify the AsPath if it already exists since this is an
717  // iBGP RibOut.
718  if (ribout->as4_supported() && !clone->aspath_4byte()) {
719  if (attr->as_path()) {
720  CreateAsPath4Byte(clone, 0);
721  } else {
722  AsPath4ByteSpec as_path;
723  clone->set_aspath_4byte(&as_path);
724  }
725  }
726  if (!ribout->as4_supported() && !clone->as_path()) {
727  if (attr->aspath_4byte()) {
728  CreateAsPath2Byte(clone);
729  } else {
730  AsPathSpec as_path;
731  clone->set_as_path(&as_path);
732  }
733  }
734  } else if (ribout->peer_type() == BgpProto::EBGP) {
735  // Don't advertise routes from non-master instances if there's
736  // no nexthop. The ribout has to be for bgpaas-clients because
737  // that's the only case with bgp peers in non-master instance.
739  ribout->nexthop().is_unspecified()) {
740  return NULL;
741  }
742 
743  // Handle route-target filtering.
744  if (IsVpnTable() && attr->ext_community() != NULL) {
746  ribout, attr->ext_community(), peerset, &new_peerset);
747  if (new_peerset.empty())
748  return NULL;
749  }
750 
751  // Sender side AS path loop check and split horizon within RibOut.
752  if (!ribout->as_override()) {
753  if (attr->IsAsPathLoop(ribout->peer_as()))
754  return NULL;
755  } else {
756  if (peer && peer->PeerType() == BgpProto::EBGP) {
757  ribout->GetSubsetPeerSet(&new_peerset, peer);
758  if (new_peerset.empty())
759  return NULL;
760  }
761  }
762 
763  clone = new BgpAttr(*attr);
764 
765  // Remove non-transitive attributes.
766  // Note that med is handled further down.
767  clone->set_originator_id(Ip4Address());
768  clone->set_cluster_list(NULL);
769 
770  // Update nexthop.
771  if (!ribout->nexthop().is_unspecified())
772  clone->set_nexthop(ribout->nexthop());
773 
774  // Reset LocalPref.
775  if (clone->local_pref())
776  clone->set_local_pref(0);
777 
778  // Reset Med if the path did not originate from an xmpp peer.
779  // The AS path is NULL if the originating xmpp peer is locally
780  // connected. It's non-NULL but empty if the originating xmpp
781  // peer is connected to another bgp speaker in the iBGP mesh.
782  if (clone->med() && !clone->IsAsPathEmpty())
783  clone->set_med(0);
784 
785  // Override the peer AS with local AS in AsPath.
786  ProcessAsOverride(ribout, clone);
787 
788  // Remove private processing must happen before local AS prepend.
789  ProcessRemovePrivate(ribout, clone);
790 
791  // Prepend the local AS to AsPath.
792  PrependLocalAs(ribout, clone, peer);
793  }
794 
795  assert(clone);
796 
797  // Update with the Default tunnel Encapsulation ordered List if
798  // configured on the peer.
799  // Note that all peers with the same list share the same Ribout, this is
800  // ensured by making the Default Encapsulation List part of the Rib
801  // Export policy.Note that, if there is Default Tunnel Encapsulation
802  // configuration any tunnel encapsulation present is removed.
803  ProcessDefaultTunnelEncapsulation(ribout, server()->extcomm_db(),
804  clone);
805 
806  ProcessLlgrState(ribout, path, clone, llgr_stale_comm);
807 
808  // Locate the new BgpAttrPtr.
809  attr_ptr = clone->attr_db()->Locate(clone);
810  attr = attr_ptr.get();
811  }
812 
813  UpdateInfo *uinfo = new UpdateInfo;
814  uinfo->target = new_peerset;
815  uinfo->roattr = RibOutAttr(route, attr, ribout->IsEncodingXmpp());
816  return uinfo;
817 }
818 
819 // Bgp Path selection..
820 // Based Attribute weight
821 bool BgpTable::PathSelection(const Path &path1, const Path &path2) {
822  const BgpPath &l_path = dynamic_cast<const BgpPath &> (path1);
823  const BgpPath &r_path = dynamic_cast<const BgpPath &> (path2);
824 
825  // Check the weight of Path
826  bool res = l_path.PathCompare(r_path, false) < 0;
827 
828  return res;
829 }
830 
832  return InputCommon(root, rt, path, path->GetPeer(), NULL,
833  DBRequest::DB_ENTRY_DELETE, NULL, path->GetPathId(), 0, 0, 0);
834 }
835 
837  const IPeer *peer, DBRequest *req,
839  uint32_t path_id, uint32_t flags, uint32_t label,
840  uint32_t l3_label) {
841  bool notify_rt = false;
842 
843  switch (oper) {
845  assert(rt);
846 
847  // The entry may currently be marked as deleted.
848  rt->ClearDelete();
849  if (peer)
850  peer->UpdateCloseRouteStats(family(), path, flags);
851 
852  // Check whether peer already has a path.
853  if (path != NULL) {
854  if ((path->GetAttr() != attrs.get()) ||
855  (path->GetFlags() != flags) ||
856  (path->GetLabel() != label) ||
857  (path->GetL3Label() != l3_label)) {
858  // Update Attributes and notify (if needed)
859  if (path->NeedsResolution())
860  path_resolver_->StopPathResolution(root->index(), path);
861  rt->DeletePath(path);
862  } else {
863  // Ignore duplicate update.
864  break;
865  }
866  }
867 
868  BgpPath *new_path;
869  new_path = new BgpPath(
870  peer, path_id, BgpPath::BGP_XMPP, attrs, flags, label, l3_label);
871 
872  // Start path resolution for the new path if
873  // (1) Path flag has ResolveNextHop set in which case the path will
874  // be resolved in the overlay routing table (or)
875  // (2) Fast convergence knob is enabled in which case the path will
876  // be marked for resolution in the underlay (default) routing table
877  // (3) Path resolution in this case is needed only for routes
878  // in the VRF routing tables and for INET, INET6 and EVPN
879  // address families.
880  bool fc_family = false;
881  if (family() == Address::INET || family() == Address::INET6 ||
882  family() == Address::EVPN) {
883  fc_family = true;
884  }
885  bool fc_enabled = (server()->IsNextHopCheckEnabled() &&
886  !rtinstance_->IsMasterRoutingInstance() && fc_family);
887  if (new_path->NeedsResolution() || fc_enabled) {
888  Address::Family family = new_path->GetAttr()->nexthop_family();
889  BgpTable *table;
890  if (new_path->NeedsResolution()) {
891  table = rtinstance_->GetTable(family);
892  } else {
893  // Fast convergence knob is enabled.
894  // Update path flag to indicate need for resolution.
895  new_path->SetResolveNextHop();
896 
897  // Get the default table.
899  assert(mgr);
900  RoutingInstance *master_ri = mgr->GetDefaultRoutingInstance();
901  assert(master_ri);
902  table = master_ri->GetTable(family);
903  }
904  path_resolver_->StartPathResolution(rt, new_path, table);
905  }
906 
907  rt->InsertPath(new_path);
908  notify_rt = true;
909  break;
910  }
911 
913  if (rt && !rt->IsDeleted()) {
914  BGP_LOG_ROUTE(this, const_cast<IPeer *>(peer), rt,
915  "Delete BGP path");
916 
917  // Remove the Path from the route
918  if (path->NeedsResolution())
919  path_resolver_->StopPathResolution(root->index(), path);
920  rt->DeletePath(path);
921  notify_rt = true;
922  }
923  break;
924  }
925 
926  default: {
927  assert(false);
928  break;
929  }
930  }
931  return notify_rt;
932 }
933 
935  DBRequest *req) {
936  const IPeer *peer = (static_cast<RequestKey *>(req->key.get()))->GetPeer();
937  RequestData *data = static_cast<RequestData *>(req->data.get());
938 
939  if (req->oper == DBRequest::DB_ENTRY_ADD_CHANGE && peer) {
940  // Skip if this peer is down.
941  if (!peer->IsReady())
942  return;
943 
944  // For xmpp peers, verify that agent is subscribed to the table and
945  // the route add is from the same incarnation of table subscription.
946  if (peer->IsXmppPeer() && peer->IsRegistrationRequired()) {
948  int instance_id = -1;
949  uint64_t subscription_gen_id = 0;
950  bool is_registered =
951  mgr->GetRegistrationInfo(const_cast<IPeer *>(peer), this,
952  &instance_id, &subscription_gen_id);
953  if ((!is_registered && (family() != Address::RTARGET)) ||
954  (is_registered &&
955  (subscription_gen_id != data->subscription_gen_id()))) {
956  return;
957  }
958  }
959  }
960 
961  // Create route if it's not already present in case of add/change.
962  BgpRoute *rt = TableFind(root, req->key.get());
963  if (!rt) {
964  if ((req->oper == DBRequest::DB_ENTRY_DELETE) ||
966  return;
967 
968  rt = static_cast<BgpRoute *>(Add(req));
969  static_cast<DBTablePartition *>(root)->Add(rt);
970  BGP_LOG_ROUTE(this, const_cast<IPeer *>(peer), rt,
971  "Insert new BGP path");
972  }
973 
974  if (req->oper == DBRequest::DB_ENTRY_NOTIFY) {
975  root->Notify(rt);
976  return;
977  }
978 
979  uint32_t path_id = 0;
980  uint32_t flags = 0;
981  uint32_t label = 0;
982  uint32_t l3_label = 0;
983  BgpPath *path = rt->FindPath(peer);
984  BgpAttrPtr attr = data ? data->attrs() : NULL;
985  if (req->oper == DBRequest::DB_ENTRY_ADD_CHANGE) {
986  assert(data);
987  const RequestData::NextHop &nexthop = data->nexthop();
988  if (nexthop.address_.is_v4())
989  path_id = nexthop.address_.to_v4().to_ulong();
990  flags = nexthop.flags_;
991  label = nexthop.label_;
992  l3_label = nexthop.l3_label_;
993 
994  attr = GetAttributes(rt, attr, peer);
995  } else {
996  if (!path)
997  return;
998  path_id = path->GetPathId();
999  }
1000 
1001  bool notify_rt = InputCommon(root, rt, path, peer, req, req->oper,
1002  attr, path_id, flags, label, l3_label);
1003  InputCommonPostProcess(root, rt, notify_rt);
1004 }
1005 
1007  BgpRoute *rt, bool notify_rt) {
1008  if (!notify_rt)
1009  return;
1010 
1011  if (rt->front() == NULL)
1012  root->Delete(rt);
1013  else
1014  root->Notify(rt);
1015 }
1016 
1017 bool BgpTable::MayDelete() const {
1018  CHECK_CONCURRENCY("bgp::Config");
1019 
1020  // Bail if the table has listeners.
1021  if (HasListeners()) {
1022  BGP_LOG_TABLE(this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
1023  "Paused table deletion due to pending listeners");
1024  return false;
1025  }
1026 
1027  // Bail if the table has walkers.
1028  if (HasWalkers()) {
1029  BGP_LOG_TABLE(this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
1030  "Paused table deletion due to pending walkers");
1031  return false;
1032  }
1033 
1034  // Bail if the table is not empty.
1035  size_t size = Size();
1036  if (size > 0) {
1037  BGP_LOG_TABLE(this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
1038  "Paused table deletion due to " << size <<
1039  " pending routes");
1040  return false;
1041  }
1042 
1043  // Check the base class at the end so that we add custom checks
1044  // before this if needed and to get more informative log message.
1045  if (!DBTableBase::MayDelete())
1046  return false;
1047 
1048  return true;
1049 }
1050 
1052  CHECK_CONCURRENCY("bgp::PeerMembership", "bgp::Config");
1053 }
1054 
1056  BGP_LOG_TABLE(this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
1057  "Received request for table deletion");
1058  deleter_->Delete();
1059 }
1060 
1061 //
1062 // Retry deletion of the table if it is pending.
1063 //
1065  if (!deleter()->IsDeleted())
1066  return;
1067  deleter()->RetryDelete();
1068 }
1069 
1071  return NULL;
1072 }
1073 
1075  if (path_resolver_)
1076  return;
1077  assert(!deleter()->IsDeleted());
1079 }
1080 
1082  if (!path_resolver_)
1083  return;
1084  delete path_resolver_;
1085  path_resolver_ = NULL;
1086 }
1087 
1088 size_t BgpTable::GetPendingRiboutsCount(size_t *markers) const {
1089  CHECK_CONCURRENCY("bgp::ShowCommand", "bgp::Config");
1090  size_t count = 0;
1091  *markers = 0;
1092 
1093  BOOST_FOREACH(const RibOutMap::value_type &value, ribout_map_) {
1094  const RibOut *ribout = value.second;
1095  for (int idx = 0; idx < DB::PartitionCount(); ++idx) {
1096  const RibOutUpdates *updates = ribout->updates(idx);
1097  for (int qid = RibOutUpdates::QFIRST; qid < RibOutUpdates::QCOUNT;
1098  ++qid) {
1099  count += updates->queue_size(qid);
1100  *markers += updates->queue_marker_count(qid);
1101  }
1102  }
1103  }
1104 
1105  return count;
1106 }
1107 
1109  return deleter_.get();
1110 }
1111 
1113  return deleter_.get();
1114 }
1115 
1116 void BgpTable::UpdatePathCount(const BgpPath *path, int count) {
1117  if (dynamic_cast<const BgpSecondaryPath *>(path)) {
1118  secondary_path_count_ += count;
1119  } else {
1120  primary_path_count_ += count;
1121  }
1122 
1123  if (!path->IsFeasible()) {
1124  infeasible_path_count_ += count;
1125  }
1126 
1127  if (path->IsStale()) {
1128  stale_path_count_ += count;
1129  }
1130 
1131  if (path->IsLlgrStale()) {
1132  llgr_stale_path_count_ += count;
1133  }
1134 }
1135 
1136 // Check whether the route is aggregate route
1137 bool BgpTable::IsAggregateRoute(const BgpRoute *route) const {
1138  return routing_instance()->IsAggregateRoute(this, route);
1139 }
1140 
1141 // Check whether the route is contributing route to aggregate route
1142 bool BgpTable::IsContributingRoute(const BgpRoute *route) const {
1143  return routing_instance()->IsContributingRoute(this, route);
1144 }
1145 
1147  vector<ShowRibOutStatistics> *sros_list) const {
1148  BOOST_FOREACH(const RibOutMap::value_type &value, ribout_map_) {
1149  const RibOut *ribout = value.second;
1150  ribout->FillStatisticsInfo(sros_list);
1151  }
1152 }
bool HasWalkers() const
Definition: db_table.h:128
void UpdatePathCount(const BgpPath *path, int count)
Definition: bgp_table.cc:1116
const Community * community() const
Definition: bgp_attr.h:914
tbb::atomic< uint64_t > stale_path_count_
Definition: bgp_table.h:226
bool IsNextHopCheckEnabled() const
Definition: bgp_server.cc:690
const std::vector< uint32_t > & communities() const
Definition: community.h:65
virtual void Shutdown()
Definition: bgp_table.cc:44
int index() const
Definition: bgp_ribout.h:276
void PrependLocalAs(const RibOut *ribout, BgpAttr *attr, const IPeer *) const
Definition: bgp_table.cc:148
bool remove_private_enabled() const
Definition: bgp_ribout.h:337
const ClusterListSpec & cluster_list() const
Definition: bgp_attr.h:229
uint32_t local_pref() const
Definition: bgp_attr.h:889
void RemovePrivate4ByteAs(const RibOut *ribout, BgpAttr *attr) const
Definition: bgp_table.cc:199
BgpTable * GetTable(Address::Family fmly)
const BgpPath * BestPath() const
Definition: bgp_route.cc:46
TypePtr Locate(Type *attr)
RibOutAttr roattr
Definition: bgp_update.h:100
void ProcessLlgrState(const RibOut *ribout, const BgpPath *path, BgpAttr *attr, bool llgr_stale_comm)
Definition: bgp_table.cc:306
const AsPathSpec & path() const
Definition: bgp_aspath.h:127
void CheckAggregatorAttr(BgpAttr *attr) const
Definition: bgp_table.cc:132
void CreateAsPath2Byte(BgpAttr *attr) const
Definition: bgp_table.cc:462
bool test(size_t pos) const
Definition: bitset.cc:146
void set_nexthop(IpAddress nexthop)
Definition: bgp_attr.h:837
virtual bool IsXmppPeer() const =0
virtual uint32_t bgp_identifier() const =0
void InputCommonPostProcess(DBTablePartBase *root, BgpRoute *rt, bool notify_rt)
Definition: bgp_table.cc:1006
const IpAddress & nexthop() const
Definition: bgp_ribout.h:327
virtual BgpProto::BgpPeerType PeerType() const =0
UpdateInfo * GetUpdateInfo(RibOut *ribout, BgpRoute *route, const RibPeerSet &peerset)
Definition: bgp_table.cc:578
AsPath4ByteSpec * Replace(as_t old_asn, as_t asn) const
Definition: bgp_aspath.cc:432
size_t queue_size(int queue_id) const
void CreateAs4Path(BgpAttr *attr) const
Definition: bgp_table.cc:428
BgpServer * server()
void set_cluster_list(const ClusterListSpec *spec)
Definition: bgp_attr.cc:991
uint32_t cluster_id() const
Definition: bgp_ribout.h:347
bool llgr() const
Definition: bgp_ribout.h:324
virtual void Input(DBTablePartition *root, DBClient *client, DBRequest *req)
Definition: bgp_table.cc:934
BitSet & reset(size_t pos)
Definition: bitset.cc:136
void PrependAsToAsPath2Byte(BgpAttr *attr, as_t asn) const
Definition: bgp_table.cc:382
RoutingInstance * rtinstance_
Definition: bgp_table.h:217
std::vector< PathSegment * > path_segments
Definition: bgp_aspath.h:235
AsPathSpec * Add(as2_t asn) const
Definition: bgp_aspath.cc:130
virtual bool IsVpnTable() const
Definition: bgp_table.h:110
RoutingInstance * routing_instance()
Definition: bgp_table.h:148
bool as4_supported() const
Definition: bgp_ribout.h:325
Family
Definition: address.h:24
virtual void Destroy()
Definition: bgp_table.cc:51
bool IsDeleted() const
Definition: db_entry.h:49
CommunityDB * comm_db()
Definition: bgp_server.h:184
bool IsStale() const
Definition: bgp_path.h:107
virtual BgpRoute * TableFind(DBTablePartition *rtp, const DBRequestKey *prefix)=0
const RibExportPolicy & ExportPolicy() const
Definition: bgp_ribout.h:308
virtual void UpdateCloseRouteStats(Address::Family family, const BgpPath *old_path, uint32_t path_flags) const =0
BgpProto::BgpPeerType peer_type() const
Definition: bgp_ribout.h:320
void RemovePrivateAs(const RibOut *ribout, BgpAttr *attr) const
Definition: bgp_table.cc:167
bool as_override() const
Definition: bgp_ribout.h:323
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
as_t AsLeftMostPublic() const
Definition: bgp_aspath.cc:307
CommunityPtr RemoveAndLocate(const Community *src, const std::vector< uint32_t > &value)
Definition: community.cc:170
#define BGP_LOG_ROUTE(table, peer, route, arg)
Definition: bgp_log.h:247
void StartPathResolution(BgpRoute *route, const BgpPath *path, BgpTable *nh_table=NULL)
RoutingInstanceMgr * routing_instance_mgr()
Definition: bgp_server.h:102
const uint32_t GetPathId() const
Definition: bgp_path.h:78
virtual DBEntry * Add(const DBRequest *req)
Definition: db_table.cc:403
std::vector< as_t > path_segment
Definition: bgp_aspath.h:214
void ProcessRemovePrivate(const RibOut *ribout, BgpAttr *attr) const
Definition: bgp_table.cc:244
void set_community(CommunityPtr comm)
Definition: bgp_attr.cc:999
void LocatePathResolver()
Definition: bgp_table.cc:1074
void ProcessAsOverride(const RibOut *ribout, BgpAttr *attr) const
Definition: bgp_table.cc:261
const BgpPath * FindPath(BgpPath::PathSource src) const
Definition: bgp_route.cc:145
RoutingInstance * GetDefaultRoutingInstance()
const Ip4Address & originator_id() const
Definition: bgp_attr.h:895
const IpAddress & aggregator_adderess() const
Definition: bgp_attr.h:894
virtual bool IsReady() const =0
virtual PathResolver * CreatePathResolver()
Definition: bgp_table.cc:1070
void Delete(DBEntryBase *)
bool HasNext() const
Definition: bgp_ribout.h:268
void PrependAsToAs4Path(BgpAttr *attr, as_t asn) const
Definition: bgp_table.cc:413
virtual Address::Family family() const =0
uint32_t GetFlags() const
Definition: bgp_path.h:100
uint32_t as_t
Definition: bgp_common.h:21
Definition: ipeer.h:186
tbb::atomic< uint64_t > infeasible_path_count_
Definition: bgp_table.h:225
size_t queue_marker_count(int queue_id) const
bool empty() const
Definition: bitset.cc:165
tbb::atomic< uint64_t > llgr_stale_path_count_
Definition: bgp_table.h:227
void set_as_path(AsPathPtr aspath)
Definition: bgp_attr.cc:955
bool GetRegistrationInfo(const IPeer *peer, const BgpTable *table, int *instance_id=NULL, uint64_t *subscription_gen_id=NULL) const
void RetryDelete()
Definition: lifetime.cc:71
virtual bool MayDelete() const
Definition: bgp_table.cc:40
void set_aggregator(as_t as_num, IpAddress address)
Definition: bgp_attr.h:841
As4PathSpec * Add(as_t asn) const
Definition: bgp_aspath.cc:618
int IsAsPathLoop(as_t asn, uint8_t max_loop_count=0) const
Definition: bgp_attr.cc:1214
uint32_t GetL3Label() const
Definition: bgp_path.h:90
as_t local_autonomous_system() const
Definition: bgp_server.h:207
BgpAttrDB * attr_db()
Definition: bgp_attr.h:928
std::vector< PathSegment * > path_segments
Definition: bgp_aspath.h:79
bool IsDeleted() const
Definition: bgp_table.h:143
Definition: db.h:24
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:991
RibOutMap ribout_map_
Definition: bgp_table.h:219
virtual size_t Size() const
Definition: db_table.cc:507
void DestroyDBTable(DBTable *table)
bool IsAggregateRoute(const BgpTable *table, const BgpRoute *route) const
bool IsFeasible() const
Definition: bgp_path.h:92
bool IsAggregateRoute(const BgpRoute *route) const
Definition: bgp_table.cc:1137
virtual bool CheckSplitHorizon(uint32_t cluster_id=0, uint32_t ribout_cid=0) const
Definition: ipeer.h:229
BgpTable(DB *db, const std::string &name)
Definition: bgp_table.cc:59
as_t AsLeftMostPublic() const
Definition: bgp_aspath.cc:533
AsPathSpec * RemovePrivate(bool all, as2_t asn, as2_t peer_as) const
Definition: bgp_aspath.cc:228
const AsPath4Byte * aspath_4byte() const
Definition: bgp_attr.h:902
virtual bool MayDelete() const
Definition: bgp_table.cc:1017
RibPeerSet target
Definition: bgp_update.h:103
const ClusterList * cluster_list() const
Definition: bgp_attr.h:907
Definition: path.h:10
uint16_t as2_t
Definition: bgp_common.h:22
void Reset(LifetimeActor *actor)
Definition: lifetime.h:82
CommunityPtr AppendAndLocate(const Community *src, uint32_t value)
Definition: community.cc:131
virtual void RetryDelete()
Definition: bgp_table.cc:1064
BgpAttrPtr & attrs()
Definition: bgp_table.h:83
void GetSubsetPeerSet(RibPeerSet *peerset, const IPeerUpdate *cpeer) const
Definition: bgp_ribout.cc:512
boost::scoped_ptr< DeleteActor > deleter_
Definition: bgp_table.h:221
boost::intrusive_ptr< const ExtCommunity > ExtCommunityPtr
Definition: community.h:448
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
void ManagedDelete()
Definition: bgp_table.cc:1055
bool ContainsValue(uint32_t value) const
Definition: community.cc:113
DBOperation oper
Definition: db_table.h:42
void RemovePrivateAs4(const RibOut *ribout, BgpAttr *attr) const
Definition: bgp_table.cc:220
int as4_path_count() const
Definition: bgp_attr.h:912
#define CHECK_CONCURRENCY(...)
bool remove_private_all() const
Definition: bgp_ribout.h:340
void DestroyPathResolver()
Definition: bgp_table.cc:1081
As4PathSpec * RemovePrivate(bool all, as_t asn, as_t peer_as) const
Definition: bgp_aspath.cc:680
bool IsContributingRoute(const BgpTable *table, const BgpRoute *route) const
bool IsEncodingBgp() const
Definition: bgp_ribout.h:331
RibOut * RibOutLocate(BgpUpdateSender *sender, const RibExportPolicy &policy)
Definition: bgp_table.cc:109
tbb::atomic< uint64_t > primary_path_count_
Definition: bgp_table.h:223
RibOut * RibOutFind(const RibExportPolicy &policy)
Definition: bgp_table.cc:99
as_t aggregator_as4_num() const
Definition: bgp_attr.h:892
IPeer * GetPeer()
Definition: bgp_path.h:76
LifetimeRef< BgpTable > instance_delete_ref_
Definition: bgp_table.h:222
virtual bool IsRouteAggregationSupported() const
Definition: bgp_table.h:112
AsPath4ByteSpec * Add(as_t asn) const
Definition: bgp_aspath.cc:392
as_t aggregator_as_num() const
Definition: bgp_attr.h:891
const As4Path * as4_path() const
Definition: bgp_attr.h:911
BgpServer * server()
Definition: bgp_attr.h:1031
void ClearDelete()
Definition: db_entry.h:48
as_t peer_as() const
Definition: bgp_ribout.h:321
uint32_t GetLabel() const
Definition: bgp_path.h:89
void SetResolveNextHop()
Definition: bgp_path.h:129
int PathCompare(const BgpPath &rhs, bool allow_ecmp) const
Definition: bgp_path.cc:58
void FillStatisticsInfo(std::vector< ShowRibOutStatistics > *sros_list) const
Definition: bgp_ribout.cc:545
bool IsAsPathEmpty() const
Definition: bgp_attr.cc:1087
std::vector< as_t > path_segment
Definition: bgp_aspath.h:374
LifetimeActor * deleter()
boost::intrusive_ptr< const Community > CommunityPtr
Definition: community.h:109
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
const AsPath * as_path() const
Definition: bgp_attr.h:899
void set_local_pref(uint32_t local_pref)
Definition: bgp_attr.h:839
virtual bool MayDelete() const
Definition: db_table.cc:220
void InsertPath(BgpPath *path)
Definition: bgp_route.cc:60
size_t GetPendingRiboutsCount(size_t *markers) const
Definition: bgp_table.cc:1088
virtual ~DeleteActor()
Definition: bgp_table.cc:38
BgpServer * server()
Definition: bgp_table.cc:88
void Shutdown()
Definition: bgp_table.cc:1051
BitSet & set(size_t pos)
Definition: bitset.cc:125
void set_originator_id(Ip4Address originator_id)
Definition: bgp_attr.h:849
tbb::atomic< uint64_t > secondary_path_count_
Definition: bgp_table.h:224
Address::Family nexthop_family() const
Definition: bgp_attr.cc:1124
const Path * front() const
Definition: route.cc:16
bool IsMasterRoutingInstance() const
bool IsContributingRoute(const BgpRoute *route) const
Definition: bgp_table.cc:1142
const ExtCommunity * ext_community() const
Definition: bgp_attr.h:915
const AsPath4ByteSpec & path() const
Definition: bgp_aspath.h:285
static bool PathSelection(const Path &path1, const Path &path2)
Definition: bgp_table.cc:821
bool IsLlgrStale() const
Definition: bgp_path.h:110
const bytes_type & GetExtCommunity() const
Definition: tunnel_encap.h:28
std::vector< ExtCommunityValue > ExtCommunityList
Definition: community.h:153
ExtCommunityPtr ReplaceTunnelEncapsulationAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &tunnel_encaps)
Definition: community.cc:899
bool remove_private_replace() const
Definition: bgp_ribout.h:341
AsPath4ByteSpec * RemovePrivate(bool all, as_t asn, as_t peer_as) const
Definition: bgp_aspath.cc:454
void StopPathResolution(int part_id, const BgpPath *path)
const BgpAttr * GetAttr() const
Definition: bgp_path.h:87
void FillRibOutStatisticsInfo(std::vector< ShowRibOutStatistics > *sros_list) const
Definition: bgp_table.cc:1146
bool IsEncodingXmpp() const
Definition: bgp_ribout.h:328
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:836
bool HasListeners() const
Definition: db_table.cc:234
void set_med(uint32_t med)
Definition: bgp_attr.h:838
uint64_t subscription_gen_id() const
Definition: bgp_table.h:88
LifetimeActor * deleter()
Definition: bgp_table.cc:1108
as_t local_as() const
Definition: bgp_ribout.h:322
virtual void set_routing_instance(RoutingInstance *rtinstance)
Definition: bgp_table.cc:81
void DeletePath(BgpPath *path)
Definition: bgp_route.cc:126
RibOutUpdates * updates(int idx)
Definition: bgp_ribout.h:316
BgpMembershipManager * membership_mgr()
Definition: bgp_server.h:173
void PrependAsToAsPath4Byte(BgpAttr *attr, as_t asn) const
Definition: bgp_table.cc:399
const As4PathSpec & path() const
Definition: bgp_aspath.h:443
static int PartitionCount()
Definition: db.cc:32
void RibOutDelete(const RibExportPolicy &policy)
Definition: bgp_table.cc:124
virtual bool IsRegistrationRequired() const =0
void set_ext_community(ExtCommunityPtr extcomm)
Definition: bgp_attr.cc:1011
int as_path_count() const
Definition: bgp_attr.h:900
void CreateAsPath4Byte(BgpAttr *attr, as_t local_as) const
Definition: bgp_table.cc:503
bool NeedsResolution() const
Definition: bgp_path.h:135
std::vector< std::string > default_tunnel_encap_list
bool ClusterListLoop(uint32_t cluster_id) const
Definition: bgp_attr.cc:223
uint32_t cluster_id() const
Definition: bgp_server.h:203
void ProcessDefaultTunnelEncapsulation(const RibOut *ribout, ExtCommunityDB *extcomm_db, BgpAttr *attr) const
Definition: bgp_table.cc:351
void Notify(DBEntryBase *entry)
const NextHop & nexthop()
Definition: bgp_table.h:82
uint32_t med() const
Definition: bgp_attr.h:888
std::vector< as2_t > path_segment
Definition: bgp_aspath.h:58
bool Has4ByteAsn(BgpAttr *attr) const
Definition: bgp_table.cc:447
std::vector< PathSegment * > path_segments
Definition: bgp_aspath.h:395
void set_aspath_4byte(AsPath4BytePtr aspath)
Definition: bgp_attr.cc:979
void set_as4_path(As4PathPtr aspath)
Definition: bgp_attr.cc:967
#define BGP_LOG_TABLE(table, level, flags, arg)
Definition: bgp_log.h:260
AsPathSpec * Replace(as2_t old_asn, as2_t asn) const
Definition: bgp_aspath.cc:206
bool remove_private_peer_loop_check() const
Definition: bgp_ribout.h:344
DeleteActor(BgpTable *table)
Definition: bgp_table.cc:34
~BgpTable()
Definition: bgp_table.cc:76
int GetIndex() const
Definition: bgp_peer.h:205
bool DeletePath(DBTablePartBase *root, BgpRoute *rt, BgpPath *path)
Definition: bgp_table.cc:831
virtual void GetRibOutInterestedPeers(RibOut *ribout, const ExtCommunity *ext_community, const RibPeerSet &peerset, RibPeerSet *new_peerset)
#define AS_TRANS
Definition: bgp_common.h:23
virtual BgpAttrPtr GetAttributes(BgpRoute *rt, BgpAttrPtr attrp, const IPeer *peer)
Definition: bgp_table.h:197
PathResolver * path_resolver_
Definition: bgp_table.h:218
IPeerUpdate * Next()
Definition: bgp_ribout.h:271
as2_t AsLeftMostPublic() const
Definition: bgp_aspath.cc:45
#define BGP_LOG_FLAG_ALL
Definition: bgp_log.h:44
int index() const
const PathList & GetPathList() const
Definition: route.h:46
#define AS2_MAX
Definition: bgp_common.h:24
void set_as4_aggregator(as_t as_num, IpAddress address)
Definition: bgp_attr.h:845
RTargetGroupMgr * rtarget_group_mgr()
Definition: bgp_server.h:110
As4PathSpec * Replace(as_t old_asn, as_t asn) const
Definition: bgp_aspath.cc:658