Skip to content

Commit c54b3d1

Browse files
authored
Vxlan tunnel endpoint custom monitoring APPL DB table. (#2589)
* added support for monitoring, primary and adv_prefix. changed filter_mac to overlay_dmac * Data Structures and code to write APP_DB VNET_MONITOR table entries for custom monitoring of Vxlan tunnel endpoints.
1 parent 7f03db2 commit c54b3d1

File tree

3 files changed

+169
-20
lines changed

3 files changed

+169
-20
lines changed

orchagent/vnetorch.cpp

+98-15
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,11 @@ VNetRouteOrch::VNetRouteOrch(DBConnector *db, vector<string> &tableNames, VNetOr
720720
handler_map_.insert(handler_pair(APP_VNET_RT_TUNNEL_TABLE_NAME, &VNetRouteOrch::handleTunnel));
721721

722722
state_db_ = shared_ptr<DBConnector>(new DBConnector("STATE_DB", 0));
723+
app_db_ = shared_ptr<DBConnector>(new DBConnector("APPL_DB", 0));
724+
723725
state_vnet_rt_tunnel_table_ = unique_ptr<Table>(new Table(state_db_.get(), STATE_VNET_RT_TUNNEL_TABLE_NAME));
724726
state_vnet_rt_adv_table_ = unique_ptr<Table>(new Table(state_db_.get(), STATE_ADVERTISE_NETWORK_TABLE_NAME));
727+
monitor_session_producer_ = unique_ptr<Table>(new Table(app_db_.get(), APP_VNET_MONITOR_TABLE_NAME));
725728

726729
gBfdOrch->attach(this);
727730
}
@@ -900,6 +903,7 @@ bool VNetRouteOrch::removeNextHopGroup(const string& vnet, const NextHopGroupKey
900903
template<>
901904
bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipPrefix,
902905
NextHopGroupKey& nexthops, string& op, string& profile,
906+
const string& monitoring,
903907
const map<NextHopKey, IpAddress>& monitors)
904908
{
905909
SWSS_LOG_ENTER();
@@ -940,7 +944,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
940944
sai_object_id_t nh_id;
941945
if (!hasNextHopGroup(vnet, nexthops))
942946
{
943-
setEndpointMonitor(vnet, monitors, nexthops);
947+
setEndpointMonitor(vnet, monitors, nexthops, monitoring, ipPrefix);
944948
if (nexthops.getSize() == 1)
945949
{
946950
NextHopKey nexthop(nexthops.to_string(), true);
@@ -957,7 +961,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
957961
{
958962
if (!addNextHopGroup(vnet, nexthops, vrf_obj))
959963
{
960-
delEndpointMonitor(vnet, nexthops);
964+
delEndpointMonitor(vnet, nexthops, ipPrefix);
961965
SWSS_LOG_ERROR("Failed to create next hop group %s", nexthops.to_string().c_str());
962966
return false;
963967
}
@@ -1031,7 +1035,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
10311035
NextHopKey nexthop(nhg.to_string(), true);
10321036
vrf_obj->removeTunnelNextHop(nexthop);
10331037
}
1034-
delEndpointMonitor(vnet, nhg);
1038+
delEndpointMonitor(vnet, nhg, ipPrefix);
10351039
}
10361040
else
10371041
{
@@ -1091,7 +1095,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
10911095
NextHopKey nexthop(nhg.to_string(), true);
10921096
vrf_obj->removeTunnelNextHop(nexthop);
10931097
}
1094-
delEndpointMonitor(vnet, nhg);
1098+
delEndpointMonitor(vnet, nhg, ipPrefix);
10951099
}
10961100
else
10971101
{
@@ -1609,39 +1613,118 @@ void VNetRouteOrch::removeBfdSession(const string& vnet, const NextHopKey& endpo
16091613
bfd_sessions_.erase(monitor_addr);
16101614
}
16111615

1612-
void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops)
1616+
void VNetRouteOrch::createMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& monitor_addr, IpPrefix& ipPrefix)
1617+
{
1618+
SWSS_LOG_ENTER();
1619+
1620+
IpAddress endpoint_addr = endpoint.ip_address;
1621+
if (monitor_info_[vnet].find(ipPrefix) != monitor_info_[vnet].end() &&
1622+
monitor_info_[vnet][ipPrefix].find(endpoint) != monitor_info_[vnet][ipPrefix].end())
1623+
{
1624+
SWSS_LOG_NOTICE("Monitoring session for prefix %s endpoint %s already exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str());
1625+
return;
1626+
}
1627+
else
1628+
{
1629+
vector<FieldValueTuple> data;
1630+
auto *vnet_obj = vnet_orch_->getTypePtr<VNetVrfObject>(vnet);
1631+
1632+
auto overlay_dmac = vnet_obj->getOverlayDMac();
1633+
string key = ipPrefix.to_string() + ":" + monitor_addr.to_string();
1634+
FieldValueTuple fvTuple1("packet_type", "vxlan");
1635+
data.push_back(fvTuple1);
1636+
1637+
FieldValueTuple fvTuple3("overlay_dmac", overlay_dmac.to_string());
1638+
data.push_back(fvTuple3);
1639+
1640+
monitor_session_producer_->set(key, data);
1641+
1642+
MonitorSessionInfo& info = monitor_info_[vnet][ipPrefix][endpoint];
1643+
info.monitor = monitor_addr;
1644+
info.state = MONITOR_SESSION_STATE::MONITOR_SESSION_STATE_DOWN;
1645+
}
1646+
}
1647+
1648+
void VNetRouteOrch::removeMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& monitor_addr, IpPrefix& ipPrefix)
1649+
{
1650+
SWSS_LOG_ENTER();
1651+
1652+
IpAddress endpoint_addr = endpoint.ip_address;
1653+
if (monitor_info_[vnet].find(ipPrefix) == monitor_info_[vnet].end() ||
1654+
monitor_info_[vnet][ipPrefix].find(endpoint) == monitor_info_[vnet][ipPrefix].end())
1655+
{
1656+
SWSS_LOG_NOTICE("Monitor session for prefix %s endpoint %s does not exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str());
1657+
}
1658+
1659+
string key = ipPrefix.to_string() + ":" + monitor_addr.to_string();
1660+
monitor_session_producer_->del(key);
1661+
monitor_info_[vnet][ipPrefix].erase(endpoint);
1662+
}
1663+
1664+
void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops, const string& monitoring, IpPrefix& ipPrefix)
16131665
{
16141666
SWSS_LOG_ENTER();
16151667

16161668
for (auto monitor : monitors)
16171669
{
16181670
NextHopKey nh = monitor.first;
16191671
IpAddress monitor_ip = monitor.second;
1620-
if (nexthop_info_[vnet].find(nh.ip_address) == nexthop_info_[vnet].end())
1672+
if (monitoring == "custom")
16211673
{
1622-
createBfdSession(vnet, nh, monitor_ip);
1674+
if (monitor_info_[vnet].find(ipPrefix) == monitor_info_[vnet].end() ||
1675+
monitor_info_[vnet][ipPrefix].find(nh) == monitor_info_[vnet][ipPrefix].end())
1676+
{
1677+
createMonitoringSession(vnet, nh, monitor_ip, ipPrefix);
1678+
}
1679+
}
1680+
else
1681+
{
1682+
if (nexthop_info_[vnet].find(nh.ip_address) == nexthop_info_[vnet].end())
1683+
{
1684+
createBfdSession(vnet, nh, monitor_ip);
1685+
}
1686+
nexthop_info_[vnet][nh.ip_address].ref_count++;
16231687
}
1624-
1625-
nexthop_info_[vnet][nh.ip_address].ref_count++;
16261688
}
16271689
}
16281690

1629-
void VNetRouteOrch::delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops)
1691+
void VNetRouteOrch::delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops, IpPrefix& ipPrefix)
16301692
{
16311693
SWSS_LOG_ENTER();
16321694

16331695
std::set<NextHopKey> nhks = nexthops.getNextHops();
1696+
bool is_custom_monitoring = false;
1697+
if (monitor_info_[vnet].find(ipPrefix) != monitor_info_[vnet].end())
1698+
{
1699+
is_custom_monitoring = true;
1700+
}
16341701
for (auto nhk: nhks)
16351702
{
16361703
IpAddress ip = nhk.ip_address;
1637-
if (nexthop_info_[vnet].find(ip) != nexthop_info_[vnet].end()) {
1638-
if (--nexthop_info_[vnet][ip].ref_count == 0)
1704+
if (is_custom_monitoring)
1705+
{
1706+
if ( monitor_info_[vnet][ipPrefix].find(nhk) != monitor_info_[vnet][ipPrefix].end())
16391707
{
1640-
IpAddress monitor_addr = nexthop_info_[vnet][ip].monitor_addr;
1641-
removeBfdSession(vnet, nhk, monitor_addr);
1708+
removeMonitoringSession(vnet, nhk, monitor_info_[vnet][ipPrefix][nhk].monitor, ipPrefix);
1709+
}
1710+
}
1711+
else
1712+
{
1713+
if (nexthop_info_[vnet].find(ip) != nexthop_info_[vnet].end()) {
1714+
if (--nexthop_info_[vnet][ip].ref_count == 0)
1715+
{
1716+
IpAddress monitor_addr = nexthop_info_[vnet][ip].monitor_addr;
1717+
{
1718+
removeBfdSession(vnet, nhk, monitor_addr);
1719+
}
1720+
}
16421721
}
16431722
}
16441723
}
1724+
if (is_custom_monitoring)
1725+
{
1726+
monitor_info_[vnet].erase(ipPrefix);
1727+
}
16451728
}
16461729

16471730
void VNetRouteOrch::postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& profile)
@@ -2024,7 +2107,7 @@ bool VNetRouteOrch::handleTunnel(const Request& request)
20242107

