Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
137 changes: 137 additions & 0 deletions tests/dash/configs/privatelink_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
from dash_api.eni_pb2 import State
from dash_api.route_type_pb2 import ActionType, EncapType, RoutingType

VNET = "vnet"
VNET_ENCAP = "vnet_encap"
VNET_DIRECT = "vnet_direct"
PRIVATELINK = "privatelink"
DECAP = "decap"

APPLIANCE_VIP = "10.1.0.5"
VM1_PA = "25.1.1.1" # VM host physical address
VM1_CA = "10.0.0.11" # VM customer address
VM_CA_SUBNET = "10.0.0.0/16"
PE_PA = "101.1.2.3" # private endpoint physical address
PE_CA = "10.2.0.100" # private endpoint customer address
PE_CA_SUBNET = "10.2.0.0/16"
PL_ENCODING_IP = "::56b2:0:ff71:0:0"
PL_ENCODING_MASK = "::ffff:ffff:ffff:0:0"
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": APPLIANCE_VIP,
"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": VM1_PA,
"mac_address": ENI_MAC,
"eni_id": ENI_ID,
"admin_state": State.STATE_ENABLED,
"pl_underlay_sip": APPLIANCE_VIP,
"pl_sip_encoding": f"{PL_ENCODING_IP}/{PL_ENCODING_MASK}"
}
}

PE_VNET_MAPPING_CONFIG = {
f"DASH_VNET_MAPPING_TABLE:{VNET1}:{PE_CA}": {
"routing_type": RoutingType.ROUTING_TYPE_PRIVATELINK,
"underlay_ip": PE_PA,
"overlay_sip_prefix": f"{PL_OVERLAY_SIP}/{PL_OVERLAY_SIP_MASK}",
"overlay_dip_prefix": f"{PL_OVERLAY_DIP}/{PL_OVERLAY_DIP_MASK}",
}
}

VM1_VNET_MAPPING_CONFIG = {
f"DASH_VNET_MAPPING_TABLE:{VNET1}:{VM1_CA}": {
"routing_type": RoutingType.ROUTING_TYPE_VNET,
"underlay_ip": VM1_PA,
}
}

PE_SUBNET_ROUTE_CONFIG = {
f"DASH_ROUTE_TABLE:{ROUTE_GROUP1}:{PE_CA_SUBNET}": {
"routing_type": RoutingType.ROUTING_TYPE_VNET,
"vnet": VNET1,
}
}

VM_SUBNET_ROUTE_CONFIG = {
f"DASH_ROUTE_TABLE:{ROUTE_GROUP1}:{VM_CA_SUBNET}": {
"routing_type": RoutingType.ROUTING_TYPE_VNET,
"vnet": VNET1,
}
}

ROUTING_TYPE_VNET_CONFIG = {
f"DASH_ROUTING_TYPE_TABLE:{VNET}": {
"items": [
{
"action_name": "action1",
"action_type": ActionType.ACTION_TYPE_STATICENCAP,
"encap_type": EncapType.ENCAP_TYPE_VXLAN,
},
]
}
}

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
}
}
57 changes: 51 additions & 6 deletions tests/dash/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import time

from ipaddress import ip_interface
from constants import ENI, VM_VNI, VNET1_VNI, VNET2_VNI, REMOTE_CA_IP, LOCAL_CA_IP, REMOTE_ENI_MAC,\
LOCAL_ENI_MAC, REMOTE_CA_PREFIX, LOOPBACK_IP, DUT_MAC, LOCAL_PA_IP, LOCAL_PTF_INTF, LOCAL_PTF_MAC,\
from constants import ENI, VM_VNI, VNET1_VNI, VNET2_VNI, REMOTE_CA_IP, LOCAL_CA_IP, REMOTE_ENI_MAC, \
LOCAL_ENI_MAC, REMOTE_CA_PREFIX, LOOPBACK_IP, DUT_MAC, LOCAL_PA_IP, LOCAL_PTF_INTF, LOCAL_PTF_MAC, \
REMOTE_PA_IP, REMOTE_PTF_INTF, REMOTE_PTF_MAC, REMOTE_PA_PREFIX, VNET1_NAME, VNET2_NAME, ROUTING_ACTION, \
ROUTING_ACTION_TYPE, LOOKUP_OVERLAY_IP, ACL_GROUP, ACL_STAGE
ROUTING_ACTION_TYPE, LOOKUP_OVERLAY_IP, ACL_GROUP, ACL_STAGE, LOCAL_DUT_INTF, REMOTE_DUT_INTF, \
REMOTE_PTF_SEND_INTF, REMOTE_PTF_RECV_INTF
from dash_utils import render_template_to_host, apply_swssconfig_file
from gnmi_utils import generate_gnmi_cert, apply_gnmi_cert, recover_gnmi_cert, apply_gnmi_file
from dash_acl import AclGroup, DEFAULT_ACL_GROUP, WAIT_AFTER_CONFIG, DefaultAclRule
Expand Down Expand Up @@ -114,12 +115,47 @@ 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(scope="module")
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 LOCAL_PTF_INTF not in dash_info and 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_DUT_INTF] = intf
dash_info[LOCAL_PTF_MAC] = neigh_table["v4"][neigh_ip]["macaddress"]
if REMOTE_PTF_INTF not in dash_info and config["name"].endswith("T2"):
intf, _ = get_intf_from_ip(config['local_addr'], config_facts)
intfs = list(config_facts["PORTCHANNEL_MEMBER"][intf].keys())
dash_info[REMOTE_PTF_SEND_INTF] = minigraph_facts["minigraph_ptf_indices"][intfs[0]]
dash_info[REMOTE_PTF_RECV_INTF] = [minigraph_facts["minigraph_ptf_indices"][i] for i in intfs]
dash_info[REMOTE_DUT_INTF] = intf
dash_info[REMOTE_PTF_MAC] = neigh_table["v4"][neigh_ip]["macaddress"]

if REMOTE_PTF_INTF in dash_info and LOCAL_PTF_INTF in dash_info:
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 +184,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 +208,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 +394,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
4 changes: 4 additions & 0 deletions tests/dash/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
REMOTE_PA_PREFIX = "remote_pa_prefix"
LOCAL_PTF_INTF = "local_ptf_intf"
REMOTE_PTF_INTF = "remote_ptf_intf"
LOCAL_DUT_INTF = "local_dut_intf"
REMOTE_DUT_INTF = "remote_dut_intf"
REMOTE_PTF_SEND_INTF = "remote_ptf_send_intf"
REMOTE_PTF_RECV_INTF = "remote_ptf_recv_intf"
ROUTING_ACTION = "routing_action"
ROUTING_ACTION_TYPE = "routing_action_type"
LOOKUP_OVERLAY_IP = "lookup_overlay_ip"
Expand Down
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_db=True,
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_db:
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}/{gnmi_key}"
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