Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 50 additions & 8 deletions orchagent/vnetorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,28 @@ bool VNetVrfObject::addRoute(IpPrefix& ipPrefix, NextHopGroupKey& nexthops)
return true;
}

void VNetVrfObject::addProfile(IpPrefix& ipPrefix, string& profile)
{
profile_[ipPrefix] = profile;
}

void VNetVrfObject::removeProfile(IpPrefix& ipPrefix)
{
if (profile_.find(ipPrefix) != profile_.end())
{
profile_.erase(ipPrefix);
}
}

string VNetVrfObject::getProfile(IpPrefix& ipPrefix)
{
if (profile_.find(ipPrefix) != profile_.end())
{
return profile_[ipPrefix];
}
return string();
}

void VNetVrfObject::increaseNextHopRefCount(const nextHop& nh)
{
/* Return when there is no next hop (dropped) */
Expand Down Expand Up @@ -820,7 +842,7 @@ bool VNetRouteOrch::removeNextHopGroup(const string& vnet, const NextHopGroupKey

template<>
bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipPrefix,
NextHopGroupKey& nexthops, string& op,
NextHopGroupKey& nexthops, string& op, string& profile,
const map<NextHopKey, IpAddress>& monitors)
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -959,6 +981,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
syncd_nexthop_groups_[vnet][nhg].tunnel_routes.erase(ipPrefix);
}
vrf_obj->removeRoute(ipPrefix);
vrf_obj->removeProfile(ipPrefix);
}

syncd_nexthop_groups_[vnet][nexthops].tunnel_routes.insert(ipPrefix);
Expand All @@ -967,7 +990,12 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
syncd_nexthop_groups_[vnet][nexthops].ref_count++;
vrf_obj->addRoute(ipPrefix, nexthops);

postRouteState(vnet, ipPrefix, nexthops);
if (!profile.empty())
{
vrf_obj->addProfile(ipPrefix, profile);
}

postRouteState(vnet, ipPrefix, nexthops, profile);
}
else if (op == DEL_COMMAND)
{
Expand Down Expand Up @@ -1019,6 +1047,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
}

vrf_obj->removeRoute(ipPrefix);
vrf_obj->removeProfile(ipPrefix);

removeRouteState(vnet, ipPrefix);
}
Expand Down Expand Up @@ -1556,7 +1585,7 @@ void VNetRouteOrch::delEndpointMonitor(const string& vnet, NextHopGroupKey& next
}
}

