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 C9C70A0526; Fri, 24 Jul 2020 14:43:49 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id BD3031BFE7; Fri, 24 Jul 2020 14:43:49 +0200 (CEST) Received: from mail-qv1-f53.google.com (mail-qv1-f53.google.com [209.85.219.53]) by dpdk.org (Postfix) with ESMTP id 016841BFE3 for ; Fri, 24 Jul 2020 14:43:47 +0200 (CEST) Received: by mail-qv1-f53.google.com with SMTP id y11so1065841qvl.4 for ; Fri, 24 Jul 2020 05:43:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=I2zZDBvST5jItuo1Bdh1191Lwa76G7zWT2ReR3KJeTk=; b=VgqUtwl0g7hCVc23lGmk6QrEODHtSx7xhwhbfXqkwz6atY1NtR0dfZQ6+p0zs+Z9YM 2T2RDMl89FxamXNNp8vD/ZVgmoz/gL43oFV/3CxP3HLGjktXm3rxRaxzStDjsmYwEMZw ifBbnhnHRVDvK8wifmL63VfQmLZs8qGEjmKlY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=I2zZDBvST5jItuo1Bdh1191Lwa76G7zWT2ReR3KJeTk=; b=HOUrS0FusOixTGqU3jotqjJO6QNFcAxqLZ0YCynzBZ0LBanyshE84DeZKZDkqzoO03 3dIWqD/4J8N2Vi/2P64nlrHSqzcK1/qa0/CO6iHp6Uf7LI1ov9NBpPp3gl4KDx3TnTXV jZMQVmYIlm2yWA63htA4XxEy4DUF9fL+ZCD+exaeiVk8yXSX4G1LON2uFPAJCodpoP9c t/Bspq/ZMXQ5GZlDH4FOQELh8JrVyCGQ8/tWbCOSv5c76NuHX1sDr69qgl8jsyrFZYM6 Hlp6aWQRqoT/O5gjoWgFxhRPy4ZWBM1kVyP71GnIv2kMdjwg61FGg9GzPcH6HcpnESxE 4JRg== X-Gm-Message-State: AOAM530wclpz9+TwcTG/TFozfA5aC7hXGYPT0Yrvq0V4mdJa0vrkDQ1n CiiFp4IX+TZYtOPC3zb9MoY/BBOCOP5Ujs5c6cM07Q== X-Google-Smtp-Source: ABdhPJxsyzGtO8nS3ioRAdFIdr2Wo2Ov6cnmJCw/OLsyJPdI9GPYSMFe/YDVOMBiIJDRYh1OWxmqsnXQRuiD5cLmiV8= X-Received: by 2002:a0c:e252:: with SMTP id x18mr9476270qvl.30.1595594627200; Fri, 24 Jul 2020 05:43:47 -0700 (PDT) MIME-Version: 1.0 References: <20200714145355.18410-1-ohilyard@iol.unh.edu> <20200720140744.210132-1-ohilyard@iol.unh.edu> <8CE3E05A3F976642AAB0F4675D0AD20E0BC84184@SHSMSX101.ccr.corp.intel.com> In-Reply-To: <8CE3E05A3F976642AAB0F4675D0AD20E0BC84184@SHSMSX101.ccr.corp.intel.com> From: Owen Hilyard Date: Fri, 24 Jul 2020 08:43:11 -0400 Message-ID: To: "Tu, Lijuan" Cc: "dts@dpdk.org" , "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" Content-Type: multipart/alternative; boundary="000000000000f5d56005ab2f52ac" 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" --000000000000f5d56005ab2f52ac Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Unfortunately I had to start a new email thread since intel's server didn't like the self-signed certificate on my local mail server. I merged all of the patches into one patch so it's a little easier to review for the second time. On Thu, Jul 23, 2020 at 10:45 PM Tu, Lijuan wrote: > Is the patch based on the latest DTS ? sorry, I can't merge it because of > code 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=E5=B9=B47=E6=9C=8820=E6=97=A5 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 > cases > > > > add rx and tx l3 test cases > > add tx l4 test case > > add documentation for new test cases > > > > 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(-) > > > > 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. > > > > Check the Rx checksum flags consistent with expected flags. > > > > -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 > combined > > @@ -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=3D= 8 > > 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. > > \ 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=3D= 32 > > + 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=3D= 8 > > 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=3D= 8 > > 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 an= d > > +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=3D= 32 > > + 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=3D= 8 > > 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=3D= 8 > > 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=3D= 32 > > + 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=3D= 8 > > 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=3D= 8 > > 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 > > > > 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 > import > > DRIVER_TEST_LACK_CAPA from pktgen import PacketGeneratorHelper @@ - > > 57,6 +67,33 @@ import packet > > > > from settings import FOLDERS > > > > +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", > > +] > > + > > > > class TestChecksumOffload(TestCase): > > > > @@ -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() > > > > 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}, > please run > > test_rx_checksum_valid_flags.") @@ -269,11 +303,147 @@ class > > TestChecksumOffload(TestCase): > > > > return None > > > > - 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 > > > > - def scapy_send_append(self, packet: str): > > - return self.tester.scapy_append(f'sendp({packet}, iface=3Difac= e)') > > + 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 th= e > 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 > headers > > + 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= else > outer_arg["chksum"]},' > > + f'{" " if len(inner_arg.values()) =3D=3D 0= else > inner_arg["chksum"]}' > > + ) > > + # Prevents the default behavior which adds DNS > headers > > + 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(chksum.values()) =3D=3D > > 0 else chksum["chksum"]}' > > + ) > > + > > + # Prevents the default behavior which adds DNS > headers > > + 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 st= ate > > for %s/%s with a %s checksum." > > + > > + vxlan_error_message =3D f"Invalid VXLAN tunnelled %s checksum > state > > for %s/%s" \ > > + f" with a %s inner checksum and a %s > outer checksum." > > + > > + gre_error_message =3D f"Invalid GRE tunnelled checksum state f= or > %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 > > > > # > > # > > @@ -448,6 +618,9 @@ class TestChecksumOffload(TestCase): > > > > # 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 > functional tests > > to use scapy. > > + self.pktgen_helper =3D PacketGeneratorHelper() > > # run packet generator > > streams =3D > self.pktgen_helper.prepare_stream_from_tginput(tgenInput, > > 100, > > None, self.tester.pktgen) @@ -511,53 +684,93 @@ > class > > TestChecksumOffload(TestCase): > > self.dut.send_expect("quit", "#", 10) > > self.result_table_print() > > > > - 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>") > > > > verification_errors: List[VerifyFailure] =3D [] > > > > - # 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])) > > > > - # 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'{tester_mac}')") > > + self.scapy_exec(f"iface =3D '{iface}'") > > > > - # 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_failure( > > + 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) > > > > - self.verify(len(verification_errors) =3D=3D 0, > "\n".join(verification_errors)) > > + for err in verification_errors: > > + self.logger.error(str(err)) > > + self.verify(len(verification_errors) =3D=3D 0, "See previous > > + output") > > > > + self.tester.send_expect("quit()", "# ") > > self.dut.send_expect("stop", "testpmd>") > > > > - 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>") > > > > verification_errors: List[VerifyFailure] =3D [] > > > > - 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) > > > > - 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 > > ] > > > > + 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 al= l > > + 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_flag_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) > > > > @@ -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) > > > > @@ -615,6 +827,8 @@ class TestChecksumOffload(TestCase): > > # updated this test case can easily take advantage of the new > functionality. > > > > # # GENEVE > > + # # This import is over here so that it is not forgotten when > the 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 > output") > > > > + 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 al= l > > + 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") > > > > def tear_down(self): > > """ > > -- > > 2.25.1 > > --000000000000f5d56005ab2f52ac Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Unfortunately I had to start a new email thread since inte= l's server didn't like the self-signed certificate on my local mail= server. I merged all of the patches into one patch so it's a little ea= sier to review for the second time.=C2=A0