20252108
if (vnet_orch_->isVnetExecVrf())
20262109
{
2027-
return doRouteTask<VNetVrfObject>(vnet_name, ip_pfx, nhg, op, profile, monitors);
2110+
return doRouteTask<VNetVrfObject>(vnet_name, ip_pfx, nhg, op, profile, monitoring, monitors);
20282111
}
20292112

20302113
return true;

orchagent/vnetorch.h

+22-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424

2525
extern sai_object_id_t gVirtualRouterId;
2626

27+
enum class MONITOR_SESSION_STATE
28+
{
29+
MONITOR_SESSION_STATE_UP,
30+
MONITOR_SESSION_STATE_DOWN,
31+
MONITOR_SESSION_STATE_UNKNOWN,
32+
};
2733
const request_description_t vnet_request_description = {
2834
{ REQ_T_STRING },
2935
{
@@ -339,9 +345,16 @@ struct BfdSessionInfo
339345
NextHopKey endpoint;
340346
};
341347

348+
struct MonitorSessionInfo
349+
{
350+
MONITOR_SESSION_STATE state;
351+
IpAddress monitor;
352+
};
353+
342354
typedef std::map<NextHopGroupKey, NextHopGroupInfo> VNetNextHopGroupInfoTable;
343355
typedef std::map<IpPrefix, NextHopGroupKey> VNetTunnelRouteTable;
344356
typedef std::map<IpAddress, BfdSessionInfo> BfdSessionTable;
357+
typedef std::map<IpPrefix, std::map<NextHopKey, MonitorSessionInfo>> MonitorSessionTable;
345358
typedef std::map<IpAddress, VNetNextHopInfo> VNetEndpointInfoTable;
346359

347360
class VNetRouteOrch : public Orch2, public Subject, public Observer
@@ -374,8 +387,11 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer
374387

375388
void createBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr);
376389
void removeBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr);
377-
void setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops);
378-
void delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops);
390+
void createMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr, IpPrefix& ipPrefix);
391+
void removeMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr, IpPrefix& ipPrefix);
392+
void setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops,
393+
const string& monitoring, IpPrefix& ipPrefix);
394+
void delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops, IpPrefix& ipPrefix);
379395
void postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& profile);
380396
void removeRouteState(const string& vnet, IpPrefix& ipPrefix);
381397
void addRouteAdvertisement(IpPrefix& ipPrefix, string& profile);
@@ -386,6 +402,7 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer
386402

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