void VNetRouteOrch::postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops)
void VNetRouteOrch::postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& profile)
{
const string state_db_key = vnet + state_db_key_delimiter + ipPrefix.to_string();
vector<FieldValueTuple> fvVector;
Expand All @@ -1581,7 +1610,7 @@ void VNetRouteOrch::postRouteState(const string& vnet, IpPrefix& ipPrefix, NextH
{
if (route_state == "active")
{
addRouteAdvertisement(ipPrefix);
addRouteAdvertisement(ipPrefix, profile);
}
else
{
Expand All @@ -1597,11 +1626,18 @@ void VNetRouteOrch::removeRouteState(const string& vnet, IpPrefix& ipPrefix)
removeRouteAdvertisement(ipPrefix);
}

void VNetRouteOrch::addRouteAdvertisement(IpPrefix& ipPrefix)
void VNetRouteOrch::addRouteAdvertisement(IpPrefix& ipPrefix, string& profile)
{
const string key = ipPrefix.to_string();
vector<FieldValueTuple> fvs;
fvs.push_back(FieldValueTuple("", ""));
if (profile.empty())
{
fvs.push_back(FieldValueTuple("", ""));
}
else
{
fvs.push_back(FieldValueTuple("profile", profile));
}
state_vnet_rt_adv_table_->set(key, fvs);
}

Expand Down Expand Up @@ -1792,7 +1828,8 @@ void VNetRouteOrch::updateVnetTunnel(const BfdUpdate& update)
// Post configured in State DB
for (auto ip_pfx : syncd_nexthop_groups_[vnet][nexthops].tunnel_routes)
{
postRouteState(vnet, ip_pfx, nexthops);
string profile = vrf_obj->getProfile(ip_pfx);
postRouteState(vnet, ip_pfx, nexthops, profile);
}
}
}
Expand All @@ -1805,6 +1842,7 @@ bool VNetRouteOrch::handleTunnel(const Request& request)
vector<string> mac_list;
vector<string> vni_list;
vector<IpAddress> monitor_list;
string profile = "";

for (const auto& name: request.getAttrFieldNames())
{
Expand All @@ -1826,6 +1864,10 @@ bool VNetRouteOrch::handleTunnel(const Request& request)
{
monitor_list = request.getAttrIPList(name);
}
else if (name == "profile")
{
profile = request.getAttrString(name);
}
else
{
SWSS_LOG_INFO("Unknown attribute: %s", name.c_str());
Expand Down Expand Up @@ -1889,7 +1931,7 @@ bool VNetRouteOrch::handleTunnel(const Request& request)

if (vnet_orch_->isVnetExecVrf())
{
return doRouteTask<VNetVrfObject>(vnet_name, ip_pfx, nhg, op, monitors);
return doRouteTask<VNetVrfObject>(vnet_name, ip_pfx, nhg, op, profile, monitors);
}

return true;
Expand Down
13 changes: 10 additions & 3 deletions orchagent/vnetorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ struct nextHop

typedef std::map<IpPrefix, NextHopGroupKey> TunnelRoutes;
typedef std::map<IpPrefix, nextHop> RouteMap;
typedef std::map<IpPrefix, string> ProfileMap;

class VNetVrfObject : public VNetObject
{
Expand Down Expand Up @@ -182,6 +183,10 @@ class VNetVrfObject : public VNetObject
bool addRoute(IpPrefix& ipPrefix, nextHop& nh);
bool removeRoute(IpPrefix& ipPrefix);

void addProfile(IpPrefix& ipPrefix, string& profile);
void removeProfile(IpPrefix& ipPrefix);
string getProfile(IpPrefix& ipPrefix);

size_t getRouteCount() const;
bool getRouteNextHop(IpPrefix& ipPrefix, nextHop& nh);
bool hasRoute(IpPrefix& ipPrefix);
Expand All @@ -199,6 +204,7 @@ class VNetVrfObject : public VNetObject

TunnelRoutes tunnels_;
RouteMap routes_;
ProfileMap profile_;
};

typedef std::unique_ptr<VNetObject> VNetObject_T;
Expand Down Expand Up @@ -270,6 +276,7 @@ const request_description_t vnet_route_description = {
{ "vni", REQ_T_STRING },
{ "mac_address", REQ_T_STRING },
{ "endpoint_monitor", REQ_T_IP_LIST },
{ "profile", REQ_T_STRING },
},
{ }
};
Expand Down Expand Up @@ -351,16 +358,16 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer
void removeBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr);
void setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops);
void delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops);
void postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops);
void postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& profile);
void removeRouteState(const string& vnet, IpPrefix& ipPrefix);
void addRouteAdvertisement(IpPrefix& ipPrefix);
void addRouteAdvertisement(IpPrefix& ipPrefix, string& profile);
void removeRouteAdvertisement(IpPrefix& ipPrefix);

void updateVnetTunnel(const BfdUpdate&);
bool updateTunnelRoute(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& op);

template<typename T>
bool doRouteTask(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& op,
bool doRouteTask(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& op, string& profile,
const std::map<NextHopKey, IpAddress>& monitors=std::map<NextHopKey, IpAddress>());

template<typename T>
Expand Down
31 changes: 20 additions & 11 deletions tests/test_vnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ def delete_vnet_local_routes(dvs, prefix, vnet_name):
time.sleep(2)


def create_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor=""):
set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac=mac, vni=vni, ep_monitor=ep_monitor)
def create_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile=""):
set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac=mac, vni=vni, ep_monitor=ep_monitor, profile=profile)


def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor=""):
def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile=""):
conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0)

