diff --git a/tests/ecmp/inner_hashing/conftest.py b/tests/ecmp/inner_hashing/conftest.py index 3325dce8935..01b001359b9 100644 --- a/tests/ecmp/inner_hashing/conftest.py +++ b/tests/ecmp/inner_hashing/conftest.py @@ -29,6 +29,8 @@ VXLAN_PORT = 13330 DUT_VXLAN_PORT_JSON_FILE = '/tmp/vxlan.switch.json' +ACL_DEPENDENCY_TABLES = ["EVERFLOW","EVERFLOWV6"] + T0_VLAN = "1000" IP_VERSIONS_LIST = ["ipv4", "ipv6"] OUTER_ENCAP_FORMATS = ["vxlan", "nvgre"] @@ -275,6 +277,21 @@ def inner_ipver(request): return request.param +@pytest.fixture(scope="module") +def remove_lag_acl_dependency(duthost): + duthost.command("cp /etc/sonic/config_db.json /etc/sonic/config_db.json.back") + + for acl_table in ACL_DEPENDENCY_TABLES: + duthost.command("sudo config acl remove table {}".format(acl_table)) + + yield + + duthost.shell("cat /etc/sonic/config_db.json.back | jq 'with_entries(select(.key==\"ACL_TABLE\"))' > /tmp/acl.json") + duthost.command("sudo config load -y /tmp/acl.json") + duthost.command("sudo config save -y") + duthost.command("rm -f /etc/sonic/config_db.json.back") + + @pytest.fixture(scope="module") def config_pbh_table_lag(duthost, lag_port_map): logging.info("Create PBH table: {}".format(TABLE_NAME)) @@ -458,3 +475,105 @@ def remove_lag_config(duthost, lag_port_map, lag_ip_map): duthost.shell('sudo config portchannel member del {} {}'.format(lag_port, port_name)) duthost.shell('sudo config portchannel del {}'.format(lag_port)) duthost.shell('sudo config vlan member add {} {} --untagged'.format(T0_VLAN, port_name)) + + +@pytest.fixture(scope="function") +def update_rule(duthost, outer_ipver, inner_ipver): + ''' + This function will update the rules: original, according to given outer/inner IP ver, and its mirrored rule + (ipv4 -> ipv6 and vice versa). + The rules will perform each other's actions. + For example, when given the ipv4-ipv4 rule: + Before: + RULE MATCH + vxlan_ipv4_ipv4 ether_type: 0x0800 + ip_protocol: 0x11 + l4_dst_port: 0x3412 + inner_ether_type: 0x0800 + + vxlan_ipv6_ipv6 ether_type: 0x86dd + ipv6_next_header: 0x11 + l4_dst_port: 0x3412 + inner_ether_type: 0x86dd + After: + vxlan_ipv4_ipv4 ether_type: 0x86dd + ipv6_next_header: 0x11 + l4_dst_port: 0x3412 + inner_ether_type: 0x86dd + + vxlan_ipv6_ipv6 ether_type: 0x0800 + ip_protocol: 0x11 + l4_dst_port: 0x3412 + inner_ether_type: 0x0800 + ''' + + def update_rule_del(outer_ipver, inner_ipver, option): + rule_name = encap_format + '_{}_{}'.format(outer_ipver, inner_ipver) + cmd = 'config pbh rule update field del {} {} --{}'.format(TABLE_NAME, rule_name, option) + duthost.command(cmd) + + def update_rule_set(outer_ipver, inner_ipver, set_dict): + rule_name = encap_format + '_{}_{}'.format(outer_ipver, inner_ipver) + cmd = 'config pbh rule update field set {} {}'.format(TABLE_NAME, rule_name) + for option, value in set_dict.items(): + cmd += ' --{} {}'.format(option, value) + duthost.command(cmd) + + # define original and swapped keys and values + if outer_ipver == "ipv4": + swapped_outer_ipver = "ipv6" + ether_type = V4_ETHER_TYPE + swapped_ether_type = V6_ETHER_TYPE + prot = 'ip-protocol' + swapped_prot = 'ipv6-next-header' + else: + swapped_outer_ipver = "ipv4" + ether_type = V6_ETHER_TYPE + swapped_ether_type = V4_ETHER_TYPE + prot = 'ipv6-next-header' + swapped_prot = 'ip-protocol' + + if inner_ipver == "ipv4": + inner_ether_type = V4_ETHER_TYPE + swapped_inner_ether_type = V6_ETHER_TYPE + swapped_inner_ipver = "ipv6" + else: + inner_ether_type = V6_ETHER_TYPE + swapped_inner_ether_type = V4_ETHER_TYPE + swapped_inner_ipver = "ipv4" + + update_set_dict = {prot: '', + 'ether-type': ether_type, + 'inner-ether-type': inner_ether_type} + swapped_update_set_dict = {swapped_prot: '', + 'ether-type': swapped_ether_type, + 'inner-ether-type': swapped_inner_ether_type} + + logging.info(" Update Rules. Swap the configuration of {}_{} and {}_{} rules" + .format(outer_ipver, inner_ipver, swapped_outer_ipver, swapped_inner_ipver)) + for encap_format in OUTER_ENCAP_FORMATS: + prot_value = VXLAN_IP_PROTOCOL if encap_format == 'vxlan' else NVGRE_IP_PROTOCOL + + update_set_dict.update({prot: prot_value}) + swapped_update_set_dict.update({swapped_prot: prot_value}) + + update_rule_del(outer_ipver, inner_ipver, prot) + update_rule_set(outer_ipver, inner_ipver, swapped_update_set_dict) + + update_rule_del(swapped_outer_ipver, swapped_inner_ipver, swapped_prot) + update_rule_set(swapped_outer_ipver, swapped_inner_ipver, update_set_dict) + + yield + + logging.info(" Restore Updated Rules ") + for encap_format in OUTER_ENCAP_FORMATS: + prot_value = VXLAN_IP_PROTOCOL if encap_format == 'vxlan' else NVGRE_IP_PROTOCOL + + update_set_dict.update({prot: prot_value}) + swapped_update_set_dict.update({swapped_prot: prot_value}) + + update_rule_del(outer_ipver, inner_ipver, swapped_prot) + update_rule_set(outer_ipver, inner_ipver, update_set_dict) + + update_rule_del(swapped_outer_ipver, swapped_inner_ipver, prot) + update_rule_set(swapped_outer_ipver, swapped_inner_ipver, swapped_update_set_dict) diff --git a/tests/ecmp/inner_hashing/test_inner_hashing.py b/tests/ecmp/inner_hashing/test_inner_hashing.py index 6a025007fd7..dac5806a00a 100644 --- a/tests/ecmp/inner_hashing/test_inner_hashing.py +++ b/tests/ecmp/inner_hashing/test_inner_hashing.py @@ -5,12 +5,13 @@ import logging import pytest import allure +import random from datetime import datetime from retry.api import retry_call from tests.ptf_runner import ptf_runner from tests.ecmp.inner_hashing.conftest import get_src_dst_ip_range, FIB_INFO_FILE_DST,\ - VXLAN_PORT, PTF_QLEN, check_pbh_counters, OUTER_ENCAP_FORMATS, NVGRE_TNI + VXLAN_PORT, PTF_QLEN, check_pbh_counters, OUTER_ENCAP_FORMATS, NVGRE_TNI, IP_VERSIONS_LIST logger = logging.getLogger(__name__) @@ -19,6 +20,9 @@ pytest.mark.asic('mellanox') ] +update_outer_ipver = random.choice(IP_VERSIONS_LIST) +update_inner_ipver = random.choice(IP_VERSIONS_LIST) + @pytest.mark.dynamic_config class TestDynamicInnerHashing(): @@ -31,7 +35,7 @@ def setup_dynamic_pbh(self, request): request.getfixturevalue("config_hash") request.getfixturevalue("config_rules") - def test_inner_hashing(self, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, vlan_ptf_ports, symmetric_hashing, duthost): + def test_inner_hashing(self, request, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, vlan_ptf_ports, symmetric_hashing, duthost): logging.info("Executing dynamic inner hash test for outer {} and inner {} with symmetric_hashing set to {}" .format(outer_ipver, inner_ipver, str(symmetric_hashing))) with allure.step('Run ptf test InnerHashTest'): @@ -45,32 +49,64 @@ def test_inner_hashing(self, hash_keys, ptfhost, outer_ipver, inner_ipver, route balancing_test_times = 150 balancing_range = 0.3 + ptf_params = {"fib_info": FIB_INFO_FILE_DST, + "router_mac": router_mac, + "src_ports": vlan_ptf_ports, + "hash_keys": hash_keys, + "vxlan_port": VXLAN_PORT, + "inner_src_ip_range": ",".join(inner_src_ip_range), + "inner_dst_ip_range": ",".join(inner_dst_ip_range), + "outer_src_ip_range": ",".join(outer_src_ip_range), + "outer_dst_ip_range": ",".join(outer_dst_ip_range), + "balancing_test_times": balancing_test_times, + "balancing_range": balancing_range, + "outer_encap_formats": OUTER_ENCAP_FORMATS, + "nvgre_tni": NVGRE_TNI, + "symmetric_hashing": symmetric_hashing} + + duthost.shell("sonic-clear pbh statistics") ptf_runner(ptfhost, "ptftests", "inner_hash_test.InnerHashTest", platform_dir="ptftests", - params={"fib_info": FIB_INFO_FILE_DST, - "router_mac": router_mac, - "src_ports": vlan_ptf_ports, - "hash_keys": hash_keys, - "vxlan_port": VXLAN_PORT, - "inner_src_ip_range": ",".join(inner_src_ip_range), - "inner_dst_ip_range": ",".join(inner_dst_ip_range), - "outer_src_ip_range": ",".join(outer_src_ip_range), - "outer_dst_ip_range": ",".join(outer_dst_ip_range), - "balancing_test_times": balancing_test_times, - "balancing_range": balancing_range, - "outer_encap_formats": OUTER_ENCAP_FORMATS, - "nvgre_tni": NVGRE_TNI, - "symmetric_hashing": symmetric_hashing}, + params=ptf_params, log_file=log_file, qlen=PTF_QLEN, socket_recv_size=16384) - retry_call(check_pbh_counters, - fargs=[duthost, outer_ipver, inner_ipver, balancing_test_times, symmetric_hashing, hash_keys], - tries=5, - delay=5) + retry_call(check_pbh_counters, + fargs=[duthost, outer_ipver, inner_ipver, balancing_test_times, symmetric_hashing, hash_keys], + tries=5, + delay=5) + + if update_outer_ipver == outer_ipver and update_inner_ipver == inner_ipver: + logging.info("Validate dynamic inner hash Edit Flow for outer {} and inner {} ip versions with" + " symmetric_hashing set to {}".format(outer_ipver, inner_ipver, str(symmetric_hashing))) + + swapped_outer_ipver = "ipv6" if outer_ipver == "ipv4" else "ipv4" + swapped_inner_ipver = "ipv6" if inner_ipver == "ipv4" else "ipv4" + with allure.step('Swap configuration of rules {}_{} with {}_{}'.format(outer_ipver, + inner_ipver, + swapped_outer_ipver, + swapped_inner_ipver)): + request.getfixturevalue("update_rule") + + with allure.step('Run again the ptf test InnerHashTest after updating the rules'): + duthost.shell("sonic-clear pbh statistics") + ptf_runner(ptfhost, + "ptftests", + "inner_hash_test.InnerHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=log_file, + qlen=PTF_QLEN, + socket_recv_size=16384) + + retry_call(check_pbh_counters, + fargs=[duthost, swapped_outer_ipver, swapped_inner_ipver, + balancing_test_times, symmetric_hashing, hash_keys], + tries=5, + delay=5) @pytest.mark.static_config diff --git a/tests/ecmp/inner_hashing/test_wr_inner_hashing.py b/tests/ecmp/inner_hashing/test_wr_inner_hashing.py index 93c5cbd391c..9a493083d1c 100644 --- a/tests/ecmp/inner_hashing/test_wr_inner_hashing.py +++ b/tests/ecmp/inner_hashing/test_wr_inner_hashing.py @@ -47,7 +47,7 @@ def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipv balancing_test_times = 200 balancing_range = 0.3 - reboot_thr = threading.Thread(target=reboot, args=(duthost, localhost, 'warm',)) + reboot_thr = threading.Thread(target=reboot, args=(duthost, localhost, 'warm', 10, 0, 0, True, True,)) reboot_thr.start() ptf_runner(ptfhost, @@ -88,7 +88,7 @@ def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipv outer_src_ip_range, outer_dst_ip_range = get_src_dst_ip_range(outer_ipver) inner_src_ip_range, inner_dst_ip_range = get_src_dst_ip_range(inner_ipver) - reboot_thr = threading.Thread(target=reboot, args=(duthost, localhost, 'warm',)) + reboot_thr = threading.Thread(target=reboot, args=(duthost, localhost, 'warm', 10, 0, 0, True, True,)) reboot_thr.start() ptf_runner(ptfhost, diff --git a/tests/ecmp/inner_hashing/test_wr_inner_hashing_lag.py b/tests/ecmp/inner_hashing/test_wr_inner_hashing_lag.py index 3883b7a7b4a..958a8f01e4c 100644 --- a/tests/ecmp/inner_hashing/test_wr_inner_hashing_lag.py +++ b/tests/ecmp/inner_hashing/test_wr_inner_hashing_lag.py @@ -23,6 +23,7 @@ class TestWRDynamicInnerHashingLag(): @pytest.fixture(scope="class", autouse=True) def setup_dynamic_pbh(self, request): with allure.step('Add required LAG config'): + request.getfixturevalue("remove_lag_acl_dependency") request.getfixturevalue("config_lag_ports") with allure.step('Config Dynamic PBH'): request.getfixturevalue("config_pbh_table_lag") @@ -48,7 +49,7 @@ def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipv balancing_test_times = 200 balancing_range = 0.3 - reboot_thr = threading.Thread(target=reboot, args=(duthost, localhost, 'warm',)) + reboot_thr = threading.Thread(target=reboot, args=(duthost, localhost, 'warm', 10, 0, 0, True, True,)) reboot_thr.start() ptf_runner(ptfhost,