From d8ca31ca6bb3068931f56a5e48743df9865bb79b Mon Sep 17 00:00:00 2001 From: Andriy Yurkiv <70649192+ayurkiv-nvda@users.noreply.github.com> Date: Wed, 11 Aug 2021 16:08:49 +0300 Subject: [PATCH] [vnet/vxlan] Add support of multiple mappers for the VxLAN tunnel (#1843) Added ability to configure VXLAN tunnel with 2 decapsulation mappers (VRF and VLAN mappers) Signed-off-by: Andriy Yurkiv --- orchagent/vxlanorch.cpp | 13 ++++++--- orchagent/vxlanorch.h | 2 +- tests/test_vnet.py | 63 +++++++++++++++++++++++++++++++++++------ 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/orchagent/vxlanorch.cpp b/orchagent/vxlanorch.cpp index 6e25454f13e8..d983052a7c7b 100644 --- a/orchagent/vxlanorch.cpp +++ b/orchagent/vxlanorch.cpp @@ -863,7 +863,7 @@ bool VxlanTunnel::deleteTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, //Creation of SAI Tunnel Object with multiple mapper types bool VxlanTunnel::createTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, - bool with_term) + bool with_term, sai_uint8_t encap_ttl) { bool p2p = false; @@ -883,7 +883,7 @@ bool VxlanTunnel::createTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, SWSS_LOG_WARN("creation src = %d",src_creation_); } - ids_.tunnel_id = create_tunnel(&ids_, &ips, ip, gUnderlayIfId, p2p); + ids_.tunnel_id = create_tunnel(&ids_, &ips, ip, gUnderlayIfId, p2p, encap_ttl); if (with_term) { @@ -1242,11 +1242,16 @@ bool VxlanTunnelOrch::createVxlanTunnelMap(string tunnelName, tunnel_map_type_t { if (map == TUNNEL_MAP_T_VIRTUAL_ROUTER) { - tunnel_obj->createTunnel(MAP_T::VRID_TO_VNI, MAP_T::VNI_TO_VRID, encap_ttl); + uint8_t mapper_list = 0; + TUNNELMAP_SET_VLAN(mapper_list); + TUNNELMAP_SET_VRF(mapper_list); + tunnel_obj->createTunnelHw(mapper_list, TUNNEL_MAP_USE_DEDICATED_ENCAP_DECAP , true, encap_ttl); } else if (map == TUNNEL_MAP_T_BRIDGE) { - tunnel_obj->createTunnel(MAP_T::BRIDGE_TO_VNI, MAP_T::VNI_TO_BRIDGE, encap_ttl); + uint8_t mapper_list = 0; + TUNNELMAP_SET_BRIDGE(mapper_list); + tunnel_obj->createTunnelHw(mapper_list, TUNNEL_MAP_USE_DEDICATED_ENCAP_DECAP, true, encap_ttl); } } diff --git a/orchagent/vxlanorch.h b/orchagent/vxlanorch.h index edc65d97fe2d..9df5e34bb673 100644 --- a/orchagent/vxlanorch.h +++ b/orchagent/vxlanorch.h @@ -181,7 +181,7 @@ class VxlanTunnel bool deleteMapperHw(uint8_t mapper_list, tunnel_map_use_t map_src); bool createMapperHw(uint8_t mapper_list, tunnel_map_use_t map_src); - bool createTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, bool with_term = true); + bool createTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, bool with_term = true, sai_uint8_t encap_ttl=0); bool deleteTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, bool with_term = true); void deletePendingSIPTunnel(); void increment_spurious_imr_add(const std::string remote_vtep); diff --git a/tests/test_vnet.py b/tests/test_vnet.py index 94be6e9cba7a..c7fd3c1225e3 100644 --- a/tests/test_vnet.py +++ b/tests/test_vnet.py @@ -354,6 +354,20 @@ def create_vxlan_tunnel(dvs, name, src_ip): ) +def create_vxlan_tunnel_map(dvs, tunnel_name, tunnel_map_entry_name, vlan, vni_id): + conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) + + # create the VXLAN tunnel map entry in Config DB + create_entry_tbl( + conf_db, + "VXLAN_TUNNEL_MAP", '|', "%s|%s" % (tunnel_name, tunnel_map_entry_name), + [ + ("vni", vni_id), + ("vlan", vlan), + ], + ) + + def get_lo(dvs): asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) vr_id = get_default_vr_id(dvs) @@ -451,34 +465,46 @@ def check_vxlan_tunnel(self, dvs, tunnel_name, src_ip): asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) global loopback_id, def_vr_id - tunnel_map_id = get_created_entries(asic_db, self.ASIC_TUNNEL_MAP, self.tunnel_map_ids, 2) + tunnel_map_id = get_created_entries(asic_db, self.ASIC_TUNNEL_MAP, self.tunnel_map_ids, 4) tunnel_id = get_created_entry(asic_db, self.ASIC_TUNNEL_TABLE, self.tunnel_ids) tunnel_term_id = get_created_entry(asic_db, self.ASIC_TUNNEL_TERM_ENTRY, self.tunnel_term_ids) # check that the vxlan tunnel termination are there - assert how_many_entries_exist(asic_db, self.ASIC_TUNNEL_MAP) == (len(self.tunnel_map_ids) + 2), "The TUNNEL_MAP wasn't created" + assert how_many_entries_exist(asic_db, self.ASIC_TUNNEL_MAP) == (len(self.tunnel_map_ids) + 4), "The TUNNEL_MAP wasn't created" assert how_many_entries_exist(asic_db, self.ASIC_TUNNEL_MAP_ENTRY) == len(self.tunnel_map_entry_ids), "The TUNNEL_MAP_ENTRY is created" assert how_many_entries_exist(asic_db, self.ASIC_TUNNEL_TABLE) == (len(self.tunnel_ids) + 1), "The TUNNEL wasn't created" assert how_many_entries_exist(asic_db, self.ASIC_TUNNEL_TERM_ENTRY) == (len(self.tunnel_term_ids) + 1), "The TUNNEL_TERM_TABLE_ENTRY wasm't created" - check_object(asic_db, self.ASIC_TUNNEL_MAP, tunnel_map_id[0], + check_object(asic_db, self.ASIC_TUNNEL_MAP, tunnel_map_id[2], { 'SAI_TUNNEL_MAP_ATTR_TYPE': 'SAI_TUNNEL_MAP_TYPE_VNI_TO_VIRTUAL_ROUTER_ID', } ) - check_object(asic_db, self.ASIC_TUNNEL_MAP, tunnel_map_id[1], + check_object(asic_db, self.ASIC_TUNNEL_MAP, tunnel_map_id[3], { 'SAI_TUNNEL_MAP_ATTR_TYPE': 'SAI_TUNNEL_MAP_TYPE_VIRTUAL_ROUTER_ID_TO_VNI', } ) + check_object(asic_db, self.ASIC_TUNNEL_MAP, tunnel_map_id[0], + { + 'SAI_TUNNEL_MAP_ATTR_TYPE': 'SAI_TUNNEL_MAP_TYPE_VNI_TO_VLAN_ID', + } + ) + + check_object(asic_db, self.ASIC_TUNNEL_MAP, tunnel_map_id[1], + { + 'SAI_TUNNEL_MAP_ATTR_TYPE': 'SAI_TUNNEL_MAP_TYPE_VLAN_ID_TO_VNI', + } + ) + check_object(asic_db, self.ASIC_TUNNEL_TABLE, tunnel_id, { 'SAI_TUNNEL_ATTR_TYPE': 'SAI_TUNNEL_TYPE_VXLAN', 'SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE': loopback_id, - 'SAI_TUNNEL_ATTR_DECAP_MAPPERS': '1:%s' % tunnel_map_id[0], - 'SAI_TUNNEL_ATTR_ENCAP_MAPPERS': '1:%s' % tunnel_map_id[1], + 'SAI_TUNNEL_ATTR_DECAP_MAPPERS': '2:%s,%s' % (tunnel_map_id[0], tunnel_map_id[2]), + 'SAI_TUNNEL_ATTR_ENCAP_MAPPERS': '2:%s,%s' % (tunnel_map_id[1], tunnel_map_id[3]), 'SAI_TUNNEL_ATTR_ENCAP_SRC_IP': src_ip, } ) @@ -506,7 +532,7 @@ def check_vxlan_tunnel_entry(self, dvs, tunnel_name, vnet_name, vni_id): time.sleep(2) if (self.tunnel_map_map.get(tunnel_name) is None): - tunnel_map_id = get_created_entries(asic_db, self.ASIC_TUNNEL_MAP, self.tunnel_map_ids, 2) + tunnel_map_id = get_created_entries(asic_db, self.ASIC_TUNNEL_MAP, self.tunnel_map_ids, 4) else: tunnel_map_id = self.tunnel_map_map[tunnel_name] @@ -518,7 +544,7 @@ def check_vxlan_tunnel_entry(self, dvs, tunnel_name, vnet_name, vni_id): check_object(asic_db, self.ASIC_TUNNEL_MAP_ENTRY, tunnel_map_entry_id[0], { 'SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP_TYPE': 'SAI_TUNNEL_MAP_TYPE_VIRTUAL_ROUTER_ID_TO_VNI', - 'SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP': tunnel_map_id[1], + 'SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP': tunnel_map_id[3], 'SAI_TUNNEL_MAP_ENTRY_ATTR_VIRTUAL_ROUTER_ID_KEY': self.vr_map[vnet_name].get('ing'), 'SAI_TUNNEL_MAP_ENTRY_ATTR_VNI_ID_VALUE': vni_id, } @@ -527,7 +553,7 @@ def check_vxlan_tunnel_entry(self, dvs, tunnel_name, vnet_name, vni_id): check_object(asic_db, self.ASIC_TUNNEL_MAP_ENTRY, tunnel_map_entry_id[1], { 'SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP_TYPE': 'SAI_TUNNEL_MAP_TYPE_VNI_TO_VIRTUAL_ROUTER_ID', - 'SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP': tunnel_map_id[0], + 'SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP': tunnel_map_id[2], 'SAI_TUNNEL_MAP_ENTRY_ATTR_VNI_ID_KEY': vni_id, 'SAI_TUNNEL_MAP_ENTRY_ATTR_VIRTUAL_ROUTER_ID_VALUE': self.vr_map[vnet_name].get('egr'), } @@ -1080,6 +1106,25 @@ def test_vnet_orch_5(self, dvs, testlog): vnet_obj.check_default_vnet_entry(dvs, 'Vnet_5') vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, 'Vnet_5', '4789') + ''' + Test 6 - Test VxLAN tunnel with multiple maps + ''' + def test_vnet_vxlan_multi_map(self, dvs, testlog): + vnet_obj = self.get_vnet_obj() + + tunnel_name = 'tunnel_v4' + + vnet_obj.fetch_exist_entries(dvs) + + create_vxlan_tunnel(dvs, tunnel_name, '10.1.0.32') + create_vnet_entry(dvs, 'Vnet1', tunnel_name, '10001', "") + + vnet_obj.check_vnet_entry(dvs, 'Vnet1') + vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, 'Vnet1', '10001') + vnet_obj.check_vxlan_tunnel(dvs, tunnel_name, '10.1.0.32') + + create_vxlan_tunnel_map(dvs, tunnel_name, 'map_1', 'Vlan1000', '1000') + # Add Dummy always-pass test at end as workaroud # for issue when Flaky fail on final test it invokes module tear-down before retrying