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(
127 boost::bind(&
PathResolver::RouteListener, this, _1, _2),
129 nexthop_longest_match_(false),
131 boost::bind(&
PathResolver::ProcessResolverNexthopRegUnregList, this),
135 boost::bind(&
PathResolver::ProcessResolverNexthopUpdateList, this),
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());
639 sprn.set_table(table->
name());
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());
1238 bool state_added = condition_listener->
CheckMatchState(table, route,
this);
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;
void FillRouteInfo(const BgpTable *table, ShowRouteBrief *show_route) const
virtual bool MayDelete() const
ResolverNexthop * LocateResolverNexthop(IpAddress address, BgpTable *table)
bool RouteListener(DBTablePartBase *root, DBEntryBase *entry)
void PauseResolverPathUpdateProcessing()
boost::scoped_ptr< DeleteActor > deleter_
const IpAddress & nexthop() const
void STLDeleteValues(Container *container)
const ResolverNexthop * rnexthop() const
static const uint8_t kMaxV6PrefixLen
const BgpPath * BestPath() const
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
void FillShowInfo(ShowPathResolver *spr, bool summary) const
void ResumeResolverPathUpdateProcessing()
ResolverNexthopList nexthop_update_list_
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
ResolverPath * CreateResolverPath(const BgpPath *path, BgpRoute *route, ResolverNexthop *rnexthop)
bool set_synchronize(const SetType *set1, const SetType *set2, AddFunctor add_fn, DelFunctor del_fn)
boost::function< void(BgpTable *, ConditionMatch *)> RequestDoneCb
void DisableResolverPathUpdateProcessing()
virtual bool Match(BgpServer *server, BgpTable *table, BgpRoute *route, bool deleted)
bool ProcessResolverNexthopRegUnregList()
static std::string PathIdString(uint32_t path_id)
void RemoveMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj)
ResolvedPathList resolved_path_list_
void TriggerPathResolution(ResolverPath *rpath)
RoutingInstance * routing_instance()
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
boost::asio::ip::address IpAddress
PathResolver(BgpTable *table)
size_t GetResolverPathUpdateListSize() const
const IpAddress & addr() const
DBTablePartBase * table_partition()
virtual ~ResolverNexthop()
PathResolverPartition(int part_id, PathResolver *resolver)
BgpAttrPtr ReplaceNexthopAndLocate(const BgpAttr *attr, const IpAddress &addr)
ResolverNexthop * rnexthop_
void StartPathResolution(BgpRoute *route, const BgpPath *path, BgpTable *nh_table=NULL)
const uint32_t GetPathId() const
const BgpRoute * GetRoute() const
bool IsResolutionFeasible() const
static const uint8_t kMaxV4PrefixLen
ResolverNexthopList nexthop_reg_unreg_list_
friend class PathResolverPartition
BgpConditionListener * condition_listener(Address::Family family)
void Delete(DBEntryBase *)
virtual Address::Family family() const =0
uint32_t GetFlags() const
PathToResolverPathMap rpath_map_
void DeferPathResolution(ResolverPath *rpath)
void Unregister(ListenerId listener)
void DisableResolverNexthopUpdateProcessing()
bool ProcessResolverNexthopUpdateList()
BgpAttrPtr ReplaceExtCommunityAndLocate(const BgpAttr *attr, ExtCommunityPtr extcomm)
#define BGP_LOG_STR(obj, level, flags, arg)
ResolverPath * RemoveResolverPath(const BgpPath *path)
ResolverNexthop(PathResolver *resolver, IpAddress address, BgpTable *table)
uint8_t prefixlen() const
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
void SetReplicateInfo(const BgpTable *table, const BgpRoute *rt)
void EnableResolverNexthopUpdateProcessing()
size_t resolved_path_count() const
void StopPathResolution(const BgpPath *path)
uint16_t GetNumber() const
void RegisterUnregisterResolverNexthop(ResolverNexthop *rnexthop)
void RemoveMatchCondition(BgpTable *table, ConditionMatch *obj, RequestDoneCb deleteDonecb)
size_t GetResolverNexthopDeleteListSize() const
ResolverRouteState * LocateResolverRouteState(BgpRoute *route)
PathSource GetSource() const
size_t GetResolverNexthopUpdateListSize() const
Inet6Prefix inet6_prefix() const
bool ProcessResolverPathUpdateList()
void AddMatchCondition(BgpTable *table, ConditionMatch *obj, RequestDoneCb addDoneCb)
ExtCommunityDB * extcomm_db()
DBTableBase::ListenerId listener_id_
friend class ResolverNexthop
Ip4Prefix inet_prefix() const
Address::Family family() const
BgpPath * LocateResolvedPath(const IPeer *peer, uint32_t path_id, const BgpAttr *attr, uint32_t label, bool is_replicated=false)
virtual const std::string & ToString() const =0
#define CHECK_CONCURRENCY(...)
void SetMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj, ConditionMatchState *state=NULL)
void UpdateResolverNexthop(ResolverNexthop *rnexthop)
void DestroyPathResolver()
virtual std::string ToString() const =0
size_t GetResolverPathUpdateListSize() const
bool CheckMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj)
DBTableBase::ListenerId listener_id() const
void RemoveResolverNexthop(ResolverNexthop *rnexthop)
BgpAttrPtr ReplaceSourceRdAndLocate(const BgpAttr *attr, const RouteDistinguisher &source_rd)
boost::scoped_ptr< TaskTrigger > nexthop_reg_unreg_trigger_
void EnableResolverPathUpdateProcessing()
const std::string & name() const
uint8_t ip_address_length() const
std::pair< IpAddress, BgpTable * > ResolverNexthopKey
void DisableResolverNexthopRegUnregProcessing()
ResolverRouteStatePtr state_
void RemoveResolverPath(int part_id, ResolverPath *rpath)
uint32_t GetLabel() const
int PathCompare(const BgpPath &rhs, bool allow_ecmp) const
const Ip4Prefix & GetPrefix() const
void ClearState(DBTableBase *tbl_base, ListenerId listener)
void UnregisterResolverNexthopDone(BgpTable *table, ConditionMatch *match)
bool InsertRoute(BgpRoute *route)
void TriggerAllResolverPaths() const
void InsertPath(BgpPath *path)
ResolverRouteState * GetResolverRouteState()
std::set< ResolverPath * > ResolverPathList
bool DuplicateForwardingPath(const BgpPath *in_path) const
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
bool ProcessResolverNexthopRegUnreg(ResolverNexthop *rnexthop)
const EvpnPrefix & GetPrefix() const
virtual std::string ToString() const
void DisableResolverPathUpdateProcessing()
bool IsMasterRoutingInstance() const
const ExtCommunity * ext_community() const
void DeleteResolvedPath(ResolvedPathList::const_iterator it)
ResolverPath(PathResolverPartition *partition, const BgpPath *path, BgpRoute *route, ResolverNexthop *rnexthop)
ResolverNexthopMap nexthop_map_
const BgpRoute * src_rt() const
void StartPathResolution(BgpRoute *route, const BgpPath *path, BgpTable *nh_table)
#define BGP_LOG_FLAG_TRACE
bool operator()(const BgpRoute *lhs, const BgpRoute *rhs) const
boost::scoped_ptr< TaskTrigger > rpath_update_trigger_
void ResumeResolverPathUpdateProcessing()
std::vector< PathResolverPartition * > partitions_
void StopPathResolution(int part_id, const BgpPath *path)
const BgpAttr * GetAttr() const
bool IsMoreSpecific(const Ip4Prefix &rhs) const
IpAddress address() const
static const int kInvalidId
void AddResolverPath(int part_id, ResolverPath *rpath)
void EnableResolverNexthopRegUnregProcessing()
void DeletePath(BgpPath *path)
static bool RoutePrefixMatch(const BgpRoute *route, const IpAddress &address)
size_t GetResolverNexthopRegUnregListSize() const
void PauseResolverPathUpdateProcessing()
static int PartitionCount()
ResolverPathList rpath_update_list_
void UnregisterMatchCondition(BgpTable *table, ConditionMatch *obj)
const Inet6Prefix & GetPrefix() const
DBTablePartBase * get_table_partition() const
const BgpTable * src_table() const
ResolverNexthopList nexthop_delete_list_
void Notify(DBEntryBase *entry)
std::vector< ResolverPathList > rpath_lists_
DeleteActor(PathResolver *resolver)
PathResolverPartition * GetPartition(int part_id)
boost::scoped_ptr< TaskTrigger > nexthop_update_trigger_
tbb::spin_rw_mutex & rw_mutex()
ResolverRouteState(PathResolver *resolver, BgpRoute *route)
PathResolverPartition * partition_
RouteDistinguisher GetSourceRouteDistinguisher() const
BgpConditionListener * get_condition_listener(Address::Family family)
virtual bool IsReplicated() const
bool nexthop_longest_match() const
ResolverRouteState * FindResolverRouteState(BgpRoute *route)
static bool RoutePrefixIsAddress(Address::Family family, const BgpRoute *route, const IpAddress &address)
std::set< BgpPath * > ResolvedPathList
void AddResolvedPath(ResolvedPathList::const_iterator it)
void EnableResolverPathUpdateProcessing()
ResolverPath * FindResolverPath(const BgpPath *path)
bool IsMoreSpecific(const Inet6Prefix &rhs) const
Ip4Address GetIPv4Address() const
Address::Family family() const
static ExtCommunityPtr UpdateExtendedCommunity(ExtCommunityDB *extcomm_db, const BgpAttr *attr, const BgpAttr *nh_attr)
PathResolver * path_resolver()
bool RemoveRoute(BgpRoute *route)
const PathList & GetPathList() const
size_t GetResolverNexthopMapSize() const
bool UpdateResolvedPaths()
virtual ~ResolverRouteState()