7 #include <boost/foreach.hpp>
15 #include "bgp/bgp_peer_types.h"
96 listener_id_(table->Register(
99 nexthop_longest_match_(false),
101 boost::bind(&
PathResolver::ProcessResolverNexthopRegUnregList, this),
105 boost::bind(&
PathResolver::ProcessResolverNexthopUpdateList, this),
106 TaskScheduler::GetInstance()->GetTaskId(
"bgp::ResolverNexthop"),
109 table_delete_ref_(this, table->
deleter()) {
148 "bgp::Config",
"bgp::ConfigHelper");
155 partitions_[part_id]->StartPathResolution(route, path, nh_table);
166 "bgp::Config",
"bgp::ConfigHelper");
189 tbb::mutex::scoped_lock lock(
mutex_);
199 tbb::mutex::scoped_lock lock(
mutex_);
249 "bgp::Config",
"bgp::ConfigHelper");
251 tbb::mutex::scoped_lock lock(
mutex_);
253 ResolverNexthopMap::iterator loc =
nexthop_map_.find(key);
280 ResolverNexthopMap::iterator loc =
nexthop_map_.find(key);
326 }
else if (rnexthop->
empty()) {
340 if (!rnexthop->
empty()) {
452 tbb::mutex::scoped_lock lock(
mutex_);
461 tbb::mutex::scoped_lock lock(
mutex_);
486 tbb::mutex::scoped_lock lock(
mutex_);
511 tbb::mutex::scoped_lock lock(
mutex_);
521 partitions_[part_id]->DisableResolverPathUpdateProcessing();
531 partitions_[part_id]->EnableResolverPathUpdateProcessing();
541 partitions_[part_id]->PauseResolverPathUpdateProcessing();
551 partitions_[part_id]->ResumeResolverPathUpdateProcessing();
562 total +=
partitions_[part_id]->GetResolverPathUpdateListSize();
573 size_t path_count = 0;
574 size_t modified_path_count = 0;
575 vector<ShowPathResolverPath> sprp_list;
582 for (PathResolverPartition::PathToResolverPathMap::const_iterator it =
586 ShowPathResolverPath sprp;
590 sprp_list.push_back(sprp);
593 spr->set_path_count(path_count);
594 spr->set_modified_path_count(modified_path_count);
602 vector<ShowPathResolverNexthop> sprn_list;
603 for (ResolverNexthopMap::const_iterator it =
nexthop_map_.begin();
607 ShowPathResolverNexthop sprn;
608 sprn.set_address(rnexthop->
address().to_string());
609 sprn.set_table(table->
name());
612 ShowRouteBrief show_route;
614 sprn.set_nexthop_route(show_route);
616 sprn_list.push_back(sprn);
619 spr->set_paths(sprp_list);
620 spr->set_nexthops(sprn_list);
635 TaskScheduler::GetInstance()->GetTaskId(
"bgp::ResolverPath"),
693 "bgp::Config",
"bgp::ConfigHelper",
"bgp::RouteAggregation");
733 PathToResolverPathMap::iterator loc =
rpath_map_.find(path);
734 return (loc !=
rpath_map_.end() ? loc->second : NULL);
744 PathToResolverPathMap::iterator loc =
rpath_map_.find(path);
763 for (ResolverPathList::iterator it = update_list.begin();
764 it != update_list.end(); ++it) {
821 : resolver_(resolver),
847 : partition_(partition),
851 state_(partition_->resolver()->LocateResolverRouteState(route)) {
879 " peer " << (peer ? peer->
ToString() :
"None") <<
895 " peer " << (peer ? peer->
ToString() :
"None") <<
908 const BgpAttr *attr, uint32_t label,
bool is_replicated) {
926 return (
new BgpPath(peer, path_id, src, attr, flags, label));
941 if (!nh_ext_community)
942 return ext_community;
953 sgid_list.push_back(value);
955 encap_list.push_back(value);
971 ext_community.get(), sgid_list);
973 ext_community.get(), encap_list);
976 ext_community.get(), *source_as);
980 ext_community.get(), *lb);
982 return ext_community;
1000 tbb::spin_rw_mutex::scoped_lock rt_write_lock;
1001 if (!rt_write_lock.try_acquire(
state_->rw_mutex(),
true)) {
1009 tbb::spin_rw_mutex::scoped_lock nh_read_lock;
1011 if (
state_ != nh_state &&
1012 nh_state && !nh_read_lock.try_acquire(nh_state->
rw_mutex(),
false)) {
1031 bool nh_ri_def =
false;
1035 bool process_paths =
false;
1036 if (
path_ && nh_route && !nh_ri_def) {
1037 process_paths =
true;
1039 Route::PathList::const_iterator it;
1042 for (; process_paths && it != nh_route->
GetPathList().end(); ++it) {
1043 const BgpPath *nh_path =
static_cast<const BgpPath *
>(it.operator->());
1082 ext_community->communities()) {
1085 export_list.push_back(
RouteTarget(v).GetExtCommunity());
1092 if (!export_list.empty()) {
1093 ext_community = extcomm_db->
AppendAndLocate(ext_community.get(), export_list);
1098 uint32_t path_id = nh_path->
GetAttr()->
nexthop().to_v4().to_ulong();
1101 future_resolved_path_list.insert(resolved_path);
1106 if (
path_ && nh_route && nh_ri_def) {
1117 future_resolved_path_list.insert(updated_path);
1123 &future_resolved_path_list,
1143 : resolver_(resolver),
1147 rpath_lists_(
DB::PartitionCount()),
1148 table_delete_ref_(this, table->
deleter()) {
1163 return (
string(
"ResolverNexthop ") +
address_.to_string());
1196 bool state_added = condition_listener->
CheckMatchState(table, route,
this);
1201 bool longest_match_updated =
true;
1222 if (longest_match_updated)
1240 "bgp::Config",
"bgp::ConfigHelper");
1284 for (ResolverPathList::iterator it =
rpath_lists_[part_id].begin();
1323 bool longest_match = (*(
routes_.begin()) == route);
1324 return longest_match;
1331 bool longest_match = (*(
routes_.begin()) == route);
1333 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
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)
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
bool ProcessResolverPathUpdateList()
void AddMatchCondition(BgpTable *table, ConditionMatch *obj, RequestDoneCb addDoneCb)
ExtCommunityDB * extcomm_db()
DBTableBase::ListenerId listener_id_
friend class ResolverNexthop
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
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)
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
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()