Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions tests/dash/configs/privatelink_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
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"
PRIVATELINK = "privatelink"
DECAP = "decap"

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.5"
VNET_MAP_IP2 = "10.1.2.5"
Comment thread
theasianpianist marked this conversation as resolved.
Outdated
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"
PL_UNDERLAY_SIP1 = "55.1.2.3"
PL_UNDERLAY_SIP2 = "55.2.3.4"
Comment thread
theasianpianist marked this conversation as resolved.
Outdated
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"
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"
ROUTE_GROUP1_GUID = "48af6ce8-26cc-4293-bfa6-0126e8fcdeb2"
ROUTE_GROUP2_GUID = "58cf62e0-22cc-4693-baa6-012358fcdec9"


APPLIANCE_CONFIG = {
f"DASH_APPLIANCE_TABLE:{APPLIANCE_ID}": {
"sip": SIP,
"vm_vni": VM_VNI
}
}

VNET_CONFIG = {
f"DASH_VNET_TABLE:{VNET1}": {
"vni": VNET1_VNI,
"guid": VNET1_GUID
}
}

ENI_CONFIG = {
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,
Comment thread
theasianpianist marked this conversation as resolved.
Outdated
"pl_sip_encoding": f"{PL_ENCODING_IP}/{PL_ENCODING_MASK}"
}
}

VNET_MAPPING_CONFIG = {
f"DASH_VNET_MAPPING_TABLE:{VNET1}:{VNET_MAP_IP1}": {
"mac_address": REMOTE_MAC_STRING,
Comment thread
theasianpianist marked this conversation as resolved.
Outdated
"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}": {
"routing_type": RoutingType.ROUTING_TYPE_VNET,
"vnet": VNET1,
}
}

ROUTING_TYPE_PL_CONFIG = {
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}": {
"guid": ROUTE_GROUP1_GUID,
"version": "rg_version"
}
}

ENI_ROUTE_GROUP1_CONFIG = {
f"DASH_ENI_ROUTE_TABLE:{ENI_ID}": {
"group_id": ROUTE_GROUP1
}
}
39 changes: 36 additions & 3 deletions tests/dash/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,36 @@ 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):
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 = {
Expand Down Expand Up @@ -148,11 +172,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:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need to add smartswitch-t1 topo as well here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll do this later. Ok to merge for now.

# 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,
Expand All @@ -170,8 +196,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)
Expand Down Expand Up @@ -354,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
57 changes: 49 additions & 8 deletions tests/dash/gnmi_utils.py
Original file line number Diff line number Diff line change
@@ -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__)

Expand All @@ -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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@theasianpianist , why change dash test case always enable ZMQ on GNMI?
If someone run these test case on a device not enable ZMQ on orchagent side, some test case may failed, can you check this change?

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"
Expand Down Expand Up @@ -267,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']:
Expand Down Expand Up @@ -324,6 +326,41 @@ def gnmi_get(duthost, ptfhost, path_list):
raise Exception("error:" + msg)


def apply_messages(
localhost,
duthost,
ptfhost,
messages,
dpu_index,
set=True,
Comment thread
theasianpianist marked this conversation as resolved.
Outdated
wait_after_apply=5,
max_updates_in_single_cmd=1024,
):
env = GNMIEnvironment(duthost)
update_list = []
delete_list = []
for i, (key, config_dict) in enumerate(messages.items()):
message = proto_utils.parse_dash_proto(key, config_dict)
keys = key.split(":", 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}/{gnmi_key}:$/root/{filename}"
else:
path = f"/APPL_DB/dpu{dpu_index}/{gnmi_key}:@/root/{filename}"
Comment thread
theasianpianist marked this conversation as resolved.
with open(env.work_dir + filename, "wb") as file:
file.write(message.SerializeToString())
update_list.append(path)
else:
path = f"/APPL_DB/dpu{dpu_index}/{filename}"
Comment thread
theasianpianist marked this conversation as resolved.
Outdated
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):
"""
Expand Down Expand Up @@ -371,20 +408,25 @@ 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)
Comment thread
theasianpianist marked this conversation as resolved.
update_list.append(path)
elif operation["OP"] == "DEL":
for k, v in operation.items():
if k == "OP":
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"])
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')
Expand All @@ -410,4 +452,3 @@ def _devide_list(operation_list):
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)
Loading