From ff9cbc55b74ddb1fa6e420e4d34c7868aba0fe40 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 14 May 2021 16:34:59 +0530 Subject: [PATCH 01/36] Adding mpls tests Committer: Siji Joseph --- tests/mpls/configs/label_del_routes.json | 27 ++ tests/mpls/configs/label_pop_routes.json | 30 ++ tests/mpls/configs/label_push_routes.json | 16 + tests/mpls/configs/label_swap_routes.json | 30 ++ tests/mpls/configs/route_del_routes.json | 12 + tests/mpls/test_mpls.py | 398 ++++++++++++++++++++++ 6 files changed, 513 insertions(+) create mode 100644 tests/mpls/configs/label_del_routes.json create mode 100644 tests/mpls/configs/label_pop_routes.json create mode 100644 tests/mpls/configs/label_push_routes.json create mode 100644 tests/mpls/configs/label_swap_routes.json create mode 100644 tests/mpls/configs/route_del_routes.json create mode 100644 tests/mpls/test_mpls.py diff --git a/tests/mpls/configs/label_del_routes.json b/tests/mpls/configs/label_del_routes.json new file mode 100644 index 00000000000..8b9ad2e1211 --- /dev/null +++ b/tests/mpls/configs/label_del_routes.json @@ -0,0 +1,27 @@ +[ + { + "LABEL_ROUTE_TABLE:1000001": { + }, + "OP": "DEL" + }, + { + "INTF_TABLE:Ethernet10": { + }, + "OP": "DEL" + }, + { + "LABEL_ROUTE_TABLE:1000003": { + }, + "OP": "DEL" + }, + { + "INTF_TABLE:Ethernet25": { + }, + "OP": "DEL" + }, + { + "ROUTE_TABLE:192.168.0.1": { + }, + "OP": "DEL" + } +] diff --git a/tests/mpls/configs/label_pop_routes.json b/tests/mpls/configs/label_pop_routes.json new file mode 100644 index 00000000000..bd56d2d50c7 --- /dev/null +++ b/tests/mpls/configs/label_pop_routes.json @@ -0,0 +1,30 @@ +[ + { + "LABEL_ROUTE_TABLE:1000001": { + "nexthop": "10.0.0.51", + "ifname": "Ethernet25", + "weight": "1" + }, + "OP": "SET" + }, + { + "INTF_TABLE:Ethernet10": { + "mpls": "enable" + }, + "OP": "SET" + }, + { + "LABEL_ROUTE_TABLE:1000003": { + "nexthop": "10.0.0.21", + "ifname": "Ethernet10", + "weight": "1" + }, + "OP": "SET" + }, + { + "INTF_TABLE:Ethernet25": { + "mpls": "enable" + }, + "OP": "SET" + } +] diff --git a/tests/mpls/configs/label_push_routes.json b/tests/mpls/configs/label_push_routes.json new file mode 100644 index 00000000000..f1c0e3c2c0b --- /dev/null +++ b/tests/mpls/configs/label_push_routes.json @@ -0,0 +1,16 @@ +[ + { + "ROUTE_TABLE:192.168.0.1": { + "nexthop": "1000001+10.0.0.51", + "ifname": "Ethernet25", + "weight": "1" + }, + "OP": "SET" + }, + { + "INTF_TABLE:Ethernet25": { + "mpls": "enable" + }, + "OP": "SET" + } +] diff --git a/tests/mpls/configs/label_swap_routes.json b/tests/mpls/configs/label_swap_routes.json new file mode 100644 index 00000000000..e911648a7f0 --- /dev/null +++ b/tests/mpls/configs/label_swap_routes.json @@ -0,0 +1,30 @@ +[ + { + "LABEL_ROUTE_TABLE:1000001": { + "nexthop": "1000002+10.0.0.51", + "ifname": "Ethernet25", + "weight": "1" + }, + "OP": "SET" + }, + { + "INTF_TABLE:Ethernet10": { + "mpls": "enable" + }, + "OP": "SET" + }, + { + "LABEL_ROUTE_TABLE:1000003": { + "nexthop": "1000004+10.0.0.21", + "ifname": "Ethernet10", + "weight": "1" + }, + "OP": "SET" + }, + { + "INTF_TABLE:Ethernet25": { + "mpls": "enable" + }, + "OP": "SET" + } +] diff --git a/tests/mpls/configs/route_del_routes.json b/tests/mpls/configs/route_del_routes.json new file mode 100644 index 00000000000..3d26072c441 --- /dev/null +++ b/tests/mpls/configs/route_del_routes.json @@ -0,0 +1,12 @@ +[ + { + "ROUTE_TABLE:192.168.0.1": { + }, + "OP": "DEL" + }, + { + "INTF_TABLE:Ethernet25": { + }, + "OP": "DEL" + } +] diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py new file mode 100644 index 00000000000..c3cdca2a8e2 --- /dev/null +++ b/tests/mpls/test_mpls.py @@ -0,0 +1,398 @@ +import os +import time +import random +import logging +import pprint +import json + +from abc import ABCMeta, abstractmethod + +import pytest + +import ptf.testutils as testutils +import ptf.mask as mask +import ptf.packet as packet + +from tests.common import reboot, port_toggle +from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer, LogAnalyzerError +from tests.common.fixtures.duthost_utils import backup_and_restore_config_db_module +from tests.common.config_reload import config_reload + +logger = logging.getLogger(__name__) + +pytestmark = [ + pytest.mark.disable_loganalyzer, # disable automatic loganalyzer + pytest.mark.topology('t1') +] +BASE_DIR = os.path.dirname(os.path.realpath(__file__)) +DUT_TMP_DIR='/tmp' +ADD_DIR = os.path.join(BASE_DIR, 'configs') + +LABEL_POP_ROUTES='label_pop_routes.json' +LABEL_PUSH_ROUTES='label_push_routes.json' +LABEL_SWAP_ROUTES='label_swap_routes.json' +LABEL_DEL_ROUTES='label_del_routes.json' + +@pytest.fixture(scope='module') +def setup(duthost, tbinfo, ptfadapter): + """ + setup fixture gathers all test required information from DUT facts and tbinfo + :param duthost: DUT host object + :param tbinfo: fixture provides information about testbed + :return: dictionary with all test required information + """ + if tbinfo['topo']['name'] not in ('t1', 't1-lag', 't1-64-lag', 't1-64-lag-clet'): + pytest.skip('Unsupported topology') + + # gather ansible facts + mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] + + # get the list of TOR/SPINE ports + for dut_port, neigh in mg_facts['minigraph_neighbors'].items(): + port_id = mg_facts['minigraph_port_indices'][dut_port] + + # get the list of port channels + port_channels = mg_facts['minigraph_portchannels'] + + + + host_facts = duthost.setup()['ansible_facts'] + + setup_information = { + 'eth_dst': host_facts['ansible_Ethernet10']['macaddress'], + 'duthost': duthost, + 'dut_tmp_dir': DUT_TMP_DIR, + 'dst_ip_spine_blocked': '192.168.144.1', + } + + logger.info('setup variables {}'.format(pprint.pformat(setup_information))) + + # FIXME: There seems to be some issue with the initial setup of the ptfadapter, causing some of the + # TestBasicAcl tests to fail because the forwarded packets are not being collected. This is an + # attempt to mitigate that issue while we continue to investigate the root cause. + # + # Ref: GitHub Issue #2032 + logger.info("setting up the ptfadapter") + ptfadapter.reinit() + + yield setup_information + + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_POP_ROUTES))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_SWAP_ROUTES))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_PUSH_ROUTES))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_DEL_ROUTES))) + + +class BaseMplsTest(object): + """ + Base class for ACL rules testing. + Derivatives have to provide @setup_rules method to prepare DUT for ACL traffic test and + optionally override @teardown_rules which base implementation is simply applying empty ACL rules + configuration file + """ + __metaclass__ = ABCMeta + + ACL_COUNTERS_UPDATE_INTERVAL = 10 # seconds + + @abstractmethod + def setup_rules(self, dut, setup, acl_table): + """ + setup rules for test + :param dut: dut host + :param setup: setup information + :param acl_table: acl table creating fixture + :return: + """ + host_facts = duthost.setup()['ansible_facts'] + route_file_dir = duthost.shell('mktemp')['stdout'] + # Copy json file to DUT + myFile=open('mpls/label_routes.json', 'r') + myLabels=myFile.read() + duthost.copy(content=myLabels, dest=route_file_dir, verbose=False) + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(route_file_dir), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + pass + + def post_setup_hook(self, dut, localhost): + """ + perform actions after rules are applied + :param dut: DUT host object + :param localhost: localhost object + :return: + """ + + pass + + def teardown_rules(self, dut, setup): + """ + teardown ACL rules after test by applying empty configuration + :param dut: DUT host object + :param setup: setup information + :return: + """ + + logger.info('removing all MPLS') + # copy rules remove configuration + #dut.copy(src=os.path.join(FILES_DIR, ACL_REMOVE_RULES_FILE), dest=setup['dut_tmp_dir']) + #remove_rules_dut_path = os.path.join(setup['dut_tmp_dir'], ACL_REMOVE_RULES_FILE) + # remove rules + #logger.info('applying {}'.format(remove_rules_dut_path)) + #dut.command('config acl update full {}'.format(remove_rules_dut_path)) + duthost = setup['duthost'] + duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) + label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) + + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + pass + + + def icmp_packet(self, setup, ptfadapter): + """ create ICMP packet for testing """ + return testutils.simple_icmp_packet( + eth_dst=setup['eth_dst'], + eth_src=ptfadapter.dataplane.get_mac(0, 10), + ip_dst='192.168.0.1', + ip_src='10.0.0.21', + icmp_type=8, + icmp_code=0, + ip_ttl=64, + ) + def mpls_packet(self, setup, ptfadapter): + """ create MPLS packet for testing """ + return testutils.simple_mpls_packet( + eth_dst=setup['eth_dst'], + eth_src=ptfadapter.dataplane.get_mac(0, 10), + mpls_tags = [ + { + 'label':1000001, + 'ttl': 255, + 's':1 + } + ], + inner_frame = testutils.simple_ip_only_packet( + ip_dst='192.168.0.1', + ip_src='10.0.0.21', + ) + ) + + def mpls_stack_packet(self, setup, ptfadapter): + """ create MPLS packet for testing """ + return testutils.simple_mpls_packet( + eth_dst=setup['eth_dst'], + eth_src=ptfadapter.dataplane.get_mac(0, 10), + mpls_tags = [ + { + 'label':1000001, + 'ttl': 255, + 's':0 + }, + { + 'label':1000010, + 'ttl': 255, + 's':0 + }, + { + 'label':1000011, + 'ttl': 255, + 's':1 + } + ], + inner_frame = testutils.simple_ip_only_packet( + ip_dst='192.168.0.1', + ip_src='10.0.0.21', + ) + ) + + + def expected_mask_ip_packet(self, pkt): + """ return mask for ip packet """ + + epkt=pkt.copy() + exp_pkt = pkt.copy() + pkt1 = exp_pkt['IP'] + exp_pkt['Ether'].type=0x0800 + exp_pkt['Ether'].remove_payload() + exp_pkt /= pkt1 + #exp_pkt['IP'].len=100 + epkt = mask.Mask(epkt) + #pkt2 = mask.Mask(pkt2) + exp_pkt = mask.Mask(exp_pkt) + exp_pkt.set_do_not_care_scapy(packet.Ether, 'dst') + exp_pkt.set_do_not_care_scapy(packet.Ether, 'src') + exp_pkt.set_do_not_care_scapy(packet.IP, 'chksum') + return exp_pkt + + def expected_mask_mpls_swap_packet(self, pkt, exp_label): + """ return mask for mpls packet """ + + exp_pkt = pkt.copy() + exp_pkt['MPLS'].ttl -= 1 + exp_pkt['MPLS'].label = exp_label + exp_pkt = mask.Mask(exp_pkt) + exp_pkt.set_do_not_care_scapy(packet.Ether, 'dst') + exp_pkt.set_do_not_care_scapy(packet.Ether, 'src') + exp_pkt.set_do_not_care_scapy(packet.IP, 'chksum') + + return exp_pkt + + def expected_mask_mpls_push_packet(self, pkt, exp_label): + """ return mask for mpls packet """ + + exp_pkt = pkt.copy() + exp_pkt['MPLS'].ttl = exp_pkt['IP'].ttl - 1 + exp_pkt['IP'].ttl -= 1 + exp_pkt['MPLS'].label = exp_label + exp_pkt = mask.Mask(exp_pkt) + exp_pkt.set_do_not_care_scapy(packet.Ether, 'dst') + exp_pkt.set_do_not_care_scapy(packet.Ether, 'src') + exp_pkt.set_do_not_care_scapy(packet.IP, 'chksum') + + return exp_pkt + + def test_pop_label(self, setup, ptfadapter): + """ test pop label """ + duthost = setup['duthost'] + duthost.copy(src=os.path.join(ADD_DIR, LABEL_POP_ROUTES), dest=setup['dut_tmp_dir']) + label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_POP_ROUTES) + + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_add_dut_path), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + pkt = self.mpls_packet(setup, ptfadapter) + exp_pkt = self.expected_mask_ip_packet(pkt) + + ptfadapter.dataplane.flush() + testutils.send(ptfadapter, '10', pkt) + res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) + + duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) + label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) + + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + + def test_swap_label(self, setup, ptfadapter): + """ test swap label """ + duthost = setup['duthost'] + duthost.copy(src=os.path.join(ADD_DIR, LABEL_SWAP_ROUTES), dest=setup['dut_tmp_dir']) + label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_SWAP_ROUTES) + + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_add_dut_path), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + pkt = self.mpls_packet(setup, ptfadapter) + exp_pkt = self.expected_mask_mpls_swap_packet(pkt, 1000002) + + ptfadapter.dataplane.flush() + testutils.send(ptfadapter, '10', pkt) + res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) + + + duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) + label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) + + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + def test_push_label(self, setup, ptfadapter): + """ test push label """ + duthost = setup['duthost'] + duthost.copy(src=os.path.join(ADD_DIR, LABEL_PUSH_ROUTES), dest=setup['dut_tmp_dir']) + label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_PUSH_ROUTES) + + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_add_dut_path), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + pkt = self.icmp_packet(setup, ptfadapter) + epkt = pkt.copy() + pkt1 = epkt['IP'] + epkt['Ether'].type=0x8847 + epkt['Ether'].remove_payload() + mp = MPLS(label=1000002, s=1, ttl=255) + mp.remove_payload() + epkt /= mp + epkt /= pkt1 + exp_pkt = self.expected_mask_mpls_push_packet(epkt, 1000001) + + ptfadapter.dataplane.flush() + testutils.send(ptfadapter, '10', pkt) + res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) + + duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) + label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) + + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + def test_swap_labelstack(self, setup, ptfadapter): + """ test swap label """ + duthost = setup['duthost'] + duthost.copy(src=os.path.join(ADD_DIR, LABEL_SWAP_ROUTES), dest=setup['dut_tmp_dir']) + label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_SWAP_ROUTES) + + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_add_dut_path), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + pkt = self.mpls_stack_packet(setup, ptfadapter) + exp_pkt = self.expected_mask_mpls_swap_packet(pkt, 1000002) + + ptfadapter.dataplane.flush() + testutils.send(ptfadapter, '10', pkt) + res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) + + + duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) + label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) + + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + +class TestBasicMpls(BaseMplsTest): + """ + Basic ACL rules traffic tests. + Setup rules using full update, run traffic tests cases. + """ + + def setup_rules(self, dut, setup, acl_table): + """ + setup rules on DUT + :param dut: dut host + :param setup: setup information + :param acl_table: acl table creating fixture + :return: + """ + + pass From 81b3f65ea203f53ca629308b0376ba84c7441bc2 Mon Sep 17 00:00:00 2001 From: SijiJ <82926171+SijiJ@users.noreply.github.com> Date: Fri, 14 May 2021 16:59:55 +0530 Subject: [PATCH 02/36] Added comments --- tests/mpls/test_mpls.py | 109 +++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index c3cdca2a8e2..27e1d19354a 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -41,7 +41,7 @@ def setup(duthost, tbinfo, ptfadapter): :param tbinfo: fixture provides information about testbed :return: dictionary with all test required information """ - if tbinfo['topo']['name'] not in ('t1', 't1-lag', 't1-64-lag', 't1-64-lag-clet'): + if tbinfo['topo']['name'] not in ('t1'): pytest.skip('Unsupported topology') # gather ansible facts @@ -54,24 +54,17 @@ def setup(duthost, tbinfo, ptfadapter): # get the list of port channels port_channels = mg_facts['minigraph_portchannels'] - - host_facts = duthost.setup()['ansible_facts'] setup_information = { 'eth_dst': host_facts['ansible_Ethernet10']['macaddress'], 'duthost': duthost, 'dut_tmp_dir': DUT_TMP_DIR, - 'dst_ip_spine_blocked': '192.168.144.1', } logger.info('setup variables {}'.format(pprint.pformat(setup_information))) - # FIXME: There seems to be some issue with the initial setup of the ptfadapter, causing some of the - # TestBasicAcl tests to fail because the forwarded packets are not being collected. This is an - # attempt to mitigate that issue while we continue to investigate the root cause. - # - # Ref: GitHub Issue #2032 + # Check for: GitHub Issue #2032 logger.info("setting up the ptfadapter") ptfadapter.reinit() @@ -85,35 +78,18 @@ def setup(duthost, tbinfo, ptfadapter): class BaseMplsTest(object): """ - Base class for ACL rules testing. - Derivatives have to provide @setup_rules method to prepare DUT for ACL traffic test and - optionally override @teardown_rules which base implementation is simply applying empty ACL rules - configuration file + Base class for MPLS rules testing. """ __metaclass__ = ABCMeta - - ACL_COUNTERS_UPDATE_INTERVAL = 10 # seconds - + @abstractmethod - def setup_rules(self, dut, setup, acl_table): + def setup_rules(self, dut, setup): """ setup rules for test :param dut: dut host :param setup: setup information - :param acl_table: acl table creating fixture :return: """ - host_facts = duthost.setup()['ansible_facts'] - route_file_dir = duthost.shell('mktemp')['stdout'] - # Copy json file to DUT - myFile=open('mpls/label_routes.json', 'r') - myLabels=myFile.read() - duthost.copy(content=myLabels, dest=route_file_dir, verbose=False) - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(route_file_dir), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) pass def post_setup_hook(self, dut, localhost): @@ -126,21 +102,14 @@ def post_setup_hook(self, dut, localhost): pass - def teardown_rules(self, dut, setup): + def teardown_rules(self, setup): """ - teardown ACL rules after test by applying empty configuration - :param dut: DUT host object + teardown MPLS configurations after test by applying DEL configuration :param setup: setup information :return: """ logger.info('removing all MPLS') - # copy rules remove configuration - #dut.copy(src=os.path.join(FILES_DIR, ACL_REMOVE_RULES_FILE), dest=setup['dut_tmp_dir']) - #remove_rules_dut_path = os.path.join(setup['dut_tmp_dir'], ACL_REMOVE_RULES_FILE) - # remove rules - #logger.info('applying {}'.format(remove_rules_dut_path)) - #dut.command('config acl update full {}'.format(remove_rules_dut_path)) duthost = setup['duthost'] duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) @@ -184,7 +153,7 @@ def mpls_packet(self, setup, ptfadapter): ) def mpls_stack_packet(self, setup, ptfadapter): - """ create MPLS packet for testing """ + """ create stacked MPLS packet for testing """ return testutils.simple_mpls_packet( eth_dst=setup['eth_dst'], eth_src=ptfadapter.dataplane.get_mac(0, 10), @@ -231,7 +200,7 @@ def expected_mask_ip_packet(self, pkt): return exp_pkt def expected_mask_mpls_swap_packet(self, pkt, exp_label): - """ return mask for mpls packet """ + """ return mask for mpls swap packet """ exp_pkt = pkt.copy() exp_pkt['MPLS'].ttl -= 1 @@ -244,7 +213,7 @@ def expected_mask_mpls_swap_packet(self, pkt, exp_label): return exp_pkt def expected_mask_mpls_push_packet(self, pkt, exp_label): - """ return mask for mpls packet """ + """ return mask for mpls push packet """ exp_pkt = pkt.copy() exp_pkt['MPLS'].ttl = exp_pkt['IP'].ttl - 1 @@ -258,8 +227,11 @@ def expected_mask_mpls_push_packet(self, pkt, exp_label): return exp_pkt def test_pop_label(self, setup, ptfadapter): - """ test pop label """ + """ test for pop MPLS label """ + duthost = setup['duthost'] + + # Copy APP_DB config to DUT duthost.copy(src=os.path.join(ADD_DIR, LABEL_POP_ROUTES), dest=setup['dut_tmp_dir']) label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_POP_ROUTES) @@ -269,13 +241,19 @@ def test_pop_label(self, setup, ptfadapter): if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + # Create packet for sending and masked expected packet on receiving port pkt = self.mpls_packet(setup, ptfadapter) exp_pkt = self.expected_mask_ip_packet(pkt) ptfadapter.dataplane.flush() + + # Send pkt from spine port 10 testutils.send(ptfadapter, '10', pkt) + + # Capture and verify packets on tor port 25 res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) + # Copy Delete MPLS configs to DUT after test duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) @@ -287,8 +265,11 @@ def test_pop_label(self, setup, ptfadapter): def test_swap_label(self, setup, ptfadapter): - """ test swap label """ + """ test for swap MPLS label """ + duthost = setup['duthost'] + + # Copy APP_DB config to DUT duthost.copy(src=os.path.join(ADD_DIR, LABEL_SWAP_ROUTES), dest=setup['dut_tmp_dir']) label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_SWAP_ROUTES) @@ -297,15 +278,20 @@ def test_swap_label(self, setup, ptfadapter): module_ignore_errors=True) if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - + + # Create packet for sending and masked expected packet on receiving port pkt = self.mpls_packet(setup, ptfadapter) exp_pkt = self.expected_mask_mpls_swap_packet(pkt, 1000002) ptfadapter.dataplane.flush() + + # Send pkt from spine port 10 testutils.send(ptfadapter, '10', pkt) + + # Capture and verify packets on tor port 25 res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) - + # Copy Delete MPLS configs to DUT after test duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) @@ -316,8 +302,11 @@ def test_swap_label(self, setup, ptfadapter): pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) def test_push_label(self, setup, ptfadapter): - """ test push label """ + """ test push MPLS label """ + duthost = setup['duthost'] + + # Copy APP_DB config to DUT duthost.copy(src=os.path.join(ADD_DIR, LABEL_PUSH_ROUTES), dest=setup['dut_tmp_dir']) label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_PUSH_ROUTES) @@ -327,7 +316,9 @@ def test_push_label(self, setup, ptfadapter): if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + # Create packet for sending and masked expected packet on receiving port pkt = self.icmp_packet(setup, ptfadapter) + ## Add MPLS header in expected packet epkt = pkt.copy() pkt1 = epkt['IP'] epkt['Ether'].type=0x8847 @@ -339,9 +330,14 @@ def test_push_label(self, setup, ptfadapter): exp_pkt = self.expected_mask_mpls_push_packet(epkt, 1000001) ptfadapter.dataplane.flush() + + # Send pkt from spine port 10 testutils.send(ptfadapter, '10', pkt) + + # Capture and verify packets on tor port 25 res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) - + + # Copy Delete MPLS configs to DUT after test duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) @@ -350,9 +346,13 @@ def test_push_label(self, setup, ptfadapter): module_ignore_errors=True) if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + def test_swap_labelstack(self, setup, ptfadapter): - """ test swap label """ + """ test swap for stack of 3 MPLS label """ + duthost = setup['duthost'] + + # Copy APP_DB config to DUT duthost.copy(src=os.path.join(ADD_DIR, LABEL_SWAP_ROUTES), dest=setup['dut_tmp_dir']) label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_SWAP_ROUTES) @@ -362,14 +362,19 @@ def test_swap_labelstack(self, setup, ptfadapter): if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + # Create packet for sending and masked expected packet on receiving port pkt = self.mpls_stack_packet(setup, ptfadapter) exp_pkt = self.expected_mask_mpls_swap_packet(pkt, 1000002) ptfadapter.dataplane.flush() + + # Send pkt from spine port 10 testutils.send(ptfadapter, '10', pkt) + + # Capture and verify packets on tor port 25 res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) - + # Copy Delete MPLS configs to DUT after test duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) @@ -382,16 +387,14 @@ def test_swap_labelstack(self, setup, ptfadapter): class TestBasicMpls(BaseMplsTest): """ - Basic ACL rules traffic tests. - Setup rules using full update, run traffic tests cases. + Basic MPLS traffic tests. """ - def setup_rules(self, dut, setup, acl_table): + def setup_rules(self, dut, setup): """ setup rules on DUT :param dut: dut host :param setup: setup information - :param acl_table: acl table creating fixture :return: """ From 756fa1f026355f92b24e062703fc5873c6db1da9 Mon Sep 17 00:00:00 2001 From: SijiJ <82926171+SijiJ@users.noreply.github.com> Date: Fri, 14 May 2021 17:49:20 +0530 Subject: [PATCH 03/36] Delete route_del_routes.json --- tests/mpls/configs/route_del_routes.json | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 tests/mpls/configs/route_del_routes.json diff --git a/tests/mpls/configs/route_del_routes.json b/tests/mpls/configs/route_del_routes.json deleted file mode 100644 index 3d26072c441..00000000000 --- a/tests/mpls/configs/route_del_routes.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "ROUTE_TABLE:192.168.0.1": { - }, - "OP": "DEL" - }, - { - "INTF_TABLE:Ethernet25": { - }, - "OP": "DEL" - } -] From ea00acaa35e36011ebaf5a5a4444a73f08b9ee73 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 14 May 2021 18:49:22 +0530 Subject: [PATCH 04/36] Modify comment --- tests/mpls/test_mpls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index 27e1d19354a..db340587802 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -78,7 +78,7 @@ def setup(duthost, tbinfo, ptfadapter): class BaseMplsTest(object): """ - Base class for MPLS rules testing. + Base class for MPLS testing. """ __metaclass__ = ABCMeta From 832786ea87b10730b8137007505a8d99bc35c452 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 17 May 2021 19:29:39 +0530 Subject: [PATCH 05/36] Add MPLS testplan --- docs/testplan/MPLS-test-plan.md | 206 ++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 docs/testplan/MPLS-test-plan.md diff --git a/docs/testplan/MPLS-test-plan.md b/docs/testplan/MPLS-test-plan.md new file mode 100644 index 00000000000..c4e5b71eaa4 --- /dev/null +++ b/docs/testplan/MPLS-test-plan.md @@ -0,0 +1,206 @@ +- [Overview](#overview) + * [Scope](#scope) + * [Testbed](#testbed) +- [Setup configuration](#setup-configuration) + + [Setup of DUT switch](#setup-of-dut-switch) +- [Test cases](#test-cases) + * [Test case \#1 - POP Label](#test-case-1---pop-label) + + [Test objective](#test-objective) + + [Test steps](#test-steps) + * [Test case \#2 - SWAP Label for single label](#test-case-2---swap-label-for-single-label) + + [Test objective](#test-objective-1) + + [Test steps](#test-steps-1) + * [Test case \#3 - PUSH Label](#test-case-3---push-label) + + [Test objective](#test-objective-2) + + [Test steps](#test-steps-2) + * [Test case \#4 - SWAP Label for multiple label stack](#test-case-4---swap-label-for-multiple-label-stack) + + [Test objective](#test-objective-3) + + [Test steps](#test-steps-3) + +## Overview +This is Test Plan to test MPLS feature on SONiC. The test enables MPLS on interfaces, configures static LSPs and assumes all basic configurations including BGP routes are already preconfigured. + +### Scope +The test is targeting a running SONiC system with basic functioning configuration. +Purpose of the test is to verify MPLS on a SONiC system bringing up the ingress, transit or egress static LSP and forwarding the traffic correctly. + +### Testbed +T1 + +## Setup configuration +MPLS configuration will be set on DUT dynamically. + +#### Setup of DUT switch +During testrun, Ansible will copy JSON file containing configuration for MPLS to DUT and push to SONiC APPL DB via swssconfig. + +JSON Sample: + +label_pop_routes.json + +``` +[ + { + "LABEL_ROUTE_TABLE:1000001": { + "nexthop": "10.0.0.51", + "ifname": "Ethernet25", + "weight": "1" + }, + "OP": "SET" + }, + { + "INTF_TABLE:Ethernet10": { + "mpls": "enable" + }, + "OP": "SET" + }, + { + "LABEL_ROUTE_TABLE:1000003": { + "nexthop": "10.0.0.21", + "ifname": "Ethernet10", + "weight": "1" + }, + "OP": "SET" + }, + { + "INTF_TABLE:Ethernet25": { + "mpls": "enable" + }, + "OP": "SET" + } +] + ``` + + label_push_routes.json + + ``` + [ + { + "ROUTE_TABLE:192.168.0.1": { + "nexthop": "1000001+10.0.0.51", + "ifname": "Ethernet25", + "weight": "1" + }, + "OP": "SET" + }, + { + "INTF_TABLE:Ethernet25": { + "mpls": "enable" + }, + "OP": "SET" + } +] +``` +label_swap_routes.json + +``` +[ + { + "LABEL_ROUTE_TABLE:1000001": { + "nexthop": "1000002+10.0.0.51", + "ifname": "Ethernet25", + "weight": "1" + }, + "OP": "SET" + }, + { + "INTF_TABLE:Ethernet10": { + "mpls": "enable" + }, + "OP": "SET" + }, + { + "LABEL_ROUTE_TABLE:1000003": { + "nexthop": "1000004+10.0.0.21", + "ifname": "Ethernet10", + "weight": "1" + }, + "OP": "SET" + }, + { + "INTF_TABLE:Ethernet25": { + "mpls": "enable" + }, + "OP": "SET" + } +] +``` +label_del_routes.json + +``` +[ + { + "LABEL_ROUTE_TABLE:1000001": { + }, + "OP": "DEL" + }, + { + "INTF_TABLE:Ethernet10": { + }, + "OP": "DEL" + }, + { + "LABEL_ROUTE_TABLE:1000003": { + }, + "OP": "DEL" + }, + { + "INTF_TABLE:Ethernet25": { + }, + "OP": "DEL" + }, + { + "ROUTE_TABLE:192.168.0.1": { + }, + "OP": "DEL" + } +] +``` +## Test cases + +Each testcase configures static LSP, sends traffic, captures on receving port and verifies appropriate LABEL action is applied on packet. + +### Test case \#1 - POP Label + +#### Test objective + +Verify that the MPLS label is removed on the received packet. + +#### Test steps +- Enable MPLS on interfaces and configure pop label. +- Send MPLS packet. +- Capture the packet and verify that it is IP packet with MPLS removed. + +### Test case \#2 - SWAP Label for single label + +#### Test objective + +Verify that the MPLS label is swapped on the received packet. + +#### Test steps +- Enable MPLS on interfaces and configure swap label for MPLS packet. +- Send MPLS packet. +- Capture the packet and verify that it is MPLS packet with label swapped as per configuration. + +### Test case \#3 - PUSH Label + +#### Test objective + +Verify that the MPLS label is pushed on the received packet. + +#### Test steps +- Enable MPLS on interfaces and configure push label for MPLS packet. +- Send IP packet. +- Capture the packet and verify that it is MPLS packet with label added as per configuration. + + +### Test case \#4 - SWAP Label for multiple label stack + +#### Test objective + +Verify that the MPLS top label is swapped on the received packet. + +#### Test steps +- Enable MPLS on interfaces and configure swap label for MPLS packet. +- Send MPLS packet. +- Capture the packet and verify that it is MPLS packet with label swapped as per configuration for the top label. + From eb64bcf5799c4beefb4155a62ff1b17bb8f54a13 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 16 Jun 2021 09:31:40 +0530 Subject: [PATCH 06/36] Update label_push_routes.json Change in configuration --- tests/mpls/configs/label_push_routes.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mpls/configs/label_push_routes.json b/tests/mpls/configs/label_push_routes.json index f1c0e3c2c0b..2909c51941c 100644 --- a/tests/mpls/configs/label_push_routes.json +++ b/tests/mpls/configs/label_push_routes.json @@ -1,8 +1,9 @@ [ { "ROUTE_TABLE:192.168.0.1": { - "nexthop": "1000001+10.0.0.51", + "nexthop": "10.0.0.51", "ifname": "Ethernet25", + "mpls_nh": "1000001", "weight": "1" }, "OP": "SET" From 6422fb72aad7822785182747f40c422fe87e30bf Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 16 Jun 2021 09:33:45 +0530 Subject: [PATCH 07/36] Update label_pop_routes.json Change in DB --- tests/mpls/configs/label_pop_routes.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/mpls/configs/label_pop_routes.json b/tests/mpls/configs/label_pop_routes.json index bd56d2d50c7..bcd673acfdf 100644 --- a/tests/mpls/configs/label_pop_routes.json +++ b/tests/mpls/configs/label_pop_routes.json @@ -3,6 +3,8 @@ "LABEL_ROUTE_TABLE:1000001": { "nexthop": "10.0.0.51", "ifname": "Ethernet25", + "mpls_nh": "swap+", + "mpls_pop": "1", "weight": "1" }, "OP": "SET" @@ -17,6 +19,8 @@ "LABEL_ROUTE_TABLE:1000003": { "nexthop": "10.0.0.21", "ifname": "Ethernet10", + "mpls_nh": "swap+", + "mpls_pop": "1", "weight": "1" }, "OP": "SET" From f194a66c5c6217e866d56d9dd0b3f807ce6f4b08 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 16 Jun 2021 09:35:22 +0530 Subject: [PATCH 08/36] Update label_swap_routes.json Change in DB --- tests/mpls/configs/label_swap_routes.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/mpls/configs/label_swap_routes.json b/tests/mpls/configs/label_swap_routes.json index e911648a7f0..704ead6c89e 100644 --- a/tests/mpls/configs/label_swap_routes.json +++ b/tests/mpls/configs/label_swap_routes.json @@ -1,8 +1,10 @@ [ { "LABEL_ROUTE_TABLE:1000001": { - "nexthop": "1000002+10.0.0.51", + "nexthop": "10.0.0.51", "ifname": "Ethernet25", + "mpls_nh": "swap+1000002", + "mpls_pop": "1", "weight": "1" }, "OP": "SET" @@ -15,8 +17,10 @@ }, { "LABEL_ROUTE_TABLE:1000003": { - "nexthop": "1000004+10.0.0.21", + "nexthop": "10.0.0.21", "ifname": "Ethernet10", + "mpls_nh": "swap+1000004", + "mpls_pop": "1", "weight": "1" }, "OP": "SET" From 2a95aa23f887ae04f53ab56dede5f06bb6d09852 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 16 Jun 2021 09:42:21 +0530 Subject: [PATCH 09/36] Update MPLS-test-plan.md Change in DB config --- docs/testplan/MPLS-test-plan.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/testplan/MPLS-test-plan.md b/docs/testplan/MPLS-test-plan.md index c4e5b71eaa4..6eeb3ad9362 100644 --- a/docs/testplan/MPLS-test-plan.md +++ b/docs/testplan/MPLS-test-plan.md @@ -43,6 +43,8 @@ label_pop_routes.json "LABEL_ROUTE_TABLE:1000001": { "nexthop": "10.0.0.51", "ifname": "Ethernet25", + "mpls_nh": "swap+", + "mpls_pop": "1", "weight": "1" }, "OP": "SET" @@ -57,6 +59,8 @@ label_pop_routes.json "LABEL_ROUTE_TABLE:1000003": { "nexthop": "10.0.0.21", "ifname": "Ethernet10", + "mpls_nh": "swap+", + "mpls_pop": "1", "weight": "1" }, "OP": "SET" @@ -76,8 +80,9 @@ label_pop_routes.json [ { "ROUTE_TABLE:192.168.0.1": { - "nexthop": "1000001+10.0.0.51", + "nexthop": "10.0.0.51", "ifname": "Ethernet25", + "mpls_nh": "1000001", "weight": "1" }, "OP": "SET" @@ -96,8 +101,10 @@ label_swap_routes.json [ { "LABEL_ROUTE_TABLE:1000001": { - "nexthop": "1000002+10.0.0.51", + "nexthop": "10.0.0.51", "ifname": "Ethernet25", + "mpls_nh": "swap+1000002", + "mpls_pop": "1" "weight": "1" }, "OP": "SET" @@ -110,8 +117,10 @@ label_swap_routes.json }, { "LABEL_ROUTE_TABLE:1000003": { - "nexthop": "1000004+10.0.0.21", + "nexthop": "10.0.0.21", "ifname": "Ethernet10", + "mpls_nh": "swap+1000004", + "mpls_pop": "1", "weight": "1" }, "OP": "SET" From a60bef6acaff32c6ebadf529af3d4e0580eecd91 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 30 Jun 2021 03:22:41 +0530 Subject: [PATCH 10/36] Update label_pop_routes.json --- tests/mpls/configs/label_pop_routes.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/mpls/configs/label_pop_routes.json b/tests/mpls/configs/label_pop_routes.json index bcd673acfdf..ee25f7c696b 100644 --- a/tests/mpls/configs/label_pop_routes.json +++ b/tests/mpls/configs/label_pop_routes.json @@ -3,7 +3,6 @@ "LABEL_ROUTE_TABLE:1000001": { "nexthop": "10.0.0.51", "ifname": "Ethernet25", - "mpls_nh": "swap+", "mpls_pop": "1", "weight": "1" }, @@ -19,7 +18,6 @@ "LABEL_ROUTE_TABLE:1000003": { "nexthop": "10.0.0.21", "ifname": "Ethernet10", - "mpls_nh": "swap+", "mpls_pop": "1", "weight": "1" }, From 924499eda679e40d930549c3b5b53ab8cccac30c Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 30 Jun 2021 03:24:00 +0530 Subject: [PATCH 11/36] Update label_push_routes.json --- tests/mpls/configs/label_push_routes.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mpls/configs/label_push_routes.json b/tests/mpls/configs/label_push_routes.json index 2909c51941c..b1db380bba0 100644 --- a/tests/mpls/configs/label_push_routes.json +++ b/tests/mpls/configs/label_push_routes.json @@ -3,7 +3,7 @@ "ROUTE_TABLE:192.168.0.1": { "nexthop": "10.0.0.51", "ifname": "Ethernet25", - "mpls_nh": "1000001", + "mpls_nh": "push1000001", "weight": "1" }, "OP": "SET" From 83fb57baa44bc54a6bdb37adcaf32213082a8596 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 30 Jun 2021 03:24:54 +0530 Subject: [PATCH 12/36] Update label_swap_routes.json --- tests/mpls/configs/label_swap_routes.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/mpls/configs/label_swap_routes.json b/tests/mpls/configs/label_swap_routes.json index 704ead6c89e..9a0277e504c 100644 --- a/tests/mpls/configs/label_swap_routes.json +++ b/tests/mpls/configs/label_swap_routes.json @@ -3,7 +3,7 @@ "LABEL_ROUTE_TABLE:1000001": { "nexthop": "10.0.0.51", "ifname": "Ethernet25", - "mpls_nh": "swap+1000002", + "mpls_nh": "swap1000002", "mpls_pop": "1", "weight": "1" }, @@ -19,7 +19,7 @@ "LABEL_ROUTE_TABLE:1000003": { "nexthop": "10.0.0.21", "ifname": "Ethernet10", - "mpls_nh": "swap+1000004", + "mpls_nh": "swap1000004", "mpls_pop": "1", "weight": "1" }, From c81f50aeca1fe2c1c5cbc959b266093aa68f21c2 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 30 Jun 2021 03:26:54 +0530 Subject: [PATCH 13/36] Update MPLS-test-plan.md --- docs/testplan/MPLS-test-plan.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/testplan/MPLS-test-plan.md b/docs/testplan/MPLS-test-plan.md index 6eeb3ad9362..36b7eb693bd 100644 --- a/docs/testplan/MPLS-test-plan.md +++ b/docs/testplan/MPLS-test-plan.md @@ -43,7 +43,6 @@ label_pop_routes.json "LABEL_ROUTE_TABLE:1000001": { "nexthop": "10.0.0.51", "ifname": "Ethernet25", - "mpls_nh": "swap+", "mpls_pop": "1", "weight": "1" }, @@ -59,7 +58,6 @@ label_pop_routes.json "LABEL_ROUTE_TABLE:1000003": { "nexthop": "10.0.0.21", "ifname": "Ethernet10", - "mpls_nh": "swap+", "mpls_pop": "1", "weight": "1" }, @@ -82,7 +80,7 @@ label_pop_routes.json "ROUTE_TABLE:192.168.0.1": { "nexthop": "10.0.0.51", "ifname": "Ethernet25", - "mpls_nh": "1000001", + "mpls_nh": "push1000001", "weight": "1" }, "OP": "SET" @@ -103,7 +101,7 @@ label_swap_routes.json "LABEL_ROUTE_TABLE:1000001": { "nexthop": "10.0.0.51", "ifname": "Ethernet25", - "mpls_nh": "swap+1000002", + "mpls_nh": "swap1000002", "mpls_pop": "1" "weight": "1" }, @@ -119,7 +117,7 @@ label_swap_routes.json "LABEL_ROUTE_TABLE:1000003": { "nexthop": "10.0.0.21", "ifname": "Ethernet10", - "mpls_nh": "swap+1000004", + "mpls_nh": "swap1000004", "mpls_pop": "1", "weight": "1" }, From 44193f07a4148d51156e4f113c41195e9cb194fb Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Thu, 20 Jan 2022 23:25:19 +0530 Subject: [PATCH 14/36] Create label_pop_routes.j2 Variable interface. --- tests/mpls/configs/label_pop_routes.j2 | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/mpls/configs/label_pop_routes.j2 diff --git a/tests/mpls/configs/label_pop_routes.j2 b/tests/mpls/configs/label_pop_routes.j2 new file mode 100644 index 00000000000..ddc6291c468 --- /dev/null +++ b/tests/mpls/configs/label_pop_routes.j2 @@ -0,0 +1,20 @@ +[ + { + "LABEL_ROUTE_TABLE:1000001": { + "nexthop": "{{ dst_peer_addr }}", + "ifname": "{{ dst_port }}", + "mpls_pop": "1", + "weight": "1" + }, + "OP": "SET" + }, + { + "LABEL_ROUTE_TABLE:1000003": { + "nexthop": "{{ src_peer_addr }}", + "ifname": "{{ src_port }}", + "mpls_pop": "1", + "weight": "1" + }, + "OP": "SET" + } +] From 91e61ace5e18b8bc0b82fd14c385e36ba6759636 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Thu, 20 Jan 2022 23:25:53 +0530 Subject: [PATCH 15/36] Create label_push_routes.j2 Variable interface --- tests/mpls/configs/label_push_routes.j2 | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/mpls/configs/label_push_routes.j2 diff --git a/tests/mpls/configs/label_push_routes.j2 b/tests/mpls/configs/label_push_routes.j2 new file mode 100644 index 00000000000..bcf55b58cd4 --- /dev/null +++ b/tests/mpls/configs/label_push_routes.j2 @@ -0,0 +1,11 @@ +[ + { + "ROUTE_TABLE:192.168.0.1": { + "nexthop": "{{ dst_peer_addr }}", + "ifname": "{{ dst_port }}", + "mpls_nh": "push1000001", + "weight": "1" + }, + "OP": "SET" + } +] From df0a2c83c5d1621e25023b6e4fd7605e84b022ca Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Thu, 20 Jan 2022 23:26:36 +0530 Subject: [PATCH 16/36] Create label_swap_routes.j2 Variable interface --- tests/mpls/configs/label_swap_routes.j2 | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/mpls/configs/label_swap_routes.j2 diff --git a/tests/mpls/configs/label_swap_routes.j2 b/tests/mpls/configs/label_swap_routes.j2 new file mode 100644 index 00000000000..4d3e8e6d739 --- /dev/null +++ b/tests/mpls/configs/label_swap_routes.j2 @@ -0,0 +1,22 @@ +[ + { + "LABEL_ROUTE_TABLE:1000001": { + "nexthop": "{{ dst_peer_addr }}", + "ifname": "{{ dst_port }}", + "mpls_nh": "swap1000002", + "mpls_pop": "1", + "weight": "1" + }, + "OP": "SET" + }, + { + "LABEL_ROUTE_TABLE:1000003": { + "nexthop": "{{ src_peer_addr }}", + "ifname": "{{ src_port }}", + "mpls_nh": "swap1000004", + "mpls_pop": "1", + "weight": "1" + }, + "OP": "SET" + } +] From 9f4a84a7c343c30d779867eb8f26ca766c0b5707 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Fri, 21 Jan 2022 00:40:23 +0530 Subject: [PATCH 17/36] Delete label_del_routes.json Deleting config with interface --- tests/mpls/configs/label_del_routes.json | 27 ------------------------ 1 file changed, 27 deletions(-) delete mode 100644 tests/mpls/configs/label_del_routes.json diff --git a/tests/mpls/configs/label_del_routes.json b/tests/mpls/configs/label_del_routes.json deleted file mode 100644 index 8b9ad2e1211..00000000000 --- a/tests/mpls/configs/label_del_routes.json +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "LABEL_ROUTE_TABLE:1000001": { - }, - "OP": "DEL" - }, - { - "INTF_TABLE:Ethernet10": { - }, - "OP": "DEL" - }, - { - "LABEL_ROUTE_TABLE:1000003": { - }, - "OP": "DEL" - }, - { - "INTF_TABLE:Ethernet25": { - }, - "OP": "DEL" - }, - { - "ROUTE_TABLE:192.168.0.1": { - }, - "OP": "DEL" - } -] From 022183ca5cffa4273cf82c07a589ec534ab32553 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Fri, 21 Jan 2022 00:40:38 +0530 Subject: [PATCH 18/36] Delete label_pop_routes.json Deleting config with interface --- tests/mpls/configs/label_pop_routes.json | 32 ------------------------ 1 file changed, 32 deletions(-) delete mode 100644 tests/mpls/configs/label_pop_routes.json diff --git a/tests/mpls/configs/label_pop_routes.json b/tests/mpls/configs/label_pop_routes.json deleted file mode 100644 index ee25f7c696b..00000000000 --- a/tests/mpls/configs/label_pop_routes.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "LABEL_ROUTE_TABLE:1000001": { - "nexthop": "10.0.0.51", - "ifname": "Ethernet25", - "mpls_pop": "1", - "weight": "1" - }, - "OP": "SET" - }, - { - "INTF_TABLE:Ethernet10": { - "mpls": "enable" - }, - "OP": "SET" - }, - { - "LABEL_ROUTE_TABLE:1000003": { - "nexthop": "10.0.0.21", - "ifname": "Ethernet10", - "mpls_pop": "1", - "weight": "1" - }, - "OP": "SET" - }, - { - "INTF_TABLE:Ethernet25": { - "mpls": "enable" - }, - "OP": "SET" - } -] From 6e95baf7fc2c9a6d3b1ce519ea72b7b8e5bf4e78 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Fri, 21 Jan 2022 00:41:02 +0530 Subject: [PATCH 19/36] Delete label_push_routes.json Deleting config with interface --- tests/mpls/configs/label_push_routes.json | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 tests/mpls/configs/label_push_routes.json diff --git a/tests/mpls/configs/label_push_routes.json b/tests/mpls/configs/label_push_routes.json deleted file mode 100644 index b1db380bba0..00000000000 --- a/tests/mpls/configs/label_push_routes.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "ROUTE_TABLE:192.168.0.1": { - "nexthop": "10.0.0.51", - "ifname": "Ethernet25", - "mpls_nh": "push1000001", - "weight": "1" - }, - "OP": "SET" - }, - { - "INTF_TABLE:Ethernet25": { - "mpls": "enable" - }, - "OP": "SET" - } -] From 60af68aaa9c10031ae2d29ad4a2ec6710ef1419b Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Fri, 21 Jan 2022 00:41:21 +0530 Subject: [PATCH 20/36] Delete label_swap_routes.json Deleting config with interface --- tests/mpls/configs/label_swap_routes.json | 34 ----------------------- 1 file changed, 34 deletions(-) delete mode 100644 tests/mpls/configs/label_swap_routes.json diff --git a/tests/mpls/configs/label_swap_routes.json b/tests/mpls/configs/label_swap_routes.json deleted file mode 100644 index 9a0277e504c..00000000000 --- a/tests/mpls/configs/label_swap_routes.json +++ /dev/null @@ -1,34 +0,0 @@ -[ - { - "LABEL_ROUTE_TABLE:1000001": { - "nexthop": "10.0.0.51", - "ifname": "Ethernet25", - "mpls_nh": "swap1000002", - "mpls_pop": "1", - "weight": "1" - }, - "OP": "SET" - }, - { - "INTF_TABLE:Ethernet10": { - "mpls": "enable" - }, - "OP": "SET" - }, - { - "LABEL_ROUTE_TABLE:1000003": { - "nexthop": "10.0.0.21", - "ifname": "Ethernet10", - "mpls_nh": "swap1000004", - "mpls_pop": "1", - "weight": "1" - }, - "OP": "SET" - }, - { - "INTF_TABLE:Ethernet25": { - "mpls": "enable" - }, - "OP": "SET" - } -] From a0c45a427a13de0bbb9a7c6b5713354e6b16bf48 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Fri, 21 Jan 2022 00:42:04 +0530 Subject: [PATCH 21/36] Create label_del_routes.j2 Adding j2 del config --- tests/mpls/configs/label_del_routes.j2 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/mpls/configs/label_del_routes.j2 diff --git a/tests/mpls/configs/label_del_routes.j2 b/tests/mpls/configs/label_del_routes.j2 new file mode 100644 index 00000000000..b45f7dcf481 --- /dev/null +++ b/tests/mpls/configs/label_del_routes.j2 @@ -0,0 +1,17 @@ +[ + { + "LABEL_ROUTE_TABLE:1000001": { + }, + "OP": "DEL" + }, + { + "LABEL_ROUTE_TABLE:1000003": { + }, + "OP": "DEL" + }, + { + "ROUTE_TABLE:192.168.0.1": { + }, + "OP": "DEL" + } +] From 89cad031be62b2871e120c4cfbfd3b715c4d778d Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Fri, 21 Jan 2022 00:44:09 +0530 Subject: [PATCH 22/36] Update test_mpls.py Addressing review comments --- tests/mpls/test_mpls.py | 487 ++++++++++++++++++++++++++++------------ 1 file changed, 348 insertions(+), 139 deletions(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index db340587802..72f91d620a6 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -21,17 +21,18 @@ logger = logging.getLogger(__name__) pytestmark = [ - pytest.mark.disable_loganalyzer, # disable automatic loganalyzer - pytest.mark.topology('t1') +# pytest.mark.disable_loganalyzer, # disable automatic loganalyzer + pytest.mark.topology('t1'), +# pytest.mark.sanity_check(skip_sanity=True) ] BASE_DIR = os.path.dirname(os.path.realpath(__file__)) DUT_TMP_DIR='/tmp' ADD_DIR = os.path.join(BASE_DIR, 'configs') -LABEL_POP_ROUTES='label_pop_routes.json' -LABEL_PUSH_ROUTES='label_push_routes.json' -LABEL_SWAP_ROUTES='label_swap_routes.json' -LABEL_DEL_ROUTES='label_del_routes.json' +LABEL_POP_ROUTES='label_pop_routes' +LABEL_PUSH_ROUTES='label_push_routes' +LABEL_SWAP_ROUTES='label_swap_routes' +LABEL_DEL_ROUTES='label_del_routes' @pytest.fixture(scope='module') def setup(duthost, tbinfo, ptfadapter): @@ -41,55 +42,136 @@ def setup(duthost, tbinfo, ptfadapter): :param tbinfo: fixture provides information about testbed :return: dictionary with all test required information """ - if tbinfo['topo']['name'] not in ('t1'): + if tbinfo['topo']['name'] not in ('t1', 't1-lag', 't1-64-lag', 't1-64-lag-clet'): pytest.skip('Unsupported topology') # gather ansible facts mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] + int_facts = duthost.interface_facts()['ansible_facts'] + host_facts = duthost.setup()['ansible_facts'] + tor_ports_ids=[] + tor_ports={} + spine_ports_ids=[] + spine_ports={} + tor_addr={} + tor_peer_addr={} + spine_addr={} + spine_peer_addr={} + tor_mac={} + spine_mac={} + # get the list of TOR/SPINE ports for dut_port, neigh in mg_facts['minigraph_neighbors'].items(): + if not port_up(duthost, dut_port): + continue port_id = mg_facts['minigraph_port_indices'][dut_port] - - # get the list of port channels - port_channels = mg_facts['minigraph_portchannels'] - - host_facts = duthost.setup()['ansible_facts'] + if 'T0' in neigh['name']: + tor_ports[port_id]=dut_port + tor_ports_ids.append(port_id) + elif 'T2' in neigh['name']: + spine_ports[port_id]=dut_port + spine_ports_ids.append(port_id) + + logger.info('tor_ports: {}'.format(tor_ports)) + logger.info('spine_ports: {}'.format(spine_ports)) + + for blk in mg_facts['minigraph_interfaces']: + if ':' in blk['peer_addr']: + continue + dut_port=blk['attachto'] + port_id = mg_facts['minigraph_port_indices'][dut_port] + neigh=mg_facts['minigraph_neighbors'][dut_port] + if 'T0' in neigh['name']: + tor_addr[port_id]=blk['addr'] + tor_peer_addr[port_id]=blk['peer_addr'] + elif 'T2' in neigh['name']: + spine_addr[port_id]=blk['addr'] + spine_peer_addr[port_id]=blk['peer_addr'] + + for pid, dut_port in tor_ports.items(): + port_id = mg_facts['minigraph_port_indices'][dut_port] + ansible_port='ansible_'+dut_port + tor_mac[port_id]=host_facts[ansible_port]['macaddress'] + + for pid, dut_port in spine_ports.items(): + port_id = mg_facts['minigraph_port_indices'][dut_port] + ansible_port='ansible_'+dut_port + spine_mac[port_id]=host_facts[ansible_port]['macaddress'] setup_information = { - 'eth_dst': host_facts['ansible_Ethernet10']['macaddress'], 'duthost': duthost, 'dut_tmp_dir': DUT_TMP_DIR, + 'dst_ip_spine_blocked': '192.168.144.1', + 'tor_ports': tor_ports, + 'spine_ports': spine_ports, + 'tor_addr': tor_addr, + 'tor_peer_addr': tor_peer_addr, + 'spine_addr': spine_addr, + 'spine_peer_addr': spine_peer_addr, + 'tor_ports_ids': tor_ports_ids, + 'spine_ports_ids': spine_ports_ids, + 'tor_mac': tor_mac, + 'spine_mac': spine_mac, } - logger.info('setup variables {}'.format(pprint.pformat(setup_information))) + logger.info('setup variables {}'.format(pprint.pformat(setup))) - # Check for: GitHub Issue #2032 + # FIXME: There seems to be some issue with the initial setup of the ptfadapter, causing some of the + # TestBasicMPLS tests to fail because the forwarded packets are not being collected. This is an + # attempt to mitigate that issue while we continue to investigate the root cause. + # + # Ref: GitHub Issue #2032 logger.info("setting up the ptfadapter") ptfadapter.reinit() yield setup_information - duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_POP_ROUTES))) - duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_SWAP_ROUTES))) - duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_PUSH_ROUTES))) - duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_DEL_ROUTES))) - + #duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_POP_ROUTES))) + #duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_SWAP_ROUTES))) + #duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_PUSH_ROUTES1))) + #duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_DEL_ROUTES))) + +def port_up(dut, interface): + intf_facts = dut.interface_facts()['ansible_facts'] + try: + port = intf_facts["ansible_interface_facts"][interface] + if port["link"] and port["active"]: + return True + except KeyError: + return False + return False class BaseMplsTest(object): """ - Base class for MPLS testing. + Base class for MPLS label testing. + Derivatives have to provide @setup_rules method to prepare DUT for MPLS traffic test and + optionally override @teardown_rules which base implementation is simply applying empty MPLS labels + configuration file """ __metaclass__ = ABCMeta - + + @abstractmethod - def setup_rules(self, dut, setup): + def setup_rules(self, dut, setup, acl_table): """ setup rules for test :param dut: dut host :param setup: setup information + :param acl_table: acl table creating fixture :return: """ + host_facts = duthost.setup()['ansible_facts'] + route_file_dir = duthost.shell('mktemp')['stdout'] + # Copy json file to DUT + myFile=open('mpls/label_routes.json', 'r') + myLabels=myFile.read() + duthost.copy(content=myLabels, dest=route_file_dir, verbose=False) + # Apply routes with swssconfig + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(route_file_dir), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) pass def post_setup_hook(self, dut, localhost): @@ -102,61 +184,85 @@ def post_setup_hook(self, dut, localhost): pass - def teardown_rules(self, setup): + def teardown_labels(self, setup, src_port, dst_port): """ - teardown MPLS configurations after test by applying DEL configuration + teardown MPLS label after test by applying empty configuration + :param dut: DUT host object :param setup: setup information :return: """ - - logger.info('removing all MPLS') + setup = setup duthost = setup['duthost'] - duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) - label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) + + logger.info('removing all MPLS') + mpls_config = '{}.json'.format(LABEL_DEL_ROUTES) + label_del_dut_path = os.path.join(setup['dut_tmp_dir'], mpls_config) + template_file='{}.j2'.format(LABEL_DEL_ROUTES) + duthost.template(src=os.path.join(ADD_DIR, template_file), dest=label_del_dut_path) # Apply routes with swssconfig result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), module_ignore_errors=True) if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - - pass + result = duthost.shell('config interface mpls remove {}'.format(src_port), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + result = duthost.shell('config interface mpls remove {}'.format(dst_port), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + + def get_src_portid(self, setup): + """ return source port id """ + + src_pids = setup['spine_ports_ids'] + return random.choice(src_pids) - def icmp_packet(self, setup, ptfadapter): + def get_dst_portid(self, setup): + """ return destination port id""" + + dst_pids = setup['tor_ports_ids'] + return random.choice(dst_pids) + + def icmp_packet(self, setup, ptfadapter, dst_pid, src_pid): """ create ICMP packet for testing """ return testutils.simple_icmp_packet( - eth_dst=setup['eth_dst'], - eth_src=ptfadapter.dataplane.get_mac(0, 10), + eth_dst=setup['spine_mac'][src_pid], + eth_src=ptfadapter.dataplane.get_mac(0, src_pid), ip_dst='192.168.0.1', - ip_src='10.0.0.21', + ip_src=setup['spine_addr'][src_pid], icmp_type=8, icmp_code=0, ip_ttl=64, ) - def mpls_packet(self, setup, ptfadapter): + def mpls_packet(self, setup, ptfadapter, dst_pid, src_pid): """ create MPLS packet for testing """ return testutils.simple_mpls_packet( - eth_dst=setup['eth_dst'], - eth_src=ptfadapter.dataplane.get_mac(0, 10), + eth_dst=setup['spine_mac'][src_pid], + eth_src=ptfadapter.dataplane.get_mac(0, src_pid), mpls_tags = [ { 'label':1000001, - 'ttl': 255, + 'ttl': 63, 's':1 } ], inner_frame = testutils.simple_ip_only_packet( ip_dst='192.168.0.1', - ip_src='10.0.0.21', + ip_src=setup['spine_addr'][src_pid], ) ) - def mpls_stack_packet(self, setup, ptfadapter): - """ create stacked MPLS packet for testing """ + def mpls_stack_packet(self, setup, ptfadapter, dst_pid, src_pid): + """ create MPLS packet for testing """ return testutils.simple_mpls_packet( - eth_dst=setup['eth_dst'], - eth_src=ptfadapter.dataplane.get_mac(0, 10), + eth_dst=setup['spine_mac'][src_pid], + eth_src=ptfadapter.dataplane.get_mac(0, src_pid), mpls_tags = [ { 'label':1000001, @@ -176,7 +282,7 @@ def mpls_stack_packet(self, setup, ptfadapter): ], inner_frame = testutils.simple_ip_only_packet( ip_dst='192.168.0.1', - ip_src='10.0.0.21', + ip_src=setup['spine_addr'][src_pid], ) ) @@ -186,6 +292,7 @@ def expected_mask_ip_packet(self, pkt): epkt=pkt.copy() exp_pkt = pkt.copy() + exp_pkt['IP'].ttl = 62 pkt1 = exp_pkt['IP'] exp_pkt['Ether'].type=0x0800 exp_pkt['Ether'].remove_payload() @@ -200,7 +307,7 @@ def expected_mask_ip_packet(self, pkt): return exp_pkt def expected_mask_mpls_swap_packet(self, pkt, exp_label): - """ return mask for mpls swap packet """ + """ return mask for mpls packet """ exp_pkt = pkt.copy() exp_pkt['MPLS'].ttl -= 1 @@ -213,7 +320,7 @@ def expected_mask_mpls_swap_packet(self, pkt, exp_label): return exp_pkt def expected_mask_mpls_push_packet(self, pkt, exp_label): - """ return mask for mpls push packet """ + """ return mask for mpls packet """ exp_pkt = pkt.copy() exp_pkt['MPLS'].ttl = exp_pkt['IP'].ttl - 1 @@ -227,98 +334,179 @@ def expected_mask_mpls_push_packet(self, pkt, exp_label): return exp_pkt def test_pop_label(self, setup, ptfadapter): - """ test for pop MPLS label """ - + """ test pop label """ + + setup = setup duthost = setup['duthost'] + + dst_pid=self.get_dst_portid(setup) + src_pid=self.get_src_portid(setup) + + dst_port=setup['tor_ports'][dst_pid] + src_port=setup['spine_ports'][src_pid] + + dst_peer_addr=setup['tor_peer_addr'][dst_pid] + src_peer_addr=setup['spine_peer_addr'][src_pid] + + config_variables = { + 'dst_port': dst_port, + 'src_port': src_port, + 'dst_peer_addr': dst_peer_addr, + 'src_peer_addr': src_peer_addr, + } + + logger.info('extra variables for MPLS config:\n{}'.format(pprint.pformat(config_variables))) + duthost.host.options['variable_manager'].extra_vars.update(config_variables) - # Copy APP_DB config to DUT - duthost.copy(src=os.path.join(ADD_DIR, LABEL_POP_ROUTES), dest=setup['dut_tmp_dir']) - label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_POP_ROUTES) + logger.info('generate config for MPLS') + mpls_config = '{}.json'.format(LABEL_POP_ROUTES) + mpls_config_path = os.path.join(setup['dut_tmp_dir'], mpls_config) + template_file='{}.j2'.format(LABEL_POP_ROUTES) + duthost.template(src=os.path.join(ADD_DIR, template_file), dest=mpls_config_path) - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_add_dut_path), + result = duthost.shell('config interface mpls add {}'.format(src_port), module_ignore_errors=True) if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - # Create packet for sending and masked expected packet on receiving port - pkt = self.mpls_packet(setup, ptfadapter) - exp_pkt = self.expected_mask_ip_packet(pkt) - - ptfadapter.dataplane.flush() - - # Send pkt from spine port 10 - testutils.send(ptfadapter, '10', pkt) - - # Capture and verify packets on tor port 25 - res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) - - # Copy Delete MPLS configs to DUT after test - duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) - label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) + result = duthost.shell('config interface mpls add {}'.format(dst_port), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(mpls_config_path), module_ignore_errors=True) if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - + + time.sleep(20) + pkt = self.mpls_packet(setup, ptfadapter, dst_pid, src_pid) + exp_pkt = self.expected_mask_ip_packet(pkt) + + ptfadapter.dataplane.flush() + testutils.send(ptfadapter, src_pid, pkt) + try: + res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) + logger.info(res) + except Exception as e: + self.teardown_labels(setup,src_port,dst_port) + pytest.fail('MPLS pop test failed \n' + str(e)) + + self.teardown_labels(setup,src_port,dst_port) def test_swap_label(self, setup, ptfadapter): - """ test for swap MPLS label """ - + """ test swap label """ + + setup = setup duthost = setup['duthost'] + + dst_pid=self.get_dst_portid(setup) + src_pid=self.get_src_portid(setup) + + dst_port=setup['tor_ports'][dst_pid] + src_port=setup['spine_ports'][src_pid] + + dst_peer_addr=setup['tor_peer_addr'][dst_pid] + src_peer_addr=setup['spine_peer_addr'][src_pid] + + config_variables = { + 'dst_port': dst_port, + 'src_port': src_port, + 'dst_peer_addr': dst_peer_addr, + 'src_peer_addr': src_peer_addr, + } + + logger.info('extra variables for MPLS config:\n{}'.format(pprint.pformat(config_variables))) + duthost.host.options['variable_manager'].extra_vars.update(config_variables) - # Copy APP_DB config to DUT - duthost.copy(src=os.path.join(ADD_DIR, LABEL_SWAP_ROUTES), dest=setup['dut_tmp_dir']) - label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_SWAP_ROUTES) + logger.info('generate config for MPLS') + mpls_config = '{}.json'.format(LABEL_SWAP_ROUTES) + mpls_config_path = os.path.join(setup['dut_tmp_dir'], mpls_config) + template_file='{}.j2'.format(LABEL_SWAP_ROUTES) + duthost.template(src=os.path.join(ADD_DIR, template_file), dest=mpls_config_path) + + result = duthost.shell('config interface mpls add {}'.format(src_port), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + + result = duthost.shell('config interface mpls add {}'.format(dst_port), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_add_dut_path), + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(mpls_config_path), module_ignore_errors=True) if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - # Create packet for sending and masked expected packet on receiving port - pkt = self.mpls_packet(setup, ptfadapter) + pkt = self.mpls_packet(setup, ptfadapter, dst_pid, src_pid) exp_pkt = self.expected_mask_mpls_swap_packet(pkt, 1000002) + + time.sleep(20) ptfadapter.dataplane.flush() + testutils.send(ptfadapter, src_pid, pkt) + try: + res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) + except Exception as e: + self.teardown_labels(setup,src_port,dst_port) + pytest.fail('MPLS swap test failed \n' + str(e)) + + self.teardown_labels(setup,src_port,dst_port) + + def test_push_label(self, setup, ptfadapter): + """ test push label """ - # Send pkt from spine port 10 - testutils.send(ptfadapter, '10', pkt) - - # Capture and verify packets on tor port 25 - res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) + setup = setup + duthost = setup['duthost'] + + dst_pid=self.get_dst_portid(setup) + src_pid=self.get_src_portid(setup) + + dst_port=setup['tor_ports'][dst_pid] + src_port=setup['spine_ports'][src_pid] + + dst_peer_addr=setup['tor_peer_addr'][dst_pid] + src_peer_addr=setup['spine_peer_addr'][src_pid] + + config_variables = { + 'dst_port': dst_port, + 'src_port': src_port, + 'dst_peer_addr': dst_peer_addr, + 'src_peer_addr': src_peer_addr, + } + + logger.info('extra variables for MPLS config:\n{}'.format(pprint.pformat(config_variables))) + duthost.host.options['variable_manager'].extra_vars.update(config_variables) - # Copy Delete MPLS configs to DUT after test - duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) - label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) + logger.info('generate config for MPLS') + mpls_config = '{}.json'.format(LABEL_PUSH_ROUTES) + mpls_config_path = os.path.join(setup['dut_tmp_dir'], mpls_config) + template_file='{}.j2'.format(LABEL_PUSH_ROUTES) + duthost.template(src=os.path.join(ADD_DIR, template_file), dest=mpls_config_path) - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), + result = duthost.shell('config interface mpls add {}'.format(src_port), module_ignore_errors=True) if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - def test_push_label(self, setup, ptfadapter): - """ test push MPLS label """ - - duthost = setup['duthost'] - - # Copy APP_DB config to DUT - duthost.copy(src=os.path.join(ADD_DIR, LABEL_PUSH_ROUTES), dest=setup['dut_tmp_dir']) - label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_PUSH_ROUTES) + result = duthost.shell('config interface mpls add {}'.format(dst_port), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_add_dut_path), + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(mpls_config_path), module_ignore_errors=True) if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - # Create packet for sending and masked expected packet on receiving port - pkt = self.icmp_packet(setup, ptfadapter) - ## Add MPLS header in expected packet + time.sleep(20) + + pkt = self.icmp_packet(setup, ptfadapter, dst_pid, src_pid) epkt = pkt.copy() pkt1 = epkt['IP'] epkt['Ether'].type=0x8847 @@ -330,71 +518,92 @@ def test_push_label(self, setup, ptfadapter): exp_pkt = self.expected_mask_mpls_push_packet(epkt, 1000001) ptfadapter.dataplane.flush() + testutils.send(ptfadapter, src_pid, pkt) + + try: + res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) + logger.info(res) + except Exception as e: + self.teardown_labels(setup,src_port,dst_port) + pytest.fail('MPLS push test failed \n' + str(e)) + + self.teardown_labels(setup,src_port,dst_port) + + def test_swap_labelstack(self, setup, ptfadapter): + """ test swap labelstack """ - # Send pkt from spine port 10 - testutils.send(ptfadapter, '10', pkt) - - # Capture and verify packets on tor port 25 - res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) + setup = setup + duthost = setup['duthost'] + + dst_pid=self.get_dst_portid(setup) + src_pid=self.get_src_portid(setup) + + dst_port=setup['tor_ports'][dst_pid] + src_port=setup['spine_ports'][src_pid] + + dst_peer_addr=setup['tor_peer_addr'][dst_pid] + src_peer_addr=setup['spine_peer_addr'][src_pid] + + config_variables = { + 'dst_port': dst_port, + 'src_port': src_port, + 'dst_peer_addr': dst_peer_addr, + 'src_peer_addr': src_peer_addr, + } + + logger.info('extra variables for MPLS config:\n{}'.format(pprint.pformat(config_variables))) + duthost.host.options['variable_manager'].extra_vars.update(config_variables) - # Copy Delete MPLS configs to DUT after test - duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) - label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) + logger.info('generate config for MPLS') + mpls_config = '{}.json'.format(LABEL_SWAP_ROUTES) + mpls_config_path = os.path.join(setup['dut_tmp_dir'], mpls_config) + template_file='{}.j2'.format(LABEL_SWAP_ROUTES) + duthost.template(src=os.path.join(ADD_DIR, template_file), dest=mpls_config_path) - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), + result = duthost.shell('config interface mpls add {}'.format(src_port), module_ignore_errors=True) if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - - def test_swap_labelstack(self, setup, ptfadapter): - """ test swap for stack of 3 MPLS label """ - - duthost = setup['duthost'] - - # Copy APP_DB config to DUT - duthost.copy(src=os.path.join(ADD_DIR, LABEL_SWAP_ROUTES), dest=setup['dut_tmp_dir']) - label_add_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_SWAP_ROUTES) + result = duthost.shell('config interface mpls add {}'.format(dst_port), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_add_dut_path), + result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(mpls_config_path), module_ignore_errors=True) if result['rc'] != 0: pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - # Create packet for sending and masked expected packet on receiving port - pkt = self.mpls_stack_packet(setup, ptfadapter) + pkt = self.mpls_stack_packet(setup, ptfadapter, dst_pid, src_pid) exp_pkt = self.expected_mask_mpls_swap_packet(pkt, 1000002) ptfadapter.dataplane.flush() - - # Send pkt from spine port 10 - testutils.send(ptfadapter, '10', pkt) - - # Capture and verify packets on tor port 25 - res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[25]) + testutils.send(ptfadapter, src_pid, pkt) - # Copy Delete MPLS configs to DUT after test - duthost.copy(src=os.path.join(ADD_DIR, LABEL_DEL_ROUTES), dest=setup['dut_tmp_dir']) - label_del_dut_path = os.path.join(setup['dut_tmp_dir'], LABEL_DEL_ROUTES) + try: + res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) + logger.info(res) + except Exception as e: + self.teardown_labels(setup,src_port,dst_port) + pytest.fail('MPLS swap labelstack test failed \n' + str(e)) - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + self.teardown_labels(setup,src_port,dst_port) class TestBasicMpls(BaseMplsTest): """ - Basic MPLS traffic tests. + Basic ACL rules traffic tests. + Setup rules using full update, run traffic tests cases. """ - def setup_rules(self, dut, setup): + def setup_rules(self, dut, setup, acl_table): """ setup rules on DUT :param dut: dut host :param setup: setup information + :param acl_table: acl table creating fixture :return: """ From 6922d24bbdfdb12527bfd3d0efa77d4ba31dd399 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Fri, 21 Jan 2022 00:50:18 +0530 Subject: [PATCH 23/36] Update test_mpls.py Removing unused codes --- tests/mpls/test_mpls.py | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index 72f91d620a6..e570ebfb8e9 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -127,10 +127,10 @@ def setup(duthost, tbinfo, ptfadapter): yield setup_information - #duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_POP_ROUTES))) - #duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_SWAP_ROUTES))) - #duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_PUSH_ROUTES1))) - #duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_DEL_ROUTES))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_POP_ROUTES))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_SWAP_ROUTES))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_PUSH_ROUTES1))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_DEL_ROUTES))) def port_up(dut, interface): intf_facts = dut.interface_facts()['ansible_facts'] @@ -153,25 +153,13 @@ class BaseMplsTest(object): @abstractmethod - def setup_rules(self, dut, setup, acl_table): + def setup_rules(self, dut, setup): """ setup rules for test :param dut: dut host :param setup: setup information - :param acl_table: acl table creating fixture :return: """ - host_facts = duthost.setup()['ansible_facts'] - route_file_dir = duthost.shell('mktemp')['stdout'] - # Copy json file to DUT - myFile=open('mpls/label_routes.json', 'r') - myLabels=myFile.read() - duthost.copy(content=myLabels, dest=route_file_dir, verbose=False) - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(route_file_dir), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) pass def post_setup_hook(self, dut, localhost): @@ -594,16 +582,15 @@ def test_swap_labelstack(self, setup, ptfadapter): class TestBasicMpls(BaseMplsTest): """ - Basic ACL rules traffic tests. + Basic MPLS label traffic tests. Setup rules using full update, run traffic tests cases. """ - def setup_rules(self, dut, setup, acl_table): + def setup_rules(self, dut, setup): """ setup rules on DUT :param dut: dut host :param setup: setup information - :param acl_table: acl table creating fixture :return: """ From d244442399ce3246f18f068555b9142afacd045b Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Fri, 21 Jan 2022 01:01:55 +0530 Subject: [PATCH 24/36] Update test_mpls.py Correcting filename --- tests/mpls/test_mpls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index e570ebfb8e9..b740e6907ec 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -129,7 +129,7 @@ def setup(duthost, tbinfo, ptfadapter): duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_POP_ROUTES))) duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_SWAP_ROUTES))) - duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_PUSH_ROUTES1))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_PUSH_ROUTES))) duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_DEL_ROUTES))) def port_up(dut, interface): From f379098c7266ba27946649fdc016050f7a9c3808 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Tue, 25 Jan 2022 10:59:58 +0530 Subject: [PATCH 25/36] Update MPLS-test-plan.md For interface config --- docs/testplan/MPLS-test-plan.md | 44 +++------------------------------ 1 file changed, 4 insertions(+), 40 deletions(-) diff --git a/docs/testplan/MPLS-test-plan.md b/docs/testplan/MPLS-test-plan.md index 36b7eb693bd..3549523d850 100644 --- a/docs/testplan/MPLS-test-plan.md +++ b/docs/testplan/MPLS-test-plan.md @@ -28,6 +28,10 @@ Purpose of the test is to verify MPLS on a SONiC system bringing up the ingress, T1 ## Setup configuration +MPLS will be enabled/disabled on interface command: +``` +config interface mpls +``` MPLS configuration will be set on DUT dynamically. #### Setup of DUT switch @@ -48,12 +52,6 @@ label_pop_routes.json }, "OP": "SET" }, - { - "INTF_TABLE:Ethernet10": { - "mpls": "enable" - }, - "OP": "SET" - }, { "LABEL_ROUTE_TABLE:1000003": { "nexthop": "10.0.0.21", @@ -62,12 +60,6 @@ label_pop_routes.json "weight": "1" }, "OP": "SET" - }, - { - "INTF_TABLE:Ethernet25": { - "mpls": "enable" - }, - "OP": "SET" } ] ``` @@ -84,12 +76,6 @@ label_pop_routes.json "weight": "1" }, "OP": "SET" - }, - { - "INTF_TABLE:Ethernet25": { - "mpls": "enable" - }, - "OP": "SET" } ] ``` @@ -107,12 +93,6 @@ label_swap_routes.json }, "OP": "SET" }, - { - "INTF_TABLE:Ethernet10": { - "mpls": "enable" - }, - "OP": "SET" - }, { "LABEL_ROUTE_TABLE:1000003": { "nexthop": "10.0.0.21", @@ -122,12 +102,6 @@ label_swap_routes.json "weight": "1" }, "OP": "SET" - }, - { - "INTF_TABLE:Ethernet25": { - "mpls": "enable" - }, - "OP": "SET" } ] ``` @@ -140,21 +114,11 @@ label_del_routes.json }, "OP": "DEL" }, - { - "INTF_TABLE:Ethernet10": { - }, - "OP": "DEL" - }, { "LABEL_ROUTE_TABLE:1000003": { }, "OP": "DEL" }, - { - "INTF_TABLE:Ethernet25": { - }, - "OP": "DEL" - }, { "ROUTE_TABLE:192.168.0.1": { }, From df4e5465a5628036283b200ac5fa9c830b6efa48 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Tue, 25 Jan 2022 11:03:13 +0530 Subject: [PATCH 26/36] Update MPLS-test-plan.md remove ip and port --- docs/testplan/MPLS-test-plan.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/testplan/MPLS-test-plan.md b/docs/testplan/MPLS-test-plan.md index 3549523d850..18922484d1f 100644 --- a/docs/testplan/MPLS-test-plan.md +++ b/docs/testplan/MPLS-test-plan.md @@ -45,8 +45,8 @@ label_pop_routes.json [ { "LABEL_ROUTE_TABLE:1000001": { - "nexthop": "10.0.0.51", - "ifname": "Ethernet25", + "nexthop": "{{ nexthop }}", + "ifname": "{{ port }}", "mpls_pop": "1", "weight": "1" }, @@ -54,8 +54,8 @@ label_pop_routes.json }, { "LABEL_ROUTE_TABLE:1000003": { - "nexthop": "10.0.0.21", - "ifname": "Ethernet10", + "nexthop": "{{ nexthop }}", + "ifname": "{{ port }}", "mpls_pop": "1", "weight": "1" }, @@ -70,8 +70,8 @@ label_pop_routes.json [ { "ROUTE_TABLE:192.168.0.1": { - "nexthop": "10.0.0.51", - "ifname": "Ethernet25", + "nexthop": "{{ nexthop }}", + "ifname": "{{ port }}", "mpls_nh": "push1000001", "weight": "1" }, @@ -85,8 +85,8 @@ label_swap_routes.json [ { "LABEL_ROUTE_TABLE:1000001": { - "nexthop": "10.0.0.51", - "ifname": "Ethernet25", + "nexthop": "{{ nexthop }}", + "ifname": "{{ port }}", "mpls_nh": "swap1000002", "mpls_pop": "1" "weight": "1" @@ -95,8 +95,8 @@ label_swap_routes.json }, { "LABEL_ROUTE_TABLE:1000003": { - "nexthop": "10.0.0.21", - "ifname": "Ethernet10", + "nexthop": "{{ nexthop }}", + "ifname": "{{ port }}", "mpls_nh": "swap1000004", "mpls_pop": "1", "weight": "1" From bcae2fc3edafe73f1885eb3241b650b237a2bc24 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Tue, 25 Jan 2022 21:00:39 +0530 Subject: [PATCH 27/36] Update test_mpls.py Removed redundant topology check --- tests/mpls/test_mpls.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index b740e6907ec..e7ef2a2e7a9 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -42,9 +42,6 @@ def setup(duthost, tbinfo, ptfadapter): :param tbinfo: fixture provides information about testbed :return: dictionary with all test required information """ - if tbinfo['topo']['name'] not in ('t1', 't1-lag', 't1-64-lag', 't1-64-lag-clet'): - pytest.skip('Unsupported topology') - # gather ansible facts mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] int_facts = duthost.interface_facts()['ansible_facts'] From 424eafc1ec215e61d8ca1baa4dbe2a3636dd49be Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 9 Feb 2022 21:56:10 +0530 Subject: [PATCH 28/36] Update MPLS-test-plan.md json ext to j2 --- docs/testplan/MPLS-test-plan.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/testplan/MPLS-test-plan.md b/docs/testplan/MPLS-test-plan.md index 18922484d1f..c8b12f0682a 100644 --- a/docs/testplan/MPLS-test-plan.md +++ b/docs/testplan/MPLS-test-plan.md @@ -39,7 +39,7 @@ During testrun, Ansible will copy JSON file containing configuration for MPLS to JSON Sample: -label_pop_routes.json +label_pop_routes.j2 ``` [ @@ -64,7 +64,7 @@ label_pop_routes.json ] ``` - label_push_routes.json + label_push_routes.j2 ``` [ @@ -79,7 +79,7 @@ label_pop_routes.json } ] ``` -label_swap_routes.json +label_swap_routes.j2 ``` [ @@ -105,7 +105,7 @@ label_swap_routes.json } ] ``` -label_del_routes.json +label_del_routes.j2 ``` [ From be0ed88076953c1aaec11bdcb86acc362abf9a95 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 16 Mar 2022 23:10:36 +0530 Subject: [PATCH 29/36] Create conftest.py Adding setup in conftest file --- tests/mpls/conftest.py | 122 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 tests/mpls/conftest.py diff --git a/tests/mpls/conftest.py b/tests/mpls/conftest.py new file mode 100644 index 00000000000..ea37b576efa --- /dev/null +++ b/tests/mpls/conftest.py @@ -0,0 +1,122 @@ +import logging +import pytest +import pprint + +logger = logging.getLogger(__name__) + +DUT_TMP_DIR='/tmp' + +LABEL_POP_ROUTES='label_pop_routes' +LABEL_PUSH_ROUTES='label_push_routes' +LABEL_SWAP_ROUTES='label_swap_routes' +LABEL_DEL_ROUTES='label_del_routes' + +@pytest.fixture(scope='module') +def setup(duthost, tbinfo, ptfadapter): + """ + setup fixture gathers all test required information from DUT facts and tbinfo + :param duthost: DUT host object + :param tbinfo: fixture provides information about testbed + :return: dictionary with all test required information + """ + if tbinfo['topo']['name'] not in ('t1'): + pytest.skip('Unsupported topology') + + # gather ansible facts + mg_facts=duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] + int_facts=duthost.interface_facts()['ansible_facts'] + host_facts=duthost.setup()['ansible_facts'] + + tor_ports_ids={} + tor_ports=[] + spine_ports_ids={} + spine_ports=[] + tor_addr={} + tor_peer_addr={} + spine_addr={} + spine_peer_addr={} + tor_mac={} + spine_mac={} + + all_ifs=[] + + ip_ifaces=duthost.get_active_ip_interfaces(tbinfo, asic_index="all") + + for k,v in ip_ifaces[0].items(): + all_ifs.append(k) + logger.info(ip_ifaces[0][k]) + if 'T0' in v['bgp_neighbor']: + tor_ports.append(k) + tor_addr[k]=v['ipv4'] + tor_peer_addr[k]=v['peer_ipv4'] + elif 'T2' in v['bgp_neighbor']: + spine_ports.append(k) + spine_addr[k]=v['ipv4'] + spine_peer_addr[k]=v['peer_ipv4'] + + logger.info('tor_ports: {}'.format(tor_ports)) + logger.info('spine_ports: {}'.format(spine_ports)) + logger.info('tor_addr: {}'.format(tor_addr)) + + for dut_port in tor_ports: + port_id=mg_facts['minigraph_port_indices'][dut_port] + tor_ports_ids[dut_port]=port_id + ansible_port='ansible_'+dut_port + tor_mac[dut_port]=host_facts[ansible_port]['macaddress'] + + for dut_port in spine_ports: + port_id=mg_facts['minigraph_port_indices'][dut_port] + spine_ports_ids[dut_port]=port_id + ansible_port='ansible_'+dut_port + spine_mac[dut_port]=host_facts[ansible_port]['macaddress'] + + logger.info('spine_mac: {}'.format(spine_mac)) + logger.info('spine_ports_ids: {}'.format(spine_ports_ids)) + + src_port=random.choice(spine_ports) + dst_port=random.choice(tor_ports) + + dst_pid=tor_ports_ids[dst_port] + src_pid=spine_ports_ids[src_port] + + dst_mac=tor_mac[dst_port] + src_mac=spine_mac[src_port] + + dst_addr=tor_addr[dst_port] + src_addr=spine_addr[src_port] + + dst_peer_addr=tor_peer_addr[dst_port] + src_peer_addr=spine_peer_addr[src_port] + + setup_information={ + 'duthost': duthost, + 'dut_tmp_dir': DUT_TMP_DIR, + 'dst_ip_spine_blocked': '192.168.144.1', + 'src_port': src_port, + 'dst_port': dst_port, + 'src_addr': src_addr, + 'src_peer_addr': src_peer_addr, + 'dst_addr': dst_addr, + 'dst_peer_addr': dst_peer_addr, + 'src_pid': src_pid, + 'dst_pid': dst_pid, + 'src_mac': src_mac, + 'dst_mac': dst_mac, + } + + logger.info('setup variables {}'.format(pprint.pformat(setup))) + + # FIXME: There seems to be some issue with the initial setup of the ptfadapter, causing some of the + # TestBasicMPLS tests to fail because the forwarded packets are not being collected. This is an + # attempt to mitigate that issue while we continue to investigate the root cause. + # + # Ref: GitHub Issue #2032 + logger.info("setting up the ptfadapter") + ptfadapter.reinit() + + yield setup_information + + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_POP_ROUTES, '.json'))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_SWAP_ROUTES, '.json'))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_PUSH_ROUTES, '.json'))) + duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_DEL_ROUTES, '.json'))) From 23a8e4773746982c82867f5317fa2475edd378cb Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 16 Mar 2022 23:11:55 +0530 Subject: [PATCH 30/36] Update test_mpls.py Addressing review comments. --- tests/mpls/test_mpls.py | 510 ++++++++++------------------------------ 1 file changed, 127 insertions(+), 383 deletions(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index e7ef2a2e7a9..7c0409e1be5 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -1,144 +1,34 @@ -import os -import time -import random +import json import logging +import os import pprint -import json - -from abc import ABCMeta, abstractmethod - -import pytest - -import ptf.testutils as testutils import ptf.mask as mask import ptf.packet as packet +import ptf.testutils as testutils +import pytest +import random +import time +from abc import ABCMeta, abstractmethod from tests.common import reboot, port_toggle -from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer, LogAnalyzerError -from tests.common.fixtures.duthost_utils import backup_and_restore_config_db_module from tests.common.config_reload import config_reload +from tests.common.fixtures.duthost_utils import backup_and_restore_config_db_module +from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer, LogAnalyzerError -logger = logging.getLogger(__name__) +logger=logging.getLogger(__name__) -pytestmark = [ -# pytest.mark.disable_loganalyzer, # disable automatic loganalyzer +pytestmark=[ pytest.mark.topology('t1'), -# pytest.mark.sanity_check(skip_sanity=True) ] -BASE_DIR = os.path.dirname(os.path.realpath(__file__)) -DUT_TMP_DIR='/tmp' -ADD_DIR = os.path.join(BASE_DIR, 'configs') +CONFIGS_DIR=os.path.dirname(os.path.realpath(__file__)) +#DUT_TMP_DIR='/tmp' +ADD_DIR=os.path.join(CONFIGS_DIR, 'configs') LABEL_POP_ROUTES='label_pop_routes' LABEL_PUSH_ROUTES='label_push_routes' LABEL_SWAP_ROUTES='label_swap_routes' LABEL_DEL_ROUTES='label_del_routes' -@pytest.fixture(scope='module') -def setup(duthost, tbinfo, ptfadapter): - """ - setup fixture gathers all test required information from DUT facts and tbinfo - :param duthost: DUT host object - :param tbinfo: fixture provides information about testbed - :return: dictionary with all test required information - """ - # gather ansible facts - mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] - int_facts = duthost.interface_facts()['ansible_facts'] - host_facts = duthost.setup()['ansible_facts'] - - tor_ports_ids=[] - tor_ports={} - spine_ports_ids=[] - spine_ports={} - tor_addr={} - tor_peer_addr={} - spine_addr={} - spine_peer_addr={} - tor_mac={} - spine_mac={} - - # get the list of TOR/SPINE ports - for dut_port, neigh in mg_facts['minigraph_neighbors'].items(): - if not port_up(duthost, dut_port): - continue - port_id = mg_facts['minigraph_port_indices'][dut_port] - if 'T0' in neigh['name']: - tor_ports[port_id]=dut_port - tor_ports_ids.append(port_id) - elif 'T2' in neigh['name']: - spine_ports[port_id]=dut_port - spine_ports_ids.append(port_id) - - logger.info('tor_ports: {}'.format(tor_ports)) - logger.info('spine_ports: {}'.format(spine_ports)) - - for blk in mg_facts['minigraph_interfaces']: - if ':' in blk['peer_addr']: - continue - dut_port=blk['attachto'] - port_id = mg_facts['minigraph_port_indices'][dut_port] - neigh=mg_facts['minigraph_neighbors'][dut_port] - if 'T0' in neigh['name']: - tor_addr[port_id]=blk['addr'] - tor_peer_addr[port_id]=blk['peer_addr'] - elif 'T2' in neigh['name']: - spine_addr[port_id]=blk['addr'] - spine_peer_addr[port_id]=blk['peer_addr'] - - for pid, dut_port in tor_ports.items(): - port_id = mg_facts['minigraph_port_indices'][dut_port] - ansible_port='ansible_'+dut_port - tor_mac[port_id]=host_facts[ansible_port]['macaddress'] - - for pid, dut_port in spine_ports.items(): - port_id = mg_facts['minigraph_port_indices'][dut_port] - ansible_port='ansible_'+dut_port - spine_mac[port_id]=host_facts[ansible_port]['macaddress'] - - setup_information = { - 'duthost': duthost, - 'dut_tmp_dir': DUT_TMP_DIR, - 'dst_ip_spine_blocked': '192.168.144.1', - 'tor_ports': tor_ports, - 'spine_ports': spine_ports, - 'tor_addr': tor_addr, - 'tor_peer_addr': tor_peer_addr, - 'spine_addr': spine_addr, - 'spine_peer_addr': spine_peer_addr, - 'tor_ports_ids': tor_ports_ids, - 'spine_ports_ids': spine_ports_ids, - 'tor_mac': tor_mac, - 'spine_mac': spine_mac, - } - - logger.info('setup variables {}'.format(pprint.pformat(setup))) - - # FIXME: There seems to be some issue with the initial setup of the ptfadapter, causing some of the - # TestBasicMPLS tests to fail because the forwarded packets are not being collected. This is an - # attempt to mitigate that issue while we continue to investigate the root cause. - # - # Ref: GitHub Issue #2032 - logger.info("setting up the ptfadapter") - ptfadapter.reinit() - - yield setup_information - - duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_POP_ROUTES))) - duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_SWAP_ROUTES))) - duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_PUSH_ROUTES))) - duthost.command('rm -rf {}'.format(os.path.join(DUT_TMP_DIR, LABEL_DEL_ROUTES))) - -def port_up(dut, interface): - intf_facts = dut.interface_facts()['ansible_facts'] - try: - port = intf_facts["ansible_interface_facts"][interface] - if port["link"] and port["active"]: - return True - except KeyError: - return False - return False - class BaseMplsTest(object): """ Base class for MPLS label testing. @@ -146,7 +36,7 @@ class BaseMplsTest(object): optionally override @teardown_rules which base implementation is simply applying empty MPLS labels configuration file """ - __metaclass__ = ABCMeta + __metaclass__=ABCMeta @abstractmethod @@ -169,86 +59,51 @@ def post_setup_hook(self, dut, localhost): pass - def teardown_labels(self, setup, src_port, dst_port): + def teardown_labels(self, setup): """ teardown MPLS label after test by applying empty configuration :param dut: DUT host object :param setup: setup information :return: """ - setup = setup - duthost = setup['duthost'] - - logger.info('removing all MPLS') - mpls_config = '{}.json'.format(LABEL_DEL_ROUTES) - label_del_dut_path = os.path.join(setup['dut_tmp_dir'], mpls_config) - template_file='{}.j2'.format(LABEL_DEL_ROUTES) - duthost.template(src=os.path.join(ADD_DIR, template_file), dest=label_del_dut_path) - - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(label_del_dut_path), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - - result = duthost.shell('config interface mpls remove {}'.format(src_port), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - - result = duthost.shell('config interface mpls remove {}'.format(dst_port), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - + logger.info("Remove mpls comfigs") + self.config_interface_mpls(setup, LABEL_DEL_ROUTES, False) - def get_src_portid(self, setup): - """ return source port id """ - - src_pids = setup['spine_ports_ids'] - return random.choice(src_pids) - - def get_dst_portid(self, setup): - """ return destination port id""" - - dst_pids = setup['tor_ports_ids'] - return random.choice(dst_pids) - - def icmp_packet(self, setup, ptfadapter, dst_pid, src_pid): + def icmp_packet(self, setup, ptfadapter): """ create ICMP packet for testing """ return testutils.simple_icmp_packet( - eth_dst=setup['spine_mac'][src_pid], - eth_src=ptfadapter.dataplane.get_mac(0, src_pid), + eth_dst=setup['src_mac'], + eth_src=ptfadapter.dataplane.get_mac(0, setup['src_pid']), ip_dst='192.168.0.1', - ip_src=setup['spine_addr'][src_pid], + ip_src=setup['src_addr'], icmp_type=8, icmp_code=0, ip_ttl=64, ) - def mpls_packet(self, setup, ptfadapter, dst_pid, src_pid): + def mpls_packet(self, setup, ptfadapter): """ create MPLS packet for testing """ return testutils.simple_mpls_packet( - eth_dst=setup['spine_mac'][src_pid], - eth_src=ptfadapter.dataplane.get_mac(0, src_pid), - mpls_tags = [ + eth_dst=setup['src_mac'], + eth_src=ptfadapter.dataplane.get_mac(0, setup['src_pid']), + mpls_tags=[ { 'label':1000001, 'ttl': 63, 's':1 } ], - inner_frame = testutils.simple_ip_only_packet( + inner_frame=testutils.simple_ip_only_packet( ip_dst='192.168.0.1', - ip_src=setup['spine_addr'][src_pid], + ip_src=setup['src_addr'], ) - ) + ) - def mpls_stack_packet(self, setup, ptfadapter, dst_pid, src_pid): + def mpls_stack_packet(self, setup, ptfadapter): """ create MPLS packet for testing """ return testutils.simple_mpls_packet( - eth_dst=setup['spine_mac'][src_pid], - eth_src=ptfadapter.dataplane.get_mac(0, src_pid), - mpls_tags = [ + eth_dst=setup['src_mac'], + eth_src=ptfadapter.dataplane.get_mac(0, setup['src_pid']), + mpls_tags=[ { 'label':1000001, 'ttl': 255, @@ -265,39 +120,39 @@ def mpls_stack_packet(self, setup, ptfadapter, dst_pid, src_pid): 's':1 } ], - inner_frame = testutils.simple_ip_only_packet( + inner_frame=testutils.simple_ip_only_packet( ip_dst='192.168.0.1', - ip_src=setup['spine_addr'][src_pid], + ip_src=setup['src_addr'], ) ) def expected_mask_ip_packet(self, pkt): """ return mask for ip packet """ - + epkt=pkt.copy() - exp_pkt = pkt.copy() - exp_pkt['IP'].ttl = 62 - pkt1 = exp_pkt['IP'] - exp_pkt['Ether'].type=0x0800 - exp_pkt['Ether'].remove_payload() + exp_pkt=pkt.copy() + exp_pkt['IP'].ttl=62 + pkt1=exp_pkt['IP'] + exp_pkt['Ethernet'].type=0x0800 + exp_pkt['Ethernet'].remove_payload() exp_pkt /= pkt1 #exp_pkt['IP'].len=100 - epkt = mask.Mask(epkt) - #pkt2 = mask.Mask(pkt2) - exp_pkt = mask.Mask(exp_pkt) + epkt=mask.Mask(epkt) + #pkt2=mask.Mask(pkt2) + exp_pkt=mask.Mask(exp_pkt) exp_pkt.set_do_not_care_scapy(packet.Ether, 'dst') exp_pkt.set_do_not_care_scapy(packet.Ether, 'src') exp_pkt.set_do_not_care_scapy(packet.IP, 'chksum') return exp_pkt - + def expected_mask_mpls_swap_packet(self, pkt, exp_label): """ return mask for mpls packet """ - exp_pkt = pkt.copy() + exp_pkt=pkt.copy() exp_pkt['MPLS'].ttl -= 1 - exp_pkt['MPLS'].label = exp_label - exp_pkt = mask.Mask(exp_pkt) + exp_pkt['MPLS'].label=exp_label + exp_pkt=mask.Mask(exp_pkt) exp_pkt.set_do_not_care_scapy(packet.Ether, 'dst') exp_pkt.set_do_not_care_scapy(packet.Ether, 'src') exp_pkt.set_do_not_care_scapy(packet.IP, 'chksum') @@ -307,33 +162,27 @@ def expected_mask_mpls_swap_packet(self, pkt, exp_label): def expected_mask_mpls_push_packet(self, pkt, exp_label): """ return mask for mpls packet """ - exp_pkt = pkt.copy() - exp_pkt['MPLS'].ttl = exp_pkt['IP'].ttl - 1 + exp_pkt=pkt.copy() + exp_pkt['MPLS'].ttl=exp_pkt['IP'].ttl - 1 exp_pkt['IP'].ttl -= 1 - exp_pkt['MPLS'].label = exp_label - exp_pkt = mask.Mask(exp_pkt) + exp_pkt['MPLS'].label=exp_label + exp_pkt=mask.Mask(exp_pkt) exp_pkt.set_do_not_care_scapy(packet.Ether, 'dst') exp_pkt.set_do_not_care_scapy(packet.Ether, 'src') exp_pkt.set_do_not_care_scapy(packet.IP, 'chksum') return exp_pkt + def config_interface_mpls(self, setup, config_file, enable=True): + """ enable/disable mpls on interface """ + duthost=setup['duthost'] - def test_pop_label(self, setup, ptfadapter): - """ test pop label """ - - setup = setup - duthost = setup['duthost'] - - dst_pid=self.get_dst_portid(setup) - src_pid=self.get_src_portid(setup) - - dst_port=setup['tor_ports'][dst_pid] - src_port=setup['spine_ports'][src_pid] + dst_port=setup['dst_port'] + src_port=setup['src_port'] - dst_peer_addr=setup['tor_peer_addr'][dst_pid] - src_peer_addr=setup['spine_peer_addr'][src_pid] + dst_peer_addr=setup['dst_peer_addr'] + src_peer_addr=setup['src_peer_addr'] - config_variables = { + config_variables={ 'dst_port': dst_port, 'src_port': src_port, 'dst_peer_addr': dst_peer_addr, @@ -342,240 +191,135 @@ def test_pop_label(self, setup, ptfadapter): logger.info('extra variables for MPLS config:\n{}'.format(pprint.pformat(config_variables))) duthost.host.options['variable_manager'].extra_vars.update(config_variables) - + logger.info('generate config for MPLS') - mpls_config = '{}.json'.format(LABEL_POP_ROUTES) - mpls_config_path = os.path.join(setup['dut_tmp_dir'], mpls_config) - template_file='{}.j2'.format(LABEL_POP_ROUTES) + mpls_config='{}.json'.format(config_file) + mpls_config_path=os.path.join(setup['dut_tmp_dir'], mpls_config) + template_file='{}.j2'.format(config_file) duthost.template(src=os.path.join(ADD_DIR, template_file), dest=mpls_config_path) - result = duthost.shell('config interface mpls add {}'.format(src_port), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - result = duthost.shell('config interface mpls add {}'.format(dst_port), + for intf in [dst_port, src_port]: + if enable: + result=duthost.shell('config interface mpls add {}'.format(intf), module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + if result['rc'] != 0: + pytest.fail('Failed to enable mplson interface {} : {}'.format(intf, result['stderr'])) + else: + result=duthost.shell('config interface mpls remove {}'.format(intf), + module_ignore_errors=True) + if result['rc'] != 0: + pytest.fail('Failed to disable mpls on interface {} : {}'.format(intf, result['stderr'])) - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(mpls_config_path), + # Apply config with swssconfig + result=duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(mpls_config_path), module_ignore_errors=True) if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - time.sleep(20) - pkt = self.mpls_packet(setup, ptfadapter, dst_pid, src_pid) - exp_pkt = self.expected_mask_ip_packet(pkt) - + def test_pop_label(self, setup, ptfadapter): + """ test pop label """ + dst_pid=setup['dst_pid'] + src_pid=setup['src_pid'] + + self.config_interface_mpls(setup, LABEL_POP_ROUTES) + + time.sleep(2) + + pkt=self.mpls_packet(setup, ptfadapter) + exp_pkt=self.expected_mask_ip_packet(pkt) + ptfadapter.dataplane.flush() testutils.send(ptfadapter, src_pid, pkt) try: - res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) + res=testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) logger.info(res) except Exception as e: - self.teardown_labels(setup,src_port,dst_port) - pytest.fail('MPLS pop test failed \n' + str(e)) + self.teardown_labels(setup) + pytest.fail('MPLS pop test failed \n'+ str(e)) - self.teardown_labels(setup,src_port,dst_port) + self.teardown_labels(setup) def test_swap_label(self, setup, ptfadapter): """ test swap label """ - setup = setup - duthost = setup['duthost'] - - dst_pid=self.get_dst_portid(setup) - src_pid=self.get_src_portid(setup) - - dst_port=setup['tor_ports'][dst_pid] - src_port=setup['spine_ports'][src_pid] - - dst_peer_addr=setup['tor_peer_addr'][dst_pid] - src_peer_addr=setup['spine_peer_addr'][src_pid] - - config_variables = { - 'dst_port': dst_port, - 'src_port': src_port, - 'dst_peer_addr': dst_peer_addr, - 'src_peer_addr': src_peer_addr, - } - - logger.info('extra variables for MPLS config:\n{}'.format(pprint.pformat(config_variables))) - duthost.host.options['variable_manager'].extra_vars.update(config_variables) - - logger.info('generate config for MPLS') - mpls_config = '{}.json'.format(LABEL_SWAP_ROUTES) - mpls_config_path = os.path.join(setup['dut_tmp_dir'], mpls_config) - template_file='{}.j2'.format(LABEL_SWAP_ROUTES) - duthost.template(src=os.path.join(ADD_DIR, template_file), dest=mpls_config_path) - - result = duthost.shell('config interface mpls add {}'.format(src_port), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + dst_pid=setup['dst_pid'] + src_pid=setup['src_pid'] - result = duthost.shell('config interface mpls add {}'.format(dst_port), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(mpls_config_path), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - - pkt = self.mpls_packet(setup, ptfadapter, dst_pid, src_pid) - exp_pkt = self.expected_mask_mpls_swap_packet(pkt, 1000002) + self.config_interface_mpls(setup, LABEL_SWAP_ROUTES) + + time.sleep(2) + + pkt=self.mpls_packet(setup, ptfadapter) + exp_pkt=self.expected_mask_mpls_swap_packet(pkt, 1000002) - time.sleep(20) - ptfadapter.dataplane.flush() testutils.send(ptfadapter, src_pid, pkt) try: - res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) + res=testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) except Exception as e: - self.teardown_labels(setup,src_port,dst_port) + self.teardown_labels(setup) pytest.fail('MPLS swap test failed \n' + str(e)) - self.teardown_labels(setup,src_port,dst_port) + self.teardown_labels(setup) def test_push_label(self, setup, ptfadapter): """ test push label """ - setup = setup - duthost = setup['duthost'] - - dst_pid=self.get_dst_portid(setup) - src_pid=self.get_src_portid(setup) + dst_pid=setup['dst_pid'] + src_pid=setup['src_pid'] - dst_port=setup['tor_ports'][dst_pid] - src_port=setup['spine_ports'][src_pid] + self.config_interface_mpls(setup, LABEL_PUSH_ROUTES) - dst_peer_addr=setup['tor_peer_addr'][dst_pid] - src_peer_addr=setup['spine_peer_addr'][src_pid] - - config_variables = { - 'dst_port': dst_port, - 'src_port': src_port, - 'dst_peer_addr': dst_peer_addr, - 'src_peer_addr': src_peer_addr, - } - - logger.info('extra variables for MPLS config:\n{}'.format(pprint.pformat(config_variables))) - duthost.host.options['variable_manager'].extra_vars.update(config_variables) - - logger.info('generate config for MPLS') - mpls_config = '{}.json'.format(LABEL_PUSH_ROUTES) - mpls_config_path = os.path.join(setup['dut_tmp_dir'], mpls_config) - template_file='{}.j2'.format(LABEL_PUSH_ROUTES) - duthost.template(src=os.path.join(ADD_DIR, template_file), dest=mpls_config_path) + time.sleep(2) - result = duthost.shell('config interface mpls add {}'.format(src_port), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - - result = duthost.shell('config interface mpls add {}'.format(dst_port), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(mpls_config_path), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - - time.sleep(20) - - pkt = self.icmp_packet(setup, ptfadapter, dst_pid, src_pid) - epkt = pkt.copy() - pkt1 = epkt['IP'] - epkt['Ether'].type=0x8847 - epkt['Ether'].remove_payload() - mp = MPLS(label=1000002, s=1, ttl=255) + pkt=self.icmp_packet(setup, ptfadapter) + epkt=pkt.copy() + pkt1=epkt['IP'] + epkt['Ethernet'].type=0x8847 + epkt['Ethernet'].remove_payload() + mp=MPLS(label=1000002, s=1, ttl=255) mp.remove_payload() epkt /= mp epkt /= pkt1 - exp_pkt = self.expected_mask_mpls_push_packet(epkt, 1000001) + exp_pkt=self.expected_mask_mpls_push_packet(epkt, 1000001) ptfadapter.dataplane.flush() testutils.send(ptfadapter, src_pid, pkt) try: - res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) + res=testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) logger.info(res) except Exception as e: - self.teardown_labels(setup,src_port,dst_port) + self.teardown_labels(setup) pytest.fail('MPLS push test failed \n' + str(e)) - self.teardown_labels(setup,src_port,dst_port) + self.teardown_labels(setup) def test_swap_labelstack(self, setup, ptfadapter): """ test swap labelstack """ - - setup = setup - duthost = setup['duthost'] - - dst_pid=self.get_dst_portid(setup) - src_pid=self.get_src_portid(setup) - - dst_port=setup['tor_ports'][dst_pid] - src_port=setup['spine_ports'][src_pid] - - dst_peer_addr=setup['tor_peer_addr'][dst_pid] - src_peer_addr=setup['spine_peer_addr'][src_pid] - - config_variables = { - 'dst_port': dst_port, - 'src_port': src_port, - 'dst_peer_addr': dst_peer_addr, - 'src_peer_addr': src_peer_addr, - } - logger.info('extra variables for MPLS config:\n{}'.format(pprint.pformat(config_variables))) - duthost.host.options['variable_manager'].extra_vars.update(config_variables) - - logger.info('generate config for MPLS') - mpls_config = '{}.json'.format(LABEL_SWAP_ROUTES) - mpls_config_path = os.path.join(setup['dut_tmp_dir'], mpls_config) - template_file='{}.j2'.format(LABEL_SWAP_ROUTES) - duthost.template(src=os.path.join(ADD_DIR, template_file), dest=mpls_config_path) + dst_pid=setup['dst_pid'] + src_pid=setup['src_pid'] - result = duthost.shell('config interface mpls add {}'.format(src_port), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) - - result = duthost.shell('config interface mpls add {}'.format(dst_port), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + self.config_interface_mpls(setup, LABEL_SWAP_ROUTES) - # Apply routes with swssconfig - result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(mpls_config_path), - module_ignore_errors=True) - if result['rc'] != 0: - pytest.fail('Failed to apply labelroute configuration file: {}'.format(result['stderr'])) + time.sleep(2) - pkt = self.mpls_stack_packet(setup, ptfadapter, dst_pid, src_pid) - exp_pkt = self.expected_mask_mpls_swap_packet(pkt, 1000002) + pkt=self.mpls_stack_packet(setup, ptfadapter) + exp_pkt=self.expected_mask_mpls_swap_packet(pkt, 1000002) ptfadapter.dataplane.flush() testutils.send(ptfadapter, src_pid, pkt) try: - res = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) + res=testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) logger.info(res) except Exception as e: - self.teardown_labels(setup,src_port,dst_port) + self.teardown_labels(setup) pytest.fail('MPLS swap labelstack test failed \n' + str(e)) - self.teardown_labels(setup,src_port,dst_port) - + self.teardown_labels(setup) class TestBasicMpls(BaseMplsTest): """ From 981b237b44aac967ccb32912dcd7acdd791275eb Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 16 Mar 2022 23:13:03 +0530 Subject: [PATCH 31/36] Update test_mpls.py Removing unused codes --- tests/mpls/test_mpls.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index 7c0409e1be5..f21d23362c7 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -137,9 +137,7 @@ def expected_mask_ip_packet(self, pkt): exp_pkt['Ethernet'].type=0x0800 exp_pkt['Ethernet'].remove_payload() exp_pkt /= pkt1 - #exp_pkt['IP'].len=100 epkt=mask.Mask(epkt) - #pkt2=mask.Mask(pkt2) exp_pkt=mask.Mask(exp_pkt) exp_pkt.set_do_not_care_scapy(packet.Ether, 'dst') exp_pkt.set_do_not_care_scapy(packet.Ether, 'src') From a101ed04e8f2217d5670ea703adc39514cd301ab Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 16 Mar 2022 23:28:30 +0530 Subject: [PATCH 32/36] Update test_mpls.py Removeing unused code --- tests/mpls/test_mpls.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index f21d23362c7..6105f71f018 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -21,7 +21,6 @@ pytest.mark.topology('t1'), ] CONFIGS_DIR=os.path.dirname(os.path.realpath(__file__)) -#DUT_TMP_DIR='/tmp' ADD_DIR=os.path.join(CONFIGS_DIR, 'configs') LABEL_POP_ROUTES='label_pop_routes' From c95f5467a1aef8241b5ccb34058a600473be8983 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Thu, 17 Mar 2022 07:23:26 +0530 Subject: [PATCH 33/36] Update test_mpls.py Correction for lgtm --- tests/mpls/test_mpls.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index 6105f71f018..a633fe43e5b 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -1,4 +1,3 @@ -import json import logging import os import pprint @@ -6,14 +5,9 @@ import ptf.packet as packet import ptf.testutils as testutils import pytest -import random import time from abc import ABCMeta, abstractmethod -from tests.common import reboot, port_toggle -from tests.common.config_reload import config_reload -from tests.common.fixtures.duthost_utils import backup_and_restore_config_db_module -from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer, LogAnalyzerError logger=logging.getLogger(__name__) @@ -136,7 +130,7 @@ def expected_mask_ip_packet(self, pkt): exp_pkt['Ethernet'].type=0x0800 exp_pkt['Ethernet'].remove_payload() exp_pkt /= pkt1 - epkt=mask.Mask(epkt) + exp_pkt=mask.Mask(exp_pkt) exp_pkt=mask.Mask(exp_pkt) exp_pkt.set_do_not_care_scapy(packet.Ether, 'dst') exp_pkt.set_do_not_care_scapy(packet.Ether, 'src') @@ -254,6 +248,7 @@ def test_swap_label(self, setup, ptfadapter): testutils.send(ptfadapter, src_pid, pkt) try: res=testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[dst_pid]) + logger.info(res) except Exception as e: self.teardown_labels(setup) pytest.fail('MPLS swap test failed \n' + str(e)) From e90192659905ad223a1cf209ea496122611b2eb3 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Thu, 17 Mar 2022 07:24:24 +0530 Subject: [PATCH 34/36] Update conftest.py addressing lgtm review --- tests/mpls/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/mpls/conftest.py b/tests/mpls/conftest.py index ea37b576efa..7540bf21300 100644 --- a/tests/mpls/conftest.py +++ b/tests/mpls/conftest.py @@ -24,7 +24,6 @@ def setup(duthost, tbinfo, ptfadapter): # gather ansible facts mg_facts=duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] - int_facts=duthost.interface_facts()['ansible_facts'] host_facts=duthost.setup()['ansible_facts'] tor_ports_ids={} From 2b71479a9e15f2328e8d2431223dffcdf804cac5 Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 27 Apr 2022 21:10:32 +0530 Subject: [PATCH 35/36] Update test_mpls.py Extra lines --- tests/mpls/test_mpls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index a633fe43e5b..6583cfd1f5c 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -119,7 +119,6 @@ def mpls_stack_packet(self, setup, ptfadapter): ) ) - def expected_mask_ip_packet(self, pkt): """ return mask for ip packet """ @@ -163,6 +162,7 @@ def expected_mask_mpls_push_packet(self, pkt, exp_label): exp_pkt.set_do_not_care_scapy(packet.IP, 'chksum') return exp_pkt + def config_interface_mpls(self, setup, config_file, enable=True): """ enable/disable mpls on interface """ duthost=setup['duthost'] From d6a4cf8b60669dacd812e3620acdf02f43651b1b Mon Sep 17 00:00:00 2001 From: Siji Joseph Date: Wed, 4 May 2022 09:05:22 +0530 Subject: [PATCH 36/36] Update test_mpls.py Removed abc --- tests/mpls/test_mpls.py | 43 +---------------------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/tests/mpls/test_mpls.py b/tests/mpls/test_mpls.py index 6583cfd1f5c..0091ebbc780 100644 --- a/tests/mpls/test_mpls.py +++ b/tests/mpls/test_mpls.py @@ -7,8 +7,6 @@ import pytest import time -from abc import ABCMeta, abstractmethod - logger=logging.getLogger(__name__) pytestmark=[ @@ -22,36 +20,13 @@ LABEL_SWAP_ROUTES='label_swap_routes' LABEL_DEL_ROUTES='label_del_routes' -class BaseMplsTest(object): +class TestBasicMpls: """ Base class for MPLS label testing. Derivatives have to provide @setup_rules method to prepare DUT for MPLS traffic test and optionally override @teardown_rules which base implementation is simply applying empty MPLS labels configuration file """ - __metaclass__=ABCMeta - - - @abstractmethod - def setup_rules(self, dut, setup): - """ - setup rules for test - :param dut: dut host - :param setup: setup information - :return: - """ - pass - - def post_setup_hook(self, dut, localhost): - """ - perform actions after rules are applied - :param dut: DUT host object - :param localhost: localhost object - :return: - """ - - pass - def teardown_labels(self, setup): """ teardown MPLS label after test by applying empty configuration @@ -312,19 +287,3 @@ def test_swap_labelstack(self, setup, ptfadapter): pytest.fail('MPLS swap labelstack test failed \n' + str(e)) self.teardown_labels(setup) - -class TestBasicMpls(BaseMplsTest): - """ - Basic MPLS label traffic tests. - Setup rules using full update, run traffic tests cases. - """ - - def setup_rules(self, dut, setup): - """ - setup rules on DUT - :param dut: dut host - :param setup: setup information - :return: - """ - - pass