diff --git a/tests/everflow/everflow_test_utilities.py b/tests/everflow/everflow_test_utilities.py index 7b81027a2cd..92edf563532 100644 --- a/tests/everflow/everflow_test_utilities.py +++ b/tests/everflow/everflow_test_utilities.py @@ -38,7 +38,8 @@ STABILITY_BUFFER = 0.05 # 50msec -OUTER_HEADER_SIZE = 38 +OUTER_HEADER_SIZE = len(packet.Ether()) + len(packet.IP()) + len(packet.GRE()) +OUTER_HEADER_SIZE_V6 = len(packet.Ether()) + len(packet.IPv6()) + len(packet.GRE()) # This IP is hardcoded into ACL rule TARGET_SERVER_IP = "192.168.0.2" @@ -330,6 +331,14 @@ def get_t2_duthost(duthosts, tbinfo): return t1_duthost, t3_duthost +@pytest.fixture(scope="module", params=[4, 6], ids=["erspan_ipv4", "erspan_ipv6"]) +def erspan_ip_ver(request): + """ + IP version of the outer IP header in a GRE packet + """ + return request.param + + @pytest.fixture(scope="module") def setup_info(duthosts, rand_one_dut_hostname, tbinfo, request, topo_scenario): """ @@ -453,7 +462,7 @@ def setup_arp_responder(duthost, ptfhost, setup_info): # TODO: This should be refactored to some common area of sonic-mgmt. -def get_neighbor_info(duthost, dest_port, tbinfo, resolved=True): +def get_neighbor_info(duthost, dest_port, tbinfo, resolved=True, ip_version=4): """ Get the IP and MAC of the neighbor on the specified destination port. @@ -463,13 +472,13 @@ def get_neighbor_info(duthost, dest_port, tbinfo, resolved=True): resolved: Whether to return a resolved route or not """ if not resolved: - return "20.20.20.100" + return "20.20.20.100" if ip_version == 4 else "2020::20:20:20:100" mg_facts = duthost.get_extended_minigraph_facts(tbinfo) for bgp_peer in mg_facts["minigraph_bgp"]: if bgp_peer["name"] == mg_facts["minigraph_neighbors"][dest_port]["name"] \ - and ipaddr.IPAddress(bgp_peer["addr"]).version == 4: + and ipaddr.IPAddress(bgp_peer["addr"]).version == ip_version: peer_ip = bgp_peer["addr"] break @@ -513,7 +522,7 @@ def get_duthost_set(setup_info): return duthost_set @pytest.fixture(scope="class") - def setup_mirror_session(self, config_method, setup_info): + def setup_mirror_session(self, config_method, setup_info, erspan_ip_ver): """ Set up a mirror session for Everflow. @@ -530,7 +539,7 @@ def setup_mirror_session(self, config_method, setup_info): for duthost in duthost_set: if not session_info: session_info = BaseEverflowTest.mirror_session_info("test_session_1", duthost.facts["asic_type"]) - BaseEverflowTest.apply_mirror_config(duthost, session_info, config_method) + BaseEverflowTest.apply_mirror_config(duthost, session_info, config_method, erspan_ip_ver=erspan_ip_ver) yield session_info @@ -538,7 +547,7 @@ def setup_mirror_session(self, config_method, setup_info): BaseEverflowTest.remove_mirror_config(duthost, session_info["session_name"], config_method) @pytest.fixture(scope="class") - def policer_mirror_session(self, config_method, setup_info): + def policer_mirror_session(self, config_method, setup_info, erspan_ip_ver): """ Set up a mirror session with a policer for Everflow. @@ -559,7 +568,8 @@ def policer_mirror_session(self, config_method, setup_info): session_info = BaseEverflowTest.mirror_session_info("TEST_POLICER_SESSION", duthost.facts["asic_type"]) # Create a policer that allows 100 packets/sec through self.apply_policer_config(duthost, policer, config_method) - BaseEverflowTest.apply_mirror_config(duthost, session_info, config_method, policer=policer) + BaseEverflowTest.apply_mirror_config(duthost, session_info, config_method, policer=policer, + erspan_ip_ver=erspan_ip_ver) yield session_info @@ -569,18 +579,23 @@ def policer_mirror_session(self, config_method, setup_info): self.remove_policer_config(duthost, policer, config_method) @staticmethod - def apply_mirror_config(duthost, session_info, config_method=CONFIG_MODE_CLI, policer=None): + def apply_mirror_config(duthost, session_info, config_method=CONFIG_MODE_CLI, policer=None, erspan_ip_ver=4): if config_method == CONFIG_MODE_CLI: - command = "config mirror_session add {} {} {} {} {} {}" \ - .format(session_info["session_name"], - session_info["session_src_ip"], - session_info["session_dst_ip"], - session_info["session_dscp"], - session_info["session_ttl"], - session_info["session_gre"]) - - if policer: - command += " --policer {}".format(policer) + if erspan_ip_ver == 4: + command = f"config mirror_session add {session_info['session_name']} \ + {session_info['session_src_ip']} {session_info['session_dst_ip']} \ + {session_info['session_dscp']} {session_info['session_ttl']} \ + {session_info['session_gre']}" + if policer: + command += f" --policer {policer}" + else: + # Adding IPv6 ERSPAN sessions from the CLI is currently not supported. + command = f"sonic-db-cli CONFIG_DB HSET 'MIRROR_SESSION|{session_info['session_name']}' \ + 'dscp' '{session_info['session_dscp']}' 'dst_ip' '{session_info['session_dst_ipv6']}' \ + 'gre_type' '{session_info['session_gre']}' 'src_ip' '{session_info['session_src_ipv6']}' \ + 'ttl' '{session_info['session_ttl']}'" + if policer: + command += f" 'policer' {policer}" elif config_method == CONFIG_MODE_CONFIGLET: pass @@ -726,6 +741,7 @@ def remove_acl_rule_config(duthost, table_name, config_method=CONFIG_MODE_CLI): pass duthost.command(command) + time.sleep(2) @abstractmethod def mirror_type(self): @@ -755,7 +771,8 @@ def send_and_check_mirror_packets(self, src_port=None, dest_ports=None, expect_recv=True, - valid_across_namespace=True): + valid_across_namespace=True, + erspan_ip_ver=4): # In Below logic idea is to send traffic in such a way so that mirror traffic # will need to go across namespaces and within namespace. If source and mirror destination @@ -799,7 +816,8 @@ def send_and_check_mirror_packets(self, duthost, direction, mirror_packet, - src_port_metadata_map[src_port][1]) + src_port_metadata_map[src_port][1], + erspan_ip_ver) # Avoid changing the original packet mirror_packet_sent = mirror_packet.copy() if src_port_metadata_map[src_port][0]: @@ -820,7 +838,7 @@ def send_and_check_mirror_packets(self, _, received_packet = result logging.info("Received packet: %s", packet.Ether(received_packet).summary()) - inner_packet = self._extract_mirror_payload(received_packet, len(mirror_packet_sent)) + inner_packet = self._extract_mirror_payload(received_packet, len(mirror_packet_sent), erspan_ip_ver) logging.info("Received inner packet: %s", inner_packet.summary()) inner_packet = Mask(inner_packet) @@ -855,25 +873,30 @@ def send_and_check_mirror_packets(self, testutils.verify_no_packet_any(ptfadapter, expected_mirror_packet, dest_ports) @staticmethod - def get_expected_mirror_packet(mirror_session, setup, duthost, direction, mirror_packet, ttl_dec): - payload = mirror_packet.copy() + def copy_and_pad(pkt, asic_type, platform_asic, hwsku): + padded = pkt.copy() # Add vendor specific padding to the packet - if duthost.facts["asic_type"] in ["mellanox"]: + if asic_type == "mellanox": if six.PY2: - payload = binascii.unhexlify("0" * 44) + str(payload) + padded = binascii.unhexlify("0" * 44) + str(padded) else: - payload = binascii.unhexlify("0" * 44) + bytes(payload) - if ( - duthost.facts["asic_type"] in ["barefoot", "cisco-8000", "marvell-teralynx"] - or duthost.facts.get("platform_asic") in ["broadcom-dnx"] - or duthost.facts["hwsku"] - in ["rd98DX35xx", "rd98DX35xx_cn9131", "Nokia-7215-A1"] - ): + padded = binascii.unhexlify("0" * 44) + bytes(padded) + if asic_type in ["barefoot", "cisco-8000", "marvell-teralynx"] \ + or platform_asic == "broadcom-dnx" \ + or hwsku in ["rd98DX35xx", "rd98DX35xx_cn9131", "Nokia-7215-A1"]: if six.PY2: - payload = binascii.unhexlify("0" * 24) + str(payload) + padded = binascii.unhexlify("0" * 24) + str(padded) else: - payload = binascii.unhexlify("0" * 24) + bytes(payload) + padded = binascii.unhexlify("0" * 24) + bytes(padded) + return padded + + @staticmethod + def get_expected_mirror_packet_ipv4(mirror_session, setup, duthost, direction, mirror_packet, ttl_dec): + asic_type = duthost.facts["asic_type"] + platform_asic = duthost.facts.get("platform_asic") + hwsku = duthost.facts["hwsku"] + payload = BaseEverflowTest.copy_and_pad(mirror_packet, asic_type, platform_asic, hwsku) expected_packet = testutils.simple_gre_packet( eth_src=setup[direction]["egress_router_mac"], @@ -888,30 +911,72 @@ def get_expected_mirror_packet(mirror_session, setup, duthost, direction, mirror expected_packet["GRE"].proto = mirror_session["session_gre"] expected_packet = Mask(expected_packet) - expected_packet.set_do_not_care_scapy(packet.Ether, "dst") - expected_packet.set_do_not_care_scapy(packet.IP, "ihl") - expected_packet.set_do_not_care_scapy(packet.IP, "len") - expected_packet.set_do_not_care_scapy(packet.IP, "flags") - expected_packet.set_do_not_care_scapy(packet.IP, "chksum") - if duthost.facts["asic_type"] == 'marvell': - expected_packet.set_do_not_care_scapy(packet.IP, "id") - expected_packet.set_do_not_care_scapy(packet.GRE, "seqnum_present") - if duthost.facts["asic_type"] in ["cisco-8000", "marvell-teralynx"] or \ - duthost.facts.get("platform_asic") in ["broadcom-dnx"]: - expected_packet.set_do_not_care_scapy(packet.GRE, "seqnum_present") + expected_packet.set_do_not_care_packet(packet.Ether, "dst") + expected_packet.set_do_not_care_packet(packet.IP, "ihl") + expected_packet.set_do_not_care_packet(packet.IP, "len") + expected_packet.set_do_not_care_packet(packet.IP, "flags") + expected_packet.set_do_not_care_packet(packet.IP, "chksum") + if asic_type == "marvell": + expected_packet.set_do_not_care_packet(packet.IP, "id") + if asic_type in ["marvell", "cisco-8000", "marvell-teralynx"] or platform_asic == "broadcom-dnx": + expected_packet.set_do_not_care_packet(packet.GRE, "seqnum_present") # The fanout switch may modify this value en route to the PTF so we should ignore it, even # though the session does have a DSCP specified. - expected_packet.set_do_not_care_scapy(packet.IP, "tos") + expected_packet.set_do_not_care_packet(packet.IP, "tos") # Mask off the payload (we check it later) expected_packet.set_do_not_care(OUTER_HEADER_SIZE * 8, len(payload) * 8) return expected_packet - def _extract_mirror_payload(self, encapsulated_packet, payload_size): - pytest_assert(len(encapsulated_packet) >= OUTER_HEADER_SIZE, - "Incomplete packet, expected at least {} header bytes".format(OUTER_HEADER_SIZE)) + @staticmethod + def get_expected_mirror_packet_ipv6(mirror_session, setup, duthost, direction, mirror_packet, hlim_dec): + asic_type = duthost.facts["asic_type"] + platform_asic = duthost.facts.get("platform_asic") + hwsku = duthost.facts["hwsku"] + payload = BaseEverflowTest.copy_and_pad(mirror_packet, asic_type, platform_asic, hwsku) + + expected_packet = testutils.simple_grev6_packet( + eth_src=setup[direction]["egress_router_mac"], + ipv6_src=mirror_session["session_src_ipv6"], + ipv6_dst=mirror_session["session_dst_ipv6"], + ipv6_dscp=int(mirror_session["session_dscp"]), + ipv6_hlim=int(mirror_session["session_ttl"]) - hlim_dec, + inner_frame=payload + ) + + expected_packet["GRE"].proto = mirror_session["session_gre"] + + expected_packet = Mask(expected_packet) + expected_packet.set_do_not_care_packet(packet.Ether, "dst") + expected_packet.set_do_not_care_packet(packet.IPv6, "plen") + expected_packet.set_do_not_care_packet(packet.IPv6, "fl") + if asic_type in ["marvell", "cisco-8000", "marvell-teralynx"] or platform_asic == "broadcom-dnx": + expected_packet.set_do_not_care_packet(packet.GRE, "seqnum_present") + + # The fanout switch may modify this value en route to the PTF so we should ignore it, even + # though the session does have a DSCP specified. + expected_packet.set_do_not_care_packet(packet.IPv6, "tc") + + # Mask off the payload (we check it later) + expected_packet.set_do_not_care(OUTER_HEADER_SIZE_V6 * 8, len(payload) * 8) + + return expected_packet + + @staticmethod + def get_expected_mirror_packet(mirror_session, setup, duthost, direction, mirror_packet, ttl_dec, erspan_ip_ver=4): + if erspan_ip_ver == 4: + return BaseEverflowTest.get_expected_mirror_packet_ipv4(mirror_session, setup, duthost, + direction, mirror_packet, ttl_dec) + else: + return BaseEverflowTest.get_expected_mirror_packet_ipv6(mirror_session, setup, duthost, + direction, mirror_packet, ttl_dec) + + def _extract_mirror_payload(self, encapsulated_packet, payload_size, erspan_ip_ver=4): + outer_header_size = OUTER_HEADER_SIZE if erspan_ip_ver == 4 else OUTER_HEADER_SIZE_V6 + pytest_assert(len(encapsulated_packet) >= outer_header_size, + f"Incomplete packet, expected at least {outer_header_size} header bytes") inner_frame = encapsulated_packet[-payload_size:] return packet.Ether(inner_frame) @@ -919,7 +984,9 @@ def _extract_mirror_payload(self, encapsulated_packet, payload_size): @staticmethod def mirror_session_info(session_name, asic_type): session_src_ip = "1.1.1.1" + session_src_ipv6 = "1111::1:1:1:1" session_dst_ip = "2.2.2.2" + session_dst_ipv6 = "2222::2:2:2:2" session_dscp = "8" session_ttl = "4" @@ -935,14 +1002,23 @@ def mirror_session_info(session_name, asic_type): for prefix_len in session_prefix_lens: session_prefixes.append(str(ipaddr.IPNetwork(session_dst_ip + "/" + prefix_len).network) + "/" + prefix_len) + session_prefix_lens_ipv6 = ["64", "128"] + session_prefixes_ipv6 = [] + for prefix_len in session_prefix_lens_ipv6: + session_prefixes_ipv6.append(str(ipaddr.IPNetwork(session_dst_ipv6 + "/" + prefix_len).network) + + "/" + prefix_len) + return { "session_name": session_name, "session_src_ip": session_src_ip, + "session_src_ipv6": session_src_ipv6, "session_dst_ip": session_dst_ip, + "session_dst_ipv6": session_dst_ipv6, "session_dscp": session_dscp, "session_ttl": session_ttl, "session_gre": session_gre, - "session_prefixes": session_prefixes + "session_prefixes": session_prefixes, + "session_prefixes_ipv6": session_prefixes_ipv6 } @staticmethod diff --git a/tests/everflow/test_everflow_ipv6.py b/tests/everflow/test_everflow_ipv6.py index df3a4b0e3a3..6afff1480a1 100644 --- a/tests/everflow/test_everflow_ipv6.py +++ b/tests/everflow/test_everflow_ipv6.py @@ -8,7 +8,7 @@ from ptf.mask import Mask import ptf.packet as scapy from . import everflow_test_utilities as everflow_utils -from .everflow_test_utilities import BaseEverflowTest, DOWN_STREAM, UP_STREAM +from .everflow_test_utilities import BaseEverflowTest, DOWN_STREAM, UP_STREAM, erspan_ip_ver # noqa F401 import random # Module-level fixtures from .everflow_test_utilities import setup_info # noqa: F401 @@ -38,11 +38,12 @@ class EverflowIPv6Tests(BaseEverflowTest): tx_port_ids = [] @pytest.fixture(scope='class', autouse=True) - def setup_mirror_session_dest_ip_route(self, tbinfo, setup_info, setup_mirror_session): # noqa F811 + def setup_mirror_session_dest_ip_route(self, tbinfo, setup_info, setup_mirror_session, erspan_ip_ver): # noqa F811 """ Setup the route for mirror session destination ip and update monitor port list. Remove the route as part of cleanup. """ + ip = "ipv4" if erspan_ip_ver == 4 else "ipv6" if setup_info['topo'] in ['t0', 'm0_vlan']: # On T0 testbed, the collector IP is routed to T1 namespace = setup_info[UP_STREAM]['remote_namespace'] @@ -57,18 +58,20 @@ def setup_mirror_session_dest_ip_route(self, tbinfo, setup_info, setup_mirror_se remote_dut = setup_info[DOWN_STREAM]['remote_dut'] rx_port_id = setup_info[DOWN_STREAM]["src_port_ptf_id"] remote_dut.shell(remote_dut.get_vtysh_cmd_for_namespace( - "vtysh -c \"config\" -c \"router bgp\" -c \"address-family ipv4\" -c \"redistribute static\"", namespace)) - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip, namespace) + f"vtysh -c \"config\" -c \"router bgp\" -c \"address-family {ip}\" -c \"redistribute static\"", namespace)) + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + session_prefixes = setup_mirror_session["session_prefixes"] if erspan_ip_ver == 4 \ + else setup_mirror_session["session_prefixes_ipv6"] + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip, namespace) EverflowIPv6Tests.tx_port_ids = BaseEverflowTest._get_tx_port_id_list(dest_port_ptf_id_list) EverflowIPv6Tests.rx_port_ptf_id = rx_port_id time.sleep(5) yield - everflow_utils.remove_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip, namespace) + everflow_utils.remove_route(remote_dut, session_prefixes[0], peer_ip, namespace) remote_dut.shell(remote_dut.get_vtysh_cmd_for_namespace( - "vtysh -c \"config\" -c \"router bgp\" -c \"address-family ipv4\" -c \"no redistribute static\"", + f"vtysh -c \"config\" -c \"router bgp\" -c \"address-family {ip}\" -c \"no redistribute static\"", namespace)) @pytest.fixture(scope='class') @@ -154,7 +157,8 @@ def background_traffic(run_count=None): def test_src_ipv6_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match on Source IPv6 addresses.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -168,11 +172,13 @@ def test_src_ipv6_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_dst_ipv6_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match on Destination IPv6 addresses.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -186,11 +192,13 @@ def test_dst_ipv6_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_next_header_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match on the Next Header field.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, next_header=0x7E) @@ -199,11 +207,13 @@ def test_next_header_mirroring(self, setup_info, setup_mirror_session, ptfadapte ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_l4_src_port_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match on the L4 Source Port.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, sport=9000) @@ -212,11 +222,13 @@ def test_l4_src_port_mirroring(self, setup_info, setup_mirror_session, ptfadapte ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_l4_dst_port_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match on the L4 Destination Port.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, dport=9001) @@ -225,12 +237,14 @@ def test_l4_dst_port_mirroring(self, setup_info, setup_mirror_session, ptfadapte ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) - def test_l4_src_port_range_mirroring(self, setup_info, setup_mirror_session, # noqa F811 + def test_l4_src_port_range_mirroring(self, setup_info, setup_mirror_session, # noqa F811 ptfadapter, everflow_dut, everflow_direction, - setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match on a range of L4 Source Ports.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, sport=10200) @@ -239,12 +253,14 @@ def test_l4_src_port_range_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) - def test_l4_dst_port_range_mirroring(self, setup_info, setup_mirror_session, # noqa F811 + def test_l4_dst_port_range_mirroring(self, setup_info, setup_mirror_session, # noqa F811 ptfadapter, everflow_dut, everflow_direction, - setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match on a range of L4 Destination Ports.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, dport=10700) @@ -253,11 +269,13 @@ def test_l4_dst_port_range_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_tcp_flags_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match on TCP Flags.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, flags=0x1B) @@ -266,11 +284,13 @@ def test_tcp_flags_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_dscp_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match on DSCP.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, dscp=37) @@ -279,11 +299,13 @@ def test_dscp_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ever ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_l4_range_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match from a source port to a range of destination ports and vice-versa.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -300,7 +322,8 @@ def test_l4_range_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) test_packet = self._base_tcpv6_packet( everflow_direction, @@ -317,11 +340,13 @@ def test_l4_range_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_tcp_response_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match a SYN -> SYN-ACK pattern.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -337,7 +362,8 @@ def test_tcp_response_mirroring(self, setup_info, setup_mirror_session, ptfadapt ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) test_packet = self._base_tcpv6_packet( everflow_direction, @@ -353,12 +379,14 @@ def test_tcp_response_mirroring(self, setup_info, setup_mirror_session, ptfadapt ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) - def test_tcp_application_mirroring(self, setup_info, setup_mirror_session, # noqa F811 + def test_tcp_application_mirroring(self, setup_info, setup_mirror_session, # noqa F811 ptfadapter, everflow_dut, everflow_direction, - setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match a TCP handshake between a client and server.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -376,7 +404,8 @@ def test_tcp_application_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) test_packet = self._base_tcpv6_packet( everflow_direction, @@ -394,12 +423,14 @@ def test_tcp_application_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) - def test_udp_application_mirroring(self, setup_info, setup_mirror_session, # noqa F811 + def test_udp_application_mirroring(self, setup_info, setup_mirror_session, # noqa F811 ptfadapter, everflow_dut, everflow_direction, - setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match UDP traffic between a client and server application.""" test_packet = self._base_udpv6_packet( everflow_direction, @@ -417,7 +448,8 @@ def test_udp_application_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) test_packet = self._base_udpv6_packet( everflow_direction, ptfadapter, @@ -434,11 +466,13 @@ def test_udp_application_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_any_protocol(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that the protocol number is ignored if it is not specified in the ACL rule.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -453,7 +487,8 @@ def test_any_protocol(self, setup_info, setup_mirror_session, ptfadapter, everfl ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) test_packet = self._base_udpv6_packet( everflow_direction, @@ -468,7 +503,8 @@ def test_any_protocol(self, setup_info, setup_mirror_session, ptfadapter, everfl ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) test_packet = self._base_udpv6_packet( everflow_direction, @@ -484,12 +520,14 @@ def test_any_protocol(self, setup_info, setup_mirror_session, ptfadapter, everfl ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) - def test_any_transport_protocol(self, setup_info, setup_mirror_session, # noqa F811 + def test_any_transport_protocol(self, setup_info, setup_mirror_session, # noqa F811 ptfadapter, everflow_dut, everflow_direction, - setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that src port and dst port rules match regardless of whether TCP or UDP traffic is sent.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -506,7 +544,8 @@ def test_any_transport_protocol(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) test_packet = self._base_udpv6_packet( everflow_direction, @@ -523,7 +562,8 @@ def test_any_transport_protocol(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_invalid_tcp_rule(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 @@ -538,7 +578,8 @@ def test_invalid_tcp_rule(self, setup_info, setup_mirror_session, ptfadapter, ev def test_source_subnet(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match packets with a Source IPv6 Subnet.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -555,11 +596,13 @@ def test_source_subnet(self, setup_info, setup_mirror_session, ptfadapter, everf ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_dest_subnet(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match packets with a Destination IPv6 Subnet.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -576,11 +619,13 @@ def test_dest_subnet(self, setup_info, setup_mirror_session, ptfadapter, everflo ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_both_subnets(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match packets with both source and destination subnets.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -597,11 +642,13 @@ def test_both_subnets(self, setup_info, setup_mirror_session, ptfadapter, everfl ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def test_fuzzy_subnets(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that we can match packets with non-standard subnet sizes.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -618,7 +665,8 @@ def test_fuzzy_subnets(self, setup_info, setup_mirror_session, ptfadapter, everf ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids) + dest_ports=EverflowIPv6Tests.tx_port_ids, + erspan_ip_ver=erspan_ip_ver) def _base_tcpv6_packet(self, direction, diff --git a/tests/everflow/test_everflow_per_interface.py b/tests/everflow/test_everflow_per_interface.py index 8bef2b5ed78..f1a271ed58b 100644 --- a/tests/everflow/test_everflow_per_interface.py +++ b/tests/everflow/test_everflow_per_interface.py @@ -6,12 +6,12 @@ import ptf.testutils as testutils from . import everflow_test_utilities as everflow_utils -from .everflow_test_utilities import BaseEverflowTest +from .everflow_test_utilities import BaseEverflowTest, erspan_ip_ver # noqa: F401 from .everflow_test_utilities import TEMPLATE_DIR, EVERFLOW_RULE_CREATE_TEMPLATE, \ DUT_RUN_DIR, EVERFLOW_RULE_CREATE_FILE, UP_STREAM from tests.common.helpers.assertions import pytest_require -from .everflow_test_utilities import setup_info, EVERFLOW_DSCP_RULES # noqa: F401 +from .everflow_test_utilities import setup_info, EVERFLOW_DSCP_RULES, STABILITY_BUFFER # noqa: F401 from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor # noqa: F401 pytestmark = [ @@ -67,16 +67,24 @@ def build_acl_rule_vars(candidate_ports, ip_ver): """ config_vars = {} config_vars['acl_table_name'] = EVERFLOW_TABLE_NAME[ip_ver] - config_vars['rules'] = [{'qualifiers': {'input_interface': ','.join(list(candidate_ports.keys()))}}] + qualifiers = {"input_interface": ','.join(list(candidate_ports.keys()))} + # During our tests, we observed a lot of ICMPv6 neighbor solicitation packets that were sent to the DUT + # trying to resolve link-local IPv6 addresses. All of these packets were mirrored by the DUT. This overwhelmed + # the PTF container, causing the kernel to drop some packets. As a result, the IPv6 tests sometimes failed. + # To prevent this issue from happening, we restrict Everflow IPv6 mirroring to TCP packets. + if ip_ver == "ipv6": + qualifiers["ip"] = {"protocol": 6} # Only mirror TCP packets + config_vars['rules'] = [{'qualifiers': qualifiers}] return config_vars @pytest.fixture(scope='module') -def apply_mirror_session(setup_info): # noqa F811 +def apply_mirror_session(setup_info, erspan_ip_ver): # noqa F811 mirror_session_info = BaseEverflowTest.mirror_session_info( EVERFLOW_SESSION_NAME, setup_info[UP_STREAM]['everflow_dut'].facts["asic_type"]) logger.info("Applying mirror session to DUT") - BaseEverflowTest.apply_mirror_config(setup_info[UP_STREAM]['everflow_dut'], mirror_session_info) + BaseEverflowTest.apply_mirror_config(setup_info[UP_STREAM]['everflow_dut'], + mirror_session_info, erspan_ip_ver=erspan_ip_ver) time.sleep(10) yield mirror_session_info @@ -85,26 +93,29 @@ def apply_mirror_session(setup_info): # noqa F811 @pytest.fixture(scope='module') -def setup_mirror_session_dest_ip_route(tbinfo, setup_info, apply_mirror_session): # noqa F811 +def setup_mirror_session_dest_ip_route(tbinfo, setup_info, apply_mirror_session, erspan_ip_ver): # noqa F811 """ Setup the route for mirror session destination ip and update monitor port list. Remove the route as part of cleanup. """ + ip = "ipv4" if erspan_ip_ver == 4 else "ipv6" namespace = setup_info[UP_STREAM]['remote_namespace'] tx_port = setup_info[UP_STREAM]["dest_port"][0] dest_port_ptf_id_list = [setup_info[UP_STREAM]["dest_port_ptf_id"][0]] remote_dut = setup_info[UP_STREAM]['remote_dut'] remote_dut.shell(remote_dut.get_vtysh_cmd_for_namespace( - "vtysh -c \"config\" -c \"router bgp\" -c \"address-family ipv4\" -c \"redistribute static\"", namespace)) - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, apply_mirror_session["session_prefixes"][0], peer_ip, namespace) + f"vtysh -c \"config\" -c \"router bgp\" -c \"address-family {ip}\" -c \"redistribute static\"", namespace)) + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + session_prefixes = apply_mirror_session["session_prefixes"] if erspan_ip_ver == 4 \ + else apply_mirror_session["session_prefixes_ipv6"] + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip, namespace) time.sleep(5) yield (apply_mirror_session, BaseEverflowTest._get_tx_port_id_list(dest_port_ptf_id_list)) - everflow_utils.remove_route(remote_dut, apply_mirror_session["session_prefixes"][0], peer_ip, namespace) + everflow_utils.remove_route(remote_dut, session_prefixes[0], peer_ip, namespace) remote_dut.shell(remote_dut.get_vtysh_cmd_for_namespace( - "vtysh -c \"config\" -c \"router bgp\" -c \"address-family ipv4\" -c \"no redistribute static\"", namespace)) + f"vtysh -c \"config\" -c \"router bgp\" -c \"address-family {ip}\" -c \"no redistribute static\"", namespace)) @pytest.fixture(scope='module', params=['ipv4', 'ipv6']) @@ -145,6 +156,7 @@ def apply_acl_rule(setup_info, tbinfo, setup_mirror_session_dest_ip_route, ip_ve "mirror_session_info": mirror_session_info, "monitor_port_ptf_ids": monitor_port_ptf_ids } + time.sleep(2) yield ret @@ -152,8 +164,9 @@ def apply_acl_rule(setup_info, tbinfo, setup_mirror_session_dest_ip_route, ip_ve BaseEverflowTest.remove_acl_rule_config(setup_info[UP_STREAM]['everflow_dut'], table_name) -def generate_testing_packet(ptfadapter, duthost, mirror_session_info, router_mac, setup, ip_ver): - if ip_ver == 'ipv4': +def generate_testing_packet(ptfadapter, duthost, mirror_session_info, router_mac, setup, pkt_ip_ver, + erspan_ip_ver=4): # noqa F811 + if pkt_ip_ver == 'ipv4': packet = testutils.simple_tcp_packet(eth_src=ptfadapter.dataplane.get_mac(0, 0), eth_dst=router_mac) else: packet = testutils.simple_tcpv6_packet(eth_src=ptfadapter.dataplane.get_mac(0, 0), eth_dst=router_mac) @@ -166,7 +179,7 @@ def generate_testing_packet(ptfadapter, duthost, mirror_session_info, router_mac dec_ttl = 2 exp_packet = BaseEverflowTest.get_expected_mirror_packet(mirror_session_info, setup, - duthost, UP_STREAM, packet, dec_ttl) + duthost, UP_STREAM, packet, dec_ttl, erspan_ip_ver) return packet, exp_packet @@ -179,15 +192,16 @@ def send_and_verify_packet(ptfadapter, packet, expected_packet, tx_port, rx_port testutils.verify_no_packet_any(ptfadapter, pkt=expected_packet, ports=rx_ports) -def test_everflow_per_interface(ptfadapter, setup_info, apply_acl_rule, tbinfo, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor, ip_ver): # noqa F811 +def test_everflow_per_interface(ptfadapter, setup_info, apply_acl_rule, tbinfo, # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor, ip_ver, erspan_ip_ver): # noqa F811 """Verify packet ingress from candidate ports are captured by EVERFLOW, while packets ingress from unselected ports are not captured """ everflow_config = apply_acl_rule packet, exp_packet = generate_testing_packet(ptfadapter, setup_info[UP_STREAM]['everflow_dut'], everflow_config['mirror_session_info'], - setup_info[UP_STREAM]['ingress_router_mac'], setup_info, ip_ver) + setup_info[UP_STREAM]['ingress_router_mac'], setup_info, ip_ver, + erspan_ip_ver) uplink_ports = everflow_config["monitor_port_ptf_ids"] # Verify that packet ingressed from INPUT_PORTS (candidate ports) are mirrored diff --git a/tests/everflow/test_everflow_testbed.py b/tests/everflow/test_everflow_testbed.py index 114f7549e91..200a67d6412 100644 --- a/tests/everflow/test_everflow_testbed.py +++ b/tests/everflow/test_everflow_testbed.py @@ -13,11 +13,11 @@ from tests.ptf_runner import ptf_runner from .everflow_test_utilities import TARGET_SERVER_IP, BaseEverflowTest, DOWN_STREAM, UP_STREAM, DEFAULT_SERVER_IP # Module-level fixtures -from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa: F401 -from tests.common.fixtures.ptfhost_utils import copy_acstests_directory # noqa: F401 -from .everflow_test_utilities import setup_info, setup_arp_responder, EVERFLOW_DSCP_RULES # noqa: F401 -from tests.common.fixtures.ptfhost_utils import copy_arp_responder_py # noqa: F401 -from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor # noqa: F401 +from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa: F401 +from tests.common.fixtures.ptfhost_utils import copy_acstests_directory # noqa: F401 +from .everflow_test_utilities import setup_info, setup_arp_responder, erspan_ip_ver, EVERFLOW_DSCP_RULES # noqa: F401 +from tests.common.fixtures.ptfhost_utils import copy_arp_responder_py # noqa: F401 +from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor # noqa: F401 pytestmark = [ pytest.mark.topology("t0", "t1", "t2", "m0") @@ -31,7 +31,7 @@ @pytest.fixture -def partial_ptf_runner(request, ptfhost): +def partial_ptf_runner(request, ptfhost, erspan_ip_ver): # noqa F811 """ Fixture to run each Everflow PTF test case via ptf_runner. @@ -43,12 +43,14 @@ def _partial_ptf_runner(setup_info, direction, session_info, acl_stage, mirror_t # Some of the arguments are fixed for each Everflow test case and defined here. # Arguments specific to each Everflow test case are passed in by each test via _partial_ptf_runner. # Arguments are passed in dictionary format via kwargs within each test case. + src_ip = session_info["session_src_ip"] if erspan_ip_ver == 4 else session_info["session_src_ipv6"] + dst_ip = session_info["session_dst_ip"] if erspan_ip_ver == 4 else session_info["session_dst_ipv6"] params = { 'hwsku': setup_info[direction]['everflow_dut'].facts['hwsku'], 'asic_type': setup_info[direction]['everflow_dut'].facts['asic_type'], 'router_mac': setup_info[direction]['ingress_router_mac'], - 'session_src_ip': session_info['session_src_ip'], - 'session_dst_ip': session_info['session_dst_ip'], + 'session_src_ip': src_ip, + 'session_dst_ip': dst_ip, 'session_ttl': session_info['session_ttl'], 'session_dscp': session_info['session_dscp'], 'acl_stage': acl_stage, @@ -85,28 +87,32 @@ class EverflowIPv4Tests(BaseEverflowTest): MIRROR_POLICER_UNSUPPORTED_ASIC_LIST = ["th3", "j2c+", "jr2"] @pytest.fixture(params=[DOWN_STREAM, UP_STREAM]) - def dest_port_type(self, setup_info, setup_mirror_session, tbinfo, request): # noqa F811 + def dest_port_type(self, setup_info, setup_mirror_session, tbinfo, request, erspan_ip_ver): # noqa F811 """ This fixture parametrize dest_port_type and can perform action based on that. As of now cleanup is being done here. """ remote_dut = setup_info[request.param]['remote_dut'] + ip = "ipv4" if erspan_ip_ver == 4 else "ipv6" remote_dut.shell(remote_dut.get_vtysh_cmd_for_namespace( - "vtysh -c \"config\" -c \"router bgp\" -c \"address-family ipv4\" -c \"redistribute static\"", + f"vtysh -c \"config\" -c \"router bgp\" -c \"address-family {ip}\" -c \"redistribute static\"", setup_info[request.param]["remote_namespace"])) yield request.param + session_prefixes = setup_mirror_session["session_prefixes"] if erspan_ip_ver == 4 \ + else setup_mirror_session["session_prefixes_ipv6"] + for index in range(0, min(3, len(setup_info[request.param]["dest_port"]))): tx_port = setup_info[request.param]["dest_port"][index] - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.remove_route(remote_dut, setup_mirror_session["session_prefixes"][0], + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + everflow_utils.remove_route(remote_dut, session_prefixes[0], peer_ip, setup_info[request.param]["remote_namespace"]) - everflow_utils.remove_route(remote_dut, setup_mirror_session["session_prefixes"][1], + everflow_utils.remove_route(remote_dut, session_prefixes[1], peer_ip, setup_info[request.param]["remote_namespace"]) remote_dut.shell(remote_dut.get_vtysh_cmd_for_namespace( - "vtysh -c \"config\" -c \"router bgp\" -c \"address-family ipv4\" -c \"no redistribute static\"", + f"vtysh -c \"config\" -c \"router bgp\" -c \"address-family {ip}\" -c \"no redistribute static\"", setup_info[request.param]["remote_namespace"])) time.sleep(15) @@ -134,7 +140,8 @@ def add_dest_routes(self, setup_info, tbinfo, dest_port_type): # noqa F811 def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, # noqa F811 dest_port_type, ptfadapter, tbinfo, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor_unconditionally): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 + erspan_ip_ver): # noqa F811 """ Verify basic forwarding scenarios for the Everflow feature. @@ -152,8 +159,10 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, # Add a route to the mirror session destination IP tx_port = setup_info[dest_port_type]["dest_port"][0] - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip, + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + session_prefixes = setup_mirror_session["session_prefixes"] if erspan_ip_ver == 4 \ + else setup_mirror_session["session_prefixes_ipv6"] + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -168,12 +177,14 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) # Add a (better) unresolved route to the mirror session destination IP - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, resolved=False) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][1], peer_ip, + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, resolved=False, + ip_version=erspan_ip_ver) + everflow_utils.add_route(remote_dut, session_prefixes[1], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -185,17 +196,18 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) # Remove the unresolved route - everflow_utils.remove_route(remote_dut, setup_mirror_session["session_prefixes"][1], + everflow_utils.remove_route(remote_dut, session_prefixes[1], peer_ip, setup_info[dest_port_type]["remote_namespace"]) # Add a better route to the mirror session destination IP tx_port = setup_info[dest_port_type]["dest_port"][1] - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session['session_prefixes'][1], peer_ip, + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + everflow_utils.add_route(remote_dut, session_prefixes[1], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -208,11 +220,12 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) # Remove the better route. - everflow_utils.remove_route(remote_dut, setup_mirror_session["session_prefixes"][1], peer_ip, + everflow_utils.remove_route(remote_dut, session_prefixes[1], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -225,7 +238,8 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) remote_dut.shell(remote_dut.get_vtysh_cmd_for_namespace( @@ -235,7 +249,8 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, def test_everflow_neighbor_mac_change(self, setup_info, setup_mirror_session, # noqa F811 dest_port_type, ptfadapter, tbinfo, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor_unconditionally): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that session destination MAC address is changed after neighbor MAC address update.""" everflow_dut = setup_info[dest_port_type]['everflow_dut'] @@ -243,8 +258,10 @@ def test_everflow_neighbor_mac_change(self, setup_info, setup_mirror_session, # Add a route to the mirror session destination IP tx_port = setup_info[dest_port_type]["dest_port"][0] - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip, + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + session_prefixes = setup_mirror_session["session_prefixes"] if erspan_ip_ver == 4 \ + else setup_mirror_session["session_prefixes_ipv6"] + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -258,7 +275,8 @@ def test_everflow_neighbor_mac_change(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) # Update the MAC on the neighbor interface for the route we installed @@ -278,7 +296,8 @@ def test_everflow_neighbor_mac_change(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) finally: @@ -299,13 +318,15 @@ def test_everflow_neighbor_mac_change(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_session, # noqa F811 dest_port_type, ptfadapter, tbinfo, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor_unconditionally): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that session is still active after removal of next hop from ECMP route that was not in use.""" everflow_dut = setup_info[dest_port_type]['everflow_dut'] @@ -313,14 +334,16 @@ def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_ses # Create two ECMP next hops tx_port = setup_info[dest_port_type]["dest_port"][0] - peer_ip_0 = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip_0, + peer_ip_0 = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + session_prefixes = setup_mirror_session["session_prefixes"] if erspan_ip_ver == 4 \ + else setup_mirror_session["session_prefixes_ipv6"] + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip_0, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) tx_port = setup_info[dest_port_type]["dest_port"][1] - peer_ip_1 = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip_1, + peer_ip_1 = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip_1, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -337,7 +360,8 @@ def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_ses everflow_dut, rx_port_ptf_id, tx_port_ptf_ids, - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) # Remaining Scenario not applicable for this topology @@ -346,8 +370,8 @@ def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_ses # Add another ECMP next hop tx_port = setup_info[dest_port_type]["dest_port"][2] - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip, + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -362,11 +386,12 @@ def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_ses [tx_port_ptf_id], dest_port_type, expect_recv=False, - valid_across_namespace=False + valid_across_namespace=False, + erspan_ip_ver=erspan_ip_ver ) # Remove the extra hop - everflow_utils.remove_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip, + everflow_utils.remove_route(remote_dut, session_prefixes[0], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -380,7 +405,8 @@ def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_ses [tx_port_ptf_id], dest_port_type, expect_recv=False, - valid_across_namespace=False + valid_across_namespace=False, + erspan_ip_ver=erspan_ip_ver ) # Verify that mirrored traffic is still sent to one of the original next hops @@ -391,13 +417,15 @@ def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_ses everflow_dut, rx_port_ptf_id, tx_port_ptf_ids, - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_session, # noqa F811 dest_port_type, ptfadapter, tbinfo, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor_unconditionally): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 + erspan_ip_ver): # noqa F811 """Verify that session is still active after removal of next hop from ECMP route that was in use.""" everflow_dut = setup_info[dest_port_type]['everflow_dut'] @@ -413,8 +441,10 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi # Add a route to the mirror session destination IP tx_port = setup_info[dest_port_type]["dest_port"][0] - peer_ip_0 = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip_0, + peer_ip_0 = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + session_prefixes = setup_mirror_session["session_prefixes"] if erspan_ip_ver == 4 \ + else setup_mirror_session["session_prefixes_ipv6"] + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip_0, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -428,18 +458,19 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) # Add two new ECMP next hops tx_port = setup_info[dest_port_type]["dest_port"][1] - peer_ip_1 = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip_1, + peer_ip_1 = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip_1, setup_info[dest_port_type]["remote_namespace"]) tx_port = setup_info[dest_port_type]["dest_port"][2] - peer_ip_2 = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip_2, + peer_ip_2 = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip_2, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -452,7 +483,8 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi rx_port_ptf_id, [tx_port_ptf_id], dest_port_type, - valid_across_namespace=False + valid_across_namespace=False, + erspan_ip_ver=erspan_ip_ver ) # Verify that traffic is not sent along either of the new next hops @@ -469,11 +501,12 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi tx_port_ptf_ids, dest_port_type, expect_recv=False, - valid_across_namespace=False + valid_across_namespace=False, + erspan_ip_ver=erspan_ip_ver ) # Remove the original next hop - everflow_utils.remove_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip_0, + everflow_utils.remove_route(remote_dut, session_prefixes[0], peer_ip_0, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -486,7 +519,8 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi rx_port_ptf_id, [tx_port_ptf_id], dest_port_type, - expect_recv=False + expect_recv=False, + erspan_ip_ver=erspan_ip_ver ) # Verify that mirrored traffis is now sent along either of the new next hops @@ -497,7 +531,8 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi everflow_dut, rx_port_ptf_id, tx_port_ptf_ids, - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) def test_everflow_dscp_with_policer( @@ -509,7 +544,8 @@ def test_everflow_dscp_with_policer( config_method, tbinfo, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor_unconditionally # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 + erspan_ip_ver # noqa F811 ): """Verify that we can rate-limit mirrored traffic from the MIRROR_DSCP table. This tests single rate three color policer mode and specifically checks CIR value @@ -517,6 +553,9 @@ def test_everflow_dscp_with_policer( sending traffic over a period of time. Received packets are accumulated and actual receive rate is calculated and compared with CIR value with tollerance range 10%. """ + if erspan_ip_ver == 6: + pytest.skip("EverflowPolicerTest does not support IPv6.") + # Add explicit for regular packet so that it's dest port is different then mirror port # NOTE: This is important to add since for the Policer test case regular packets # and mirror packets can go to same interface, which causes tail drop of @@ -561,7 +600,8 @@ def test_everflow_dscp_with_policer( # Add explicit route for the mirror session peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, policer_mirror_session["session_prefixes"][0], peer_ip, + session_prefixes = policer_mirror_session["session_prefixes"] + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -617,7 +657,7 @@ def test_everflow_dscp_with_policer( self.remove_acl_table_config(everflow_dut, table_name, config_method) if bind_interface_namespace: self.remove_acl_table_config(everflow_dut, table_name, config_method, bind_interface_namespace) - everflow_utils.remove_route(remote_dut, policer_mirror_session["session_prefixes"][0], peer_ip, + everflow_utils.remove_route(remote_dut, session_prefixes[0], peer_ip, setup_info[dest_port_type]["remote_namespace"]) everflow_utils.remove_route(everflow_dut, self.DEFAULT_DST_IP + "/32", default_traffic_peer_ip, setup_info[default_tarffic_port_type]["remote_namespace"]) @@ -625,8 +665,8 @@ def test_everflow_dscp_with_policer( def test_everflow_frwd_with_bkg_trf(self, setup_info, # noqa F811 setup_mirror_session, - dest_port_type, ptfadapter, tbinfo - ): + dest_port_type, ptfadapter, tbinfo, + erspan_ip_ver): # noqa F811 """ Verify basic forwarding scenarios for the Everflow feature with background traffic. Background Traffic PKT1 IP in IP with same ports & macs but with dummy ips @@ -640,8 +680,10 @@ def test_everflow_frwd_with_bkg_trf(self, # Add a route to the mirror session destination IP tx_port = setup_info[dest_port_type]["dest_port"][0] - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][0], peer_ip, + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + session_prefixes = setup_mirror_session["session_prefixes"] if erspan_ip_ver == 4 \ + else setup_mirror_session["session_prefixes_ipv6"] + everflow_utils.add_route(remote_dut, session_prefixes[0], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) @@ -716,12 +758,14 @@ def background_traffic(run_count=None): everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) # Add a (better) unresolved route to the mirror session destination IP - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, resolved=False) - everflow_utils.add_route(remote_dut, setup_mirror_session["session_prefixes"][1], peer_ip, + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, resolved=False, + ip_version=erspan_ip_ver) + everflow_utils.add_route(remote_dut, session_prefixes[1], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) background_traffic(run_count=1) @@ -734,17 +778,18 @@ def background_traffic(run_count=None): everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) # Remove the unresolved route - everflow_utils.remove_route(remote_dut, setup_mirror_session["session_prefixes"][1], + everflow_utils.remove_route(remote_dut, session_prefixes[1], peer_ip, setup_info[dest_port_type]["remote_namespace"]) # Add a better route to the mirror session destination IP tx_port = setup_info[dest_port_type]["dest_port"][1] - peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo) - everflow_utils.add_route(remote_dut, setup_mirror_session['session_prefixes'][1], peer_ip, + peer_ip = everflow_utils.get_neighbor_info(remote_dut, tx_port, tbinfo, ip_version=erspan_ip_ver) + everflow_utils.add_route(remote_dut, session_prefixes[1], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) background_traffic(run_count=1) @@ -757,11 +802,12 @@ def background_traffic(run_count=None): everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) # Remove the better route. - everflow_utils.remove_route(remote_dut, setup_mirror_session["session_prefixes"][1], peer_ip, + everflow_utils.remove_route(remote_dut, session_prefixes[1], peer_ip, setup_info[dest_port_type]["remote_namespace"]) time.sleep(15) background_traffic(run_count=1) @@ -774,7 +820,8 @@ def background_traffic(run_count=None): everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type + dest_port_type, + erspan_ip_ver=erspan_ip_ver ) remote_dut.shell(remote_dut.get_vtysh_cmd_for_namespace( @@ -789,7 +836,8 @@ def background_traffic(run_count=None): background_traffic(run_count=1) def _run_everflow_test_scenarios(self, ptfadapter, setup, mirror_session, duthost, rx_port, - tx_ports, direction, expect_recv=True, valid_across_namespace=True): + tx_ports, direction, expect_recv=True, valid_across_namespace=True, + erspan_ip_ver=4): # noqa F811 # FIXME: In the ptf_runner version of these tests, LAGs were passed down to the tests # as comma-separated strings of LAG member port IDs (e.g. portchannel0001 -> "2,3"). # Because the DSCP test is still using ptf_runner we will preserve this for now, @@ -827,7 +875,8 @@ def _run_everflow_test_scenarios(self, ptfadapter, setup, mirror_session, duthos src_port=rx_port, dest_ports=tx_port_ids, expect_recv=expect_recv, - valid_across_namespace=valid_across_namespace + valid_across_namespace=valid_across_namespace, + erspan_ip_ver=erspan_ip_ver ) def _base_tcp_packet(