4 #include <boost/uuid/uuid_io.hpp>
5 #include <boost/lexical_cast.hpp>
10 #include <vnc_cfg_types.h>
11 #include <agent_types.h>
25 #include <sandesh/sandesh_trace.h>
26 #include <sandesh/common/vns_constants.h>
33 using namespace boost::asio;
44 return table_->MayDelete();
49 assert(table_->vrf_entry_.get() != NULL);
50 table_->vrf_entry_->SetRouteTableDeleted(table_->GetTableType());
52 table_->vrf_delete_ref_.Reset(NULL);
53 table_->vrf_entry_ = NULL;
72 RouteTable(db, name), agent_(NULL), vrf_id_(0), vrf_entry_(NULL, this),
73 deleter_(NULL), vrf_delete_ref_(this, NULL), unresolved_rt_tree_(),
74 unresolved_nh_tree_() {
88 return unique_ptr<DBEntry>(
static_cast<DBEntry *
>(route));
96 return l_path.
IsLess(r_path);
100 static const string uc_suffix(
".uc.route.0");
101 static const string mpls_suffix(
".uc.route.3");
102 static const string mc_suffix(
".mc.route.0");
103 static const string evpn_suffix(
".evpn.route.0");
104 static const string l2_suffix(
".l2.route.0");
105 static const string uc_inet6_suffix(
".uc.route6.0");
119 return uc_inet6_suffix;
150 LOG(DEBUG,
"Deleted all BGP injected routes for " << base->
name());
213 if (req_table !=
this) {
214 if (req_table == NULL) {
223 req_table->
Input(p, client, req);
266 bool route_added = (rt == NULL);
267 rt =
LocateRoute(part, vrf, rt, key, data, ¬ify);
284 if (prev_active_path) {
292 active_path_changed =
true;
300 (path != prev_active_path)) {
303 if (cnh && new_cnh &&
327 if (rt != NULL && rt->
IsDeleted() ==
false)
334 assert(rt->
vrf() != NULL);
378 (*it)->EnqueueResync();
381 req.
key = (*it)->GetDBRequestKey();
402 (*it)->EnqueueRouteResync();
472 if (data == NULL || key->
peer() == NULL) {
559 bool force_delete =
false;
566 for (Route::PathList::iterator it =
GetPathList().begin();
576 bool check_can_delete =
583 check_can_delete =
false;
592 if (check_can_delete && data &&
617 for(Route::PathList::iterator it =
GetPathList().begin();
667 std::unique_ptr<AgentPath> path_ref(path);
677 const Peer *old_active_path_peer = path->
peer();
691 RouteInfo rt_info_del;
710 if (new_active_path && new_active_path->
nexthop()) {
729 for(Route::PathList::const_iterator it =
GetPathList().begin();
732 if (path->
peer() == NULL) {
744 for(Route::PathList::const_iterator it =
GetPathList().begin();
747 if (path->
peer() == NULL) {
820 for (Route::PathList::const_iterator it =
826 if (intf_path == NULL &&
846 for(Route::PathList::const_iterator it =
GetPathList().begin();
849 if (path->
peer() == NULL) {
866 for(Route::PathList::const_iterator it =
GetPathList().begin();
869 if (path->
peer() == peer) {
898 tunnel_nh_list_.begin(); iter != tunnel_nh_list_.end(); iter++) {
906 req.
key = std::move(key);
907 req.
data.reset(NULL);
938 dependant_routes_.begin(); iter != dependant_routes_.end(); iter++) {
945 for(Route::PathList::const_iterator it =
GetPathList().begin();
948 static_cast<const AgentPath *
>(it.operator->());
960 for(Route::PathList::iterator it =
GetPathList().begin();
963 if (path->
Sync(
this) ==
true) {
973 for(Route::PathList::const_iterator it =
GetPathList().begin();
1005 bool is_inet_rt =
false;
1006 bool service_address =
false;
1010 service_address = agent->
params()->
1014 bool local_route =
false;
1020 if (is_inet_rt && (!service_address && !local_route) &&
1033 return "Route Entry";
1066 bool del, uint32_t *evpn_label) {
1077 if (local_peer_path) {
1078 *evpn_label = local_peer_path->
label();
1084 if (local_vm_peer_path) {
1085 *evpn_label = local_vm_peer_path->
label();
1090 if (local_vm_peer_path) {
1091 *evpn_label = local_vm_peer_path->
label();
1093 }
else if (local_peer_path) {
1094 *evpn_label = local_peer_path->
label();
1103 bool delete_label =
false;
1109 delete_label =
true;
1112 if (local_peer_path == NULL &&
1113 local_vm_peer_path == NULL) {
1114 delete_label =
true;
1116 if (*evpn_label == path->
label()) {
1132 if ((path != local_peer_path) && (path != local_vm_peer_path))
1138 *evpn_label = path->
label();
1149 assert((local_vm_peer_path != NULL) ^ (local_peer_path != NULL));
1162 if (path->
peer() == NULL) {
1172 bool delete_all =
false;
1191 bool tor_path =
false;
1199 for (Route::PathList::iterator it =
GetPathList().begin();
1202 static_cast<AgentPath *
>(it.operator->());
1208 if (del && (path->
peer() == it_path->
peer())) {
1226 local_vm_peer_path = it_path;
1233 if (tor_peer_path == NULL)
1234 tor_peer_path = it_path;
1239 if (evpn_peer_path == NULL)
1240 evpn_peer_path = it_path;
1244 fabric_peer_path = it_path;
1246 multicast_peer_path = it_path;
1248 local_peer_path = it_path;
1253 if ((del && (tor_peer_path == NULL)) || !del) {
1263 if ((local_vm_peer_path == NULL) &&
1264 (tor_peer_path == NULL) &&
1265 (evpn_peer_path == NULL) &&
1266 (fabric_peer_path == NULL)) {
1267 if (multicast_peer_path != NULL) {
1276 std::unique_ptr<AgentPath> path_ref(multicast_peer_path);
1282 bool learning_enabled =
false;
1283 bool pbb_nh =
false;
1284 uint32_t old_fabric_mpls_label = 0;
1285 if (multicast_peer_path == NULL) {
1292 IsFabricMulticastLabel(multicast_peer_path->
label()))
1294 old_fabric_mpls_label = multicast_peer_path->
label();
1300 if (tor_peer_path) {
1303 ComputeNextHop(agent)->GetDBRequestKey()).release());
1304 std::unique_ptr<const NextHopKey> key4(tor_peer_key);
1306 component_nh_list.push_back(component_nh_data4);
1309 if (evpn_peer_path) {
1312 ComputeNextHop(agent)->GetDBRequestKey()).release());
1313 std::unique_ptr<const NextHopKey> key2(evpn_peer_key);
1315 component_nh_list.push_back(component_nh_data2);
1318 if (fabric_peer_path) {
1320 static_cast<NextHopKey *
>((fabric_peer_path->
1321 ComputeNextHop(agent)->GetDBRequestKey()).release());
1322 std::unique_ptr<const NextHopKey> key3(fabric_peer_key);
1324 component_nh_list.push_back(component_nh_data3);
1327 if (local_vm_peer_path) {
1329 static_cast<NextHopKey *
>((local_vm_peer_path->
1330 ComputeNextHop(agent)->GetDBRequestKey()).release());
1331 std::unique_ptr<const NextHopKey> key4(local_vm_peer_key);
1333 component_nh_list.push_back(component_nh_data4);
1338 learning_enabled =
true;
1340 if (cnh && cnh->
pbb_nh() ==
true) {
1351 vrf()->layer2_control_word()));
1354 FindActiveEntry(nh_req.
key.get()));
1374 if (fabric_peer_path) {
1379 if (old_fabric_mpls_label != fabric_peer_path->
label()) {
1395 bool unresolved =
false;
1396 uint32_t vxlan_id = 0;
1400 if (local_vm_peer_path) {
1402 unresolved = local_vm_peer_path->
unresolved();
1403 vxlan_id = local_vm_peer_path->
vxlan_id();
1405 }
else if (tor_peer_path) {
1408 vxlan_id = tor_peer_path->
vxlan_id();
1410 }
else if (fabric_peer_path) {
1413 vxlan_id = fabric_peer_path->
vxlan_id();
1415 }
else if (evpn_peer_path) {
1418 vxlan_id = evpn_peer_path->
vxlan_id();
1423 uint32_t label = evpn_label;
1426 if (fabric_peer_path) {
1427 label = fabric_peer_path->
label();
1431 multicast_peer_path,
1440 if (multicast_route_path) {
std::vector< int > TagList
boost::intrusive_ptr< NextHop > NextHopRef
std::vector< int > SecurityGroupList
std::set< std::string > VnListType
bool RtPathHasInterfaceComposite(const AgentPath *a_path)
returns true if the given path is not null and points
bool RtPathHasLocalInterface(const AgentPath *a_path)
returns true if the given path is not null and points
#define AGENT_ROUTE_LOG(table, msg, route, vrf, peer_info)
#define OPER_TRACE_ROUTE_ENTRY(obj, table,...)
std::vector< std::string > CommunityList
const AddressList & gateway_list() const
void set_label(uint32_t label)
void ResetEcmpHashFields()
virtual bool Sync(AgentRoute *sync_route)
const VnListType & dest_vn_list() const
void set_inactive(bool inactive)
void ImportPrevActiveNH(Agent *agent, NextHop *nh)
NextHop * nexthop() const
bool is_subnet_discard() const
AgentRouteTable * GetDependentTable() const
virtual bool IsLess(const AgentPath &right) const
void set_peer_sequence_number(uint64_t sequence_number)
const PathPreference & path_preference() const
virtual const AgentPath * UsablePath() const
uint32_t vxlan_id() const
const Peer * peer() const
const bool unresolved() const
const std::string & dest_vn_name() const
virtual const NextHop * ComputeNextHop(Agent *agent) const
DeleteActor(AgentRouteTable *rt_table)
virtual bool MayDelete() const
Agent supports multiple route tables - Inet-unicast (IPv4/IPv6), Inet-multicast, bridge,...
void RemoveUnresolvedNH(const NextHop *)
bool DelExplicitRouteWalkerCb(DBTablePartBase *part, DBEntryBase *entry)
UnresolvedRouteTree unresolved_rt_tree_
static bool PathSelection(const Path &path1, const Path &path2)
virtual void ProcessAdd(AgentRoute *rt)
const std::string & vrf_name() const
void Process(DBRequest &req)
void SetVrf(VrfEntry *vrf)
AgentRoute * LocateRoute(DBTablePartition *part, VrfEntry *vrf, AgentRoute *rt, AgentRouteKey *key, AgentRouteData *data, bool *notify)
virtual Agent::RouteTableType GetTableType() const =0
SandeshTraceBufferPtr OperDBTraceBuf
virtual void RetryDelete()
virtual void ProcessDelete(AgentRoute *rt)
LifetimeActor * deleter()
void DeleteRouteDone(DBTable::DBTableWalkRef walk_ref, DBTableBase *base, RouteTableWalkerState *state)
virtual std::unique_ptr< DBEntry > AllocEntry(const DBRequestKey *k) const
void AddUnresolvedRoute(const AgentRoute *rt)
void EvaluateUnresolvedRoutes(void)
boost::scoped_ptr< DeleteActor > deleter_
LifetimeRef< AgentRouteTable > vrf_delete_ref_
VrfEntry * vrf_entry() const
AgentRoute * FindActiveEntryNoLock(const AgentRouteKey *key)
void Input(DBTablePartition *part, DBClient *client, DBRequest *req)
UnresolvedNHTree unresolved_nh_tree_
virtual void NotifyEntry(AgentRoute *entry)
AgentRouteTable(DB *db, const std::string &name)
void EvaluateUnresolvedNH(void)
virtual ~AgentRouteTable()
static const std::string & GetSuffix(Agent::RouteTableType type)
void RemoveUnresolvedRoute(const AgentRoute *rt)
AgentRoute * FindActiveEntry(const AgentRouteKey *key)
void AddChangeInput(DBTablePartition *part, VrfEntry *vrf, AgentRoute *rt, AgentRouteKey *key, AgentRouteData *data)
void AddUnresolvedNH(const NextHop *)
Base class for all Route entries in agent.
virtual int CompareTo(const Route &rhs) const =0
AgentPath * GetLocalVmPortPath() const
virtual void DeleteDerivedRoutes(AgentRouteTable *table)
const AgentPath * FindIntfOrCompLocalVmPortPath() const
Finds path to an interface or a composite of interfaces and returns it. The priority is given to comp...
virtual bool ReComputeMulticastPaths(AgentPath *path, bool del)
virtual AgentPath * FindPathUsingKeyData(const AgentRouteKey *key, const AgentRouteData *data) const
virtual void UpdateDerivedRoutes(AgentRouteTable *table, const AgentPath *path, bool active_path_changed)
bool IsRPFInvalid() const
bool ProcessPath(Agent *agent, DBTablePartition *part, AgentPath *path, AgentRouteData *data)
void AddUnresolvedRouteToTable(AgentRouteTable *table)
AgentPath * FindLocalPath() const
void FillTrace(RouteInfo &route, Trace event, const AgentPath *path) const
void ResyncTunnelNextHop()
virtual bool IsLess(const DBEntry &rhs) const
void InsertPath(const AgentPath *path)
const AgentPath * GetActivePath() const
virtual void HandleDeviceMastershipUpdate(AgentPath *path, bool del)
virtual void HandleMulticastLabel(const Agent *agent, AgentPath *path, const AgentPath *local_peer_path, const AgentPath *local_vm_peer_path, bool del, uint32_t *evpn_label)
const NextHop * GetActiveNextHop() const
virtual const std::string GetAddressString() const =0
virtual uint32_t GetActiveLabel() const
bool WaitForTraffic() const
void DeleteInput(DBTablePartition *part, AgentRouteTable *table, AgentRouteKey *key, AgentRouteData *data)
bool DeleteAllBgpPath(DBTablePartBase *part, AgentRouteTable *table)
bool SubOpResyncInput(VrfEntry *vrf, AgentRouteTable *table, AgentPath **path_ptr, AgentRouteKey *key, AgentRouteData *data)
void UpdateDependantRoutes()
AgentRouteTable * dependent_route_table_
virtual bool ReComputePathAdd(AgentPath *path)
virtual std::string ToString() const =0
virtual KeyPtr GetDBRequestKey() const =0
void RemovePath(AgentPath *path)
void DeletePathFromPeer(DBTablePartBase *part, AgentRouteTable *table, AgentPath *path)
virtual Composite::Type GetMulticastCompType()
virtual AgentPath * FindPath(const Peer *peer) const
void EnqueueRouteResync() const
void set_origin_vn_name(const VnListType &dest_vn_list)
virtual Agent::RouteTableType GetTableType() const =0
void RemoveUnresolvedRouteFromTable(AgentRouteTable *table)
bool SubOpAddChangeInput(VrfEntry *vrf, AgentRouteTable *table, AgentPath **path_ptr, AgentRouteKey *key, AgentRouteData *data, bool route_added)
virtual bool ValidateMcastSrc() const
virtual bool RecomputeRoutePath(Agent *agent, DBTablePartition *part, AgentPath *path, AgentRouteData *data)
AgentPath * FindLocalVmPortPath() const
virtual bool ReComputePathDeletion(AgentPath *path)
const std::string & dest_vn_name() const
AgentParam * params() const
VrfTable * vrf_table() const
const Peer * local_peer() const
const Peer * local_vm_peer() const
const std::string & fabric_vn_name() const
const Peer * multicast_peer() const
static const std::string & NullString()
PhysicalDeviceTable * physical_device_table() const
NextHopTable * nexthop_table() const
static Agent * GetInstance()
InetUnicastAgentRouteTable * fabric_inet4_unicast_table() const
bool forwarding_enabled() const
const std::string & fabric_vrf_name() const
MplsTable * mpls_table() const
const ComponentNHList & component_nh_list() const
void UpdateEcmpHashFieldsUponRouteDelete(Agent *agent, const string &vrf_name)
COMPOSITETYPE composite_nh_type() const
void set_validate_mcast_src(bool validate_mcast_src)
std::unique_ptr< DBRequestKey > KeyPtr
DBTableBase * get_table() const
virtual KeyPtr GetDBRequestKey() const =0
bool Enqueue(DBRequest *req)
const std::string & name() const
void Notify(DBEntryBase *entry)
void Delete(DBEntryBase *)
void Process(DBClient *client, DBRequest *req)
virtual void Add(DBEntry *entry)
DBEntry * Find(const DBEntry *entry)
DBTableWalkRef AllocWalker(WalkFn walk_fn, WalkCompleteFn walk_complete)
void WalkTable(DBTableWalkRef walk)
DBEntry * Find(const DBEntry *entry)
void ReleaseWalker(DBTableWalkRef &walk)
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
DBEntry * FindNoLock(const DBEntry *entry)
boost::intrusive_ptr< DBTableWalk > DBTableWalkRef
void Reset(LifetimeActor *actor)
void FreeLabel(uint32_t label)
static const uint32_t kInvalidLabel
uint32_t CreateRouteLabel(uint32_t label, const NextHopKey *nh_key, const std::string &vrf_name, const std::string &route)
void UpdateLabels(uint32_t evpn_label, uint32_t fabric_label)
static bool CopyPathParameters(Agent *agent, AgentPath *path, const std::string &dest_vn_name, bool unresolved, uint32_t vxlan_id, uint32_t label, uint32_t tunnel_type, NextHop *nh, const AgentRoute *rt, bool ha_stale=false)
void Process(DBRequest &req)
bool learning_enabled() const
virtual bool IsLess(const DBEntry &rhs) const
bool wait_for_traffic() const
virtual bool IsDeleted() const
const Type GetType() const
@ MULTICAST_FABRIC_TREE_BUILDER
const std::string & GetName() const
virtual bool SkipAddChangeRequest() const
virtual bool export_to_controller() const
void UpdateDeviceMastership(const std::string &vrf, ComponentNHList clist, bool del)
void Sort(Compare compare, const Path *prev_front)
const PathList & GetPathList() const
const Path * front() const
void insert(const Path *path)
void remove(const Path *path)
static TypeBmap VxlanType()
static TypeBmap AllType()
static TypeBmap MplsType()
const string & GetName() const
bool allow_route_add_on_deleted_vrf() const
const uint32_t vrf_id() const
LifetimeActor * deleter()
virtual void RetryDelete()
AgentRouteTable * GetRouteTable(uint8_t table_type) const
VrfEntry * FindVrfFromName(const string &name)
#define LOG(_Level, _Msg)
std::vector< ComponentNHPtr > ComponentNHList
boost::shared_ptr< const ComponentNHKey > ComponentNHKeyPtr
std::vector< ComponentNHKeyPtr > ComponentNHKeyList
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
virtual bool UpdateRoute(AgentRoute *rt)
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)=0
virtual bool CanDeletePath(Agent *agent, AgentPath *path, const AgentRoute *rt) const
virtual AgentPath * CreateAgentPath(const Peer *peer, AgentRoute *rt) const
uint64_t sequence_number_
bool AddChangePath(Agent *agent, AgentPath *path, const AgentRoute *rt)
bool is_multicast() const
const Peer * peer() const
virtual Agent::RouteTableType GetRouteTableType()=0
virtual AgentRoute * AllocRouteEntry(VrfEntry *vrf, bool is_multicast) const =0
const std::string & vrf_name() const
virtual std::string ToString() const =0
std::unique_ptr< DBRequestKey > key
std::unique_ptr< DBRequestData > data
bool operator()(const NextHop *nh1, const NextHop *nh2) const
bool operator()(const AgentRoute *rt1, const AgentRoute *rt2) const