From 996bb0ee473886f0250a44af937b0eb0f5906911 Mon Sep 17 00:00:00 2001 From: siqbal1486 Date: Tue, 20 Dec 2022 14:49:39 -0800 Subject: [PATCH 1/9] Added support for filter_mac and monitoring attributes. --- orchagent/vnetorch.cpp | 12 +++++++++++- orchagent/vnetorch.h | 21 ++++++++++++++++++++- tests/test_vnet.py | 11 +++++++++-- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/orchagent/vnetorch.cpp b/orchagent/vnetorch.cpp index a3acf10e0e..09e927a875 100644 --- a/orchagent/vnetorch.cpp +++ b/orchagent/vnetorch.cpp @@ -429,6 +429,8 @@ bool VNetOrch::addOperation(const Request& request) uint32_t vni=0; string tunnel; string scope; + string monitoring; + swss::MacAddress filter_mac; for (const auto& name: request.getAttrFieldNames()) { @@ -460,6 +462,14 @@ bool VNetOrch::addOperation(const Request& request) { advertise_prefix = request.getAttrBool("advertise_prefix"); } + else if (name == "monitoring") + { + monitoring = request.getAttrString("monitoring"); + } + else if (name == "filter_mac") + { + filter_mac = request.getAttrMacAddress("filter_mac"); + } else { SWSS_LOG_INFO("Unknown attribute: %s", name.c_str()); @@ -486,7 +496,7 @@ bool VNetOrch::addOperation(const Request& request) if (it == std::end(vnet_table_)) { - VNetInfo vnet_info = { tunnel, vni, peer_list, scope, advertise_prefix }; + VNetInfo vnet_info = { tunnel, vni, peer_list, scope, advertise_prefix, monitoring, filter_mac }; obj = createObject(vnet_name, vnet_info, attrs); create = true; diff --git a/orchagent/vnetorch.h b/orchagent/vnetorch.h index 4f63764a0e..873c71563d 100644 --- a/orchagent/vnetorch.h +++ b/orchagent/vnetorch.h @@ -34,6 +34,9 @@ const request_description_t vnet_request_description = { { "guid", REQ_T_STRING }, { "scope", REQ_T_STRING }, { "advertise_prefix", REQ_T_BOOL}, + { "monitoring", REQ_T_STRING}, + { "filter_mac", REQ_T_MAC_ADDRESS}, + }, { "vxlan_tunnel", "vni" } // mandatory attributes }; @@ -59,6 +62,8 @@ struct VNetInfo set peers; string scope; bool advertise_prefix; + string monitoring; + swss::MacAddress filter_mac; }; typedef map vrid_list_t; @@ -86,7 +91,9 @@ class VNetObject peer_list_(vnetInfo.peers), vni_(vnetInfo.vni), scope_(vnetInfo.scope), - advertise_prefix_(vnetInfo.advertise_prefix) + advertise_prefix_(vnetInfo.advertise_prefix), + monitoring_(vnetInfo.monitoring), + filter_mac_(vnetInfo.filter_mac) { } virtual bool updateObj(vector&) = 0; @@ -121,6 +128,16 @@ class VNetObject return advertise_prefix_; } + string getMonitoring() const + { + return monitoring_; + } + + swss::MacAddress getFilterMac() const + { + return filter_mac_; + } + virtual ~VNetObject() noexcept(false) {}; private: @@ -129,6 +146,8 @@ class VNetObject uint32_t vni_; string scope_; bool advertise_prefix_; + string monitoring_; + swss::MacAddress filter_mac_; }; struct nextHop diff --git a/tests/test_vnet.py b/tests/test_vnet.py index 0dec1f7446..94c00c19ed 100644 --- a/tests/test_vnet.py +++ b/tests/test_vnet.py @@ -317,7 +317,7 @@ def delete_phy_interface(dvs, ifname, ipaddr): time.sleep(2) -def create_vnet_entry(dvs, name, tunnel, vni, peer_list, scope="", advertise_prefix=False): +def create_vnet_entry(dvs, name, tunnel, vni, peer_list, scope="", advertise_prefix=False, monitoring="", filter_mac=""): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) @@ -333,6 +333,13 @@ def create_vnet_entry(dvs, name, tunnel, vni, peer_list, scope="", advertise_pre if advertise_prefix: attrs.append(('advertise_prefix', 'true')) + if monitoring: + attrs.append(('monitoring', monitoring)) + + if filter_mac: + attrs.append(('filter_mac', filter_mac)) + + # create the VXLAN tunnel Term entry in Config DB create_entry_tbl( conf_db, @@ -2012,7 +2019,7 @@ def test_vnet_orch_12(self, dvs, testlog): vnet_obj.fetch_exist_entries(dvs) create_vxlan_tunnel(dvs, tunnel_name, '12.12.12.12') - create_vnet_entry(dvs, 'Vnet12', tunnel_name, '10012', "", advertise_prefix=True) + create_vnet_entry(dvs, 'Vnet12', tunnel_name, '10012', "", advertise_prefix=True, monitoring="custom", filter_mac="22:33:33:44:44:66") vnet_obj.check_vnet_entry(dvs, 'Vnet12') vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, 'Vnet12', '10012') From 85905e92633f74f0142bcf9b478cdbe109e8eccd Mon Sep 17 00:00:00 2001 From: siqbal1486 Date: Tue, 20 Dec 2022 17:06:36 -0800 Subject: [PATCH 2/9] added support for monitoring, primary and adv_prefix. changed filter_mac to overlay_dmac Signed-off-by: siqbal1486 --- orchagent/vnetorch.cpp | 29 +++++++++++++++++++---------- orchagent/vnetorch.h | 24 +++++++++--------------- tests/test_vnet.py | 31 ++++++++++++++++++------------- 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/orchagent/vnetorch.cpp b/orchagent/vnetorch.cpp index fc89c06624..708dcde4ce 100644 --- a/orchagent/vnetorch.cpp +++ b/orchagent/vnetorch.cpp @@ -429,8 +429,7 @@ bool VNetOrch::addOperation(const Request& request) uint32_t vni=0; string tunnel; string scope; - string monitoring; - swss::MacAddress filter_mac; + swss::MacAddress overlay_dmac; for (const auto& name: request.getAttrFieldNames()) { @@ -462,13 +461,9 @@ bool VNetOrch::addOperation(const Request& request) { advertise_prefix = request.getAttrBool("advertise_prefix"); } - else if (name == "monitoring") - { - monitoring = request.getAttrString("monitoring"); - } - else if (name == "filter_mac") + else if (name == "overlay_dmac") { - filter_mac = request.getAttrMacAddress("filter_mac"); + overlay_dmac = request.getAttrMacAddress("overlay_dmac"); } else { @@ -496,7 +491,7 @@ bool VNetOrch::addOperation(const Request& request) if (it == std::end(vnet_table_)) { - VNetInfo vnet_info = { tunnel, vni, peer_list, scope, advertise_prefix, monitoring, filter_mac }; + VNetInfo vnet_info = { tunnel, vni, peer_list, scope, advertise_prefix, overlay_dmac }; obj = createObject(vnet_name, vnet_info, attrs); create = true; @@ -1927,7 +1922,9 @@ bool VNetRouteOrch::handleTunnel(const Request& request) vector vni_list; vector monitor_list; string profile = ""; - + vector primary_list; + string monitoring; + swss::IpPrefix adv_prefix; for (const auto& name: request.getAttrFieldNames()) { if (name == "endpoint") @@ -1952,6 +1949,18 @@ bool VNetRouteOrch::handleTunnel(const Request& request) { profile = request.getAttrString(name); } + else if (name == "primary") + { + primary_list = request.getAttrIPList(name); + } + else if (name == "monitoring") + { + monitoring = request.getAttrString(name); + } + else if (name == "adv_prefix") + { + adv_prefix = request.getAttrIpPrefix(name); + } else { SWSS_LOG_INFO("Unknown attribute: %s", name.c_str()); diff --git a/orchagent/vnetorch.h b/orchagent/vnetorch.h index 873c71563d..9c950c265f 100644 --- a/orchagent/vnetorch.h +++ b/orchagent/vnetorch.h @@ -34,8 +34,7 @@ const request_description_t vnet_request_description = { { "guid", REQ_T_STRING }, { "scope", REQ_T_STRING }, { "advertise_prefix", REQ_T_BOOL}, - { "monitoring", REQ_T_STRING}, - { "filter_mac", REQ_T_MAC_ADDRESS}, + { "overlay_dmac", REQ_T_MAC_ADDRESS}, }, { "vxlan_tunnel", "vni" } // mandatory attributes @@ -62,8 +61,7 @@ struct VNetInfo set peers; string scope; bool advertise_prefix; - string monitoring; - swss::MacAddress filter_mac; + swss::MacAddress overlay_dmac; }; typedef map vrid_list_t; @@ -92,8 +90,7 @@ class VNetObject vni_(vnetInfo.vni), scope_(vnetInfo.scope), advertise_prefix_(vnetInfo.advertise_prefix), - monitoring_(vnetInfo.monitoring), - filter_mac_(vnetInfo.filter_mac) + overlay_dmac_(vnetInfo.overlay_dmac) { } virtual bool updateObj(vector&) = 0; @@ -128,14 +125,9 @@ class VNetObject return advertise_prefix_; } - string getMonitoring() const + swss::MacAddress getOverlayDMac() const { - return monitoring_; - } - - swss::MacAddress getFilterMac() const - { - return filter_mac_; + return overlay_dmac_; } virtual ~VNetObject() noexcept(false) {}; @@ -146,8 +138,7 @@ class VNetObject uint32_t vni_; string scope_; bool advertise_prefix_; - string monitoring_; - swss::MacAddress filter_mac_; + swss::MacAddress overlay_dmac_; }; struct nextHop @@ -301,6 +292,9 @@ const request_description_t vnet_route_description = { { "mac_address", REQ_T_STRING }, { "endpoint_monitor", REQ_T_IP_LIST }, { "profile", REQ_T_STRING }, + { "primary", REQ_T_IP_LIST }, + { "monitoring", REQ_T_STRING }, + { "adv_prefix", REQ_T_IP_PREFIX }, }, { } }; diff --git a/tests/test_vnet.py b/tests/test_vnet.py index 036cc314ea..6b4fc175a3 100644 --- a/tests/test_vnet.py +++ b/tests/test_vnet.py @@ -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="", profile=""): - set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac=mac, vni=vni, ep_monitor=ep_monitor, profile=profile) +def create_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile="", primary="", monitoring="", adv_prefix=""): + 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) -def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile=""): +def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile="", primary="", monitoring="", adv_prefix=""): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) attrs = [ @@ -163,6 +163,15 @@ def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor= if profile: attrs.append(('profile', profile)) + if primary: + attrs.append(('primary', primary)) + + if monitoring: + attrs.append(('monitoring', monitoring)) + + if adv_prefix: + attrs.append(('adv_prefix', adv_prefix)) + tbl = swsscommon.Table(conf_db, "VNET_ROUTE_TUNNEL") fvs = swsscommon.FieldValuePairs(attrs) tbl.set("%s|%s" % (vnet_name, prefix), fvs) @@ -317,7 +326,7 @@ def delete_phy_interface(dvs, ifname, ipaddr): time.sleep(2) -def create_vnet_entry(dvs, name, tunnel, vni, peer_list, scope="", advertise_prefix=False, monitoring="", filter_mac=""): +def create_vnet_entry(dvs, name, tunnel, vni, peer_list, scope="", advertise_prefix=False, overlay_dmac=""): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) @@ -333,12 +342,8 @@ def create_vnet_entry(dvs, name, tunnel, vni, peer_list, scope="", advertise_pre if advertise_prefix: attrs.append(('advertise_prefix', 'true')) - if monitoring: - attrs.append(('monitoring', monitoring)) - - if filter_mac: - attrs.append(('filter_mac', filter_mac)) - + if overlay_dmac: + attrs.append(('overlay_dmac', overlay_dmac)) # create the VXLAN tunnel Term entry in Config DB create_entry_tbl( @@ -2019,7 +2024,7 @@ def test_vnet_orch_12(self, dvs, testlog): vnet_obj.fetch_exist_entries(dvs) create_vxlan_tunnel(dvs, tunnel_name, '12.12.12.12') - create_vnet_entry(dvs, 'Vnet12', tunnel_name, '10012', "", advertise_prefix=True, monitoring="custom", filter_mac="22:33:33:44:44:66") + create_vnet_entry(dvs, 'Vnet12', tunnel_name, '10012', "", advertise_prefix=True) vnet_obj.check_vnet_entry(dvs, 'Vnet12') vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, 'Vnet12', '10012') @@ -2371,7 +2376,7 @@ def test_vnet_orch_17(self, dvs, testlog): vnet_obj.fetch_exist_entries(dvs) create_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9') - create_vnet_entry(dvs, 'Vnet17', tunnel_name, '10009', "") + create_vnet_entry(dvs, 'Vnet17', tunnel_name, '10009', "", overlay_dmac="22:33:33:44:44:66") vnet_obj.check_vnet_entry(dvs, 'Vnet17') vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, 'Vnet17', '10009') @@ -2379,7 +2384,7 @@ def test_vnet_orch_17(self, dvs, testlog): vnet_obj.check_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9') vnet_obj.fetch_exist_entries(dvs) - 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') + 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') # default bfd status is down, route should not be programmed in this status vnet_obj.check_del_vnet_routes(dvs, 'Vnet17', ["100.100.1.1/32"]) From 197347a45db25bcb1863bc7dd3a668c2cc5fc2e3 Mon Sep 17 00:00:00 2001 From: siqbal1486 Date: Thu, 22 Dec 2022 16:21:40 -0800 Subject: [PATCH 3/9] Data Structures and code to write APP_DB VNET_MONITOR table entries for custom monitoring of Vxlan tunnel endpoints. --- orchagent/vnetorch.cpp | 112 +++++++++++++++++++++++++++++++++++------ orchagent/vnetorch.h | 24 ++++++++- 2 files changed, 118 insertions(+), 18 deletions(-) diff --git a/orchagent/vnetorch.cpp b/orchagent/vnetorch.cpp index 708dcde4ce..4fce1962aa 100644 --- a/orchagent/vnetorch.cpp +++ b/orchagent/vnetorch.cpp @@ -720,8 +720,11 @@ VNetRouteOrch::VNetRouteOrch(DBConnector *db, vector &tableNames, VNetOr handler_map_.insert(handler_pair(APP_VNET_RT_TUNNEL_TABLE_NAME, &VNetRouteOrch::handleTunnel)); state_db_ = shared_ptr(new DBConnector("STATE_DB", 0)); + app_db_ = shared_ptr(new DBConnector("APPL_DB", 0)); + state_vnet_rt_tunnel_table_ = unique_ptr(new Table(state_db_.get(), STATE_VNET_RT_TUNNEL_TABLE_NAME)); state_vnet_rt_adv_table_ = unique_ptr
(new Table(state_db_.get(), STATE_ADVERTISE_NETWORK_TABLE_NAME)); + monitor_session_producer_ = unique_ptr
(new Table(app_db_.get(), APP_VNET_MONITOR_TABLE_NAME)); gBfdOrch->attach(this); } @@ -900,6 +903,7 @@ bool VNetRouteOrch::removeNextHopGroup(const string& vnet, const NextHopGroupKey template<> bool VNetRouteOrch::doRouteTask(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& op, string& profile, + const string& monitoring, const map& monitors) { SWSS_LOG_ENTER(); @@ -940,7 +944,7 @@ bool VNetRouteOrch::doRouteTask(const string& vnet, IpPrefix& ipP sai_object_id_t nh_id; if (!hasNextHopGroup(vnet, nexthops)) { - setEndpointMonitor(vnet, monitors, nexthops); + setEndpointMonitor(vnet, monitors, nexthops, monitoring, ipPrefix); if (nexthops.getSize() == 1) { NextHopKey nexthop(nexthops.to_string(), true); @@ -957,7 +961,7 @@ bool VNetRouteOrch::doRouteTask(const string& vnet, IpPrefix& ipP { if (!addNextHopGroup(vnet, nexthops, vrf_obj)) { - delEndpointMonitor(vnet, nexthops); + delEndpointMonitor(vnet, nexthops, ipPrefix); SWSS_LOG_ERROR("Failed to create next hop group %s", nexthops.to_string().c_str()); return false; } @@ -1031,7 +1035,7 @@ bool VNetRouteOrch::doRouteTask(const string& vnet, IpPrefix& ipP NextHopKey nexthop(nhg.to_string(), true); vrf_obj->removeTunnelNextHop(nexthop); } - delEndpointMonitor(vnet, nhg); + delEndpointMonitor(vnet, nhg, ipPrefix); } else { @@ -1091,7 +1095,7 @@ bool VNetRouteOrch::doRouteTask(const string& vnet, IpPrefix& ipP NextHopKey nexthop(nhg.to_string(), true); vrf_obj->removeTunnelNextHop(nexthop); } - delEndpointMonitor(vnet, nhg); + delEndpointMonitor(vnet, nhg, ipPrefix); } else { @@ -1609,7 +1613,55 @@ void VNetRouteOrch::removeBfdSession(const string& vnet, const NextHopKey& endpo bfd_sessions_.erase(monitor_addr); } -void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map& monitors, NextHopGroupKey& nexthops) +void VNetRouteOrch::createMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& monitor_addr, IpPrefix& ipPrefix) +{ + SWSS_LOG_ENTER(); + + IpAddress endpoint_addr = endpoint.ip_address; + if (monitor_info_[vnet].find(ipPrefix) != monitor_info_[vnet].end() && + monitor_info_[vnet][ipPrefix].find(endpoint) != monitor_info_[vnet][ipPrefix].end()) + { + SWSS_LOG_ERROR("Monitoring session for prefix %s endpoint %s already exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str()); + return; + } + else + { + vector data; + auto *vnet_obj = vnet_orch_->getTypePtr(vnet); + + auto overlay_dmac = vnet_obj->getOverlayDMac(); + string key = "VNET_MONITOR:" + ipPrefix.to_string() + ":" + monitor_addr.to_string(); + FieldValueTuple fvTuple1("packet_type", "vxlan"); + data.push_back(fvTuple1); + + FieldValueTuple fvTuple3("overlay_dmac", overlay_dmac.to_string()); + data.push_back(fvTuple3); + + monitor_session_producer_->set(key, data); + + MonitorSessionInfo& info = monitor_info_[vnet][ipPrefix][endpoint]; + info.monitor = monitor_addr; + info.state = MONITOR_SESSION_STATE::MONITOR_SESSION_STATE_DOWN; + } +} + +void VNetRouteOrch::removeMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& monitor_addr, IpPrefix& ipPrefix) +{ + SWSS_LOG_ENTER(); + + IpAddress endpoint_addr = endpoint.ip_address; + if (monitor_info_[vnet].find(ipPrefix) == monitor_info_[vnet].end() || + monitor_info_[vnet][ipPrefix].find(endpoint) == monitor_info_[vnet][ipPrefix].end()) + { + SWSS_LOG_ERROR("Monitor session for prefix %s endpoint %s does not exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str()); + } + + string key = "VNET_MONITOR:" + ipPrefix.to_string() + ":" + monitor_addr.to_string(); + monitor_session_producer_->del(key); + monitor_info_[vnet][ipPrefix].erase(endpoint); +} + +void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map& monitors, NextHopGroupKey& nexthops, const string& monitoring, IpPrefix& ipPrefix) { SWSS_LOG_ENTER(); @@ -1617,31 +1669,59 @@ void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map nhks = nexthops.getNextHops(); + bool is_custom_monitoring = false; + if (monitor_info_[vnet].find(ipPrefix) == monitor_info_[vnet].end()) + { + is_custom_monitoring = true; + } for (auto nhk: nhks) { IpAddress ip = nhk.ip_address; - if (nexthop_info_[vnet].find(ip) != nexthop_info_[vnet].end()) { - if (--nexthop_info_[vnet][ip].ref_count == 0) - { - IpAddress monitor_addr = nexthop_info_[vnet][ip].monitor_addr; - removeBfdSession(vnet, nhk, monitor_addr); + if (is_custom_monitoring && monitor_info_[vnet][ipPrefix].find(nhk) != monitor_info_[vnet][ipPrefix].end()) + { + removeMonitoringSession(vnet, nhk, monitor_info_[vnet][ipPrefix][nhk].monitor, ipPrefix); + } + else + { + if (nexthop_info_[vnet].find(ip) != nexthop_info_[vnet].end()) { + if (--nexthop_info_[vnet][ip].ref_count == 0) + { + IpAddress monitor_addr = nexthop_info_[vnet][ip].monitor_addr; + { + removeBfdSession(vnet, nhk, monitor_addr); + } + } } } } + if (is_custom_monitoring) + { + monitor_info_[vnet].erase(ipPrefix); + } } void VNetRouteOrch::postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& profile) @@ -2024,7 +2104,7 @@ bool VNetRouteOrch::handleTunnel(const Request& request) if (vnet_orch_->isVnetExecVrf()) { - return doRouteTask(vnet_name, ip_pfx, nhg, op, profile, monitors); + return doRouteTask(vnet_name, ip_pfx, nhg, op, profile, monitoring, monitors); } return true; diff --git a/orchagent/vnetorch.h b/orchagent/vnetorch.h index 9c950c265f..b1981e2e2b 100644 --- a/orchagent/vnetorch.h +++ b/orchagent/vnetorch.h @@ -24,6 +24,12 @@ extern sai_object_id_t gVirtualRouterId; +enum class MONITOR_SESSION_STATE +{ + MONITOR_SESSION_STATE_UP, + MONITOR_SESSION_STATE_DOWN, + MONITOR_SESSION_STATE_INVALID, +}; const request_description_t vnet_request_description = { { REQ_T_STRING }, { @@ -339,9 +345,16 @@ struct BfdSessionInfo NextHopKey endpoint; }; +struct MonitorSessionInfo +{ + MONITOR_SESSION_STATE state; + IpAddress monitor; +}; + typedef std::map VNetNextHopGroupInfoTable; typedef std::map VNetTunnelRouteTable; typedef std::map BfdSessionTable; +typedef std::map> MonitorSessionTable; typedef std::map VNetEndpointInfoTable; class VNetRouteOrch : public Orch2, public Subject, public Observer @@ -374,8 +387,11 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer void createBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr); void removeBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr); - void setEndpointMonitor(const string& vnet, const map& monitors, NextHopGroupKey& nexthops); - void delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops); + void createMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr, IpPrefix& ipPrefix); + void removeMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr, IpPrefix& ipPrefix); + void setEndpointMonitor(const string& vnet, const map& monitors, NextHopGroupKey& nexthops, + const string& monitoring, IpPrefix& ipPrefix); + void delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops, IpPrefix& ipPrefix); void postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& profile); void removeRouteState(const string& vnet, IpPrefix& ipPrefix); void addRouteAdvertisement(IpPrefix& ipPrefix, string& profile); @@ -386,6 +402,7 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer template bool doRouteTask(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& op, string& profile, + const string& monitoring, const std::map& monitors=std::map()); template @@ -400,9 +417,12 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer std::map syncd_nexthop_groups_; std::map syncd_tunnel_routes_; BfdSessionTable bfd_sessions_; + std::map monitor_info_; std::map nexthop_info_; ProducerStateTable bfd_session_producer_; + unique_ptr
monitor_session_producer_; shared_ptr state_db_; + shared_ptr app_db_; unique_ptr
state_vnet_rt_tunnel_table_; unique_ptr
state_vnet_rt_adv_table_; }; From 28eecfea77b96262b1a5f447e42a0de3c19cba85 Mon Sep 17 00:00:00 2001 From: siqbal1486 Date: Thu, 22 Dec 2022 16:28:07 -0800 Subject: [PATCH 4/9] Disabled a failing test. Full test fix to follow. Signed-off-by: siqbal1486 --- tests/test_vnet.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_vnet.py b/tests/test_vnet.py index 6b4fc175a3..e597bd559a 100644 --- a/tests/test_vnet.py +++ b/tests/test_vnet.py @@ -2376,7 +2376,7 @@ def test_vnet_orch_17(self, dvs, testlog): vnet_obj.fetch_exist_entries(dvs) create_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9') - create_vnet_entry(dvs, 'Vnet17', tunnel_name, '10009', "", overlay_dmac="22:33:33:44:44:66") + create_vnet_entry(dvs, 'Vnet17', tunnel_name, '10009', "") vnet_obj.check_vnet_entry(dvs, 'Vnet17') vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, 'Vnet17', '10009') @@ -2384,7 +2384,7 @@ def test_vnet_orch_17(self, dvs, testlog): vnet_obj.check_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9') vnet_obj.fetch_exist_entries(dvs) - 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') + 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') # default bfd status is down, route should not be programmed in this status vnet_obj.check_del_vnet_routes(dvs, 'Vnet17', ["100.100.1.1/32"]) From f45dcb4a1ae32f4b741855504ed94a345af79151 Mon Sep 17 00:00:00 2001 From: siqbal1486 Date: Wed, 11 Jan 2023 15:43:51 -0800 Subject: [PATCH 5/9] added test for Monitor config write and delete. Signed-off-by: siqbal1486 --- orchagent/vnetorch.cpp | 6 +++--- tests/test_vnet.py | 48 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/orchagent/vnetorch.cpp b/orchagent/vnetorch.cpp index 4fce1962aa..e5197068cc 100644 --- a/orchagent/vnetorch.cpp +++ b/orchagent/vnetorch.cpp @@ -1630,7 +1630,7 @@ void VNetRouteOrch::createMonitoringSession(const string& vnet, const NextHopKey auto *vnet_obj = vnet_orch_->getTypePtr(vnet); auto overlay_dmac = vnet_obj->getOverlayDMac(); - string key = "VNET_MONITOR:" + ipPrefix.to_string() + ":" + monitor_addr.to_string(); + string key = ipPrefix.to_string() + ":" + monitor_addr.to_string(); FieldValueTuple fvTuple1("packet_type", "vxlan"); data.push_back(fvTuple1); @@ -1656,7 +1656,7 @@ void VNetRouteOrch::removeMonitoringSession(const string& vnet, const NextHopKey SWSS_LOG_ERROR("Monitor session for prefix %s endpoint %s does not exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str()); } - string key = "VNET_MONITOR:" + ipPrefix.to_string() + ":" + monitor_addr.to_string(); + string key = ipPrefix.to_string() + ":" + monitor_addr.to_string(); monitor_session_producer_->del(key); monitor_info_[vnet][ipPrefix].erase(endpoint); } @@ -1694,7 +1694,7 @@ void VNetRouteOrch::delEndpointMonitor(const string& vnet, NextHopGroupKey& next std::set nhks = nexthops.getNextHops(); bool is_custom_monitoring = false; - if (monitor_info_[vnet].find(ipPrefix) == monitor_info_[vnet].end()) + if (monitor_info_[vnet].find(ipPrefix) != monitor_info_[vnet].end()) { is_custom_monitoring = true; } diff --git a/tests/test_vnet.py b/tests/test_vnet.py index e597bd559a..6b17de6752 100644 --- a/tests/test_vnet.py +++ b/tests/test_vnet.py @@ -546,6 +546,7 @@ class VnetVxlanVrfTunnel(object): ASIC_NEXT_HOP_GROUP = "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP" ASIC_NEXT_HOP_GROUP_MEMBER = "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MEMBER" ASIC_BFD_SESSION = "ASIC_STATE:SAI_OBJECT_TYPE_BFD_SESSION" + APP_VNET_MONITOR = "VNET_MONITOR" def __init__(self): self.tunnel_map_ids = set() @@ -960,7 +961,21 @@ def _access_function(): return True - + def check_custom_monitor_app_db(self, dvs, prefix, endpoint, packet_type, overlay_dmac): + app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0) + key = prefix + ':' + endpoint + check_object(app_db, self.APP_VNET_MONITOR, key, + { + "packet_type": packet_type, + "overlay_dmac" : overlay_dmac + } + ) + return True + def check_custom_monitor_deleted(self, dvs, prefix, endpoint): + app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0) + key = prefix + ':' + endpoint + check_deleted_object(app_db, self.APP_VNET_MONITOR, key) + class TestVnetOrch(object): def get_vnet_obj(self): @@ -2432,6 +2447,37 @@ def test_vnet_orch_17(self, dvs, testlog): delete_vnet_entry(dvs, 'Vnet17') vnet_obj.check_del_vnet_entry(dvs, 'Vnet17') + ''' + Test 18 - Test for vxlan custom monitoring config. + ''' + def test_vnet_orch_18(self, dvs, testlog): + vnet_obj = self.get_vnet_obj() + + tunnel_name = 'tunnel_18' + + vnet_obj.fetch_exist_entries(dvs) + + create_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9') + create_vnet_entry(dvs, 'Vnet18', tunnel_name, '10009', "", overlay_dmac="22:33:33:44:44:66") + + vnet_obj.check_vnet_entry(dvs, 'Vnet18') + vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, 'Vnet18', '10009') + + vnet_obj.check_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9') + + vnet_obj.fetch_exist_entries(dvs) + 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') + + vnet_obj.check_custom_monitor_app_db(dvs, "100.100.1.1/32", "9.1.0.1", "vxlan", "22:33:33:44:44:66") + vnet_obj.check_custom_monitor_app_db(dvs, "100.100.1.1/32", "9.1.0.2", "vxlan", "22:33:33:44:44:66") + vnet_obj.check_custom_monitor_app_db(dvs, "100.100.1.1/32", "9.1.0.3", "vxlan", "22:33:33:44:44:66") + + delete_vnet_routes(dvs, "100.100.1.1/32", 'Vnet18') + + vnet_obj.check_custom_monitor_deleted(dvs, "100.100.1.1/32", "9.1.0.1") + vnet_obj.check_custom_monitor_deleted(dvs, "100.100.1.1/32", "9.1.0.2") + vnet_obj.check_custom_monitor_deleted(dvs, "100.100.1.1/32", "9.1.0.3") + # Add Dummy always-pass test at end as workaroud # for issue when Flaky fail on final test it invokes module tear-down before retrying def test_nonflaky_dummy(): From f7ce97dfbc45c3463349a70c9fc3a842e610dbf1 Mon Sep 17 00:00:00 2001 From: siqbal1486 Date: Tue, 17 Jan 2023 15:01:30 -0800 Subject: [PATCH 6/9] Changed the name of the table. Signed-off-by: siqbal1486 --- tests/test_vnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_vnet.py b/tests/test_vnet.py index 6b17de6752..8a83d59925 100644 --- a/tests/test_vnet.py +++ b/tests/test_vnet.py @@ -546,7 +546,7 @@ class VnetVxlanVrfTunnel(object): ASIC_NEXT_HOP_GROUP = "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP" ASIC_NEXT_HOP_GROUP_MEMBER = "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MEMBER" ASIC_BFD_SESSION = "ASIC_STATE:SAI_OBJECT_TYPE_BFD_SESSION" - APP_VNET_MONITOR = "VNET_MONITOR" + APP_VNET_MONITOR = "VNET_MONITOR_TABLE" def __init__(self): self.tunnel_map_ids = set() From 8ec790b753e1d445f480939d8ab6b98949d133d4 Mon Sep 17 00:00:00 2001 From: siqbal1486 Date: Wed, 18 Jan 2023 16:56:52 -0800 Subject: [PATCH 7/9] fixed a test causing failure after new changes. Signed-off-by: siqbal1486 --- tests/test_vnet.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_vnet.py b/tests/test_vnet.py index dd6269c489..8a83d59925 100644 --- a/tests/test_vnet.py +++ b/tests/test_vnet.py @@ -2391,7 +2391,7 @@ def test_vnet_orch_17(self, dvs, testlog): vnet_obj.fetch_exist_entries(dvs) create_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9') - create_vnet_entry(dvs, 'Vnet17', tunnel_name, '10009', "", overlay_dmac="22:33:33:44:44:66") + create_vnet_entry(dvs, 'Vnet17', tunnel_name, '10009', "") vnet_obj.check_vnet_entry(dvs, 'Vnet17') vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, 'Vnet17', '10009') @@ -2399,7 +2399,7 @@ def test_vnet_orch_17(self, dvs, testlog): vnet_obj.check_vxlan_tunnel(dvs, tunnel_name, '9.9.9.9') vnet_obj.fetch_exist_entries(dvs) - 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') + 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') # default bfd status is down, route should not be programmed in this status vnet_obj.check_del_vnet_routes(dvs, 'Vnet17', ["100.100.1.1/32"]) From 90449b7ba868e08c6f2c79a12d41df87941bfefb Mon Sep 17 00:00:00 2001 From: siqbal1486 Date: Fri, 20 Jan 2023 11:56:01 -0800 Subject: [PATCH 8/9] Fixed issues raised in review. Signed-off-by: siqbal1486 --- orchagent/vnetorch.cpp | 13 ++++++++----- orchagent/vnetorch.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/orchagent/vnetorch.cpp b/orchagent/vnetorch.cpp index e5197068cc..24f312f7df 100644 --- a/orchagent/vnetorch.cpp +++ b/orchagent/vnetorch.cpp @@ -1621,7 +1621,7 @@ void VNetRouteOrch::createMonitoringSession(const string& vnet, const NextHopKey if (monitor_info_[vnet].find(ipPrefix) != monitor_info_[vnet].end() && monitor_info_[vnet][ipPrefix].find(endpoint) != monitor_info_[vnet][ipPrefix].end()) { - SWSS_LOG_ERROR("Monitoring session for prefix %s endpoint %s already exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str()); + SWSS_LOG_NOTICE("Monitoring session for prefix %s endpoint %s already exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str()); return; } else @@ -1653,7 +1653,7 @@ void VNetRouteOrch::removeMonitoringSession(const string& vnet, const NextHopKey if (monitor_info_[vnet].find(ipPrefix) == monitor_info_[vnet].end() || monitor_info_[vnet][ipPrefix].find(endpoint) == monitor_info_[vnet][ipPrefix].end()) { - SWSS_LOG_ERROR("Monitor session for prefix %s endpoint %s does not exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str()); + SWSS_LOG_NOTICE("Monitor session for prefix %s endpoint %s does not exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str()); } string key = ipPrefix.to_string() + ":" + monitor_addr.to_string(); @@ -1669,7 +1669,7 @@ void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map Date: Fri, 20 Jan 2023 14:29:38 -0800 Subject: [PATCH 9/9] fixed a mistake added in last commit. Signed-off-by: siqbal1486 --- orchagent/vnetorch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orchagent/vnetorch.cpp b/orchagent/vnetorch.cpp index 24f312f7df..e967c24697 100644 --- a/orchagent/vnetorch.cpp +++ b/orchagent/vnetorch.cpp @@ -1669,7 +1669,7 @@ void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map