From 2831abe07fa0ea95596a523a4698cace7e9a75ad Mon Sep 17 00:00:00 2001 From: Prabhat Aravind Date: Fri, 13 Sep 2024 01:24:49 +0000 Subject: [PATCH 1/5] [dash]: Initial changes to run dash tests on smartswitch Signed-off-by: Prabhat Aravind --- tests/dash/conftest.py | 16 +++++++++++++--- tests/dash/gnmi_utils.py | 9 +++++---- tests/dash/test_dash_vnet.py | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/tests/dash/conftest.py b/tests/dash/conftest.py index 445fba4ae8..c86c910ddb 100644 --- a/tests/dash/conftest.py +++ b/tests/dash/conftest.py @@ -114,6 +114,12 @@ def get_intf_from_ip(local_ip, config_facts): if str(intf_ip.ip) == local_ip: return intf, intf_ip + for intf, config in list(config_facts["PORTCHANNEL_INTERFACE"].items()): + for ip in config: + intf_ip = ip_interface(ip) + if str(intf_ip.ip) == local_ip: + return intf, intf_ip + @pytest.fixture(params=["no-underlay-route", "with-underlay-route"]) def use_underlay_route(request): @@ -148,11 +154,13 @@ def dash_config_info(duthost, config_facts, minigraph_facts, tbinfo): # Take neighbor 1 as local PA, take neighbor 2 as remote PA if ip_interface(neigh_ip).version == 4: if LOCAL_PA_IP not in dash_info: - dash_info[LOCAL_PA_IP] = neigh_ip intf, _ = get_intf_from_ip(config['local_addr'], config_facts) + if "PortChannel" in intf: + continue + dash_info[LOCAL_PA_IP] = neigh_ip dash_info[LOCAL_PTF_INTF] = minigraph_facts["minigraph_ptf_indices"][intf] dash_info[LOCAL_PTF_MAC] = neigh_table["v4"][neigh_ip]["macaddress"] - if topo == 'dpu-1' and REMOTE_PA_IP not in dash_info: + if (topo == 'dpu-1' or topo == "t1-28-lag") and REMOTE_PA_IP not in dash_info: # For DPU with only one single port, we just have one neighbor (neighbor 1). # So, we take neighbor 1 as the local PA. For the remote PA, # we take the original neighbor 2's IP as the remote PA IP, @@ -170,8 +178,10 @@ def dash_config_info(duthost, config_facts, minigraph_facts, tbinfo): dash_info[REMOTE_PA_PREFIX] = fake_neighbor_2_prefix break elif REMOTE_PA_IP not in dash_info: - dash_info[REMOTE_PA_IP] = neigh_ip intf, intf_ip = get_intf_from_ip(config['local_addr'], config_facts) + if "PortChannel" in intf: + continue + dash_info[REMOTE_PA_IP] = neigh_ip dash_info[REMOTE_PTF_INTF] = minigraph_facts["minigraph_ptf_indices"][intf] dash_info[REMOTE_PTF_MAC] = neigh_table["v4"][neigh_ip]["macaddress"] dash_info[REMOTE_PA_PREFIX] = str(intf_ip.network) diff --git a/tests/dash/gnmi_utils.py b/tests/dash/gnmi_utils.py index 95432701df..bb37b51161 100644 --- a/tests/dash/gnmi_utils.py +++ b/tests/dash/gnmi_utils.py @@ -23,7 +23,8 @@ def __init__(self, duthost): self.gnmi_client_cert = "gnmiclient.crt" self.gnmi_client_key = "gnmiclient.key" self.gnmi_server_start_wait_time = 30 - self.enable_zmq = duthost.shell("netstat -na | grep -w 8100", module_ignore_errors=True)['rc'] == 0 + #self.enable_zmq = duthost.shell("netstat -na | grep -w 8100", module_ignore_errors=True)['rc'] == 0 + self.enable_zmq = True cmd = "docker images | grep -w sonic-gnmi" if duthost.shell(cmd, module_ignore_errors=True)['rc'] == 0: cmd = "docker ps | grep -w gnmi" @@ -371,9 +372,9 @@ def apply_gnmi_file(localhost, duthost, ptfhost, dest_path=None, config_json=Non keys = k.split(":", 1) k = keys[0] + "[key=" + keys[1] + "]" if proto_utils.ENABLE_PROTO: - path = "/APPL_DB/localhost/%s:$/root/%s" % (k, filename) + path = "/APPL_DB/dpu1/%s:$/root/%s" % (k, filename) else: - path = "/APPL_DB/localhost/%s:@/root/%s" % (k, filename) + path = "/APPL_DB/dpu1/%s:@/root/%s" % (k, filename) update_list.append(path) elif operation["OP"] == "DEL": for k, v in operation.items(): @@ -381,7 +382,7 @@ def apply_gnmi_file(localhost, duthost, ptfhost, dest_path=None, config_json=Non continue keys = k.split(":", 1) k = keys[0] + "[key=" + keys[1] + "]" - path = "/APPL_DB/localhost/%s" % (k) + path = "/APPL_DB/dpu1/%s" % (k) delete_list.append(path) else: logger.info("Invalid operation %s" % operation["OP"]) diff --git a/tests/dash/test_dash_vnet.py b/tests/dash/test_dash_vnet.py index db11b7da67..beaa45ebf4 100644 --- a/tests/dash/test_dash_vnet.py +++ b/tests/dash/test_dash_vnet.py @@ -65,7 +65,7 @@ def test_outbound_direct( inner_packet_type, acl_default_rule, vxlan_udp_dport): - asic_db_checker(["SAI_OBJECT_TYPE_VNET", "SAI_OBJECT_TYPE_ENI"]) + # asic_db_checker(["SAI_OBJECT_TYPE_VNET", "SAI_OBJECT_TYPE_ENI"]) if skip_dataplane_checking: return expected_inner_packet, vxlan_packet, _ = packets.outbound_vnet_packets(dash_config_info, From ee6190d549e5285fd5bd9924b3cc4ef355e16ba0 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Wed, 25 Sep 2024 03:17:07 +0000 Subject: [PATCH 2/5] Add privatelink configs Signed-off-by: Lawrence Lee --- tests/dash/configs/privatelink_config.py | 173 +++++++++++++++++++++++ tests/dash/gnmi_utils.py | 43 +++++- 2 files changed, 210 insertions(+), 6 deletions(-) create mode 100644 tests/dash/configs/privatelink_config.py diff --git a/tests/dash/configs/privatelink_config.py b/tests/dash/configs/privatelink_config.py new file mode 100644 index 0000000000..b9e0d2692c --- /dev/null +++ b/tests/dash/configs/privatelink_config.py @@ -0,0 +1,173 @@ +import base64 +import socket +import uuid +from ipaddress import ip_address as IP + +from dash_api.appliance_pb2 import Appliance +from dash_api.vnet_pb2 import Vnet +from dash_api.eni_pb2 import Eni, State +from dash_api.eni_route_pb2 import EniRoute +from dash_api.route_pb2 import Route +from dash_api.vnet_mapping_pb2 import VnetMapping +from dash_api.route_type_pb2 import RouteType, RoutingType, ActionType, EncapType +from dash_api.route_group_pb2 import RouteGroup +from google.protobuf.json_format import ParseDict + +VNET_ENCAP = "vnet_encap" +VNET_DIRECT = "vnet_direct" +PRIVATELINK = "privatelink" +DECAP = "decap" + +SIP = "10.0.0.1" +INBOUND_UNDERLAY_IP = "25.1.1.1" +OUTBOUND_UNDERLAY_IP = "101.1.2.3" +VNET_MAP_IP1 = "10.1.1.1" +VNET_MAP_IP2 = "10.1.1.2" +OUTBOUND_ROUTE_PREFIX1 = "10.1.0.8/32" +OUTBOUND_ROUTE_PREFIX2 = "10.1.0.9/32" +OVERLAY_IP = "10.0.0.6" +PL_ENCODING_IP = "::56b2:0:ff71:0:0" +PL_ENCODING_MASK = "::ffff:ffff:ffff:0:0" +PL_UNDERLAY_SIP1 = "55.1.2.3" +PL_UNDERLAY_SIP2 = "55.2.3.4" +PL_OVERLAY_SIP = "fd41:108:20:abc:abc::0" +PL_OVERLAY_SIP_MASK = "ffff:ffff:ffff:ffff:ffff:ffff::" +PL_OVERLAY_DIP = "2603:10e1:100:2::3401:203" +PL_OVERLAY_DIP_MASK = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + +APPLIANCE_ID = "100" +VM_VNI = "4321" +ENCAP_VNI = 100 +VNET1 = "Vnet1" +VNET1_VNI = "45654" +VNET1_GUID = "559c6ce8-26ab-4193-b946-ccc6e8f930b2" +MAC_STRING = "F4939FEFC47E" +MAC_ADDRESS = "F4:93:9F:EF:C4:7E" +ENI_ID = "497f23d7-f0ac-4c99-a98f-59b470e8c7bd" +ROUTE_GROUP1 = "RouteGroup1" +ROUTE_GROUP2 = "RouteGroup2" +ROUTE_GROUP1_GUID = "48af6ce8-26cc-4293-bfa6-0126e8fcdeb2" +ROUTE_GROUP2_GUID = "58cf62e0-22cc-4693-baa6-012358fcdec9" + +APPLIANCE_CONFIG = { + f"DASH_APPLIANCE_TABLE:{APPLIANCE_ID}": + ParseDict({ + "sip": { + "ipv4": socket.htonl(int(IP(SIP))) + }, + "vm_vni": int(VM_VNI) + }, Appliance()) +} + +VNET_CONFIG = { + f"DASH_VNET_TABLE:{VNET1}": + ParseDict({ + "vni": VNET1_VNI, + "guid": { + "value": base64.b64encode(bytes.fromhex(uuid.UUID(VNET1_GUID).hex)) + } + }, Vnet()) +} + +ENI_CONFIG = { + f"DASH_ENI_TABLE:{ENI_ID}": + ParseDict({ + "vnet": VNET1, + "underlay_ip": { + "ipv4": socket.htonl(int(IP(INBOUND_UNDERLAY_IP))) + }, + "mac_address": bytes.fromhex(MAC_STRING), + "eni_id": ENI_ID, + "admin_state": State.STATE_ENABLED, + "pl_underlay_sip": { + "ipv4": socket.htonl(int(IP(PL_UNDERLAY_SIP1))) + }, + "pl_sip_encoding": { + "ip": { + "ipv6": base64.b64encode(IP(PL_ENCODING_IP).packed) + }, + "mask": { + "ipv6": base64.b64encode(IP(PL_ENCODING_MASK).packed) + } + } + }, Eni()) +} + +VNET_MAPPING_CONFIG = { + f"DASH_VNET_MAPPING_TABLE:{VNET1}:{VNET_MAP_IP1}": + ParseDict({ + "mac_address": bytes.fromhex(MAC_STRING), + "routing_type": RoutingType.ROUTING_TYPE_PRIVATELINK, + "underlay_ip": { + "ipv4": socket.htonl(int(IP(OUTBOUND_UNDERLAY_IP))) + }, + "overlay_sip_prefix": { + "ip": { + "ipv6": base64.b64encode(IP(PL_OVERLAY_SIP).packed) + }, + "mask": { + "ipv6": base64.b64encode(IP(PL_OVERLAY_SIP_MASK).packed) + } + }, + "overlay_dip_prefix": { + "ip": { + "ipv6": base64.b64encode(IP(PL_OVERLAY_DIP).packed) + }, + "mask": { + "ipv6": base64.b64encode(IP(PL_OVERLAY_DIP_MASK).packed) + } + }, + }, VnetMapping()) +} + +ROUTE_VNET_CONFIG = { + f"DASH_ROUTE_TABLE:{ROUTE_GROUP1}:{OUTBOUND_ROUTE_PREFIX1}": + ParseDict({ + "routing_type": RoutingType.ROUTING_TYPE_VNET, + "vnet": VNET1, + }, Route()) +} + +ROUTE_VNET_CONFIG_UNDERLAY_SIP = { + f"DASH_ROUTE_TABLE:{ROUTE_GROUP2}:{OUTBOUND_ROUTE_PREFIX2}": + ParseDict({ + "routing_type": RoutingType.ROUTING_TYPE_VNET, + "vnet": VNET1, + "underlay_sip": { + "ipv4": socket.htonl(int(IP(PL_UNDERLAY_SIP2))) + } + }, Route()) +} + +ROUTING_TYPE_PL_CONFIG = { + f"DASH_ROUTE_TYPE_TABLE:{PRIVATELINK}": + ParseDict({ + "items": [ + { + "action_name": "action1", + "action_type": ActionType.ACTION_TYPE_4_to_6 + }, + { + "action_name": "action2", + "action_type": ActionType.ACTION_TYPE_STATICENCAP, + "encap_type": EncapType.ENCAP_TYPE_NVGRE, + "vni": ENCAP_VNI + } + ] + }, RouteType()) +} + +ROUTE_GROUP1_CONFIG = { + f"DASH_ROUTE_GROUP_TABLE:{ROUTE_GROUP1}": + ParseDict({ + "guid": ROUTE_GROUP1_GUID, + "version": "rg_version" + }, RouteGroup()) +} + +ENI_ROUTE_GROUP1_CONFIG = { + f"DASH_ENI_ROUTE_TABLE:{ENI_ID}": + ParseDict({ + "group_id": ROUTE_GROUP1 + }, EniRoute()) +} diff --git a/tests/dash/gnmi_utils.py b/tests/dash/gnmi_utils.py index bb37b51161..6954090291 100644 --- a/tests/dash/gnmi_utils.py +++ b/tests/dash/gnmi_utils.py @@ -23,7 +23,7 @@ def __init__(self, duthost): self.gnmi_client_cert = "gnmiclient.crt" self.gnmi_client_key = "gnmiclient.key" self.gnmi_server_start_wait_time = 30 - #self.enable_zmq = duthost.shell("netstat -na | grep -w 8100", module_ignore_errors=True)['rc'] == 0 + # self.enable_zmq = duthost.shell("netstat -na | grep -w 8100", module_ignore_errors=True)['rc'] == 0 self.enable_zmq = True cmd = "docker images | grep -w sonic-gnmi" if duthost.shell(cmd, module_ignore_errors=True)['rc'] == 0: @@ -268,6 +268,7 @@ def gnmi_set(duthost, ptfhost, delete_list, update_list, replace_list): cmd += '--xpath ' + xpath cmd += ' ' cmd += '--value ' + xvalue + logger.info(f"PTF GNMI command: {cmd}") output = ptfhost.shell(cmd, module_ignore_errors=True) error = "GRPC error\n" if error in output['stdout']: @@ -307,6 +308,7 @@ def gnmi_get(duthost, ptfhost, path_list): for path in path_list: path = path.replace('sonic-db:', '') cmd += " " + path + logger.info(f"Running command on PTF: {cmd}") output = ptfhost.shell(cmd, module_ignore_errors=True) if output['stderr']: raise Exception("error:" + output['stderr']) @@ -325,6 +327,31 @@ def gnmi_get(duthost, ptfhost, path_list): raise Exception("error:" + msg) +def apply_messages(localhost, duthost, ptfhost, messages, set=True, wait_after_apply=5, max_updates_in_single_cmd=1024): + env = GNMIEnvironment(duthost) + update_list = [] + delete_list = [] + for i, (key, message) in enumerate(messages.items()): + keys = key.split(":", 1) + k = keys[0] + "[key=" + keys[1] + "]" + filename = f"update{i}" + + if set: + if proto_utils.ENABLE_PROTO: + path = f"/APPL_DB/dpu0/{k}:$/root/{filename}" + else: + path = f"/APPL_DB/dpu0/{k}:@/root/{filename}" + with open(env.work_dir+filename, "wb") as file: + file.write(message.SerializeToString()) + update_list.append(path) + else: + path = f"/APPL_DB/dpu0/{filename}" + delete_list.append(path) + + write_gnmi_files(localhost, duthost, ptfhost, env, delete_list, update_list, max_updates_in_single_cmd) + time.sleep(wait_after_apply) + + def apply_gnmi_file(localhost, duthost, ptfhost, dest_path=None, config_json=None, wait_after_apply=5, max_updates_in_single_cmd=1024): """ @@ -386,6 +413,11 @@ def apply_gnmi_file(localhost, duthost, ptfhost, dest_path=None, config_json=Non delete_list.append(path) else: logger.info("Invalid operation %s" % operation["OP"]) + write_gnmi_files(localhost, duthost, ptfhost, env, delete_list, update_list, max_updates_in_single_cmd) + time.sleep(wait_after_apply) + + +def write_gnmi_files(localhost, duthost, ptfhost, env, delete_list, update_list, max_updates_in_single_cmd): localhost.shell(f'tar -zcvf /tmp/updates.tar.gz -C {env.work_dir} .') ptfhost.copy(src='/tmp/updates.tar.gz', dest='~') ptfhost.shell('tar -xf updates.tar.gz') @@ -407,8 +439,7 @@ def _devide_list(operation_list): for update_list in update_list_group: gnmi_set(duthost, ptfhost, [], update_list, []) - localhost.shell('rm -f /tmp/updates.tar.gz') - ptfhost.shell('rm -f updates.tar.gz') - localhost.shell(f'rm -f {env.work_dir}update*') - ptfhost.shell('rm -f update*') - time.sleep(wait_after_apply) + # localhost.shell('rm -f /tmp/updates.tar.gz') + # ptfhost.shell('rm -f updates.tar.gz') + # localhost.shell(f'rm -f {env.work_dir}update*') + # ptfhost.shell('rm -f update*') From 52870fd164509c14f5d1a18e93c24de6d0576a6a Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Thu, 26 Sep 2024 06:36:38 +0000 Subject: [PATCH 3/5] Add privatelink outbound test Signed-off-by: Lawrence Lee --- tests/dash/configs/privatelink_config.py | 22 +++--- tests/dash/conftest.py | 23 ++++++ tests/dash/gnmi_utils.py | 28 +++++--- tests/dash/packets.py | 91 ++++++++++++++++++++++++ tests/dash/test_dash_privatelink.py | 78 ++++++++++++++++++++ 5 files changed, 222 insertions(+), 20 deletions(-) create mode 100644 tests/dash/test_dash_privatelink.py diff --git a/tests/dash/configs/privatelink_config.py b/tests/dash/configs/privatelink_config.py index b9e0d2692c..6b420fc4fd 100644 --- a/tests/dash/configs/privatelink_config.py +++ b/tests/dash/configs/privatelink_config.py @@ -18,13 +18,13 @@ PRIVATELINK = "privatelink" DECAP = "decap" -SIP = "10.0.0.1" +SIP = "10.2.0.1" INBOUND_UNDERLAY_IP = "25.1.1.1" OUTBOUND_UNDERLAY_IP = "101.1.2.3" -VNET_MAP_IP1 = "10.1.1.1" -VNET_MAP_IP2 = "10.1.1.2" -OUTBOUND_ROUTE_PREFIX1 = "10.1.0.8/32" -OUTBOUND_ROUTE_PREFIX2 = "10.1.0.9/32" +VNET_MAP_IP1 = "10.1.1.5" +VNET_MAP_IP2 = "10.1.2.5" +OUTBOUND_ROUTE_PREFIX1 = "10.1.1.0/24" +OUTBOUND_ROUTE_PREFIX2 = "10.1.2.0/24" OVERLAY_IP = "10.0.0.6" PL_ENCODING_IP = "::56b2:0:ff71:0:0" PL_ENCODING_MASK = "::ffff:ffff:ffff:0:0" @@ -41,8 +41,10 @@ VNET1 = "Vnet1" VNET1_VNI = "45654" VNET1_GUID = "559c6ce8-26ab-4193-b946-ccc6e8f930b2" -MAC_STRING = "F4939FEFC47E" -MAC_ADDRESS = "F4:93:9F:EF:C4:7E" +ENI_MAC = "F4:93:9F:EF:C4:7E" +ENI_MAC_STRING = ENI_MAC.replace(":", "") +REMOTE_MAC = "43:BE:65:25:FA:67" +REMOTE_MAC_STRING = REMOTE_MAC.replace(":", "") ENI_ID = "497f23d7-f0ac-4c99-a98f-59b470e8c7bd" ROUTE_GROUP1 = "RouteGroup1" ROUTE_GROUP2 = "RouteGroup2" @@ -76,7 +78,7 @@ "underlay_ip": { "ipv4": socket.htonl(int(IP(INBOUND_UNDERLAY_IP))) }, - "mac_address": bytes.fromhex(MAC_STRING), + "mac_address": base64.b64encode(bytes.fromhex(ENI_MAC_STRING)), "eni_id": ENI_ID, "admin_state": State.STATE_ENABLED, "pl_underlay_sip": { @@ -96,7 +98,7 @@ VNET_MAPPING_CONFIG = { f"DASH_VNET_MAPPING_TABLE:{VNET1}:{VNET_MAP_IP1}": ParseDict({ - "mac_address": bytes.fromhex(MAC_STRING), + "mac_address": base64.b64encode(bytes.fromhex(REMOTE_MAC_STRING)), "routing_type": RoutingType.ROUTING_TYPE_PRIVATELINK, "underlay_ip": { "ipv4": socket.htonl(int(IP(OUTBOUND_UNDERLAY_IP))) @@ -140,7 +142,7 @@ } ROUTING_TYPE_PL_CONFIG = { - f"DASH_ROUTE_TYPE_TABLE:{PRIVATELINK}": + f"DASH_ROUTING_TYPE_TABLE:{PRIVATELINK}": ParseDict({ "items": [ { diff --git a/tests/dash/conftest.py b/tests/dash/conftest.py index c86c910ddb..7e4e700028 100644 --- a/tests/dash/conftest.py +++ b/tests/dash/conftest.py @@ -126,6 +126,24 @@ def use_underlay_route(request): return request.param == "with-underlay-route" +@pytest.fixture +def dash_pl_config(duthost, config_facts, minigraph_facts): + dash_info = { + DUT_MAC: config_facts["DEVICE_METADATA"]["localhost"]["mac"], + LOCAL_CA_IP: "10.2.2.2", + } + + neigh_table = duthost.switch_arptable()['ansible_facts']['arptable'] + for neigh_ip, config in list(config_facts["BGP_NEIGHBOR"].items()): + if ip_interface(neigh_ip).version == 4: + if config["name"].endswith("T0"): + intf, _ = get_intf_from_ip(config['local_addr'], config_facts) + dash_info[LOCAL_PTF_INTF] = minigraph_facts["minigraph_ptf_indices"][intf] + dash_info[LOCAL_PTF_MAC] = neigh_table["v4"][neigh_ip]["macaddress"] + break + return dash_info + + @pytest.fixture(scope="function") def dash_config_info(duthost, config_facts, minigraph_facts, tbinfo): dash_info = { @@ -364,3 +382,8 @@ def acl_default_rule(localhost, duthost, ptfhost, dash_config_info): default_acl_rule.teardown() del default_acl_group time.sleep(WAIT_AFTER_CONFIG) + + +@pytest.fixture(scope="module") +def dpu_index(): + return 0 diff --git a/tests/dash/gnmi_utils.py b/tests/dash/gnmi_utils.py index 6954090291..bd812a203b 100644 --- a/tests/dash/gnmi_utils.py +++ b/tests/dash/gnmi_utils.py @@ -308,7 +308,6 @@ def gnmi_get(duthost, ptfhost, path_list): for path in path_list: path = path.replace('sonic-db:', '') cmd += " " + path - logger.info(f"Running command on PTF: {cmd}") output = ptfhost.shell(cmd, module_ignore_errors=True) if output['stderr']: raise Exception("error:" + output['stderr']) @@ -327,7 +326,16 @@ def gnmi_get(duthost, ptfhost, path_list): raise Exception("error:" + msg) -def apply_messages(localhost, duthost, ptfhost, messages, set=True, wait_after_apply=5, max_updates_in_single_cmd=1024): +def apply_messages( + localhost, + duthost, + ptfhost, + messages, + dpu_index, + set=True, + wait_after_apply=5, + max_updates_in_single_cmd=1024, +): env = GNMIEnvironment(duthost) update_list = [] delete_list = [] @@ -338,14 +346,14 @@ def apply_messages(localhost, duthost, ptfhost, messages, set=True, wait_after_a if set: if proto_utils.ENABLE_PROTO: - path = f"/APPL_DB/dpu0/{k}:$/root/{filename}" + path = f"/APPL_DB/dpu{dpu_index}/{k}:$/root/{filename}" else: - path = f"/APPL_DB/dpu0/{k}:@/root/{filename}" - with open(env.work_dir+filename, "wb") as file: + path = f"/APPL_DB/dpu{dpu_index}/{k}:@/root/{filename}" + with open(env.work_dir + filename, "wb") as file: file.write(message.SerializeToString()) update_list.append(path) else: - path = f"/APPL_DB/dpu0/{filename}" + path = f"/APPL_DB/dpu{dpu_index}/{filename}" delete_list.append(path) write_gnmi_files(localhost, duthost, ptfhost, env, delete_list, update_list, max_updates_in_single_cmd) @@ -439,7 +447,7 @@ def _devide_list(operation_list): for update_list in update_list_group: gnmi_set(duthost, ptfhost, [], update_list, []) - # localhost.shell('rm -f /tmp/updates.tar.gz') - # ptfhost.shell('rm -f updates.tar.gz') - # localhost.shell(f'rm -f {env.work_dir}update*') - # ptfhost.shell('rm -f update*') + localhost.shell('rm -f /tmp/updates.tar.gz') + ptfhost.shell('rm -f updates.tar.gz') + localhost.shell(f'rm -f {env.work_dir}update*') + ptfhost.shell('rm -f update*') diff --git a/tests/dash/packets.py b/tests/dash/packets.py index dbb5ec606a..8b39cba88f 100644 --- a/tests/dash/packets.py +++ b/tests/dash/packets.py @@ -11,6 +11,7 @@ import time from tests.common.helpers.assertions import pytest_assert from six import StringIO +from configs import privatelink_config as pl logger = logging.getLogger(__name__) @@ -34,6 +35,96 @@ def set_icmp_sub_type(packet, packet_type): packet[scapy.ICMP].type = 0 +def get_bits(ip): + addr = ip_address(ip) + return int(addr) + + +def get_pl_overlay_sip(orig_sip, ol_sip, ol_mask, pl_sip_encoding, pl_sip_mask): + pkt_sip = get_bits(orig_sip) + ol_sip_ip = get_bits(ol_sip) + ol_sip_mask = get_bits(ol_mask) + pl_encoding_ip = get_bits(pl_sip_encoding) + pl_encoding_mask = get_bits(pl_sip_mask) + + overlay_sip = ( + ((pkt_sip & ~ol_sip_mask) | ol_sip_ip) & ~pl_encoding_mask + ) | pl_encoding_ip + return str(ip_address(overlay_sip)) + + +def get_pl_overlay_dip(orig_dip, ol_dip, ol_mask): + pkt_dip = get_bits(orig_dip) + ol_dip_ip = get_bits(ol_dip) + ol_dip_mask = get_bits(ol_mask) + + overlay_dip = (pkt_dip & ~ol_dip_mask) | ol_dip_ip + return str(ip_address(overlay_dip)) + + +def outbound_pl_packets(config, inner_packet_type='udp', vxlan_udp_dport=4789): + inner_packet = generate_inner_packet(inner_packet_type)( + eth_src=pl.ENI_MAC, + ip_src=config[LOCAL_CA_IP], + ip_dst=pl.VNET_MAP_IP1, + ) + + vxlan_packet = testutils.simple_vxlan_packet( + eth_src=config[LOCAL_PTF_MAC], + eth_dst=config[DUT_MAC], + ip_src=pl.INBOUND_UNDERLAY_IP, + ip_dst=pl.SIP, + udp_dport=vxlan_udp_dport, + with_udp_chksum=False, + vxlan_vni=int(pl.VNET1_VNI), + inner_frame=inner_packet + ) + + exp_overlay_sip = get_pl_overlay_sip( + inner_packet[scapy.IP].src, + pl.PL_OVERLAY_SIP, + pl.PL_OVERLAY_SIP_MASK, + pl.PL_ENCODING_IP, + pl.PL_ENCODING_MASK + ) + + exp_overlay_dip = get_pl_overlay_dip( + inner_packet[scapy.IP].dst, + pl.PL_OVERLAY_DIP, + pl.PL_OVERLAY_DIP_MASK + ) + + logger.info(f"Expecting overlay SIP: {exp_overlay_sip}") + logger.info(f"Expecting overlay DIP: {exp_overlay_dip}") + + exp_inner_packet = scapy.Ether() / scapy.IPv6() / scapy.UDP() + exp_inner_packet[scapy.Ether].src = pl.ENI_MAC + exp_inner_packet[scapy.Ether].dst = pl.REMOTE_MAC + exp_inner_packet[scapy.IPv6].src = exp_overlay_sip + exp_inner_packet[scapy.IPv6].dst = exp_overlay_dip + exp_inner_packet[scapy.UDP] = inner_packet[scapy.UDP] + + exp_encap_packet = testutils.simple_gre_packet( + ip_src=pl.PL_UNDERLAY_SIP1, + ip_dst=pl.OUTBOUND_UNDERLAY_IP, + gre_key_present=True, + gre_key=pl.ENCAP_VNI, + inner_frame=exp_inner_packet, + ip_id=0, + ip_ttl=63, + ) + + masked_exp_packet = Mask(exp_encap_packet) + masked_exp_packet.set_do_not_care_scapy(scapy.Ether, "src") + masked_exp_packet.set_do_not_care_scapy(scapy.Ether, "dst") + masked_exp_packet.set_do_not_care_scapy(scapy.IP, "chksum") + + # Temporarily ignore GRE key + masked_exp_packet.set_do_not_care_scapy(scapy.GRE, "key") + + return vxlan_packet, masked_exp_packet + + def inbound_vnet_packets(dash_config_info, inner_extra_conf={}, inner_packet_type='udp', vxlan_udp_dport=4789): inner_packet = generate_inner_packet(inner_packet_type)( eth_src=dash_config_info[REMOTE_ENI_MAC], diff --git a/tests/dash/test_dash_privatelink.py b/tests/dash/test_dash_privatelink.py new file mode 100644 index 0000000000..c9f444df36 --- /dev/null +++ b/tests/dash/test_dash_privatelink.py @@ -0,0 +1,78 @@ +import pytest +import configs.privatelink_config as pl +from gnmi_utils import apply_messages +from packets import outbound_pl_packets +import ptf.testutils as testutils +from constants import LOCAL_PTF_INTF +from ipaddress import ip_interface +import logging + +logger = logging.getLogger(__name__) + + +@pytest.fixture(scope="module") +def dpu_ip(duthost, dpu_index): + cmd = f"ip addr show | grep Ethernet-BP{dpu_index} | grep inet | awk '{{print $2}}'" + npu_interface_ip = ip_interface(duthost.shell(cmd)["stdout"].strip()) + return npu_interface_ip.ip + 1 + + +@pytest.fixture(scope="module", autouse=True) +def add_dpu_static_route(duthost, dpu_ip): + cmd = f"ip route replace {pl.SIP}/32 via {dpu_ip}" + duthost.shell(cmd) + + yield + + duthost.shell(f"ip route del {pl.SIP}") + + +@pytest.fixture +def common_setup_teardown(localhost, duthost, ptfhost, dpu_index): + logger.info("Programming DPU through gNMI") + logger.info("DPU configs:") + logger.info(pl.ROUTING_TYPE_PL_CONFIG) + apply_messages(localhost, duthost, ptfhost, pl.ROUTING_TYPE_PL_CONFIG, dpu_index) + messages = { + **pl.APPLIANCE_CONFIG, + **pl.VNET_CONFIG, + **pl.ENI_CONFIG, + **pl.VNET_MAPPING_CONFIG, + **pl.ROUTE_GROUP1_CONFIG + } + logger.info(messages) + + apply_messages(localhost, duthost, ptfhost, messages, dpu_index) + + messages = { + **pl.ROUTE_VNET_CONFIG, + **pl.ENI_ROUTE_GROUP1_CONFIG + } + logger.info(messages) + apply_messages(localhost, duthost, ptfhost, messages, dpu_index) + + return + + +def test_privatelink_basic_transform( + ptfadapter, + common_setup_teardown, + dash_pl_config, + localhost, + duthost, + ptfhost, + dpu_index, + minigraph_facts, + config_facts, +): + pc_member_config = config_facts["PORTCHANNEL_MEMBER"] + member_ports = [] + for member_config in pc_member_config.values(): + for member in member_config: + member_ports.append(member) + + expected_ptf_ports = [minigraph_facts["minigraph_ptf_indices"][port] for port in member_ports] + logger.info(f"Expecting transformed packet on PTF ports: {expected_ptf_ports}") + pkt, exp_pkt = outbound_pl_packets(dash_pl_config) + testutils.send(ptfadapter, dash_pl_config[LOCAL_PTF_INTF], pkt, 1) + testutils.verify_packet_any_port(ptfadapter, exp_pkt, expected_ptf_ports) From c9fdb123fd74bc8b125820920ac990bca014a7e3 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Sat, 28 Sep 2024 01:55:04 +0000 Subject: [PATCH 4/5] improve config formatting Signed-off-by: Lawrence Lee --- tests/dash/configs/privatelink_config.py | 167 ++++++++--------------- tests/dash/gnmi_utils.py | 15 +- tests/dash/packets.py | 28 ++-- tests/dash/proto_utils.py | 106 ++++++++++++-- tests/dash/test_dash_privatelink.py | 21 ++- 5 files changed, 181 insertions(+), 156 deletions(-) diff --git a/tests/dash/configs/privatelink_config.py b/tests/dash/configs/privatelink_config.py index 6b420fc4fd..f1113878d1 100644 --- a/tests/dash/configs/privatelink_config.py +++ b/tests/dash/configs/privatelink_config.py @@ -1,17 +1,5 @@ -import base64 -import socket -import uuid -from ipaddress import ip_address as IP - -from dash_api.appliance_pb2 import Appliance -from dash_api.vnet_pb2 import Vnet -from dash_api.eni_pb2 import Eni, State -from dash_api.eni_route_pb2 import EniRoute -from dash_api.route_pb2 import Route -from dash_api.vnet_mapping_pb2 import VnetMapping -from dash_api.route_type_pb2 import RouteType, RoutingType, ActionType, EncapType -from dash_api.route_group_pb2 import RouteGroup -from google.protobuf.json_format import ParseDict +from dash_api.eni_pb2 import State +from dash_api.route_type_pb2 import ActionType, EncapType, RoutingType VNET_ENCAP = "vnet_encap" VNET_DIRECT = "vnet_direct" @@ -51,125 +39,84 @@ ROUTE_GROUP1_GUID = "48af6ce8-26cc-4293-bfa6-0126e8fcdeb2" ROUTE_GROUP2_GUID = "58cf62e0-22cc-4693-baa6-012358fcdec9" + APPLIANCE_CONFIG = { - f"DASH_APPLIANCE_TABLE:{APPLIANCE_ID}": - ParseDict({ - "sip": { - "ipv4": socket.htonl(int(IP(SIP))) - }, - "vm_vni": int(VM_VNI) - }, Appliance()) + f"DASH_APPLIANCE_TABLE:{APPLIANCE_ID}": { + "sip": SIP, + "vm_vni": VM_VNI + } } VNET_CONFIG = { - f"DASH_VNET_TABLE:{VNET1}": - ParseDict({ - "vni": VNET1_VNI, - "guid": { - "value": base64.b64encode(bytes.fromhex(uuid.UUID(VNET1_GUID).hex)) - } - }, Vnet()) + f"DASH_VNET_TABLE:{VNET1}": { + "vni": VNET1_VNI, + "guid": VNET1_GUID + } } ENI_CONFIG = { - f"DASH_ENI_TABLE:{ENI_ID}": - ParseDict({ - "vnet": VNET1, - "underlay_ip": { - "ipv4": socket.htonl(int(IP(INBOUND_UNDERLAY_IP))) - }, - "mac_address": base64.b64encode(bytes.fromhex(ENI_MAC_STRING)), - "eni_id": ENI_ID, - "admin_state": State.STATE_ENABLED, - "pl_underlay_sip": { - "ipv4": socket.htonl(int(IP(PL_UNDERLAY_SIP1))) - }, - "pl_sip_encoding": { - "ip": { - "ipv6": base64.b64encode(IP(PL_ENCODING_IP).packed) - }, - "mask": { - "ipv6": base64.b64encode(IP(PL_ENCODING_MASK).packed) - } - } - }, Eni()) + f"DASH_ENI_TABLE:{ENI_ID}": { + "vnet": VNET1, + "underlay_ip": INBOUND_UNDERLAY_IP, + "mac_address": ENI_MAC, + "eni_id": ENI_ID, + "admin_state": State.STATE_ENABLED, + "pl_underlay_sip": PL_UNDERLAY_SIP1, + "pl_sip_encoding": f"{PL_ENCODING_IP}/{PL_ENCODING_MASK}" + } } VNET_MAPPING_CONFIG = { - f"DASH_VNET_MAPPING_TABLE:{VNET1}:{VNET_MAP_IP1}": - ParseDict({ - "mac_address": base64.b64encode(bytes.fromhex(REMOTE_MAC_STRING)), - "routing_type": RoutingType.ROUTING_TYPE_PRIVATELINK, - "underlay_ip": { - "ipv4": socket.htonl(int(IP(OUTBOUND_UNDERLAY_IP))) - }, - "overlay_sip_prefix": { - "ip": { - "ipv6": base64.b64encode(IP(PL_OVERLAY_SIP).packed) - }, - "mask": { - "ipv6": base64.b64encode(IP(PL_OVERLAY_SIP_MASK).packed) - } - }, - "overlay_dip_prefix": { - "ip": { - "ipv6": base64.b64encode(IP(PL_OVERLAY_DIP).packed) - }, - "mask": { - "ipv6": base64.b64encode(IP(PL_OVERLAY_DIP_MASK).packed) - } - }, - }, VnetMapping()) + f"DASH_VNET_MAPPING_TABLE:{VNET1}:{VNET_MAP_IP1}": { + "mac_address": REMOTE_MAC_STRING, + "routing_type": RoutingType.ROUTING_TYPE_PRIVATELINK, + "underlay_ip": OUTBOUND_UNDERLAY_IP, + "overlay_sip_prefix": f"{PL_OVERLAY_SIP}/{PL_OVERLAY_SIP_MASK}", + "overlay_dip_prefix": f"{PL_OVERLAY_DIP}/{PL_OVERLAY_DIP_MASK}", + } } ROUTE_VNET_CONFIG = { - f"DASH_ROUTE_TABLE:{ROUTE_GROUP1}:{OUTBOUND_ROUTE_PREFIX1}": - ParseDict({ - "routing_type": RoutingType.ROUTING_TYPE_VNET, - "vnet": VNET1, - }, Route()) + f"DASH_ROUTE_TABLE:{ROUTE_GROUP1}:{OUTBOUND_ROUTE_PREFIX1}": { + "routing_type": RoutingType.ROUTING_TYPE_VNET, + "vnet": VNET1, + } } ROUTE_VNET_CONFIG_UNDERLAY_SIP = { - f"DASH_ROUTE_TABLE:{ROUTE_GROUP2}:{OUTBOUND_ROUTE_PREFIX2}": - ParseDict({ - "routing_type": RoutingType.ROUTING_TYPE_VNET, - "vnet": VNET1, - "underlay_sip": { - "ipv4": socket.htonl(int(IP(PL_UNDERLAY_SIP2))) - } - }, Route()) + f"DASH_ROUTE_TABLE:{ROUTE_GROUP2}:{OUTBOUND_ROUTE_PREFIX2}": { + "routing_type": RoutingType.ROUTING_TYPE_VNET, + "vnet": VNET1, + "underlay_sip": PL_UNDERLAY_SIP2, + } } ROUTING_TYPE_PL_CONFIG = { - f"DASH_ROUTING_TYPE_TABLE:{PRIVATELINK}": - ParseDict({ - "items": [ - { - "action_name": "action1", - "action_type": ActionType.ACTION_TYPE_4_to_6 - }, - { - "action_name": "action2", - "action_type": ActionType.ACTION_TYPE_STATICENCAP, - "encap_type": EncapType.ENCAP_TYPE_NVGRE, - "vni": ENCAP_VNI - } - ] - }, RouteType()) + f"DASH_ROUTING_TYPE_TABLE:{PRIVATELINK}": { + "items": [ + { + "action_name": "action1", + "action_type": ActionType.ACTION_TYPE_4_to_6 + }, + { + "action_name": "action2", + "action_type": ActionType.ACTION_TYPE_STATICENCAP, + "encap_type": EncapType.ENCAP_TYPE_NVGRE, + "vni": ENCAP_VNI + } + ] + } } ROUTE_GROUP1_CONFIG = { - f"DASH_ROUTE_GROUP_TABLE:{ROUTE_GROUP1}": - ParseDict({ - "guid": ROUTE_GROUP1_GUID, - "version": "rg_version" - }, RouteGroup()) + f"DASH_ROUTE_GROUP_TABLE:{ROUTE_GROUP1}": { + "guid": ROUTE_GROUP1_GUID, + "version": "rg_version" + } } ENI_ROUTE_GROUP1_CONFIG = { - f"DASH_ENI_ROUTE_TABLE:{ENI_ID}": - ParseDict({ - "group_id": ROUTE_GROUP1 - }, EniRoute()) + f"DASH_ENI_ROUTE_TABLE:{ENI_ID}": { + "group_id": ROUTE_GROUP1 + } } diff --git a/tests/dash/gnmi_utils.py b/tests/dash/gnmi_utils.py index bd812a203b..20b4b8c52c 100644 --- a/tests/dash/gnmi_utils.py +++ b/tests/dash/gnmi_utils.py @@ -1,12 +1,12 @@ -import logging import json +import logging +import math import time import uuid -import math from functools import lru_cache -import pytest import proto_utils +import pytest logger = logging.getLogger(__name__) @@ -339,16 +339,17 @@ def apply_messages( env = GNMIEnvironment(duthost) update_list = [] delete_list = [] - for i, (key, message) in enumerate(messages.items()): + for i, (key, config_dict) in enumerate(messages.items()): + message = proto_utils.parse_dash_proto(key, config_dict) keys = key.split(":", 1) - k = keys[0] + "[key=" + keys[1] + "]" + gnmi_key = keys[0] + "[key=" + keys[1] + "]" filename = f"update{i}" if set: if proto_utils.ENABLE_PROTO: - path = f"/APPL_DB/dpu{dpu_index}/{k}:$/root/{filename}" + path = f"/APPL_DB/dpu{dpu_index}/{gnmi_key}:$/root/{filename}" else: - path = f"/APPL_DB/dpu{dpu_index}/{k}:@/root/{filename}" + path = f"/APPL_DB/dpu{dpu_index}/{gnmi_key}:@/root/{filename}" with open(env.work_dir + filename, "wb") as file: file.write(message.SerializeToString()) update_list.append(path) diff --git a/tests/dash/packets.py b/tests/dash/packets.py index 8b39cba88f..fb2fd7bfcb 100644 --- a/tests/dash/packets.py +++ b/tests/dash/packets.py @@ -1,18 +1,18 @@ +import logging +import sys +import time from ipaddress import ip_address import ptf.packet as scapy -import scapy.utils as scapy_utils -from ptf.mask import Mask import ptf.testutils as testutils -from ptf.dataplane import match_exp_pkt +import scapy.utils as scapy_utils +from configs import privatelink_config as pl from constants import * # noqa: F403 -import logging -import sys -import time -from tests.common.helpers.assertions import pytest_assert +from ptf.dataplane import match_exp_pkt +from ptf.mask import Mask from six import StringIO -from configs import privatelink_config as pl +from tests.common.helpers.assertions import pytest_assert logger = logging.getLogger(__name__) @@ -105,22 +105,20 @@ def outbound_pl_packets(config, inner_packet_type='udp', vxlan_udp_dport=4789): exp_inner_packet[scapy.UDP] = inner_packet[scapy.UDP] exp_encap_packet = testutils.simple_gre_packet( + eth_src=config[DUT_MAC], ip_src=pl.PL_UNDERLAY_SIP1, ip_dst=pl.OUTBOUND_UNDERLAY_IP, gre_key_present=True, - gre_key=pl.ENCAP_VNI, + gre_key=pl.ENCAP_VNI << 8, inner_frame=exp_inner_packet, ip_id=0, ip_ttl=63, ) masked_exp_packet = Mask(exp_encap_packet) - masked_exp_packet.set_do_not_care_scapy(scapy.Ether, "src") - masked_exp_packet.set_do_not_care_scapy(scapy.Ether, "dst") - masked_exp_packet.set_do_not_care_scapy(scapy.IP, "chksum") - - # Temporarily ignore GRE key - masked_exp_packet.set_do_not_care_scapy(scapy.GRE, "key") + masked_exp_packet.set_do_not_care_packet(scapy.Ether, "src") + masked_exp_packet.set_do_not_care_packet(scapy.Ether, "dst") + masked_exp_packet.set_do_not_care_packet(scapy.IP, "chksum") return vxlan_packet, masked_exp_packet diff --git a/tests/dash/proto_utils.py b/tests/dash/proto_utils.py index 23a6e0b458..3167870681 100644 --- a/tests/dash/proto_utils.py +++ b/tests/dash/proto_utils.py @@ -1,27 +1,111 @@ +import base64 +import ipaddress import re import socket -import ipaddress import uuid -import pytest +from ipaddress import ip_address +import pytest +from dash_api.acl_group_pb2 import AclGroup +from dash_api.acl_in_pb2 import AclIn +from dash_api.acl_out_pb2 import AclOut +from dash_api.acl_rule_pb2 import AclRule, Action from dash_api.appliance_pb2 import Appliance -from dash_api.vnet_pb2 import Vnet from dash_api.eni_pb2 import Eni, State +from dash_api.eni_route_pb2 import EniRoute +from dash_api.prefix_tag_pb2 import PrefixTag from dash_api.qos_pb2 import Qos +from dash_api.route_group_pb2 import RouteGroup from dash_api.route_pb2 import Route from dash_api.route_rule_pb2 import RouteRule +from dash_api.route_type_pb2 import (ActionType, RouteType, RouteTypeItem, + RoutingType) +from dash_api.types_pb2 import IpPrefix, IpVersion, ValueOrRange from dash_api.vnet_mapping_pb2 import VnetMapping -from dash_api.route_type_pb2 import RoutingType, ActionType, RouteType, RouteTypeItem -from dash_api.types_pb2 import IpVersion, IpPrefix, ValueOrRange -from dash_api.acl_group_pb2 import AclGroup -from dash_api.acl_out_pb2 import AclOut -from dash_api.acl_in_pb2 import AclIn -from dash_api.acl_rule_pb2 import AclRule, Action -from dash_api.prefix_tag_pb2 import PrefixTag - +from dash_api.vnet_pb2 import Vnet +from google.protobuf.descriptor import FieldDescriptor +from google.protobuf.json_format import ParseDict ENABLE_PROTO = True +PB_INT_TYPES = set([ + FieldDescriptor.TYPE_INT32, + FieldDescriptor.TYPE_INT64, + FieldDescriptor.TYPE_UINT32, + FieldDescriptor.TYPE_UINT64, + FieldDescriptor.TYPE_FIXED64, + FieldDescriptor.TYPE_FIXED32, + FieldDescriptor.TYPE_SFIXED32, + FieldDescriptor.TYPE_SFIXED64, + FieldDescriptor.TYPE_SINT32, + FieldDescriptor.TYPE_SINT64 +]) + +PB_CLASS_MAP = { + "APPLIANCE": Appliance, + "VNET": Vnet, + "ENI": Eni, + "VNET_MAPPING": VnetMapping, + "ROUTE": Route, + "ROUTING_TYPE": RouteType, + "ROUTE_GROUP": RouteGroup, + "ENI_ROUTE": EniRoute, +} + + +def parse_ip_address(ip_str): + ip_addr = ip_address(ip_str) + if ip_addr.version == 4: + encoded_val = socket.htonl(int(ip_addr)) + else: + encoded_val = base64.b64encode(ip_addr.packed) + + return {f"ipv{ip_addr.version}": encoded_val} + + +def parse_ip_prefix(ip_prefix_str): + ip_addr, mask = ip_prefix_str.split("/") + return {"ip": parse_ip_address(ip_addr), "mask": parse_ip_address(ip_address(mask))} + + +def parse_byte_field(orig_val): + return base64.b64encode(bytes.fromhex(orig_val.replace(":", ""))) + + +def parse_guid(guid_str): + return {"value": parse_byte_field(uuid.UUID(guid_str).hex)} + + +def parse_dash_proto(key: str, proto_dict: dict): + """ + Custom parser for DASH configs to allow writing configs + in a more human-readable format + """ + table_name = re.search(r"DASH_(\w+)_TABLE", key).group(1) + message = PB_CLASS_MAP[table_name]() + field_map = message.DESCRIPTOR.fields_by_name + new_dict = {} + for key, value in proto_dict.items(): + if field_map[key].type == field_map[key].TYPE_MESSAGE: + + if field_map[key].message_type.name == "IpAddress": + new_dict[key] = parse_ip_address(value) + elif field_map[key].message_type.name == "IpPrefix": + new_dict[key] = parse_ip_prefix(value) + elif field_map[key].message_type.name == "Guid": + new_dict[key] = parse_guid(value) + + elif field_map[key].type == field_map[key].TYPE_BYTES: + new_dict[key] = parse_byte_field(value) + + elif field_map[key].type in PB_INT_TYPES: + new_dict[key] = int(value) + + if key not in new_dict: + new_dict[key] = value + + return ParseDict(new_dict, message) + def appliance_from_json(json_obj): pb = Appliance() diff --git a/tests/dash/test_dash_privatelink.py b/tests/dash/test_dash_privatelink.py index c9f444df36..ac40a00fc0 100644 --- a/tests/dash/test_dash_privatelink.py +++ b/tests/dash/test_dash_privatelink.py @@ -1,11 +1,12 @@ -import pytest +import logging +from ipaddress import ip_interface + import configs.privatelink_config as pl -from gnmi_utils import apply_messages -from packets import outbound_pl_packets import ptf.testutils as testutils +import pytest from constants import LOCAL_PTF_INTF -from ipaddress import ip_interface -import logging +from gnmi_utils import apply_messages +from packets import outbound_pl_packets logger = logging.getLogger(__name__) @@ -27,10 +28,8 @@ def add_dpu_static_route(duthost, dpu_ip): duthost.shell(f"ip route del {pl.SIP}") -@pytest.fixture +@pytest.fixture(autouse=True) def common_setup_teardown(localhost, duthost, ptfhost, dpu_index): - logger.info("Programming DPU through gNMI") - logger.info("DPU configs:") logger.info(pl.ROUTING_TYPE_PL_CONFIG) apply_messages(localhost, duthost, ptfhost, pl.ROUTING_TYPE_PL_CONFIG, dpu_index) messages = { @@ -56,12 +55,7 @@ def common_setup_teardown(localhost, duthost, ptfhost, dpu_index): def test_privatelink_basic_transform( ptfadapter, - common_setup_teardown, dash_pl_config, - localhost, - duthost, - ptfhost, - dpu_index, minigraph_facts, config_facts, ): @@ -74,5 +68,6 @@ def test_privatelink_basic_transform( expected_ptf_ports = [minigraph_facts["minigraph_ptf_indices"][port] for port in member_ports] logger.info(f"Expecting transformed packet on PTF ports: {expected_ptf_ports}") pkt, exp_pkt = outbound_pl_packets(dash_pl_config) + ptfadapter.dataplane.flush() testutils.send(ptfadapter, dash_pl_config[LOCAL_PTF_INTF], pkt, 1) testutils.verify_packet_any_port(ptfadapter, exp_pkt, expected_ptf_ports) From dd59d33f17bb5818387960082ab742318b3504d6 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Mon, 30 Sep 2024 19:58:28 +0000 Subject: [PATCH 5/5] remove unused config Signed-off-by: Lawrence Lee --- tests/dash/configs/privatelink_config.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/dash/configs/privatelink_config.py b/tests/dash/configs/privatelink_config.py index f1113878d1..5971c3d678 100644 --- a/tests/dash/configs/privatelink_config.py +++ b/tests/dash/configs/privatelink_config.py @@ -83,14 +83,6 @@ } } -ROUTE_VNET_CONFIG_UNDERLAY_SIP = { - f"DASH_ROUTE_TABLE:{ROUTE_GROUP2}:{OUTBOUND_ROUTE_PREFIX2}": { - "routing_type": RoutingType.ROUTING_TYPE_VNET, - "vnet": VNET1, - "underlay_sip": PL_UNDERLAY_SIP2, - } -} - ROUTING_TYPE_PL_CONFIG = { f"DASH_ROUTING_TYPE_TABLE:{PRIVATELINK}": { "items": [