Hi David, Please find my replies inline.
> -----Original Message----- > From: David Marchand <[email protected]> > Sent: Tuesday, November 30, 2021 8:30 PM > To: [email protected] > Cc: [email protected]; Stokes, Ian <[email protected]>; > [email protected]; Amber, Kumar <[email protected]>; > [email protected]; [email protected]; [email protected] > Subject: [PATCH v3 2/4] system-dpdk: Use dummy-pmd port for packet injection. > > net_pcap is not always available in DPDK (like, in a dev environment when you > forgot to install the libpcap-devel). > On the other hand, OVS already has its own way to inject packets into a > bridge. > Let's make use of it. > > This solution is slower than net/pcap DPDK, so lower the number of expected > packets so that it runs in OVS_CTL_TIMEOUT seconds. > > While at it, convert "known" packets from pcap to scapy so that the injected > packets can be updated without having to read/write a pcap file. > > Note: this change also (avoids/) fixes a python exception in PcapWriter with > scapy 2.4.3 that comes from EPEL. > > Suggested-by: Ilya Maximets <[email protected]> > Signed-off-by: David Marchand <[email protected]> > --- > Changes since v2: > - updated documentation, > - cleaned tests/automake.mk, > - fixed shebang in python script, > - added missing check for scapy availability, > > Changes since v1: > - renamed generator script, > - decreased packet count for fuzzy test, > - simplified wait expression for packet count, > > --- > Documentation/topics/dpdk/bridge.rst | 7 ++-- > tests/automake.mk | 7 +--- > tests/genpkts.py | 56 +++++++++++++++++++++++++++ > tests/mfex_fuzzy.py | 32 --------------- > tests/pcap/mfex_test.pcap | Bin 416 -> 0 bytes > tests/system-dpdk-macros.at | 4 +- > tests/system-dpdk.at | 33 +++++++++++++--- > 7 files changed, 89 insertions(+), 50 deletions(-) create mode 100755 > tests/genpkts.py delete mode 100755 tests/mfex_fuzzy.py delete mode 100644 > tests/pcap/mfex_test.pcap > > diff --git a/Documentation/topics/dpdk/bridge.rst > b/Documentation/topics/dpdk/bridge.rst > index f645b9ade5..648ce203eb 100644 > --- a/Documentation/topics/dpdk/bridge.rst > +++ b/Documentation/topics/dpdk/bridge.rst > @@ -408,7 +408,7 @@ Fuzzy tests can also be done on miniflow extract with > the help of auto-validator and Scapy. The steps below describes the steps to > reproduce the setup with IP being fuzzed to generate packets. > > -Scapy is used to create fuzzy IP packets and save them into a PCAP :: > +Scapy is used to create fuzzy IP packets (see tests/genpkts.py) :: > > pkt = fuzz(Ether()/IP()/TCP()) > > @@ -418,9 +418,8 @@ Set the miniflow extract to autovalidator using :: > > OVS is configured to receive the generated packets :: > > - $ ovs-vsctl add-port br0 pcap0 -- \ > - set Interface pcap0 type=dpdk options:dpdk-devargs=net_pcap0 > - "rx_pcap=fuzzy.pcap" > + $ ovs-vsctl add-port br0 p1 -- \ > + set Interface p1 type=dummy-pmd > > With this workflow, the autovalidator will ensure that all MFEX > implementations are classifying each packet in exactly the same way. > diff --git a/tests/automake.mk b/tests/automake.mk index > 43731d0973..3bc74a5aff 100644 > --- a/tests/automake.mk > +++ b/tests/automake.mk > @@ -143,11 +143,6 @@ $(srcdir)/tests/fuzz-regression-list.at: > tests/automake.mk > echo "TEST_FUZZ_REGRESSION([$$basename])"; \ > done > [email protected] && mv [email protected] $@ > > -EXTRA_DIST += $(MFEX_AUTOVALIDATOR_TESTS) - > MFEX_AUTOVALIDATOR_TESTS = \ > - tests/pcap/mfex_test.pcap \ > - tests/mfex_fuzzy.py > - > OVSDB_CLUSTER_TESTSUITE_AT = \ > tests/ovsdb-cluster-testsuite.at \ > tests/ovsdb-execution.at \ > @@ -518,7 +513,7 @@ tests_test_type_props_SOURCES = tests/test-type- > props.c CHECK_PYFILES = \ > tests/appctl.py \ > tests/flowgen.py \ > - tests/mfex_fuzzy.py \ > + tests/genpkts.py \ > tests/ovsdb-monitor-sort.py \ > tests/test-daemon.py \ > tests/test-json.py \ > diff --git a/tests/genpkts.py b/tests/genpkts.py new file mode 100755 index > 0000000000..f64f786ccb > --- /dev/null > +++ b/tests/genpkts.py > @@ -0,0 +1,56 @@ > +#!/usr/bin/env python3 > + > +import sys > + > +from scapy.all import RandMAC, RandIP, RandIP6, RandShort, fuzz from > +scapy.all import IPv6, Dot1Q, IP, Ether, UDP, TCP > + > +if len(sys.argv) < 2: > + print('usage: {} packets_count [fuzz]'.format(sys.argv[0])) > + sys.exit(1) > + > +tmpl = [] > + > +if len(sys.argv) == 2: > + eth = Ether(dst='ff:ff:ff:ff:ff:ff') > + vlan = eth / Dot1Q(vlan=1) > + p = eth / IP() / TCP(sport=20, dport=80, flags='SA', window=8192) > + tmpl += [p.build().hex()] > + p = eth / IP() / UDP(sport=53, dport=53) > + tmpl += [p.build().hex()] > + p = eth / IP() / TCP(sport=20, dport=80, flags='S', window=8192) > + tmpl += [p.build().hex()] > + p = eth / IP() / UDP(sport=53, dport=53) > + tmpl += [p.build().hex()] > + p = vlan / IP() / UDP(sport=53, dport=53) > + tmpl += [p.build().hex()] > + p = vlan / IP() / TCP(sport=20, dport=80, flags='S', window=8192) > + tmpl += [p.build().hex()] Hardcoding the values here is not preferable as we wanted to test the optimized implementations with various values contained inside the header. > +elif sys.argv[2] == 'fuzz': > + # Generate random protocol bases, use a fuzz() over the combined packet > + # for full fuzzing. > + eth = Ether(src=RandMAC(), dst=RandMAC()) > + vlan = Dot1Q() > + ipv4 = IP(src=RandIP(), dst=RandIP()) > + ipv6 = IPv6(src=RandIP6(), dst=RandIP6()) > + udp = UDP(dport=RandShort(), sport=RandShort()) > + tcp = TCP(dport=RandShort(), sport=RandShort()) > + > + # IPv4 packets with fuzzing > + tmpl += [fuzz(eth / ipv4 / udp).build().hex()] > + tmpl += [fuzz(eth / ipv4 / tcp).build().hex()] > + tmpl += [fuzz(eth / vlan / ipv4 / udp).build().hex()] > + tmpl += [fuzz(eth / vlan / ipv4 / tcp).build().hex()] > + > + # IPv6 packets with fuzzing > + tmpl += [fuzz(eth / ipv6 / udp).build().hex()] > + tmpl += [fuzz(eth / ipv6 / tcp).build().hex()] > + tmpl += [fuzz(eth / vlan / ipv6 / udp).build().hex()] > + tmpl += [fuzz(eth / vlan / ipv6 / tcp).build().hex()] > + > +i = 0 > +count = int(sys.argv[1]) > +while count != 0: > + print(tmpl[i % len(tmpl)]) > + i += 1 > + count -= 1 > diff --git a/tests/mfex_fuzzy.py b/tests/mfex_fuzzy.py deleted file mode > 100755 > index 3efe1152da..0000000000 > --- a/tests/mfex_fuzzy.py > +++ /dev/null > @@ -1,32 +0,0 @@ > -#!/usr/bin/python3 > - > -import sys > - > -from scapy.all import RandMAC, RandIP, PcapWriter, RandIP6, RandShort, fuzz > -from scapy.all import IPv6, Dot1Q, IP, Ether, UDP, TCP > - > -path = str(sys.argv[1]) + "/pcap/fuzzy.pcap" > -pktdump = PcapWriter(path, append=False, sync=True) > - > -for i in range(0, 2000): > - > - # Generate random protocol bases, use a fuzz() over the combined packet > - # for full fuzzing. > - eth = Ether(src=RandMAC(), dst=RandMAC()) > - vlan = Dot1Q() > - ipv4 = IP(src=RandIP(), dst=RandIP()) > - ipv6 = IPv6(src=RandIP6(), dst=RandIP6()) > - udp = UDP(dport=RandShort(), sport=RandShort()) > - tcp = TCP(dport=RandShort(), sport=RandShort()) > - > - # IPv4 packets with fuzzing > - pktdump.write(fuzz(eth / ipv4 / udp)) > - pktdump.write(fuzz(eth / ipv4 / tcp)) > - pktdump.write(fuzz(eth / vlan / ipv4 / udp)) > - pktdump.write(fuzz(eth / vlan / ipv4 / tcp)) > - > - # IPv6 packets with fuzzing > - pktdump.write(fuzz(eth / ipv6 / udp)) > - pktdump.write(fuzz(eth / ipv6 / tcp)) > - pktdump.write(fuzz(eth / vlan / ipv6 / udp)) > - pktdump.write(fuzz(eth / vlan / ipv6 / tcp)) > diff --git a/tests/pcap/mfex_test.pcap b/tests/pcap/mfex_test.pcap deleted > file > mode 100644 index > 1aac67b8d643ecb016c758cba4cc32212a80f52a..0000000000000000000000000 > 000000000000000 > GIT binary patch > literal 0 > HcmV?d00001 > > literal 416 > zcmca|c+)~A1{MYw`2U}Qff2}Q<eHVR>K`M68ITRa|G@yFii5$Gfk6YL%z>@uY&}o > | > z2s4N<1VH2&7y^V87$)XGOtD~MV$cFgfG~zBGGJ2#YtF$<F=a4i;9x8Q*<ZrSM6Uf > z > xK>KST_NTIwYriok6N4Vm)gX- > Q@<yO<!C`>c^{cp<7_5LgK^UuU{2>VS0RZ!RQ+EIW > > diff --git a/tests/system-dpdk-macros.at b/tests/system-dpdk-macros.at index > ef0e84e939..5a6b3cbff9 100644 > --- a/tests/system-dpdk-macros.at > +++ b/tests/system-dpdk-macros.at > @@ -37,7 +37,7 @@ m4_define([OVS_DPDK_PRE_PHY_SKIP], > # > # Create an empty database and start ovsdb-server. Add special configuration > # > dpdk-init to enable DPDK functionality. Start ovs-vswitchd connected to that > -# > database using system devices (no dummies). > +# database using system devices. > # > m4_define([OVS_DPDK_START], > [dnl Create database. > @@ -62,7 +62,7 @@ m4_define([OVS_DPDK_START], > AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . > other_config:dpdk-extra=-- > log-level=pmd.*:error]) > > dnl Start ovs-vswitchd. > - AT_CHECK([ovs-vswitchd --detach --no-chdir --pidfile --log-file -vvconn - > vofproto_dpif -vunixctl], [0], [stdout], [stderr]) > + AT_CHECK([ovs-vswitchd --enable-dummy --detach --no-chdir --pidfile > + --log-file -vvconn -vofproto_dpif -vunixctl], [0], [stdout], [stderr]) > AT_CAPTURE_FILE([ovs-vswitchd.log]) > on_exit "kill_ovs_vswitchd `cat ovs-vswitchd.pid`" > ]) > diff --git a/tests/system-dpdk.at b/tests/system-dpdk.at index > 9c8f4bb15a..73c58030b1 100644 > --- a/tests/system-dpdk.at > +++ b/tests/system-dpdk.at > @@ -224,22 +224,29 @@ dnl > ------------------------------------------------------------- > ------------- > dnl Add standard DPDK PHY port > AT_SETUP([OVS-DPDK - MFEX Autovalidator]) > AT_KEYWORDS([dpdk]) > +AT_SKIP_IF([! $PYTHON3 -c "import scapy"], [], []) > > OVS_DPDK_START() > > dnl Add userspace bridge and attach it to OVS AT_CHECK([ovs-vsctl add-br > br0 - > - set bridge br0 datapath_type=netdev]) -AT_CHECK([ovs-vsctl add-port br0 p1 > -- > set Interface p1 type=dpdk options:dpdk- > devargs=net_pcap1,rx_pcap=$srcdir/pcap/mfex_test.pcap,infinite_rx=1], [], > [stdout], [stderr]) > +AT_CHECK([ovs-vsctl add-port br0 p1 -- set interface p1 > +type=dummy-pmd]) > AT_CHECK([ovs-vsctl show], [], [stdout]) > > AT_SKIP_IF([! ovs-appctl dpif-netdev/miniflow-parser-get | sed 1,4d | grep > "True"], [], [dnl > ]) > > +on_exit "pkill -f -x -9 '$PYTHON3 $srcdir/genpkts.py -1'" > +($PYTHON3 $srcdir/genpkts.py -1 | while read pkt; do > + ovs-appctl netdev-dummy/receive p1 "$pkt" || break > + done) & > + > AT_CHECK([ovs-appctl dpif-netdev/miniflow-parser-set autovalidator], [0], > [dnl > Miniflow extract implementation set to autovalidator. > ]) > > -OVS_WAIT_UNTIL([test `ovs-vsctl get interface p1 statistics | grep -oP > 'rx_packets=\s*\K\d+'` -ge 1000]) > +OVS_WAIT_UNTIL([test `ovs-vsctl get interface p1 statistics:rx_packets` > +-ge 1000]) pkill -f -x -9 '$PYTHON3 $srcdir/genpkts.py -1' > > dnl Clean up > AT_CHECK([ovs-vsctl del-port br0 p1], [], [stdout], [stderr]) @@ -252,22 > +259,27 @@ dnl Add standard DPDK PHY port AT_SETUP([OVS-DPDK - MFEX > Autovalidator Fuzzy]) > AT_KEYWORDS([dpdk]) > AT_SKIP_IF([! $PYTHON3 -c "import scapy"], [], []) > -AT_CHECK([$PYTHON3 $srcdir/mfex_fuzzy.py $srcdir], [], [stdout]) > OVS_DPDK_START() > > dnl Add userspace bridge and attach it to OVS AT_CHECK([ovs-vsctl add-br > br0 - > - set bridge br0 datapath_type=netdev]) -AT_CHECK([ovs-vsctl add-port br0 p1 > -- > set Interface p1 type=dpdk options:dpdk- > devargs=net_pcap1,rx_pcap=$srcdir/pcap/fuzzy.pcap,infinite_rx=1], [], > [stdout], > [stderr]) > +AT_CHECK([ovs-vsctl add-port br0 p1 -- set interface p1 > +type=dummy-pmd]) > AT_CHECK([ovs-vsctl show], [], [stdout]) > > AT_SKIP_IF([! ovs-appctl dpif-netdev/miniflow-parser-get | sed 1,4d | grep > "True"], [], [dnl > ]) > > +on_exit "pkill -f -x -9 '$PYTHON3 $srcdir/genpkts.py -1 fuzz'" > +($PYTHON3 $srcdir/genpkts.py -1 fuzz | while read pkt; do > + ovs-appctl netdev-dummy/receive p1 "$pkt" || break > + done) & > + > AT_CHECK([ovs-appctl dpif-netdev/miniflow-parser-set autovalidator], [0], > [dnl > Miniflow extract implementation set to autovalidator. > ]) > > -OVS_WAIT_UNTIL([test `ovs-vsctl get interface p1 statistics | grep -oP > 'rx_packets=\s*\K\d+'` -ge 100000]) We should increase the packet count to at-least 10x the current number to have a proper fuzzy testing and we have measured it would only take 10~ to 15~ sec more. The current runtime did not catch issues when we purposely broke the implementation and by allowing to run for 10000 packets, it did catch the induced error. Regards Amber > +OVS_WAIT_UNTIL([test `ovs-vsctl get interface p1 statistics:rx_packets` > +-ge 1000]) pkill -f -x -9 '$PYTHON3 $srcdir/genpkts.py -1 fuzz' > > dnl Clean up > AT_CHECK([ovs-vsctl del-port br0 p1], [], [stdout], [stderr]) @@ -278,13 > +290,20 @@ dnl > -------------------------------------------------------------------------- > dnl > -------------------------------------------------------------------------- > AT_SETUP([OVS-DPDK - MFEX Configuration]) > AT_KEYWORDS([dpdk]) > +AT_SKIP_IF([! $PYTHON3 -c "import scapy"], [], []) > + > OVS_DPDK_START() > AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:pmd-cpu- > mask=0xC]) dnl Add userspace bridge and attach it to OVS AT_CHECK([ovs-vsctl > add-br br0 -- set bridge br0 datapath_type=netdev]) -AT_CHECK([ovs-vsctl add- > port br0 p1 -- set Interface p1 type=dpdk options:dpdk- > devargs=net_pcap1,rx_pcap=$srcdir/pcap/mfex_test.pcap,infinite_rx=1], [], > [stdout], [stderr]) > +AT_CHECK([ovs-vsctl add-port br0 p1 -- set interface p1 > +type=dummy-pmd]) > AT_CHECK([ovs-vsctl show], [], [stdout]) > > +on_exit "pkill -f -x -9 '$PYTHON3 $srcdir/genpkts.py -1'" > +($PYTHON3 $srcdir/genpkts.py -1 | while read pkt; do > + ovs-appctl netdev-dummy/receive p1 "$pkt" || break > + done) & > + > AT_CHECK([ovs-appctl dpif-netdev/miniflow-parser-set scalar 1], [2], [], > [dnl > Error: unknown argument 1. > @@ -377,6 +396,8 @@ Error: invalid study_pkt_cnt value: -pmd. > ovs-appctl: ovs-vswitchd: server returned an error > ]) > > +pkill -f -x -9 '$PYTHON3 $srcdir/genpkts.py -1' > + > dnl Clean up > AT_CHECK([ovs-vsctl del-port br0 p1], [], [stdout], [stderr]) > OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [ > -- > 2.23.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
