OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
routepath_replicator.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 
7 #include <boost/foreach.hpp>
8 
9 #include <utility>
10 
11 #include "base/set_util.h"
12 #include "base/task_annotations.h"
13 #include "base/task_trigger.h"
14 #include "bgp/bgp_config.h"
15 #include "bgp/bgp_log.h"
16 #include "bgp/bgp_route.h"
17 #include "bgp/bgp_server.h"
22 #include "bgp/routing-instance/routing_instance_analytics_types.h"
23 
24 using std::ostringstream;
25 using std::make_pair;
26 using std::pair;
27 using std::string;
28 using std::vector;
29 
30 //
31 // RoutePathReplication trace macro. Optionally logs the server name as well for
32 // easier debugging in multi server unit tests
33 //
34 #define RPR_TRACE(obj, ...) \
35 do { \
36  if (LoggingDisabled()) break; \
37  bgp_log_test::LogServerName(server()); \
38  Rpr##obj##Log::Send("RoutingInstance", \
39  SandeshLevel::SYS_DEBUG, __FILE__, __LINE__, __VA_ARGS__); \
40  Rpr##obj::TraceMsg(trace_buf_, __FILE__, __LINE__, __VA_ARGS__); \
41 } while (false)
42 
43 #define RPR_TRACE_ONLY(obj, ...) \
44 do { \
45  if (LoggingDisabled()) break; \
46  bgp_log_test::LogServerName(server()); \
47  Rpr##obj::TraceMsg(trace_buf_, __FILE__, __LINE__, __VA_ARGS__); \
48 } while (false)
49 
51 public:
52  explicit DeleteActor(TableState *ts)
53  : LifetimeActor(ts->replicator()->server()->lifetime_manager()),
54  ts_(ts) {
55  }
56 
57  virtual bool MayDelete() const {
58  return ts_->MayDelete();
59  }
60 
61  virtual void Shutdown() {
62  }
63 
64  virtual void Destroy() {
66  }
67 
68 private:
70 };
71 
73  : replicator_(replicator),
74  table_(table),
75  listener_id_(DBTableBase::kInvalidId),
76  deleter_(new DeleteActor(this)),
77  table_delete_ref_(this, table->deleter()) {
78  assert(table->deleter() != NULL);
79 }
80 
82  if (walk_ref() != NULL) {
84  }
85 }
86 
88  deleter()->Delete();
89 }
90 
91 bool TableState::deleted() const {
92  return deleter()->IsDeleted();
93 }
94 
96  return deleter_.get();
97 }
98 
100  return deleter_.get();
101 }
102 
103 bool TableState::MayDelete() const {
104  if (list_.empty() && !route_count() &&
105  ((walk_ref() == NULL) || !walk_ref()->walk_is_active()))
106  return true;
107  return false;
108 }
109 
111  if (!deleter()->IsDeleted())
112  return;
113  deleter()->RetryDelete();
114 }
115 
117  list_.insert(group);
118 }
119 
121  list_.erase(group);
122 }
123 
124 const RtGroup *TableState::FindGroup(RtGroup *group) const {
125  GroupList::const_iterator it = list_.find(group);
126  return (it != list_.end() ? *it : NULL);
127 }
128 
129 uint32_t TableState::route_count() const {
131 }
132 
134  : replicator_(replicator) {
135 }
136 
138  ReplicatedRtPathList::const_iterator it) {
139  pair<ReplicatedRtPathList::iterator, bool> result;
140  result = replicate_list_.insert(*it);
141  assert(result.second);
142 }
143 
145  ReplicatedRtPathList::const_iterator it) {
146  replicator_->DeleteSecondaryPath(table, rt, *it);
147  replicate_list_.erase(it);
148 }
149 
150 //
151 // Return the list of secondary table names for the given primary path.
152 // We go through all SecondaryRouteInfos and skip the ones that don't
153 // match the primary path.
154 //
155 vector<string> RtReplicated::GetTableNameList(const BgpPath *path) const {
156  vector<string> table_list;
157  BOOST_FOREACH(const SecondaryRouteInfo &rinfo, replicate_list_) {
158  if (rinfo.peer_ != path->GetPeer())
159  continue;
160  if (rinfo.path_id_ != path->GetPathId())
161  continue;
162  if (rinfo.src_ != path->GetSource())
163  continue;
164  table_list.push_back(rinfo.table_->name());
165  }
166  return table_list;
167 }
168 
170  Address::Family family)
171  : server_(server),
172  family_(family),
173  vpn_table_(NULL),
174  trace_buf_(SandeshTraceBufferCreate("RoutePathReplicator", 500)) {
175 }
176 
178  assert(table_state_list_.empty());
179 }
180 
182  assert(!vpn_table_);
184  assert(mgr);
186  assert(master);
187  vpn_table_ = master->GetTable(family_);
188  assert(vpn_table_);
189  assert(AddTableState(vpn_table_));
190 }
191 
193  RtGroup *group) {
194  assert(table->IsVpnTable() || group);
195 
196  TableStateList::iterator loc = table_state_list_.find(table);
197  if (loc == table_state_list_.end()) {
198  TableState *ts = new TableState(this, table);
199  DBTableBase::ListenerId id = table->Register(
200  boost::bind(&RoutePathReplicator::RouteListener, this, ts, _1, _2),
201  "RoutePathReplicator");
202  ts->set_listener_id(id);
203  if (group)
204  ts->AddGroup(group);
205  table_state_list_.insert(make_pair(table, ts));
206  RPR_TRACE(RegTable, table->name());
207  return ts;
208  } else {
209  assert(group);
210  TableState *ts = loc->second;
211  ts->AddGroup(group);
212  return ts;
213  }
214 }
215 
217  TableState *ts = FindTableState(table);
218  assert(ts);
219  ts->RemoveGroup(group);
220 }
221 
223  TableState *ts = FindTableState(table);
224  assert(ts);
225  RPR_TRACE(UnregTable, table->name());
226  table->Unregister(ts->listener_id());
227  table_state_list_.erase(table);
228  delete ts;
229 }
230 
232  TableStateList::iterator loc = table_state_list_.find(table);
233  return (loc != table_state_list_.end() ? loc->second : NULL);
234 }
235 
237  const BgpTable *table) const {
238  TableStateList::const_iterator loc =
239  table_state_list_.find(const_cast<BgpTable *>(table));
240  return (loc != table_state_list_.end() ? loc->second : NULL);
241 }
242 
243 void
245  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
246  TableState *ts = FindTableState(table);
247  assert(ts);
248  if (!ts->walk_ref()) {
249  DBTable::DBTableWalkRef walk_ref = table->AllocWalker(
250  boost::bind(&RoutePathReplicator::RouteListener, this, ts, _1, _2),
251  boost::bind(&RoutePathReplicator::BulkReplicationDone, this, _2));
252  table->WalkTable(walk_ref);
253  ts->set_walk_ref(walk_ref);
254  } else {
255  table->WalkAgain(ts->walk_ref());
256  }
257 }
258 
259 void
261  CHECK_CONCURRENCY("db::Walker");
262  BgpTable *table = static_cast<BgpTable *>(dbtable);
263  RPR_TRACE(WalkDone, table->name());
264  TableState *ts = FindTableState(table);
265  ts->RetryDelete();
266 }
267 
269  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
271  if (!vpn_ts || vpn_ts->FindGroup(group))
272  return;
273  RPR_TRACE(TableJoin, vpn_table_->name(), group->rt().ToString(), true);
274  group->AddImportTable(family(), vpn_table_);
275  RPR_TRACE(TableJoin, vpn_table_->name(), group->rt().ToString(), false);
276  group->AddExportTable(family(), vpn_table_);
277  AddTableState(vpn_table_, group);
278 }
279 
281  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
283  if (!vpn_ts)
284  return;
285  RPR_TRACE(TableLeave, vpn_table_->name(), group->rt().ToString(), true);
287  RPR_TRACE(TableLeave, vpn_table_->name(), group->rt().ToString(), false);
290 }
291 
292 //
293 // Add a given BgpTable to RtGroup of given RouteTarget.
294 // It will create a new RtGroup if none exists.
295 // In case of export RouteTarget, create TableState if it doesn't exist.
296 //
298  bool import) {
299  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
300 
301  tbb::mutex::scoped_lock lock(mutex_);
302  RPR_TRACE(TableJoin, table->name(), rt.ToString(), import);
303 
304  bool first = false;
305  RtGroup *group = server()->rtarget_group_mgr()->LocateRtGroup(rt);
306  if (import) {
307  first = group->AddImportTable(family(), table);
308  if (group->HasDepRoutes())
310  if (family_ == Address::INETVPN)
312  BOOST_FOREACH(BgpTable *sec_table, group->GetExportTables(family())) {
313  if (sec_table->IsVpnTable() || sec_table->empty())
314  continue;
315  RequestWalk(sec_table);
316  }
317  } else {
318  first = group->AddExportTable(family(), table);
319  AddTableState(table, group);
320  if (!table->empty()) {
321  RequestWalk(table);
322  }
323  }
324 
325  // Join the vpn table when group is created.
326  if (first)
327  JoinVpnTable(group);
328 }
329 
330 //
331 // Remove a BgpTable from RtGroup of given RouteTarget.
332 // If the last group is going away, the RtGroup will be removed
333 // In case of export RouteTarget, trigger remove of TableState appropriate.
334 //
336  bool import) {
337  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
338 
339  tbb::mutex::scoped_lock lock(mutex_);
340  RtGroup *group = server()->rtarget_group_mgr()->GetRtGroup(rt);
341  assert(group);
342  RPR_TRACE(TableLeave, table->name(), rt.ToString(), import);
343 
344  if (import) {
345  group->RemoveImportTable(family(), table);
346  if (group->HasDepRoutes())
348  if (family_ == Address::INETVPN)
350  BOOST_FOREACH(BgpTable *sec_table, group->GetExportTables(family())) {
351  if (sec_table->IsVpnTable() || sec_table->empty())
352  continue;
353  RequestWalk(sec_table);
354  }
355  } else {
356  group->RemoveExportTable(family(), table);
357  RemoveTableState(table, group);
358  if (!table->empty()) {
359  RequestWalk(table);
360  }
361  }
362 
363  // Leave the vpn table when the last VRF has left the group.
364  if (!group->HasVrfTables(family())) {
365  LeaveVpnTable(group);
367  }
368 }
369 
371  BgpRoute *rt, RtReplicated *dbstate,
372  const RtReplicated::ReplicatedRtPathList *future) {
373  set_synchronize(dbstate->GetMutableList(), future,
374  boost::bind(&RtReplicated::AddRouteInfo, dbstate, table, rt, _1),
375  boost::bind(&RtReplicated::DeleteRouteInfo, dbstate, table, rt, _1));
376 
377  if (dbstate->GetList().empty()) {
378  rt->ClearState(table, ts->listener_id());
379  delete dbstate;
380  if (table->GetDBStateCount(ts->listener_id()) == 0)
381  ts->RetryDelete();
382  }
383 }
384 
386  const ExtCommunity *ext_community,
387  int vn_index) {
388  as_t asn = server->autonomous_system();
389  ExtCommunityPtr extcomm_ptr;
390  if (vn_index) {
391  if (asn > AS2_MAX && vn_index > 0xffff) {
392  OriginVn origin_vn(asn, AS_TRANS);
393  extcomm_ptr = server->extcomm_db()->ReplaceOriginVnAndLocate(
394  ext_community, origin_vn.GetExtCommunity());
395  OriginVn origin_vn2(AS_TRANS, vn_index);
396  extcomm_ptr = server->extcomm_db()->AppendAndLocate(
397  extcomm_ptr.get(), origin_vn2.GetExtCommunity());
398  } else {
399  OriginVn origin_vn(asn, vn_index);
400  extcomm_ptr = server->extcomm_db()->ReplaceOriginVnAndLocate(
401  ext_community, origin_vn.GetExtCommunity());
402  return extcomm_ptr;
403  }
404  }
405  extcomm_ptr = server->extcomm_db()->RemoveOriginVnAndLocate(ext_community);
406  return extcomm_ptr;
407 }
408 
409 //
410 // Update the ExtCommunity with the RouteTargets from the export list
411 // and the OriginVn. The OriginVn is derived from the RouteTargets in
412 // vpn routes.
413 //
415  const RoutingInstance *rtinstance, const ExtCommunity *ext_community,
416  const ExtCommunity::ExtCommunityList &export_list) {
417  // Add RouteTargets exported by the instance for a non-master instance.
418  ExtCommunityPtr extcomm_ptr;
419  if (!rtinstance->IsMasterRoutingInstance()) {
420  extcomm_ptr =
421  server->extcomm_db()->AppendAndLocate(ext_community, export_list);
422  return extcomm_ptr;
423  }
424 
425  // Bail if we have a vpn route without extended communities.
426  if (!ext_community)
427  return ExtCommunityPtr(NULL);
428 
429  // Nothing to do if we already have the OriginVn community with our AS
430  // or with a vn index from the global range.
431  BOOST_FOREACH(const ExtCommunity::ExtCommunityValue &comm,
432  ext_community->communities()) {
433  if (!ExtCommunity::is_origin_vn(comm))
434  continue;
435  OriginVn origin_vn(comm);
436  if (!origin_vn.IsGlobal() &&
437  origin_vn.as_number() != server->autonomous_system()) {
438  continue;
439  }
440  return ExtCommunityPtr(ext_community);
441  }
442 
443  // Add the OriginVn if we have a valid vn index.
444  int vn_index =
445  server->routing_instance_mgr()->GetVnIndexByExtCommunity(ext_community);
446  return UpdateOriginVn(server, ext_community, vn_index);
447 }
448 
449 //
450 // Concurrency: Called in the context of the DB partition task.
451 //
452 // This function handles
453 // 1. Table Notification for path replication
454 // 2. Table walk for import/export of new targets
455 //
456 // Replicate a path (clone the BgpPath) to secondary BgpTables based on the
457 // export targets of the primary BgpTable.
458 // If primary table is a VRF table attach it's export targets to replicated
459 // path in the VPN table.
460 //
462  DBTablePartBase *root, DBEntryBase *entry) {
463  CHECK_CONCURRENCY("db::DBTable");
464 
465  BgpTable *table = static_cast<BgpTable *>(root->parent());
466  BgpRoute *rt = static_cast<BgpRoute *>(entry);
467  const RoutingInstance *rtinstance = table->routing_instance();
468 
470  assert(id != DBTableBase::kInvalidId);
471 
472  // Get the DBState.
473  RtReplicated *dbstate =
474  static_cast<RtReplicated *>(rt->GetState(table, id));
475  RtReplicated::ReplicatedRtPathList replicated_path_list;
476 
477  //Flag to track if any change happenned to route in last 30 minutes
478  bool route_unchanged = false;
479  //List of tables that needs replication of route
480  RtGroup::RtGroupMemberList addedTables;
481  //List of tables having the latest changes in route
482  RtGroup::RtGroupMemberList previousTables;
483  //Threshold used for optimised replication
484  uint64_t optimizationThresholdTime = 30ULL * 60 * 1000000;
485  uint64_t start = UTCTimestampUsec();
486 
487  //Optimize only if last route change occurred 30 mins before.
488  //We update the route_unchanged flag to true
489  if ( (start - rt->last_update_at() > optimizationThresholdTime) &&
490  dbstate != NULL)
491  {
492  RPR_TRACE(RouteListener, "Route change occurred before threshold \
493  time, optimising replication");
494  route_unchanged = true;
495  }
496 
497  //
498  // Cleanup if the route is not usable.
499  // If route aggregation is enabled, contributing route/more specific route
500  // for a aggregate route will NOT be replicated to destination table
501  //
502  if (!rt->IsUsable() || (table->IsRouteAggregationSupported() &&
503  !rtinstance->deleted() &&
504  table->IsContributingRoute(rt))) {
505  if (!dbstate) {
506  return true;
507  }
508  DBStateSync(table, ts, rt, dbstate, &replicated_path_list);
509  return true;
510  }
511 
512  // Create and set new DBState on the route. This will get cleaned up via
513  // via the call to DBStateSync if we don't need to replicate the route to
514  // any tables.
515  if (dbstate == NULL) {
516  dbstate = new RtReplicated(this);
517  rt->SetState(table, id, dbstate);
518  }
519 
520  // Get the export route target list from the routing instance.
521  ExtCommunity::ExtCommunityList export_list;
522  if (!rtinstance->IsMasterRoutingInstance()) {
523  BOOST_FOREACH(RouteTarget rtarget, rtinstance->GetExportList()) {
524  export_list.push_back(rtarget.GetExtCommunity());
525  }
526  }
527 
528  // Updating previousTables with the list of tables having the information
529  // about the route.
530  if (route_unchanged){
531  replicated_path_list = dbstate->GetList();
532  BOOST_FOREACH (RtReplicated::SecondaryRouteInfo path,
533  replicated_path_list){
534  previousTables.insert(path.table_);
535  }
536  }
537 
538  // Replicate all feasible and non-replicated paths.
539  for (Route::PathList::iterator it = rt->GetPathList().begin();
540  it != rt->GetPathList().end(); ++it) {
541  BgpPath *path = static_cast<BgpPath *>(it.operator->());
542 
543  // Skip if the source peer is down.
544  if (!path->IsStale() && !path->IsLlgrStale() && path->GetPeer() &&
545  !path->GetPeer()->IsReady())
546  continue;
547 
548  // No need to replicate aliased or replicated paths.
549  if (path->IsReplicated() || path->IsAliased())
550  continue;
551 
552  // Do not replicate non-ecmp paths.
553  if (rt->BestPath()->PathCompare(*path, true))
554  break;
555 
556  // Do not replicate if nexthop is not hitched by ermvpn tree.
557  if (path->CheckErmVpn())
558  break;
559 
560  const BgpAttr *attr = path->GetAttr();
561  const ExtCommunity *ext_community = attr->ext_community();
562 
563  ExtCommunityPtr extcomm_ptr =
564  UpdateExtCommunity(server(), rtinstance, ext_community, export_list);
565  ext_community = extcomm_ptr.get();
566  if (!ext_community)
567  continue;
568 
569  // Go through all extended communities.
570  //
571  // Get the vn_index from the OriginVn extended community.
572  // For each RouteTarget extended community, get the list of tables
573  // to which we need to replicate the path.
574  int vn_index = 0;
575  RtGroup::RtGroupMemberList secondary_tables;
576  BOOST_FOREACH(const ExtCommunity::ExtCommunityValue &comm,
577  ext_community->communities()) {
578  if (ExtCommunity::is_origin_vn(comm)) {
579  OriginVn origin_vn(comm);
580  vn_index = origin_vn.vn_index();
581  } else if (ExtCommunity::is_route_target(comm)) {
582  RtGroup *group =
583  server()->rtarget_group_mgr()->GetRtGroup(comm);
584  if (!group)
585  continue;
586  RtGroup::RtGroupMemberList import_list =
587  group->GetImportTables(family());
588  if (import_list.empty())
589  continue;
590  secondary_tables.insert(import_list.begin(), import_list.end());
591  }
592  }
593 
594  // Update with family specific secondary tables.
595  table->UpdateSecondaryTablesForReplication(rt, &secondary_tables);
596 
597  // Skip if we don't need to replicate the path to any tables.
598  if (secondary_tables.empty())
599  continue;
600 
601  // Add OriginVn when replicating self-originated routes from a VRF.
602  if (!vn_index && !rtinstance->IsMasterRoutingInstance() &&
603  path->IsVrfOriginated() && rtinstance->virtual_network_index()) {
604  vn_index = rtinstance->virtual_network_index();
605  extcomm_ptr = UpdateOriginVn(server_, extcomm_ptr.get(), vn_index);
606  }
607 
608  if (route_unchanged){
609  addedTables = RtGroup::RtGroupMemberList();
610  // Finding the difference between sets, secondary_tables and
611  // previousTables
612  std::set_difference(secondary_tables.begin(), secondary_tables.end(),
613  previousTables.begin(), previousTables.end(),
614  std::inserter(addedTables, addedTables.end()));
615  //Updating the secondary tables with the difference.
616  secondary_tables = addedTables;
617 
618  }
619 
620 
621  // Replicate path to all destination tables.
622  BOOST_FOREACH(BgpTable *dest, secondary_tables) {
623  // Skip if destination is same as source table.
624  if (dest == table)
625  continue;
626 
627  const RoutingInstance *dest_rtinstance = dest->routing_instance();
628  ExtCommunityPtr new_extcomm_ptr = extcomm_ptr;
629 
630  // If the origin vn is unresolved, see if route has a RouteTarget
631  // that's in the set of export RouteTargets for the dest instance.
632  // If so, we set the origin vn for the replicated route to be the
633  // vn for the dest instance.
634  if (!vn_index && dest_rtinstance->virtual_network_index() &&
635  dest_rtinstance->HasExportTarget(ext_community)) {
636  int dest_vn_index = dest_rtinstance->virtual_network_index();
637  new_extcomm_ptr = UpdateOriginVn(server_, extcomm_ptr.get(),
638  dest_vn_index);
639  }
640 
641  // Replicate the route to the destination table. The destination
642  // table may decide to not replicate based on it's own policy e.g.
643  // multicast routes are never leaked across routing-instances.
644  BgpRoute *replicated_rt = dest->RouteReplicate(
645  server_, table, rt, path, new_extcomm_ptr);
646  if (!replicated_rt)
647  continue;
648 
649  // Add information about the secondary path to the replicated path
650  // list.
651  RtReplicated::SecondaryRouteInfo rtinfo(dest, path->GetPeer(),
652  path->GetPathId(), path->GetSource(), replicated_rt);
653  pair<RtReplicated::ReplicatedRtPathList::iterator, bool> result;
654  result = replicated_path_list.insert(rtinfo);
655  // Assert if the insertion to replication path list fails
656  if (!route_unchanged)
657  assert(result.second);
658  RPR_TRACE_ONLY(Replicate, table->name(), rt->ToString(),
659  path->ToString(),
661  dest->name(), replicated_rt->ToString());
662  }
663  }
664 
665  // Update the DBState to reflect the new list of secondary paths. The
666  // DBState will get cleared if the list is empty.
667  DBStateSync(table, ts, rt, dbstate, &replicated_path_list);
668  return true;
669 }
671  BgpTable *table, BgpRoute *rt) const {
672  const TableState *ts = FindTableState(table);
673  if (!ts)
674  return NULL;
675  RtReplicated *dbstate =
676  static_cast<RtReplicated *>(rt->GetState(table, ts->listener_id()));
677  return dbstate;
678 }
679 
680 //
681 // Return the list of secondary table names for the given primary path.
682 //
684  const BgpTable *table, const BgpRoute *rt, const BgpPath *path) const {
685  const TableState *ts = FindTableState(table);
686  if (!ts)
687  return vector<string>();
688  const RtReplicated *dbstate = static_cast<const RtReplicated *>(
689  rt->GetState(table, ts->listener_id()));
690  if (!dbstate)
691  return vector<string>();
692  return dbstate->GetTableNameList(path);
693 }
694 
696  const RtReplicated::SecondaryRouteInfo &rtinfo) {
697  BgpRoute *rt_secondary = rtinfo.rt_;
698  BgpTable *secondary_table = rtinfo.table_;
699  const IPeer *peer = rtinfo.peer_;
700  uint32_t path_id = rtinfo.path_id_;
701  BgpPath::PathSource src = rtinfo.src_;
702 
703  DBTablePartBase *partition =
704  secondary_table->GetTablePartition(rt_secondary);
705  BgpPath *secondary_path = rt_secondary->FindSecondaryPath(rt, src,
706  peer, path_id);
707  if (secondary_path && secondary_path->NeedsResolution()) {
708  secondary_table->path_resolver()->StopPathResolution(partition->index(),
709  secondary_path);
710  }
711  assert(rt_secondary->RemoveSecondaryPath(rt, src, peer, path_id));
712  if (rt_secondary->count() == 0) {
713  RPR_TRACE_ONLY(Flush, secondary_table->name(), rt_secondary->ToString(),
714  peer ? peer->ToString() : "Nil",
715  BgpPath::PathIdString(path_id), table->name(),
716  rt->ToString(), "Delete");
717  partition->Delete(rt_secondary);
718  } else {
719  partition->Notify(rt_secondary);
720  RPR_TRACE_ONLY(Flush, secondary_table->name(), rt_secondary->ToString(),
721  peer ? peer->ToString() : "Nil",
722  BgpPath::PathIdString(path_id), table->name(),
723  rt->ToString(), "Path update");
724  }
725 }
726 
728  ostringstream out;
729  out << table_->name() << "(" << table_ << ")" << ":" <<
730  peer_->ToString() << "(" << peer_ << ")" << ":" <<
731  rt_->ToString() << "(" << rt_ << ")";
732  return out.str();
733 }
DBTableBase::ListenerId listener_id() const
ExtCommunityPtr AppendAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &list)
Definition: community.cc:696
bool RemoveImportTable(Address::Family family, BgpTable *tbl)
as_t as_number() const
Definition: origin_vn.cc:110
ExtCommunityPtr ReplaceOriginVnAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityValue &origin_vn)
Definition: community.cc:884
boost::array< uint8_t, 8 > ExtCommunityValue
Definition: community.h:152
std::set< BgpTable * > RtGroupMemberList
Definition: rtarget_group.h:63
void JoinVpnTable(RtGroup *group)
BgpTable * GetTable(Address::Family fmly)
bool deleted() const
void WalkTable(DBTableWalkRef walk)
Definition: db_table.cc:625
const BgpPath * BestPath() const
Definition: bgp_route.cc:46
const RouteTargetList & GetExportList() const
bool CheckErmVpn() const
Definition: bgp_path.h:136
void NotifyRtGroup(const RouteTarget &rt)
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
bool AddExportTable(Address::Family family, BgpTable *tbl)
int virtual_network_index() const
bool set_synchronize(const SetType *set1, const SetType *set2, AddFunctor add_fn, DelFunctor del_fn)
Definition: set_util.h:21
const RtGroupMemberList & GetExportTables(Address::Family family) const
bool RemoveSecondaryPath(const BgpRoute *src_rt, BgpPath::PathSource src, const IPeer *peer, uint32_t path_id)
Definition: bgp_route.cc:397
bool HasDepRoutes() const
virtual BgpRoute * RouteReplicate(BgpServer *server, BgpTable *table, BgpRoute *src, const BgpPath *path, ExtCommunityPtr community)=0
TableState * AddTableState(BgpTable *table, RtGroup *group=NULL)
static std::string PathIdString(uint32_t path_id)
Definition: bgp_path.cc:18
virtual bool IsVpnTable() const
Definition: bgp_table.h:110
RoutingInstance * routing_instance()
Definition: bgp_table.h:148
Family
Definition: address.h:24
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
ReplicatedRtPathList * GetMutableList()
bool IsStale() const
Definition: bgp_path.h:107
ExtCommunityPtr RemoveOriginVnAndLocate(const ExtCommunity *src)
Definition: community.cc:871
uint32_t route_count() const
int ListenerId
Definition: db_table.h:62
RoutePathReplicator * replicator()
DBTableWalkRef AllocWalker(WalkFn walk_fn, WalkCompleteFn walk_complete)
Definition: db_table.cc:613
void set_listener_id(DBTableBase::ListenerId listener_id)
RoutingInstanceMgr * routing_instance_mgr()
Definition: bgp_server.h:102
const uint32_t GetPathId() const
Definition: bgp_path.h:78
const RtGroupMemberList & GetImportTables(Address::Family family) const
DBTableBase * parent()
void DeleteSecondaryPath(BgpTable *table, BgpRoute *rt, const RtReplicated::SecondaryRouteInfo &rtinfo)
int GetVnIndexByExtCommunity(const ExtCommunity *community) const
RoutingInstance * GetDefaultRoutingInstance()
virtual bool IsReady() const =0
RoutePathReplicator * replicator_
void Delete(DBEntryBase *)
void DBStateSync(BgpTable *table, TableState *ts, BgpRoute *rt, RtReplicated *dbstate, const RtReplicated::ReplicatedRtPathList *future)
uint64_t GetDBStateCount(ListenerId listener)
Definition: db_table.cc:216
virtual std::string ToString() const
Definition: bgp_path.cc:177
uint32_t as_t
Definition: bgp_common.h:21
Definition: ipeer.h:186
virtual bool MayDelete() const
void Unregister(ListenerId listener)
Definition: db_table.cc:186
void NotifyAllStaticRoutes()
Definition: bgp_server.cc:1004
const RtGroup * FindGroup(RtGroup *group) const
void ReleaseWalker(DBTableWalkRef &walk)
Definition: db_table.cc:619
void RetryDelete()
Definition: lifetime.cc:71
const bytes_type & GetExtCommunity() const
bool IsUsable() const
Definition: bgp_route.cc:324
bool RouteListener(TableState *ts, DBTablePartBase *root, DBEntryBase *entry)
LifetimeActor * deleter()
boost::scoped_ptr< DeleteActor > deleter_
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
#define RPR_TRACE(obj,...)
void WalkAgain(DBTableWalkRef walk)
Definition: db_table.cc:631
TableStateList table_state_list_
PathSource
Definition: bgp_path.h:37
const uint64_t last_update_at() const
Definition: db_entry.h:72
PathSource GetSource() const
Definition: bgp_path.h:103
RtGroup * LocateRtGroup(const RouteTarget &rt)
const ExtCommunityList & communities() const
Definition: community.h:180
bool IsDeleted() const
Definition: lifetime.h:131
void AddRouteInfo(BgpTable *table, BgpRoute *rt, ReplicatedRtPathList::const_iterator it)
ExtCommunityDB * extcomm_db()
Definition: bgp_server.h:187
void RemoveRtGroup(const RouteTarget &rt)
boost::intrusive_ptr< const ExtCommunity > ExtCommunityPtr
Definition: community.h:448
virtual const std::string & ToString() const =0
#define CHECK_CONCURRENCY(...)
bool HasVrfTables(Address::Family family) const
std::set< SecondaryRouteInfo > ReplicatedRtPathList
RoutePathReplicator(BgpServer *server, Address::Family family)
ReplicatedRtPathList replicate_list_
void RemoveTableState(BgpTable *table, RtGroup *group)
virtual void UpdateSecondaryTablesForReplication(BgpRoute *rt, TableSet *secondary_tables)
Definition: bgp_table.h:135
virtual std::string ToString() const =0
std::vector< std::string > GetTableNameList(const BgpPath *path) const
IPeer * GetPeer()
Definition: bgp_path.h:76
bool HasExportTarget(const ExtCommunity *extcomm) const
bool IsVrfOriginated() const
Definition: bgp_path.h:68
void DeleteRouteInfo(BgpTable *table, BgpRoute *rt, ReplicatedRtPathList::const_iterator it)
virtual bool IsRouteAggregationSupported() const
Definition: bgp_table.h:112
const std::string & name() const
Definition: db_table.h:110
int PathCompare(const BgpPath &rhs, bool allow_ecmp) const
Definition: bgp_path.cc:58
bool AddImportTable(Address::Family family, BgpTable *tbl)
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
bool IsGlobal() const
Definition: origin_vn.cc:134
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:436
RtGroup * GetRtGroup(const RouteTarget &rt)
std::vector< std::string > GetReplicatedTableNameList(const BgpTable *table, const BgpRoute *route, const BgpPath *path) const
void set_walk_ref(DBTable::DBTableWalkRef walk_ref)
void DeleteTableState(BgpTable *table)
void RequestWalk(BgpTable *table)
const DBTable::DBTableWalkRef & walk_ref() const
bool IsMasterRoutingInstance() const
bool IsContributingRoute(const BgpRoute *route) const
Definition: bgp_table.cc:1142
BgpPath * FindSecondaryPath(BgpRoute *src_rt, BgpPath::PathSource src, const IPeer *peer, uint32_t path_id)
Definition: bgp_route.cc:372
const ExtCommunity * ext_community() const
Definition: bgp_attr.h:915
int vn_index() const
Definition: origin_vn.cc:122
void Join(BgpTable *table, const RouteTarget &rt, bool import)
BgpTable * table() const
void BulkReplicationDone(DBTableBase *dbtable)
static ExtCommunityPtr UpdateExtCommunity(BgpServer *server, const RoutingInstance *rtinstance, const ExtCommunity *ext_community, const ExtCommunity::ExtCommunityList &export_list)
static uint64_t UTCTimestampUsec()
Definition: time_util.h:13
virtual void Delete()
Definition: lifetime.cc:38
bool IsLlgrStale() const
Definition: bgp_path.h:110
std::vector< ExtCommunityValue > ExtCommunityList
Definition: community.h:153
void StopPathResolution(int part_id, const BgpPath *path)
static bool is_route_target(const ExtCommunityValue &val)
Definition: community.h:265
const BgpAttr * GetAttr() const
Definition: bgp_path.h:87
const ReplicatedRtPathList & GetList() const
size_t count() const
Definition: bgp_route.cc:420
static const int kInvalidId
Definition: db_table.h:64
bool IsAliased() const
Definition: bgp_path.h:98
std::string ToString() const
LifetimeActor * deleter()
Definition: bgp_table.cc:1108
bool empty() const
Definition: db_table.h:101
RtReplicated(RoutePathReplicator *replicator)
const bytes_type & GetExtCommunity() const
Definition: origin_vn.h:33
Address::Family family() const
TableState * FindTableState(BgpTable *table)
void RemoveGroup(RtGroup *group)
bool NeedsResolution() const
Definition: bgp_path.h:135
static ExtCommunityPtr UpdateOriginVn(BgpServer *server, const ExtCommunity *ext_community, int vn_index)
boost::intrusive_ptr< DBTableWalk > DBTableWalkRef
Definition: db_table.h:169
void Notify(DBEntryBase *entry)
bool RemoveExportTable(Address::Family family, BgpTable *tbl)
#define RPR_TRACE_ONLY(obj,...)
const RouteTarget & rt()
void Leave(BgpTable *table, const RouteTarget &rt, bool import)
bool deleted() const
void LeaveVpnTable(RtGroup *group)
virtual bool IsReplicated() const
Definition: bgp_path.h:91
void AddGroup(RtGroup *group)
as_t autonomous_system() const
Definition: bgp_server.h:205
const RtReplicated * GetReplicationState(BgpTable *table, BgpRoute *rt) const
#define AS_TRANS
Definition: bgp_common.h:23
bool MayDelete() const
TableState(RoutePathReplicator *replicator, BgpTable *table)
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
Definition: sandesh_trace.h:46
PathResolver * path_resolver()
Definition: bgp_table.h:153
int index() const
const PathList & GetPathList() const
Definition: route.h:46
#define AS2_MAX
Definition: bgp_common.h:24
RTargetGroupMgr * rtarget_group_mgr()
Definition: bgp_server.h:110
static bool is_origin_vn(const ExtCommunityValue &val)
Definition: community.h:193