OpenSDN source code
routing_instance.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  * Copyright Contributors to the OpenSDN project
4  */
5 
7 
8 #include <boost/foreach.hpp>
9 #include <boost/assign/list_of.hpp>
10 #include <boost/functional/hash.hpp>
11 
12 #include <algorithm>
13 
14 #include "base/set_util.h"
15 #include "base/task_annotations.h"
16 #include "base/task_trigger.h"
17 #include "bgp/bgp_config.h"
18 #include "bgp/bgp_factory.h"
19 #include "bgp/bgp_log.h"
20 #include "bgp/bgp_mvpn.h"
21 #include "bgp/bgp_server.h"
22 #include "bgp/mvpn/mvpn_table.h"
28 #include "bgp/routing-instance/routing_table_types.h"
32 
33 using boost::assign::list_of;
34 using boost::system::error_code;
35 using boost::tie;
36 using std::make_pair;
37 using std::ostringstream;
38 using std::set;
39 using std::string;
40 using std::vector;
41 
44 
46 public:
47  explicit DeleteActor(RoutingInstanceMgr *manager)
48  : LifetimeActor(manager->server_->lifetime_manager()),
49  manager_(manager) {
50  }
51  virtual bool MayDelete() const {
52  return manager_->MayDelete();
53  }
54  virtual void Shutdown() {
55  manager_->Shutdown();
56  }
57  virtual void Destroy() {
59  }
60 
61 private:
63 };
64 
66  server_(server),
67  instance_config_lists_(
68  TaskScheduler::GetInstance()->HardwareThreadCount()),
69  default_rtinstance_(NULL),
70  deleted_count_(0),
71  asn_listener_id_(server->RegisterASNUpdateCallback(
72  boost::bind(&RoutingInstanceMgr::ASNUpdateCallback, this, _1, _2))),
73  identifier_listener_id_(server->RegisterIdentifierUpdateCallback(
74  boost::bind(&RoutingInstanceMgr::IdentifierUpdateCallback,
75  this, _1))),
76  dormant_trace_buf_size_(
77  GetEnvRoutingInstanceDormantTraceBufferCapacity()),
78  trace_buf_threshold_(
79  GetEnvRoutingInstanceDormantTraceBufferThreshold()),
80  deleter_(new DeleteActor(this)),
81  server_delete_ref_(this, server->deleter()) {
82  int task_id = TaskScheduler::GetInstance()->GetTaskId("bgp::ConfigHelper");
83  int hw_thread_count = TaskScheduler::GetInstance()->HardwareThreadCount();
84  for (int idx = 0; idx < hw_thread_count; ++idx) {
85  instance_config_triggers_.push_back(new TaskTrigger(boost::bind(
87  task_id, idx));
88  }
91  TaskScheduler::GetInstance()->GetTaskId("bgp::Config"), 0));
92 }
93 
95  assert(mvpn_project_managers_.empty());
96  assert(virtual_networks_.empty());
97  assert(deleted_count_ == 0);
101 }
102 
104  const string &network) const {
105  std::scoped_lock lock(mutex_);
106 
107  MvpnProjectManagerNetworks::const_iterator iter =
108  mvpn_project_managers_.find(network);
109  if (iter == mvpn_project_managers_.end())
110  return 0;
111  return iter->second.size();
112 }
113 
115  deleter_->Delete();
116 }
117 
119  for (RoutingInstanceIterator it = begin(); it != end(); ++it) {
120  InstanceTargetRemove(it->second);
121  InstanceVnIndexRemove(it->second);
122  }
123 }
124 
126  if (!neighbor_config_list_.empty())
127  return false;
128  for (size_t idx = 0; idx < instance_config_lists_.size(); ++idx) {
129  if (!instance_config_lists_[idx].empty())
130  return false;
131  }
132  return true;
133 }
134 
136  return deleter_.get();
137 }
138 
140  return deleter()->IsDeleted();
141 }
142 
143 //
144 // Go through all export targets for the RoutingInstance and add an entry for
145 // each one to the InstanceTargetMap.
146 //
147 // Ignore export targets that are not in the import list. This is done since
148 // export only targets are managed by user and the same export only target can
149 // be configured on multiple virtual networks.
150 //
152  std::scoped_lock lock(mutex_);
153  for (RoutingInstance::RouteTargetList::const_iterator it =
154  rti->GetExportList().begin(); it != rti->GetExportList().end(); ++it) {
155  if (rti->GetImportList().find(*it) == rti->GetImportList().end())
156  continue;
157  target_map_.insert(make_pair(*it, rti));
158  }
159 }
160 
161 //
162 // Go through all export targets for the RoutingInstance and remove the entry
163 // for each one from the InstanceTargetMap. Note that there may be multiple
164 // entries in the InstanceTargetMap for a given export target. Hence we need
165 // to make sure that we only remove the entry that matches the RoutingInstance.
166 //
167 // Ignore export targets that are not in the import list. They shouldn't be in
168 // in the map because of the same check in InstanceTargetAdd.
169 //
171  std::scoped_lock lock(mutex_);
172  for (RoutingInstance::RouteTargetList::const_iterator it =
173  rti->GetExportList().begin(); it != rti->GetExportList().end(); ++it) {
174  if (rti->GetImportList().find(*it) == rti->GetImportList().end())
175  continue;
176  for (InstanceTargetMap::iterator loc = target_map_.find(*it);
177  loc != target_map_.end() && loc->first == *it; ++loc) {
178  if (loc->second == rti) {
179  target_map_.erase(loc);
180  break;
181  }
182  }
183  }
184 }
185 
186 //
187 // Lookup the RoutingInstance for the given RouteTarget.
188 //
190  const RouteTarget &rtarget) const {
191  InstanceTargetMap::const_iterator loc = target_map_.find(rtarget);
192  if (loc == target_map_.end()) {
193  return NULL;
194  }
195  return loc->second;
196 }
197 
198 //
199 // Add an entry for the vn index to the VnIndexMap.
200 //
202  std::scoped_lock lock(mutex_);
203  if (rti->virtual_network_index())
204  vn_index_map_.insert(make_pair(rti->virtual_network_index(), rti));
205 }
206 
207 //
208 // Remove the entry for the vn index from the VnIndexMap. Note that there may
209 // be multiple entries in the VnIndexMap for a given vn index target. Hence we
210 // need to make sure that we remove the entry that matches the RoutingInstance.
211 //
213  std::scoped_lock lock(mutex_);
214  if (!rti->virtual_network_index())
215  return;
216 
217  int vn_index = rti->virtual_network_index();
218  for (VnIndexMap::iterator loc = vn_index_map_.find(vn_index);
219  loc != vn_index_map_.end() && loc->first == vn_index; ++loc) {
220  if (loc->second == rti) {
221  vn_index_map_.erase(loc);
222  break;
223  }
224  }
225 }
226 
227 //
228 // Lookup the RoutingInstance for the given vn index.
229 //
231  int vn_index) const {
232  VnIndexMap::const_iterator loc = vn_index_map_.find(vn_index);
233  if (loc == vn_index_map_.end())
234  return NULL;
235  return loc->second;
236 }
237 
238 //
239 // Lookup the VN name for the given vn index.
240 //
242  int vn_index) const {
243  const RoutingInstance *rti = GetInstanceByVnIndex(vn_index);
244  return rti ? rti->GetVirtualNetworkName() : "unresolved";
245 }
246 
247 //
248 // Lookup the vn index for the given RouteTarget.
249 //
250 // Return 0 if the RouteTarget does not map to a RoutingInstance.
251 // Return -1 if the RouteTarget maps to multiple RoutingInstances
252 // that belong to different VNs.
253 //
255  const RouteTarget &rtarget) const {
256  int vn_index = 0;
257  for (InstanceTargetMap::const_iterator loc = target_map_.find(rtarget);
258  loc != target_map_.end() && loc->first == rtarget; ++loc) {
259  int ri_vn_index = loc->second->virtual_network_index();
260  if (vn_index && ri_vn_index && ri_vn_index != vn_index)
261  return -1;
262  vn_index = ri_vn_index;
263  }
264 
265  return vn_index;
266 }
267 
268 //
269 // Derive the vn index from the route targets in the ExtCommunity.
270 //
271 // If the result is ambiguous i.e. we have a RouteTarget that maps
272 // to multiple vn indexes or we have multiple RouteTargets that map
273 // to different vn indexes, return 0.
274 //
276  const ExtCommunity *ext_community) const {
277  int vn_index = 0;
278  BOOST_FOREACH(const ExtCommunity::ExtCommunityValue &comm,
279  ext_community->communities()) {
281  continue;
282 
283  RouteTarget rtarget(comm);
284  int rtgt_vn_index = GetVnIndexByRouteTarget(rtarget);
285  if (rtgt_vn_index < 0 ||
286  (vn_index && rtgt_vn_index && rtgt_vn_index != vn_index)) {
287  vn_index = 0;
288  break;
289  } else if (rtgt_vn_index) {
290  vn_index = rtgt_vn_index;
291  }
292  }
293 
294  return vn_index;
295 }
296 
297 int
299  std::scoped_lock lock(mutex_);
300  size_t i = bmap_.find_first();
301  if (i == bmap_.npos) {
302  i = callbacks_.size();
303  callbacks_.push_back(callback);
304  } else {
305  bmap_.reset(i);
306  if (bmap_.none()) {
307  bmap_.clear();
308  }
309  callbacks_[i] = callback;
310  }
311  return i;
312 }
313 
315  std::scoped_lock lock(mutex_);
316  callbacks_[listener] = NULL;
317  if ((size_t) listener == callbacks_.size() - 1) {
318  while (!callbacks_.empty() && callbacks_.back() == NULL) {
319  callbacks_.pop_back();
320  }
321  if (bmap_.size() > callbacks_.size()) {
322  bmap_.resize(callbacks_.size());
323  }
324  } else {
325  if ((size_t) listener >= bmap_.size()) {
326  bmap_.resize(listener + 1);
327  }
328  bmap_.set(listener);
329  }
330 }
331 
333  std::scoped_lock lock(mutex_);
334  for (InstanceOpListenersList::iterator iter = callbacks_.begin();
335  iter != callbacks_.end(); ++iter) {
336  if (*iter != NULL) {
337  RoutingInstanceCb cb = *iter;
338  (cb)(name, op);
339  }
340  }
341 }
342 
344  if (deleted()) {
345  deleter()->RetryDelete();
346  } else {
347  BOOST_FOREACH(const string &name, instance_config_lists_[idx]) {
348  const BgpInstanceConfig *config =
349  server()->config_manager()->FindInstance(name);
350  if (!config)
351  continue;
352  LocateRoutingInstance(config);
353  }
354  }
355 
356  instance_config_lists_[idx].clear();
357  return true;
358 }
359 
361  return default_rtinstance_;
362 }
363 
365  return default_rtinstance_;
366 }
367 
369  RoutingInstanceList::iterator iter = instances_.find(name);
370  if (iter != instances_.end())
371  return iter->second;
372  return NULL;
373 }
374 
376  const string &name) const {
377  RoutingInstanceList::const_iterator iter = instances_.find(name);
378  if (iter != instances_.end())
379  return iter->second;
380  return NULL;
381 }
382 
384  const string &name) {
385  std::scoped_lock lock(mutex_);
386  RoutingInstanceList::iterator iter = instances_.find(name);
387  if (iter != instances_.end())
388  return iter->second;
389  return NULL;
390 }
391 
393  std::scoped_lock lock(mutex_);
394  instances_.insert(make_pair(rtinstance->config()->name(),
395  rtinstance));
396 }
397 
399  const BgpInstanceConfig *config) {
400  RoutingInstance *rtinstance = GetRoutingInstanceLocked(config->name());
401  if (rtinstance) {
402  if (rtinstance->deleted()) {
405  config->name(),
406  "Instance recreated before pending deletion is complete");
407  } else {
408  UpdateRoutingInstance(rtinstance, config);
409  }
410  } else {
411  rtinstance = CreateRoutingInstance(config);
412  }
413 }
414 
415 void RoutingInstanceMgr::LocateRoutingInstance(const string &name) {
416  static boost::hash<string> string_hash;
417 
418  if (name == BgpConfigManager::kMasterInstance) {
419  const BgpInstanceConfig *config =
420  server()->config_manager()->FindInstance(name);
421  assert(config);
422  LocateRoutingInstance(config);
423  } else {
424  size_t idx = string_hash(name) % instance_config_lists_.size();
425  instance_config_lists_[idx].insert(name);
426  instance_config_triggers_[idx]->Set();
427  }
428 }
429 
430 // Update VirtualNetwork to RoutingInstance name mapping.
432  const string &virtual_network, const string &instance_name) {
433  std::scoped_lock lock(mutex_);
434 
435  VirtualNetworksMap::iterator iter;
436  bool inserted;
437  tie(iter, inserted) = virtual_networks_.insert(make_pair(virtual_network,
438  set<string>()));
439  assert(iter->second.insert(instance_name).second);
440  return true;
441 }
442 
444  const string &virtual_network, const string &instance_name) {
445  std::scoped_lock lock(mutex_);
446 
447  VirtualNetworksMap::iterator iter = virtual_networks_.find(virtual_network);
448  assert(iter != virtual_networks_.end());
449 
450  // Delete this instance from the set of virtual-network to instances map.
451  assert(iter->second.erase(instance_name) == 1);
452 
453  RoutingInstanceStatsData instance_info;
454  bool mapping_deleted = iter->second.empty();
455 
456  // Delete the mapping if the member set is empty.
457  if (mapping_deleted) {
458  virtual_networks_.erase(iter);
459 
460  // Delete the virtual-network specific UVE.
461  instance_info.set_deleted(true);
462  } else {
463 
464  // Delete this instance's uve, by deleting all table stats.
465  map<string, RoutingTableStats> stats_map;
466  stats_map.insert(make_pair(instance_name, RoutingTableStats()));
467  stats_map[instance_name].set_deleted(true);
468 
469  // Delete all uve stats across all address families.
471  i = static_cast<Address::Family>(i + 1)) {
472  SetTableStatsUve(i, stats_map, &instance_info);
473  }
474  }
475 
476  // Send delete uve.
477  instance_info.set_name(virtual_network);
478  assert(!instance_info.get_name().empty());
479  BGP_UVE_SEND(RoutingInstanceStats, instance_info);
480 
481  return mapping_deleted;
482 }
483 
485  const map<string, RoutingTableStats> &stats_map,
486  RoutingInstanceStatsData *instance_info) const {
487  // By switching over all families, we get compiler to tell us in future,
488  // when ever familiy enum list gets modified.
489  switch (family) {
490  case Address::UNSPEC:
491  break;
492  case Address::INET:
493  case Address::INETMPLS:
494  instance_info->set_raw_ipv4_stats(stats_map);
495  break;
496  case Address::INET6:
497  instance_info->set_raw_ipv6_stats(stats_map);
498  break;
499  case Address::INETVPN:
500  instance_info->set_raw_inetvpn_stats(stats_map);
501  break;
502  case Address::INET6VPN:
503  instance_info->set_raw_inet6vpn_stats(stats_map);
504  break;
505  case Address::RTARGET:
506  instance_info->set_raw_rtarget_stats(stats_map);
507  break;
508  case Address::EVPN:
509  instance_info->set_raw_evpn_stats(stats_map);
510  break;
511  case Address::ERMVPN:
512  instance_info->set_raw_ermvpn_stats(stats_map);
513  break;
514  case Address::MVPN:
515  instance_info->set_raw_mvpn_stats(stats_map);
516  break;
518  break;
519  }
520 }
521 
523  uint32_t out_q_depth = 0;
524 
525  for (RoutingInstanceIterator rit = begin(); rit != end(); ++rit) {
526  RoutingInstanceStatsData instance_info;
527  map<string, RoutingTableStats> stats_map;
528 
529  stats_map.insert(make_pair(rit->second->name(), RoutingTableStats()));
530  RoutingInstance::RouteTableList const rt_list =
531  rit->second->GetTables();
532 
533  // Prepare and send Statistics UVE for each routing-instance.
534  for (RoutingInstance::RouteTableList::const_iterator it =
535  rt_list.begin(); it != rt_list.end(); ++it) {
536  BgpTable *table = it->second;
537 
538  size_t markers;
539  out_q_depth += table->GetPendingRiboutsCount(&markers);
540 
541  stats_map[rit->second->name()].set_prefixes(table->Size());
542  stats_map[rit->second->name()].set_primary_paths(
543  table->GetPrimaryPathCount());
544  stats_map[rit->second->name()].set_secondary_paths(
545  table->GetSecondaryPathCount());
546  stats_map[rit->second->name()].set_infeasible_paths(
547  table->GetInfeasiblePathCount());
548 
549  uint64_t total_paths = table->GetPrimaryPathCount() +
550  table->GetSecondaryPathCount() +
551  table->GetInfeasiblePathCount();
552  stats_map[rit->second->name()].set_total_paths(total_paths);
553  SetTableStatsUve(table->family(), stats_map, &instance_info);
554  }
555 
556  // Set the primary key and trigger uve send.
557  instance_info.set_name(rit->second->GetVirtualNetworkName());
558  assert(!instance_info.get_name().empty());
559  BGP_UVE_SEND(RoutingInstanceStats, instance_info);
560  }
561 
562  return out_q_depth;
563 }
564 
566  const BgpInstanceConfig *config) {
567  RoutingInstance *rtinstance = BgpStaticObjectFactory::Create<RoutingInstance>(
568  config->name(), server_, this, config);
569  uint32_t ri_index = config->index();
570  if (config->name() == BgpConfigManager::kMasterInstance) {
571  default_rtinstance_ = rtinstance;
572  ri_index = 0;
573  }
574 
575  rtinstance->ProcessConfig();
576  InsertRoutingInstance(rtinstance);
577  rtinstance->set_index(ri_index);
578 
579  InstanceTargetAdd(rtinstance);
580  InstanceVnIndexAdd(rtinstance);
582 
583  // Notify clients about routing instance create
584  NotifyInstanceOp(config->name(), INSTANCE_ADD);
585 
586  vector<string> import_rt(config->import_list().begin(),
587  config->import_list().end());
588  vector<string> export_rt(config->export_list().begin(),
589  config->export_list().end());
590  RTINSTANCE_LOG(Create, rtinstance,
591  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL,
592  import_rt, export_rt, rtinstance->virtual_network_index());
593 
594  // Schedule creation of neighbors for this instance.
596 
597  // Update instance to virtual-network mapping structures.
599  rtinstance->name());
600 
601  // Create MvpnManager for all children mvpn networks.
602  MvpnTable *mvpn_table =
603  dynamic_cast<MvpnTable *>(rtinstance->GetTable(Address::MVPN));
604  mvpn_table->CreateMvpnManagers();
605  return rtinstance;
606 }
607 
609  const BgpInstanceConfig *config) {
610  bool old_always_subscribe = rtinstance->always_subscribe();
611 
612  // Note that InstanceTarget[Remove|Add] depend on the RouteTargetList in
613  // the RoutingInstance.
614  InstanceTargetRemove(rtinstance);
615  InstanceVnIndexRemove(rtinstance);
616  rtinstance->UpdateConfig(config);
617  InstanceTargetAdd(rtinstance);
618  InstanceVnIndexAdd(rtinstance);
619 
620  if (old_always_subscribe != rtinstance->always_subscribe()) {
623  }
624 
625  // Notify clients about routing instance create
627 
628  vector<string> import_rt(config->import_list().begin(),
629  config->import_list().end());
630  vector<string> export_rt(config->export_list().begin(),
631  config->export_list().end());
632  RTINSTANCE_LOG(Update, rtinstance,
633  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL, import_rt, export_rt,
634  rtinstance->virtual_network_index());
635 }
636 
637 //
638 // Concurrency: BGP Config task
639 //
640 // Trigger deletion of a particular routing-instance
641 //
642 // This involves several asynchronous steps such as deleting all tables in
643 // routing-instance (flush all notifications, registrations and user data).
644 //
646  CHECK_CONCURRENCY("bgp::Config");
647 
648  RoutingInstance *rtinstance = GetRoutingInstance(name);
649 
650  // Ignore if instance is not found as it might already have been deleted.
651  if (rtinstance && rtinstance->deleted()) {
653  rtinstance->GetVirtualNetworkName(), name,
654  "Duplicate instance delete while pending deletion");
655  return;
656  } else if (!rtinstance) {
658  name, name, "Instance not found during delete");
659  return;
660  }
661 
662  InstanceVnIndexRemove(rtinstance);
663  InstanceTargetRemove(rtinstance);
664  rtinstance->ClearConfig();
665 
666  RTINSTANCE_LOG(Delete, rtinstance,
667  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL);
668 
669  rtinstance->ProcessServiceChainConfig();
670  rtinstance->FlushStaticRouteConfig();
671  rtinstance->FlushRouteAggregationConfig();
672 
674  rtinstance->ManagedDelete();
675 }
676 
677 //
678 // Concurrency: Called from BGP config task manager
679 //
680 // Destroy a routing instance from the data structures
681 //
683  CHECK_CONCURRENCY("bgp::Config");
684 
685  RTINSTANCE_LOG(Destroy, rtinstance,
686  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL);
687 
689  rtinstance->name());
690 
691  // instance should also be deleted here
692  const string name = rtinstance->name();
693  RoutingInstanceList::iterator loc = instances_.find(rtinstance->name());
694  assert(loc != instances_.end());
695  instances_.erase(loc);
696  int index = rtinstance->index();
697  delete rtinstance;
698  // disable the TraceBuf for the deleted RoutingInstance
699  DisableTraceBuffer(name);
700  // index was allocated in Config Manager so needs to be freed
701  if (index >= 0)
703 
704  if (deleted())
705  return;
706 
707  if (rtinstance == default_rtinstance_) {
708  default_rtinstance_ = NULL;
709  return;
710  }
711 
712  const BgpInstanceConfig *config
713  = server()->config_manager()->FindInstance(name);
714  if (config) {
715  CreateRoutingInstance(config);
716  return;
717  }
718 }
719 
721  const std::string &name) {
722  SandeshTraceBufferPtr trace_buf;
723 
724  trace_buf = GetActiveTraceBuffer(name);
725  if (trace_buf == NULL) {
726  trace_buf = GetTraceBuffer(name);
727  }
728 
729  return trace_buf;
730 }
731 
733  const std::string &name) {
734  tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
735  SandeshTraceBufferPtr trace_buf;
736  RoutingInstanceTraceBufferMap::iterator iter;
737 
738  iter = trace_buffer_active_.find(name);
739  if (iter != trace_buffer_active_.end()) {
740  return iter->second;
741  }
742 
743  iter = trace_buffer_dormant_.find(name);
744  if (iter != trace_buffer_dormant_.end()) {
745  // tracebuf was created for this RoutingInstance in its prior
746  // incarnation
747  trace_buf = iter->second;
748  trace_buffer_dormant_.erase(iter);
749  trace_buffer_dormant_list_.remove(name);
750  trace_buffer_active_.insert(make_pair(name, trace_buf));
751  return trace_buf;
752  }
753 
754  // create new sandesh Buffer
755  trace_buf = SandeshTraceBufferCreate(
756  name + RTINSTANCE_TRACE_BUF, 1000);
757  trace_buffer_active_.insert(make_pair(name, trace_buf));
758 
759  return trace_buf;
760 }
761 
762 void RoutingInstanceMgr::DisableTraceBuffer(const std::string &name) {
763  tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
764  SandeshTraceBufferPtr trace_buf;
765  SandeshTraceBufferPtr trace_buf_delete;
766  RoutingInstanceTraceBufferMap::iterator iter;
767  std::pair<RoutingInstanceTraceBufferMap::iterator, bool> ret;
768  std::string ri_name;
769 
770  // Moving the trace buff from Active map to Dormant map
771  iter = trace_buffer_active_.find(name);
772  if (iter != trace_buffer_active_.end()) {
773  trace_buf = iter->second;
774  trace_buffer_active_.erase(iter);
776  // Move to Dormant map.
778  // Make room in the Dormant map, so creating by:
779  // 1. Delete oldest entries in dormant map
780  // 2. Insert the new entry.
781  size_t del_count = std::min(trace_buffer_dormant_list_.size(),
783  if (!del_count) {
784  // retain the latest deleted RI's TraceBuf
785  del_count = 1;
786  }
787  for (size_t i = 0; i < del_count; i++) {
788  iter = trace_buffer_dormant_.find(
790  assert(iter != trace_buffer_dormant_.end());
791  trace_buf_delete = iter->second;
792  trace_buffer_dormant_.erase(iter);
793  trace_buffer_dormant_list_.pop_front();
794  trace_buf_delete.reset();
795  }
796  }
797  ret = trace_buffer_dormant_.insert(make_pair(name, trace_buf));
798  assert(ret.second == true);
799  trace_buffer_dormant_list_.push_back(name);
800  }
801  }
802 
803  return;
804 }
805 
807 RoutingInstanceMgr::GetActiveTraceBuffer(const std::string &name) const {
808  tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
809  RoutingInstanceTraceBufferMap::const_iterator iter =
810  trace_buffer_active_.find(name);
811 
812  if (iter != trace_buffer_active_.end()) {
813  return iter->second;
814  } else {
815  return SandeshTraceBufferPtr();
816  }
817 }
818 
820 RoutingInstanceMgr::GetDormantTraceBuffer(const std::string &name) const {
821  tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
822  RoutingInstanceTraceBufferMap::const_iterator iter =
823  trace_buffer_dormant_.find(name);
824 
825  if (iter != trace_buffer_dormant_.end()) {
826  return iter->second;
827  } else {
828  return SandeshTraceBufferPtr();
829  }
830 }
831 
833  &name) const {
834  tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
835  RoutingInstanceTraceBufferMap::const_iterator iter =
836  trace_buffer_active_.find(name);
837 
838  return (iter != trace_buffer_active_.end());
839 }
840 
842  &name) const {
843  tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
844  RoutingInstanceTraceBufferMap::const_iterator iter =
845  trace_buffer_dormant_.find(name);
846  return (iter != trace_buffer_dormant_.end());
847 }
848 
849 size_t
851  char *buffer_capacity_str = getenv(
852  "CONTRAIL_ROUTING_INSTANCE_DORMANT_TRACE_BUFFER_SIZE");
853  // return Trace buf capacity 0, if not set in env variable.
854  if (buffer_capacity_str) {
855  size_t env_buffer_capacity = strtoul(buffer_capacity_str, NULL, 0);
856  return env_buffer_capacity;
857  }
858  return 0;
859 }
860 
861 size_t
863  char *buffer_threshold_str = getenv(
864  "CONTRAIL_ROUTING_INSTANCE_DORMANT_TRACE_BUFFER_THRESHOLD");
865  if (buffer_threshold_str) {
866  size_t env_buffer_threshold = strtoul(buffer_threshold_str, NULL, 0);
867  return env_buffer_threshold;
868  }
870 }
871 
873  tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
874  return trace_buffer_active_.size();
875 }
876 
878  tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
879  return trace_buffer_dormant_.size();
880 }
881 
883  const BgpInstanceConfig *config) {
884  if (config->neighbor_list().empty())
885  return;
886  std::scoped_lock lock(mutex_);
887  neighbor_config_list_.insert(config->name());
889 }
890 
892  if (deleted()) {
893  deleter()->RetryDelete();
894  } else {
895  BOOST_FOREACH(const string &name, neighbor_config_list_) {
896  RoutingInstance *rtinstance = GetRoutingInstance(name);
897  if (!rtinstance || rtinstance->deleted())
898  continue;
899  rtinstance->CreateNeighbors();
900  }
901  }
902 
903  neighbor_config_list_.clear();
904  return true;
905 }
906 
907 void RoutingInstanceMgr::ASNUpdateCallback(as_t old_asn, as_t old_local_asn) {
908  if (server_->local_autonomous_system() == old_local_asn)
909  return;
910  for (RoutingInstanceIterator it = begin(); it != end(); ++it) {
911  it->second->FlushAllRTargetRoutes(old_local_asn);
912  it->second->InitAllRTargetRoutes(server_->local_autonomous_system());
913  }
915  const Ip4Address old_identifier(server()->bgp_identifier());
916  master->DeleteMvpnRTargetRoute(old_local_asn, old_identifier);
918 }
919 
921  for (RoutingInstanceIterator it = begin(); it != end(); ++it) {
922  it->second->ProcessIdentifierUpdate(server_->local_autonomous_system());
923  }
926  old_identifier);
928 }
929 
930 //
931 // Disable processing of all instance config lists.
932 // For testing only.
933 //
935  for (size_t idx = 0; idx < instance_config_triggers_.size(); ++idx) {
936  instance_config_triggers_[idx]->set_disable();
937  }
938 }
939 
940 //
941 // Enable processing of all instance config lists.
942 // For testing only.
943 //
945  for (size_t idx = 0; idx < instance_config_triggers_.size(); ++idx) {
946  instance_config_triggers_[idx]->set_enable();
947  }
948 }
949 
950 //
951 // Disable processing of neighbor config list.
952 // For testing only.
953 //
955  neighbor_config_trigger_->set_disable();
956 }
957 
958 //
959 // Enable processing of neighbor config list.
960 // For testing only.
961 //
963  neighbor_config_trigger_->set_enable();
964 }
965 
967 public:
969  : LifetimeActor(server ? server->lifetime_manager() : NULL),
970  parent_(parent) {
971  }
972  virtual bool MayDelete() const {
973  return parent_->MayDelete();
974  }
975  virtual void Shutdown() {
979  parent_->Shutdown();
980  }
981  virtual void Destroy() {
984  }
985 
986 private:
988 };
989 
991  RoutingInstanceMgr *mgr,
992  const BgpInstanceConfig *config)
993  : name_(name), index_(-1), server_(server), mgr_(mgr), config_(config),
994  is_master_(false), always_subscribe_(false), virtual_network_index_(0),
995  virtual_network_allow_transit_(false),
996  virtual_network_pbb_evpn_enable_(false),
997  vxlan_id_(0),
998  deleter_(new DeleteActor(server, this)),
999  manager_delete_ref_(this, NULL),
1000  mvpn_project_manager_network_(BgpConfigManager::kFabricInstance) {
1001  if (mgr) {
1002  std::scoped_lock lock(mgr->mutex());
1004  }
1005 }
1006 
1008 }
1009 
1011  CHECK_CONCURRENCY("bgp::Config");
1012 
1013  if (config_->neighbor_list().empty())
1014  return;
1016  BOOST_FOREACH(const string &name, config_->neighbor_list()) {
1018  continue;
1020  }
1021 }
1022 
1024  RoutingPolicyMgr *policy_mgr = server()->routing_policy_mgr();
1025  BOOST_FOREACH(RoutingPolicyAttachInfo info,
1027  RoutingPolicy *policy =
1028  policy_mgr->GetRoutingPolicy(info.routing_policy_);
1029  if (policy) {
1030  routing_policies_.push_back(make_pair(policy,
1031  policy->generation()));
1032  }
1033  }
1034 }
1035 
1037  return mgr_->LocateTraceBuffer(name_);
1038 }
1039 
1040 //
1041 // Update the routing policy on the instance
1042 // 1. New policy is added
1043 // 2. Policy order changed
1044 // 3. Policy is removed
1045 // 4. Existing policy gets updated(terms in the policy got modified)
1046 // In any of the above cases, we call routing policy manager to re-evaluate the
1047 // routes in the BgpTables of this routing instance with new set of policies
1048 //
1050  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
1051  RoutingPolicyMgr *policy_mgr = server()->routing_policy_mgr();
1053  routing_policies())) {
1054  // Let RoutingPolicyMgr handle update of routing policy on the instance
1055  policy_mgr->ApplyRoutingPolicy(this);
1056  }
1057 }
1058 
1060  if (is_master_)
1061  return;
1062 
1074  vector<SCAddress::Family> families = list_of
1077 
1078  BOOST_FOREACH(SCAddress::Family family, families) {
1079  const ServiceChainConfig *sc_config =
1080  config_ ? config_->service_chain_info(family) : NULL;
1082  if (sc_config && !sc_config->routing_instance.empty()) {
1083  manager->LocateServiceChain(this, *sc_config);
1084  } else {
1085  manager->StopServiceChain(this);
1086  }
1087  }
1088 }
1089 
1091  if (is_master_)
1092  return;
1093 
1094  vector<Address::Family> families = list_of(Address::INET)(Address::INET6);
1095  BOOST_FOREACH(Address::Family family, families) {
1097  if (!manager && !config_->static_routes(family).empty())
1098  manager = LocateStaticRouteMgr(family);
1099  if (manager)
1100  manager->ProcessStaticRouteConfig();
1101  }
1102 }
1103 
1105  if (is_master_)
1106  return;
1107 
1108  vector<Address::Family> families = list_of(Address::INET)(Address::INET6);
1109  BOOST_FOREACH(Address::Family family, families) {
1111  if (!manager && !config_->static_routes(family).empty())
1112  manager = LocateStaticRouteMgr(family);
1113  if (manager)
1114  manager->UpdateStaticRouteConfig();
1115  }
1116 }
1117 
1119  if (is_master_)
1120  return;
1121 
1122  vector<Address::Family> families = list_of(Address::INET)(Address::INET6);
1123  BOOST_FOREACH(Address::Family family, families) {
1125  if (manager)
1126  manager->FlushStaticRouteConfig();
1127  }
1128 }
1129 
1131  if (is_master_)
1132  return;
1133 
1134  vector<Address::Family> families = list_of(Address::INET)(Address::INET6);
1135  BOOST_FOREACH(Address::Family family, families) {
1137  if (manager)
1138  manager->UpdateAllRoutes();
1139  }
1140 }
1141 
1143  if (is_master_)
1144  return;
1145 
1146  vector<Address::Family> families = list_of(Address::INET)(Address::INET6);
1147  BOOST_FOREACH(Address::Family family, families) {
1148  IRouteAggregator *aggregator = route_aggregator(family);
1149  if (!aggregator && !config_->aggregate_routes(family).empty())
1150  aggregator = LocateRouteAggregator(family);
1151  if (aggregator)
1152  aggregator->ProcessAggregateRouteConfig();
1153  }
1154 }
1155 
1157  if (is_master_)
1158  return;
1159 
1160  vector<Address::Family> families = list_of(Address::INET)(Address::INET6);
1161  BOOST_FOREACH(Address::Family family, families) {
1162  IRouteAggregator *aggregator = route_aggregator(family);
1163  if (!aggregator && !config_->aggregate_routes(family).empty())
1164  aggregator = LocateRouteAggregator(family);
1165  if (aggregator)
1166  aggregator->UpdateAggregateRouteConfig();
1167  }
1168 }
1169 
1171  if (is_master_)
1172  return;
1173 
1174  vector<Address::Family> families = list_of(Address::INET)(Address::INET6);
1175  BOOST_FOREACH(Address::Family family, families) {
1176  IRouteAggregator *aggregator = route_aggregator(family);
1177  if (aggregator)
1178  aggregator->FlushAggregateRouteConfig();
1179  }
1180 }
1181 
1183  if (asn == 0)
1184  return;
1185  string id_str = "target:" + old_ip.to_string() + ":0";
1186  RouteTarget rtarget = RouteTarget::FromString(id_str);
1187  DeleteRTargetRoute(asn, rtarget);
1188 }
1189 
1191  if (asn == 0)
1192  return;
1193  const Ip4Address server_ip(server()->bgp_identifier());
1194  string id_str = "target:" + server_ip.to_string() + ":0";
1195  RouteTarget rtarget = RouteTarget::FromString(id_str);
1196  AddRTargetRoute(asn, rtarget);
1197 }
1198 
1200  RoutingInstanceInfo info = GetDataCollection("");
1201 
1202  // Initialize virtual network info.
1208  vxlan_id_ = config_->vxlan_id();
1210 
1211  // Always subscribe (using RTF) for RTs of PNF service chain instances.
1213 
1214  vector<string> import_rt, export_rt;
1215  BOOST_FOREACH(string irt, config_->import_list()) {
1216  error_code error;
1217  RouteTarget rt = RouteTarget::FromString(irt, &error);
1218  if (!error) {
1219  import_.insert(rt);
1220  import_rt.push_back(irt);
1221  }
1222  }
1223  BOOST_FOREACH(string ert, config_->export_list()) {
1224  error_code error;
1225  RouteTarget rt = RouteTarget::FromString(ert, &error);
1226  if (!error) {
1227  export_.insert(rt);
1228  export_rt.push_back(ert);
1229  }
1230  }
1231  RTINSTANCE_LOG(Update, this,
1232  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL,
1233  import_rt, export_rt, this->virtual_network_index());
1234 
1235  if (import_rt.size())
1236  info.set_add_import_rt(import_rt);
1237  if (export_rt.size())
1238  info.set_add_export_rt(export_rt);
1239  if (import_rt.size() || export_rt.size())
1241 
1242  // Create BGP Table
1244  assert(mgr_->count() == 0);
1245  is_master_ = true;
1246 
1254 
1255  BgpTable *table_inet = static_cast<BgpTable *>(
1256  server_->database()->CreateTable("inet.0"));
1257  assert(table_inet);
1258  AddTable(table_inet);
1259 
1260  BgpTable *table_inetmpls = static_cast<BgpTable *>(
1261  server_->database()->CreateTable("inet.3"));
1262  assert(table_inetmpls);
1263  AddTable(table_inetmpls);
1264 
1265  BgpTable *table_inet6 = static_cast<BgpTable *>(
1266  server_->database()->CreateTable("inet6.0"));
1267  assert(table_inet6);
1268  AddTable(table_inet6);
1269  } else {
1270  // Create foo.family.0.
1271  // Create path-resolver in INET, INET6 and EVPN VRF tables to enable
1272  // nh_reachability check for fast convergence.
1274  inet_table->LocatePathResolver();
1275 
1276  BgpTable *inet6_table =
1278  inet6_table->LocatePathResolver();
1279 
1281 
1283  evpn_table->LocatePathResolver();
1284 
1286 
1287  // Create path-resolver in mvpn table.
1288  table->LocatePathResolver();
1289  }
1290 
1295 }
1296 
1298  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
1299 
1300  // This is a noop in production code. However unit tests may pass a
1301  // new object.
1302  config_ = cfg;
1303 
1304  // Always subscribe (using RTF) for RTs of PNF service chain instances.
1306 
1307  // Figure out if there's a significant configuration change that requires
1308  // notifying routes to all listeners.
1309  bool notify_routes = false;
1311  notify_routes = true;
1314  notify_routes = true;
1315  if (virtual_network_ != cfg->virtual_network())
1316  notify_routes = true;
1318  notify_routes = true;
1319 
1320  // Trigger notification of all routes in each table.
1321  if (notify_routes) {
1322  BOOST_FOREACH(RouteTableList::value_type &entry, vrf_tables_by_name_) {
1323  BgpTable *table = entry.second;
1324  table->NotifyAllEntries();
1325  }
1326  }
1327 
1328  // Update all static routes so that they reflect the new OriginVn.
1331 
1332  string prev_vn_name = GetVirtualNetworkName();
1333 
1334  // Update virtual network info.
1336 
1337  // Recreate instance stats' UVE, if its key: virtual_network is modified.
1338  if (prev_vn_name != GetVirtualNetworkName()) {
1339  mgr_->DeleteVirtualNetworkMapping(prev_vn_name, name_);
1341  }
1342 
1346  vxlan_id_ = cfg->vxlan_id();
1348 
1349  // Master routing instance doesn't have import & export list
1350  // Master instance imports and exports all RT
1352  return;
1353 
1354  RouteTargetList future_import;
1355  vector<string> add_import_rt, remove_import_rt;
1356  BOOST_FOREACH(const string &rtarget_str, cfg->import_list()) {
1357  error_code error;
1358  RouteTarget rt = RouteTarget::FromString(rtarget_str, &error);
1359  if (!error)
1360  future_import.insert(rt);
1361  }
1362  set_synchronize(&import_, &future_import,
1363  boost::bind(&RoutingInstance::AddRouteTarget, this, true,
1364  &add_import_rt, _1),
1365  boost::bind(&RoutingInstance::DeleteRouteTarget, this, true,
1366  &remove_import_rt, _1));
1367 
1368  RouteTargetList future_export;
1369  vector<string> add_export_rt, remove_export_rt;
1370  BOOST_FOREACH(const string &rtarget_str, cfg->export_list()) {
1371  error_code error;
1372  RouteTarget rt = RouteTarget::FromString(rtarget_str, &error);
1373  if (!error)
1374  future_export.insert(rt);
1375  }
1376  set_synchronize(&export_, &future_export,
1377  boost::bind(&RoutingInstance::AddRouteTarget, this, false,
1378  &add_export_rt, _1),
1379  boost::bind(&RoutingInstance::DeleteRouteTarget, this, false,
1380  &remove_export_rt, _1));
1381 
1382  RoutingInstanceInfo info = GetDataCollection("");
1383  if (add_import_rt.size())
1384  info.set_add_import_rt(add_import_rt);
1385  if (remove_import_rt.size())
1386  info.set_remove_import_rt(remove_import_rt);
1387  if (add_export_rt.size())
1388  info.set_add_export_rt(add_export_rt);
1389  if (remove_export_rt.size())
1390  info.set_remove_export_rt(remove_export_rt);
1391  if (add_import_rt.size() || remove_import_rt.size() ||
1392  add_export_rt.size() || remove_export_rt.size())
1394 
1399 }
1400 
1402  CHECK_CONCURRENCY("bgp::Config");
1403  config_ = NULL;
1404 }
1405 
1407  // RoutingInstanceMgr logs the delete for non-master instances.
1408  if (IsMasterRoutingInstance()) {
1409  RTINSTANCE_LOG(Delete, this,
1410  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL);
1411  }
1412  deleter_->Delete();
1413 }
1414 
1416  CHECK_CONCURRENCY("bgp::Config");
1417 
1418  RTINSTANCE_LOG(Shutdown, this,
1419  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL);
1420 
1421  ClearConfig();
1423  if (is_master_) {
1424  const Ip4Address old_identifier(server()->bgp_identifier());
1426  old_identifier);
1427  }
1428  ClearRouteTarget();
1429 
1433 }
1434 
1436  return true;
1437 }
1438 
1440  return deleter_.get();
1441 }
1442 
1444  return deleter_.get();
1445 }
1446 
1448  return deleter()->IsDeleted();
1449 }
1450 
1452  if (!virtual_network_.empty())
1453  return virtual_network_;
1454  size_t pos = name_.rfind(':');
1455  if (pos == string::npos) {
1456  return name_;
1457  } else {
1458  return name_.substr(0, pos);
1459  }
1460 }
1461 
1463  return virtual_network_index_;
1464 }
1465 
1468 }
1469 
1472 }
1473 
1475  return vxlan_id_;
1476 }
1477 
1479  Address::Family vpn_family) {
1480  BgpTable *table = GetTable(vrf_family);
1481  if (table) {
1482  RoutePathReplicator *replicator = server_->replicator(vpn_family);
1483  BOOST_FOREACH(RouteTarget rt, import_) {
1484  replicator->Leave(table, rt, true);
1485  }
1486  BOOST_FOREACH(RouteTarget rt, export_) {
1487  replicator->Leave(table, rt, false);
1488  }
1489  }
1490 }
1491 
1493  const RouteTarget &rtarget) {
1494  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
1495 
1496  RTargetPrefix prefix(asn, rtarget);
1497  RTargetRoute rt_key(prefix);
1498 
1500  BgpTable *table = master->GetTable(Address::RTARGET);
1501  DBTablePartition *tbl_partition =
1502  static_cast<DBTablePartition *>(table->GetTablePartition(0));
1503 
1504  std::scoped_lock lock(mgr_->mutex());
1505  RTargetRoute *route =
1506  static_cast<RTargetRoute *>(tbl_partition->Find(&rt_key));
1507  if (!route) {
1508  route = new RTargetRoute(prefix);
1509  tbl_partition->Add(route);
1510  } else {
1511  route->ClearDelete();
1512  }
1513 
1514  if (route->FindPath(BgpPath::Local, index_))
1515  return;
1516 
1517  BgpAttrSpec attr_spec;
1519  attr_spec.push_back(&nexthop);
1521  attr_spec.push_back(&origin);
1522  BgpAttrPtr attr = server_->attr_db()->Locate(attr_spec);
1523 
1524  BgpPath *path = new BgpPath(index_, BgpPath::Local, attr);
1525  route->InsertPath(path);
1526  tbl_partition->Notify(route);
1527  BGP_LOG_ROUTE(table, static_cast<IPeer *>(NULL),
1528  route, "Insert Local path with path id " << index_);
1529 }
1530 
1532  const RouteTarget &rtarget) {
1533  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
1534 
1535  if (asn == 0)
1536  return;
1537 
1538  RTargetPrefix prefix(asn, rtarget);
1539  RTargetRoute rt_key(prefix);
1540 
1542  BgpTable *table = master->GetTable(Address::RTARGET);
1543  DBTablePartition *tbl_partition =
1544  static_cast<DBTablePartition *>(table->GetTablePartition(0));
1545 
1546  std::scoped_lock lock(mgr_->mutex());
1547  RTargetRoute *route =
1548  static_cast<RTargetRoute *>(tbl_partition->Find(&rt_key));
1549  if (!route || !route->RemovePath(BgpPath::Local, index_))
1550  return;
1551 
1552  BGP_LOG_ROUTE(table, static_cast<IPeer *>(NULL),
1553  route, "Delete Local path with path id " << index_);
1554  if (!route->HasPaths()) {
1555  tbl_partition->Delete(route);
1556  } else {
1557  tbl_partition->Notify(route);
1558  }
1559 }
1560 
1562  if (is_master_)
1563  return;
1564 
1565  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
1566  BOOST_FOREACH(RouteTarget rtarget, import_) {
1567  if (asn != 0 && always_subscribe_)
1568  AddRTargetRoute(asn, rtarget);
1569  }
1570 }
1571 
1573  if (is_master_)
1574  return;
1575 
1576  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
1577  BOOST_FOREACH(RouteTarget rtarget, import_) {
1578  DeleteRTargetRoute(asn, rtarget);
1579  }
1580 }
1581 
1583  FlushAllRTargetRoutes(asn);
1584  InitAllRTargetRoutes(asn);
1586 }
1587 
1589  vector<string> *change_list, RouteTargetList::const_iterator it) {
1590  BgpTable *ermvpn_table = GetTable(Address::ERMVPN);
1591  RoutePathReplicator *ermvpn_replicator =
1593  BgpTable *mvpn_table = GetTable(Address::MVPN);
1594  RoutePathReplicator *mvpn_replicator =
1596  BgpTable *evpn_table = GetTable(Address::EVPN);
1597  RoutePathReplicator *evpn_replicator =
1599  BgpTable *inet_table = GetTable(Address::INET);
1600  RoutePathReplicator *inetvpn_replicator =
1602  BgpTable *inet6_table = GetTable(Address::INET6);
1603  RoutePathReplicator *inet6vpn_replicator =
1605 
1606  change_list->push_back(it->ToString());
1607  if (import) {
1608  import_.insert(*it);
1611  } else {
1612  export_.insert(*it);
1613  }
1614 
1615  ermvpn_replicator->Join(ermvpn_table, *it, import);
1616  mvpn_replicator->Join(mvpn_table, *it, import);
1617  evpn_replicator->Join(evpn_table, *it, import);
1618  inetvpn_replicator->Join(inet_table, *it, import);
1619  inet6vpn_replicator->Join(inet6_table, *it, import);
1620 }
1621 
1623  vector<string> *change_list, RouteTargetList::iterator it) {
1624  BgpTable *ermvpn_table = GetTable(Address::ERMVPN);
1625  RoutePathReplicator *ermvpn_replicator =
1627  BgpTable *mvpn_table = GetTable(Address::MVPN);
1628  RoutePathReplicator *mvpn_replicator =
1630  BgpTable *evpn_table = GetTable(Address::EVPN);
1631  RoutePathReplicator *evpn_replicator =
1633  BgpTable *inet_table = GetTable(Address::INET);
1634  RoutePathReplicator *inetvpn_replicator =
1636  BgpTable *inet6_table = GetTable(Address::INET6);
1637  RoutePathReplicator *inet6vpn_replicator =
1639 
1640  ermvpn_replicator->Leave(ermvpn_table, *it, import);
1641  mvpn_replicator->Leave(mvpn_table, *it, import);
1642  evpn_replicator->Leave(evpn_table, *it, import);
1643  inetvpn_replicator->Leave(inet_table, *it, import);
1644  inet6vpn_replicator->Leave(inet6_table, *it, import);
1645 
1646  change_list->push_back(it->ToString());
1647  if (import) {
1649  import_.erase(it);
1650  } else {
1651  export_.erase(it);
1652  }
1653 }
1654 
1656  CHECK_CONCURRENCY("bgp::Config");
1657  if (IsMasterRoutingInstance()) {
1658  return;
1659  }
1660 
1666 
1667  import_.clear();
1668  export_.clear();
1669 }
1670 
1672  BgpTable *rtargettbl = static_cast<BgpTable *>(
1673  server_->database()->CreateTable("bgp.rtarget.0"));
1674  RTINSTANCE_LOG_TABLE(Create, this, rtargettbl, SandeshLevel::SYS_DEBUG,
1676  AddTable(rtargettbl);
1677  return rtargettbl;
1678 }
1679 
1681  string table_name = GetTableName(name(), vpn_family);
1682  BgpTable *table = static_cast<BgpTable *>(
1683  server_->database()->CreateTable(table_name));
1684  assert(table);
1685 
1686  AddTable(table);
1687  RTINSTANCE_LOG_TABLE(Create, this, table, SandeshLevel::SYS_DEBUG,
1689  assert(server_->rtarget_group_mgr()->empty());
1690  RoutePathReplicator *replicator = server_->replicator(vpn_family);
1691  replicator->Initialize();
1692  return table;
1693 }
1694 
1696  Address::Family vpn_family) {
1697  string table_name = GetTableName(name(), vrf_family);
1698  BgpTable *table = static_cast<BgpTable *>(
1699  server_->database()->CreateTable(table_name));
1700  assert(table);
1701 
1702  AddTable(table);
1703  RTINSTANCE_LOG_TABLE(Create, this, table, SandeshLevel::SYS_DEBUG,
1705  RoutePathReplicator *replicator = server_->replicator(vpn_family);
1706  BOOST_FOREACH(RouteTarget rt, import_) {
1707  replicator->Join(table, rt, true);
1708  }
1709  BOOST_FOREACH(RouteTarget rt, export_) {
1710  replicator->Join(table, rt, false);
1711  }
1712  return table;
1713 }
1714 
1716  vrf_tables_by_name_.insert(make_pair(tbl->name(), tbl));
1717  vrf_tables_by_family_.insert(make_pair(tbl->family(), tbl));
1718  tbl->set_routing_instance(this);
1719  RoutingInstanceInfo info = GetDataCollection("Add");
1720  info.set_family(Address::FamilyToString(tbl->family()));
1722 }
1723 
1725  RoutingInstanceInfo info = GetDataCollection("Remove");
1726  info.set_family(Address::FamilyToString(tbl->family()));
1727  vrf_tables_by_name_.erase(tbl->name());
1728  vrf_tables_by_family_.erase(tbl->family());
1730 }
1731 
1732 //
1733 // Concurrency: BGP Config task
1734 //
1735 // Remove the table from the map and delete the table data structure
1736 //
1738  CHECK_CONCURRENCY("bgp::Config");
1739 
1740  BgpTable *table = static_cast<BgpTable *>(dbtable);
1741 
1742  RTINSTANCE_LOG_TABLE(Destroy, this, table,
1743  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL);
1744 
1745  // Remove this table from various data structures
1746  server_->database()->RemoveTable(table);
1747  RemoveTable(table);
1748 
1749  // Make sure that there are no routes left in this table
1750  assert(table->Size() == 0);
1751 
1752  delete table;
1753 }
1754 
1755 string RoutingInstance::GetTableName(string instance_name,
1756  Address::Family fmly) {
1757  string table_name;
1758  if (instance_name == BgpConfigManager::kMasterInstance) {
1759  if ((fmly == Address::INET) || (fmly == Address::INET6)) {
1760  table_name = Address::FamilyToTableString(fmly) + ".0";
1761  } else if (fmly == Address::INETMPLS) {
1762  table_name = Address::FamilyToTableString(fmly) + ".3";
1763  } else {
1764  table_name = "bgp." + Address::FamilyToTableString(fmly) + ".0";
1765  }
1766  } else {
1767  table_name =
1768  instance_name + "." + Address::FamilyToTableString(fmly) + ".0";
1769  }
1770  return table_name;
1771 }
1772 
1774  RouteTableFamilyList::const_iterator loc = vrf_tables_by_family_.find(fmly);
1775  return (loc != vrf_tables_by_family_.end() ? loc->second : NULL);
1776 }
1777 
1779  RouteTableFamilyList::const_iterator loc = vrf_tables_by_family_.find(fmly);
1780  return (loc != vrf_tables_by_family_.end() ? loc->second : NULL);
1781 }
1782 
1783 string RoutingInstance::GetVrfFromTableName(const string table) {
1784  static set<string> master_tables = list_of("inet.0")("inet.3")("inet6.0");
1785  static set<string> vpn_tables =
1786  list_of("bgp.l3vpn.0")("bgp.ermvpn.0")("bgp.evpn.0")("bgp.rtarget.0")
1787  ("bgp.l3vpn-inet6.0")("bgp.mvpn.0");
1788 
1789  if (master_tables.find(table) != master_tables.end())
1791  if (vpn_tables.find(table) != vpn_tables.end())
1793 
1794  size_t pos1 = table.rfind('.');
1795  if (pos1 == string::npos)
1796  return "__unknown__";
1797  size_t pos2 = table.rfind('.', pos1 - 1);
1798  if (pos2 == string::npos)
1799  return "__unknown__";
1800 
1801  return table.substr(0, pos2);
1802 }
1803 
1805  index_ = index;
1806  if (is_master_)
1807  return;
1808 
1810 }
1811 
1812 RoutingInstanceInfo RoutingInstance::GetDataCollection(const char *operation) {
1813  RoutingInstanceInfo info;
1814  info.set_name(GetVirtualNetworkName());
1815  info.set_instance_name(name_);
1816  info.set_hostname(server_->localname());
1817  if (rd_.get()) info.set_route_distinguisher(rd_->ToString());
1818  if (operation) info.set_operation(operation);
1819  return info;
1820 }
1821 
1822 //
1823 // Return true if one of the route targets in the ExtCommunity is in the
1824 // set of export RouteTargets for this RoutingInstance.
1825 //
1827  if (!extcomm)
1828  return false;
1829 
1830  BOOST_FOREACH(const ExtCommunity::ExtCommunityValue &value,
1831  extcomm->communities()) {
1832  if (!ExtCommunity::is_route_target(value))
1833  continue;
1834  RouteTarget rtarget(value);
1835  if (export_.find(rtarget) != export_.end())
1836  return true;
1837  }
1838 
1839  return false;
1840 }
1841 
1842 // Return true if the route is a service-chain route
1844  const BgpTable *table = route->table();
1845  if (!table) {
1846  return false;
1847  }
1848  const BgpInstanceConfig *rt_config = this->config();
1849  if (!rt_config) {
1850  return false;
1851  }
1852  SCAddress::Family sc_family =
1854  const ServiceChainConfig *sc_config =
1855  rt_config->service_chain_info(sc_family);
1856  if (!sc_config) {
1857  return false;
1858  }
1859  return true;
1860 }
1861 
1862 //
1863 // On given route/path apply the routing policy
1864 // Called from
1865 // * InsertPath [While adding the path for the first time]
1866 // * While walking the routing table to apply updating routing policy
1867 //
1868 
1870  BgpPath *path) const {
1871  ExtCommunityPtr ext_community = path->GetOriginalAttr()->ext_community();
1872  if (path->IsReplicated() &&
1873  ext_community && ext_community->GetSubClusterId()) {
1874  // If self sub-cluster id macthes with what is associated with the route
1875  // then no need to apply policy.
1876  if (route->SubClusterId() == ext_community->GetSubClusterId()) {
1877  BGP_LOG_ROUTE(route->table(), static_cast<IPeer *>(path->GetPeer()),
1878  route, "Not applying policy since sub-cluster associated "
1879  "with path is same as that with route");
1880  return true;
1881  }
1882  }
1883  // Don't apply routing policy on secondary path for service chain route
1884  if (path->IsReplicated() && IsServiceChainRoute(route)) {
1885  BGP_LOG_ROUTE(route->table(), static_cast<IPeer *>(path->GetPeer()),
1886  route, "Not applying policy for service-chain secondary "
1887  "routes");
1888  return true;
1889  }
1890  const RoutingPolicyMgr *policy_mgr = server()->routing_policy_mgr();
1891  // Take snapshot of original attribute
1892  BgpAttr *out_attr = new BgpAttr(*(path->GetOriginalAttr()));
1893  BOOST_FOREACH(RoutingPolicyInfo info, routing_policies()) {
1894  RoutingPolicyPtr policy = info.first;
1895  // Process the routing policy on original attribute and prefix
1896  // Update of the attribute based on routing policy action is done
1897  // on the snapshot of original attribute passed to this function
1899  policy_mgr->ExecuteRoutingPolicy(policy.get(), route,
1900  path, out_attr);
1901  if (result.first) {
1902  // Hit a terminal policy
1903  if (!result.second) {
1904  // Result of the policy is reject
1905  path->SetPolicyReject();
1906  } else if (path->IsPolicyReject()) {
1907  // Result of the policy is Accept
1908  // Clear the reject flag is marked before
1909  path->ResetPolicyReject();
1910  }
1911  IPeer *peer = path->GetPeer();
1912  // Process default tunnel encapsulation that may be configured per
1913  // address family on the peer. 'peer' is not expected to be NULL
1914  // except in unit tests.
1915  if (peer) {
1916  peer->ProcessPathTunnelEncapsulation(path, out_attr,
1917  server_->extcomm_db(), route->table());
1918  }
1919  BgpAttrPtr modified_attr = server_->attr_db()->Locate(out_attr);
1920  // Update the path with new set of attributes
1921  path->SetAttr(modified_attr, path->GetOriginalAttr());
1922  return result.second;
1923  }
1924  }
1925  // After processing all the routing policy,,
1926  // We are here means, all the routing policies have accepted the route
1927  IPeer *peer = path->GetPeer();
1928  if (peer) {
1929  peer->ProcessPathTunnelEncapsulation(path, out_attr,
1930  server_->extcomm_db(), route->table());
1931  }
1932  BgpAttrPtr modified_attr = server_->attr_db()->Locate(out_attr);
1933  path->SetAttr(modified_attr, path->GetOriginalAttr());
1934  // Clear the reject if marked so in past
1935  if (path->IsPolicyReject()) path->ResetPolicyReject();
1936  return true;
1937 }
1938 
1940  Address::Family family) {
1942  if (manager)
1943  return manager;
1944  if (family == Address::INET) {
1945  inet_static_route_mgr_.reset(
1946  BgpStaticObjectFactory::Create<IStaticRouteMgr, Address::INET>(this));
1947  return inet_static_route_mgr_.get();
1948  } else if (family == Address::INET6) {
1950  BgpStaticObjectFactory::Create<IStaticRouteMgr, Address::INET6>(this));
1951  return inet6_static_route_mgr_.get();
1952  }
1953  return NULL;
1954 }
1955 
1957  Address::Family family) {
1958  IRouteAggregator *aggregator = route_aggregator(family);
1959  if (aggregator)
1960  return aggregator;
1961  if (family == Address::INET) {
1962  GetTable(family)->LocatePathResolver();
1963  inet_route_aggregator_.reset(
1964  BgpStaticObjectFactory::Create<IRouteAggregator, Address::INET>(this));
1965  inet_route_aggregator_->Initialize();
1966  return inet_route_aggregator_.get();
1967  } else if (family == Address::INET6) {
1968  GetTable(family)->LocatePathResolver();
1970  BgpStaticObjectFactory::Create<IRouteAggregator, Address::INET6>(this));
1971  inet6_route_aggregator_->Initialize();
1972  return inet6_route_aggregator_.get();
1973  }
1974  return NULL;
1975 }
1976 
1978  if (family == Address::INET) {
1979  inet_route_aggregator_.reset();
1980  } else if (family == Address::INET6) {
1981  inet6_route_aggregator_.reset();
1982  }
1983 }
1984 
1985 // Check whether the route is aggregating route
1987  const BgpRoute *route) const {
1988  if (!route_aggregator(table->family())) return false;
1989  return route_aggregator(table->family())->IsAggregateRoute(route);
1990 }
1991 
1992 // Check whether the route is contributing route to aggregate route
1994  const BgpRoute *route) const {
1995  if (!route_aggregator(table->family())) return false;
1996  return route_aggregator(table->family())->IsContributingRoute(route);
1997 }
1998 
2000  SCAddress sc_addr;
2001  SCAddress::Family sc_family =
2002  sc_addr.AddressFamilyToSCFamily(fmly);
2003  const ServiceChainConfig *sc_config =
2004  config_ ? config_->service_chain_info(sc_family) : NULL;
2005  if (sc_config && !sc_config->routing_instance.empty()) {
2006  RoutingInstance *dest =
2008  if (dest) return dest->virtual_network_index();
2009  }
2010  return virtual_network_index_;
2011 }
2012 
2014  return (peer_manager_ ? peer_manager_->size() : 0);
2015 }
2016 
2018  if (!peer_manager_)
2019  peer_manager_.reset(BgpStaticObjectFactory::Create<PeerManager>(this));
2020  return peer_manager_.get();
2021 }
2022 
2023 // Get primary routing instance name from service RI names which works for both
2024 // in-network and transparent service chains. Use name based lookup to identify
2025 // the primary RI of service instance.
2026 // Service RI Name Format: <domain>:<project>:<VN>:<ServiceRI>
2027 // Primaru RI Name Format: <domain>:<project>:<VN>:<VN>
2029  string n = name;
2030  vector<string> tokens;
2031  boost::split(tokens, n, boost::is_any_of(":"));
2032  if (tokens.size() < 3)
2033  return "";
2034  ostringstream os;
2035  os << tokens[0] << ":" << tokens[1] << ":" << tokens[2] << ":" << tokens[2];
2036  return os.str();
2037 }
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:15
std::vector< BgpAttribute * > BgpAttrSpec
Definition: bgp_attr.h:823
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:999
std::pair< RoutingPolicyPtr, uint32_t > RoutingPolicyInfo
Definition: bgp_common.h:47
boost::intrusive_ptr< RoutingPolicy > RoutingPolicyPtr
Definition: bgp_common.h:29
uint32_t as_t
Definition: bgp_common.h:22
#define BGP_UVE_SEND(type, object)
Definition: bgp_log.h:47
#define BGP_LOG_ROUTE(table, peer, route, arg)
Definition: bgp_log.h:248
Family
Definition: address.h:25
@ NUM_FAMILIES
Definition: address.h:36
@ INET
Definition: address.h:27
@ EVPN
Definition: address.h:32
@ INET6VPN
Definition: address.h:30
@ RTARGET
Definition: address.h:31
@ ERMVPN
Definition: address.h:33
@ INET6
Definition: address.h:28
@ INETVPN
Definition: address.h:29
@ MVPN
Definition: address.h:34
@ INETMPLS
Definition: address.h:35
@ UNSPEC
Definition: address.h:26
static std::string FamilyToTableString(Family family)
Definition: address.cc:68
static std::string FamilyToString(Family fmly)
Definition: address.cc:64
const ExtCommunity * ext_community() const
Definition: bgp_attr.h:918
virtual void ResetRoutingInstanceIndexBit(int index)=0
static const char * kMasterInstance
Definition: bgp_config.h:779
virtual const BgpInstanceConfig * FindInstance(const std::string &name) const =0
const RoutingPolicyConfigList & routing_policy_list() const
Definition: bgp_config.h:498
const std::string & virtual_network() const
Definition: bgp_config.h:455
int virtual_network_index() const
Definition: bgp_config.h:460
const RouteTargetList & export_list() const
Definition: bgp_config.h:447
const RouteTargetList & import_list() const
Definition: bgp_config.h:443
const AggregateRouteList & aggregate_routes(Address::Family family) const
Definition: bgp_config.cc:391
const std::string & name() const
Definition: bgp_config.h:433
bool virtual_network_allow_transit() const
Definition: bgp_config.h:465
const std::string & routing_instance_vxlan() const
Definition: bgp_config.h:512
const ServiceChainConfig * service_chain_info(SCAddress::Family family) const
Definition: bgp_config.cc:380
int index() const
Definition: bgp_config.h:510
bool virtual_network_pbb_evpn_enable() const
Definition: bgp_config.h:472
bool has_pnf() const
Definition: bgp_config.h:452
const NeighborList & neighbor_list() const
Definition: bgp_config.h:435
int vxlan_id() const
Definition: bgp_config.h:480
const StaticRouteList & static_routes(Address::Family family) const
Definition: bgp_config.cc:360
TypePtr Locate(Type *attr)
bool IsPolicyReject() const
Definition: bgp_path.h:119
void SetAttr(const BgpAttrPtr attr, const BgpAttrPtr original_attr)
Definition: bgp_path.h:83
void SetPolicyReject()
Definition: bgp_path.h:114
IPeer * GetPeer()
Definition: bgp_path.h:77
virtual bool IsReplicated() const
Definition: bgp_path.h:92
void ResetPolicyReject()
Definition: bgp_path.h:117
@ Local
Definition: bgp_path.h:44
const BgpAttr * GetOriginalAttr() const
Definition: bgp_path.h:89
const BgpPath * FindPath(BgpPath::PathSource src) const
Definition: bgp_route.cc:147
bool RemovePath(BgpPath::PathSource src, const IPeer *peer=NULL, uint32_t path_id=0)
Definition: bgp_route.cc:264
BgpTable * table()
Definition: bgp_route.cc:426
uint32_t SubClusterId() const
Definition: bgp_route.cc:781
void InsertPath(BgpPath *path)
Definition: bgp_route.cc:62
bool HasPaths() const
Definition: bgp_route.h:29
RTargetGroupMgr * rtarget_group_mgr()
Definition: bgp_server.h:115
ExtCommunityDB * extcomm_db()
Definition: bgp_server.h:194
IServiceChainMgr * service_chain_mgr(SCAddress::Family family)
Definition: bgp_server.h:141
uint32_t bgp_identifier() const
Definition: bgp_server.h:216
BgpConfigManager * config_manager()
Definition: bgp_server.h:105
void UnregisterASNUpdateCallback(int listener)
Definition: bgp_server.cc:882
DB * database()
Definition: bgp_server.h:208
RoutePathReplicator * replicator(Address::Family family)
Definition: bgp_server.h:153
as_t local_autonomous_system() const
Definition: bgp_server.h:215
void UnregisterIdentifierUpdateCallback(int listener)
Definition: bgp_server.cc:972
BgpAttrDB * attr_db()
Definition: bgp_server.h:188
const std::string & localname() const
Definition: bgp_server.cc:687
RoutingPolicyMgr * routing_policy_mgr()
Definition: bgp_server.h:111
const uint64_t GetSecondaryPathCount() const
Definition: bgp_table.h:162
virtual void set_routing_instance(RoutingInstance *rtinstance)
Definition: bgp_table.cc:81
size_t GetPendingRiboutsCount(size_t *markers) const
Definition: bgp_table.cc:1098
void LocatePathResolver()
Definition: bgp_table.cc:1084
const uint64_t GetPrimaryPathCount() const
Definition: bgp_table.h:161
const uint64_t GetInfeasiblePathCount() const
Definition: bgp_table.h:165
virtual Address::Family family() const =0
void ClearDelete()
Definition: db_entry.h:48
const std::string & name() const
Definition: db_table.h:111
void Notify(DBEntryBase *entry)
void Delete(DBEntryBase *)
virtual void Add(DBEntry *entry)
DBEntry * Find(const DBEntry *entry)
void NotifyAllEntries()
Definition: db_table.cc:623
virtual size_t Size() const
Definition: db_table.cc:534
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:463
void RemoveTable(DBTableBase *tbl_base)
Definition: db.cc:87
DBTableBase * CreateTable(const std::string &name)
Definition: db.cc:99
static bool is_route_target(const ExtCommunityValue &val)
Definition: community.h:268
boost::array< uint8_t, 8 > ExtCommunityValue
Definition: community.h:155
const ExtCommunityList & communities() const
Definition: community.h:183
Definition: ipeer.h:187
virtual void ProcessPathTunnelEncapsulation(const BgpPath *path, BgpAttr *attr, ExtCommunityDB *extcomm_db, const BgpTable *table) const =0
virtual void ProcessAggregateRouteConfig()=0
virtual void FlushAggregateRouteConfig()=0
virtual bool IsContributingRoute(const BgpRoute *route) const =0
virtual bool IsAggregateRoute(const BgpRoute *route) const =0
virtual void UpdateAggregateRouteConfig()=0
bool IsDeleted() const
Definition: lifetime.h:132
void RetryDelete()
Definition: lifetime.cc:74
void Reset(LifetimeActor *actor)
Definition: lifetime.h:83
void CreateMvpnManagers()
Definition: mvpn_table.cc:124
void PeerResurrect(std::string name)
Definition: peer_manager.cc:65
virtual BgpPeer * PeerLookup(std::string name) const
bool empty() const
void Join(BgpTable *table, const RouteTarget &rt, bool import)
void Leave(BgpTable *table, const RouteTarget &rt, bool import)
static RouteTarget FromString(const std::string &str, boost::system::error_code *error=NULL)
DeleteActor(RoutingInstanceMgr *manager)
InstanceTargetMap target_map_
RoutingInstanceConfigList neighbor_config_list_
int GetVnIndexByExtCommunity(const ExtCommunity *community) const
void EnableNeighborConfigListProcessing()
RoutingInstanceTraceBufferMap trace_buffer_active_
RoutingInstance * CreateRoutingInstance(const BgpInstanceConfig *config)
void UpdateRoutingInstance(RoutingInstance *rtinstance, const BgpInstanceConfig *config)
std::vector< TaskTrigger * > instance_config_triggers_
RoutingInstanceIterator end()
void ASNUpdateCallback(as_t old_asn, as_t old_local_asn)
bool CreateVirtualNetworkMapping(const std::string &virtual_network, const std::string &instance_name)
void DestroyRoutingInstance(RoutingInstance *rtinstance)
void NotifyInstanceOp(std::string name, Operation deleted)
std::vector< RoutingInstanceConfigList > instance_config_lists_
MvpnProjectManagerNetworks mvpn_project_managers_
LifetimeActor * deleter()
boost::scoped_ptr< TaskTrigger > neighbor_config_trigger_
bool HasRoutingInstanceDormantTraceBuf(const std::string &name) const
void InstanceTargetRemove(const RoutingInstance *rti)
size_t GetMvpnProjectManagerCount(const std::string &network) const
RoutingInstanceList::iterator RoutingInstanceIterator
LifetimeRef< RoutingInstanceMgr > server_delete_ref_
void InstanceTargetAdd(RoutingInstance *rti)
void InstanceVnIndexRemove(const RoutingInstance *rti)
size_t GetEnvRoutingInstanceDormantTraceBufferCapacity() const
RoutingInstance * GetRoutingInstance(const std::string &name)
boost::dynamic_bitset bmap_
void CreateRoutingInstanceNeighbors(const BgpInstanceConfig *config)
void InsertRoutingInstance(RoutingInstance *rtinstance)
const RoutingInstance * GetInstanceByVnIndex(int vn_index) const
RoutingInstanceTraceBufferMap trace_buffer_dormant_
size_t count() const
boost::scoped_ptr< DeleteActor > deleter_
RoutingInstanceIterator begin()
VirtualNetworksMap virtual_networks_
RoutingInstance * GetDefaultRoutingInstance()
BgpServer * server()
void EnableInstanceConfigListProcessing()
void InstanceVnIndexAdd(RoutingInstance *rti)
bool DeleteVirtualNetworkMapping(const std::string &virtual_network, const std::string &instance_name)
SandeshTraceBufferPtr GetDormantTraceBuffer(const std::string &name) const
boost::function< void(std::string, int)> RoutingInstanceCb
std::string GetVirtualNetworkByVnIndex(int vn_index) const
void UnregisterInstanceOpCallback(int id)
void DisableTraceBuffer(const std::string &name)
bool ProcessInstanceConfigList(int idx)
virtual void DeleteRoutingInstance(const std::string &name)
RoutingInstanceTraceBufferList trace_buffer_dormant_list_
size_t GetRoutingInstanceActiveTraceBufSize() const
int GetVnIndexByRouteTarget(const RouteTarget &rtarget) const
tbb::spin_rw_mutex rw_mutex_
void IdentifierUpdateCallback(Ip4Address old_identifier)
void DisableInstanceConfigListProcessing()
static std::string GetPrimaryRoutingInstanceName(const string &name_in)
RoutingInstanceMgr(BgpServer *server)
RoutingInstanceList instances_
RoutingInstance * default_rtinstance_
std::mutex & mutex()
int RegisterInstanceOpCallback(RoutingInstanceCb cb)
void DisableNeighborConfigListProcessing()
SandeshTraceBufferPtr GetActiveTraceBuffer(const std::string &name) const
const RoutingInstance * GetInstanceByTarget(const RouteTarget &target) const
SandeshTraceBufferPtr LocateTraceBuffer(const std::string &name)
InstanceOpListenersList callbacks_
SandeshTraceBufferPtr GetTraceBuffer(const std::string &name)
void LocateRoutingInstance(const BgpInstanceConfig *config)
RoutingInstance * GetRoutingInstanceLocked(const std::string &name)
uint32_t SendTableStatsUve()
size_t GetRoutingInstanceDormantTraceBufSize() const
void SetTableStatsUve(Address::Family family, const std::map< std::string, RoutingTableStats > &stats_map, RoutingInstanceStatsData *instance_info) const
virtual ~RoutingInstanceMgr()
bool HasRoutingInstanceActiveTraceBuf(const std::string &name) const
size_t GetEnvRoutingInstanceDormantTraceBufferThreshold() const
DeleteActor(BgpServer *server, RoutingInstance *parent)
virtual bool MayDelete() const
const std::string & name() const
BgpTable * VrfTableCreate(Address::Family vrf_family, Address::Family vpn_family)
boost::scoped_ptr< IStaticRouteMgr > inet_static_route_mgr_
void ProcessServiceChainConfig()
void InitAllRTargetRoutes(as_t asn)
const RoutingInstanceMgr * manager() const
LifetimeRef< RoutingInstance > manager_delete_ref_
void UpdateConfig(const BgpInstanceConfig *config)
bool ProcessRoutingPolicy(const BgpRoute *route, BgpPath *path) const
bool deleted() const
void AddRouteTarget(bool import, std::vector< std::string > *change_list, RouteTargetList::const_iterator it)
static std::string GetTableName(std::string instance_name, Address::Family fmly)
bool virtual_network_allow_transit_
std::unique_ptr< RouteDistinguisher > rd_
IRouteAggregator * route_aggregator(Address::Family family) const
void DeleteRouteTarget(bool import, std::vector< std::string > *change_list, RouteTargetList::iterator it)
void RemoveTable(BgpTable *tbl)
bool virtual_network_pbb_evpn_enable() const
RoutingPolicyAttachList * routing_policies()
RoutingInstance(std::string name, BgpServer *server, RoutingInstanceMgr *mgr, const BgpInstanceConfig *config)
boost::scoped_ptr< IRouteAggregator > inet6_route_aggregator_
RoutingPolicyAttachList routing_policies_
int GetOriginVnForAggregateRoute(Address::Family family) const
boost::scoped_ptr< DeleteActor > deleter_
std::map< std::string, BgpTable * > RouteTableList
void AddTable(BgpTable *tbl)
IRouteAggregator * LocateRouteAggregator(Address::Family family)
bool HasExportTarget(const ExtCommunity *extcomm) const
void AddMvpnRTargetRoute(as_t asn)
BgpTable * RTargetTableCreate()
PeerManager * peer_manager()
bool virtual_network_allow_transit() const
void set_index(int index)
static std::string GetVrfFromTableName(const std::string table)
IStaticRouteMgr * static_route_mgr(Address::Family family)
IStaticRouteMgr * LocateStaticRouteMgr(Address::Family family)
void DeleteRTargetRoute(as_t asn, const RouteTarget &rtarget)
void DeleteMvpnRTargetRoute(as_t old_asn, Ip4Address old_ip)
void AddRTargetRoute(as_t asn, const RouteTarget &rtarget)
void DestroyDBTable(DBTable *table)
void ProcessRoutingPolicyConfig()
bool IsContributingRoute(const BgpTable *table, const BgpRoute *route) const
const RouteTargetList & GetImportList() const
RoutingInstanceInfo GetDataCollection(const char *operation)
void ProcessRouteAggregationConfig()
void FlushRouteAggregationConfig()
BgpServer * server()
virtual ~RoutingInstance()
int virtual_network_index() const
boost::scoped_ptr< PeerManager > peer_manager_
BgpTable * VpnTableCreate(Address::Family vpn_family)
bool IsServiceChainRoute(const BgpRoute *route) const
const BgpInstanceConfig * config() const
BgpServer * server_
void UpdateRouteAggregationConfig()
boost::scoped_ptr< IRouteAggregator > inet_route_aggregator_
SandeshTraceBufferPtr trace_buffer() const
const BgpInstanceConfig * config_
RouteTargetList import_
PeerManager * LocatePeerManager()
bool MayDelete() const
void DestroyRouteAggregator(Address::Family family)
const RouteTargetList & GetExportList() const
bool always_subscribe() const
void ProcessIdentifierUpdate(as_t asn)
std::set< RouteTarget > RouteTargetList
LifetimeActor * deleter()
BgpTable * GetTable(Address::Family fmly)
RoutingInstanceMgr * mgr_
void ClearFamilyRouteTarget(Address::Family vrf_family, Address::Family vpn_family)
std::string virtual_network_
RouteTableList vrf_tables_by_name_
boost::scoped_ptr< IStaticRouteMgr > inet6_static_route_mgr_
RouteTableFamilyList vrf_tables_by_family_
bool virtual_network_pbb_evpn_enable_
void FlushAllRTargetRoutes(as_t asn)
RouteTargetList export_
size_t peer_manager_size() const
bool IsMasterRoutingInstance() const
void UpdateRoutingPolicyConfig()
bool IsAggregateRoute(const BgpTable *table, const BgpRoute *route) const
const std::string GetVirtualNetworkName() const
std::string routing_instance_vxlan_
bool UpdateRoutingPolicyList(const RoutingPolicyConfigList &cfg_list, RoutingPolicyAttachList *oper_list)
void ApplyRoutingPolicy(RoutingInstance *instance)
RoutingPolicy::PolicyResult ExecuteRoutingPolicy(const RoutingPolicy *policy, const BgpRoute *route, const BgpPath *path, BgpAttr *attr) const
RoutingPolicy * GetRoutingPolicy(const std::string &name)
uint32_t generation() const
std::pair< bool, bool > PolicyResult
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:307
int GetTaskId(const std::string &name)
Definition: task.cc:884
static TaskScheduler * GetInstance()
Definition: task.cc:574
int HardwareThreadCount()
Definition: task.h:405
boost::intrusive_ptr< const ExtCommunity > ExtCommunityPtr
Definition: community.h:451
SandeshTraceBufferPtr RoutingInstanceTraceBuf(SandeshTraceBufferCreate(RTINSTANCE_TRACE_BUF, 1000))
#define RTINSTANCE_LOG_TABLE(type, rtinstance, table, level, flags,...)
#define RTINSTANCE_LOG_FLAG_ALL
#define RTINSTANCE_TRACE_BUF
#define ROUTING_INSTANCE_DORMANT_TRACE_BUFFER_THRESHOLD_1K
#define ROUTING_INSTANCE_COLLECTOR_INFO(info)
#define RTINSTANCE_LOG(type, rtinstance, level, flags,...)
#define RTINSTANCE_LOG_WARNING_MESSAGE(server, flags,...)
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:19
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
Definition: sandesh_trace.h:47
bool set_synchronize(const SetType *set1, const SetType *set2, AddFunctor add_fn, DelFunctor del_fn)
Definition: set_util.h:22
std::string routing_policy_
Definition: bgp_common.h:38
static Family AddressFamilyToSCFamily(Address::Family family)
std::string routing_instance
Definition: bgp_config.h:328
#define CHECK_CONCURRENCY(...)
void STLDeleteValues(Container *container)
Definition: util.h:102