test suite reviews and discussions
 help / color / mirror / Atom feed
From: Owen Hilyard <ohilyard@iol.unh.edu>
To: "Tu, Lijuan" <lijuan.tu@intel.com>
Cc: "dts@dpdk.org" <dts@dpdk.org>,
	"Yigit, Ferruh" <ferruh.yigit@intel.com>,
	 "arybchenko@solarflare.com" <arybchenko@solarflare.com>,
	 "olivier.matz@6wind.com" <olivier.matz@6wind.com>,
	 "david.marchand@redhat.com" <david.marchand@redhat.com>,
	 "ivan.malov@oktetlabs.ru" <ivan.malov@oktetlabs.ru>,
	"Richardson, Bruce" <bruce.richardson@intel.com>,
	 "lylavoie@iol.unh.edu" <lylavoie@iol.unh.edu>,
	"rasland@mellanox.com" <rasland@mellanox.com>,
	 "j.hendergart@f5.com" <j.hendergart@f5.com>,
	"thomas@monjalon.net" <thomas@monjalon.net>
Subject: Re: [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases
Date: Fri, 24 Jul 2020 08:43:11 -0400	[thread overview]
Message-ID: <CAHx6DYAUQcNwR52AhM6nxPwPFvyFvRBkmX0RZeto+R66ghE4Dg@mail.gmail.com> (raw)
In-Reply-To: <8CE3E05A3F976642AAB0F4675D0AD20E0BC84184@SHSMSX101.ccr.corp.intel.com>

[-- Attachment #1: Type: text/plain, Size: 28747 bytes --]

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 <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...
> should be based on latest DTS.
>
> Thanks, Lijuan.
>
> > -----Original Message-----
> > From: dts <dts-bounces@dpdk.org> On Behalf Of Owen Hilyard
> > Sent: 2020年7月20日 22:08
> > To: dts@dpdk.org
> > Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; arybchenko@solarflare.com;
> > olivier.matz@6wind.com; david.marchand@redhat.com;
> > ivan.malov@oktetlabs.ru; Richardson, Bruce <bruce.richardson@intel.com>;
> > 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 <ohilyard@iol.unh.edu>
> > ---
> >  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
> >  ===========================================
> >  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=18 ethertype=800 l3_len=20 l4_proto=17 l4_len=8
> > flags=PKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_BAD
> > PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> >     tx: flags=PKT_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
> > +===========================================
> > +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=32
> > +    nb forwarding cores=1 - nb forwarding ports=10
> > +    RX queues=1 - RX desc=128 - RX free threshold=64
> > +    RX threshold registers: pthresh=8 hthresh=8 wthresh=4
> > +    TX queues=1 - TX desc=512 - TX free threshold=0
> > +    TX threshold registers: pthresh=32 hthresh=8 wthresh=8
> > +
> > +Send a packet with a good checksum::
> > +
> > +   port=0, mbuf=0x2269df8780, pkt_len=96, nb_segs=1:
> > +   rx: l2_len=18 ethertype=800 l3_len=20 l4_proto=17 l4_len=8
> > flags=PKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD
> > PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> > +   tx: flags=PKT_TX_L4_NO_CKSUM PKT_TX_IPV4
> > +
> > +Send a packet with a bad checksum::
> > +
> > +   port=0, mbuf=0x2269df7e40, pkt_len=96, nb_segs=1:
> > +   rx: l2_len=18 ethertype=800 l3_len=20 l4_proto=17 l4_len=8
> > flags=PKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_BAD
> > PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> > +   tx: flags=PKT_TX_L4_NO_CKSUM PKT_TX_IPV4
> > +
> > +Verify flags are as expected.
> > +
> > +Test Case: Hardware Checksum Check L4 TX
> > +===========================================
> > +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=32
> > +    nb forwarding cores=1 - nb forwarding ports=10
> > +    RX queues=1 - RX desc=128 - RX free threshold=64
> > +    RX threshold registers: pthresh=8 hthresh=8 wthresh=4
> > +    TX queues=1 - TX desc=512 - TX free threshold=0
> > +    TX threshold registers: pthresh=32 hthresh=8 wthresh=8
> > +
> > +
> > +Start a packet capture on the tester in the backround::
> > +
> > +   # tcpdump -i <iface> -s 65535 -w
> > + /tmp/tester/test_hardware_checksum_check_l4_tx_capture.pcap &
> > +
> > +Send a packet with a good checksum::
> > +
> > +   port=0, mbuf=0x2269df8780, pkt_len=96, nb_segs=1:
> > +   rx: l2_len=18 ethertype=800 l3_len=20 l4_proto=17 l4_len=8
> > flags=PKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD
> > PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> > +   tx: flags=PKT_TX_L4_NO_CKSUM PKT_TX_IPV4
> > +
> > +Send a packet with a bad checksum::
> > +
> > +   port=0, mbuf=0x2269df7e40, pkt_len=96, nb_segs=1:
> > +   rx: l2_len=18 ethertype=800 l3_len=20 l4_proto=17 l4_len=8
> > flags=PKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_GOOD
> > PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> > +   tx: flags=PKT_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
> > +===========================================
> > +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=32
> > +    nb forwarding cores=1 - nb forwarding ports=10
> > +    RX queues=1 - RX desc=128 - RX free threshold=64
> > +    RX threshold registers: pthresh=8 hthresh=8 wthresh=4
> > +    TX queues=1 - TX desc=512 - TX free threshold=0
> > +    TX threshold registers: pthresh=32 hthresh=8 wthresh=8
> > +
> > +
> > +Start a packet capture on the tester in the backround::
> > +
> > +   # 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::
> > +
> > +   port=0, mbuf=0x2269df8780, pkt_len=96, nb_segs=1:
> > +   rx: l2_len=18 ethertype=800 l3_len=20 l4_proto=17 l4_len=8
> > flags=PKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD
> > PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> > +   tx: flags=PKT_TX_L4_NO_CKSUM PKT_TX_IPV4
> > +
> > +Send a packet with a bad checksum with a 0 in it's payload::
> > +
> > +   port=0, mbuf=0x2269df7e40, pkt_len=96, nb_segs=1:
> > +   rx: l2_len=18 ethertype=800 l3_len=20 l4_proto=17 l4_len=8
> > flags=PKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_BAD
> > PKT_RX_OUTER_L4_CKSUM_UNKNOWN
> > +   tx: flags=PKT_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 = [
> > +    IP,
> > +    IPv6
> > +]
> > +
> > +l4_proto_classes = [
> > +    UDP,
> > +    TCP,
> > +    SCTP
> > +]
> > +
> > +tunnelling_proto_classes = [
> > +    VXLAN,
> > +    GRE,
> > +]
> > +
> > +l3_protos = [
> > +    "IP",
> > +    "IPv6"
> > +]
> > +
> > +l4_protos = [
> > +    "UDP",
> > +    "TCP",
> > +    "SCTP",
> > +]
> > +
> >
> >  class TestChecksumOffload(TestCase):
> >
> > @@ -79,8 +116,6 @@ class TestChecksumOffload(TestCase):
> >              cur_path = os.path.dirname(
> >                  os.path.dirname(os.path.realpath(__file__)))
> >              self.output_path = os.sep.join([cur_path,
> self.logger.log_path])
> > -        # create an instance to set stream field setting
> > -        self.pktgen_helper = 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 = True):
> >          self.pmdout.get_output(timeout=5)  # Remove any old output
> >          self.scapy_exec(f"sendp({pkt_str}, iface=iface)")
> > -        time.sleep(1)
> >          testpmd_output: str = self.pmdout.get_output(timeout=5)
> >          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 = pkt[layer].chksum
> > +        del pkt[layer].chksum
> > +        # Converting it to raw will calculate the checksum
> > +        return layer(Raw(pkt[layer])).chksum == csum
> >
> > -    def scapy_send_append(self, packet: str):
> > -        return self.tester.scapy_append(f'sendp({packet}, iface=iface)')
> > +    def scapy_exec(self, cmd: str, timeout=1) -> str:
> > +        return self.tester.send_expect(cmd, ">>>", timeout=timeout)
> > +
> > +    def get_packets(self, dut_mac, tester_mac):
> > +        eth = Ether(dst=dut_mac, src=tester_mac)
> > +        packets = []
> > +        checksum_options = ({}, {'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 = eth / l3() / l4(**chksum) / (
> > +                        f'UNTUNNELED,{l3.__name__},{l4.__name__},{" " if
> > len(chksum.values()) == 0 else chksum["chksum"]}'
> > +                    )
> > +
> > +                    # Prevents the default behavior which adds DNS
> headers
> > +                    if l4 == UDP:
> > +                        pkt[UDP].dport, pkt[UDP].sport = 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 = eth / l3() / UDP(**outer_arg) / VXLAN() /
> Ether() / l3() /
> > l4(**inner_arg) / (
> > +                            f'VXLAN,{l3.__name__},{l4.__name__},'
> > +                            f'{" " if len(outer_arg.values()) == 0 else
> outer_arg["chksum"]},'
> > +                            f'{" " if len(inner_arg.values()) == 0 else
> inner_arg["chksum"]}'
> > +                        )
> > +                        # Prevents the default behavior which adds DNS
> headers
> > +                        if l4 == UDP:
> > +                            pkt[VXLAN][UDP].dport,
> > + pkt[VXLAN][UDP].sport = 1001, 1001
> > +
> > +                        packets.append(pkt)
> > +        # GRE
> > +        for l3 in l3_proto_classes:
> > +            for l4 in l4_proto_classes:
> > +                for chksum in checksum_options:
> > +                    pkt = eth / l3() / GRE() / l3() / l4(**chksum) / (
> > +                        f'GRE,{l3.__name__},{l4.__name__},{" " if
> len(chksum.values()) ==
> > 0 else chksum["chksum"]}'
> > +                    )
> > +
> > +                    # Prevents the default behavior which adds DNS
> headers
> > +                    if l4 == UDP:
> > +                        pkt[GRE][UDP].dport, pkt[GRE][UDP].sport =
> > + 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 = rdpcap('{packet_file_path}')")
> > +        self.scapy_exec(f"sendp(packets, iface={iface})")
> > +        self.tester.send_expect("quit()", "# ")
> > +
> > +    def validate_packet_list_checksums(self, packets):
> > +        name_to_class_dict = {
> > +            'UDP': UDP,
> > +            'TCP': TCP,
> > +            'SCTP': SCTP,
> > +            'IP': IP,
> > +            'IPv6': IPv6,
> > +            'VXLAN': VXLAN,
> > +            'GRE': GRE,
> > +        }
> > +
> > +        error_messages = []
> > +
> > +        untunnelled_error_message = f"Invalid untunneled checksum state
> > for %s/%s with a %s checksum."
> > +
> > +        vxlan_error_message = f"Invalid VXLAN tunnelled %s checksum
> state
> > for %s/%s" \
> > +                              f" with a %s inner checksum and a %s
> outer checksum."
> > +
> > +        gre_error_message = f"Invalid GRE tunnelled checksum state for
> %s/%s
> > with a %s checksum."
> > +
> > +        for packet in packets:
> > +            payload: str
> > +            # try:
> > +            payload = 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 = name_to_class_dict[payload[1]]
> > +            l4 = name_to_class_dict[payload[2]]
> > +            if payload[0] == "UNTUNNELED":
> > +                chksum_should_be_valid = payload[3] == " "
> > +                if self.validate_checksum(packet, l4) !=
> chksum_should_be_valid:
> > +                    error_messages.append(
> > +                        untunnelled_error_message % (
> > +                            l3.__name__, l4.__name__, 'valid' if
> chksum_should_be_valid
> > == '' else 'invalid'
> > +                        )
> > +                    )
> > +            elif payload[0] == "VXLAN":
> > +                outer_chksum_should_be_valid = payload[3] == " "
> > +                inner_chksum_should_be_valid = payload[4] == " "
> > +                if self.validate_checksum(packet[VXLAN], l4) !=
> > inner_chksum_should_be_valid:
> > +                    error_messages.append(
> > +                        vxlan_error_message % (
> > +                            "inner", l4.__name__, l3.__name__,
> > +                            'valid' if inner_chksum_should_be_valid ==
> '' else 'invalid',
> > +                            'valid' if outer_chksum_should_be_valid ==
> '' else 'invalid'
> > +                        )
> > +                    )
> > +                if self.validate_checksum(packet, l4) !=
> > outer_chksum_should_be_valid:
> > +                    error_messages.append(
> > +                        vxlan_error_message % (
> > +                            "outer", l3.__name__, l4.__name__,
> > +                            'valid' if inner_chksum_should_be_valid ==
> '' else 'invalid',
> > +                            'valid' if outer_chksum_should_be_valid ==
> '' else 'invalid'
> > +                        )
> > +                    )
> > +            elif payload[0] == "GRE":
> > +                chksum_should_be_valid = payload[3] == " "
> > +                if self.validate_checksum(packet, l4) !=
> chksum_should_be_valid:
> > +                    error_messages.append(
> > +                        gre_error_message % (
> > +                            l3.__name__, l4.__name__, 'valid' if
> chksum_should_be_valid
> > == '' 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 = PacketGeneratorHelper()
> >              # run packet generator
> >              streams =
> 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] = []
> >
> > -        # untunnelled
> > -        vf =
> > self.try_helper_hardware_checksum_check_catch_failure('Ether(dst="%s",
> > src="%s")/IP(%s)/UDP()/("X"*50)',
> > -
>  "PKT_RX_IP_CKSUM_")
> > -        if vf is not None:
> > -            verification_errors.append(vf)
> > +        iface =
> > self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]))
> > +        dut_mac = self.dut.get_mac_address(self.dut_ports[0])
> > +        tester_mac =
> > + self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0]))
> >
> > -        # tunneled inner
> > -        vf = self.try_helper_hardware_checksum_check_catch_failure(
> > -            'Ether(dst="%s", src="%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 = Ether(dst='{dut_mac}',
> src='{tester_mac}')")
> > +        self.scapy_exec(f"iface = '{iface}'")
> >
> > -        # tunneled outer
> > -        vf = self.try_helper_hardware_checksum_check_catch_failure(
> > -            'Ether(dst="%s", src="%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=0xf":
> > +                vf =
> 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=(chksum == ""))
> > +                if vf is not None:
> > +                    verification_errors.append(vf)
> >
> > -        self.verify(len(verification_errors) == 0,
> "\n".join(verification_errors))
> > +        for err in verification_errors:
> > +            self.logger.error(str(err))
> > +        self.verify(len(verification_errors) == 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] = []
> >
> > -        l3_protos: List[str] = [
> > -            "IP",
> > -            "IPv6"
> > -        ]
> > +        iface =
> > self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]))
> > +        dut_mac = self.dut.get_mac_address(self.dut_ports[0])
> > +        tester_mac =
> > self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0]))
> > +        eth = Ether(dst=dut_mac, src=tester_mac)
> >
> > -        l4_protos: List[str] = [
> > -            "UDP",
> > -            "TCP",
> > -            "SCTP",
> > +        checksum_options = ({}, {'chksum': 0xf},)
> > +
> > +        packets = [
> > +            eth / IP(**chksum) / TCP() / Raw(load=str(int(len(chksum)
> > + != 1))) for chksum in checksum_options
> >          ]
> >
> > +        capture_file_name =
> > "test_hardware_checksum_check_l3_tx_capture.pcap"
> > +
> > +        packet_file_path =
> > "/tmp/test_hardware_checksum_check_l3_tx_packets.pcap"
> > +        capture_file_path = "/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 = rdpcap("output/tmp/pcap/" +
> > + capture_file_name)
> > +
> > +        self.verify(len(packets) == len(captured_packets), "Not all
> > + packets were received")
> > +
> > +        error_messages = []
> > +        for pkt in captured_packets:
> > +            should_pass = pkt[TCP].payload.build() == b'1'
> > +            if not (self.validate_checksum(pkt, IP) == should_pass):
> > +                error_messages.append(f"A packet was marked as having a"
> > +                                      f"{' valid' if should_pass == ''
> else 'n invalid'}"
> > +                                      f" checksum when it should have
> > + had the opposite.")
> > +
> > +        self.dut.send_expect("stop", "testpmd>")
> > +        if len(error_messages) != 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] = []
> > +
> >          iface =
> > self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]))
> >          dut_mac = self.dut.get_mac_address(self.dut_ports[0])
> >          tester_mac =
> > self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0]))
> > @@ -589,7 +802,7 @@ class TestChecksumOffload(TestCase):
> >                                  should_pass = outer_arg == ""
> >                              vf =
> 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={inner_arg})/('X'*50)",
> >                                  flag, f"{l3}/{l4}/VXLAN/{l3}/{l4}",
> >                                  should_pass=should_pass)
> >
> > @@ -602,8 +815,7 @@ class TestChecksumOffload(TestCase):
> >                  for inner_arg in "", "chksum=0xf":
> >                      should_pass: bool = inner_arg == ""
> >                      vf =
> 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=should_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) == 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] = []
> > +
> > +        iface =
> > self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]))
> > +        dut_mac = self.dut.get_mac_address(self.dut_ports[0])
> > +        tester_mac =
> > + self.tester.get_mac(self.tester.get_local_port(self.dut_ports[0]))
> > +
> > +        packets = self.get_packets(dut_mac, tester_mac)
> > +
> > +        capture_file_name =
> > "test_hardware_checksum_check_l4_tx_capture.pcap"
> > +
> > +        packet_file_path =
> > "/tmp/test_hardware_checksum_check_l4_tx_packets.pcap"
> > +        capture_file_path = "/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 = rdpcap("output/tmp/pcap/" +
> > + capture_file_name)
> > +
> > +        self.verify(len(packets) == len(captured_packets), "Not all
> > + packets were received")
> > +
> > +        error_messages =
> > + self.validate_packet_list_checksums(captured_packets)
> > +
> >          self.dut.send_expect("stop", "testpmd>")
> > +        if len(error_messages) != 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
>
>

[-- Attachment #2: Type: text/html, Size: 37192 bytes --]

      reply	other threads:[~2020-07-24 12:43 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-14 14:53 [dts] [PATCH] checksum offload: add hardware checksum checks case Owen Hilyard
2020-07-20 14:07 ` [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases Owen Hilyard
2020-07-20 14:13   ` [dts] [PATCH] checksum hardware checks: fix typo Owen Hilyard
2020-08-12  1:53     ` Ma, LihongX
2020-07-24  2:45   ` [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases Tu, Lijuan
2020-07-24 12:43     ` Owen Hilyard [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAHx6DYAUQcNwR52AhM6nxPwPFvyFvRBkmX0RZeto+R66ghE4Dg@mail.gmail.com \
    --to=ohilyard@iol.unh.edu \
    --cc=arybchenko@solarflare.com \
    --cc=bruce.richardson@intel.com \
    --cc=david.marchand@redhat.com \
    --cc=dts@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=ivan.malov@oktetlabs.ru \
    --cc=j.hendergart@f5.com \
    --cc=lijuan.tu@intel.com \
    --cc=lylavoie@iol.unh.edu \
    --cc=olivier.matz@6wind.com \
    --cc=rasland@mellanox.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).