Skip to content

Commit 8541200

Browse files
authored
[vnetorch] missing handling of rx and tx interval of monitoring session (sonic-net#3878)
What I did Adding rx_monitor_timer and tx_monitor_timer handling per HLD: https://github.com/sonic-net/SONiC/blob/master/doc/vxlan/Overlay%20ECMP%20ehancements.md sign-off: Jing Zhang zhangjing@microsoft.com Why I did it It's needed for SSW HA scenario as DPU side bfd is a software solution, interval must be set to a reasonable value.
1 parent 46daad0 commit 8541200

4 files changed

Lines changed: 108 additions & 19 deletions

File tree

orchagent/vnetorch.cpp

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,8 @@ bool VNetRouteOrch::selectNextHopGroup(const string& vnet,
10151015
NextHopGroupKey& nexthops_primary,
10161016
NextHopGroupKey& nexthops_secondary,
10171017
const string& monitoring,
1018+
const int32_t rx_monitor_timer,
1019+
const int32_t tx_monitor_timer,
10181020
IpPrefix& ipPrefix,
10191021
VNetVrfObject *vrf_obj,
10201022
NextHopGroupKey& nexthops_selected,
@@ -1033,18 +1035,18 @@ bool VNetRouteOrch::selectNextHopGroup(const string& vnet,
10331035
auto it_route = syncd_tunnel_routes_[vnet].find(ipPrefix);
10341036
if (it_route == syncd_tunnel_routes_[vnet].end())
10351037
{
1036-
setEndpointMonitor(vnet, monitors, nexthops_primary, monitoring, ipPrefix);
1037-
setEndpointMonitor(vnet, monitors, nexthops_secondary, monitoring, ipPrefix);
1038+
setEndpointMonitor(vnet, monitors, nexthops_primary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix);
1039+
setEndpointMonitor(vnet, monitors, nexthops_secondary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix);
10381040
}
10391041
else
10401042
{
10411043
if (it_route->second.primary != nexthops_primary)
10421044
{
1043-
setEndpointMonitor(vnet, monitors, nexthops_primary, monitoring, ipPrefix);
1045+
setEndpointMonitor(vnet, monitors, nexthops_primary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix);
10441046
}
10451047
if (it_route->second.secondary != nexthops_secondary)
10461048
{
1047-
setEndpointMonitor(vnet, monitors, nexthops_secondary, monitoring, ipPrefix);
1049+
setEndpointMonitor(vnet, monitors, nexthops_secondary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix);
10481050
}
10491051
nexthops_selected = it_route->second.nhg_key;
10501052
return true;
@@ -1103,7 +1105,7 @@ bool VNetRouteOrch::selectNextHopGroup(const string& vnet,
11031105
else if (!hasNextHopGroup(vnet, nexthops_primary))
11041106
{
11051107
SWSS_LOG_INFO("Creating next hop group %s", nexthops_primary.to_string().c_str());
1106-
setEndpointMonitor(vnet, monitors, nexthops_primary, monitoring, ipPrefix);
1108+
setEndpointMonitor(vnet, monitors, nexthops_primary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix);
11071109
if (!createNextHopGroup(vnet, nexthops_primary, vrf_obj, monitoring))
11081110
{
11091111
delEndpointMonitor(vnet, nexthops_primary, ipPrefix);
@@ -1117,7 +1119,10 @@ bool VNetRouteOrch::selectNextHopGroup(const string& vnet,
11171119
template<>
11181120
bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipPrefix,
11191121
NextHopGroupKey& nexthops, string& op, string& profile,
1120-
const string& monitoring, NextHopGroupKey& nexthops_secondary,
1122+
const string& monitoring,
1123+
const int32_t rx_monitor_timer,
1124+
const int32_t tx_monitor_timer,
1125+
NextHopGroupKey& nexthops_secondary,
11211126
const IpPrefix& adv_prefix,
11221127
const map<NextHopKey, IpAddress>& monitors)
11231128
{
@@ -1158,7 +1163,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
11581163
{
11591164
sai_object_id_t nh_id = SAI_NULL_OBJECT_ID;
11601165
NextHopGroupKey active_nhg("", true);
1161-
if (!selectNextHopGroup(vnet, nexthops, nexthops_secondary, monitoring, ipPrefix, vrf_obj, active_nhg, monitors))
1166+
if (!selectNextHopGroup(vnet, nexthops, nexthops_secondary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix, vrf_obj, active_nhg, monitors))
11621167
{
11631168
return true;
11641169
}
@@ -1981,7 +1986,7 @@ void VNetRouteOrch::delRoute(const IpPrefix& ipPrefix)
19811986
syncd_routes_.erase(route_itr);
19821987
}
19831988

1984-
void VNetRouteOrch::createBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& monitor_addr)
1989+
void VNetRouteOrch::createBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& monitor_addr, const int32_t rx_monitor_timer, const int32_t tx_monitor_timer)
19851990
{
19861991
SWSS_LOG_ENTER();
19871992

@@ -2012,6 +2017,19 @@ void VNetRouteOrch::createBfdSession(const string& vnet, const NextHopKey& endpo
20122017
// when the device goes into TSA. The following parameter ensures that these session are
20132018
// brought down while transitioning to TSA and brought back up when transitioning to TSB.
20142019
data.emplace_back("shutdown_bfd_during_tsa", "true");
2020+
2021+
if (rx_monitor_timer >= 0)
2022+
{
2023+
FieldValueTuple fv_rx("rx_interval", to_string(rx_monitor_timer));
2024+
data.push_back(fv_rx);
2025+
}
2026+
2027+
if (tx_monitor_timer >= 0)
2028+
{
2029+
FieldValueTuple fv_tx("tx_interval", to_string(tx_monitor_timer));
2030+
data.push_back(fv_tx);
2031+
}
2032+
20152033
bfd_session_producer_.set(key, data);
20162034
bfd_sessions_[monitor_addr].bfd_state = SAI_BFD_SESSION_STATE_DOWN;
20172035
}
@@ -2116,7 +2134,7 @@ void VNetRouteOrch::removeMonitoringSession(const string& vnet, const NextHopKey
21162134
monitor_info_[vnet][ipPrefix].erase(monitor_addr);
21172135
}
21182136

2119-
void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops, const string& monitoring, IpPrefix& ipPrefix)
2137+
void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops, const string& monitoring, const int32_t rx_monitor_timer, const int32_t tx_monitor_timer, IpPrefix& ipPrefix)
21202138
{
21212139
SWSS_LOG_ENTER();
21222140

@@ -2145,7 +2163,7 @@ void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map<NextHopKey,
21452163
{
21462164
if (nexthop_info_[vnet].find(nh.ip_address) == nexthop_info_[vnet].end())
21472165
{
2148-
createBfdSession(vnet, nh, monitor_ip);
2166+
createBfdSession(vnet, nh, monitor_ip, rx_monitor_timer, tx_monitor_timer);
21492167
}
21502168
nexthop_info_[vnet][nh.ip_address].ref_count++;
21512169
}
@@ -2863,6 +2881,8 @@ bool VNetRouteOrch::handleTunnel(const Request& request)
28632881
vector<IpAddress> primary_list;
28642882
vector<IpAddress> secondary_list;
28652883
string monitoring;
2884+
int32_t rx_monitor_timer = -1;
2885+
int32_t tx_monitor_timer = -1;
28662886
swss::IpPrefix adv_prefix;
28672887
bool has_priority_ep = false;
28682888
bool has_adv_pfx = false;
@@ -2908,6 +2928,14 @@ bool VNetRouteOrch::handleTunnel(const Request& request)
29082928
{
29092929
check_directly_connected = request.getAttrBool(name);
29102930
}
2931+
else if (name == "rx_monitor_timer")
2932+
{
2933+
rx_monitor_timer = static_cast<int32_t>(request.getAttrUint(name));
2934+
}
2935+
else if (name == "tx_monitor_timer")
2936+
{
2937+
tx_monitor_timer = static_cast<int32_t>(request.getAttrUint(name));
2938+
}
29112939
else
29122940
{
29132941
SWSS_LOG_INFO("Unknown attribute: %s", name.c_str());
@@ -3043,7 +3071,7 @@ bool VNetRouteOrch::handleTunnel(const Request& request)
30433071
}
30443072
if (vnet_orch_->isVnetExecVrf())
30453073
{
3046-
return doRouteTask<VNetVrfObject>(vnet_name, ip_pfx, (has_priority_ep == true) ? nhg_primary : nhg, op, profile, monitoring, nhg_secondary, adv_prefix, monitors);
3074+
return doRouteTask<VNetVrfObject>(vnet_name, ip_pfx, (has_priority_ep == true) ? nhg_primary : nhg, op, profile, monitoring, rx_monitor_timer, tx_monitor_timer, nhg_secondary, adv_prefix, monitors);
30473075
}
30483076

30493077
return true;

orchagent/vnetorch.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ const request_description_t vnet_route_description = {
311311
{ "monitoring", REQ_T_STRING },
312312
{ "adv_prefix", REQ_T_IP_PREFIX },
313313
{ "check_directly_connected", REQ_T_BOOL },
314+
{ "rx_monitor_timer", REQ_T_UINT },
315+
{ "tx_monitor_timer", REQ_T_UINT },
314316
},
315317
{ }
316318
};
@@ -479,16 +481,17 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer
479481
const string& monitoring);
480482
NextHopGroupKey getActiveNHSet(const string&, NextHopGroupKey&, const IpPrefix& );
481483

482-
bool selectNextHopGroup(const string&, NextHopGroupKey&, NextHopGroupKey&, const string&, IpPrefix&,
484+
bool selectNextHopGroup(const string&, NextHopGroupKey&, NextHopGroupKey&, const string&, const int32_t, const int32_t, IpPrefix&,
483485
VNetVrfObject *vrf_obj, NextHopGroupKey&,
484486
const std::map<NextHopKey,IpAddress>& monitors=std::map<NextHopKey, IpAddress>());
485487

486-
void createBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr);
488+
void createBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr, const int32_t rx_monitor_timer, const int32_t tx_monitor_timer);
487489
void removeBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr);
488490
void createMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr, IpPrefix& ipPrefix);
489491
void removeMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr, IpPrefix& ipPrefix);
490492
void setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops,
491-
const string& monitoring, IpPrefix& ipPrefix);
493+
const string& monitoring, const int32_t rx_monitor_timer, const int32_t tx_monitor_timer,
494+
IpPrefix& ipPrefix);
492495
void delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops, IpPrefix& ipPrefix);
493496
void postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& profile);
494497
void removeRouteState(const string& vnet, IpPrefix& ipPrefix);
@@ -506,7 +509,8 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer
506509

