7 #include <boost/assign/list_of.hpp>
8 #include <boost/foreach.hpp>
25 #include "bgp/routing-instance/static_route_types.h"
29 using boost::assign::list_of;
30 using boost::system::error_code;
113 for (Route::PathList::iterator it =
145 return (
string(
"StaticRoute ") +
nexthop_.to_string());
160 return (
nexthop_ == ip_route->GetPrefix().addr());
179 template <
typename T>
183 : routing_instance_(rtinstance),
186 nexthop_(config.nexthop),
187 nexthop_route_(NULL),
188 unregistered_(false) {
196 template <
typename T>
201 if (prefix_ != prefix) {
204 if (nexthop_ != config.
nexthop) {
205 return NexthopChange;
208 return AttributeChange;
210 for (vector<string>::const_iterator it = config.
route_targets.begin();
214 if (rtarget_list_.find(rtarget) == rtarget_list_.end()) {
215 return AttributeChange;
218 if (community_ != GetCommunity(config)) {
219 return AttributeChange;
225 template <
typename T>
232 info->set_prefix(prefix_.ToString());
233 info->set_static_rt(path ?
true :
false);
234 info->set_nexthop(nexthop_.to_string());
235 if (nexthop_route_) {
236 ShowRouteBrief show_route;
237 nexthop_route_->FillRouteInfo(table, &show_route);
238 info->set_nexthop_rt(show_route);
241 vector<string> community_list;
242 BOOST_FOREACH(uint32_t value, community_->communities()) {
245 info->set_community_list(community_list);
247 vector<string> route_target_list;
248 for (RouteTargetList::const_iterator it = rtarget_list_.begin();
249 it != rtarget_list_.end(); ++it) {
250 route_target_list.push_back(it->ToString());
252 info->set_route_target_list(route_target_list);
257 info->set_secondary_tables(
264 template <
typename T>
270 if (is_nexthop_route(route) && !unregistered()) {
309 manager_->EnqueueStaticRouteReq(req);
319 template <
typename T>
323 for (vector<string>::const_iterator it = config.
communities.begin();
330 CommunityDB *comm_db = routing_instance()->server()->comm_db();
331 return comm_db->
Locate(comm_spec);
343 template <
typename T>
346 for (RouteTargetList::const_iterator it = rtarget_list().begin();
347 it != rtarget_list().end(); it++) {
348 export_list.push_back(it->GetExtCommunity());
351 BgpServer *server = routing_instance()->server();
356 int vn_index = routing_instance()->virtual_network_index();
357 if (export_list.empty() && vn_index) {
359 if (asn >
AS2_MAX && vn_index > 0xffff) {
369 new_ext_community.get(), origin_vn.GetExtCommunity());
372 return new_ext_community;
375 template <
typename T>
377 rtarget_list_.clear();
378 for (vector<string>::const_iterator it = config.
route_targets.begin();
384 rtarget_list_.insert(rtarget);
386 community_ = GetCommunity(config);
390 template <
typename T>
398 if (!static_route || static_route->
IsDeleted())
return;
400 for (NexthopPathIdList::iterator it = NexthopPathIds()->begin();
401 it != NexthopPathIds()->end(); it++) {
404 "Removed Static route path " << static_route->
ToString() <<
406 " in table " << bgp_table()->name());
410 partition->
Delete(static_route);
412 partition->
Notify(static_route);
417 template <
typename T>
425 if (static_route == NULL)
return;
430 for (NexthopPathIdList::iterator it = NexthopPathIds()->begin();
431 it != NexthopPathIds()->end(); it++) {
435 "Update attributes of StaticRoute path "
436 << static_route->
ToString() <<
" path_id "
438 << bgp_table()->name());
443 existing_path->
GetAttr(), ptr);
457 partition->
Notify(static_route);
461 template <
typename T>
471 if (static_route == NULL) {
472 static_route =
new RouteT(prefix_);
473 partition->
Add(static_route);
479 for (Route::PathList::iterator it = nexthop_route()->GetPathList().begin();
480 it != nexthop_route()->GetPathList().end(); it++) {
481 BgpPath *nexthop_route_path =
static_cast<BgpPath *
>(it.operator->());
487 if (nexthop_route()->BestPath()->PathCompare(*nexthop_route_path,
true))
494 if (nexthop_route()->DuplicateForwardingPath(nexthop_route_path))
500 nexthop_route_path->
GetAttr(), ptr);
520 vpn_route->GetPrefix().route_distinguisher());
529 if (existing_path != NULL) {
530 if ((new_attr.get() != existing_path->
GetAttr()) ||
548 partition->
Notify(static_route);
551 "Added Static Route path " << static_route->
ToString() <<
553 " in table " << bgp_table()->name());
556 if (!old_path_ids)
return;
558 for (NexthopPathIdList::iterator it = old_path_ids->begin();
559 it != old_path_ids->end(); it++) {
560 if (NexthopPathIds()->find(*it) != NexthopPathIds()->end())
563 partition->
Notify(static_route);
566 "Removed StaticRoute path " << static_route->
ToString() <<
568 " in table " << bgp_table()->name());
572 template <
typename T>
580 partition->
Notify(static_route);
583 template <
typename T>
597 template <
typename T>
599 : rtinstance_(rtinstance),
600 listener_(rtinstance_->server()->condition_listener(GetFamily())),
603 TaskScheduler::GetInstance()->GetTaskId(
"bgp::Config"), 0)) {
626 assert(addr.is_v4());
632 assert(addr.is_v6());
636 template <
typename T>
638 static_route_queue_->Enqueue(req);
641 template <
typename T>
651 (listener_->GetMatchState(table, route, info));
654 switch (req->
type_) {
691 listener_->RemoveMatchState(table, route, info);
694 UnregisterAndResolveStaticRoute(info);
703 template <
typename T>
707 for (StaticRouteProcessList::iterator
708 it = unregister_static_route_list_.begin();
709 it != unregister_static_route_list_.end(); ++it) {
711 listener_->UnregisterMatchCondition(info->
bgp_table(), info);
715 unregister_static_route_list_.clear();
717 if (static_route_map_.empty()) {
718 rtinstance_->server()->RemoveStaticRouteMgr(
this);
721 if (!routing_instance()->deleted() &&
722 routing_instance()->config()) {
723 ProcessStaticRouteConfig();
728 template <
typename T>
730 tbb::mutex::scoped_lock lock(mutex_);
731 unregister_static_route_list_.insert(entry);
732 unregister_list_trigger_->Set();
735 template <
typename T>
744 typename StaticRouteMap::iterator it = static_route_map_.find(route_key);
745 if (it != static_route_map_.end()) {
747 if (it->second->deleted())
return;
756 assert(change != StaticRouteT::PrefixChange);
759 if (change == StaticRouteT::NoChange)
763 if (change == StaticRouteT::AttributeChange) {
773 listener_->RemoveMatchCondition(
774 match->
bgp_table(), it->second.get(), callback);
779 new StaticRouteT(routing_instance(),
this, prefix, config);
782 if (static_route_map_.empty())
783 rtinstance_->server()->InsertStaticRouteMgr(
this);
784 static_route_map_.insert(make_pair(route_key, static_route_match));
786 listener_->AddMatchCondition(match->
bgp_table(), static_route_match.get(),
790 template <
typename T>
797 UnregisterAndResolveStaticRoute(match);
802 template <
typename T>
805 typename StaticRouteMap::iterator it = static_route_map_.find(static_route);
806 if (it == static_route_map_.end())
return;
808 if (it->second->deleted())
return;
814 listener_->RemoveMatchCondition(match->
bgp_table(), match, callback);
817 template <
typename T>
820 if (routing_instance()->deleted() || !routing_instance()->config())
return;
822 routing_instance()->config()->static_routes(GetFamily());
823 typedef BgpInstanceConfig::StaticRouteList::const_iterator iterator_t;
824 for (iterator_t iter = list.begin(); iter != list.end(); ++iter) {
825 LocateStaticRoutePrefix(*iter);
829 template <
typename T>
831 if (static_route_queue_)
832 delete static_route_queue_;
835 template <
typename T>
839 routing_instance()->config()->static_routes(GetFamily());
842 config_list.begin(), config_list.end(),
849 template <
typename T>
852 for (
typename StaticRouteMap::iterator it = static_route_map_.begin();
853 it != static_route_map_.end(); it++) {
854 RemoveStaticRoutePrefix(it->first);
858 template <
typename T>
860 typename StaticRouteMap::iterator loc,
861 StaticRouteConfigList::iterator it) {
862 AddressT address = this->GetAddress(it->address);
863 PrefixT prefix(address, it->prefix_length);
864 RouteKey route_key(prefix, it->nexthop);
869 template <
typename T>
871 LocateStaticRoutePrefix(*it);
874 template <
typename T>
876 RemoveStaticRoutePrefix(loc->first);
879 template <
typename T>
881 StaticRouteConfigList::iterator it) {
882 LocateStaticRoutePrefix(*it);
885 template <
typename T>
888 for (
typename StaticRouteMap::iterator it = static_route_map_.begin();
889 it != static_route_map_.end(); ++it) {
896 template <
typename T>
899 for (
typename StaticRouteMap::iterator it = static_route_map_.begin();
900 it != static_route_map_.end(); ++it) {
907 template <
typename T>
909 unregister_list_trigger_->set_disable();
912 template <
typename T>
914 unregister_list_trigger_->set_enable();
917 template <
typename T>
920 return static_route_map_.size();
923 template <
typename T>
927 for (
typename StaticRouteMap::const_iterator it = static_route_map_.begin();
928 it != static_route_map_.end(); ++it) {
939 if (static_route_map_.empty())
942 info->set_ri_name(ri->
name());
944 static_route_map_.begin(); it != static_route_map_.end(); ++it) {
947 StaticRouteInfo static_info;
949 info->static_route_list.push_back(static_info);
boost::intrusive_ptr< const AsPath > AsPathPtr
std::vector< std::string > route_targets
virtual string ToString() const
static Family VpnFamilyFromFamily(Family family)
int CompareStaticRoute(typename StaticRouteMap::iterator loc, StaticRouteConfigList::iterator it)
const IpAddress & nexthop() const
BgpTable * GetTable(Address::Family fmly)
StaticRouteMgr< T > StaticRouteMgrT
const BgpPath * BestPath() const
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
ExtCommunityPtr UpdateExtCommunity(const BgpAttr *attr) const
void AddStaticRoute(StaticRouteConfigList::iterator it)
TypePtr Locate(Type *attr)
virtual void EnableUnregisterTrigger()
RouteTargetList rtarget_list_
BgpTable * bgp_table() const
set< uint32_t > NexthopPathIdList
StaticRouteState(StaticRoutePtr info)
virtual bool Match(BgpServer *server, BgpTable *table, BgpRoute *route, bool deleted)
DISALLOW_COPY_AND_ASSIGN(StaticRoute)
boost::function< void(BgpTable *, ConditionMatch *)> RequestDoneCb
BgpAttrPtr ReplaceCommunityAndLocate(const BgpAttr *attr, CommunityPtr community)
DBEntry * Find(const DBEntry *entry)
static std::string PathIdString(uint32_t path_id)
virtual void NotifyAllRoutes()
ConditionMatchState * GetMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj)
RoutingInstance * routing_instance()
#define KEY_COMPARE(x, y)
const PrefixT & prefix() const
boost::asio::ip::address IpAddress
const IpAddress & nexthop() const
virtual void UpdateAllRoutes()
void UpdateStaticRoute(typename StaticRouteMap::iterator loc, StaticRouteConfigList::iterator it)
StaticRouteMgr(RoutingInstance *instance)
bool is_nexthop_route(BgpRoute *route)
virtual void UpdateStaticRouteConfig()
void set_nexthop_route(BgpRoute *nexthop_route)
const std::string & name() const
const BgpPath * FindPath(BgpPath::PathSource src) const
virtual void FlushStaticRouteConfig()
BgpConditionListener * condition_listener(Address::Family family)
RoutePathReplicator * replicator(Address::Family family)
std::set< StaticRouteConfig > StaticRouteList
std::vector< std::string > communities
virtual void ProcessStaticRouteConfig()
void Delete(DBEntryBase *)
uint32_t GetFlags() const
BgpAttrPtr ReplaceExtCommunityAndLocate(const BgpAttr *attr, ExtCommunityPtr extcomm)
int GetTaskId(const std::string &name)
#define BGP_LOG_STR(obj, level, flags, arg)
bool StaticRouteEventCallback(StaticRouteRequest *req)
DISALLOW_COPY_AND_ASSIGN(StaticRouteState)
RoutingInstance * routing_instance() const
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
virtual void DisableUnregisterTrigger()
RoutingInstance * routing_instance_
BgpRoute * nexthop_route_
void map_difference(ForwardIterator __first1, ForwardIterator __last1, ForwardIterator __first2, ForwardIterator __last2, AddFunctor __add_fn, DelFunctor __del_fn, EqFunctor __eq_fn)
Address::Family GetFamily() const
virtual uint32_t GetRouteCount() const
ExtCommunityDB * extcomm_db()
static TaskScheduler * GetInstance()
StaticRouteMgrT * manager_
boost::asio::ip::address_v6 Ip6Address
BgpAttrPtr ReplaceSubProtocolAndLocate(const BgpAttr *attr, const std::string &sbp)
#define CHECK_CONCURRENCY(...)
AddressT GetAddress(IpAddress addr) const
void SetMatchState(BgpTable *table, BgpRoute *route, ConditionMatch *obj, ConditionMatchState *state=NULL)
const string MatchProtocolToString(MatchProtocol::MatchProtocolType protocol)
void EnqueueStaticRouteReq(StaticRouteRequest *req)
const RouteTargetList & rtarget_list() const
WorkQueue< StaticRouteRequest * > * static_route_queue_
void DelStaticRoute(typename StaticRouteMap::iterator loc)
virtual std::string ToString() const =0
bool ProcessUnregisterList()
BgpAttrPtr ReplaceSourceRdAndLocate(const BgpAttr *attr, const RouteDistinguisher &source_rd)
void FillShowInfo(StaticRouteInfo *info) const
int static_route_task_id_
set< RouteTarget > RouteTargetList
static RouteTarget FromString(const std::string &str, boost::system::error_code *error=NULL)
uint32_t GetLabel() const
int PathCompare(const BgpPath &rhs, bool allow_ecmp) const
AddressT GetAddress(IpAddress addr) const
boost::asio::ip::address_v4 Ip4Address
void InsertPath(BgpPath *path)
std::vector< std::string > GetReplicatedTableNameList(const BgpTable *table, const BgpRoute *route, const BgpPath *path) const
bool RemovePath(BgpPath::PathSource src, const IPeer *peer=NULL, uint32_t path_id=0)
BgpRoute * nexthop_route() const
bool unregistered() const
void UnregisterAndResolveStaticRoute(StaticRoutePtr entry)
bool IsMasterRoutingInstance() const
const ExtCommunity * ext_community() const
BgpAttrPtr ReplaceAsPathAndLocate(const BgpAttr *attr, AsPathPtr aspath)
const BgpRoute * src_rt() const
Address::Family GetFamily() const
#define BGP_LOG_FLAG_TRACE
static ExtCommunityPtr UpdateExtCommunity(BgpServer *server, const RoutingInstance *rtinstance, const ExtCommunity *ext_community, const ExtCommunity::ExtCommunityList &export_list)
void AddStaticRoute(NexthopPathIdList *list)
const BgpAttr * GetAttr() const
void RemoveStaticRoutePrefix(const RouteKey &static_route)
DBEntry * Find(const DBEntry *entry)
virtual bool FillStaticRouteInfo(RoutingInstance *rtinstance, StaticRouteEntriesInfo *info) const
const bytes_type & GetExtCommunity() const
CommunityPtr GetCommunity(const StaticRouteConfig &config)
NexthopPathIdList nexthop_path_ids_
virtual void Add(DBEntry *entry)
CompareResult CompareConfig(const StaticRouteConfig &config)
const BgpTable * src_table() const
void StopStaticRouteDone(BgpTable *table, ConditionMatch *info)
void Notify(DBEntryBase *entry)
BgpInstanceConfig::StaticRouteList StaticRouteConfigList
uint32_t num_matchstate() const
virtual bool IsReplicated() const
as_t autonomous_system() const
StaticRoute(RoutingInstance *rtinstance, StaticRouteMgrT *manager, const PrefixT &static_route, const StaticRouteConfig &config)
NexthopPathIdList * NexthopPathIds()
void LocateStaticRoutePrefix(const StaticRouteConfig &config)
const PathList & GetPathList() const
virtual uint32_t GetDownRouteCount() const
void UpdateAttributes(const StaticRouteConfig &config)
ConditionMatchPtr StaticRoutePtr