diff --git a/tests/srv6/srv6_utils.py b/tests/srv6/srv6_utils.py index a9c1c31917..bd5c0f5498 100755 --- a/tests/srv6/srv6_utils.py +++ b/tests/srv6/srv6_utils.py @@ -3,7 +3,7 @@ import requests import ptf.packet as scapy import ptf.testutils as testutils - +from ptf.mask import Mask from tests.common.helpers.assertions import pytest_assert logger = logging.getLogger(__name__) @@ -13,6 +13,60 @@ # test_log_dir = "/home/admin/testlogs/" +class MaskException(Exception): + """Generic Mask Exception""" + + pass + +class MyMask(Mask): + def __init__(self, exp_pkt, ignore_extra_bytes=False, dont_care_all=False): + Mask.__init__(self, exp_pkt, ignore_extra_bytes) + if dont_care_all: + self.mask = [0] * self.size + def set_care_all(self): + self.mask = [0xFF] * self.size + def set_care(self, offset, bitwidth): + #logger.info("zzz set_care offset:{} bitwidth:{}".format(offset, bitwidth)) + for idx in range(offset, offset + bitwidth): + offsetB = idx // 8 + offsetb = idx % 8 + self.mask[offsetB] = self.mask[offsetB] | (1 << (7 - offsetb)) + def set_care_packet(self, hdr_type, field_name): + if hdr_type not in self.exp_pkt: + self.valid = False + raise MaskException("Unknown header type") + + try: + fields_desc = [ + field + for field in hdr_type.fields_desc + if field.name + in self.exp_pkt[hdr_type] + .__class__(bytes(self.exp_pkt[hdr_type])) + .fields.keys() + ] # build & parse packet to be sure all fields are correctly filled + except Exception: # noqa + self.valid = False + raise MaskException("Can not build or decode Packet") + + if field_name not in [x.name for x in fields_desc]: + self.valid = False + raise MaskException("Field %s does not exist in frame" % field_name) + + hdr_offset = self.size - len(self.exp_pkt[hdr_type]) + offset = 0 + bitwidth = 0 + for f in fields_desc: + try: + bits = f.size + except Exception: # noqa + bits = 8 * f.sz + if f.name == field_name: + bitwidth = bits + break + else: + offset += bits + self.set_care(hdr_offset * 8 + offset, bitwidth) # # Helper func for print a set of lines @@ -285,3 +339,333 @@ def collect_frr_debugfile(duthosts, rand_one_dut_hostname, nbrhosts, filename, v nbrhost.shell(cmd, module_ignore_errors=True) cmd = "docker cp bgp:{} {}".format(filename, test_log_dir) nbrhost.shell(cmd, module_ignore_errors=True) +def reset_topo_pkt_counter(ptfadapter): + ptfadapter.dataplane.flush() + +def check_topo_recv_pkt_raw(ptfadapter, port=0, dst_ip="", dscp = 0, no_packet = False, no_vlan=True, validateDSCP = True): + #port info is fixed and also define and used in trex_agent.py + if no_vlan == False: + if "." in dst_ip: + pkt_base = Ether()/Dot1Q()/IP(dst = dst_ip, tos=(dscp<<2))/UDP(dport=5000, sport=5001)/"data" + else: + pkt_base = Ether()/Dot1Q()/IPv6(dst = dst_ip, tc=(dscp<<2))/UDP(dport=5000,sport=5001)/"data" + else: + if "." in dst_ip: + pkt_base = Ether()/IP(dst = dst_ip, tos=(dscp<<2))/UDP(dport=5000, sport=5001)/"data" + else: + pkt_base = Ether()/IPv6(dst = dst_ip, tc=(dscp<<2))/UDP(dport=5000,sport=5001)/"data" + + mask = MyMask(pkt_base, ignore_extra_bytes=True, dont_care_all=True) + # mask.set_do_not_care_scapy(scapy.Ether, 'dst') + # mask.set_do_not_care_scapy(scapy.Ether, 'src') + # mask.set_do_not_care_scapy(scapy.Dot1Q, 'vlan') + # mask.set_do_not_care_scapy(scapy.IP, "ihl") + # mask.set_do_not_care_scapy(scapy.IP, "tos") + # mask.set_do_not_care_scapy(scapy.IP, "len") + # mask.set_do_not_care_scapy(scapy.IP, "id") + # mask.set_do_not_care_scapy(scapy.IP, "flags") + # mask.set_do_not_care_scapy(scapy.IP, "frag") + + # mask.set_do_not_care_scapy(scapy.IP, "ttl") + # mask.set_do_not_care_scapy(scapy.IP, "src") + # mask.set_do_not_care_scapy(scapy.IP, "chksum") + # mask.set_do_not_care_scapy(scapy.UDP, "chksum") + # mask.set_do_not_care_scapy(scapy.UDP, "len") + ## mask.set_do_not_care_scapy(scapy.IP, "dst") + if "." in dst_ip: + if validateDSCP: + mask.set_care_packet(scapy.IP, "tos") + mask.set_care_packet(scapy.IP, "dst") + mask.set_care_packet(scapy.UDP, "dport") + mask.set_care_packet(scapy.UDP, "sport") + else: + if validateDSCP: + mask.set_care_packet(scapy.IPv6, "tc") + mask.set_care_packet(scapy.IPv6, "dst") + mask.set_care_packet(scapy.UDP, "dport") + mask.set_care_packet(scapy.UDP, "sport") + + logger.debug("check_topo_recv_pkt_raw pkt_base: " + pkt_base.summary()) + + if no_packet: + #verify no packet is received on the exact port! + testutils.verify_no_packet(ptfadapter, mask, port_id=port, timeout=2) + else: + #verify packet is received on the exact port! + testutils.verify_packet(ptfadapter, mask, port_id=port, timeout=30) + + # (index, rcv_pkt) = testutils.verify_packet_any_port(ptfadapter, mask, ports=ptf_ports, timeout=1) + # received = False + # if rcv_pkt: + # received = True + # #poll more time to see + # cnt = testutils.count_matched_packets_all_ports(ptfadapter, mask, ports = ptf_ports, timeout=2) + + # logger.debug(("index:{} tot_cnt_in_2s:{} rcv_pkt: {}").format(index, cnt + 1, scapy.Ether(rcv_pkt).summary())) + + # return received +def check_topo_recv_pkt_vpn(ptfadapter, port=0, dst_ip="", dscp = 0, vpnsid = "", no_packet = False, no_vlan=True, outer_sip=""): + #udp port info is fixed and also define and used in trex_agent.py + outer_src_ip6 = outer_sip if outer_sip != "" else "0::0" + if no_vlan == False: + if "." in dst_ip: + pkt_base = Ether()/Dot1Q()/IPv6(src=outer_src_ip6, dst=vpnsid, nh=4)/IP(dst = dst_ip, tos=(dscp<<2))/UDP(dport=5000, sport=5001)/"data" + else: + pkt_base = Ether()/Dot1Q()/IPv6(src=outer_src_ip6, dst=vpnsid, nh=41)/IPv6(dst = dst_ip, tc=(dscp<<2))/UDP(dport=5000,sport=5001)/"data" + else: + if "." in dst_ip: + pkt_base = Ether()/IPv6(src=outer_src_ip6, dst=vpnsid, nh=4)/IP(dst = dst_ip, tos=(dscp<<2))/UDP(dport=5000, sport=5001)/"data" + else: + pkt_base = Ether()/IPv6(src=outer_src_ip6, dst=vpnsid, nh=41)/IPv6(dst = dst_ip, tc=(dscp<<2))/UDP(dport=5000,sport=5001)/"data" + + mask = MyMask(pkt_base, ignore_extra_bytes=True, dont_care_all=True) + ETH_H_LEN = 14 + VLAN_H_LEN = 4 + IP4_H_LEN = 20 + IP6_H_LEN = 40 + IP4_DST_OFFSET = 16 + IP6_SRC_OFFSET = 8 + IP6_DST_OFFSET = 24 + UDP_SPORT_OFFSET = 0 + UDP_DPORT_OFFSET = 2 + + vlan_h_len = VLAN_H_LEN + if no_vlan == True: + vlan_h_len = 0 + + if "." in dst_ip: + #mask outer sip + if outer_sip != "": + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_SRC_OFFSET)*8, 128) + #mask outer dip + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_DST_OFFSET)*8, 128) + #mask inner dip + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP4_DST_OFFSET)*8, 32) + #mask inner udp + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP4_H_LEN + UDP_SPORT_OFFSET)*8, 16) + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP4_H_LEN + UDP_DPORT_OFFSET)*8, 16) + else: + #mask outer sip + if outer_sip != "": + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_SRC_OFFSET)*8, 128) + #mask outer dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_DST_OFFSET)*8, 128) + #mask inner dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_DST_OFFSET)*8, 128) + #mask inner udp + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_H_LEN + UDP_SPORT_OFFSET)*8, 16) + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_H_LEN + UDP_DPORT_OFFSET)*8, 16) + + logger.debug("check_topo_recv_pkt_vpn pkt_base: " + pkt_base.summary()) + + if no_packet: + #verify no packet is received on the exact port! + testutils.verify_no_packet(ptfadapter, mask, port_id=port, timeout=2) + else: + #verify packet is received on the exact port! + testutils.verify_packet(ptfadapter, mask, port_id=port, timeout=30) + +#check that packet is recved on only one of the port +def check_topo_recv_pkt_vpn_one_port_only(ptfadapter, ports=[], dst_ip="", dscp = 0, vpnsid = "", no_vlan=True, outer_sip=""): + #udp port info is fixed and also define and used in trex_agent.py + outer_src_ip6 = outer_sip if outer_sip != "" else "0::0" + if no_vlan == False: + if "." in dst_ip: + pkt_base = Ether()/Dot1Q()/IPv6(src=outer_src_ip6, dst=vpnsid, nh=4)/IP(dst = dst_ip, tos=(dscp<<2))/UDP(dport=5000, sport=5001)/"data" + else: + pkt_base = Ether()/Dot1Q()/IPv6(src=outer_src_ip6, dst=vpnsid, nh=41)/IPv6(dst = dst_ip, tc=(dscp<<2))/UDP(dport=5000,sport=5001)/"data" + else: + if "." in dst_ip: + pkt_base = Ether()/IPv6(src=outer_src_ip6, dst=vpnsid, nh=4)/IP(dst = dst_ip, tos=(dscp<<2))/UDP(dport=5000, sport=5001)/"data" + else: + pkt_base = Ether()/IPv6(src=outer_src_ip6, dst=vpnsid, nh=41)/IPv6(dst = dst_ip, tc=(dscp<<2))/UDP(dport=5000,sport=5001)/"data" + + mask = MyMask(pkt_base, ignore_extra_bytes=True, dont_care_all=True) + ETH_H_LEN = 14 + VLAN_H_LEN = 4 + IP4_H_LEN = 20 + IP6_H_LEN = 40 + IP4_DST_OFFSET = 16 + IP6_SRC_OFFSET = 8 + IP6_DST_OFFSET = 24 + UDP_SPORT_OFFSET = 0 + UDP_DPORT_OFFSET = 2 + + vlan_h_len = VLAN_H_LEN + if no_vlan == True: + vlan_h_len = 0 + + if "." in dst_ip: + #mask outer sip + if outer_sip != "": + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_SRC_OFFSET)*8, 128) + #mask outer dip + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_DST_OFFSET)*8, 128) + #mask inner dip + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP4_DST_OFFSET)*8, 32) + #mask inner udp + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP4_H_LEN + UDP_SPORT_OFFSET)*8, 16) + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP4_H_LEN + UDP_DPORT_OFFSET)*8, 16) + else: + #mask outer sip + if outer_sip != "": + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_SRC_OFFSET)*8, 128) + #mask outer dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_DST_OFFSET)*8, 128) + #mask inner dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_DST_OFFSET)*8, 128) + #mask inner udp + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_H_LEN + UDP_SPORT_OFFSET)*8, 16) + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_H_LEN + UDP_DPORT_OFFSET)*8, 16) + + logger.debug("check_topo_recv_pkt_vpn_one_port_only pkt_base: " + pkt_base.summary()) + + cnt = 0 + for port in ports: + if cnt == 0: + #!!this function blocks a long time depending on the packet num + cnt = testutils.count_matched_packets(ptfadapter, mask, port) + if cnt > 0: + logger.debug("check_topo_recv_pkt_vpn_one_port_only recv pkt:{} on port:{} ".format(cnt, port)) + else: + logger.debug("check_topo_recv_pkt_vpn_one_port_only recv pkt:0 on port:{} ".format(port)) + else: + testutils.verify_no_packet(ptfadapter, mask, port_id=port, timeout=2) + + pytest_assert(cnt > 0) + +def check_topo_recv_pkt_te(ptfadapter, port=0, dst_ip="", dscp = 0, vpnsid = "", segment = "", no_packet = False, no_vlan=True, outer_sip=""): + #udp port info is fixed and also define and used in trex_agent.py + outer_src_ip6 = outer_sip if outer_sip != "" else "0::0" + if no_vlan == False: + if "." in dst_ip: + pkt_base = Ether()/Dot1Q()/IPv6(src=outer_src_ip6, dst=segment, nh=41)/IPv6(dst=vpnsid, nh=4)/IP(dst = dst_ip, tos=(dscp<<2))/UDP(dport=5000, sport=5001)/"data" + else: + pkt_base = Ether()/Dot1Q()/IPv6(src=outer_src_ip6, dst=segment, nh=41)/IPv6(dst=vpnsid, nh=41)/IPv6(dst = dst_ip, tc=(dscp<<2))/UDP(dport=5000,sport=5001)/"data" + else: + if "." in dst_ip: + pkt_base = Ether()/IPv6(src=outer_src_ip6, dst=segment, nh=41)/IPv6(dst=vpnsid, nh=4)/IP(dst = dst_ip, tos=(dscp<<2))/UDP(dport=5000, sport=5001)/"data" + else: + pkt_base = Ether()/IPv6(src=outer_src_ip6, dst=segment, nh=41)/IPv6(dst=vpnsid, nh=41)/IPv6(dst = dst_ip, tc=(dscp<<2))/UDP(dport=5000,sport=5001)/"data" + + mask = MyMask(pkt_base, ignore_extra_bytes=True, dont_care_all=True) + ETH_H_LEN = 14 + VLAN_H_LEN = 4 + IP4_H_LEN = 20 + IP6_H_LEN = 40 + IP4_DST_OFFSET = 16 + IP6_SRC_OFFSET = 8 + IP6_DST_OFFSET = 24 + UDP_SPORT_OFFSET = 0 + UDP_DPORT_OFFSET = 2 + + vlan_h_len = VLAN_H_LEN + if no_vlan == True: + vlan_h_len = 0 + + if "." in dst_ip: + #mask outer sip + if outer_sip != "": + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_SRC_OFFSET)*8, 128) + #mask te dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_DST_OFFSET)*8, 128) + #mask vpn dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_DST_OFFSET)*8, 128) + + #mask inner dip + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_H_LEN + IP4_DST_OFFSET)*8, 32) + #mask inner udp + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_H_LEN + IP4_H_LEN + UDP_SPORT_OFFSET)*8, 16) + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_H_LEN + IP4_H_LEN + UDP_DPORT_OFFSET)*8, 16) + else: + #mask outer sip + if outer_sip != "": + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_SRC_OFFSET)*8, 128) + #mask te dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_DST_OFFSET)*8, 128) + #mask vpn dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_DST_OFFSET)*8, 128) + + #mask inner dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_H_LEN + IP6_DST_OFFSET)*8, 128) + #mask inner udp + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_H_LEN + IP6_H_LEN + UDP_SPORT_OFFSET)*8, 16) + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + IP6_H_LEN + IP6_H_LEN + UDP_DPORT_OFFSET)*8, 16) + + logger.debug("check_topo_recv_pkt_te pkt_base: " + pkt_base.summary()) + + if no_packet: + #verify no packet is received on the exact port! + testutils.verify_no_packet(ptfadapter, mask, port_id=port, timeout=2) + else: + #verify packet is received on the exact port! + testutils.verify_packet(ptfadapter, mask, port_id=port, timeout=30) + +def check_topo_recv_pkt_srh_te(ptfadapter, port=0, dst_ip="", dscp = 0, vpnsid = "", segment = "", no_packet = False, no_vlan=True, outer_sip=""): + #udp port info is fixed and also define and used in trex_agent.py + outer_src_ip6 = outer_sip if outer_sip != "" else "0::0" + if no_vlan == False: + if "." in dst_ip: + pkt_base = Ether()/Dot1Q()/IPv6(src=outer_src_ip6, dst=segment, nh=43)/IPv6ExtHdrSegmentRouting(addresses=[vpnsid], nh=4, segleft=1)/IP(dst = dst_ip, tos=(dscp<<2))/UDP(dport=5000, sport=5001)/"data" + else: + pkt_base = Ether()/Dot1Q()/IPv6(src=outer_src_ip6, dst=segment, nh=43)/IPv6ExtHdrSegmentRouting(addresses=[vpnsid], nh=41, segleft=1)/IPv6(dst = dst_ip, tc=(dscp<<2))/UDP(dport=5000,sport=5001)/"data" + else: + if "." in dst_ip: + pkt_base = Ether()/IPv6(src=outer_src_ip6, dst=segment, nh=43)/IPv6ExtHdrSegmentRouting(addresses=[vpnsid], nh=4, segleft=1)/IP(dst = dst_ip, tos=(dscp<<2))/UDP(dport=5000, sport=5001)/"data" + else: + pkt_base = Ether()/IPv6(src=outer_src_ip6, dst=segment, nh=43)/IPv6ExtHdrSegmentRouting(addresses=[vpnsid], nh=41, segleft=1)/IPv6(dst = dst_ip, tc=(dscp<<2))/UDP(dport=5000,sport=5001)/"data" + + mask = MyMask(pkt_base, ignore_extra_bytes=True, dont_care_all=True) + ETH_H_LEN = 14 + VLAN_H_LEN = 4 + IP4_H_LEN = 20 + IP6_H_LEN = 40 + IP4_DST_OFFSET = 16 + IP6_SRC_OFFSET = 8 + IP6_DST_OFFSET = 24 + SRH_H_LEN = 24 + SRH_ADDR_OFFSET = 8 + UDP_SPORT_OFFSET = 0 + UDP_DPORT_OFFSET = 2 + + vlan_h_len = VLAN_H_LEN + if no_vlan == True: + vlan_h_len = 0 + + if "." in dst_ip: + #mask outer sip + if outer_sip != "": + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_SRC_OFFSET)*8, 128) + #mask te dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_DST_OFFSET)*8, 128) + #mask vpn dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + SRH_ADDR_OFFSET)*8, 128) + + #mask inner dip + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + SRH_H_LEN + IP4_DST_OFFSET)*8, 32) + #mask inner udp + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + SRH_H_LEN + IP4_H_LEN + UDP_SPORT_OFFSET)*8, 16) + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + SRH_H_LEN + IP4_H_LEN + UDP_DPORT_OFFSET)*8, 16) + else: + #mask outer sip + if outer_sip != "": + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_SRC_OFFSET)*8, 128) + #mask te dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_DST_OFFSET)*8, 128) + #mask vpn dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + SRH_ADDR_OFFSET)*8, 128) + + #mask inner dip6 + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + SRH_H_LEN + IP6_DST_OFFSET)*8, 128) + #mask inner udp + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + SRH_H_LEN + IP6_H_LEN + UDP_SPORT_OFFSET)*8, 16) + mask.set_care((ETH_H_LEN + vlan_h_len + IP6_H_LEN + SRH_H_LEN + IP6_H_LEN + UDP_DPORT_OFFSET)*8, 16) + + logger.debug("check_topo_recv_pkt_srh_te pkt_base: " + pkt_base.summary()) + + if no_packet: + #verify no packet is received on the exact port! + testutils.verify_no_packet(ptfadapter, mask, port_id=port, timeout=2) + else: + #verify packet is received on the exact port! + testutils.verify_packet(ptfadapter, mask, port_id=port, timeout=30) diff --git a/tests/srv6/test_srv6_basic_sanity.py b/tests/srv6/test_srv6_basic_sanity.py index 3360babc70..8bed77df20 100644 --- a/tests/srv6/test_srv6_basic_sanity.py +++ b/tests/srv6/test_srv6_basic_sanity.py @@ -21,6 +21,9 @@ from common_utils import enable_tcpdump from common_utils import disable_tcpdump +from srv6_utils import * +from trex_utils import * + logger = logging.getLogger(__name__) @@ -46,6 +49,16 @@ # The port used by ptf to connect with backplane. This number is different from 3 ndoe case. # ptf_port_for_backplane = 18 +ptf_port_for_p2_to_p1 = 16 +ptf_port_for_p2_to_p3 = 36 +ptf_port_for_p4_to_p1 = 17 +ptf_port_for_p4_to_p3 = 37 +ptf_port_for_pe3_to_p2 = 39 +ptf_port_for_pe3_to_p4 = 40 +ptf_port_for_p1_to_pe1 = 28 +ptf_port_for_p1_to_pe2 = 29 +ptf_port_for_p3_to_pe1 = 34 +ptf_port_for_p3_to_pe2 = 35 # The number of routes published by each CE num_ce_routes = 10 @@ -81,6 +94,9 @@ # Initialize the testbed # def setup_config(duthosts, rand_one_dut_hostname, nbrhosts, ptfhost): + logger.info("step 0 - install trex on PTF") + trex_install(ptfhost) + logger.info("Announce routes from CEs") ptfip = ptfhost.mgmt_ip nexthop = "10.10.246.254" diff --git a/tests/srv6/trex_agent.py b/tests/srv6/trex_agent.py index 3f9ded1bcd..0eb564dbfd 100755 --- a/tests/srv6/trex_agent.py +++ b/tests/srv6/trex_agent.py @@ -134,7 +134,7 @@ def create_single_ipv6_pkt_with_dscp_random(dip = "192:168:1:1::1", dscp=0, fram return STLPktBuilder(pkt = pkt_base/pkt_pyld, vm = vm) # simple packet creation -# +# def create_ip_pkt_with_dscp(dip = "192.168.0.1", dscp=0, frame_size = 64, dscp_random = False): src = {'start': "0.0.0.1", 'end': "255.255.255.254"} @@ -142,7 +142,7 @@ def create_ip_pkt_with_dscp(dip = "192.168.0.1", dscp=0, frame_size = 64, dscp_r #pkt_base = Ether(src="00:00:00:00:00:01",dst=r127_mac)/Dot1Q(vlan=100)/IP(dst = dip, tos=(dscp<<2))/UDP(dport=5000,sport=5001) pkt_base = Ether(src="00:00:00:00:00:01")/IP(dst = dip, tos=(dscp<<2))/UDP(dport=5000,sport=5001) pyld_size = frame_size - len(pkt_base) - pkt_pyld = generate_payload(pyld_size) + pkt_pyld = generate_payload(pyld_size) vm = [ # src op="random" @@ -168,7 +168,7 @@ def create_ipv6_pkt_with_dscp(dip = "192:168:1:1::1", dscp=0, frame_size = 96, d src = {'start': "0.0.0.1", 'end': "255.255.255.254"} pkt_base = Ether(src="00:00:00:00:00:01")/IPv6(dst = dip, tc=(dscp<<2))/UDP(dport=5000,sport=5001) pyld_size = frame_size - len(pkt_base) - pkt_pyld = generate_payload(pyld_size) + pkt_pyld = generate_payload(pyld_size) vm = [ STLVmFlowVar(name="ip_src", min_value=src['start'], max_value=src['end'], size=4, op="random"), STLVmWrFlowVar(fv_name="ip_src", pkt_offset ="IPv6.src",offset_fixup=12 )] @@ -186,7 +186,7 @@ def create_ip_in_ip6_pkt(uni, dip = "192.168.0.1", dscp=4, frame_size = 128): src = {'start': "0.0.0.1", 'end': "255.255.255.254"} pkt_base = Ether(src="00:00:00:00:00:01")/IPv6(dst=uni, nh=4)/IP(dst = dip, tos=(dscp<<2))/UDP(dport=5000,sport=5001) pyld_size = frame_size - len(pkt_base) - pkt_pyld = generate_payload(pyld_size) + pkt_pyld = generate_payload(pyld_size) vm = [ # src @@ -208,7 +208,7 @@ def create_ipv6_in_ip6_pkt(uni, dip = "192:168:1:1::1", dscp=0, frame_size = 128 src = {'start': "0.0.0.1", 'end': "255.255.255.254"} pkt_base = Ether(src="00:00:00:00:00:01")/IPv6(dst = uni, nh=41)/IPv6(dst = dip, tc=(dscp<<2))/UDP(dport=5000,sport=5001) pyld_size = frame_size - len(pkt_base) - pkt_pyld = generate_payload(pyld_size) + pkt_pyld = generate_payload(pyld_size) vm = STLScVmRaw( [ STLVmFlowVar(name="ip_src", min_value=src['start'], max_value=src['end'], size=4, op="random"), STLVmWrFlowVar(fv_name="ip_src", pkt_offset ="IPv6:1.src",offset_fixup=12 )]) @@ -259,7 +259,7 @@ def trex_do_transmit(dip, dscp = 0, uni = "", duration = 10, single_stream = Fal stream = STLStream(packet=pkt, mode=STLTXCont(pps=1000)) my_ports = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] - + #acquire and reset counter c.reset(ports = my_ports) in_port = 0 @@ -271,7 +271,7 @@ def trex_do_transmit(dip, dscp = 0, uni = "", duration = 10, single_stream = Fal c.wait_on_traffic() #wait some time and get the stats time.sleep(2) - + #get the stats stats = c.get_stats() if not stats: @@ -326,7 +326,7 @@ def trex_do_transmit(dip, dscp = 0, uni = "", duration = 10, single_stream = Fal if 11 in stats: result['PE3_tx_to_P4'] = int(stats[11]["ipackets"]) - c.clear_stats(ports = my_ports) + c.clear_stats(ports = my_ports) except Exception as e: err_str = "trex_do_transmit exp Error: %s" % e print(err_str) @@ -366,7 +366,7 @@ def trex_start_transmit(dip, dscp = 0, uni = "", single_stream = False, ingress_ my_ports = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] #acquire and reset counter c.reset(ports = my_ports) - + in_port = 0 #add the stream @@ -443,7 +443,7 @@ def trex_stop_transmit(conn, dip = "", dscp = 0, uni = "", ingress_pe=""): if 11 in stats: result['PE3_tx_to_P4'] = int(stats[11]["ipackets"]) - conn.clear_stats() + conn.clear_stats() except Exception as e: err_str = "trex_stop_transmit exp Error: %s" % e print(err_str) @@ -464,7 +464,7 @@ def process_trex_cmd(data, ctx): if data["cmd"] != "start" and data["cmd"] != "stop" and data["cmd"] != "run": print("error, unsupported cmd:{}".format(data["cmd"])) return result - + trex_conn = None if "trex_conn" in ctx: trex_conn = ctx["trex_conn"] @@ -477,7 +477,7 @@ def process_trex_cmd(data, ctx): if data["cmd"] == "stop": print("error, no transmit is running") return result - + #get all test data dip = data["dip"] dscp = 0 diff --git a/tests/srv6/trex_cfg.yaml b/tests/srv6/trex_cfg.yaml index 255d5327b9..7db3011b55 100644 --- a/tests/srv6/trex_cfg.yaml +++ b/tests/srv6/trex_cfg.yaml @@ -27,6 +27,4 @@ - dest_mac : '52:54:00:96:90:d5' # port 10 src_mac : '6e:fc:2e:56:21:27' - dest_mac : '52:54:00:df:1c:5e' # port 11 - src_mac : 'c2:68:6a:7b:c2:28' - - + src_mac : 'c2:68:6a:7b:c2:28' \ No newline at end of file diff --git a/tests/srv6/trex_utils.py b/tests/srv6/trex_utils.py index 655ddbcf73..9d8fa31c3e 100755 --- a/tests/srv6/trex_utils.py +++ b/tests/srv6/trex_utils.py @@ -27,7 +27,7 @@ def trex_agent_run(cmd): current_time = datetime.datetime.now() logger.info("start req:{}, at:{}".format(cmd, current_time)) - s.send(json.dumps(cmd)) + s.send(json.dumps(cmd).encode()) #wait 60 seconds maximum to receive data s.settimeout(60) @@ -50,13 +50,13 @@ def trex_agent_run(cmd): def trex_run(dip, dscp = 0, uni = "", duration = 10, single_stream = False, ingress_pe="", dscp_random = False): """ Run Trex with stream (uni, dip, dscp) for duration seconds. if uni is specified, It is the outer dst IPv6 address. - Returns packets result on all ports, for example: + Returns packets result on all ports, for example: {'ptf_tot_tx': 15001, 'ptf_tot_rx': 15035, 'P3_tx_to_PE2': 3909, 'P3_tx_to_PE1': 3959, 'P1_tx_to_PE2': 3626, 'P1_tx_to_PE1': 3607} @param dip - inner dst ipv4/ipv6 address @param dscp - inner dscp in ipv4/ipv6 header @param uni - if specified, It is the outer dst IPv6 address @single_stream - whether to send data in a single stream - @ingress_pe - can only be PE11/PE12/PE21, by default is PE21 + @ingress_pe - can only be PE1/PE2/PE3, by default is PE3 @dscp_random - send a stream with random dscp """ cmd = {} @@ -70,8 +70,8 @@ def trex_run(dip, dscp = 0, uni = "", duration = 10, single_stream = False, ingr if single_stream: cmd["single_stream"] = True if ingress_pe != "": - if ingress_pe != "PE11" and ingress_pe != "PE12" and ingress_pe != "PE21": - logger.info("trex_run: ingress_pe only support PE11 or PE12 or PE21") + if ingress_pe != "PE1" and ingress_pe != "PE2" and ingress_pe != "PE3": + logger.info("trex_run: ingress_pe only support PE1 or PE2 or PE3") return None cmd["ingress_pe"] = ingress_pe @@ -90,7 +90,7 @@ def trex_start(dip, dscp = 0, uni = "", single_stream = False, ingress_pe="", ds @param dscp - inner dscp in ipv4/ipv6 header @param uni - if specified, It is the outer dst IPv6 address @single_stream - whether to send data in a single stream - @ingress_pe - can only be PE11/PE12/PE21, by default is PE21 + @ingress_pe - can only be PE1/PE2/PE3, by default is PE3 @dscp_random - send a stream with random dscp """ cmd = {} @@ -104,8 +104,8 @@ def trex_start(dip, dscp = 0, uni = "", single_stream = False, ingress_pe="", ds cmd["single_stream"] = True if ingress_pe != "": - if ingress_pe != "PE11" and ingress_pe != "PE12" and ingress_pe != "PE21": - logger.info("trex_start: ingress_pe only support PE11 or PE12 or PE21") + if ingress_pe != "PE1" and ingress_pe != "PE2" and ingress_pe != "PE3": + logger.info("trex_start: ingress_pe only support PE1 or PE2 or PE3") return None cmd["ingress_pe"] = ingress_pe @@ -118,7 +118,7 @@ def trex_start(dip, dscp = 0, uni = "", single_stream = False, ingress_pe="", ds def trex_stop(dip, dscp = 0, uni = ""): """ - Stop the stream and return packets result on all ports, for example: + Stop the stream and return packets result on all ports, for example: {'ptf_tot_tx': 15001, 'ptf_tot_rx': 15035, 'P3_tx_to_PE2': 3909, 'P3_tx_to_PE1': 3959, 'P1_tx_to_PE2': 3626, 'P1_tx_to_PE1': 3607} """ cmd = {} @@ -157,22 +157,22 @@ def thresh_check(result, check_list): if "ptf_tot_tx" in check_list and thresh_check_item(result, "ptf_tot_tx", check_list["ptf_tot_tx"]) == False: return False - + if "ptf_tot_rx" in check_list and thresh_check_item(result, "ptf_tot_rx", check_list["ptf_tot_rx"]) == False: return False - + if "P1_tx_to_PE1" in check_list and thresh_check_item(result, "P1_tx_to_PE1", check_list["P1_tx_to_PE1"]) == False: return False - + if "P1_tx_to_PE2" in check_list and thresh_check_item(result, "P1_tx_to_PE2", check_list["P1_tx_to_PE2"]) == False: return False - + if "P3_tx_to_PE1" in check_list and thresh_check_item(result, "P3_tx_to_PE1", check_list["P3_tx_to_PE1"]) == False: return False - + if "P3_tx_to_PE2" in check_list and thresh_check_item(result, "P3_tx_to_PE2", check_list["P3_tx_to_PE2"]) == False: return False - + if "P2_tx_to_P1" in check_list and thresh_check_item(result, "P2_tx_to_P1", check_list["P2_tx_to_P1"]) == False: return False @@ -193,16 +193,16 @@ def thresh_check(result, check_list): return True def check_pkt_drop(result, span): - + if "ptf_tot_tx" not in result or result["ptf_tot_tx"] == 0: return False - + if "ptf_tot_rx" not in result: return False - + if span <= 0: return False - + tx = result["ptf_tot_tx"] rx = result["ptf_tot_rx"]