OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
route_aggregator.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 
7 #include <boost/foreach.hpp>
8 
9 #include <algorithm>
10 #include <string>
11 #include <vector>
12 
13 #include "sandesh/sandesh_types.h"
14 #include "sandesh/sandesh.h"
15 #include "sandesh/sandesh_trace.h"
16 #include "base/lifetime.h"
17 #include "base/map_util.h"
18 #include "base/task_annotations.h"
19 #include "base/task_trigger.h"
20 #include "bgp/bgp_log.h"
21 #include "bgp/bgp_server.h"
25 #include "bgp/routing-instance/route_aggregate_types.h"
26 
27 using std::make_pair;
28 using std::string;
29 
30 class RouteAggregatorState : public DBState {
31 public:
33  }
34 
36  assert(!aggregating_info_);
38  aggregator_ = true;
39  }
40 
42  assert(aggregating_info_);
43  aggregating_info_ = NULL;
44  aggregator_ = false;
45  }
46 
48  assert(!contributing_info_);
50  contributor_ = true;
51  }
52 
54  assert(contributing_info_);
55  contributing_info_ = NULL;
56  contributor_ = false;
57  }
58 
60  return contributing_info_;
61  }
62 
64  return aggregating_info_;
65  }
66 
67  bool contributor() const {
68  return contributor_;
69  }
70 
71  bool aggregator() const {
72  return aggregator_;
73  }
74 
75 private:
81 };
82 
83 template <typename T>
85 public:
86  typedef typename T::TableT TableT;
87  typedef typename T::RouteT RouteT;
88  typedef typename T::PrefixT PrefixT;
89  typedef typename T::AddressT AddressT;
91  // List of more specific routes resulted in Aggregate route PER PARTITION
92  typedef std::set<BgpRoute *> RouteList;
93  typedef std::vector<RouteList> ContributingRouteList;
94 
96  NoChange = 0,
98  };
99 
100  AggregateRoute(RoutingInstance *rtinstance, AggregateRouteMgrT *manager,
102 
103  virtual ~AggregateRoute() {
104  assert(!HasContributingRoutes());
105  }
106 
109  return manager_->GetAddress(addr);
110  }
111 
112  // Compare config and return whether cfg has updated
114 
117  }
118 
120  return routing_instance_;
121  }
122 
123  BgpTable *bgp_table() const {
124  return routing_instance_->GetTable(this->GetFamily());
125  }
126 
128  return aggregate_route_;
129  }
130 
131  IpAddress nexthop() const {
132  return nexthop_;
133  }
134 
135  bool IsMoreSpecific(BgpRoute *route) const {
136  const RouteT *ip_route = static_cast<RouteT *>(route);
137  const PrefixT &ip_prefix = ip_route->GetPrefix();
138  if (ip_prefix.addr() != GetAddress(nexthop()) &&
139  ip_prefix != aggregate_route_prefix_ &&
140  ip_prefix.IsMoreSpecific(aggregate_route_prefix_)) {
141  return true;
142  }
143  return false;
144  }
145 
146  bool IsOriginVnMatch(BgpRoute *route) const;
147  bool IsBestMatch(BgpRoute *route) const;
148 
149  virtual bool Match(BgpServer *server, BgpTable *table,
150  BgpRoute *route, bool deleted);
151 
153  nexthop_ = nexthop;
155  }
156 
157  void AddAggregateRoute();
158  void UpdateAggregateRoute();
159  void RemoveAggregateRoute();
160 
161  void set_aggregate_route(BgpRoute *aggregate);
162 
163  virtual string ToString() const {
164  return (string("AggregateRoute ") +
166  }
167 
169  return &contributors_;
170  }
171 
173  return contributors_;
174  }
175 
176  bool HasContributingRoutes() const {
177  BOOST_FOREACH(RouteList per_part_contributor, contribute_route_list()) {
178  if (!per_part_contributor.empty()) {
179  return true;
180  }
181  }
182  return false;
183  }
184 
185  bool IsContributingRoute(BgpRoute *route) const {
186  uint32_t part_id = route->get_table_partition()->index();
187  return (contributors_[part_id].find(route) !=
188  contributors_[part_id].end());
189  }
190 
192  DBRequest req;
194  RouteT *ip_route = static_cast<RouteT *>(route);
195  const PrefixT &prefix = ip_route->GetPrefix();
196  req.key.reset(new typename TableT::RequestKey(prefix, NULL));
197  bgp_table()->Enqueue(&req);
198  }
199 
201  RouteAggregatorState *state = static_cast<RouteAggregatorState *>
202  (route->GetState(bgp_table(), manager_->listener_id()));
203  if (state == NULL) {
204  state = new RouteAggregatorState();
205  route->SetState(bgp_table(), manager_->listener_id(), state);
206  }
207  return state;
208  }
209 
211  uint32_t part_id = route->get_table_partition()->index();
212  contributors_[part_id].insert(route);
213  RouteAggregatorState *state = LocateRouteState(route);
216  return (contributors_[part_id].size() == 1);
217  }
218 
220  if (!state->aggregator() && !state->contributor()) {
222  delete state;
223  }
224  }
225 
227  uint32_t part_id = route->get_table_partition()->index();
228  int num_deleted = contributors_[part_id].erase(route);
229  RouteAggregatorState *state = static_cast<RouteAggregatorState *>
230  (route->GetState(bgp_table(), manager_->listener_id()));
231  if (state) {
232  state->reset_contributing_info();
233  ClearRouteState(route, state);
235  } else {
236  assert(num_deleted != 1);
237  }
238  return contributors_[part_id].empty();
239  }
240 
241  void FillShowInfo(AggregateRouteInfo *info, bool summary) const;
242 
243 private:
250 
252 };
253 
254 template <typename T>
256  AggregateRouteMgrT *manager, const PrefixT &aggregate_route,
257  IpAddress nexthop)
258  : routing_instance_(rtinstance),
259  manager_(manager),
260  aggregate_route_prefix_(aggregate_route),
261  nexthop_(nexthop),
262  aggregate_route_(NULL),
263  contributors_(ContributingRouteList(DB::PartitionCount())) {
264 }
265 
266 // Compare config and return whether cfg has updated
267 template <typename T>
269  const AggregateRouteConfig &cfg) {
270  AddressT address = this->GetAddress(cfg.aggregate);
271  PrefixT prefix(address, cfg.prefix_length);
272  assert(aggregate_route_prefix_ == prefix);
273  if (nexthop_ != cfg.nexthop) {
274  return NexthopChange;
275  }
276  return NoChange;
277 }
278 
279 template <typename T>
281  const BgpPath *path = route->BestPath();
282  const BgpAttr *attr = path->GetAttr();
283  const ExtCommunity *ext_community = attr->ext_community();
284  int vni = 0;
285  if (ext_community) {
286  BOOST_FOREACH(const ExtCommunity::ExtCommunityValue &comm,
287  ext_community->communities()) {
288  if (!ExtCommunity::is_origin_vn(comm)) continue;
289  OriginVn origin_vn(comm);
290  vni = origin_vn.vn_index();
291  break;
292  }
293  }
294 
295  if (!vni && path->IsVrfOriginated())
296  vni = routing_instance()->virtual_network_index();
297 
298  if (vni == routing_instance()->GetOriginVnForAggregateRoute(GetFamily()))
299  return true;
300 
301  return false;
302 }
303 
304 //
305 // Calculate all aggregate prefixes to which the route can be contributing.
306 // We need to calculate the longest prefix to which this route belongs.
307 // E.g. routing instance is configured with 1/8, 1.1/16 and 1.1.1/24, 1.1.1.1/32
308 // should match 1.1.1/24. Similarly, 1.1.1/24 should be most specific to 1.1/16
309 // as so on
310 //
311 template <typename T>
313  const RouteT *ip_route = static_cast<RouteT *>(route);
314  const PrefixT &ip_prefix = ip_route->GetPrefix();
316  std::set<PrefixT> prefix_list;
317  for (it = manager_->aggregate_route_map().begin();
318  it != manager_->aggregate_route_map().end(); ++it) {
319  if (!it->second->deleted() && ip_prefix != it->first &&
320  ip_prefix.IsMoreSpecific(it->first)) {
321  prefix_list.insert(it->first);
322  }
323  }
324  // It should match atleast one prefix
325  assert(prefix_list.size());
326  //
327  // Longest prefix matches the aggregate prefix of current AggregateRoute
328  // return true to make this route as contributing route
329  // Longest prefix is the last prefix in the set
330  //
331  if (*(prefix_list.rbegin()) == aggregate_route_prefix_) return true;
332  return false;
333 }
334 
335 // Match function called from BgpConditionListener
336 // Concurrency : db::DBTable
337 template <typename T>
339  BgpRoute *route, bool deleted) {
340  CHECK_CONCURRENCY("db::DBTable");
341 
342  //
343  // Only interested routes
344  // Should satisfy following conditions
345  // 1. Origin VN should match origin VN of aggregated route
346  // 2. Route should be more specific
347  //
348  if ((!deleted && !IsOriginVnMatch(route)) || !IsMoreSpecific(route))
349  return false;
350 
351  if (!deleted) {
352  //
353  // If the route is already contributing, check whether it is still
354  // most specific aggregate prefix. Else remove the route as contributing
355  // route. As part of the notification, route will become contributing to
356  // most specific aggregate route prefix.
357  //
358  if (IsContributingRoute(route)) {
359  if (!IsBestMatch(route)) deleted = true;
360  } else if (table->IsContributingRoute(route)) {
361  //
362  // If the route is already contributing route of other aggregate
363  // prefix of this bgp-table, ignore it
364  //
365  return false;
366  }
367  }
368 
369  //
370  // Consider route only if it matches most specific aggregate prefix
371  // configured on the routing instance. e.g. if routing instance has
372  // following prefixes configured, 1/8, 1.1/16 and 1.1.1/24,
373  // 1.1.1.1/32 should match to 1.1.1/24 as most specific route.
374  //
375  if (!deleted && !IsBestMatch(route)) return false;
376 
377  BgpConditionListener *listener = server->condition_listener(GetFamily());
378  bool state_added = listener->CheckMatchState(table, route, this);
379  bool trigger_eval = false;
380  if (!deleted) {
381  if (!state_added) {
382  listener->SetMatchState(table, route, this);
383  trigger_eval = AddContributingRoute(route);
384  }
385  } else {
386  if (!state_added) {
387  // Not seen ADD ignore DELETE
388  return false;
389  }
390  trigger_eval = RemoveContributingRoute(route);
391  listener->RemoveMatchState(table, route, this);
392  }
393 
394  if (trigger_eval) manager_->EvaluateAggregateRoute(this);
395  return true;
396 }
397 
398 // AddAggregateRoute
399 template <typename T>
401  CHECK_CONCURRENCY("bgp::RouteAggregation");
402 
403  RouteT rt_key(aggregate_route_prefix());
404  DBTablePartition *partition =
405  static_cast<DBTablePartition *>(bgp_table()->GetTablePartition(&rt_key));
406  BgpRoute *aggregate_route =
407  static_cast<BgpRoute *>(partition->Find(&rt_key));
408 
409  if (aggregate_route == NULL) {
410  aggregate_route = new RouteT(aggregate_route_prefix());
411  partition->Add(aggregate_route);
412  } else {
413  aggregate_route->ClearDelete();
414  }
415 
416  BgpPath *existing_path = aggregate_route->FindPath(BgpPath::Aggregate, 0);
417  assert(existing_path == NULL);
418 
419  BgpAttrSpec attrs;
420  BgpAttrNextHop attr_nexthop(this->GetAddress(nexthop()));
421  attrs.push_back(&attr_nexthop);
422  ExtCommunitySpec extcomm_spec;
423  OriginVn origin_vn(routing_instance()->server()->autonomous_system(),
424  routing_instance()->GetOriginVnForAggregateRoute(GetFamily()));
425  extcomm_spec.communities.push_back(origin_vn.GetExtCommunityValue());
426  attrs.push_back(&extcomm_spec);
427  BgpAttrPtr attr = routing_instance()->server()->attr_db()->Locate(attrs);
428  BgpPath *new_path = new BgpPath(BgpPath::Aggregate,
429  attr.get(), BgpPath::ResolveNexthop, 0);
430  bgp_table()->path_resolver()->StartPathResolution(aggregate_route,
431  new_path);
432  aggregate_route->InsertPath(new_path);
433  partition->Notify(aggregate_route);
434  set_aggregate_route(aggregate_route);
435 
436  BGP_LOG_STR(BgpMessage, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_TRACE,
437  "Added aggregate path " << aggregate_route_->ToString() <<
438  " in table " << partition->table()->name());
439 }
440 
441 // UpdateAggregateRoute
442 template <typename T>
444  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
445 
446  if (aggregate_route_ == NULL) return;
447 
448  DBTablePartition *partition = static_cast<DBTablePartition *>
449  (bgp_table()->GetTablePartition(aggregate_route_));
450 
451  aggregate_route_->ClearDelete();
452 
453  BgpPath *existing_path = aggregate_route_->FindPath(BgpPath::Aggregate, 0);
454  if (existing_path)
455  bgp_table()->path_resolver()->StopPathResolution(partition->index(),
456  existing_path);
457  aggregate_route_->RemovePath(BgpPath::Aggregate);
458 
459  BgpAttrSpec attrs;
460  BgpAttrNextHop attr_nexthop(this->GetAddress(nexthop()));
461  attrs.push_back(&attr_nexthop);
462  ExtCommunitySpec extcomm_spec;
463  OriginVn origin_vn(routing_instance()->server()->autonomous_system(),
464  routing_instance()->GetOriginVnForAggregateRoute(GetFamily()));
465  extcomm_spec.communities.push_back(origin_vn.GetExtCommunityValue());
466  attrs.push_back(&extcomm_spec);
467  BgpAttrPtr attr = routing_instance()->server()->attr_db()->Locate(attrs);
468  BgpPath *new_path = new BgpPath(BgpPath::Aggregate,
469  attr.get(), BgpPath::ResolveNexthop, 0);
470  bgp_table()->path_resolver()->StartPathResolution(aggregate_route_,
471  new_path);
472  aggregate_route_->InsertPath(new_path);
473 
474  partition->Notify(aggregate_route_);
475 
476  BGP_LOG_STR(BgpMessage, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_TRACE,
477  "Updated aggregate path " << aggregate_route_->ToString() <<
478  " in table " << partition->table()->name());
479 }
480 
481 // RemoveAggregateRoute
482 template <typename T>
484  CHECK_CONCURRENCY("bgp::RouteAggregation");
485  BgpRoute *aggregate_route = aggregate_route_;
486  if (!aggregate_route) return;
487 
488  DBTablePartition *partition = static_cast<DBTablePartition *>
489  (bgp_table()->GetTablePartition(aggregate_route_));
490 
491  BgpPath *existing_path =
492  aggregate_route->FindPath(BgpPath::Aggregate, 0);
493  assert(existing_path != NULL);
494 
495  bgp_table()->path_resolver()->StopPathResolution(partition->index(),
496  existing_path);
497  aggregate_route->RemovePath(BgpPath::Aggregate);
498 
499  BGP_LOG_STR(BgpMessage, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_TRACE,
500  "Removed aggregate path " << aggregate_route_->ToString() <<
501  " in table " << partition->table()->name());
502 
503  if (!aggregate_route->HasPaths()) {
504  partition->Delete(aggregate_route);
505  } else {
506  partition->Notify(aggregate_route);
507  }
508  set_aggregate_route(NULL);
509 }
510 
511 template <typename T>
513  if (aggregate) {
514  assert(aggregate_route_ == NULL);
515  RouteAggregatorState *state = LocateRouteState(aggregate);
517  } else {
518  assert(aggregate_route_ != NULL);
519  RouteAggregatorState *state = static_cast<RouteAggregatorState *>
520  (aggregate_route_->GetState(bgp_table(), manager_->listener_id()));
521  assert(state);
522  state->reset_aggregating_info();
523  ClearRouteState(aggregate_route_, state);
524  }
525  aggregate_route_ = aggregate;
526 }
527 
528 template <typename T>
529 void AggregateRoute<T>::FillShowInfo(AggregateRouteInfo *info,
530  bool summary) const {
531  BgpTable *table = bgp_table();
532  info->set_deleted(deleted());
533  info->set_prefix(aggregate_route_prefix_.ToString());
534  if (aggregate_route_) {
535  ShowRouteBrief show_route;
536  aggregate_route_->FillRouteInfo(table, &show_route);
537  info->set_aggregate_rt(show_route);
538  }
539 
540  info->set_nexthop(nexthop_.to_string());
541 
542  if (summary)
543  return;
544 
545  std::vector<string> contributor_list;
546  BOOST_FOREACH(const RouteList &list, contribute_route_list()) {
547  BOOST_FOREACH(BgpRoute *rt, list) {
548  contributor_list.push_back(rt->ToString());
549  }
550  }
551  info->set_contributors(contributor_list);
552 }
553 
554 template <typename T>
556 public:
557  explicit DeleteActor(RouteAggregator *aggregator) :
558  LifetimeActor(aggregator->routing_instance()->server()->lifetime_manager()),
559  aggregator_(aggregator) {
560  }
561  virtual ~DeleteActor() {
562  }
563 
564  virtual bool MayDelete() const {
565  return aggregator_->MayDelete();
566  }
567 
568  virtual void Destroy() {
569  aggregator_->routing_instance()->DestroyRouteAggregator(
570  aggregator_->GetFamily());
571  }
572 
573 private:
575 };
576 
577 template <typename T>
579  : rtinstance_(rtinstance),
580  condition_listener_(rtinstance_->server()->condition_listener(GetFamily())),
581  listener_id_(DBTableBase::kInvalidId),
582  update_list_trigger_(new TaskTrigger(
583  boost::bind(&RouteAggregator::ProcessUpdateList, this),
584  TaskScheduler::GetInstance()->GetTaskId("bgp::RouteAggregation"),
585  0)),
586  unregister_list_trigger_(new TaskTrigger(
587  boost::bind(&RouteAggregator::ProcessUnregisterList, this),
588  TaskScheduler::GetInstance()->GetTaskId("bgp::Config"), 0)),
589  deleter_(new DeleteActor(this)),
590  instance_delete_ref_(this, rtinstance->deleter()) {
591 }
592 
593 template <typename T>
595  if (listener_id_ != DBTableBase::kInvalidId)
596  bgp_table()->Unregister(listener_id_);
597  listener_id_ = DBTableBase::kInvalidId;
598 }
599 
600 template <typename T>
602  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
603  const AggregateRouteConfigList &list =
604  routing_instance()->config()->aggregate_routes(GetFamily());
605  typedef AggregateRouteConfigList::const_iterator iterator_t;
606  for (iterator_t iter = list.begin(); iter != list.end(); ++iter) {
607  LocateAggregateRoutePrefix(*iter);
608  }
609 }
610 
612  const AggregateRouteConfig &rhs) {
615  return false;
616 }
617 
618 template <typename T>
620  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
621  AggregateRouteConfigList config_list =
622  routing_instance()->config()->aggregate_routes(GetFamily());
623  sort(config_list.begin(), config_list.end(), CompareAggregateRouteConfig);
624 
625  map_difference(&aggregate_route_map_,
626  config_list.begin(), config_list.end(),
627  boost::bind(&RouteAggregator<T>::CompareAggregateRoute, this, _1, _2),
628  boost::bind(&RouteAggregator<T>::AddAggregateRoute, this, _1),
629  boost::bind(&RouteAggregator<T>::DelAggregateRoute, this, _1),
630  boost::bind(&RouteAggregator<T>::UpdateAggregateRoute, this, _1, _2));
631 }
632 
633 template <typename T>
635  CHECK_CONCURRENCY("bgp::Config");
636  for (typename AggregateRouteMap::iterator it = aggregate_route_map_.begin();
637  it != aggregate_route_map_.end(); it++) {
638  RemoveAggregateRoutePrefix(it->first);
639  }
640 }
641 
642 template <>
644  return Address::INET;
645 }
646 
647 template <>
649  return Address::INET6;
650 }
651 
652 template <>
654  const {
655  assert(addr.is_v4());
656  return addr.to_v4();
657 }
658 
659 template <>
661  const {
662  assert(addr.is_v6());
663  return addr.to_v6();
664 }
665 
666 template <typename T>
668  return rtinstance_->GetTable(GetFamily());
669 }
670 
671 template <typename T>
673  // Register to the table before adding first match condition
674  listener_id_ = bgp_table()->Register(
675  boost::bind(&RouteAggregator::RouteListener, this, _1, _2),
676  "RouteAggregator");
677 }
678 
679 template <typename T>
681  if (!aggregate_route_map_.empty())
682  return false;
683  if (!update_aggregate_list_.empty())
684  return false;
685  if (!unregister_aggregate_list_.empty())
686  return false;
687  return true;
688 }
689 
690 // Cascade delete from RoutingInstance delete_ref to self.
691 template <typename T>
693  deleter_->Delete();
694 }
695 
696 // Attempt to enqueue a delete for the RouteAggregator.
697 template <typename T>
699  if (!deleter_->IsDeleted())
700  return;
701  deleter_->RetryDelete();
702 }
703 
704 template <typename T>
706  tbb::mutex::scoped_lock lock(mutex_);
707  update_aggregate_list_.insert(entry);
708  update_list_trigger_->Set();
709 }
710 
711 template <typename T>
713  AggregateRoutePtr entry) {
714  tbb::mutex::scoped_lock lock(mutex_);
715  unregister_aggregate_list_.insert(entry);
716  unregister_list_trigger_->Set();
717 }
718 
719 template <typename T>
721  RouteAggregatorState *state = static_cast<RouteAggregatorState *>
722  (route->GetState(bgp_table(), listener_id()));
723  if (state) {
724  return (state->aggregator());
725  }
726  return false;
727 }
728 
729 template <typename T>
731  RouteAggregatorState *state = static_cast<RouteAggregatorState *>
732  (route->GetState(bgp_table(), listener_id()));
733  if (state) {
734  return state->contributor();
735  }
736  return false;
737 }
738 
739 template <typename T>
740 bool RouteAggregator<T>::FillAggregateRouteInfo(AggregateRouteEntriesInfo *info,
741  bool summary) const {
742  if (aggregate_route_map().empty())
743  return false;
744 
745  info->set_name(rtinstance_->GetVirtualNetworkName());
746  info->set_instance_name(rtinstance_->name());
747  vector<AggregateRouteInfo> aggregate_route_list =
748  vector<AggregateRouteInfo>();
749  for (typename AggregateRouteMap::const_iterator it =
750  aggregate_route_map_.begin(); it != aggregate_route_map_.end(); it++) {
751  AggregateRouteT *aggregate =
752  static_cast<AggregateRouteT *>(it->second.get());
753  AggregateRouteInfo aggregate_info;
754  aggregate->FillShowInfo(&aggregate_info, summary);
755  aggregate_route_list.push_back(aggregate_info);
756  }
757  info->set_aggregate_route_list(aggregate_route_list);
758  return true;
759 }
760 
761 template <typename T>
763  typename AggregateRouteMap::iterator loc,
764  AggregateRouteConfigList::iterator it) {
765  AddressT address = this->GetAddress(it->aggregate);
766  PrefixT prefix(address, it->prefix_length);
767  KEY_COMPARE(loc->first, prefix);
768  return 0;
769 }
770 
771 template <typename T>
773  AggregateRouteConfigList::iterator it) {
774  LocateAggregateRoutePrefix(*it);
775 }
776 
777 template <typename T>
779  typename AggregateRouteMap::iterator loc) {
780  RemoveAggregateRoutePrefix(loc->first);
781 }
782 
783 template <typename T>
785  typename AggregateRouteMap::iterator loc,
786  AggregateRouteConfigList::iterator it) {
787  LocateAggregateRoutePrefix(*it);
788 }
789 
790 template <typename T>
792  &cfg) {
793  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
794  AddressT address = this->GetAddress(cfg.aggregate);
795  PrefixT prefix(address, cfg.prefix_length);
796 
797  // Verify whether the entry already exists
798  typename AggregateRouteMap::iterator it = aggregate_route_map_.find(prefix);
799  if (it != aggregate_route_map_.end()) {
800  // Wait for the delete complete cb
801  if (it->second->deleted()) return;
802 
803  AggregateRouteT *match =
804  static_cast<AggregateRouteT *>(it->second.get());
805  // Check whether the config has got updated
806  typename AggregateRouteT::CompareResult change =
807  match->CompareConfig(cfg);
808  // No change..
809  if (change == AggregateRouteT::NoChange) return;
810 
811  if (change == AggregateRouteT::NexthopChange)
812  match->UpdateNexthop(cfg.nexthop);
813  return;
814  }
815 
816  AggregateRouteT *match =
817  new AggregateRouteT(routing_instance(), this, prefix, cfg.nexthop);
818  AggregateRoutePtr aggregate_route_match = AggregateRoutePtr(match);
819  aggregate_route_map_.insert(make_pair(prefix, aggregate_route_match));
820 
821  condition_listener_->AddMatchCondition(match->bgp_table(),
822  aggregate_route_match.get(), BgpConditionListener::RequestDoneCb());
823  return;
824 }
825 
826 template <typename T>
828  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
829  typename AggregateRouteMap::iterator it =
830  aggregate_route_map_.find(aggregate);
831  if (it == aggregate_route_map_.end()) return;
832  if (it->second->deleted()) return;
833 
835  boost::bind(&RouteAggregator::StopAggregateRouteDone, this, _1, _2);
836 
837  AggregateRouteT *match = static_cast<AggregateRouteT *>(it->second.get());
838  condition_listener_->RemoveMatchCondition(match->bgp_table(),
839  match, callback);
840 }
841 
842 template <typename T>
844  ConditionMatch *info) {
845  CHECK_CONCURRENCY("db::Walker");
846  UnregisterAndResolveRouteAggregate(info);
847  return;
848 }
849 
850 template <typename T>
852  CHECK_CONCURRENCY("bgp::Config");
853 
854  for (AggregateRouteProcessList::iterator
855  it = unregister_aggregate_list_.begin();
856  it != unregister_aggregate_list_.end(); ++it) {
857  AggregateRouteT *aggregate = static_cast<AggregateRouteT *>(it->get());
858  aggregate_route_map_.erase(aggregate->aggregate_route_prefix());
859  condition_listener_->UnregisterMatchCondition(aggregate->bgp_table(),
860  aggregate);
861  }
862 
863  unregister_aggregate_list_.clear();
864 
865  if (!routing_instance()->deleted() && routing_instance()->config())
866  ProcessAggregateRouteConfig();
867 
868  if (MayDelete()) RetryDelete();
869  return true;
870 }
871 
872 template <typename T>
874  CHECK_CONCURRENCY("bgp::RouteAggregation");
875 
876  for (AggregateRouteProcessList::iterator
877  it = update_aggregate_list_.begin();
878  it != update_aggregate_list_.end(); ++it) {
879  AggregateRouteT *aggregate = static_cast<AggregateRouteT *>(it->get());
880  if (aggregate->aggregate_route()) {
881  if (!aggregate->HasContributingRoutes())
882  aggregate->RemoveAggregateRoute();
883  } else {
884  if (aggregate->HasContributingRoutes())
885  aggregate->AddAggregateRoute();
886  }
887  }
888 
889  update_aggregate_list_.clear();
890 
891  if (MayDelete()) RetryDelete();
892  return true;
893 }
894 
895 // Need this to store the aggregate info in aggregated route as DBState
896 template <typename T>
898  DBEntryBase *entry) {
899  return true;
900 }
901 
902 // Enable/Disable task triggers
903 template <typename T>
905  update_list_trigger_->set_disable();
906 }
907 
908 template <typename T>
910  update_list_trigger_->set_enable();
911 }
912 
913 template <typename T>
915  return update_aggregate_list_.size();
916 }
917 
918 template <typename T>
920  unregister_list_trigger_->set_disable();
921 }
922 
923 template <typename T>
925  unregister_list_trigger_->set_enable();
926 }
927 
928 template <typename T>
930  return unregister_aggregate_list_.size();
931 }
932 
933 // Explicit instantiation of RouteAggregator for INET and INET6.
virtual void ProcessAggregateRouteConfig()
ContributingRouteList contributors_
void RemoveAggregateRoutePrefix(const PrefixT &static_route)
AggregateRouteMgrT * manager_
const AggregateRouteMap & aggregate_route_map() const
virtual void EnableRouteAggregateUpdate()
AggregateRoute(RoutingInstance *rtinstance, AggregateRouteMgrT *manager, const PrefixT &aggregate_route, IpAddress nexthop)
boost::array< uint8_t, 8 > ExtCommunityValue
Definition: community.h:152
BgpRoute * aggregate_route_
bool IsOriginVnMatch(BgpRoute *route) const
BgpTable * GetTable(Address::Family fmly)
virtual bool IsAggregateRoute(const BgpRoute *route) const
virtual void FlushAggregateRouteConfig()
const BgpPath * BestPath() const
Definition: bgp_route.cc:46
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
BgpTable * bgp_table() const
boost::function< void(BgpTable *, ConditionMatch *)> RequestDoneCb
std::set< BgpRoute * > RouteList
bool MayDelete() const
DBEntry * Find(const DBEntry *entry)
void RemoveMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj)
Family
Definition: address.h:24
#define KEY_COMPARE(x, y)
Definition: util.h:70
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
bool IsMoreSpecific(BgpRoute *route) const
boost::asio::ip::address IpAddress
Definition: address.h:13
Address::Family GetFamily() const
T::AddressT AddressT
int CompareAggregateRoute(typename AggregateRouteMap::iterator loc, AggregateRouteConfigList::iterator it)
bool contributor() const
void DelAggregateRoute(typename AggregateRouteMap::iterator loc)
virtual bool MayDelete() const
bool Enqueue(DBRequest *req)
Definition: db_table.cc:194
virtual void DisableUnregResolveTask()
std::vector< BgpAttribute * > BgpAttrSpec
Definition: bgp_attr.h:822
void StopAggregateRouteDone(BgpTable *table, ConditionMatch *info)
const BgpPath * FindPath(BgpPath::PathSource src) const
Definition: bgp_route.cc:145
BgpConditionListener * condition_listener(Address::Family family)
Definition: bgp_server.h:114
BgpTable * bgp_table() const
DBTableBase::ListenerId listener_id() const
void Delete(DBEntryBase *)
Address::Family GetFamily() const
ContributingRouteList * contribute_route_list()
CompareResult CompareConfig(const AggregateRouteConfig &cfg)
BgpInstanceConfig::AggregateRouteList AggregateRouteConfigList
#define BGP_LOG_STR(obj, level, flags, arg)
Definition: bgp_log.h:89
AggregateRoutePtr aggregating_info()
PrefixT aggregate_route_prefix_
Definition: db.h:24
void set_contributing_info(AggregateRoutePtr aggregator)
AggregateRoutePtr contributing_info_
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:991
RouteAggregator(RoutingInstance *instance)
T::PrefixT PrefixT
AddressT GetAddress(IpAddress addr) const
bool AddContributingRoute(BgpRoute *route)
void EvaluateAggregateRoute(AggregateRoutePtr entry)
void map_difference(ForwardIterator __first1, ForwardIterator __last1, ForwardIterator __first2, ForwardIterator __last2, AddFunctor __add_fn, DelFunctor __del_fn, EqFunctor __eq_fn)
Definition: map_util.h:20
bool RouteListener(DBTablePartBase *root, DBEntryBase *entry)
RoutingInstance * routing_instance() const
#define BOOL_KEY_COMPARE(x, y)
Definition: util.h:64
const ExtCommunityList & communities() const
Definition: community.h:180
void UnregisterAndResolveRouteAggregate(AggregateRoutePtr entry)
void ClearRouteState(BgpRoute *route, RouteAggregatorState *state)
const ContributingRouteList & contribute_route_list() const
void UpdateAggregateRoute(typename AggregateRouteMap::iterator loc, AggregateRouteConfigList::iterator it)
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
DISALLOW_COPY_AND_ASSIGN(AggregateRoute)
virtual size_t GetUpdateAggregateListSize() const
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
const PrefixT & aggregate_route_prefix() const
virtual void Initialize()
DBOperation oper
Definition: db_table.h:42
virtual bool FillAggregateRouteInfo(AggregateRouteEntriesInfo *info, bool summary) const
#define CHECK_CONCURRENCY(...)
void SetMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj, ConditionMatchState *state=NULL)
virtual std::string ToString() const =0
bool CheckMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj)
bool aggregator() const
bool IsVrfOriginated() const
Definition: bgp_path.h:68
const std::string & name() const
Definition: db_table.h:110
void UpdateNexthop(IpAddress nexthop)
DeleteActor(RouteAggregator *aggregator)
void ClearDelete()
Definition: db_entry.h:48
RouteAggregatorState * LocateRouteState(BgpRoute *route)
RouteAggregator< T > AggregateRouteMgrT
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
void InsertPath(BgpPath *path)
Definition: bgp_route.cc:60
IpAddress nexthop() const
bool RemovePath(BgpPath::PathSource src, const IPeer *peer=NULL, uint32_t path_id=0)
Definition: bgp_route.cc:262
bool IsContributingRoute(BgpRoute *route) const
RoutingInstance * routing_instance_
bool IsContributingRoute(const BgpRoute *route) const
Definition: bgp_table.cc:1142
const ExtCommunity * ext_community() const
Definition: bgp_attr.h:915
bool RemoveContributingRoute(BgpRoute *route)
void set_aggregating_info(AggregateRoutePtr aggregator)
int vn_index() const
Definition: origin_vn.cc:122
DISALLOW_COPY_AND_ASSIGN(RouteAggregatorState)
#define BGP_LOG_FLAG_TRACE
Definition: bgp_log.h:43
void LocateAggregateRoutePrefix(const AggregateRouteConfig &cfg)
bool HasContributingRoutes() const
void NotifyContributingRoute(BgpRoute *route)
void AddAggregateRoute(AggregateRouteConfigList::iterator it)
AggregateRoutePtr contributing_info()
AddressT GetAddress(IpAddress addr) const
T::AddressT AddressT
bool HasPaths() const
Definition: bgp_route.h:27
const BgpAttr * GetAttr() const
Definition: bgp_path.h:87
ConditionMatchPtr AggregateRoutePtr
static const int kInvalidId
Definition: db_table.h:64
AggregateRoutePtr aggregating_info_
virtual bool Match(BgpServer *server, BgpTable *table, BgpRoute *route, bool deleted)
virtual void DisableRouteAggregateUpdate()
void set_aggregate_route(BgpRoute *aggregate)
virtual void Add(DBEntry *entry)
virtual bool IsContributingRoute(const BgpRoute *route) const
DBTablePartBase * get_table_partition() const
Definition: db_entry.cc:115
bool CompareAggregateRouteConfig(const AggregateRouteConfig &lhs, const AggregateRouteConfig &rhs)
std::vector< uint64_t > communities
Definition: community.h:143
void Notify(DBEntryBase *entry)
virtual void EnableUnregResolveTask()
virtual size_t GetUnregResolveListSize() const
const uint64_t GetExtCommunityValue() const
Definition: origin_vn.h:37
virtual string ToString() const
RoutingInstance * routing_instance()
BgpRoute * aggregate_route() const
std::vector< RouteList > ContributingRouteList
bool IsBestMatch(BgpRoute *route) const
int index() const
void FillShowInfo(AggregateRouteInfo *info, bool summary) const
virtual void UpdateAggregateRouteConfig()
static bool is_origin_vn(const ExtCommunityValue &val)
Definition: community.h:193
virtual ~AggregateRoute()