Skip to content

Commit 9008381

Browse files
[inner hahsing] extension of PBH tests (#4848)
Added coverage of multiple interface types(LAG) and all possible match fields in pbh_rule. Added 2 new tests: test_inner_hashing_lag.py, test_wr_inner_hashing_lag.py Signed-off-by: Anton <antonh@nvidia.com>
1 parent 3690281 commit 9008381

6 files changed

Lines changed: 365 additions & 100 deletions

File tree

ansible/roles/test/files/ptftests/inner_hash_test.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ def setUp(self):
7979
self.vxlan_port = self.test_params['vxlan_port']
8080
self.outer_encap_formats = self.test_params['outer_encap_formats']
8181
self.symmetric_hashing = self.test_params.get('symmetric_hashing', False)
82+
self.nvgre_tni = self.test_params.get('nvgre_tni', '')
8283
self.outer_dst_ip = self.outer_dst_ip_interval.get_first_ip()
8384

8485
self.next_hop = self.fib[self.outer_dst_ip]
@@ -226,6 +227,7 @@ def check_ipv4_route_nvgre(self, hash_key, src_port, ip_dst, ip_src, dport, spor
226227

227228
outer_ip_src = self.outer_src_ip_interval.get_random_ip() if hash_key == 'outer-tuples' else self.outer_src_ip_interval.get_first_ip()
228229
outer_ip_dst = self.outer_dst_ip_interval.get_random_ip() if hash_key == 'outer-tuples' else self.outer_dst_ip_interval.get_first_ip()
230+
nvgre_tni = self.nvgre_tni if self.nvgre_tni else random.randint(1, 254) + 20000
229231

230232
pkt = self.generate_inner_pkt(sport, dport, ip_src, ip_dst, ip_proto)
231233
nvgre_pkt = simple_nvgre_packet(
@@ -235,8 +237,9 @@ def check_ipv4_route_nvgre(self, hash_key, src_port, ip_dst, ip_src, dport, spor
235237
ip_src=outer_ip_src,
236238
ip_dst=outer_ip_dst,
237239
ip_ttl=64,
238-
nvgre_tni=random.randint(1, 254)+20000,
239-
inner_frame=pkt)
240+
inner_frame=pkt,
241+
nvgre_tni=nvgre_tni,
242+
nvgre_flowid=0)
240243

241244
logging.info("Sending packet from port {} outer_ip_src {} outer_ip_dst {} inner_src_ip {} inner_dst_ip {} inner_sport {} inner_dport {} inner_ipproto {}"\
242245
.format(src_port, outer_ip_src, outer_ip_dst, ip_src, ip_dst, sport, dport, ip_proto))
@@ -316,15 +319,17 @@ def check_ipv6_route_nvgre(self, hash_key, src_port, ip_dst, ip_src, dport, spor
316319

317320
outer_ip_src = self.outer_src_ip_interval.get_random_ip() if hash_key == 'outer-tuples' else self.outer_src_ip_interval.get_first_ip()
318321
outer_ip_dst = self.outer_dst_ip_interval.get_random_ip() if hash_key == 'outer-tuples' else self.outer_dst_ip_interval.get_first_ip()
322+
nvgre_tni = self.nvgre_tni if self.nvgre_tni else random.randint(1, 254) + 20000
319323

320324
pkt = self.generate_inner_pkt(sport, dport, ip_src, ip_dst, ip_proto)
321325
nvgre_pkt = self.simple_nvgrev6_packet(
322326
eth_dst=self.router_mac,
323327
eth_src=src_mac,
324328
ipv6_src=outer_ip_src,
325329
ipv6_dst=outer_ip_dst,
326-
nvgre_tni=random.randint(1, 254)+20000,
327-
inner_frame=pkt)
330+
inner_frame=pkt,
331+
nvgre_tni=nvgre_tni,
332+
nvgre_flowid=0)
328333

329334
logging.info("Sending packet from port {} outer_ip_src {} outer_ip_dst {} inner_src_ip {} inner_dst_ip {} inner_sport {} inner_dport {} inner_ipproto {}"\
330335
.format(src_port, outer_ip_src, outer_ip_dst, ip_src, ip_dst, sport, dport, ip_proto))

tests/ecmp/inner_hashing/conftest.py

Lines changed: 118 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44
import tempfile
55
import re
6+
import allure
67

78
from datetime import datetime
89

@@ -28,6 +29,7 @@
2829
VXLAN_PORT = 13330
2930
DUT_VXLAN_PORT_JSON_FILE = '/tmp/vxlan.switch.json'
3031

32+
T0_VLAN = "1000"
3133
IP_VERSIONS_LIST = ["ipv4", "ipv6"]
3234
OUTER_ENCAP_FORMATS = ["vxlan", "nvgre"]
3335
TABLE_NAME = "pbh_table"
@@ -42,10 +44,16 @@
4244
V6_ETHER_TYPE = "0x86dd"
4345
VXLAN_IP_PROTOCOL = "0x11"
4446
NVGRE_IP_PROTOCOL = "0x2f"
47+
GRE_KEY = "0x2500"
48+
NVGRE_TNI = 0x25
49+
GRE_MASK = "0xffffff00"
4550
VXLAN_L4_DST_PORT = "0x3412"
4651
VXLAN_L4_DST_PORT_OPTION = " --l4-dst-port {}".format(VXLAN_L4_DST_PORT)
52+
NVGRE_GRE_KEY_OPTION = " --gre-key {}/{}".format(GRE_KEY, GRE_MASK)
4753
ADD_PBH_TABLE_CMD = "sudo config pbh table add '{}' --interface-list '{}' --description '{}'"
4854
DEL_PBH_TABLE_CMD = "sudo config pbh table delete '{}'"
55+
ADD_PBH_RULE_BASE_CMD = "sudo config pbh rule add '{}' '{}' --priority '{}' --ether-type {}" \
56+
" --inner-ether-type '{}' --hash '{}' --packet-action '{}' --flow-counter 'ENABLED'"
4957
ADD_PBH_RULE_BASE_CMD = "sudo config pbh rule add '{}' '{}' --priority '{}' --ether-type {}" \
5058
" --inner-ether-type '{}' --hash '{}' --packet-action '{}' --flow-counter 'ENABLED'"
5159
DEL_PBH_RULE_CMD = "sudo config pbh rule delete '{}' '{}'"
@@ -181,6 +189,59 @@ def vlan_ptf_ports(config_facts, tbinfo, duthost):
181189
return ports
182190

183191

192+
@pytest.fixture(scope='module')
193+
def lag_port_map(duthost, config_facts, vlan_ptf_ports, tbinfo):
194+
'''
195+
Create lag-port map for vlan ptf ports
196+
'''
197+
portchannels = config_facts.get('PORTCHANNEL', {}).keys()
198+
mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
199+
port_list_idx = 0
200+
lag_port_map = {}
201+
port_key_list = list(mg_facts['minigraph_ptf_indices'].keys())
202+
port_val_list = list(mg_facts['minigraph_ptf_indices'].values())
203+
204+
for portchannel_idx in range(1, 10000): # Max len of PortChannel index can be '9999'
205+
lag_port = 'PortChannel{}'.format(portchannel_idx)
206+
207+
if lag_port not in portchannels:
208+
port_idx_value = vlan_ptf_ports[port_list_idx]
209+
position = port_val_list.index(port_idx_value)
210+
port_name = port_key_list[position]
211+
lag_port_map[lag_port] = port_name
212+
port_list_idx += 1
213+
214+
if len(lag_port_map) == len(vlan_ptf_ports):
215+
break
216+
217+
return lag_port_map
218+
219+
220+
@pytest.fixture(scope='module')
221+
def lag_ip_map(lag_port_map):
222+
index = 1
223+
base_ipv4_addr = '100.0.{}.1/31'
224+
base_ipv6_addr = 'fc00:{}::1/126'
225+
lag_ip_map = {}
226+
227+
for lag_port, _ in lag_port_map.items():
228+
ipv4_addr = base_ipv4_addr.format(index)
229+
ipv6_addr = base_ipv6_addr.format(index)
230+
lag_ip_map[lag_port] = {'ipv4': ipv4_addr, 'ipv6': ipv6_addr}
231+
index += 1
232+
233+
return lag_ip_map
234+
235+
236+
@pytest.fixture(scope='module')
237+
def config_lag_ports(duthost, lag_port_map, lag_ip_map):
238+
add_lag_config(duthost, lag_port_map, lag_ip_map)
239+
240+
yield
241+
242+
remove_lag_config(duthost, lag_port_map, lag_ip_map)
243+
244+
184245
@pytest.fixture(scope='module')
185246
def router_mac(duthosts, rand_one_dut_hostname):
186247
duthost = duthosts[rand_one_dut_hostname]
@@ -214,8 +275,23 @@ def inner_ipver(request):
214275
return request.param
215276

216277

278+
@pytest.fixture(scope="module")
279+
def config_pbh_table_lag(duthost, lag_port_map):
280+
logging.info("Create PBH table: {}".format(TABLE_NAME))
281+
test_intfs_str = ",".join(lag_port_map.keys())
282+
283+
duthost.command(ADD_PBH_TABLE_CMD.format(TABLE_NAME,
284+
test_intfs_str,
285+
TABLE_DESCRIPTION))
286+
287+
yield
288+
289+
duthost.command(DEL_PBH_TABLE_CMD.format(TABLE_NAME))
290+
291+
217292
@pytest.fixture(scope="module")
218293
def config_pbh_table(duthost, vlan_ptf_ports, tbinfo):
294+
logging.info("Create PBH table: {}".format(TABLE_NAME))
219295
test_intfs_str = get_dut_test_intfs_str(duthost, vlan_ptf_ports, tbinfo)
220296

221297
duthost.command(ADD_PBH_TABLE_CMD.format(TABLE_NAME,
@@ -239,6 +315,7 @@ def get_dut_test_intfs_str(duthost, vlan_ptf_ports, tbinfo):
239315

240316
@pytest.fixture(scope="module")
241317
def config_hash_fields(duthost):
318+
logging.info("Create PBH hash-fields")
242319
for hash_field, hash_field_params_dict in HASH_FIELD_CONFIG.items():
243320
cmd = get_hash_field_add_cmd(hash_field, hash_field_params_dict)
244321
duthost.command(cmd)
@@ -260,6 +337,7 @@ def get_hash_field_add_cmd(hash_field_name, hash_field_params_dict):
260337

261338
@pytest.fixture(scope="module")
262339
def config_hash(duthost):
340+
logging.info("Create PBH hash: {}".format(HASH_NAME))
263341
duthost.command(ADD_PBH_HASH_CMD.format(HASH_NAME, PBH_HASH_FIELD_LIST))
264342

265343
yield
@@ -291,6 +369,7 @@ def config_ipv6_rules(duthost, inner_ipver):
291369

292370

293371
def config_vxlan_rule(duthost, ip_ver_option, ether_type, outer_ipver, inner_ipver):
372+
logging.info("Create PBH rule: {}".format(VXLAN_RULE_NAME.format(outer_ipver, inner_ipver)))
294373
inner_ether_type = V4_ETHER_TYPE if inner_ipver == "ipv4" else V6_ETHER_TYPE
295374
duthost.command((ADD_PBH_RULE_BASE_CMD + ip_ver_option + VXLAN_L4_DST_PORT_OPTION)
296375
.format(TABLE_NAME,
@@ -305,8 +384,9 @@ def config_vxlan_rule(duthost, ip_ver_option, ether_type, outer_ipver, inner_ipv
305384

306385

307386
def config_nvgre_rule(duthost, ip_ver_option, ether_type, outer_ipver, inner_ipver):
387+
logging.info("Create PBH rule: {}".format(NVGRE_RULE_NAME.format(outer_ipver, inner_ipver)))
308388
inner_ether_type = V4_ETHER_TYPE if inner_ipver == "ipv4" else V6_ETHER_TYPE
309-
duthost.command((ADD_PBH_RULE_BASE_CMD + ip_ver_option)
389+
duthost.command((ADD_PBH_RULE_BASE_CMD + ip_ver_option + NVGRE_GRE_KEY_OPTION)
310390
.format(TABLE_NAME,
311391
NVGRE_RULE_NAME.format(outer_ipver, inner_ipver),
312392
NVGRE_RULE_PRIO,
@@ -341,16 +421,40 @@ def get_src_dst_ip_range(ipver):
341421

342422

343423
def check_pbh_counters(duthost, outer_ipver, inner_ipver, balancing_test_times, symmetric_hashing, hash_keys):
344-
symmetric_multiplier = 2 if symmetric_hashing else 1
345-
exp_port_multiplier = 4 # num of POs in t0 topology
346-
hash_keys_multiplier = len(hash_keys)
347-
# for hash key "ip-proto", the traffic sends always in one way
348-
exp_count = str((balancing_test_times * symmetric_multiplier * exp_port_multiplier * (hash_keys_multiplier-1))
349-
+ (balancing_test_times * exp_port_multiplier))
350-
pbh_statistic_output = duthost.shell("show pbh statistic")['stdout']
351-
for outer_encap_format in OUTER_ENCAP_FORMATS:
352-
regex = r'{}\s+{}_{}_{}\s+(\d+)\s+\d+'.format(TABLE_NAME, outer_encap_format, outer_ipver, inner_ipver)
353-
current_count = re.search(regex, pbh_statistic_output).group(1)
354-
assert current_count == exp_count,\
355-
"PBH counters are different from expected for {}, outer ipver {}, inner ipver {}. Expected: {}, " \
356-
"Current: {}".format(outer_encap_format, outer_ipver, inner_ipver, exp_count, current_count)
424+
logging.info('Verify PBH counters')
425+
with allure.step('Verify PBH counters'):
426+
symmetric_multiplier = 2 if symmetric_hashing else 1
427+
exp_port_multiplier = 4 # num of POs in t0 topology
428+
hash_keys_multiplier = len(hash_keys)
429+
# for hash key "ip-proto", the traffic sends always in one way
430+
exp_count = str((balancing_test_times * symmetric_multiplier * exp_port_multiplier * (hash_keys_multiplier-1))
431+
+ (balancing_test_times * exp_port_multiplier))
432+
pbh_statistic_output = duthost.shell("show pbh statistic")['stdout']
433+
for outer_encap_format in OUTER_ENCAP_FORMATS:
434+
regex = r'{}\s+{}_{}_{}\s+(\d+)\s+\d+'.format(TABLE_NAME, outer_encap_format, outer_ipver, inner_ipver)
435+
current_count = re.search(regex, pbh_statistic_output).group(1)
436+
assert current_count == exp_count,\
437+
"PBH counters are different from expected for {}, outer ipver {}, inner ipver {}. Expected: {}, " \
438+
"Current: {}".format(outer_encap_format, outer_ipver, inner_ipver, exp_count, current_count)
439+
440+
441+
def add_lag_config(duthost, lag_port_map, lag_ip_map):
442+
logging.info('Add LAG configuration')
443+
with allure.step('Add LAG configuration'):
444+
for lag_port, port_name in lag_port_map.items():
445+
duthost.shell('sudo config vlan member del {} {}'.format(T0_VLAN, port_name))
446+
duthost.shell('sudo config portchannel add {} --fallback enable'.format(lag_port))
447+
duthost.shell('sudo config portchannel member add {} {}'.format(lag_port, port_name))
448+
duthost.shell('config interface ip add {} {}'.format(lag_port, lag_ip_map[lag_port]['ipv4']))
449+
duthost.shell('config interface ip add {} {}'.format(lag_port, lag_ip_map[lag_port]['ipv6']))
450+
451+
452+
def remove_lag_config(duthost, lag_port_map, lag_ip_map):
453+
logging.info('Remove LAG configuration')
454+
with allure.step('Remove LAG configuration'):
455+
for lag_port, port_name in lag_port_map.items():
456+
duthost.shell('config interface ip remove {} {}'.format(lag_port, lag_ip_map[lag_port]['ipv4']))
457+
duthost.shell('config interface ip remove {} {}'.format(lag_port, lag_ip_map[lag_port]['ipv6']))
458+
duthost.shell('sudo config portchannel member del {} {}'.format(lag_port, port_name))
459+
duthost.shell('sudo config portchannel del {}'.format(lag_port))
460+
duthost.shell('sudo config vlan member add {} {} --untagged'.format(T0_VLAN, port_name))

tests/ecmp/inner_hashing/test_inner_hashing.py

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
import logging
66
import pytest
7+
import allure
78

89
from datetime import datetime
910
from retry.api import retry_call
1011
from tests.ptf_runner import ptf_runner
1112
from tests.ecmp.inner_hashing.conftest import get_src_dst_ip_range, FIB_INFO_FILE_DST,\
12-
VXLAN_PORT, PTF_QLEN, check_pbh_counters, OUTER_ENCAP_FORMATS
13+
VXLAN_PORT, PTF_QLEN, check_pbh_counters, OUTER_ENCAP_FORMATS, NVGRE_TNI
1314

1415
logger = logging.getLogger(__name__)
1516

@@ -24,44 +25,47 @@ class TestDynamicInnerHashing():
2425

2526
@pytest.fixture(scope="class", autouse=True)
2627
def setup_dynamic_pbh(self, request):
27-
request.getfixturevalue("config_pbh_table")
28-
request.getfixturevalue("config_hash_fields")
29-
request.getfixturevalue("config_hash")
30-
request.getfixturevalue("config_rules")
28+
with allure.step('Config Dynamic PBH'):
29+
request.getfixturevalue("config_pbh_table")
30+
request.getfixturevalue("config_hash_fields")
31+
request.getfixturevalue("config_hash")
32+
request.getfixturevalue("config_rules")
3133

3234
def test_inner_hashing(self, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, vlan_ptf_ports, symmetric_hashing, duthost):
3335
logging.info("Executing dynamic inner hash test for outer {} and inner {} with symmetric_hashing set to {}"
3436
.format(outer_ipver, inner_ipver, str(symmetric_hashing)))
35-
timestamp = datetime.now().strftime('%Y-%m-%d-%H:%M:%S')
36-
log_file = "/tmp/inner_hash_test.DynamicInnerHashTest.{}.{}.{}.log".format(outer_ipver, inner_ipver, timestamp)
37-
logging.info("PTF log file: %s" % log_file)
38-
39-
outer_src_ip_range, outer_dst_ip_range = get_src_dst_ip_range(outer_ipver)
40-
inner_src_ip_range, inner_dst_ip_range = get_src_dst_ip_range(inner_ipver)
41-
42-
balancing_test_times = 150
43-
balancing_range = 0.3
44-
45-
ptf_runner(ptfhost,
46-
"ptftests",
47-
"inner_hash_test.InnerHashTest",
48-
platform_dir="ptftests",
49-
params={"fib_info": FIB_INFO_FILE_DST,
50-
"router_mac": router_mac,
51-
"src_ports": vlan_ptf_ports,
52-
"hash_keys": hash_keys,
53-
"vxlan_port": VXLAN_PORT,
54-
"inner_src_ip_range": ",".join(inner_src_ip_range),
55-
"inner_dst_ip_range": ",".join(inner_dst_ip_range),
56-
"outer_src_ip_range": ",".join(outer_src_ip_range),
57-
"outer_dst_ip_range": ",".join(outer_dst_ip_range),
58-
"balancing_test_times": balancing_test_times,
59-
"balancing_range": balancing_range,
60-
"outer_encap_formats": OUTER_ENCAP_FORMATS,
61-
"symmetric_hashing": symmetric_hashing},
62-
log_file=log_file,
63-
qlen=PTF_QLEN,
64-
socket_recv_size=16384)
37+
with allure.step('Run ptf test InnerHashTest'):
38+
timestamp = datetime.now().strftime('%Y-%m-%d-%H:%M:%S')
39+
log_file = "/tmp/inner_hash_test.DynamicInnerHashTest.{}.{}.{}.log".format(outer_ipver, inner_ipver, timestamp)
40+
logging.info("PTF log file: %s" % log_file)
41+
42+
outer_src_ip_range, outer_dst_ip_range = get_src_dst_ip_range(outer_ipver)
43+
inner_src_ip_range, inner_dst_ip_range = get_src_dst_ip_range(inner_ipver)
44+
45+
balancing_test_times = 150
46+
balancing_range = 0.3
47+
48+
ptf_runner(ptfhost,
49+
"ptftests",
50+
"inner_hash_test.InnerHashTest",
51+
platform_dir="ptftests",
52+
params={"fib_info": FIB_INFO_FILE_DST,
53+
"router_mac": router_mac,
54+
"src_ports": vlan_ptf_ports,
55+
"hash_keys": hash_keys,
56+
"vxlan_port": VXLAN_PORT,
57+
"inner_src_ip_range": ",".join(inner_src_ip_range),
58+
"inner_dst_ip_range": ",".join(inner_dst_ip_range),
59+
"outer_src_ip_range": ",".join(outer_src_ip_range),
60+
"outer_dst_ip_range": ",".join(outer_dst_ip_range),
61+
"balancing_test_times": balancing_test_times,
62+
"balancing_range": balancing_range,
63+
"outer_encap_formats": OUTER_ENCAP_FORMATS,
64+
"nvgre_tni": NVGRE_TNI,
65+
"symmetric_hashing": symmetric_hashing},
66+
log_file=log_file,
67+
qlen=PTF_QLEN,
68+
socket_recv_size=16384)
6569

6670
retry_call(check_pbh_counters,
6771
fargs=[duthost, outer_ipver, inner_ipver, balancing_test_times, symmetric_hashing, hash_keys],

0 commit comments

Comments
 (0)