7 #include <boost/foreach.hpp>
13 #include "sandesh/sandesh_types.h"
14 #include "sandesh/sandesh.h"
15 #include "sandesh/sandesh_trace.h"
25 #include "bgp/routing-instance/route_aggregate_types.h"
137 const PrefixT &ip_prefix = ip_route->GetPrefix();
164 return (
string(
"AggregateRoute ") +
178 if (!per_part_contributor.empty()) {
195 const PrefixT &prefix = ip_route->GetPrefix();
196 req.
key.reset(
new typename TableT::RequestKey(prefix, NULL));
236 assert(num_deleted != 1);
241 void FillShowInfo(AggregateRouteInfo *info,
bool summary)
const;
254 template <
typename T>
258 : routing_instance_(rtinstance),
260 aggregate_route_prefix_(aggregate_route),
262 aggregate_route_(NULL),
267 template <
typename T>
272 assert(aggregate_route_prefix_ == prefix);
274 return NexthopChange;
279 template <
typename T>
296 vni = routing_instance()->virtual_network_index();
298 if (vni == routing_instance()->GetOriginVnForAggregateRoute(GetFamily()))
311 template <
typename T>
314 const PrefixT &ip_prefix = ip_route->GetPrefix();
316 std::set<PrefixT> prefix_list;
319 if (!it->second->deleted() && ip_prefix != it->first &&
320 ip_prefix.IsMoreSpecific(it->first)) {
321 prefix_list.insert(it->first);
325 assert(prefix_list.size());
331 if (*(prefix_list.rbegin()) == aggregate_route_prefix_)
return true;
337 template <
typename T>
348 if ((!deleted && !IsOriginVnMatch(route)) || !IsMoreSpecific(route))
358 if (IsContributingRoute(route)) {
359 if (!IsBestMatch(route)) deleted =
true;
375 if (!deleted && !IsBestMatch(route))
return false;
379 bool trigger_eval =
false;
383 trigger_eval = AddContributingRoute(route);
390 trigger_eval = RemoveContributingRoute(route);
394 if (trigger_eval) manager_->EvaluateAggregateRoute(
this);
399 template <
typename T>
403 RouteT rt_key(aggregate_route_prefix());
409 if (aggregate_route == NULL) {
410 aggregate_route =
new RouteT(aggregate_route_prefix());
411 partition->
Add(aggregate_route);
417 assert(existing_path == NULL);
421 attrs.push_back(&attr_nexthop);
423 OriginVn origin_vn(routing_instance()->server()->autonomous_system(),
424 routing_instance()->GetOriginVnForAggregateRoute(GetFamily()));
426 attrs.push_back(&extcomm_spec);
427 BgpAttrPtr attr = routing_instance()->server()->attr_db()->Locate(attrs);
430 bgp_table()->path_resolver()->StartPathResolution(aggregate_route,
433 partition->
Notify(aggregate_route);
434 set_aggregate_route(aggregate_route);
437 "Added aggregate path " << aggregate_route_->ToString() <<
438 " in table " << partition->
table()->
name());
442 template <
typename T>
446 if (aggregate_route_ == NULL)
return;
449 (bgp_table()->GetTablePartition(aggregate_route_));
451 aggregate_route_->ClearDelete();
455 bgp_table()->path_resolver()->StopPathResolution(partition->
index(),
461 attrs.push_back(&attr_nexthop);
463 OriginVn origin_vn(routing_instance()->server()->autonomous_system(),
464 routing_instance()->GetOriginVnForAggregateRoute(GetFamily()));
466 attrs.push_back(&extcomm_spec);
467 BgpAttrPtr attr = routing_instance()->server()->attr_db()->Locate(attrs);
470 bgp_table()->path_resolver()->StartPathResolution(aggregate_route_,
472 aggregate_route_->InsertPath(new_path);
474 partition->
Notify(aggregate_route_);
477 "Updated aggregate path " << aggregate_route_->ToString() <<
478 " in table " << partition->
table()->
name());
482 template <
typename T>
485 BgpRoute *aggregate_route = aggregate_route_;
486 if (!aggregate_route)
return;
489 (bgp_table()->GetTablePartition(aggregate_route_));
493 assert(existing_path != NULL);
495 bgp_table()->path_resolver()->StopPathResolution(partition->
index(),
500 "Removed aggregate path " << aggregate_route_->ToString() <<
501 " in table " << partition->
table()->
name());
504 partition->
Delete(aggregate_route);
506 partition->
Notify(aggregate_route);
508 set_aggregate_route(NULL);
511 template <
typename T>
514 assert(aggregate_route_ == NULL);
518 assert(aggregate_route_ != NULL);
520 (aggregate_route_->GetState(bgp_table(), manager_->listener_id()));
523 ClearRouteState(aggregate_route_, state);
525 aggregate_route_ = aggregate;
528 template <
typename T>
530 bool summary)
const {
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);
540 info->set_nexthop(nexthop_.to_string());
545 std::vector<string> contributor_list;
546 BOOST_FOREACH(
const RouteList &list, contribute_route_list()) {
548 contributor_list.push_back(rt->
ToString());
551 info->set_contributors(contributor_list);
554 template <
typename T>
559 aggregator_(aggregator) {
565 return aggregator_->MayDelete();
569 aggregator_->routing_instance()->DestroyRouteAggregator(
570 aggregator_->GetFamily());
577 template <
typename T>
579 : rtinstance_(rtinstance),
580 condition_listener_(rtinstance_->server()->condition_listener(GetFamily())),
584 TaskScheduler::GetInstance()->GetTaskId(
"bgp::RouteAggregation"),
590 instance_delete_ref_(this, rtinstance->
deleter()) {
593 template <
typename T>
596 bgp_table()->Unregister(listener_id_);
600 template <
typename T>
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);
618 template <
typename T>
622 routing_instance()->config()->aggregate_routes(GetFamily());
626 config_list.begin(), config_list.end(),
633 template <
typename T>
636 for (
typename AggregateRouteMap::iterator it = aggregate_route_map_.begin();
637 it != aggregate_route_map_.end(); it++) {
638 RemoveAggregateRoutePrefix(it->first);
655 assert(addr.is_v4());
662 assert(addr.is_v6());
666 template <
typename T>
668 return rtinstance_->GetTable(GetFamily());
671 template <
typename T>
674 listener_id_ = bgp_table()->Register(
679 template <
typename T>
681 if (!aggregate_route_map_.empty())
683 if (!update_aggregate_list_.empty())
685 if (!unregister_aggregate_list_.empty())
691 template <
typename T>
697 template <
typename T>
699 if (!deleter_->IsDeleted())
701 deleter_->RetryDelete();
704 template <
typename T>
706 tbb::mutex::scoped_lock lock(mutex_);
707 update_aggregate_list_.insert(entry);
708 update_list_trigger_->Set();
711 template <
typename T>
714 tbb::mutex::scoped_lock lock(mutex_);
715 unregister_aggregate_list_.insert(entry);
716 unregister_list_trigger_->Set();
719 template <
typename T>
722 (route->
GetState(bgp_table(), listener_id()));
729 template <
typename T>
732 (route->
GetState(bgp_table(), listener_id()));
739 template <
typename T>
741 bool summary)
const {
742 if (aggregate_route_map().empty())
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++) {
753 AggregateRouteInfo aggregate_info;
755 aggregate_route_list.push_back(aggregate_info);
757 info->set_aggregate_route_list(aggregate_route_list);
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);
771 template <
typename T>
773 AggregateRouteConfigList::iterator it) {
774 LocateAggregateRoutePrefix(*it);
777 template <
typename T>
779 typename AggregateRouteMap::iterator loc) {
780 RemoveAggregateRoutePrefix(loc->first);
783 template <
typename T>
785 typename AggregateRouteMap::iterator loc,
786 AggregateRouteConfigList::iterator it) {
787 LocateAggregateRoutePrefix(*it);
790 template <
typename T>
798 typename AggregateRouteMap::iterator it = aggregate_route_map_.find(prefix);
799 if (it != aggregate_route_map_.end()) {
801 if (it->second->deleted())
return;
809 if (change == AggregateRouteT::NoChange)
return;
811 if (change == AggregateRouteT::NexthopChange)
819 aggregate_route_map_.insert(make_pair(prefix, aggregate_route_match));
821 condition_listener_->AddMatchCondition(match->
bgp_table(),
826 template <
typename T>
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;
838 condition_listener_->RemoveMatchCondition(match->
bgp_table(),
842 template <
typename T>
846 UnregisterAndResolveRouteAggregate(info);
850 template <
typename T>
854 for (AggregateRouteProcessList::iterator
855 it = unregister_aggregate_list_.begin();
856 it != unregister_aggregate_list_.end(); ++it) {
859 condition_listener_->UnregisterMatchCondition(aggregate->
bgp_table(),
863 unregister_aggregate_list_.clear();
865 if (!routing_instance()->deleted() && routing_instance()->config())
866 ProcessAggregateRouteConfig();
868 if (MayDelete()) RetryDelete();
872 template <
typename T>
876 for (AggregateRouteProcessList::iterator
877 it = update_aggregate_list_.begin();
878 it != update_aggregate_list_.end(); ++it) {
889 update_aggregate_list_.clear();
891 if (MayDelete()) RetryDelete();
896 template <
typename T>
903 template <
typename T>
905 update_list_trigger_->set_disable();
908 template <
typename T>
910 update_list_trigger_->set_enable();
913 template <
typename T>
915 return update_aggregate_list_.size();
918 template <
typename T>
920 unregister_list_trigger_->set_disable();
923 template <
typename T>
925 unregister_list_trigger_->set_enable();
928 template <
typename T>
930 return unregister_aggregate_list_.size();
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)
void RemoveAggregateRoute()
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
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
BgpTable * bgp_table() const
boost::function< void(BgpTable *, ConditionMatch *)> RequestDoneCb
std::set< BgpRoute * > RouteList
DBEntry * Find(const DBEntry *entry)
void RemoveMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj)
#define KEY_COMPARE(x, y)
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
bool IsMoreSpecific(BgpRoute *route) const
boost::asio::ip::address IpAddress
Address::Family GetFamily() const
int CompareAggregateRoute(typename AggregateRouteMap::iterator loc, AggregateRouteConfigList::iterator it)
void DelAggregateRoute(typename AggregateRouteMap::iterator loc)
virtual bool MayDelete() const
bool Enqueue(DBRequest *req)
virtual void DisableUnregResolveTask()
std::vector< BgpAttribute * > BgpAttrSpec
void StopAggregateRouteDone(BgpTable *table, ConditionMatch *info)
const BgpPath * FindPath(BgpPath::PathSource src) const
void UpdateAggregateRoute()
BgpConditionListener * condition_listener(Address::Family family)
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)
AggregateRoutePtr aggregating_info()
PrefixT aggregate_route_prefix_
void set_contributing_info(AggregateRoutePtr aggregator)
AggregateRoutePtr contributing_info_
bool ProcessUnregisterList()
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
RouteAggregator(RoutingInstance *instance)
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)
bool RouteListener(DBTablePartBase *root, DBEntryBase *entry)
RoutingInstance * routing_instance() const
#define BOOL_KEY_COMPARE(x, y)
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
DISALLOW_COPY_AND_ASSIGN(AggregateRoute)
virtual size_t GetUpdateAggregateListSize() const
std::unique_ptr< DBRequestKey > key
const PrefixT & aggregate_route_prefix() const
virtual void Initialize()
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 IsVrfOriginated() const
const std::string & name() const
void UpdateNexthop(IpAddress nexthop)
void reset_aggregating_info()
DeleteActor(RouteAggregator *aggregator)
RouteAggregatorState * LocateRouteState(BgpRoute *route)
RouteAggregator< T > AggregateRouteMgrT
void ClearState(DBTableBase *tbl_base, ListenerId listener)
boost::asio::ip::address_v4 Ip4Address
void InsertPath(BgpPath *path)
IpAddress nexthop() const
RouteAggregator * aggregator_
bool RemovePath(BgpPath::PathSource src, const IPeer *peer=NULL, uint32_t path_id=0)
bool IsContributingRoute(BgpRoute *route) const
RoutingInstance * routing_instance_
bool IsContributingRoute(const BgpRoute *route) const
const ExtCommunity * ext_community() const
bool RemoveContributingRoute(BgpRoute *route)
void set_aggregating_info(AggregateRoutePtr aggregator)
DISALLOW_COPY_AND_ASSIGN(RouteAggregatorState)
#define BGP_LOG_FLAG_TRACE
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
const BgpAttr * GetAttr() const
ConditionMatchPtr AggregateRoutePtr
static const int kInvalidId
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
bool CompareAggregateRouteConfig(const AggregateRouteConfig &lhs, const AggregateRouteConfig &rhs)
void Notify(DBEntryBase *entry)
virtual void EnableUnregResolveTask()
virtual size_t GetUnregResolveListSize() const
const uint64_t GetExtCommunityValue() const
virtual string ToString() const
void reset_contributing_info()
RoutingInstance * routing_instance()
BgpRoute * aggregate_route() const
std::vector< RouteList > ContributingRouteList
bool IsBestMatch(BgpRoute *route) const
void FillShowInfo(AggregateRouteInfo *info, bool summary) const
virtual void UpdateAggregateRouteConfig()
virtual ~AggregateRoute()