* [dts] [PATCH] checksum offload: add hardware checksum checks case
@ 2020-07-14 14:53 Owen Hilyard
2020-07-20 14:07 ` [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases Owen Hilyard
0 siblings, 1 reply; 6+ messages in thread
From: Owen Hilyard @ 2020-07-14 14:53 UTC (permalink / raw)
To: dts
Cc: ferruh.yigit, arybchenko, olivier.matz, david.marchand,
ivan.malov, bruce.richardson, jerin.jacob, lylavoie, rasland,
j.hendergart, ohilyard, thomas
add test case for hardware checksum checks
add test documentation for test case
Signed-off-by: Owen Hilyard <ohilyard@iol.unh.edu>
---
test_plans/checksum_offload_test_plan.rst | 134 +---------
tests/TestSuite_checksum_offload.py | 287 +++++++++++++++-------
2 files changed, 200 insertions(+), 221 deletions(-)
diff --git a/test_plans/checksum_offload_test_plan.rst b/test_plans/checksum_offload_test_plan.rst
index a42e28e..4fd8c5a 100644
--- a/test_plans/checksum_offload_test_plan.rst
+++ b/test_plans/checksum_offload_test_plan.rst
@@ -221,8 +221,13 @@ combination: good/bad ip checksum + good/bad udp/tcp checksum.
Check the Rx checksum flags consistent with expected flags.
-Test Case: Hardware Checksum Check IP UDP
+Test Case: Hardware Checksum Check L4
===========================================
+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.
Setup the ``csum`` forwarding mode::
@@ -251,131 +256,4 @@ 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.
-Test Case: Hardware Checksum Check IP TCP
-===========================================
-
-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=0x2269df7500, pkt_len=108, nb_segs=1:
- rx: l2_len=18 ethertype=800 l3_len=20 l4_proto=6 l4_len=20 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=0x2269df6bc0, pkt_len=108, nb_segs=1:
- rx: l2_len=18 ethertype=800 l3_len=20 l4_proto=6 l4_len=20 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 IP SCTP
-===========================================
-
-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=0x2269df6280, pkt_len=100, nb_segs=1:
- rx: l2_len=18 ethertype=800 l3_len=20 l4_proto=132 l4_len=0 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=0x2269df5940, pkt_len=100, nb_segs=1:
- rx: l2_len=18 ethertype=800 l3_len=20 l4_proto=132 l4_len=0 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 IPv6 UDP
-===========================================
-
-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=0x2269df5000, pkt_len=116, nb_segs=1:
- rx: l2_len=18 ethertype=86dd l3_len=40 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_IPV6
-
-
-Send a packet with a bad checksum::
-
- port=0, mbuf=0x2269df46c0, pkt_len=116, nb_segs=1:
- rx: l2_len=18 ethertype=86dd l3_len=40 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_IPV6
-
-Verify flags are as expected.
-Test Case: Hardware Checksum Check IPv6 TCP
-===========================================
-
-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=0x2269df3d80, pkt_len=128, nb_segs=1:
- rx: l2_len=18 ethertype=86dd l3_len=40 l4_proto=6 l4_len=20 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_IPV6
-
-
-Send a packet with a bad checksum::
-
- port=0, mbuf=0x2269df3440, pkt_len=128, nb_segs=1:
- rx: l2_len=18 ethertype=86dd l3_len=40 l4_proto=6 l4_len=20 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_IPV6
-
Verify flags are as expected.
\ No newline at end of file
diff --git a/tests/TestSuite_checksum_offload.py b/tests/TestSuite_checksum_offload.py
index 53eb918..9ff5a41 100644
--- a/tests/TestSuite_checksum_offload.py
+++ b/tests/TestSuite_checksum_offload.py
@@ -39,6 +39,10 @@ Test support of RX/TX Checksum Offload Features by Poll Mode Drivers.
import os
import re
+import subprocess
+import time
+from typing import List, Union, Tuple, Pattern
+
import time
from rst import RstReport
@@ -48,8 +52,11 @@ from test_case import TestCase
from framework.pmd_output import PmdOutput
from test_capabilities import DRIVER_TEST_LACK_CAPA
from pktgen import PacketGeneratorHelper
+from exception import VerifyFailure
import packet
+from settings import FOLDERS
+
class TestChecksumOffload(TestCase):
@@ -91,6 +98,9 @@ class TestChecksumOffload(TestCase):
self.dut.send_expect("csum set udp hw %d" % port, "testpmd>")
self.dut.send_expect("csum set tcp hw %d" % port, "testpmd>")
self.dut.send_expect("csum set sctp hw %d" % port, "testpmd>")
+ self.dut.send_expect("csum set outer-ip hw %d" % port, "testpmd>")
+ self.dut.send_expect("csum set outer-udp hw %d" % port, "testpmd>")
+ self.dut.send_expect("csum parse-tunnel on %d" % port, "testpmd>")
self.dut.send_expect("port start all", "testpmd>")
def checksum_enablesw(self, port):
@@ -146,11 +156,9 @@ class TestChecksumOffload(TestCase):
self.verify("PKT_RX_L4_CKSUM_GOOD" in line, "Packet Rx L4 checksum valid-flags error!")
elif (flag == 0):
if self.nic == "cavium_a063":
- self.verify("PKT_RX_L4_CKSUM_BAD" in line or "PKT_RX_L4_CKSUM_UNKNOWN" in line,
- "Packet Rx L4 checksum valid-flags error!")
+ self.verify("PKT_RX_L4_CKSUM_BAD" in line or "PKT_RX_L4_CKSUM_UNKNOWN" in line, "Packet Rx L4 checksum valid-flags error!")
else:
- self.verify("PKT_RX_L4_CKSUM_BAD" in line,
- "Packet Rx L4 checksum valid-flags error!")
+ self.verify("PKT_RX_L4_CKSUM_BAD" in line, "Packet Rx L4 checksum valid-flags error!")
else:
if "PKT_RX_L4_CKSUM" not in line:
self.verify(0, "There is no L4 checksum flags appeared!")
@@ -178,8 +186,8 @@ class TestChecksumOffload(TestCase):
chksum = self.get_chksum_values(packets_expected)
- inst = self.tester.tcpdump_sniff_packets(intf=rx_interface, count=len(packets_sent) * 4,
- filters=[{'layer': 'ether', 'config': {'src': sniff_src}}])
+ inst = self.tester.tcpdump_sniff_packets(intf=rx_interface, count=len(packets_sent)*4,
+ filters=[{'layer': 'ether', 'config': {'src': sniff_src}}])
self.pkt = packet.Packet()
for packet_type in list(packets_sent.keys()):
@@ -189,10 +197,9 @@ class TestChecksumOffload(TestCase):
p = self.tester.load_tcpdump_sniff_packets(inst)
nr_packets = len(p)
print(p)
- packets_received = [p[i].sprintf("%IP.chksum%;%TCP.chksum%;%UDP.chksum%;%SCTP.chksum%") for i in
- range(nr_packets)]
+ packets_received = [p[i].sprintf("%IP.chksum%;%TCP.chksum%;%UDP.chksum%;%SCTP.chksum%") for i in range(nr_packets)]
print(len(packets_sent), len(packets_received))
- self.verify(len(packets_sent) * 4 == len(packets_received), "Unexpected Packets Drop")
+ self.verify(len(packets_sent)*4 == len(packets_received), "Unexpected Packets Drop")
for packet_received in packets_received:
ip_checksum, tcp_checksum, udp_checksum, sctp_checksum = packet_received.split(';')
@@ -227,47 +234,47 @@ class TestChecksumOffload(TestCase):
self.tester.scapy_append(f'sendp({packet}, iface="{itf}")')
return self.tester.scapy_execute()
- def checksum_flags_are_good(self, flag: str, testpmd_output: str) -> bool:
- good_flag_in_output: bool = flag + "GOOD" in testpmd_output
- self.verify(good_flag_in_output or flag + "BAD" in testpmd_output,
- f"Flag {flag[:-1]} not found, please run test_rx_checksum_valid_flags.")
- return good_flag_in_output
-
def get_pkt_rx_l4_cksum(self, testpmd_output: str) -> bool:
return self.checksum_flags_are_good("PKT_RX_L4_CKSUM_", testpmd_output)
def get_pkt_rx_ip_cksum(self, testpmd_output: str) -> bool:
return self.checksum_flags_are_good("PKT_RX_IP_CKSUM_", testpmd_output)
- def send_pkt_expect_good_bad_from_flag(self, pkt_str: str, do_l3_csum: bool = False, good: bool = True):
- self.send_scapy_packet(pkt_str)
- out: str = self.pmdout.get_output(timeout=5)
- # self.logger.info("Packet Result:\n" + out)
- self.verify(self.get_pkt_rx_l4_cksum(out) == good, "L4 checksum was not correctly checked.")
- if do_l3_csum:
- self.verify(self.get_pkt_rx_ip_cksum(out) == good, "L3 checksum was not correctly checked.")
+ 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.")
+ self.verify((flag + "UNKNOWN") not in testpmd_output,
+ f"Flag {flag[:-1]} was found to be unknown for test {test_name}, indicating a possible lack of support")
+ if should_pass:
+ if flag + "GOOD" in testpmd_output:
+ return
+ else: # flag + "BAD" in testpmd_output
+ self.verify(False, f"{flag}BAD was found in output, expecting {flag}GOOD.")
+ else:
+ if flag + "BAD" in testpmd_output:
+ return
+ else: # flag + "GOOD" in testpmd_output
+ self.verify(False, f"{flag}GOOD was found in output, expecting {flag}BAD.")
- def helper_hardware_checksum_check(self, pkt_str: str, do_l3_csum: bool = False):
- self.dut.send_expect("start", "testpmd>")
+ def send_pkt_expect_good_bad_from_flag_catch_failure(self, pkt_str: str, flag: str, test_name: str,
+ should_pass: bool = True) -> Union[VerifyFailure, None]:
+ try:
+ self.send_pkt_expect_good_bad_from_flag(pkt_str, flag, test_name, should_pass=should_pass)
+ except VerifyFailure as vf:
+ return vf
- self.checksum_enablehw(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]))
+ return None
- good_pkt: str
- bad_pkt: str
- if do_l3_csum:
- # Blank out the fields where a checksum would go for the good packet
- good_pkt = pkt_str % (dut_mac, tester_mac, "", "")
- bad_pkt = pkt_str % (dut_mac, tester_mac, "chksum=0xf", "chksum=0xf")
- else:
- good_pkt = pkt_str % (dut_mac, tester_mac, "")
- bad_pkt = pkt_str % (dut_mac, tester_mac, "chksum=0xf")
+ def scapy_exec(self, cmd: str):
+ return self.tester.send_expect(cmd, ">>>")
- self.send_pkt_expect_good_bad_from_flag(good_pkt, do_l3_csum=do_l3_csum, good=True)
- self.send_pkt_expect_good_bad_from_flag(bad_pkt, do_l3_csum=do_l3_csum, good=False)
+ def scapy_send_append(self, packet: str):
+ return self.tester.scapy_append(f'sendp({packet}, iface=iface)')
- self.dut.send_expect("stop", "testpmd>")
#
#
#
@@ -281,19 +288,17 @@ class TestChecksumOffload(TestCase):
"""
mac = self.dut.get_mac_address(self.dut_ports[0])
- pktsChkErr = {
- 'IP/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=1)/IP(chksum=0x0)/UDP(chksum=0xf)/("X"*46)' % mac,
- 'IP/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=1)/IP(chksum=0x0)/TCP(chksum=0xf)/("X"*46)' % mac,
- 'IP/SCTP': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=1)/IP(chksum=0x0)/SCTP(chksum=0xf)/("X"*48)' % mac,
- 'IPv6/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=1)/IPv6(src="::1")/UDP(chksum=0xf)/("X"*46)' % mac,
- 'IPv6/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=1)/IPv6(src="::1")/TCP(chksum=0xf)/("X"*46)' % mac}
+ pktsChkErr = {'IP/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=1)/IP(chksum=0x0)/UDP(chksum=0xf)/("X"*46)' % mac,
+ 'IP/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=1)/IP(chksum=0x0)/TCP(chksum=0xf)/("X"*46)' % mac,
+ 'IP/SCTP': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=1)/IP(chksum=0x0)/SCTP(chksum=0xf)/("X"*48)' % mac,
+ 'IPv6/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=1)/IPv6(src="::1")/UDP(chksum=0xf)/("X"*46)' % mac,
+ 'IPv6/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=1)/IPv6(src="::1")/TCP(chksum=0xf)/("X"*46)' % mac}
- pkts = {
- 'IP/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/Dot1Q(vlan=1)/IP(src="127.0.0.1")/UDP()/("X"*46)' % mac,
- 'IP/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/Dot1Q(vlan=1)/IP(src="127.0.0.1")/TCP()/("X"*46)' % mac,
- 'IP/SCTP': 'Ether(dst="02:00:00:00:00:00", src="%s")/Dot1Q(vlan=1)/IP(src="127.0.0.1")/SCTP()/("X"*48)' % mac,
- 'IPv6/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/Dot1Q(vlan=1)/IPv6(src="::1")/UDP()/("X"*46)' % mac,
- 'IPv6/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/Dot1Q(vlan=1)/IPv6(src="::1")/TCP()/("X"*46)' % mac}
+ pkts = {'IP/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/Dot1Q(vlan=1)/IP(src="127.0.0.1")/UDP()/("X"*46)' % mac,
+ 'IP/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/Dot1Q(vlan=1)/IP(src="127.0.0.1")/TCP()/("X"*46)' % mac,
+ 'IP/SCTP': 'Ether(dst="02:00:00:00:00:00", src="%s")/Dot1Q(vlan=1)/IP(src="127.0.0.1")/SCTP()/("X"*48)' % mac,
+ 'IPv6/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/Dot1Q(vlan=1)/IPv6(src="::1")/UDP()/("X"*46)' % mac,
+ 'IPv6/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/Dot1Q(vlan=1)/IPv6(src="::1")/TCP()/("X"*46)' % mac}
if self.kdriver in DRIVER_TEST_LACK_CAPA['sctp_tx_offload']:
del pktsChkErr['IP/SCTP']
@@ -325,17 +330,11 @@ class TestChecksumOffload(TestCase):
result = self.get_chksum_values(pkts_ref)
# set the expected checksum values same with the actual values
- pkts_good = {
- 'IP/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(chksum=int(%s))/UDP(chksum=int(%s))/("X"*46)' % (
- mac, result['IP/UDP'][0], result['IP/UDP'][1]),
- 'IP/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="10.0.0.1",chksum=int(%s))/TCP(chksum=int(%s))/("X"*46)' % (
- mac, result['IP/TCP'][0], result['IP/TCP'][1]),
- 'IP/SCTP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="10.0.0.1",chksum=int(%s))/SCTP(chksum=int(%s))/("X"*48)' % (
- mac, result['IP/SCTP'][0], result['IP/SCTP'][1]),
- 'IPv6/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="::1")/UDP(chksum=int(%s))/("X"*46)' % (
- mac, result['IPv6/UDP'][0]),
- 'IPv6/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="::1")/TCP(chksum=int(%s))/("X"*46)' % (
- mac, result['IPv6/TCP'][0])}
+ pkts_good = {'IP/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(chksum=int(%s))/UDP(chksum=int(%s))/("X"*46)' % (mac, result['IP/UDP'][0], result['IP/UDP'][1]),
+ 'IP/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="10.0.0.1",chksum=int(%s))/TCP(chksum=int(%s))/("X"*46)' % (mac, result['IP/TCP'][0], result['IP/TCP'][1]),
+ 'IP/SCTP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="10.0.0.1",chksum=int(%s))/SCTP(chksum=int(%s))/("X"*48)' % (mac, result['IP/SCTP'][0], result['IP/SCTP'][1]),
+ 'IPv6/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="::1")/UDP(chksum=int(%s))/("X"*46)' % (mac, result['IPv6/UDP'][0]),
+ 'IPv6/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="::1")/TCP(chksum=int(%s))/("X"*46)' % (mac, result['IPv6/TCP'][0])}
# set the expected checksum values different from the actual values
pkts_bad = {'IP/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(chksum=0x0)/UDP(chksum=0xf)/("X"*46)' % mac,
@@ -399,24 +398,17 @@ class TestChecksumOffload(TestCase):
mac = self.dut.get_mac_address(self.dut_ports[0])
sndIP = '10.0.0.1'
sndIPv6 = '::1'
- sndPkts = {
- 'IP/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s",chksum=0x0)/UDP(chksum=0xf)/("X"*46)' % (
- mac, sndIP),
- 'IP/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s",chksum=0x0)/TCP(chksum=0xf)/("X"*46)' % (
- mac, sndIP),
- 'IPv6/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/UDP(chksum=0xf)/("X"*46)' % (
- mac, sndIPv6),
- 'IPv6/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/TCP(chksum=0xf)/("X"*46)' % (
- mac, sndIPv6)}
+ sndPkts = {'IP/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s",chksum=0x0)/UDP(chksum=0xf)/("X"*46)' % (mac, sndIP),
+ 'IP/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s",chksum=0x0)/TCP(chksum=0xf)/("X"*46)' % (mac, sndIP),
+ 'IPv6/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/UDP(chksum=0xf)/("X"*46)' % (mac, sndIPv6),
+ 'IPv6/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/TCP(chksum=0xf)/("X"*46)' % (mac, sndIPv6)}
expIP = sndIP
expIPv6 = sndIPv6
expPkts = {'IP/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/UDP()/("X"*46)' % (mac, expIP),
'IP/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/TCP()/("X"*46)' % (mac, expIP),
- 'IPv6/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/UDP()/("X"*46)' % (
- mac, expIPv6),
- 'IPv6/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/TCP()/("X"*46)' % (
- mac, expIPv6)}
+ 'IPv6/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/UDP()/("X"*46)' % (mac, expIPv6),
+ 'IPv6/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/TCP()/("X"*46)' % (mac, expIPv6)}
self.dut.send_expect("start", "testpmd>")
result = self.checksum_validate(sndPkts, expPkts)
@@ -458,12 +450,12 @@ class TestChecksumOffload(TestCase):
self.tester.pktgen.clear_streams()
# run packet generator
streams = self.pktgen_helper.prepare_stream_from_tginput(tgenInput, 100,
- None, self.tester.pktgen)
+ None, self.tester.pktgen)
Bps[str(size)], Pps[str(size)] = self.tester.pktgen.measure_throughput(stream_ids=streams)
self.verify(Pps[str(size)] > 0, "No traffic detected")
Pps[str(size)] /= 1E6
Pct[str(size)] = (Pps[str(size)] * 100) / \
- self.wirespeed(self.nic, size, 2)
+ self.wirespeed(self.nic, size, 2)
result.append(Pps[str(size)])
result.append(Pct[str(size)])
@@ -500,7 +492,7 @@ class TestChecksumOffload(TestCase):
self.result_table_create(tblheader)
self.pmdout.start_testpmd(
lcore, "--portmask=%s" % self.portMask + " --enable-rx-cksum " +
- "--port-topology=loop", socket=self.ports_socket)
+ "--port-topology=loop", socket=self.ports_socket)
self.dut.send_expect("set fwd csum", "testpmd> ")
if mode == "hw":
@@ -519,25 +511,134 @@ class TestChecksumOffload(TestCase):
self.dut.send_expect("quit", "#", 10)
self.result_table_print()
- def test_hardware_checksum_check_ip_udp(self):
- self.helper_hardware_checksum_check('Ether(dst="%s", src="%s")/IP(%s)/UDP(%s)/("X"*50)',
- do_l3_csum=True)
+ def test_hardware_checksum_check_ip(self):
+ self.dut.send_expect("start", "testpmd>")
+ self.checksum_enablehw(self.dut_ports[0])
+
+ verification_errors: List[VerifyFailure] = []
- def test_hardware_checksum_check_ip_tcp(self):
- self.helper_hardware_checksum_check('Ether(dst="%s", src="%s")/IP(%s)/TCP(%s)/("X"*50)',
- do_l3_csum=True)
+ # 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)
- def test_hardware_checksum_check_ip_sctp(self):
- self.helper_hardware_checksum_check('Ether(dst="%s", src="%s")/IP(%s)/SCTP(%s)/("X"*50)',
- do_l3_csum=True)
+ # 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)
- def test_hardware_checksum_check_ipv6_udp(self):
- self.helper_hardware_checksum_check('Ether(dst="%s", src="%s")/IPv6(src="::1")/UDP(%s)/("X"*50)',
- do_l3_csum=False)
+ # 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)
- def test_hardware_checksum_check_ipv6_tcp(self):
- self.helper_hardware_checksum_check('Ether(dst="%s", src="%s")/IPv6(src="::1")/TCP(%s)/("X"*50)',
- do_l3_csum=False)
+ self.verify(len(verification_errors) == 0, "\n".join(verification_errors))
+
+ self.dut.send_expect("stop", "testpmd>")
+
+ def test_hardware_checksum_check_l4(self):
+ self.checksum_enablehw(self.dut_ports[0])
+ self.dut.send_expect("start", "testpmd>")
+
+ verification_errors: List[VerifyFailure] = []
+
+ l3_protos: List[str] = [
+ "IP",
+ "IPv6"
+ ]
+
+ l4_protos: List[str] = [
+ "UDP",
+ "TCP",
+ "SCTP",
+ ]
+
+ 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]))
+
+ self.tester.send_expect("scapy", ">>> ")
+ self.scapy_exec(f"eth = Ether(dst='{dut_mac}', src='{tester_mac}')")
+ self.scapy_exec(f"iface = '{iface}'")
+ # Untunneled
+ for l3 in l3_protos:
+ for l4 in l4_protos:
+ for chksum in "", "chksum=0xf":
+ vf = self.send_pkt_expect_good_bad_from_flag_catch_failure(
+ f"eth/{l3}()/{l4}({chksum})/('X'*50)",
+ "PKT_RX_L4_CKSUM_", f"{l3}/{l4}",
+ should_pass=(chksum == ""))
+ if vf is not None:
+ verification_errors.append(vf)
+
+ # Tunneled
+ # VXLAN
+ for l3 in l3_protos:
+ for l4 in l4_protos:
+ for outer_arg in "", "chksum=0xf":
+ for inner_arg in "", "chksum=0xf":
+ for flag in "PKT_RX_L4_CKSUM_", "PKT_RX_OUTER_L4_CKSUM_":
+ if flag == "PKT_RX_L4_CKSUM_":
+ should_pass = inner_arg == ""
+ else: # flag == PKT_RX_OUTER_L4_CKSUM_
+ 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)",
+ flag, f"{l3}/{l4}/VXLAN/{l3}/{l4}",
+ should_pass=should_pass)
+
+ if vf is not None:
+ verification_errors.append(vf)
+
+ # GRE
+ for l3 in l3_protos:
+ for l4 in l4_protos:
+ 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)",
+ "PKT_RX_L4_CKSUM_", f"{l3}/GRE/{l3}/{l4}",
+ should_pass=should_pass)
+
+ if vf is not None:
+ verification_errors.append(vf)
+
+ # This section is commented out because GENEVE is not supported in the current version (2.3.3) that is used
+ # in dts. This will be available in scapy 2.4.3, so this was added and commented out so that when scapy is
+ # updated this test case can easily take advantage of the new functionality.
+
+ # # GENEVE
+ # for l3_outer in l3_protos:
+ # for l4_outer in l4_protos:
+ # for l3_inner in l3_protos:
+ # for l4 in l4_protos:
+ # for outer_arg in "", "chksum=0xf":
+ # for inner_arg in "", "chksum=0xf":
+ # for flag in "PKT_RX_L4_CKSUM_", "PKT_RX_OUTER_L4_CKSUM_":
+ # should_pass: bool = inner_arg == "" if flag == "PKT_RX_L4_CKSUM_" else outer_arg == ""
+ # vf = self.send_pkt_expect_good_bad_from_flag_catch_failure(
+ # f"eth/{l3_outer}()/{l4_outer}({outer_arg})/GENEVE()/eth/{l3_inner}()/"
+ # f"{l4}({inner_arg})/('X'*50)",
+ # flag, f"{l3_outer}/{l4_outer}/VXLAN/{l3_inner}/{l4}",
+ # should_pass=should_pass)
+ #
+ # if vf is not None:
+ # verification_errors.append(vf)
+
+ # tunneled inner
+
+ for err in verification_errors:
+ self.logger.error(str(err))
+ self.verify(len(verification_errors) == 0, "See previous output")
+
+ self.dut.send_expect("stop", "testpmd>")
def tear_down(self):
"""
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases
2020-07-14 14:53 [dts] [PATCH] checksum offload: add hardware checksum checks case Owen Hilyard
@ 2020-07-20 14:07 ` Owen Hilyard
2020-07-20 14:13 ` [dts] [PATCH] checksum hardware checks: fix typo Owen Hilyard
2020-07-24 2:45 ` [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases Tu, Lijuan
0 siblings, 2 replies; 6+ messages in thread
From: Owen Hilyard @ 2020-07-20 14:07 UTC (permalink / raw)
To: dts
Cc: ferruh.yigit, arybchenko, olivier.matz, david.marchand,
ivan.malov, bruce.richardson, lylavoie, rasland, j.hendergart,
ohilyard, thomas
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dts] [PATCH] checksum hardware checks: fix typo
2020-07-20 14:07 ` [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases Owen Hilyard
@ 2020-07-20 14:13 ` 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
1 sibling, 1 reply; 6+ messages in thread
From: Owen Hilyard @ 2020-07-20 14:13 UTC (permalink / raw)
To: dts
Cc: ferruh.yigit, arybchenko, olivier.matz, david.marchand,
ivan.malov, bruce.richardson, lylavoie, rasland, j.hendergart,
ohilyard, thomas
fixed typo
Signed-off-by: Owen Hilyard <ohilyard@iol.unh.edu>
---
test_plans/checksum_offload_test_plan.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test_plans/checksum_offload_test_plan.rst b/test_plans/checksum_offload_test_plan.rst
index de2e1a9..2010641 100644
--- a/test_plans/checksum_offload_test_plan.rst
+++ b/test_plans/checksum_offload_test_plan.rst
@@ -318,7 +318,7 @@ Start the packet forwarding::
TX threshold registers: pthresh=32 hthresh=8 wthresh=8
-Start a packet capture on the tester in the backround::
+Start a packet capture on the tester in the background::
# tcpdump -i <iface> -s 65535 -w /tmp/tester/test_hardware_checksum_check_l4_tx_capture.pcap &
@@ -358,7 +358,7 @@ Start the packet forwarding::
TX threshold registers: pthresh=32 hthresh=8 wthresh=8
-Start a packet capture on the tester in the backround::
+Start a packet capture on the tester in the background::
# tcpdump -i <iface> -s 65535 -w /tmp/tester/test_hardware_checksum_check_l3_tx_capture.pcap &
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [dts] [PATCH] checksum hardware checks: fix typo
2020-07-20 14:13 ` [dts] [PATCH] checksum hardware checks: fix typo Owen Hilyard
@ 2020-08-12 1:53 ` Ma, LihongX
0 siblings, 0 replies; 6+ messages in thread
From: Ma, LihongX @ 2020-08-12 1:53 UTC (permalink / raw)
To: Owen Hilyard, dts
Cc: Yigit, Ferruh, arybchenko, olivier.matz, david.marchand,
ivan.malov, Richardson, Bruce, lylavoie, rasland, j.hendergart,
thomas
Acked-by: lihongx.ma <lihongx.ma@intel.com>
Regards,
Ma,lihong
-----Original Message-----
From: dts <dts-bounces@dpdk.org> On Behalf Of Owen Hilyard
Sent: Monday, July 20, 2020 10:14 PM
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 hardware checks: fix typo
fixed typo
Signed-off-by: Owen Hilyard <ohilyard@iol.unh.edu>
---
test_plans/checksum_offload_test_plan.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases
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-07-24 2:45 ` Tu, Lijuan
2020-07-24 12:43 ` Owen Hilyard
1 sibling, 1 reply; 6+ messages in thread
From: Tu, Lijuan @ 2020-07-24 2:45 UTC (permalink / raw)
To: Owen Hilyard, dts
Cc: Yigit, Ferruh, arybchenko, olivier.matz, david.marchand,
ivan.malov, Richardson, Bruce, lylavoie, rasland, j.hendergart,
thomas
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [dts] [PATCH] checksum checks: Add hardware offload l3 and l4 cases
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
0 siblings, 0 replies; 6+ messages in thread
From: Owen Hilyard @ 2020-07-24 12:43 UTC (permalink / raw)
To: Tu, Lijuan
Cc: dts, Yigit, Ferruh, arybchenko, olivier.matz, david.marchand,
ivan.malov, Richardson, Bruce, lylavoie, rasland, j.hendergart,
thomas
[-- 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 --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-08-12 1:53 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 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).