7 #include <boost/foreach.hpp>
15 #include "bgp/bgp_peer_types.h"
49 if (evpn_route->
GetPrefix().
addr().to_v4() == address.to_v4() &&
55 if (evpn_route->
GetPrefix().
addr().to_v6() == address.to_v6() &&
80 if (evpn_route ==
nullptr) {
126 listener_id_(table->Register(
129 nexthop_longest_match_(false),
136 TaskScheduler::GetInstance()->GetTaskId(
"bgp::ResolverNexthop"),
139 table_delete_ref_(this, table->
deleter()) {
178 "bgp::Config",
"bgp::ConfigHelper");
185 partitions_[part_id]->StartPathResolution(route, path, nh_table);
196 "bgp::Config",
"bgp::ConfigHelper");
219 tbb::mutex::scoped_lock lock(
mutex_);
229 tbb::mutex::scoped_lock lock(
mutex_);
279 "bgp::Config",
"bgp::ConfigHelper");
281 tbb::mutex::scoped_lock lock(
mutex_);
283 ResolverNexthopMap::iterator loc =
nexthop_map_.find(key);
310 ResolverNexthopMap::iterator loc =
nexthop_map_.find(key);
356 }
else if (rnexthop->
empty()) {
370 if (!rnexthop->
empty()) {
482 tbb::mutex::scoped_lock lock(
mutex_);
491 tbb::mutex::scoped_lock lock(
mutex_);
516 tbb::mutex::scoped_lock lock(
mutex_);
541 tbb::mutex::scoped_lock lock(
mutex_);
551 partitions_[part_id]->DisableResolverPathUpdateProcessing();
561 partitions_[part_id]->EnableResolverPathUpdateProcessing();
571 partitions_[part_id]->PauseResolverPathUpdateProcessing();
581 partitions_[part_id]->ResumeResolverPathUpdateProcessing();
592 total +=
partitions_[part_id]->GetResolverPathUpdateListSize();
603 size_t path_count = 0;
604 size_t modified_path_count = 0;
605 vector<ShowPathResolverPath> sprp_list;
612 for (PathResolverPartition::PathToResolverPathMap::const_iterator it =
616 ShowPathResolverPath sprp;
620 sprp_list.push_back(sprp);
623 spr->set_path_count(path_count);
624 spr->set_modified_path_count(modified_path_count);
632 vector<ShowPathResolverNexthop> sprn_list;
633 for (ResolverNexthopMap::const_iterator it =
nexthop_map_.begin();
637 ShowPathResolverNexthop sprn;
638 sprn.set_address(rnexthop->
address().to_string());
642 ShowRouteBrief show_route;
644 sprn.set_nexthop_route(show_route);
646 sprn_list.push_back(sprn);
649 spr->set_paths(sprp_list);
650 spr->set_nexthops(sprn_list);
665 TaskScheduler::GetInstance()->GetTaskId(
"bgp::ResolverPath"),
728 "bgp::Config",
"bgp::ConfigHelper",
"bgp::RouteAggregation");
768 PathToResolverPathMap::iterator loc =
rpath_map_.find(path);
769 return (loc !=
rpath_map_.end() ? loc->second : NULL);
779 PathToResolverPathMap::iterator loc =
rpath_map_.find(path);
798 for (ResolverPathList::iterator it = update_list.begin();
799 it != update_list.end(); ++it) {
856 : resolver_(resolver),
882 : partition_(partition),
886 state_(partition_->resolver()->LocateResolverRouteState(route)) {
914 " peer " << (peer ? peer->
ToString() :
"None") <<
930 " peer " << (peer ? peer->
ToString() :
"None") <<
943 const BgpAttr *attr, uint32_t label,
bool is_replicated) {
961 return (
new BgpPath(peer, path_id, src, attr, flags, label));
976 if (!nh_ext_community)
977 return ext_community;
989 sgid_list.push_back(value);
991 encap_list.push_back(value);
1009 ext_community.get(), sgid_list);
1011 ext_community.get(), encap_list);
1014 ext_community.get(), *source_as);
1018 ext_community.get(), *lb);
1022 ext_community.get(), *rt_mac);
1024 return ext_community;
1042 tbb::spin_rw_mutex::scoped_lock rt_write_lock;
1043 if (!rt_write_lock.try_acquire(
state_->rw_mutex(),
true)) {
1051 tbb::spin_rw_mutex::scoped_lock nh_read_lock;
1053 if (
state_ != nh_state &&
1054 nh_state && !nh_read_lock.try_acquire(nh_state->
rw_mutex(),
false)) {
1073 bool nh_ri_def =
false;
1077 bool process_paths =
false;
1078 if (
path_ && nh_route && !nh_ri_def) {
1079 process_paths =
true;
1081 Route::PathList::const_iterator it;
1084 for (; process_paths && it != nh_route->
GetPathList().end(); ++it) {
1085 const BgpPath *nh_path =
static_cast<const BgpPath *
>(it.operator->());
1124 ext_community->communities()) {
1127 export_list.push_back(
RouteTarget(v).GetExtCommunity());
1134 if (!export_list.empty()) {
1135 ext_community = extcomm_db->
AppendAndLocate(ext_community.get(), export_list);
1140 uint32_t path_id = nh_path->
GetAttr()->
nexthop().to_v4().to_ulong();
1143 future_resolved_path_list.insert(resolved_path);
1148 if (
path_ && nh_route && nh_ri_def) {
1159 future_resolved_path_list.insert(updated_path);
1165 &future_resolved_path_list,
1185 : resolver_(resolver),
1189 rpath_lists_(
DB::PartitionCount()),
1190 table_delete_ref_(this, table->
deleter()) {
1205 return (
string(
"ResolverNexthop ") +
address_.to_string());
1243 bool longest_match_updated =
true;
1264 if (longest_match_updated)
1282 "bgp::Config",
"bgp::ConfigHelper");
1326 for (ResolverPathList::iterator it =
rpath_lists_[part_id].begin();
1363 if (lhs_e !=
nullptr) {
1377 bool longest_match = (*(
routes_.begin()) == route);
1378 return longest_match;
1385 bool longest_match = (*(
routes_.begin()) == route);
1387 return longest_match;
boost::asio::ip::address IpAddress
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
#define BGP_LOG_FLAG_TRACE
#define BGP_LOG_STR(obj, level, flags, arg)
static const uint8_t kMaxV4PrefixLen
static const uint8_t kMaxV6PrefixLen
BgpAttrPtr ReplaceNexthopAndLocate(const BgpAttr *attr, const IpAddress &addr)
BgpAttrPtr ReplaceExtCommunityAndLocate(const BgpAttr *attr, ExtCommunityPtr extcomm)
BgpAttrPtr ReplaceSourceRdAndLocate(const BgpAttr *attr, const RouteDistinguisher &source_rd)
const IpAddress & nexthop() const
const ExtCommunity * ext_community() const
bool CheckMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj)
boost::function< void(BgpTable *, ConditionMatch *)> RequestDoneCb
void RemoveMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj)
void SetMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj, ConditionMatchState *state=NULL)
void AddMatchCondition(BgpTable *table, ConditionMatch *obj, RequestDoneCb addDoneCb)
void RemoveMatchCondition(BgpTable *table, ConditionMatch *obj, RequestDoneCb deleteDonecb)
void UnregisterMatchCondition(BgpTable *table, ConditionMatch *obj)
bool IsResolutionFeasible() const
uint32_t GetLabel() const
uint32_t GetFlags() const
const uint32_t GetPathId() const
static std::string PathIdString(uint32_t path_id)
virtual bool IsReplicated() const
const BgpAttr * GetAttr() const
RouteDistinguisher GetSourceRouteDistinguisher() const
PathSource GetSource() const
int PathCompare(const BgpPath &rhs, bool allow_ecmp) const
const BgpPath * BestPath() const
void DeletePath(BgpPath *path)
void FillRouteInfo(const BgpTable *table, ShowRouteBrief *show_route) const
void InsertPath(BgpPath *path)
bool DuplicateForwardingPath(const BgpPath *in_path) const
const BgpRoute * src_rt() const
const BgpTable * src_table() const
void SetReplicateInfo(const BgpTable *table, const BgpRoute *rt)
ExtCommunityDB * extcomm_db()
BgpConditionListener * condition_listener(Address::Family family)
void DestroyPathResolver()
RoutingInstance * routing_instance()
PathResolver * path_resolver()
virtual Address::Family family() const =0
virtual std::string ToString() const =0
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
void ClearState(DBTableBase *tbl_base, ListenerId listener)
DBTablePartBase * get_table_partition() const
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
static const int kInvalidId
void Unregister(ListenerId listener)
const std::string & name() const
void Notify(DBEntryBase *entry)
void Delete(DBEntryBase *)
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
static int PartitionCount()
Ip4Prefix inet_prefix() const
uint8_t prefixlen() const
uint8_t ip_address_length() const
Address::Family family() const
Inet6Prefix inet6_prefix() const
const IpAddress & addr() const
const EvpnPrefix & GetPrefix() const
virtual const std::string & ToString() const =0
bool IsMoreSpecific(const Inet6Prefix &rhs) const
const Inet6Prefix & GetPrefix() const
const Ip4Prefix & GetPrefix() const
bool IsMoreSpecific(const Ip4Prefix &rhs) const
void PauseResolverPathUpdateProcessing()
ResolverPath * CreateResolverPath(const BgpPath *path, BgpRoute *route, ResolverNexthop *rnexthop)
PathResolverPartition(int part_id, PathResolver *resolver)
void DisableResolverPathUpdateProcessing()
DBTablePartBase * table_partition()
ResolverPath * RemoveResolverPath(const BgpPath *path)
boost::scoped_ptr< TaskTrigger > rpath_update_trigger_
void StartPathResolution(BgpRoute *route, const BgpPath *path, BgpTable *nh_table)
ResolverPathList rpath_update_list_
ResolverPath * FindResolverPath(const BgpPath *path)
void EnableResolverPathUpdateProcessing()
size_t GetResolverPathUpdateListSize() const
bool ProcessResolverPathUpdateList()
void StopPathResolution(const BgpPath *path)
void ResumeResolverPathUpdateProcessing()
void TriggerPathResolution(ResolverPath *rpath)
std::set< ResolverPath * > ResolverPathList
void DeferPathResolution(ResolverPath *rpath)
PathToResolverPathMap rpath_map_
DeleteActor(PathResolver *resolver)
virtual bool MayDelete() const
void RegisterUnregisterResolverNexthop(ResolverNexthop *rnexthop)
std::pair< IpAddress, BgpTable * > ResolverNexthopKey
size_t GetResolverNexthopDeleteListSize() const
void EnableResolverPathUpdateProcessing()
friend class ResolverNexthop
static bool RoutePrefixMatch(const BgpRoute *route, const IpAddress &address)
ResolverRouteState * FindResolverRouteState(BgpRoute *route)
DBTableBase::ListenerId listener_id_
void UnregisterResolverNexthopDone(BgpTable *table, ConditionMatch *match)
size_t GetResolverNexthopMapSize() const
void FillShowInfo(ShowPathResolver *spr, bool summary) const
size_t GetResolverNexthopRegUnregListSize() const
void RemoveResolverNexthop(ResolverNexthop *rnexthop)
void ResumeResolverPathUpdateProcessing()
void DisableResolverNexthopRegUnregProcessing()
bool ProcessResolverNexthopRegUnregList()
ResolverNexthopList nexthop_delete_list_
ResolverNexthop * LocateResolverNexthop(IpAddress address, BgpTable *table)
bool RouteListener(DBTablePartBase *root, DBEntryBase *entry)
boost::scoped_ptr< TaskTrigger > nexthop_update_trigger_
PathResolverPartition * GetPartition(int part_id)
boost::scoped_ptr< TaskTrigger > nexthop_reg_unreg_trigger_
friend class PathResolverPartition
boost::scoped_ptr< DeleteActor > deleter_
BgpConditionListener * get_condition_listener(Address::Family family)
void StopPathResolution(int part_id, const BgpPath *path)
std::vector< PathResolverPartition * > partitions_
DBTableBase::ListenerId listener_id() const
void StartPathResolution(BgpRoute *route, const BgpPath *path, BgpTable *nh_table=NULL)
ResolverRouteState * LocateResolverRouteState(BgpRoute *route)
void DisableResolverPathUpdateProcessing()
bool ProcessResolverNexthopRegUnreg(ResolverNexthop *rnexthop)
void UpdateResolverNexthop(ResolverNexthop *rnexthop)
void PauseResolverPathUpdateProcessing()
bool nexthop_longest_match() const
ResolverNexthopList nexthop_reg_unreg_list_
ResolverNexthopList nexthop_update_list_
Address::Family family() const
bool ProcessResolverNexthopUpdateList()
void EnableResolverNexthopRegUnregProcessing()
size_t GetResolverNexthopUpdateListSize() const
ResolverNexthopMap nexthop_map_
PathResolver(BgpTable *table)
void EnableResolverNexthopUpdateProcessing()
void DisableResolverNexthopUpdateProcessing()
size_t GetResolverPathUpdateListSize() const
void AddResolverPath(int part_id, ResolverPath *rpath)
IpAddress address() const
void TriggerAllResolverPaths() const
std::vector< ResolverPathList > rpath_lists_
virtual bool Match(BgpServer *server, BgpTable *table, BgpRoute *route, bool deleted)
ResolverRouteState * GetResolverRouteState()
ResolverNexthop(PathResolver *resolver, IpAddress address, BgpTable *table)
const BgpRoute * GetRoute() const
virtual ~ResolverNexthop()
virtual std::string ToString() const
bool InsertRoute(BgpRoute *route)
bool RemoveRoute(BgpRoute *route)
void RemoveResolverPath(int part_id, ResolverPath *rpath)
PathResolverPartition * partition() const
ResolverNexthop * rnexthop_
BgpPath * LocateResolvedPath(const IPeer *peer, uint32_t path_id, const BgpAttr *attr, uint32_t label, bool is_replicated=false)
ResolverRouteStatePtr state_
ResolvedPathList resolved_path_list_
bool UpdateResolvedPaths()
const ResolverNexthop * rnexthop() const
size_t resolved_path_count() const
std::set< BgpPath * > ResolvedPathList
PathResolverPartition * partition_
ResolverPath(PathResolverPartition *partition, const BgpPath *path, BgpRoute *route, ResolverNexthop *rnexthop)
void DeleteResolvedPath(ResolvedPathList::const_iterator it)
void AddResolvedPath(ResolvedPathList::const_iterator it)
tbb::spin_rw_mutex & rw_mutex()
virtual ~ResolverRouteState()
ResolverRouteState(PathResolver *resolver, BgpRoute *route)
const bytes_type & GetExtCommunity() const
const PathList & GetPathList() const
bool IsMasterRoutingInstance() const
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Ip4Address GetIPv4Address() const
uint16_t GetNumber() const
static ExtCommunityPtr UpdateExtendedCommunity(ExtCommunityDB *extcomm_db, const BgpAttr *attr, const BgpAttr *nh_attr)
static bool RoutePrefixIsAddress(Address::Family family, const BgpRoute *route, const IpAddress &address)
bool set_synchronize(const SetType *set1, const SetType *set2, AddFunctor add_fn, DelFunctor del_fn)
bool operator()(const BgpRoute *lhs, const BgpRoute *rhs) const
#define CHECK_CONCURRENCY(...)
void STLDeleteValues(Container *container)