On Thu, Jul 23, 2020 at 10:45 PM T= u, Lijuan <lijuan.tu@intel.com> wrote:
Is = the patch based on the latest DTS ? sorry, I can't merge it because of = code conflict. Could you please rework it. Btw, all patches, v1/v2... shoul= d be based on latest DTS.

Thanks, Lijuan.

> -----Original Message-----
> From: dts <
dts-bounces@dpdk.org> On Behalf Of Owen Hilyard
> Sent: 2020=E5=B9=B47=E6=9C=8820=E6=97=A5 22:08
> To: dts@dpdk.org=
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; arybchenko@solarflare.com;
> olivier.ma= tz@6wind.com; david.marchand@redhat.com;
> ivan.malo= v@oktetlabs.ru; Richardson, Bruce <bruce.richardson@intel.com>;
> lylavoie@iol= .unh.edu; ras= land@mellanox.com; j.hendergart@f5.com;
> ohilyard@iol= .unh.edu; thom= as@monjalon.net
> Subject: [dts] [PATCH] checksum checks: Add hardware offload l3 and l4= cases
>
> add rx and tx l3 test cases
> add tx l4 test case
> add documentation for new test cases
>
> Signed-off-by: Owen Hilyard <ohilyard@iol.unh.edu>
> ---
>=C2=A0 test_plans/checksum_offload_test_plan.rst | 122 +++++++-
>=C2=A0 tests/TestSuite_checksum_offload.py=C2=A0 =C2=A0 =C2=A0 =C2=A0| = 331 +++++++++++++++++++---
>=C2=A0 2 files changed, 412 insertions(+), 41 deletions(-)
>
> 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.
>
>=C2=A0 Check the Rx checksum flags consistent with expected flags.
>
> -Test Case: Hardware Checksum Check L4
> +Test Case: Hardware Checksum Check L4 RX
>=C2=A0 =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
>=C2=A0 This test involves testing many different scenarios with a L4 ch= ecksum.
>=C2=A0 A variety of tunneling protocols, L3 protocols and L4 protocols = are combined
> @@ -256,4 +256,122 @@ Send a packet with a bad checksum::
>=C2=A0 =C2=A0 =C2=A0rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_prot= o=3D17 l4_len=3D8
> flags=3DPKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_BAD
> PKT_RX_OUTER_L4_CKSUM_UNKNOWN
>=C2=A0 =C2=A0 =C2=A0tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4
>
> -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::
> +
> +=C2=A0 testpmd> set fwd csum
> +=C2=A0 Set csum packet forwarding mode
> +
> +Start the packet forwarding::
> +
> +=C2=A0 testpmd> start
> +=C2=A0 =C2=A0 csum packet forwarding - CRC stripping disabled - packe= ts/burst=3D32
> +=C2=A0 =C2=A0 nb forwarding cores=3D1 - nb forwarding ports=3D10
> +=C2=A0 =C2=A0 RX queues=3D1 - RX desc=3D128 - RX free threshold=3D64<= br> > +=C2=A0 =C2=A0 RX threshold registers: pthresh=3D8 hthresh=3D8 wthresh= =3D4
> +=C2=A0 =C2=A0 TX queues=3D1 - TX desc=3D512 - TX free threshold=3D0 > +=C2=A0 =C2=A0 TX threshold registers: pthresh=3D32 hthresh=3D8 wthres= h=3D8
> +
> +Send a packet with a good checksum::
> +
> +=C2=A0 =C2=A0port=3D0, mbuf=3D0x2269df8780, pkt_len=3D96, nb_segs=3D1= :
> +=C2=A0 =C2=A0rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D1= 7 l4_len=3D8
> flags=3DPKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD
> PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> +=C2=A0 =C2=A0tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4
> +
> +Send a packet with a bad checksum::
> +
> +=C2=A0 =C2=A0port=3D0, mbuf=3D0x2269df7e40, pkt_len=3D96, nb_segs=3D1= :
> +=C2=A0 =C2=A0rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D1= 7 l4_len=3D8
> flags=3DPKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_BAD
> PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> +=C2=A0 =C2=A0tx: 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 checksu= m.
> +A variety of tunneling protocols, L3 protocols and L4 protocols are > +combined to test as many scenarios as possible. Currently, UDP, TCP a= nd
> +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 t= o
> +determine whether the hardware offloading of checksums works properly= .
> +
> +Setup the ``csum`` forwarding mode::
> +
> +=C2=A0 testpmd> set fwd csum
> +=C2=A0 Set csum packet forwarding mode
> +
> +Start the packet forwarding::
> +
> +=C2=A0 testpmd> start
> +=C2=A0 =C2=A0 csum packet forwarding - CRC stripping disabled - packe= ts/burst=3D32
> +=C2=A0 =C2=A0 nb forwarding cores=3D1 - nb forwarding ports=3D10
> +=C2=A0 =C2=A0 RX queues=3D1 - RX desc=3D128 - RX free threshold=3D64<= br> > +=C2=A0 =C2=A0 RX threshold registers: pthresh=3D8 hthresh=3D8 wthresh= =3D4
> +=C2=A0 =C2=A0 TX queues=3D1 - TX desc=3D512 - TX free threshold=3D0 > +=C2=A0 =C2=A0 TX threshold registers: pthresh=3D32 hthresh=3D8 wthres= h=3D8
> +
> +
> +Start a packet capture on the tester in the backround::
> +
> +=C2=A0 =C2=A0# tcpdump -i <iface> -s 65535 -w
> + /tmp/tester/test_hardware_checksum_check_l4_tx_capture.pcap & > +
> +Send a packet with a good checksum::
> +
> +=C2=A0 =C2=A0port=3D0, mbuf=3D0x2269df8780, pkt_len=3D96, nb_segs=3D1= :
> +=C2=A0 =C2=A0rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D1= 7 l4_len=3D8
> flags=3DPKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD
> PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> +=C2=A0 =C2=A0tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4
> +
> +Send a packet with a bad checksum::
> +
> +=C2=A0 =C2=A0port=3D0, mbuf=3D0x2269df7e40, pkt_len=3D96, nb_segs=3D1= :
> +=C2=A0 =C2=A0rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D1= 7 l4_len=3D8
> flags=3DPKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_GOOD
> PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> +=C2=A0 =C2=A0tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4
> +
> +Inspect the pcap file from the packet capture and verify the checksum= s.
> +
> +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::
> +
> +=C2=A0 testpmd> set fwd csum
> +=C2=A0 Set csum packet forwarding mode
> +
> +Start the packet forwarding::
> +
> +=C2=A0 testpmd> start
> +=C2=A0 =C2=A0 csum packet forwarding - CRC stripping disabled - packe= ts/burst=3D32
> +=C2=A0 =C2=A0 nb forwarding cores=3D1 - nb forwarding ports=3D10
> +=C2=A0 =C2=A0 RX queues=3D1 - RX desc=3D128 - RX free threshold=3D64<= br> > +=C2=A0 =C2=A0 RX threshold registers: pthresh=3D8 hthresh=3D8 wthresh= =3D4
> +=C2=A0 =C2=A0 TX queues=3D1 - TX desc=3D512 - TX free threshold=3D0 > +=C2=A0 =C2=A0 TX threshold registers: pthresh=3D32 hthresh=3D8 wthres= h=3D8
> +
> +
> +Start a packet capture on the tester in the backround::
> +
> +=C2=A0 =C2=A0# tcpdump -i <iface> -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::
> +
> +=C2=A0 =C2=A0port=3D0, mbuf=3D0x2269df8780, pkt_len=3D96, nb_segs=3D1= :
> +=C2=A0 =C2=A0rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D1= 7 l4_len=3D8
> flags=3DPKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD
> PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> +=C2=A0 =C2=A0tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4
> +
> +Send a packet with a bad checksum with a 0 in it's payload::
> +
> +=C2=A0 =C2=A0port=3D0, mbuf=3D0x2269df7e40, pkt_len=3D96, nb_segs=3D1= :
> +=C2=A0 =C2=A0rx: l2_len=3D18 ethertype=3D800 l3_len=3D20 l4_proto=3D1= 7 l4_len=3D8
> flags=3DPKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_BAD
> PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> +=C2=A0 =C2=A0tx: flags=3DPKT_TX_L4_NO_CKSUM PKT_TX_IPV4
> +
> +Inspect the pcap file from the packet capture and verify the checksum= s.
> 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
>
>=C2=A0 from rst import RstReport
>=C2=A0 import utils
> -
> +from exception import VerifyFailure
> +from pktgen import PacketGeneratorHelper from scapy.layers.inet impor= t
> +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
>=C2=A0 from test_case import TestCase
> +
>=C2=A0 from framework.pmd_output import PmdOutput=C2=A0 from test_capab= ilities import
> DRIVER_TEST_LACK_CAPA=C2=A0 from pktgen import PacketGeneratorHelper @= @ -
> 57,6 +67,33 @@ import packet
>
>=C2=A0 from settings import FOLDERS
>
> +l3_proto_classes =3D [
> +=C2=A0 =C2=A0 IP,
> +=C2=A0 =C2=A0 IPv6
> +]
> +
> +l4_proto_classes =3D [
> +=C2=A0 =C2=A0 UDP,
> +=C2=A0 =C2=A0 TCP,
> +=C2=A0 =C2=A0 SCTP
> +]
> +
> +tunnelling_proto_classes =3D [
> +=C2=A0 =C2=A0 VXLAN,
> +=C2=A0 =C2=A0 GRE,
> +]
> +
> +l3_protos =3D [
> +=C2=A0 =C2=A0 "IP",
> +=C2=A0 =C2=A0 "IPv6"
> +]
> +
> +l4_protos =3D [
> +=C2=A0 =C2=A0 "UDP",
> +=C2=A0 =C2=A0 "TCP",
> +=C2=A0 =C2=A0 "SCTP",
> +]
> +
>
>=C2=A0 class TestChecksumOffload(TestCase):
>
> @@ -79,8 +116,6 @@ class TestChecksumOffload(TestCase):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cur_path =3D os.path.d= irname(
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 os.path.= dirname(os.path.realpath(__file__)))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.output_path =3D o= s.sep.join([cur_path, self.logger.log_path])
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 # create an instance to set stream field = setting
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.pktgen_helper =3D PacketGeneratorHel= per()
>
>=C2=A0 =C2=A0 =C2=A0 def set_up(self):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 """
> @@ -243,7 +278,6 @@ class TestChecksumOffload(TestCase):
>=C2=A0 =C2=A0 =C2=A0 def send_pkt_expect_good_bad_from_flag(self, pkt_s= tr: str, flag: str,
> test_name: str, should_pass: bool =3D True):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.pmdout.get_output(timeout=3D5)= =C2=A0 # Remove any old output
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.scapy_exec(f"sendp({pkt_st= r}, iface=3Diface)")
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 time.sleep(1)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 testpmd_output: str =3D self.pmdout.= get_output(timeout=3D5)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.verify(flag in testpmd_output,<= br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 f"Flag {flag[:-1]} not found for test {test_name}, please run > test_rx_checksum_valid_flags.") @@ -269,11 +303,147 @@ class
> TestChecksumOffload(TestCase):
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return None
>
> -=C2=A0 =C2=A0 def scapy_exec(self, cmd: str):
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 return self.tester.send_expect(cmd, "= ;>>>")
> +=C2=A0 =C2=A0 def validate_checksum(self, pkt, layer) -> bool:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 """
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 @param pkt: The packet to validate the ch= ecksum of.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 @return: Whether the checksum was valid.<= br> > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 """
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if pkt is None:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return False
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 csum =3D pkt[layer].chksum
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 del pkt[layer].chksum
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # Converting it to raw will calculate the= checksum
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return layer(Raw(pkt[layer])).chksum =3D= =3D csum
>
> -=C2=A0 =C2=A0 def scapy_send_append(self, packet: str):
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 return self.tester.scapy_append(f'sen= dp({packet}, iface=3Diface)')
> +=C2=A0 =C2=A0 def scapy_exec(self, cmd: str, timeout=3D1) -> str:<= br> > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return self.tester.send_expect(cmd, "= ;>>>", timeout=3Dtimeout)
> +
> +=C2=A0 =C2=A0 def get_packets(self, dut_mac, tester_mac):
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 eth =3D Ether(dst=3Ddut_mac, src=3Dtester= _mac)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 packets =3D []
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 checksum_options =3D ({}, {'chksum= 9;: 0xf},)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # Untunneled
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for l3 in l3_proto_classes:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for l4 in l4_proto_classes:=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for chksum in= checksum_options:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= # The packet's data can be used to identify how the packet was
> constructed so avoid any issues with
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= # ordering
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= pkt =3D eth / l3() / l4(**chksum) / (
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 f'UNTUNNELED,{l3.__name__},{l4.__name__},{" " = if
> len(chksum.values()) =3D=3D 0 else chksum["chksum"]}' > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= )
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= # Prevents the default behavior which adds DNS headers
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= if l4 =3D=3D UDP:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 pkt[UDP].dport, pkt[UDP].sport =3D 1001, 1001
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= packets.append(pkt)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # Tunneled
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # VXLAN
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for l3 in l3_proto_classes:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for l4 in l4_proto_classes:=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for outer_arg= in checksum_options:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= for inner_arg in checksum_options:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 pkt =3D eth / l3() / UDP(**outer_arg) / VXLAN() / Ether() / = l3() /
> l4(**inner_arg) / (
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 f'VXLAN,{l3.__name__},{l4.__name__},'<= br> > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 f'{" " if len(outer_arg.values()= ) =3D=3D 0 else outer_arg["chksum"]},'
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 f'{" " if len(inner_arg.values()= ) =3D=3D 0 else inner_arg["chksum"]}'
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 # Prevents the default behavior which adds DNS headers
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 if l4 =3D=3D UDP:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 pkt[VXLAN][UDP].dport,
> + pkt[VXLAN][UDP].sport =3D 1001, 1001
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 packets.append(pkt)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # GRE
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for l3 in l3_proto_classes:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for l4 in l4_proto_classes:=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for chksum in= checksum_options:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= pkt =3D eth / l3() / GRE() / l3() / l4(**chksum) / (
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 f'GRE,{l3.__name__},{l4.__name__},{" " if len(= chksum.values()) =3D=3D
> 0 else chksum["chksum"]}'
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= )
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= # Prevents the default behavior which adds DNS headers
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= if l4 =3D=3D UDP:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 pkt[GRE][UDP].dport, pkt[GRE][UDP].sport =3D
> + 1001, 1001
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= packets.append(pkt)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return packets
> +
> +=C2=A0 =C2=A0 def replay_pcap_file_on_tester(self, iface, packet_file= _path):
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.send_expect("scapy"= , ">>>")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.scapy_exec(f"packets =3D rdpcap= ('{packet_file_path}')")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.scapy_exec(f"sendp(packets, ifa= ce=3D{iface})")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.send_expect("quit()"= ;, "# ")
> +
> +=C2=A0 =C2=A0 def validate_packet_list_checksums(self, packets):
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 name_to_class_dict =3D {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'UDP': UDP,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'TCP': TCP,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'SCTP': SCTP,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'IP': IP,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'IPv6': IPv6,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'VXLAN': VXLAN,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'GRE': GRE,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 error_messages =3D []
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 untunnelled_error_message =3D f"Inva= lid untunneled checksum state
> for %s/%s with a %s checksum."
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 vxlan_error_message =3D f"Invalid VX= LAN tunnelled %s checksum state
> for %s/%s" \
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f" with a %s inner checksum and a = %s outer checksum."
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 gre_error_message =3D f"Invalid GRE = tunnelled checksum state for %s/%s
> with a %s checksum."
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for packet in packets:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 payload: str
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # try:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 payload =3D packet[Raw].loa= d.decode('utf-8').split(",")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # # This error usually happ= ens with tunneling protocols, and means that
> an additional cast is needed
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # except UnicodeDecodeError= :
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #=C2=A0 =C2=A0 =C2=A0for pr= oto in tunnelling_proto_classes:
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 l3 =3D name_to_class_dict[p= ayload[1]]
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 l4 =3D name_to_class_dict[p= ayload[2]]
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if payload[0] =3D=3D "= UNTUNNELED":
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 chksum_should= _be_valid =3D payload[3] =3D=3D " "
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if self.valid= ate_checksum(packet, l4) !=3D chksum_should_be_valid:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= error_messages.append(
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 untunnelled_error_message % (
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 l3.__name__, l4.__name__, 'valid' if c= hksum_should_be_valid
> =3D=3D '' else 'invalid'
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 elif payload[0] =3D=3D &quo= t;VXLAN":
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 outer_chksum_= should_be_valid =3D payload[3] =3D=3D " "
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 inner_chksum_= should_be_valid =3D payload[4] =3D=3D " "
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if self.valid= ate_checksum(packet[VXLAN], l4) !=3D
> inner_chksum_should_be_valid:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= error_messages.append(
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 vxlan_error_message % (
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 "inner", l4.__name__, l3.__name__, > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 'valid' if inner_chksum_should_be_vali= d =3D=3D '' else 'invalid',
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 'valid' if outer_chksum_should_be_vali= d =3D=3D '' else 'invalid'
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if self.valid= ate_checksum(packet, l4) !=3D
> outer_chksum_should_be_valid:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= error_messages.append(
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 vxlan_error_message % (
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 "outer", l3.__name__, l4.__name__, > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 'valid' if inner_chksum_should_be_vali= d =3D=3D '' else 'invalid',
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 'valid' if outer_chksum_should_be_vali= d =3D=3D '' else 'invalid'
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 elif payload[0] =3D=3D &quo= t;GRE":
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 chksum_should= _be_valid =3D payload[3] =3D=3D " "
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if self.valid= ate_checksum(packet, l4) !=3D chksum_should_be_valid:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= error_messages.append(
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 gre_error_message % (
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 l3.__name__, l4.__name__, 'valid' if c= hksum_should_be_valid
> =3D=3D '' else 'invalid'
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= )
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return error_messages
>
>=C2=A0 =C2=A0 =C2=A0 #
>=C2=A0 =C2=A0 =C2=A0 #
> @@ -448,6 +618,9 @@ class TestChecksumOffload(TestCase):
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # clear streams before= add new streams
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.pktgen.cle= ar_streams()
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # create an instance to set= stream field setting
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # Moved here because it mes= ses with the ability of the functional tests
> to use scapy.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.pktgen_helper =3D Pack= etGeneratorHelper()
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # run packet generator=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 streams =3D self.pktge= n_helper.prepare_stream_from_tginput(tgenInput,
> 100,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 None, self.tester.pktgen) @@ -511,53 +684,93 @@ class
> TestChecksumOffload(TestCase):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.dut.send_expect(&= quot;quit", "#", 10)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.result_table_prin= t()
>
> -=C2=A0 =C2=A0 def test_hardware_checksum_check_ip(self):
> +=C2=A0 =C2=A0 def test_hardware_checksum_check_ip_rx(self):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.dut.send_expect("start&quo= t;, "testpmd>")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.send_expect("scapy"= , ">>>")
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.checksum_enablehw(self.dut_port= s[0])
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.dut.send_expect("start", &= quot;testpmd>")
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 verification_errors: List[VerifyFail= ure] =3D []
>
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 # untunnelled
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 vf =3D
> self.try_helper_hardware_checksum_check_catch_failure('Ether(dst= =3D"%s",
> src=3D"%s")/IP(%s)/UDP()/("X"*50)',
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0"PKT_RX_IP_CKSUM_")
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 if vf is not None:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 verification_errors.append(= vf)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 iface =3D
> self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]= ))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 dut_mac =3D self.dut.get_mac_address(self= .dut_ports[0])
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 tester_mac =3D
> + self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0])) >
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 # tunneled inner
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 vf =3D self.try_helper_hardware_checksum_= check_catch_failure(
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'Ether(dst=3D"%s&q= uot;, src=3D"%s")/IP()/UDP()/IP(%s)/("X"*50)',
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "PKT_RX_OUTER_IP_CKSUM= _")
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 if vf is not None:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 verification_errors.append(= vf)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.scapy_exec(f"eth =3D Ether(dst= =3D'{dut_mac}', src=3D'{tester_mac}')")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.scapy_exec(f"iface =3D '{if= ace}'")
>
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 # tunneled outer
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 vf =3D self.try_helper_hardware_checksum_= check_catch_failure(
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'Ether(dst=3D"%s&q= uot;, src=3D"%s")/IP()/UDP()/IP(%s)/("X"*50)',
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "PKT_RX_OUTER_IP_CKSUM= _")
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 if vf is not None:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 verification_errors.append(= vf)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # Untunnelled
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for l4 in l4_protos:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for chksum in "",= "chksum=3D0xf":
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 vf =3D self.s= end_pkt_expect_good_bad_from_flag_catch_failure(
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= f"eth/IP({chksum})/{l4}()/(X'*50)",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= "PKT_RX_IP_CKSUM_", f"{l4}",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= should_pass=3D(chksum =3D=3D ""))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if vf is not = None:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= verification_errors.append(vf)
>
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.verify(len(verification_errors) =3D= =3D 0, "\n".join(verification_errors))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for err in verification_errors:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.logger.error(str(err))=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.verify(len(verification_errors) =3D= =3D 0, "See previous
> + output")
>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.send_expect("quit()"= ;, "# ")
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.dut.send_expect("stop"= ;, "testpmd>")
>
> -=C2=A0 =C2=A0 def test_hardware_checksum_check_l4(self):
> +=C2=A0 =C2=A0 def test_hardware_checksum_check_ip_tx(self):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.checksum_enablehw(self.dut_port= s[0])
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.dut.send_expect("start&quo= t;, "testpmd>")
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 verification_errors: List[VerifyFail= ure] =3D []
>
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 l3_protos: List[str] =3D [
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "IP",
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "IPv6"
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ]
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 iface =3D
> self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]= ))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 dut_mac =3D self.dut.get_mac_address(self= .dut_ports[0])
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 tester_mac =3D
> self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0]))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 eth =3D Ether(dst=3Ddut_mac, src=3Dtester= _mac)
>
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 l4_protos: List[str] =3D [
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "UDP",
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "TCP",
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "SCTP",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 checksum_options =3D ({}, {'chksum= 9;: 0xf},)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 packets =3D [
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 eth / IP(**chksum) / TCP() = / Raw(load=3Dstr(int(len(chksum)
> + !=3D 1))) for chksum in checksum_options
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ]
>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 capture_file_name =3D
> "test_hardware_checksum_check_l3_tx_capture.pcap"
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 packet_file_path =3D
> "/tmp/test_hardware_checksum_check_l3_tx_packets.pcap"
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 capture_file_path =3D "/tmp/tester/&= quot; + capture_file_name
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.send_expect(f"tcpdump -i= {iface} -s 65535 -w
> + {capture_file_path} &", "# ")
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 wrpcap(packet_file_path, packets)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.session.copy_file_to(packet_f= ile_path,
> + packet_file_path)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.replay_pcap_file_on_tester(iface, pa= cket_file_path)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.session.copy_file_from(packet= _file_path,
> + "output/tmp/pcap/" + capture_file_name)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 captured_packets =3D rdpcap("output/= tmp/pcap/" +
> + capture_file_name)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.verify(len(packets) =3D=3D len(captu= red_packets), "Not all
> + packets were received")
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 error_messages =3D []
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for pkt in captured_packets:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 should_pass =3D pkt[TCP].pa= yload.build() =3D=3D b'1'
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if not (self.validate_check= sum(pkt, IP) =3D=3D should_pass):
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 error_message= s.append(f"A packet was marked as having a"
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"{= 9; valid' if should_pass =3D=3D '' else 'n invalid'}&qu= ot;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f" che= cksum when it should have
> + had the opposite.")
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.dut.send_expect("stop", &q= uot;testpmd>")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if len(error_messages) !=3D 0:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for error_msg in error_mess= ages:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.logger.e= rror(error_msg)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.verify(False, "Se= e prior output")
> +
> +=C2=A0 =C2=A0 def test_hardware_checksum_check_l4_rx(self):
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.checksum_enablehw(self.dut_ports[0])=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.dut.send_expect("start", &= quot;testpmd>")
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 verification_errors: List[VerifyFailure] = =3D []
> +
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iface =3D
> self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]= ))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dut_mac =3D self.dut.get_mac_address= (self.dut_ports[0])
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tester_mac =3D
> self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0]))
> @@ -589,7 +802,7 @@ class TestChecksumOffload(TestCase):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 should_pass =3D outer_arg = =3D=3D ""
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 vf =3D self.send_pkt_expect_good_bad_fro= m_flag_catch_failure(
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"eth/{l3}()/{l4}({ou= ter_arg})/VXLAN()/{l3}()/"
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"{l4}({inner_arg})/('X= '*50)",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"{l4}(chksum=3D{inner_arg}= )/('X'*50)",
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 flag, f"{l3}/{l4}/VXL= AN/{l3}/{l4}",
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 should_pass=3Dshould_pass)=
>
> @@ -602,8 +815,7 @@ class TestChecksumOffload(TestCase):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for inne= r_arg in "", "chksum=3D0xf":
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 should_pass: bool =3D inner_arg =3D=3D ""
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 vf =3D self.send_pkt_expect_good_bad_from_flag_catch_failure(
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 f"eth/{l3}()/GRE()/{l3}()/"
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 f"{l4}({inner_arg})/('X'*50)",
> +
> + f"eth/{l3}()/GRE()/{l3}()/{l4}({inner_arg})/('X'*50)&qu= ot;,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 "PKT_RX_L4_CKSUM_", f"{l3}/GRE/{l3}/{l4= }",
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 should_pass=3Dshould_pass)
>
> @@ -615,6 +827,8 @@ class TestChecksumOffload(TestCase):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # updated this test case can easily = take advantage of the new functionality.
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # # GENEVE
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # # This import is over here so that it i= s not forgotten when the update
> happens
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # from scapy.contrib.geneve import GENEVE=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # for l3_outer in l3_protos:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #=C2=A0 =C2=A0 =C2=A0for l4_outer in= l4_protos:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f= or l3_inner in l3_protos:
> @@ -638,7 +852,46 @@ class TestChecksumOffload(TestCase):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.logger.error(str(= err))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.verify(len(verification_errors)= =3D=3D 0, "See previous output")
>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.send_expect("quit",= "#")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.dut.send_expect("stop", &q= uot;testpmd>")
> +
> +=C2=A0 =C2=A0 def test_hardware_checksum_check_l4_tx(self):
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.checksum_enablehw(self.dut_ports[0])=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.dut.send_expect("start", &= quot;testpmd>")
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 verification_errors: List[VerifyFailure] = =3D []
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 iface =3D
> self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]= ))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 dut_mac =3D self.dut.get_mac_address(self= .dut_ports[0])
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 tester_mac =3D
> + self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0])) > +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 packets =3D self.get_packets(dut_mac, tes= ter_mac)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 capture_file_name =3D
> "test_hardware_checksum_check_l4_tx_capture.pcap"
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 packet_file_path =3D
> "/tmp/test_hardware_checksum_check_l4_tx_packets.pcap"
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 capture_file_path =3D "/tmp/tester/&= quot; + capture_file_name
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.send_expect(f"tcpdump -i= {iface} -s 65535 -w
> + {capture_file_path} &", "# ")
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 wrpcap(packet_file_path, packets)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.session.copy_file_to(packet_f= ile_path,
> + packet_file_path)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.replay_pcap_file_on_tester(iface, pa= cket_file_path)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.tester.session.copy_file_from(packet= _file_path,
> + "output/tmp/pcap/" + capture_file_name)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 captured_packets =3D rdpcap("output/= tmp/pcap/" +
> + capture_file_name)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.verify(len(packets) =3D=3D len(captu= red_packets), "Not all
> + packets were received")
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 error_messages =3D
> + self.validate_packet_list_checksums(captured_packets)
> +
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.dut.send_expect("stop"= ;, "testpmd>")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if len(error_messages) !=3D 0:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for error_msg in error_mess= ages:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.logger.e= rror(error_msg)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.verify(False, "Se= e prior output")
>
>=C2=A0 =C2=A0 =C2=A0 def tear_down(self):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 """
> --
> 2.25.1

--000000000000f5d56005ab2f52ac--