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) {
558 bool force_delete =
false;
565 for (Route::PathList::iterator it =
GetPathList().begin();
575 bool check_can_delete =
582 check_can_delete =
false;
591 if (check_can_delete && data &&
616 for(Route::PathList::iterator it =
GetPathList().begin();
666 std::unique_ptr<AgentPath> path_ref(path);
676 const Peer *old_active_path_peer = path->
peer();
690 RouteInfo rt_info_del;
709 if (new_active_path && new_active_path->
nexthop()) {
728 for(Route::PathList::const_iterator it =
GetPathList().begin();
731 if (path->
peer() == NULL) {
743 for(Route::PathList::const_iterator it =
GetPathList().begin();
746 if (path->
peer() == NULL) {
819 for (Route::PathList::const_iterator it =
825 if (intf_path == NULL &&
845 for(Route::PathList::const_iterator it =
GetPathList().begin();
848 if (path->
peer() == NULL) {
865 for(Route::PathList::const_iterator it =
GetPathList().begin();
868 if (path->
peer() == peer) {
897 tunnel_nh_list_.begin(); iter != tunnel_nh_list_.end(); iter++) {
905 req.
key = std::move(key);
906 req.
data.reset(NULL);
937 dependant_routes_.begin(); iter != dependant_routes_.end(); iter++) {
944 for(Route::PathList::const_iterator it =
GetPathList().begin();
947 static_cast<const AgentPath *
>(it.operator->());
959 for(Route::PathList::iterator it =
GetPathList().begin();
962 if (path->
Sync(
this) ==
true) {
972 for(Route::PathList::const_iterator it =
GetPathList().begin();
1004 bool is_inet_rt =
false;
1005 bool service_address =
false;
1009 service_address = agent->
params()->
1013 bool local_route =
false;
1019 if (is_inet_rt && (!service_address && !local_route) &&
1032 return "Route Entry";
1036 int cmp =
CompareTo(static_cast<const Route &>(rhs));
1065 bool del, uint32_t *evpn_label) {
1076 if (local_peer_path) {
1077 *evpn_label = local_peer_path->
label();
1083 if (local_vm_peer_path) {
1084 *evpn_label = local_vm_peer_path->
label();
1089 if (local_vm_peer_path) {
1090 *evpn_label = local_vm_peer_path->
label();
1092 }
else if (local_peer_path) {
1093 *evpn_label = local_peer_path->
label();
1102 bool delete_label =
false;
1108 delete_label =
true;
1111 if (local_peer_path == NULL &&
1112 local_vm_peer_path == NULL) {
1113 delete_label =
true;
1115 if (*evpn_label == path->
label()) {
1131 if ((path != local_peer_path) && (path != local_vm_peer_path))
1137 *evpn_label = path->
label();
1148 assert((local_vm_peer_path != NULL) ^ (local_peer_path != NULL));
1161 if (path->
peer() == NULL) {
1171 bool delete_all =
false;
1190 bool tor_path =
false;
1198 for (Route::PathList::iterator it =
GetPathList().begin();
1201 static_cast<AgentPath *
>(it.operator->());
1207 if (del && (path->
peer() == it_path->
peer())) {
1225 local_vm_peer_path = it_path;
1232 if (tor_peer_path == NULL)
1233 tor_peer_path = it_path;
1238 if (evpn_peer_path == NULL)
1239 evpn_peer_path = it_path;
1243 fabric_peer_path = it_path;
1245 multicast_peer_path = it_path;
1247 local_peer_path = it_path;
1252 if ((del && (tor_peer_path == NULL)) || !del) {
1262 if ((local_vm_peer_path == NULL) &&
1263 (tor_peer_path == NULL) &&
1264 (evpn_peer_path == NULL) &&
1265 (fabric_peer_path == NULL)) {
1266 if (multicast_peer_path != NULL) {
1275 std::unique_ptr<AgentPath> path_ref(multicast_peer_path);
1281 bool learning_enabled =
false;
1282 bool pbb_nh =
false;
1283 uint32_t old_fabric_mpls_label = 0;
1284 if (multicast_peer_path == NULL) {
1291 IsFabricMulticastLabel(multicast_peer_path->
label()))
1293 old_fabric_mpls_label = multicast_peer_path->
label();
1299 if (tor_peer_path) {
1302 ComputeNextHop(agent)->GetDBRequestKey()).release());
1303 std::unique_ptr<const NextHopKey> key4(tor_peer_key);
1305 component_nh_list.push_back(component_nh_data4);
1308 if (evpn_peer_path) {
1311 ComputeNextHop(agent)->GetDBRequestKey()).release());
1312 std::unique_ptr<const NextHopKey> key2(evpn_peer_key);
1314 component_nh_list.push_back(component_nh_data2);
1317 if (fabric_peer_path) {
1319 static_cast<NextHopKey *
>((fabric_peer_path->
1320 ComputeNextHop(agent)->GetDBRequestKey()).release());
1321 std::unique_ptr<const NextHopKey> key3(fabric_peer_key);
1323 component_nh_list.push_back(component_nh_data3);
1326 if (local_vm_peer_path) {
1328 static_cast<NextHopKey *
>((local_vm_peer_path->
1329 ComputeNextHop(agent)->GetDBRequestKey()).release());
1330 std::unique_ptr<const NextHopKey> key4(local_vm_peer_key);
1332 component_nh_list.push_back(component_nh_data4);
1337 learning_enabled =
true;
1339 if (cnh && cnh->
pbb_nh() ==
true) {
1350 vrf()->layer2_control_word()));
1353 FindActiveEntry(nh_req.
key.get()));
1373 if (fabric_peer_path) {
1378 if (old_fabric_mpls_label != fabric_peer_path->
label()) {
1394 bool unresolved =
false;
1395 uint32_t vxlan_id = 0;
1399 if (local_vm_peer_path) {
1401 unresolved = local_vm_peer_path->
unresolved();
1402 vxlan_id = local_vm_peer_path->
vxlan_id();
1404 }
else if (tor_peer_path) {
1407 vxlan_id = tor_peer_path->
vxlan_id();
1409 }
else if (fabric_peer_path) {
1412 vxlan_id = fabric_peer_path->
vxlan_id();
1414 }
else if (evpn_peer_path) {
1417 vxlan_id = evpn_peer_path->
vxlan_id();
1422 uint32_t label = evpn_label;
1425 if (fabric_peer_path) {
1426 label = fabric_peer_path->
label();
1430 multicast_peer_path,
1439 if (multicast_route_path) {
const std::string & GetName() const
uint64_t sequence_number_
AgentPath * FindLocalVmPortPath() const
SandeshTraceBufferPtr OperDBTraceBuf
static const std::string & GetSuffix(Agent::RouteTableType type)
void ResyncTunnelNextHop()
const VnListType & dest_vn_list() const
void ResetEcmpHashFields()
virtual bool ReComputePathDeletion(AgentPath *path)
#define OPER_TRACE_ROUTE_ENTRY(obj, table,...)
void UpdateEcmpHashFieldsUponRouteDelete(Agent *agent, const string &vrf_name)
void Process(DBClient *client, DBRequest *req)
void Sort(Compare compare, const Path *prev_front)
void EnqueueRouteResync() const
bool is_multicast() const
AgentRouteTable * dependent_route_table_
virtual bool UpdateRoute(AgentRoute *rt)
const std::string & vrf_name() const
static Agent * GetInstance()
void WalkTable(DBTableWalkRef walk)
virtual bool CanDeletePath(Agent *agent, AgentPath *path, const AgentRoute *rt) const
void AddUnresolvedRouteToTable(AgentRouteTable *table)
bool learning_enabled() const
void UpdateDeviceMastership(const std::string &vrf, ComponentNHList clist, bool del)
const PathPreference & path_preference() const
virtual std::unique_ptr< DBEntry > AllocEntry(const DBRequestKey *k) const
virtual const std::string GetAddressString() const =0
VrfEntry * FindVrfFromName(const string &name)
InetUnicastAgentRouteTable * fabric_inet4_unicast_table() const
NextHopTable * nexthop_table() const
DBTableBase * get_table() const
void ImportPrevActiveNH(Agent *agent, NextHop *nh)
DeleteActor(AgentRouteTable *rt_table)
bool WaitForTraffic() const
DBEntry * Find(const DBEntry *entry)
Agent supports multiple route tables - Inet-unicast (IPv4/IPv6), Inet-multicast, bridge, EVPN (Type2/Type5). This base class contains common code for all types of route tables.
virtual int CompareTo(const Route &rhs) const =0
AgentRoute * LocateRoute(DBTablePartition *part, VrfEntry *vrf, AgentRoute *rt, AgentRouteKey *key, AgentRouteData *data, bool *notify)
virtual ~AgentRouteTable()
PhysicalDeviceTable * physical_device_table() const
bool SubOpAddChangeInput(VrfEntry *vrf, AgentRouteTable *table, AgentPath **path_ptr, AgentRouteKey *key, AgentRouteData *data, bool route_added)
virtual void RetryDelete()
const AddressList & gateway_list() const
bool RtPathHasInterfaceComposite(const AgentPath *a_path)
returns true if the given path is not null and points
void EvaluateUnresolvedRoutes(void)
std::vector< int > SecurityGroupList
bool SubOpResyncInput(VrfEntry *vrf, AgentRouteTable *table, AgentPath **path_ptr, AgentRouteKey *key, AgentRouteData *data)
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)=0
const std::string & dest_vn_name() const
std::unique_ptr< DBRequestData > data
DBTableWalkRef AllocWalker(WalkFn walk_fn, WalkCompleteFn walk_complete)
#define AGENT_ROUTE_LOG(table, msg, route, vrf, peer_info)
bool Enqueue(DBRequest *req)
void DeletePathFromPeer(DBTablePartBase *part, AgentRouteTable *table, AgentPath *path)
static TypeBmap MplsType()
virtual AgentPath * FindPathUsingKeyData(const AgentRouteKey *key, const AgentRouteData *data) const
virtual uint32_t GetActiveLabel() const
boost::shared_ptr< const ComponentNHKey > ComponentNHKeyPtr
const string & GetName() const
LifetimeActor * deleter()
const std::string & dest_vn_name() const
void Delete(DBEntryBase *)
MplsTable * mpls_table() const
std::unique_ptr< DBRequestKey > KeyPtr
virtual void RetryDelete()
Base class for all Route entries in agent.
virtual KeyPtr GetDBRequestKey() const =0
virtual bool MayDelete() const
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)
virtual bool IsLess(const AgentPath &right) const
virtual AgentRoute * AllocRouteEntry(VrfEntry *vrf, bool is_multicast) const =0
virtual bool SkipAddChangeRequest() const
virtual const AgentPath * UsablePath() const
void ReleaseWalker(DBTableWalkRef &walk)
std::vector< ComponentNHKeyPtr > ComponentNHKeyList
virtual bool IsDeleted() const
AgentRoute * FindActiveEntry(const AgentRouteKey *key)
LifetimeRef< AgentRouteTable > vrf_delete_ref_
const std::string & fabric_vrf_name() const
const Type GetType() const
const AgentPath * GetActivePath() const
NextHop * nexthop() const
virtual Agent::RouteTableType GetTableType() const =0
VrfEntry * vrf_entry() const
void FillTrace(RouteInfo &route, Trace event, const AgentPath *path) const
virtual AgentPath * CreateAgentPath(const Peer *peer, AgentRoute *rt) const
void set_validate_mcast_src(bool validate_mcast_src)
boost::scoped_ptr< DeleteActor > deleter_
virtual void ProcessAdd(AgentRoute *rt)
AgentRoute * FindActiveEntryNoLock(const AgentRouteKey *key)
void Reset(LifetimeActor *actor)
AgentPath * FindLocalPath() const
const NextHop * GetActiveNextHop() const
bool is_subnet_discard() const
bool allow_route_add_on_deleted_vrf() const
std::unique_ptr< DBRequestKey > key
void Input(DBTablePartition *part, DBClient *client, DBRequest *req)
void RemovePath(AgentPath *path)
virtual Agent::RouteTableType GetRouteTableType()=0
void UpdateLabels(uint32_t evpn_label, uint32_t fabric_label)
static const std::string & NullString()
static TypeBmap AllType()
const Peer * peer() const
virtual bool ReComputeMulticastPaths(AgentPath *path, bool del)
const Peer * multicast_peer() const
static bool PathSelection(const Path &path1, const Path &path2)
virtual void ProcessDelete(AgentRoute *rt)
void DeleteRouteDone(DBTable::DBTableWalkRef walk_ref, DBTableBase *base, RouteTableWalkerState *state)
const ComponentNHList & component_nh_list() const
bool AddChangePath(Agent *agent, AgentPath *path, const AgentRoute *rt)
const Peer * local_peer() const
const bool unresolved() const
DBEntry * FindNoLock(const DBEntry *entry)
void InsertPath(const AgentPath *path)
const std::string & name() const
std::vector< std::string > CommunityList
void set_peer_sequence_number(uint64_t sequence_number)
COMPOSITETYPE composite_nh_type() const
AgentParam * params() const
const uint32_t vrf_id() const
std::set< std::string > VnListType
virtual KeyPtr GetDBRequestKey() const =0
void RemoveUnresolvedRouteFromTable(AgentRouteTable *table)
virtual void DeleteDerivedRoutes(AgentRouteTable *table)
bool DelExplicitRouteWalkerCb(DBTablePartBase *part, DBEntryBase *entry)
virtual std::string ToString() const =0
static const uint32_t kInvalidLabel
const AgentPath * FindIntfOrCompLocalVmPortPath() const
Finds path to an interface or a composite of interfaces and returns it. The priority is given to comp...
VrfTable * vrf_table() const
virtual bool Sync(AgentRoute *sync_route)
AgentPath * GetLocalVmPortPath() const
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
virtual void NotifyEntry(AgentRoute *entry)
uint32_t CreateRouteLabel(uint32_t label, const NextHopKey *nh_key, const std::string &vrf_name, const std::string &route)
void set_inactive(bool inactive)
const Path * front() const
virtual std::string ToString() const =0
virtual bool RecomputeRoutePath(Agent *agent, DBTablePartition *part, AgentPath *path, AgentRouteData *data)
UnresolvedRouteTree unresolved_rt_tree_
void RemoveUnresolvedRoute(const AgentRoute *rt)
void DeleteInput(DBTablePartition *part, AgentRouteTable *table, AgentRouteKey *key, AgentRouteData *data)
void RemoveUnresolvedNH(const NextHop *)
bool IsRPFInvalid() const
LifetimeActor * deleter()
void Process(DBRequest &req)
bool ProcessPath(Agent *agent, DBTablePartition *part, AgentPath *path, AgentRouteData *data)
virtual bool ReComputePathAdd(AgentPath *path)
void UpdateDependantRoutes()
const Peer * peer() const
DBEntry * Find(const DBEntry *entry)
virtual bool ValidateMcastSrc() const
const std::string & vrf_name() const
bool forwarding_enabled() const
#define LOG(_Level, _Msg)
AgentRouteTable * GetRouteTable(uint8_t table_type) const
void set_label(uint32_t label)
void Process(DBRequest &req)
const Peer * local_vm_peer() const
AgentRouteTable(DB *db, const std::string &name)
bool DeleteAllBgpPath(DBTablePartBase *part, AgentRouteTable *table)
void AddChangeInput(DBTablePartition *part, VrfEntry *vrf, AgentRoute *rt, AgentRouteKey *key, AgentRouteData *data)
virtual const NextHop * ComputeNextHop(Agent *agent) const
bool wait_for_traffic() const
virtual void Add(DBEntry *entry)
std::vector< ComponentNHPtr > ComponentNHList
virtual bool export_to_controller() const
void EvaluateUnresolvedNH(void)
boost::intrusive_ptr< DBTableWalk > DBTableWalkRef
void Notify(DBEntryBase *entry)
void AddUnresolvedNH(const NextHop *)
const std::string & fabric_vn_name() 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)
virtual AgentPath * FindPath(const Peer *peer) const
bool RtPathHasLocalInterface(const AgentPath *a_path)
returns true if the given path is not null and points
void AddUnresolvedRoute(const AgentRoute *rt)
bool operator()(const NextHop *nh1, const NextHop *nh2) const
virtual Composite::Type GetMulticastCompType()
virtual void UpdateDerivedRoutes(AgentRouteTable *table, const AgentPath *path, bool active_path_changed)
bool operator()(const AgentRoute *rt1, const AgentRoute *rt2) const
static TypeBmap VxlanType()
UnresolvedNHTree unresolved_nh_tree_
void insert(const Path *path)
uint32_t vxlan_id() const
virtual bool IsLess(const DBEntry &rhs) const
virtual bool IsLess(const DBEntry &rhs) const
virtual Agent::RouteTableType GetTableType() const =0
void FreeLabel(uint32_t label)
AgentRouteTable * GetDependentTable() const
void SetVrf(VrfEntry *vrf)
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
const PathList & GetPathList() const
boost::intrusive_ptr< NextHop > NextHopRef
std::vector< int > TagList