22import pytest
33import ptf .testutils as testutils
44import packets
5+ import time
6+ import json
57
6- from constants import LOCAL_PTF_INTF , REMOTE_PA_IP , REMOTE_PTF_RECV_INTF , REMOTE_DUT_INTF
8+ from constants import LOCAL_PTF_INTF , REMOTE_PA_IP , REMOTE_PTF_RECV_INTF , REMOTE_DUT_INTF , \
9+ VXLAN_UDP_BASE_SRC_PORT , VXLAN_UDP_SRC_PORT_MASK
710from gnmi_utils import apply_gnmi_file
811from dash_utils import render_template_to_host , apply_swssconfig_file
912from tests .dash .conftest import get_interface_ip
13+ from tests .common import config_reload
1014
1115APPLIANCE_VIP = "10.1.0.5"
1216ENABLE_GNMI_API = True
2125
2226"""
2327Test prerequisites:
24- - DPU needs the Appliance VIP configured as its loopback IP
2528- Assign IPs to DPU-NPU dataplane interfaces
26- - Default route on DPU to NPU
2729"""
2830
2931
3032@pytest .fixture (scope = "module" , autouse = True )
31- def add_dpu_static_route (duthost , dpu_ip ):
32- cmd = f"ip route replace { APPLIANCE_VIP } /32 via { dpu_ip } "
33- duthost .shell (cmd )
33+ def dpu_setup_vnet (duthost , dpuhosts , dpu_index , skip_config ):
34+ if skip_config :
3435
35- yield
36+ return
37+ dpuhost = dpuhosts [dpu_index ]
38+ # explicitly add mgmt IP route so the default route doesn't disrupt SSH access
39+ dpuhost .shell (f'ip route replace { duthost .mgmt_ip } /32 via 169.254.200.254' )
40+ intfs = dpuhost .shell ("show ip int" )["stdout" ]
41+ dpu_cmds = list ()
42+ if "Loopback0" not in intfs :
43+ dpu_cmds .append ("config loopback add Loopback0" )
44+ dpu_cmds .append (f"config int ip add Loopback0 { APPLIANCE_VIP } /32" )
3645
37- duthost .shell (f"ip route del { APPLIANCE_VIP } /32 via { dpu_ip } " )
46+ dpu_cmds .append (f"ip route replace default via { dpuhost .npu_data_port_ip } " )
47+ dpuhost .shell_cmds (cmds = dpu_cmds )
3848
3949
4050@pytest .fixture (scope = "module" , autouse = True )
41- def add_npu_static_routes (duthost , dpu_ip , dash_smartswitch_vnet_config , skip_config , skip_cleanup ):
51+ def add_npu_static_routes_vnet (duthost , dash_smartswitch_vnet_config , skip_config , skip_cleanup , dpu_index , dpuhosts ):
4252 if not skip_config :
53+ dpuhost = dpuhosts [dpu_index ]
4354 cmds = []
4455 pe_nexthop_ip = get_interface_ip (duthost , dash_smartswitch_vnet_config [REMOTE_DUT_INTF ]).ip + 1
4556 cmds .append (f"ip route replace { dash_smartswitch_vnet_config [REMOTE_PA_IP ]} /32 via { pe_nexthop_ip } " )
57+ cmds .append (f"ip route replace { APPLIANCE_VIP } /32 via { dpuhost .dpu_data_port_ip } " )
4658 logger .info (f"Adding static routes: { cmds } " )
4759 duthost .shell_cmds (cmds = cmds )
4860
4961 yield
5062
5163 if not skip_config and not skip_cleanup :
64+ dpuhost = dpuhosts [dpu_index ]
5265 cmds = []
5366 cmds .append (f"ip route del { dash_smartswitch_vnet_config [REMOTE_PA_IP ]} /32 via { pe_nexthop_ip } " )
67+ cmds .append (f"ip route del { APPLIANCE_VIP } /32 via { dpuhost .dpu_data_port_ip } " )
5468 logger .info (f"Removing static routes: { cmds } " )
5569 duthost .shell_cmds (cmds = cmds )
5670
5771
58- @pytest .fixture (autouse = True )
59- def common_setup_teardown (localhost , duthost , ptfhost , dpu_index , dash_smartswitch_vnet_config , skip_config ):
72+ @pytest .fixture (scope = "module" , autouse = True )
73+ def set_vxlan_udp_sport_range (dpuhosts , dpu_index ):
74+ """
75+ Configure VXLAN UDP source port range in dpu configuration.
76+ """
77+ dpuhost = dpuhosts [dpu_index ]
78+ vxlan_sport_config = [
79+ {
80+ "SWITCH_TABLE:switch" : {
81+ "vxlan_sport" : VXLAN_UDP_BASE_SRC_PORT ,
82+ "vxlan_mask" : VXLAN_UDP_SRC_PORT_MASK
83+ },
84+ "OP" : "SET"
85+ }
86+ ]
87+
88+ logger .info (f"Setting VXLAN source port config: { vxlan_sport_config } " )
89+ config_path = "/tmp/vxlan_sport_config.json"
90+ dpuhost .copy (content = json .dumps (vxlan_sport_config , indent = 4 ), dest = config_path , verbose = False )
91+ apply_swssconfig_file (dpuhost , config_path )
92+ if 'pensando' in dpuhost .facts ['asic_type' ]:
93+ logger .warning ("Applying Pensando DPU VXLAN sport workaround" )
94+ dpuhost .shell ("pdsctl debug update device --vxlan-port 4789 --vxlan-src-ports 5120-5247" )
95+ yield
96+ if str (VXLAN_UDP_BASE_SRC_PORT ) in dpuhost .shell ("redis-cli -n 0 hget SWITCH_TABLE:switch vxlan_sport" )['stdout' ]:
97+ config_reload (dpuhost , safe_reload = True , yang_validate = False )
98+
99+
100+ @pytest .fixture (scope = "module" , autouse = True )
101+ def common_setup_teardown (
102+ localhost ,
103+ duthost ,
104+ ptfhost ,
105+ dpu_index ,
106+ dash_smartswitch_vnet_config ,
107+ skip_config ,
108+ dpuhosts ,
109+ add_npu_static_routes_vnet ,
110+ dpu_setup_vnet ,
111+ set_vxlan_udp_sport_range ):
60112 if skip_config :
61113 return
62114
63- host = f"dpu{ dpu_index } "
115+ dpuhost = dpuhosts [dpu_index ]
116+ host = f"dpu{ dpuhost .dpu_index } "
64117 op = "SET"
118+ # Until this fix and related are in 202506 release this workaround is needed
119+ # Issue observed is that first set of DASH objects is not configured
120+ # https://github.com/sonic-net/sonic-swss-common/pull/1068
121+ time .sleep (180 )
65122 for i in range (0 , 4 ):
66123 config = f"dash_smartswitch_vnet_{ i } "
67124 template_name = "{}.j2" .format (config )
@@ -74,29 +131,20 @@ def common_setup_teardown(localhost, duthost, ptfhost, dpu_index, dash_smartswit
74131
75132 yield
76133
77- op = "DEL"
78- for i in reversed (range (0 , 4 )):
79- config = f"dash_smartswitch_vnet_{ i } "
80- template_name = "{}.j2" .format (config )
81- dest_path = "/tmp/{}.json" .format (config )
82- render_template_to_host (template_name , duthost , dest_path , dash_smartswitch_vnet_config , op = op )
83- if ENABLE_GNMI_API :
84- apply_gnmi_file (localhost , duthost , ptfhost , dest_path , None , 5 , 1024 , host )
85- else :
86- apply_swssconfig_file (duthost , dest_path )
134+ # Route rule removal is broken so config reload to cleanup for now
135+ # https://github.com/sonic-net/sonic-buildimage/issues/23590
136+ config_reload (dpuhost , safe_reload = True , yang_validate = False )
87137
88138
89139def test_smartswitch_outbound_vnet (
90140 ptfadapter ,
91141 dash_smartswitch_vnet_config ,
92142 skip_dataplane_checking ,
93- inner_packet_type ,
94- vxlan_udp_dport ):
143+ inner_packet_type ):
95144
96145 if skip_dataplane_checking :
97146 return
98147 _ , vxlan_packet , expected_packet = packets .outbound_smartswitch_vnet_packets (dash_smartswitch_vnet_config ,
99- vxlan_udp_dport = vxlan_udp_dport ,
100148 inner_packet_type = inner_packet_type )
101149 ptfadapter .dataplane .flush ()
102150 testutils .send (ptfadapter , dash_smartswitch_vnet_config [LOCAL_PTF_INTF ], vxlan_packet , 1 )
0 commit comments