507510
template<typename T>
508511
bool doRouteTask(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& op, string& profile,
509-
const string& monitoring, NextHopGroupKey& nexthops_secondary, const IpPrefix& adv_prefix,
512+
const string& monitoring, const int32_t rx_monitor_timer, const int32_t tx_monitor_timer,
513+
NextHopGroupKey& nexthops_secondary, const IpPrefix& adv_prefix,
510514
const std::map<NextHopKey, IpAddress>& monitors=std::map<NextHopKey, IpAddress>());
511515

512516
template<typename T>

tests/test_vnet.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3112,7 +3112,58 @@ def test_vnet_local_route_ecmp(self, dvs, testlog):
31123112
delete_vxlan_tunnel(dvs, tunnel_name)
31133113
vnet_obj.check_del_vxlan_tunnel(dvs)
31143114

3115+
'''
3116+
Test 32 - Test for priority vnet tunnel routes with local endpoint + bfd monitoring + rx and tx timer.
3117+
'''
3118+
def test_vnet_orch_30(self, dvs, dvs_acl, testlog):
3119+
self.setup_db(dvs)
3120+
self.clear_srv_config(dvs)
3121+
3122+
vnet_obj = self.get_vnet_obj()
3123+
tunnel_name = 'tunnel_32'
3124+
vnet_name = 'Vnet32'
3125+
asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0)
3126+
3127+
vnet_obj.fetch_exist_entries(dvs)
3128+
3129+
create_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9')
3130+
create_vnet_entry(dvs, vnet_name, tunnel_name, '10028', "", advertise_prefix=True, overlay_dmac="22:33:33:44:44:66")
3131+
3132+
vnet_obj.check_vnet_entry(dvs, vnet_name)
3133+
vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, vnet_name, '10028')
3134+
vnet_obj.check_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9')
3135+
3136+
# create l3 interface
3137+
self.create_l3_intf("Ethernet8", "")
3138+
3139+
# set ip address
3140+
self.add_ip_address("Ethernet8", "9.1.0.1/32")
3141+
3142+
# bring up interface
3143+
self.set_admin_status("Ethernet8", "up")
3144+
3145+
# add neighbor for directly connected endpoint
3146+
self.add_neighbor("Ethernet8", "9.1.0.1", "00:01:02:03:04:05")
3147+
3148+
vnet_obj.fetch_exist_entries(dvs)
3149+
create_vnet_routes(dvs, "100.100.1.1/32", vnet_name, '9.1.0.1,9.1.0.2', ep_monitor='9.1.0.1,9.1.0.2', primary ='9.1.0.1', profile="Test_profile", monitoring='', rx_monitor_timer=100, tx_monitor_timer=100, adv_prefix='100.100.1.0/24', check_directly_connected=True)
3150+
3151+
# Remove tunnel route 1
3152+
delete_vnet_routes(dvs, "100.100.1.1/32", vnet_name)
3153+
3154+
vnet_obj.check_del_vnet_routes(dvs, vnet_name, ["100.100.1.1/32"])
3155+
check_remove_state_db_routes(dvs, vnet_name, "100.100.1.1/32")
3156+
check_remove_routes_advertisement(dvs, "100.100.1.0/24")
3157+
3158+
delete_vnet_entry(dvs, vnet_name)
3159+
vnet_obj.check_del_vnet_entry(dvs, vnet_name)
3160+
delete_vxlan_tunnel(dvs, tunnel_name)
3161+
3162+
self.remove_neighbor("Ethernet8", "9.1.0.1")
3163+
self.remove_ip_address("Ethernet8", "9.1.0.1/32")
3164+
self.set_admin_status("Ethernet8", "down")
3165+
31153166
# Add Dummy always-pass test at end as workaroud
31163167
# for issue when Flaky fail on final test it invokes module tear-down before retrying
31173168
def test_nonflaky_dummy():
3118-
pass
3169+
pass

