On 1/3/22 15:15, David Marchand wrote:
> 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]>
> Reviewed-by: Maxime Coquelin <[email protected]>
> Acked-by: Eelco Chaudron <[email protected]>
> ---
> Changes since v3:
> - dropped documentation update following rebase,
> - fixed regression in fuzzy packets generation,
>
> 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,
>
> ---
> tests/automake.mk | 7 +---
> tests/genpkts.py | 63 ++++++++++++++++++++++++++++++++++++
> 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 +++++++++++++++----
> 6 files changed, 93 insertions(+), 46 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/tests/automake.mk b/tests/automake.mk
> index ab2b87012e..e7002634f2 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 \
> @@ -519,7 +514,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..466d356d4e
> --- /dev/null
> +++ b/tests/genpkts.py
> @@ -0,0 +1,63 @@
> +#!/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)
> +
> +
> +def simple_packets():
> + tmpl = []
> + 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()]
> + return tmpl
> +
> +
> +def fuzzy_packets():
> + tmpl = []
> + # 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()]
> + return tmpl
> +
> +
> +count = int(sys.argv[1])
> +while True:
> + for packet in simple_packets() if len(sys.argv) == 2 else
> fuzzy_packets():
> + print(packet)
> + count -= 1
> + if (count == 0):
> + sys.exit(0)
> 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..0000000000000000000000000000000000000000
> 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*<ZrSM6Ufz
> 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 062253ee14..6e675e5828 100644
> --- a/tests/system-dpdk-macros.at
> +++ b/tests/system-dpdk-macros.at
> @@ -31,7 +31,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.
> @@ -56,7 +56,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 5c988da280..ecce9e3c9b 100644
> --- a/tests/system-dpdk.at
> +++ b/tests/system-dpdk.at
> @@ -226,22 +226,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) &
With this pattern I'm having issues running tests in parallel (in the
main testsuite with the next patch applied). One of the tests always
fails and succedes on re-check. I have an impression that script breaks
or getting killed before sending all the packets (cross-fire from the
other test?). In general, the pattern here doesn't seem CPU friendly
and that might be an issue for CPU-usage-restricted test environments.
Suggesting a following change for the test:
diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at
index fbb8fe9a7..5f6a07151 100644
--- a/tests/dpif-netdev.at
+++ b/tests/dpif-netdev.at
@@ -645,17 +645,16 @@ OVS_VSWITCHD_START(
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.
])
+AT_SKIP_IF([! $PYTHON3 $srcdir/genpkts.py 1000 > packets])
+cat packets | while read pkt; do
+ AT_CHECK([ovs-appctl netdev-dummy/receive p1 "$pkt"], [0], [ignore])
+done
+
OVS_WAIT_UNTIL([test `ovs-vsctl get interface p1 statistics:rx_packets` -ge
1000])
-pkill -f -x -9 '$PYTHON3 $srcdir/genpkts.py -1'
OVS_VSWITCHD_STOP
AT_CLEANUP
---
Same for the fuzzy test below. This will save a lot of CPU cycles as
we will not have parallel thread that generates packets, and will also
not need to kill it. This also removes the race between packet generation
and enabling of the autovalidator.
I also added the AT_SKIP_IF for the actual genpkts.py call, because I have
scapy crashing on one of my systems during the packet generation. Looks
like some internal bug. So, it's better to skip instead of failing in this
case. I kept the import check, because it's more visual for the user, i.e.
it clearly suggests a missing dependency.
What do you think?
> +
> 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])
> @@ -254,22 +261,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])
> +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])
> @@ -280,13 +292,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) &
This configuration test doesn't seem to need any packets generated.
And so it doesn't seem to need a scapy dependency. Or am I missing
something?
> +
> AT_CHECK([ovs-appctl dpif-netdev/miniflow-parser-set scalar 1], [2],
> [], [dnl
> Error: unknown argument 1.
> @@ -379,6 +398,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], [
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev