From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E9016A0518; Fri, 24 Jul 2020 04:45:16 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id DFB161D5F9; Fri, 24 Jul 2020 04:45:16 +0200 (CEST) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id EB3591D531 for ; Fri, 24 Jul 2020 04:45:14 +0200 (CEST) IronPort-SDR: 4P5nE+JpDohkmeV2RQ0mMX8dYXP2syY0k4jstl263LpM+ndpodVkXM/XVw1ba5ONFfH4e84OBF R0iRETuVnW2g== X-IronPort-AV: E=McAfee;i="6000,8403,9691"; a="212186175" X-IronPort-AV: E=Sophos;i="5.75,389,1589266800"; d="scan'208";a="212186175" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jul 2020 19:45:14 -0700 IronPort-SDR: Wt+WfBUza/I/TG1ayAL4dU2c+YAdroCbTAQ6V7Lt7MzlLcXZ+ZHHj7+jETGL9hqgZ1LvjCwg4v rf1IOwDtlFUw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,389,1589266800"; d="scan'208";a="271221232" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by fmsmga007.fm.intel.com with ESMTP; 23 Jul 2020 19:45:13 -0700 Received: from fmsmsx609.amr.corp.intel.com (10.18.126.89) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 23 Jul 2020 19:45:13 -0700 Received: from fmsmsx609.amr.corp.intel.com (10.18.126.89) by fmsmsx609.amr.corp.intel.com (10.18.126.89) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Thu, 23 Jul 2020 19:45:11 -0700 Received: from shsmsx154.ccr.corp.intel.com (10.239.6.54) by fmsmsx609.amr.corp.intel.com (10.18.126.89) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.1713.5 via Frontend Transport; Thu, 23 Jul 2020 19:45:11 -0700 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.22]) by SHSMSX154.ccr.corp.intel.com ([169.254.7.32]) with mapi id 14.03.0439.000; Fri, 24 Jul 2020 10:45:09 +0800 From: "Tu, Lijuan" To: Owen Hilyard , "dts@dpdk.org" CC: "Yigit, Ferruh" , "arybchenko@solarflare.com" , "olivier.matz@6wind.com" , "david.marchand@redhat.com" , "ivan.malov@oktetlabs.ru" , "Richardson, Bruce" , "lylavoie@iol.unh.edu" , "rasland@mellanox.com" , "j.hendergart@f5.com" , "thomas@monjalon.net" Thread-Topic: [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases Thread-Index: AQHWXp89mL6E1oXHI0+62lB+zyCCzqkWC0OQ Date: Fri, 24 Jul 2020 02:45:08 +0000 Message-ID: <8CE3E05A3F976642AAB0F4675D0AD20E0BC84184@SHSMSX101.ccr.corp.intel.com> References: <20200714145355.18410-1-ohilyard@iol.unh.edu> <20200720140744.210132-1-ohilyard@iol.unh.edu> In-Reply-To: <20200720140744.210132-1-ohilyard@iol.unh.edu> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="iso-2022-jp" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dts-bounces@dpdk.org Sender: "dts" Is the patch based on the latest DTS ? sorry, I can't merge it because of c= ode conflict. Could you please rework it. Btw, all patches, v1/v2... should= be based on latest DTS. Thanks, Lijuan. > -----Original Message----- > From: dts On Behalf Of Owen Hilyard > Sent: 2020=1B$BG/=1B(B7=1B$B7n=1B(B20=1B$BF|=1B(B 22:08 > To: dts@dpdk.org > Cc: Yigit, Ferruh ; arybchenko@solarflare.com; > olivier.matz@6wind.com; david.marchand@redhat.com; > ivan.malov@oktetlabs.ru; Richardson, Bruce ; > lylavoie@iol.unh.edu; rasland@mellanox.com; j.hendergart@f5.com; > ohilyard@iol.unh.edu; thomas@monjalon.net > Subject: [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 ca= ses >=20 > add rx and tx l3 test cases > add tx l4 test case > add documentation for new test cases >=20 > Signed-off-by: Owen Hilyard > --- > test_plans/checksum_offload_test_plan.rst | 122 +++++++- > tests/TestSuite_checksum_offload.py | 331 +++++++++++++++++++--- > 2 files changed, 412 insertions(+), 41 deletions(-) >=20 > diff --git a/test_plans/checksum_offload_test_plan.rst > b/test_plans/checksum_offload_test_plan.rst > index 4fd8c5a..de2e1a9 100644 > --- a/test_plans/checksum_offload_test_plan.rst > +++ b/test_plans/checksum_offload_test_plan.rst > @@ -221,7 +221,7 @@ combination: good/bad ip checksum + good/bad > udp/tcp checksum. >=20 > Check the Rx checksum flags consistent with expected flags. >=20 > -Test Case: Hardware Checksum Check L4 > +Test Case: Hardware Checksum Check L4 RX > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > This test involves testing many different scenarios with a L4 checksum. > A variety of tunneling protocols, L3 protocols and L4 protocols are comb= ined > @@ -256,4 +256,122 @@ Send a packet with a bad checksum:: > rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D17 l4_len=3D8 > flags=3DPKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_BAD > PKT_RX_OUTER_L4_CKSUM_UNKNOWN > tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4 >=20 > -Verify flags are as expected. > \ No newline at end of file > +Verify flags are as expected. > + > +Test Case: Hardware Checksum Check L3 RX > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > +This test involves testing L3 checksum hardware offload. > +Due to the relative dominance of IPv4 and IPv6 as L3 protocols, and > +IPv6's lack of a checksum, only IPv4's checksum is tested. > + > +Setup the ``csum`` forwarding mode:: > + > + testpmd> set fwd csum > + Set csum packet forwarding mode > + > +Start the packet forwarding:: > + > + testpmd> start > + csum packet forwarding - CRC stripping disabled - packets/burst=3D32 > + nb forwarding cores=3D1 - nb forwarding ports=3D10 > + RX queues=3D1 - RX desc=3D128 - RX free threshold=3D64 > + RX threshold registers: pthresh=3D8 hthresh=3D8 wthresh=3D4 > + TX queues=3D1 - TX desc=3D512 - TX free threshold=3D0 > + TX threshold registers: pthresh=3D32 hthresh=3D8 wthresh=3D8 > + > +Send a packet with a good checksum:: > + > + port=3D0, mbuf=3D0x2269df8780, pkt_len=3D96, nb_segs=3D1: > + rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D17 l4_len=3D8 > flags=3DPKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD > PKT_RX_OUTER_L4_CKSUM_UNKNOWN > + tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4 > + > +Send a packet with a bad checksum:: > + > + port=3D0, mbuf=3D0x2269df7e40, pkt_len=3D96, nb_segs=3D1: > + rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D17 l4_len=3D8 > flags=3DPKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_BAD > PKT_RX_OUTER_L4_CKSUM_UNKNOWN > + tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4 > + > +Verify flags are as expected. > + > +Test Case: Hardware Checksum Check L4 TX > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > +This test involves testing many different scenarios with a L4 checksum. > +A variety of tunneling protocols, L3 protocols and L4 protocols are > +combined to test as many scenarios as possible. Currently, UDP, TCP and > +SCTP are used as L4 protocols, with IP and IPv6 being used at level 3. > +The tested tunneling protocols are VXLAN and GRE. This test is used to > +determine whether the hardware offloading of checksums works properly. > + > +Setup the ``csum`` forwarding mode:: > + > + testpmd> set fwd csum > + Set csum packet forwarding mode > + > +Start the packet forwarding:: > + > + testpmd> start > + csum packet forwarding - CRC stripping disabled - packets/burst=3D32 > + nb forwarding cores=3D1 - nb forwarding ports=3D10 > + RX queues=3D1 - RX desc=3D128 - RX free threshold=3D64 > + RX threshold registers: pthresh=3D8 hthresh=3D8 wthresh=3D4 > + TX queues=3D1 - TX desc=3D512 - TX free threshold=3D0 > + TX threshold registers: pthresh=3D32 hthresh=3D8 wthresh=3D8 > + > + > +Start a packet capture on the tester in the backround:: > + > + # tcpdump -i -s 65535 -w > + /tmp/tester/test_hardware_checksum_check_l4_tx_capture.pcap & > + > +Send a packet with a good checksum:: > + > + port=3D0, mbuf=3D0x2269df8780, pkt_len=3D96, nb_segs=3D1: > + rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D17 l4_len=3D8 > flags=3DPKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD > PKT_RX_OUTER_L4_CKSUM_UNKNOWN > + tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4 > + > +Send a packet with a bad checksum:: > + > + port=3D0, mbuf=3D0x2269df7e40, pkt_len=3D96, nb_segs=3D1: > + rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D17 l4_len=3D8 > flags=3DPKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_GOOD > PKT_RX_OUTER_L4_CKSUM_UNKNOWN > + tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4 > + > +Inspect the pcap file from the packet capture and verify the checksums. > + > +Test Case: Hardware Checksum Check L3 TX > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > +This test involves testing L3 checksum hardware offload. > +Due to the relative dominance of IPv4 and IPv6 as L3 protocols, and > +IPv6's lack of a checksum, only IPv4's checksum is tested. > + > +Setup the ``csum`` forwarding mode:: > + > + testpmd> set fwd csum > + Set csum packet forwarding mode > + > +Start the packet forwarding:: > + > + testpmd> start > + csum packet forwarding - CRC stripping disabled - packets/burst=3D32 > + nb forwarding cores=3D1 - nb forwarding ports=3D10 > + RX queues=3D1 - RX desc=3D128 - RX free threshold=3D64 > + RX threshold registers: pthresh=3D8 hthresh=3D8 wthresh=3D4 > + TX queues=3D1 - TX desc=3D512 - TX free threshold=3D0 > + TX threshold registers: pthresh=3D32 hthresh=3D8 wthresh=3D8 > + > + > +Start a packet capture on the tester in the backround:: > + > + # tcpdump -i -s 65535 -w > + /tmp/tester/test_hardware_checksum_check_l3_tx_capture.pcap & > + > +Send a packet with a good checksum with a 1 in it's payload:: > + > + port=3D0, mbuf=3D0x2269df8780, pkt_len=3D96, nb_segs=3D1: > + rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D17 l4_len=3D8 > flags=3DPKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD > PKT_RX_OUTER_L4_CKSUM_UNKNOWN > + tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4 > + > +Send a packet with a bad checksum with a 0 in it's payload:: > + > + port=3D0, mbuf=3D0x2269df7e40, pkt_len=3D96, nb_segs=3D1: > + rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D17 l4_len=3D8 > flags=3DPKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_BAD > PKT_RX_OUTER_L4_CKSUM_UNKNOWN > + tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4 > + > +Inspect the pcap file from the packet capture and verify the checksums. > diff --git a/tests/TestSuite_checksum_offload.py > b/tests/TestSuite_checksum_offload.py > index 9ff5a41..c4a877d 100644 > --- a/tests/TestSuite_checksum_offload.py > +++ b/tests/TestSuite_checksum_offload.py > @@ -47,8 +47,18 @@ import time >=20 > from rst import RstReport > import utils > - > +from exception import VerifyFailure > +from pktgen import PacketGeneratorHelper from scapy.layers.inet import > +UDP, TCP, IP from scapy.layers.inet6 import IPv6 from scapy.layers.l2 > +import Ether, GRE from scapy.layers.sctp import SCTP from > +scapy.layers.vxlan import VXLAN from scapy.packet import Raw from > +scapy.utils import wrpcap, rdpcap from test_capabilities import > +DRIVER_TEST_LACK_CAPA > from test_case import TestCase > + > from framework.pmd_output import PmdOutput from test_capabilities impor= t > DRIVER_TEST_LACK_CAPA from pktgen import PacketGeneratorHelper @@ - > 57,6 +67,33 @@ import packet >=20 > from settings import FOLDERS >=20 > +l3_proto_classes =3D [ > + IP, > + IPv6 > +] > + > +l4_proto_classes =3D [ > + UDP, > + TCP, > + SCTP > +] > + > +tunnelling_proto_classes =3D [ > + VXLAN, > + GRE, > +] > + > +l3_protos =3D [ > + "IP", > + "IPv6" > +] > + > +l4_protos =3D [ > + "UDP", > + "TCP", > + "SCTP", > +] > + >=20 > class TestChecksumOffload(TestCase): >=20 > @@ -79,8 +116,6 @@ class TestChecksumOffload(TestCase): > cur_path =3D os.path.dirname( > os.path.dirname(os.path.realpath(__file__))) > self.output_path =3D os.sep.join([cur_path, self.logger.log_= path]) > - # create an instance to set stream field setting > - self.pktgen_helper =3D PacketGeneratorHelper() >=20 > def set_up(self): > """ > @@ -243,7 +278,6 @@ class TestChecksumOffload(TestCase): > def send_pkt_expect_good_bad_from_flag(self, pkt_str: str, flag: str= , > test_name: str, should_pass: bool =3D True): > self.pmdout.get_output(timeout=3D5) # Remove any old output > self.scapy_exec(f"sendp({pkt_str}, iface=3Diface)") > - time.sleep(1) > testpmd_output: str =3D self.pmdout.get_output(timeout=3D5) > self.verify(flag in testpmd_output, > f"Flag {flag[:-1]} not found for test {test_name}, p= lease run > test_rx_checksum_valid_flags.") @@ -269,11 +303,147 @@ class > TestChecksumOffload(TestCase): >=20 > return None >=20 > - def scapy_exec(self, cmd: str): > - return self.tester.send_expect(cmd, ">>>") > + def validate_checksum(self, pkt, layer) -> bool: > + """ > + @param pkt: The packet to validate the checksum of. > + @return: Whether the checksum was valid. > + """ > + if pkt is None: > + return False > + > + csum =3D pkt[layer].chksum > + del pkt[layer].chksum > + # Converting it to raw will calculate the checksum > + return layer(Raw(pkt[layer])).chksum =3D=3D csum >=20 > - def scapy_send_append(self, packet: str): > - return self.tester.scapy_append(f'sendp({packet}, iface=3Diface)= ') > + def scapy_exec(self, cmd: str, timeout=3D1) -> str: > + return self.tester.send_expect(cmd, ">>>", timeout=3Dtimeout) > + > + def get_packets(self, dut_mac, tester_mac): > + eth =3D Ether(dst=3Ddut_mac, src=3Dtester_mac) > + packets =3D [] > + checksum_options =3D ({}, {'chksum': 0xf},) > + # Untunneled > + for l3 in l3_proto_classes: > + for l4 in l4_proto_classes: > + for chksum in checksum_options: > + # The packet's data can be used to identify how the = packet was > constructed so avoid any issues with > + # ordering > + pkt =3D eth / l3() / l4(**chksum) / ( > + f'UNTUNNELED,{l3.__name__},{l4.__name__},{" " if > len(chksum.values()) =3D=3D 0 else chksum["chksum"]}' > + ) > + > + # Prevents the default behavior which adds DNS heade= rs > + if l4 =3D=3D UDP: > + pkt[UDP].dport, pkt[UDP].sport =3D 1001, 1001 > + > + packets.append(pkt) > + > + # Tunneled > + # VXLAN > + for l3 in l3_proto_classes: > + for l4 in l4_proto_classes: > + for outer_arg in checksum_options: > + for inner_arg in checksum_options: > + pkt =3D eth / l3() / UDP(**outer_arg) / VXLAN() = / Ether() / l3() / > l4(**inner_arg) / ( > + f'VXLAN,{l3.__name__},{l4.__name__},' > + f'{" " if len(outer_arg.values()) =3D=3D 0 e= lse outer_arg["chksum"]},' > + f'{" " if len(inner_arg.values()) =3D=3D 0 e= lse inner_arg["chksum"]}' > + ) > + # Prevents the default behavior which adds DNS h= eaders > + if l4 =3D=3D UDP: > + pkt[VXLAN][UDP].dport, > + pkt[VXLAN][UDP].sport =3D 1001, 1001 > + > + packets.append(pkt) > + # GRE > + for l3 in l3_proto_classes: > + for l4 in l4_proto_classes: > + for chksum in checksum_options: > + pkt =3D eth / l3() / GRE() / l3() / l4(**chksum) / ( > + f'GRE,{l3.__name__},{l4.__name__},{" " if len(ch= ksum.values()) =3D=3D > 0 else chksum["chksum"]}' > + ) > + > + # Prevents the default behavior which adds DNS heade= rs > + if l4 =3D=3D UDP: > + pkt[GRE][UDP].dport, pkt[GRE][UDP].sport =3D > + 1001, 1001 > + > + packets.append(pkt) > + > + return packets > + > + def replay_pcap_file_on_tester(self, iface, packet_file_path): > + self.tester.send_expect("scapy", ">>>") > + self.scapy_exec(f"packets =3D rdpcap('{packet_file_path}')") > + self.scapy_exec(f"sendp(packets, iface=3D{iface})") > + self.tester.send_expect("quit()", "# ") > + > + def validate_packet_list_checksums(self, packets): > + name_to_class_dict =3D { > + 'UDP': UDP, > + 'TCP': TCP, > + 'SCTP': SCTP, > + 'IP': IP, > + 'IPv6': IPv6, > + 'VXLAN': VXLAN, > + 'GRE': GRE, > + } > + > + error_messages =3D [] > + > + untunnelled_error_message =3D f"Invalid untunneled checksum stat= e > for %s/%s with a %s checksum." > + > + vxlan_error_message =3D f"Invalid VXLAN tunnelled %s checksum st= ate > for %s/%s" \ > + f" with a %s inner checksum and a %s outer= checksum." > + > + gre_error_message =3D f"Invalid GRE tunnelled checksum state for= %s/%s > with a %s checksum." > + > + for packet in packets: > + payload: str > + # try: > + payload =3D packet[Raw].load.decode('utf-8').split(",") > + # # This error usually happens with tunneling protocols, and= means that > an additional cast is needed > + # except UnicodeDecodeError: > + # for proto in tunnelling_proto_classes: > + > + l3 =3D name_to_class_dict[payload[1]] > + l4 =3D name_to_class_dict[payload[2]] > + if payload[0] =3D=3D "UNTUNNELED": > + chksum_should_be_valid =3D payload[3] =3D=3D " " > + if self.validate_checksum(packet, l4) !=3D chksum_should= _be_valid: > + error_messages.append( > + untunnelled_error_message % ( > + l3.__name__, l4.__name__, 'valid' if chksum_= should_be_valid > =3D=3D '' else 'invalid' > + ) > + ) > + elif payload[0] =3D=3D "VXLAN": > + outer_chksum_should_be_valid =3D payload[3] =3D=3D " " > + inner_chksum_should_be_valid =3D payload[4] =3D=3D " " > + if self.validate_checksum(packet[VXLAN], l4) !=3D > inner_chksum_should_be_valid: > + error_messages.append( > + vxlan_error_message % ( > + "inner", l4.__name__, l3.__name__, > + 'valid' if inner_chksum_should_be_valid =3D= =3D '' else 'invalid', > + 'valid' if outer_chksum_should_be_valid =3D= =3D '' else 'invalid' > + ) > + ) > + if self.validate_checksum(packet, l4) !=3D > outer_chksum_should_be_valid: > + error_messages.append( > + vxlan_error_message % ( > + "outer", l3.__name__, l4.__name__, > + 'valid' if inner_chksum_should_be_valid =3D= =3D '' else 'invalid', > + 'valid' if outer_chksum_should_be_valid =3D= =3D '' else 'invalid' > + ) > + ) > + elif payload[0] =3D=3D "GRE": > + chksum_should_be_valid =3D payload[3] =3D=3D " " > + if self.validate_checksum(packet, l4) !=3D chksum_should= _be_valid: > + error_messages.append( > + gre_error_message % ( > + l3.__name__, l4.__name__, 'valid' if chksum_= should_be_valid > =3D=3D '' else 'invalid' > + ) > + ) > + > + return error_messages >=20 > # > # > @@ -448,6 +618,9 @@ class TestChecksumOffload(TestCase): >=20 > # clear streams before add new streams > self.tester.pktgen.clear_streams() > + # create an instance to set stream field setting > + # Moved here because it messes with the ability of the funct= ional tests > to use scapy. > + self.pktgen_helper =3D PacketGeneratorHelper() > # run packet generator > streams =3D self.pktgen_helper.prepare_stream_from_tginput(t= genInput, > 100, > None, self.tester.pktgen) @@ -511,53 +684,93 @@ clas= s > TestChecksumOffload(TestCase): > self.dut.send_expect("quit", "#", 10) > self.result_table_print() >=20 > - def test_hardware_checksum_check_ip(self): > + def test_hardware_checksum_check_ip_rx(self): > self.dut.send_expect("start", "testpmd>") > + self.tester.send_expect("scapy", ">>>") > self.checksum_enablehw(self.dut_ports[0]) > + self.dut.send_expect("start", "testpmd>") >=20 > verification_errors: List[VerifyFailure] =3D [] >=20 > - # untunnelled > - vf =3D > self.try_helper_hardware_checksum_check_catch_failure('Ether(dst=3D"%s", > src=3D"%s")/IP(%s)/UDP()/("X"*50)', > - "PKT_= RX_IP_CKSUM_") > - if vf is not None: > - verification_errors.append(vf) > + iface =3D > self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0])) > + dut_mac =3D self.dut.get_mac_address(self.dut_ports[0]) > + tester_mac =3D > + self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0])) >=20 > - # tunneled inner > - vf =3D self.try_helper_hardware_checksum_check_catch_failure( > - 'Ether(dst=3D"%s", src=3D"%s")/IP()/UDP()/IP(%s)/("X"*50)', > - "PKT_RX_OUTER_IP_CKSUM_") > - if vf is not None: > - verification_errors.append(vf) > + self.scapy_exec(f"eth =3D Ether(dst=3D'{dut_mac}', src=3D'{teste= r_mac}')") > + self.scapy_exec(f"iface =3D '{iface}'") >=20 > - # tunneled outer > - vf =3D self.try_helper_hardware_checksum_check_catch_failure( > - 'Ether(dst=3D"%s", src=3D"%s")/IP()/UDP()/IP(%s)/("X"*50)', > - "PKT_RX_OUTER_IP_CKSUM_") > - if vf is not None: > - verification_errors.append(vf) > + # Untunnelled > + for l4 in l4_protos: > + for chksum in "", "chksum=3D0xf": > + vf =3D self.send_pkt_expect_good_bad_from_flag_catch_fai= lure( > + f"eth/IP({chksum})/{l4}()/(X'*50)", > + "PKT_RX_IP_CKSUM_", f"{l4}", > + should_pass=3D(chksum =3D=3D "")) > + if vf is not None: > + verification_errors.append(vf) >=20 > - self.verify(len(verification_errors) =3D=3D 0, "\n".join(verific= ation_errors)) > + for err in verification_errors: > + self.logger.error(str(err)) > + self.verify(len(verification_errors) =3D=3D 0, "See previous > + output") >=20 > + self.tester.send_expect("quit()", "# ") > self.dut.send_expect("stop", "testpmd>") >=20 > - def test_hardware_checksum_check_l4(self): > + def test_hardware_checksum_check_ip_tx(self): > self.checksum_enablehw(self.dut_ports[0]) > self.dut.send_expect("start", "testpmd>") >=20 > verification_errors: List[VerifyFailure] =3D [] >=20 > - l3_protos: List[str] =3D [ > - "IP", > - "IPv6" > - ] > + iface =3D > self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0])) > + dut_mac =3D self.dut.get_mac_address(self.dut_ports[0]) > + tester_mac =3D > self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0])) > + eth =3D Ether(dst=3Ddut_mac, src=3Dtester_mac) >=20 > - l4_protos: List[str] =3D [ > - "UDP", > - "TCP", > - "SCTP", > + checksum_options =3D ({}, {'chksum': 0xf},) > + > + packets =3D [ > + eth / IP(**chksum) / TCP() / Raw(load=3Dstr(int(len(chksum) > + !=3D 1))) for chksum in checksum_options > ] >=20 > + capture_file_name =3D > "test_hardware_checksum_check_l3_tx_capture.pcap" > + > + packet_file_path =3D > "/tmp/test_hardware_checksum_check_l3_tx_packets.pcap" > + capture_file_path =3D "/tmp/tester/" + capture_file_name > + > + self.tester.send_expect(f"tcpdump -i {iface} -s 65535 -w > + {capture_file_path} &", "# ") > + > + wrpcap(packet_file_path, packets) > + self.tester.session.copy_file_to(packet_file_path, > + packet_file_path) > + > + self.replay_pcap_file_on_tester(iface, packet_file_path) > + > + self.tester.session.copy_file_from(packet_file_path, > + "output/tmp/pcap/" + capture_file_name) > + > + captured_packets =3D rdpcap("output/tmp/pcap/" + > + capture_file_name) > + > + self.verify(len(packets) =3D=3D len(captured_packets), "Not all > + packets were received") > + > + error_messages =3D [] > + for pkt in captured_packets: > + should_pass =3D pkt[TCP].payload.build() =3D=3D b'1' > + if not (self.validate_checksum(pkt, IP) =3D=3D should_pass): > + error_messages.append(f"A packet was marked as having a" > + f"{' valid' if should_pass =3D=3D = '' else 'n invalid'}" > + f" checksum when it should have > + had the opposite.") > + > + self.dut.send_expect("stop", "testpmd>") > + if len(error_messages) !=3D 0: > + for error_msg in error_messages: > + self.logger.error(error_msg) > + self.verify(False, "See prior output") > + > + def test_hardware_checksum_check_l4_rx(self): > + self.checksum_enablehw(self.dut_ports[0]) > + self.dut.send_expect("start", "testpmd>") > + > + verification_errors: List[VerifyFailure] =3D [] > + > iface =3D > self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0])) > dut_mac =3D self.dut.get_mac_address(self.dut_ports[0]) > tester_mac =3D > self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0])) > @@ -589,7 +802,7 @@ class TestChecksumOffload(TestCase): > should_pass =3D outer_arg =3D=3D "" > vf =3D self.send_pkt_expect_good_bad_from_fl= ag_catch_failure( > f"eth/{l3}()/{l4}({outer_arg})/VXLAN()/{= l3}()/" > - f"{l4}({inner_arg})/('X'*50)", > + f"{l4}(chksum=3D{inner_arg})/('X'*50)", > flag, f"{l3}/{l4}/VXLAN/{l3}/{l4}", > should_pass=3Dshould_pass) >=20 > @@ -602,8 +815,7 @@ class TestChecksumOffload(TestCase): > for inner_arg in "", "chksum=3D0xf": > should_pass: bool =3D inner_arg =3D=3D "" > vf =3D self.send_pkt_expect_good_bad_from_flag_catch= _failure( > - f"eth/{l3}()/GRE()/{l3}()/" > - f"{l4}({inner_arg})/('X'*50)", > + > + f"eth/{l3}()/GRE()/{l3}()/{l4}({inner_arg})/('X'*50)", > "PKT_RX_L4_CKSUM_", f"{l3}/GRE/{l3}/{l4}", > should_pass=3Dshould_pass) >=20 > @@ -615,6 +827,8 @@ class TestChecksumOffload(TestCase): > # updated this test case can easily take advantage of the new fu= nctionality. >=20 > # # GENEVE > + # # This import is over here so that it is not forgotten when th= e update > happens > + # from scapy.contrib.geneve import GENEVE > # for l3_outer in l3_protos: > # for l4_outer in l4_protos: > # for l3_inner in l3_protos: > @@ -638,7 +852,46 @@ class TestChecksumOffload(TestCase): > self.logger.error(str(err)) > self.verify(len(verification_errors) =3D=3D 0, "See previous out= put") >=20 > + self.tester.send_expect("quit", "#") > + self.dut.send_expect("stop", "testpmd>") > + > + def test_hardware_checksum_check_l4_tx(self): > + self.checksum_enablehw(self.dut_ports[0]) > + self.dut.send_expect("start", "testpmd>") > + > + verification_errors: List[VerifyFailure] =3D [] > + > + iface =3D > self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0])) > + dut_mac =3D self.dut.get_mac_address(self.dut_ports[0]) > + tester_mac =3D > + self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0])) > + > + packets =3D self.get_packets(dut_mac, tester_mac) > + > + capture_file_name =3D > "test_hardware_checksum_check_l4_tx_capture.pcap" > + > + packet_file_path =3D > "/tmp/test_hardware_checksum_check_l4_tx_packets.pcap" > + capture_file_path =3D "/tmp/tester/" + capture_file_name > + > + self.tester.send_expect(f"tcpdump -i {iface} -s 65535 -w > + {capture_file_path} &", "# ") > + > + wrpcap(packet_file_path, packets) > + self.tester.session.copy_file_to(packet_file_path, > + packet_file_path) > + > + self.replay_pcap_file_on_tester(iface, packet_file_path) > + > + self.tester.session.copy_file_from(packet_file_path, > + "output/tmp/pcap/" + capture_file_name) > + > + captured_packets =3D rdpcap("output/tmp/pcap/" + > + capture_file_name) > + > + self.verify(len(packets) =3D=3D len(captured_packets), "Not all > + packets were received") > + > + error_messages =3D > + self.validate_packet_list_checksums(captured_packets) > + > self.dut.send_expect("stop", "testpmd>") > + if len(error_messages) !=3D 0: > + for error_msg in error_messages: > + self.logger.error(error_msg) > + self.verify(False, "See prior output") >=20 > def tear_down(self): > """ > -- > 2.25.1