7 #include <boost/foreach.hpp>
16 #include "bgp/bgp_peer_types.h"
24 #include "bgp/routing-instance/routing_instance_analytics_types.h"
35 sg_(sg), global_ermvpn_tree_rt_(NULL), states_(states),
81 : partition_(partition),
86 edge_replication_not_supported_(false),
87 assisted_replication_supported_(false),
88 assisted_replication_leaf_(false) {
94 : partition_(partition),
99 edge_replication_not_supported_(false),
100 assisted_replication_supported_(false),
101 assisted_replication_leaf_(false) {
118 bool changed =
false;
137 edge_replication_not_supported =
true;
152 assisted_replication_supported =
true;
160 assisted_replication_leaf =
true;
186 inclusive_mcast_route_(NULL) {
195 inclusive_mcast_route_(NULL) {
237 tbl_partition->
Add(route);
245 ReplaceMFlagsAndLocate(
attr_->ext_community(), mcastFlags);
247 attr_.get(), ext_community);
256 route,
"Insert new Local path");
329 if (pbb_evpn_enable && remote_ethernet_tag &&
330 (local_ethernet_tag != remote_ethernet_tag))
336 olist_spec.elements.push_back(elem);
352 leaf_olist_spec.
elements.push_back(elem);
358 if (olist_spec.elements.empty() && leaf_olist_spec.
elements.empty())
401 : evpn_manager_(manager),
404 single_active_(true),
405 route_lists_(
DB::PartitionCount()) {
420 pair<RouteList::iterator, bool> ret =
route_lists_[part_id].insert(route);
444 for (
size_t part_id = 0; part_id <
route_lists_.size(); ++part_id) {
462 for (RemotePeList::iterator it =
pe_list_.begin();
464 it->esi_valid =
false;
470 bool changed =
false;
471 for (Route::PathList::const_iterator path_it =
475 static_cast<const BgpPath *
>(path_it.operator->());
486 for (RemotePeList::iterator it =
pe_list_.begin();
489 if (it->attr->nexthop() != remote_pe.
attr->nexthop())
500 if (*it == remote_pe) {
501 it->esi_valid =
true;
515 for (RemotePeList::iterator it =
pe_list_.begin(), next = it;
518 if (!it->esi_valid) {
526 for (RemotePeList::iterator it =
pe_list_.begin();
528 if (it->single_active) {
548 for (
size_t part_id = 0; part_id <
route_lists_.size(); ++part_id) {
561 single_active(path->GetAttr()->evpn_single_active()),
562 peer(path->GetPeer()),
563 attr(path->GetAttr()),
564 flags(path->GetFlags()),
565 src(path->GetSource()) {
574 if (peer != rhs.
peer)
576 if (attr != rhs.
attr)
578 if (flags != rhs.
flags)
589 :
evpn_manager_(evpn_manager), route_(route), segment_(NULL) {
611 " peer " << (peer ? peer->
ToString() :
"None") <<
626 " peer " << (peer ? peer->
ToString() :
"None") <<
654 return (
new BgpPath(peer, src, attr, flags, label));
668 bool found_primary_pe =
false;
676 found_primary_pe =
true;
685 for (; found_primary_pe && path &&
segment_ &&
695 future_aliased_path_list.insert(aliased_path);
701 &future_aliased_path_list,
712 : evpn_manager_(evpn_manager),
763 bool exclude_edge_replication_supported) {
768 if (exclude_edge_replication_supported &&
811 if (list->count(sg)) {
812 deleted = (*list)[sg].erase(node);
813 if ((*list)[sg].size() == 0)
816 return (deleted > 0);
939 rt, &label, address, &te);
943 EvpnState::StatesMap::const_iterator iter =
states_.find(sg);
944 return iter !=
states_.end() ? iter->second : NULL;
948 EvpnState::StatesMap::iterator iter =
states_.find(sg);
949 return iter !=
states_.end() ? iter->second : NULL;
960 assert(
states_.insert(make_pair(sg, state.get())).second);
1033 listener_id_(
DBTable::kInvalidId),
1035 boost::bind(&
EvpnManager::ProcessSegmentDeleteSet, this),
1036 TaskScheduler::GetInstance()->GetTaskId(
"bgp::EvpnSegment"), 0)),
1038 boost::bind(&
EvpnManager::ProcessSegmentUpdateSet, this),
1039 TaskScheduler::GetInstance()->GetTaskId(
"bgp::EvpnSegment"), 0)),
1040 table_delete_ref_(this, table->
deleter()) {
1108 partitions_[part_id]->DisableMacUpdateProcessing();
1118 partitions_[part_id]->EnableMacUpdateProcessing();
1179 return (loc !=
segment_map_.end()) ? loc->second : NULL;
1267 if (!esi_ad_route->
IsValid()) {
1370 }
else if (segment && segment->
esi() != path->
GetAttr()->
esi()) {
1429 bool is_usable = route->
IsUsable();
1431 bool checkErmvpnRoute =
false;
1436 if ((!is_usable && !checkErmvpnRoute) || is_deleted) {
1442 evpn_state->smet_routes().erase(route);
1443 EVPN_RT_LOG(route,
"Processed Smet route deletion");
1453 evpn_state->smet_routes().insert(route);
1456 ErmVpnRoute *global_rt = evpn_state->global_ermvpn_tree_rt();
1462 ReplaceNexthopAndLocate(attr.get(), address);
1463 path->
SetAttr(new_attr, attr);
1480 EVPN_RT_LOG(route,
"Processed Smet route creation");
1513 if (!ermvpn_route || !ermvpn_route->
IsUsable())
1521 GetGlobalTreeRootRoute(
1524 return (global_rt && global_rt == ermvpn_route);
1535 assert(ermvpn_route);
1551 evpn_state->set_global_ermvpn_tree_rt(NULL);
1556 BOOST_FOREACH(
EvpnRoute *route, evpn_state->smet_routes()) {
1565 "Processed EVPN GlobalErmVpnRoute deletion");
1579 evpn_state = dbstate->
state();
1583 dbstate->
state()->set_global_ermvpn_tree_rt(ermvpn_route);
1586 BOOST_FOREACH(
EvpnRoute *route, evpn_state->smet_routes()) {
1590 "Processed EVPN GlobalErmVpnRoute creation");
1603 switch (route->GetPrefix().type()) {
1608 if (route->GetPrefix().mac_addr().IsBroadcast()) {
1632 vector<string> regular_nves;
1633 vector<string> ar_replicators;
1634 vector<ShowEvpnMcastLeaf> ar_leafs;
1635 EvpnManagerPartition::EvpnMcastNodeList::const_iterator it =
1636 partitions_[0]->remote_mcast_node_list()->begin();
1637 for (; it !=
partitions_[0]->remote_mcast_node_list()->end(); it++) {
1640 ShowEvpnMcastLeaf leaf;
1641 leaf.set_address(node->
address().to_string());
1643 ar_leafs.push_back(leaf);
1645 ar_replicators.push_back(node->
address().to_string());
1647 regular_nves.push_back(node->
address().to_string());
1652 sort(regular_nves.begin(), regular_nves.end());
1653 sort(ar_replicators.begin(), ar_replicators.end());
1654 sort(ar_leafs.begin(), ar_leafs.end());
1655 sevt->set_regular_nves(regular_nves);
1656 sevt->set_ar_replicators(ar_replicators);
1657 sevt->set_ar_leafs(ar_leafs);
1681 if (!partition->
empty())
1683 if (!partition->
states().empty())
1727 source(route->GetPrefix().source()),
1728 group(route->GetPrefix().group()) {
1732 source(route->GetPrefix().source()), group(route->GetPrefix().group()) {
1736 source(source), group(group) {
1740 if (source < other.
source)
1742 if (source > other.
source)
1744 if (group < other.
group)
1746 if (group > other.
group)
tbb::spin_rw_mutex segment_rw_mutex_
bool operator==(const RemotePe &rhs) const
Equality operator for EvpnSegment::RemotePe. Do not compare esi_valid and single_active fields since ...
BgpAttrPtr ReplaceLeafOListAndLocate(const BgpAttr *attr, const BgpOListSpec *leaf_olist_spec)
LifetimeActor * deleter()
Return the LifetimeActor for the EvpnManager.
bool ProcessSegmentUpdateSet()
Process the set of EvpnSegments that need to be updated.
const Ip4Address identifier() const
const EvpnState::StatesMap & states() const
EvpnMcastNode(EvpnManagerPartition *partition, EvpnRoute *route, uint8_t type)
Constructor for EvpnMcastNode. The type indicates whether this is a local or remote EvpnMcastNode...
const EvpnMcastNodeList & remote_mcast_node_list() const
tbb::atomic< int > db_states_count_
void Shutdown()
Initiate shutdown for the EvpnManager.
const IpAddress & nexthop() const
void STLDeleteValues(Container *container)
boost::intrusive_ptr< EvpnState > EvpnStatePtr
BgpTable * GetTable(Address::Family fmly)
bool UpdatePeList()
Update the PE list for this EvpnSegment. This should be called when the AutoDisocvery route is update...
const BgpPath * BestPath() const
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
const ErmVpnPrefix & GetPrefix() const
This class represents the EvpnManager state associated with a MAC route.
ErmVpnRoute * global_ermvpn_tree_rt_
Ip4Address replicator_address() const
void ErmVpnRouteListener(DBTablePartBase *tpart, DBEntryBase *db_entry)
ErmVpnTable route listener callback function.
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
bool ProcessMacRouteAliasing()
Update aliased BgpPaths for the EvpnRoute based on the remote PEs for the EvpnSegment. Return true if the list of aliased paths is modified.
BgpServer * server()
Return the BgpServer for the EvpnManagerPartition.
void TriggerMacRouteUpdate()
Trigger an update of all dependent MAC routes for this EvpnSegment. Note that the bgp::EvpnSegment ta...
bool empty() const
Return true if the EvpnManagerPartition is empty i.e. it has no local or remote EvpnMcastNodes and no...
std::map< SG, EvpnState * > StatesMap
bool set_synchronize(const SetType *set1, const SetType *set2, AddFunctor add_fn, DelFunctor del_fn)
boost::scoped_ptr< DeleteActor > deleter_
SegmentSet segment_delete_set_
EvpnManager(EvpnTable *table)
void AddInclusiveMulticastRoute()
Add Inclusive Multicast route for this EvpnLocalMcastNode. The attributes are based on the Broadcast ...
DBEntry * Find(const DBEntry *entry)
bool ProcessSegmentDeleteSet()
Process the set of EvpnSegments that can potentially be deleted. Remove the EvpnSegment from the map ...
EvpnMcastNodeList leaf_node_list_
void set_segment(EvpnSegment *segment)
void AutoDiscoveryRouteListener(EvpnRoute *route)
DBListener callback handler for AutoDisocvery routes in the EvpnTable.
bool RemoveMcastNodeFromList(EvpnState::SG &sg, EvpnMcastNode *node, EvpnMcastNodeList *list)
Delete an EvpnMcastNode from the EvpnManagerPartition.
EvpnManagerPartition * GetPartition(size_t part_id)
Get the EvpnManagerPartition for the given partition id.
EvpnMcastNodeList local_mcast_node_list_
tbb::atomic< int > refcount_
bool MayDelete() const
Return true if it's safe to delete this EvpnSegment.
RoutingInstance * routing_instance()
This class represents (in the context of an EVPN instance) a local vRouter that's connected to a cont...
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
void NotifyForestNode(int part_id, const Ip4Address &source, const Ip4Address &group)
boost::asio::ip::address IpAddress
EvpnManager * evpn_manager_
const_iterator end() const
DBTablePartition * table_partition_
#define BGP_LOG_ROUTE(table, peer, route, arg)
const uint32_t GetPathId() const
void DisableMacUpdateProcessing()
Disable processing of the update lists in all partitions. For testing only.
bool assisted_replication_leaf_
RemotePeList::const_iterator const_iterator
bool assisted_replication_supported_
void EnableMacUpdateProcessing()
Enable processing of the update lists in all partitions. For testing only.
void FreePartitions()
Free the EvpnManagerPartitions.
#define EVPN_TRACE(type,...)
void SetDBState(EvpnRoute *route, EvpnMcastNode *dbstate)
Set DB State and update count.
EvpnMacState(EvpnManager *evpn_manager, EvpnRoute *route)
const BgpPath * FindPath(BgpPath::PathSource src) const
void NotifyReplicatorNodeRoutes()
Go through all replicator EvpnMcastNodes and notify associated Broadcast MAC route.
void ManagedDelete()
Trigger deletion of the EvpnManager and propagate the delete to any dependents.
const ErmVpnTable * table() const
void AddAliasedPath(AliasedPathList::const_iterator it)
Add the BgpPath specified by the iterator to the aliased path list. Also inserts the BgpPath to the B...
void set_global_ermvpn_tree_rt(ErmVpnRoute *global_ermvpn_tree_rt)
void AddMacRoute(size_t part_id, EvpnRoute *route)
Add the given MAC route as a dependent of this EvpnSegment.
bool edge_replication_not_supported() const
void clear_esi_ad_route()
void Delete(DBEntryBase *)
void AllocPartitions()
Allocate the EvpnManagerPartitions.
SG(const Ip4Address &source, const Ip4Address &group)
uint32_t GetFlags() const
int ermvpn_listener_id() const
EvpnManager * evpn_manager_
void Unregister(ListenerId listener)
void NotifyIrClientNodeRoutes(bool exclude_edge_replication_supported)
Go through all ingress replication client EvpnMcastNodes and notify the associated Broadcast MAC rout...
const_iterator end() const
const EvpnTable * table() const
Return the EvpnTable for the EvpnManagerPartition.
BgpAttrPtr ReplaceExtCommunityAndLocate(const BgpAttr *attr, ExtCommunityPtr extcomm)
const McastTreeManager * tree_manager() const
This class represents (in the context of an EVPN instance) a remote vRouter or PE discovered via BGP...
#define BGP_LOG_STR(obj, level, flags, arg)
virtual void TriggerUpdate()
Handle update of EvpnRemoteMcastNode.
EvpnSegment * FindSegment(const EthernetSegmentId &esi)
Find the EvpnSegment for the given EthernetSegmentId.
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
EvpnMcastNodeList remote_mcast_node_list_
void SelectiveMulticastRouteListener(EvpnManagerPartition *partition, EvpnRoute *route)
DBListener callback handler for SelectiveMulticast routes in the EvpnTable.
DBTablePartition * GetTablePartition()
Get the DBTablePartition for the EvpnTable for our partition id.
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
virtual void Initialize()
Initialize the EvpnManager. We allocate the EvpnManagerPartitions and register a DBListener for the E...
RemotePe(const BgpPath *path)
const uint8_t tunnel_flags() const
void DeleteMacRoute(size_t part_id, EvpnRoute *route)
Delete the given MAC route as a dependent of this EvpnSegment. Trigger deletion of the EvpnSegment if...
EvpnState::StatesMap states_
void ClearDBState(EvpnRoute *route)
Create DB State and update count. If there is no DB State associated in the table, resume table deletion if the deletion was pending.
bool UpdateAttributes(EvpnRoute *route)
Update the label and attributes for a EvpnMcastNode. Return true if either of them changed...
boost::scoped_ptr< TaskTrigger > segment_update_trigger_
const EthernetSegmentId & esi() const
void RouteListener(DBTablePartBase *tpart, DBEntryBase *db_entry)
DBListener callback handler for the EvpnTable.
ExtCommunityDB * extcomm_db()
void EnableSegmentDeleteProcessing()
Enable processing of the delete list. For testing only.
virtual void TriggerUpdate()
Handle update of EvpnLocalMcastNode.
virtual void TriggerUpdate()=0
Handle update of EvpnLocalMcastNode.
void TriggerSegmentUpdate(EvpnSegment *segment)
Trigger update of the given EvpnSegment. The EvpnSegment is added to a set of EvpnSegments for which ...
const EthernetSegmentId & esi() const
std::map< SG, std::set< EvpnMcastNode * > > EvpnMcastNodeList
This class represents the EVPN manager for an EvpnTable in a VRF.
This class represents a remote EVPN segment that has 2 or more PEs that are multi-homed to it...
DeleteActor(EvpnManager *evpn_manager)
void InclusiveMulticastRouteListener(EvpnManagerPartition *partition, EvpnRoute *route)
DBListener callback handler for InclusiveMulticast routes in the EvpnTable.
void DeleteAliasedPath(AliasedPathList::const_iterator it)
Delete the BgpPath specified by the iterator from the aliased path list. Also deletes the BgpPath fro...
virtual const std::string & ToString() const =0
void TriggerMacRouteUpdate(EvpnRoute *route)
Add the given MAC route to the update list. This method gets called either when the MAC route itself ...
void EnableMacUpdateProcessing()
Enable processing of the update list. For testing only.
#define CHECK_CONCURRENCY(...)
virtual ~EvpnRemoteMcastNode()
virtual bool MayDelete() const
SegmentSet segment_update_set_
PartitionList partitions_
EvpnManager * evpn_manager_
EvpnSegment * LocateSegment(const EthernetSegmentId &esi)
Find or create the EvpnSegment for the given EthernetSegmentId.
uint16_t GetVrfId() const
#define EVPN_RT_LOG(rt,...)
EvpnMcastNodeList replicator_node_list_
Ip4Address replicator_address_
const std::string & name() const
virtual void Terminate()
Terminate the EvpnManager. We free the EvpnManagerPartitions and unregister from the EvpnTable...
EvpnManager * evpn_manager_
void AddMcastNode(EvpnMcastNode *node, EvpnRoute *route)
Add an EvpnMcastNode to the EvpnManagerPartition.
uint32_t GetLabel() const
BgpPath * LocateAliasedPath(const EvpnSegment::RemotePe *remote_pe, uint32_t label)
Find or create the matching aliased BgpPath.
Ip4Address source() const
const EvpnMcastNodeList & leaf_node_list() const
void TriggerSegmentDelete(EvpnSegment *segment)
Trigger deletion of the given EvpnSegment. The EvpnSegment is added to a set of EvpnSegments that can...
void ClearState(DBTableBase *tbl_base, ListenerId listener)
const_iterator begin() const
void FillShowInfo(ShowEvpnTable *sevt) const
Fill information for introspect command. Note that all IM routes are always in partition 0...
const_iterator begin() const
boost::asio::ip::address_v4 Ip4Address
Simple structure to hold <S,G>. Source as "0.0.0.0" can be used to encode <*,G> as well...
EvpnLocalMcastNode(EvpnManagerPartition *partition, EvpnRoute *route)
Constructor for EvpnLocalMcastNode.
void InsertPath(BgpPath *path)
bool single_active() const
AliasedPathList aliased_path_list_
virtual UpdateInfo * GetUpdateInfo(EvpnRoute *route)
Construct export state for the given EvpnRoute. Note that the route only needs to be exported to the ...
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
bool RemovePath(BgpPath::PathSource src, const IPeer *peer=NULL, uint32_t path_id=0)
const EvpnPrefix & GetPrefix() const
virtual ~EvpnLocalMcastNode()
bool virtual_network_pbb_evpn_enable() const
void MacAdvertisementRouteListener(EvpnManagerPartition *partition, EvpnRoute *route)
DBListener callback handler for MacAdvertisement routes in the EvpnTable.
bool GetForestNodeAddress(ErmVpnRoute *rt, Ip4Address *address) const
uint32_t bgp_identifier() const
EvpnRoute * esi_ad_route()
const ExtCommunity * ext_community() const
EvpnStatePtr LocateState(EvpnRoute *route)
void DestroyEvpnManager()
This class holds Evpn state for a particular <S,G> at any given time.
EvpnStatePtr GetState(const SG &sg)
uint32_t GetAddress() const
EvpnManagerPartition * partition_
#define BGP_LOG_FLAG_TRACE
const EthernetSegmentId & esi() const
void UpdateMcastNode(EvpnMcastNode *node, EvpnRoute *route)
Update an EvpnMcastNode in the EvpnManagerPartition. Need to remove/add EvpnMcastNode from the replic...
BgpAttrPtr ReplaceOListAndLocate(const BgpAttr *attr, const BgpOListSpec *olist_spec)
DBTablePartition * GetTablePartition(size_t part_id)
Get the DBTablePartition for the EvpnTable for given partition id.
RouteListVector route_lists_
const BgpAttr * GetAttr() const
ErmVpnTable * ermvpn_table_
bool ProcessMacUpdateList()
Process the MAC route update list for this EvpnManagerPartition.
EvpnRoute * inclusive_mcast_route_
EvpnMcastNodeList regular_node_list_
#define EVPN_ERMVPN_RT_LOG(rt,...)
static const int kInvalidId
This class represents a partition in the EvpnManager.
void EnableSegmentUpdateProcessing()
Enable processing of the update list. For testing only.
IpAddress ip_address() const
void DeletePath(BgpPath *path)
bool assisted_replication_supported() const
boost::scoped_ptr< TaskTrigger > segment_delete_trigger_
UpdateInfo * GetUpdateInfo(EvpnRoute *route)
void NotifyNodeRoute(EvpnMcastNode *node)
Notify the Broadcast MAC route for the given EvpnMcastNode.
void DisableSegmentDeleteProcessing()
Disable processing of the delete list. For testing only.
static int PartitionCount()
EvpnRemoteMcastNode(EvpnManagerPartition *partition, EvpnRoute *route)
EvpnStatePtr CreateState(const SG &sg)
virtual void Add(DBEntry *entry)
EvpnManagerPartition(EvpnManager *evpn_manager, size_t part_id)
EvpnSegment(EvpnManager *evpn_manager, const EthernetSegmentId &esi)
void DisableMacUpdateProcessing()
Disable processing of the update list. For testing only.
boost::scoped_ptr< TaskTrigger > mac_update_trigger_
void DeleteMcastNode(EvpnMcastNode *node, EvpnRoute *route)
Delete an EvpnMcastNode from the EvpnManagerPartition.
void set_esi_ad_route(EvpnRoute *esi_ad_route)
Ip4Address address() const
void Notify(DBEntryBase *entry)
const RouteDistinguisher & route_distinguisher() const
const BgpAttr * attr() const
bool operator<(const SG &other) const
EvpnState(const SG &sg, StatesMap *states, EvpnManager *manager)
A global MVPN state for a given <S.G> within a EvpnProjectManager.
ErmVpnTable * ermvpn_table()
ErmVpnRoute * global_ermvpn_tree_rt()
std::set< BgpPath * > AliasedPathList
EvpnRouteList mac_update_list_
bool MayDelete() const
Trigger deletion of the EvpnManager and propagate the delete to any dependents.
bool assisted_replication_leaf() const
virtual bool GetForestNodePMSI(ErmVpnRoute *rt, uint32_t *label, Ip4Address *address, std::vector< std::string > *encap) const
This is the base class for a multicast node in an EVPN instance. The node could either represent a lo...
void set_state(EvpnStatePtr state)
void NotifyForestNode(EvpnRoute *route, ErmVpnTable *table)
void SetAttr(const BgpAttrPtr attr, const BgpAttrPtr original_attr)
EvpnMcastNodeList ir_client_node_list_
bool edge_replication_not_supported_
void DisableSegmentUpdateProcessing()
Disable processing of the update list. For testing only.
bool IsUsableGlobalTreeRootRoute(ErmVpnRoute *ermvpn_route) const
Check whether an ErmVpnRoute is locally originated GlobalTreeRoute.
const PathList & GetPathList() const
EvpnRoute * esi_ad_route_
virtual bool IsValid() const
void DeleteInclusiveMulticastRoute()
Delete Inclusive Multicast route for this EvpnLocalMcastNode.
void RetryDelete()
Attempt to enqueue a delete for the EvpnManager.
virtual std::string ToString() const