391408
template<typename T>
@@ -400,9 +417,12 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer
400417
std::map<std::string, VNetNextHopGroupInfoTable> syncd_nexthop_groups_;
401418
std::map<std::string, VNetTunnelRouteTable> syncd_tunnel_routes_;
402419
BfdSessionTable bfd_sessions_;
420+
std::map<std::string, MonitorSessionTable> monitor_info_;
403421
std::map<std::string, VNetEndpointInfoTable> nexthop_info_;
404422
ProducerStateTable bfd_session_producer_;
423+
unique_ptr<Table> monitor_session_producer_;
405424
shared_ptr<DBConnector> state_db_;
425+
shared_ptr<DBConnector> app_db_;
406426
unique_ptr<Table> state_vnet_rt_tunnel_table_;
407427
unique_ptr<Table> state_vnet_rt_adv_table_;
408428
};

tests/test_vnet.py

+49-3
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ class VnetVxlanVrfTunnel(object):
546546
ASIC_NEXT_HOP_GROUP = "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP"
547547
ASIC_NEXT_HOP_GROUP_MEMBER = "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MEMBER"
548548
ASIC_BFD_SESSION = "ASIC_STATE:SAI_OBJECT_TYPE_BFD_SESSION"
549+
APP_VNET_MONITOR = "VNET_MONITOR_TABLE"
549550

550551
def __init__(self):
551552
self.tunnel_map_ids = set()
@@ -960,7 +961,21 @@ def _access_function():
960961

961962
return True
962963