tests/vnet_lib.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ def delete_vnet_local_routes(dvs, prefix, vnet_name):
140140
time.sleep(2)
141141

142142

143-
def create_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile="", primary="", monitoring="", adv_prefix="", check_directly_connected=False):
144-
set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac=mac, vni=vni, ep_monitor=ep_monitor, profile=profile, primary=primary, monitoring=monitoring, adv_prefix=adv_prefix, check_directly_connected=check_directly_connected)
143+
def create_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile="", primary="", monitoring="", rx_monitor_timer=-1, tx_monitor_timer=-1, adv_prefix="", check_directly_connected=False):
144+
set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac=mac, vni=vni, ep_monitor=ep_monitor, profile=profile, primary=primary, monitoring=monitoring, rx_monitor_timer=rx_monitor_timer, tx_monitor_timer=tx_monitor_timer, adv_prefix=adv_prefix, check_directly_connected=check_directly_connected)
145145

146146

147-
def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile="", primary="", monitoring="", adv_prefix="", check_directly_connected=False):
147+
def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile="", primary="", monitoring="", rx_monitor_timer=-1, tx_monitor_timer=-1, adv_prefix="", check_directly_connected=False):
148148
conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0)
149149

150150
attrs = [
@@ -175,6 +175,12 @@ def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor=
175175
if check_directly_connected:
176176
attrs.append(('check_directly_connected', 'true'))
177177

178+
if rx_monitor_timer != -1:
179+
attrs.append(('rx_monitor_timer', str(rx_monitor_timer)))
180+
181+
if tx_monitor_timer != -1:
182+
attrs.append(('tx_monitor_timer', str(tx_monitor_timer)))
183+
178184
tbl = swsscommon.Table(conf_db, "VNET_ROUTE_TUNNEL")
179185
fvs = swsscommon.FieldValuePairs(attrs)
180186
tbl.set("%s|%s" % (vnet_name, prefix), fvs)

0 commit comments

Comments
 (0)