attrs = [
Expand All @@ -160,6 +160,9 @@ def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor=
if ep_monitor:
attrs.append(('endpoint_monitor', ep_monitor))

if profile:
attrs.append(('profile', profile))

tbl = swsscommon.Table(conf_db, "VNET_ROUTE_TUNNEL")
fvs = swsscommon.FieldValuePairs(attrs)
tbl.set("%s|%s" % (vnet_name, prefix), fvs)
Expand Down Expand Up @@ -490,13 +493,19 @@ def check_remove_state_db_routes(dvs, vnet, prefix):
assert vnet + '|' + prefix not in keys


def check_routes_advertisement(dvs, prefix):
def check_routes_advertisement(dvs, prefix, profile=""):
state_db = swsscommon.DBConnector(swsscommon.STATE_DB, dvs.redis_sock, 0)
tbl = swsscommon.Table(state_db, "ADVERTISE_NETWORK_TABLE")
keys = tbl.getKeys()

assert prefix in keys

if profile:
status, fvs = tbl.get(prefix)
assert status, "Got an error when get a key"
fvs = dict(fvs)
assert fvs['profile'] == profile


def check_remove_routes_advertisement(dvs, prefix):
state_db = swsscommon.DBConnector(swsscommon.STATE_DB, dvs.redis_sock, 0)
Expand Down Expand Up @@ -1986,7 +1995,7 @@ def test_vnet_orch_12(self, dvs, testlog):
vnet_obj.check_vxlan_tunnel(dvs, tunnel_name, '12.12.12.12')

vnet_obj.fetch_exist_entries(dvs)
create_vnet_routes(dvs, "100.100.1.1/32", 'Vnet12', '12.0.0.1,12.0.0.2,12.0.0.3', ep_monitor='12.1.0.1,12.1.0.2,12.1.0.3')
create_vnet_routes(dvs, "100.100.1.1/32", 'Vnet12', '12.0.0.1,12.0.0.2,12.0.0.3', ep_monitor='12.1.0.1,12.1.0.2,12.1.0.3', profile="test_profile")

# default bfd status is down, route should not be programmed in this status
vnet_obj.check_del_vnet_routes(dvs, 'Vnet12', ["100.100.1.1/32"])
Expand All @@ -2000,14 +2009,14 @@ def test_vnet_orch_12(self, dvs, testlog):
time.sleep(2)
route1, nhg1_1 = vnet_obj.check_vnet_ecmp_routes(dvs, 'Vnet12', ['12.0.0.1', '12.0.0.2', '12.0.0.3'], tunnel_name)
check_state_db_routes(dvs, 'Vnet12', "100.100.1.1/32", ['12.0.0.1', '12.0.0.2', '12.0.0.3'])
check_routes_advertisement(dvs, "100.100.1.1/32")
check_routes_advertisement(dvs, "100.100.1.1/32", "test_profile")

# Remove endpoint from group if it goes down
update_bfd_session_state(dvs, '12.1.0.2', 'Down')
time.sleep(2)
route1, nhg1_1 = vnet_obj.check_vnet_ecmp_routes(dvs, 'Vnet12', ['12.0.0.1', '12.0.0.3'], tunnel_name, route_ids=route1, nhg=nhg1_1)
check_state_db_routes(dvs, 'Vnet12', "100.100.1.1/32", ['12.0.0.1', '12.0.0.3'])
check_routes_advertisement(dvs, "100.100.1.1/32")
check_routes_advertisement(dvs, "100.100.1.1/32", "test_profile")

# Create another tunnel route with endpoint group overlapped with route1
vnet_obj.fetch_exist_entries(dvs)
Expand All @@ -2029,15 +2038,15 @@ def test_vnet_orch_12(self, dvs, testlog):

route1, nhg1_1 = vnet_obj.check_vnet_ecmp_routes(dvs, 'Vnet12', ['12.0.0.1'], tunnel_name, route_ids=route1, nhg=nhg1_1)
check_state_db_routes(dvs, 'Vnet12', "100.100.1.1/32", ['12.0.0.1'])
check_routes_advertisement(dvs, "100.100.1.1/32")
check_routes_advertisement(dvs, "100.100.1.1/32", "test_profile")

# Set the route1 to a new group
set_vnet_routes(dvs, "100.100.1.1/32", 'Vnet12', '12.0.0.1,12.0.0.2,12.0.0.3,12.0.0.4', ep_monitor='12.1.0.1,12.1.0.2,12.1.0.3,12.1.0.4')
set_vnet_routes(dvs, "100.100.1.1/32", 'Vnet12', '12.0.0.1,12.0.0.2,12.0.0.3,12.0.0.4', ep_monitor='12.1.0.1,12.1.0.2,12.1.0.3,12.1.0.4', profile="test_profile2")
update_bfd_session_state(dvs, '12.1.0.4', 'Up')
time.sleep(2)
route1, nhg1_2 = vnet_obj.check_vnet_ecmp_routes(dvs, 'Vnet12', ['12.0.0.1', '12.0.0.4'], tunnel_name, route_ids=route1)
check_state_db_routes(dvs, 'Vnet12', "100.100.1.1/32", ['12.0.0.1', '12.0.0.4'])
check_routes_advertisement(dvs, "100.100.1.1/32")
check_routes_advertisement(dvs, "100.100.1.1/32", "test_profile2")

# Check the previous nexthop group is removed
vnet_obj.fetch_exist_entries(dvs)
Expand All @@ -2048,7 +2057,7 @@ def test_vnet_orch_12(self, dvs, testlog):
time.sleep(2)
route1, nhg1_2 = vnet_obj.check_vnet_ecmp_routes(dvs, 'Vnet12', ['12.0.0.1', '12.0.0.2', '12.0.0.4'], tunnel_name, route_ids=route1, nhg=nhg1_2)
check_state_db_routes(dvs, 'Vnet12', "100.100.1.1/32", ['12.0.0.1', '12.0.0.2', '12.0.0.4'])
check_routes_advertisement(dvs, "100.100.1.1/32")
check_routes_advertisement(dvs, "100.100.1.1/32", "test_profile2")

# Set all endpoint to down state
update_bfd_session_state(dvs, '12.1.0.1', 'Down')
Expand Down