963-
964+
def check_custom_monitor_app_db(self, dvs, prefix, endpoint, packet_type, overlay_dmac):
965+
app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)
966+
key = prefix + ':' + endpoint
967+
check_object(app_db, self.APP_VNET_MONITOR, key,
968+
{
969+
"packet_type": packet_type,
970+
"overlay_dmac" : overlay_dmac
971+
}
972+
)
973+
return True
974+
def check_custom_monitor_deleted(self, dvs, prefix, endpoint):
975+
app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)
976+
key = prefix + ':' + endpoint
977+
check_deleted_object(app_db, self.APP_VNET_MONITOR, key)
978+
964979
class TestVnetOrch(object):
965980

966981
def get_vnet_obj(self):
@@ -2376,15 +2391,15 @@ def test_vnet_orch_17(self, dvs, testlog):
23762391
vnet_obj.fetch_exist_entries(dvs)
23772392

23782393
create_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9')
2379-
create_vnet_entry(dvs, 'Vnet17', tunnel_name, '10009', "", overlay_dmac="22:33:33:44:44:66")
2394+
create_vnet_entry(dvs, 'Vnet17', tunnel_name, '10009', "")
23802395

23812396
vnet_obj.check_vnet_entry(dvs, 'Vnet17')
23822397
vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, 'Vnet17', '10009')
23832398

23842399
vnet_obj.check_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9')
23852400

23862401
vnet_obj.fetch_exist_entries(dvs)
2387-
create_vnet_routes(dvs, "100.100.1.1/32", 'Vnet17', '9.0.0.1,9.0.0.2,9.0.0.3', ep_monitor='9.1.0.1,9.1.0.2,9.1.0.3', primary ='9.0.0.1',monitoring='custom', adv_prefix='100.100.1.1/27')
2402+
create_vnet_routes(dvs, "100.100.1.1/32", 'Vnet17', '9.0.0.1,9.0.0.2,9.0.0.3', ep_monitor='9.1.0.1,9.1.0.2,9.1.0.3')
23882403

23892404
# default bfd status is down, route should not be programmed in this status
23902405
vnet_obj.check_del_vnet_routes(dvs, 'Vnet17', ["100.100.1.1/32"])
@@ -2432,6 +2447,37 @@ def test_vnet_orch_17(self, dvs, testlog):
24322447
delete_vnet_entry(dvs, 'Vnet17')
24332448
vnet_obj.check_del_vnet_entry(dvs, 'Vnet17')
24342449

2450+
'''
2451+
Test 18 - Test for vxlan custom monitoring config.
2452+
'''
2453+
def test_vnet_orch_18(self, dvs, testlog):
2454+
vnet_obj = self.get_vnet_obj()
2455+
2456+
tunnel_name = 'tunnel_18'
2457+
2458+
vnet_obj.fetch_exist_entries(dvs)
2459+
2460+
create_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9')
2461+
create_vnet_entry(dvs, 'Vnet18', tunnel_name, '10009', "", overlay_dmac="22:33:33:44:44:66")
2462+
2463+
vnet_obj.check_vnet_entry(dvs, 'Vnet18')
2464+
vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, 'Vnet18', '10009')
2465+
2466+
vnet_obj.check_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9')
2467+
2468+
vnet_obj.fetch_exist_entries(dvs)
2469+
create_vnet_routes(dvs, "100.100.1.1/32", 'Vnet18', '9.0.0.1,9.0.0.2,9.0.0.3', ep_monitor='9.1.0.1,9.1.0.2,9.1.0.3',primary ='9.0.0.1',monitoring='custom', adv_prefix='100.100.1.1/27')
2470+
2471+
vnet_obj.check_custom_monitor_app_db(dvs, "100.100.1.1/32", "9.1.0.1", "vxlan", "22:33:33:44:44:66")
2472+
vnet_obj.check_custom_monitor_app_db(dvs, "100.100.1.1/32", "9.1.0.2", "vxlan", "22:33:33:44:44:66")
2473+
vnet_obj.check_custom_monitor_app_db(dvs, "100.100.1.1/32", "9.1.0.3", "vxlan", "22:33:33:44:44:66")
2474+
2475+
delete_vnet_routes(dvs, "100.100.1.1/32", 'Vnet18')
2476+
2477+
vnet_obj.check_custom_monitor_deleted(dvs, "100.100.1.1/32", "9.1.0.1")
2478+
vnet_obj.check_custom_monitor_deleted(dvs, "100.100.1.1/32", "9.1.0.2")
2479+
vnet_obj.check_custom_monitor_deleted(dvs, "100.100.1.1/32", "9.1.0.3")
2480+
24352481
# Add Dummy always-pass test at end as workaroud
24362482
# for issue when Flaky fail on final test it invokes module tear-down before retrying
24372483
def test_nonflaky_dummy():

0 commit comments

Comments
 (0)