[ovs-dev] [PATCH v2 2/3] system-dpdk: Use dummy-pmd port for packet injection.

Eelco Chaudron echaudro at redhat.com
Wed Nov 24 16:07:38 UTC 2021


On 23 Nov 2021, at 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 <i.maximets at ovn.org>
> Signed-off-by: David Marchand <david.marchand at redhat.com>

One small nit below, rest looks good!

> ---
> Changes since v1:
> - renamed generator script,
> - decreased packet count for fuzzy test,
> - simplified wait expression for packet count,
>
> ---
>  tests/automake.mk           |   5 ++--
>  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        |  30 +++++++++++++++----
>  6 files changed, 84 insertions(+), 43 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 43731d0973..c519a5cb36 100644
> --- a/tests/automake.mk
> +++ b/tests/automake.mk
> @@ -145,8 +145,7 @@ $(srcdir)/tests/fuzz-regression-list.at: tests/automake.mk
>
>  EXTRA_DIST += $(MFEX_AUTOVALIDATOR_TESTS)
>  MFEX_AUTOVALIDATOR_TESTS = \
> -	tests/pcap/mfex_test.pcap \
> -	tests/mfex_fuzzy.py
> +	tests/genpkts.py
>
>  OVSDB_CLUSTER_TESTSUITE_AT = \
>  	tests/ovsdb-cluster-testsuite.at \
> @@ -518,7 +517,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..e243bb960f
> --- /dev/null
> +++ b/tests/genpkts.py
> @@ -0,0 +1,56 @@
> +#!/usr/bin/python3

Maybe change this to “#!/usr/bin/env python3” as other scripts have.

> +
> +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()]
> +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..0000000000000000000000000000000000000000
> GIT binary patch
> literal 0
> HcmV?d00001
>
> literal 416
> zcmca|c+)~A1{MYw`2U}Qff2}Q<eHVR>K`M68ITRa|G at 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 c6708caaf0..b3614f0565 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.
> @@ -59,7 +59,7 @@ m4_define([OVS_DPDK_START],
>     AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true])
>
>     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 2f45613171..7b5d063f62 100644
> --- a/tests/system-dpdk.at
> +++ b/tests/system-dpdk.at
> @@ -230,17 +230,23 @@ 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])
> @@ -253,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])
> +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])
> @@ -283,9 +294,14 @@ 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.
> @@ -378,6 +394,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



More information about the dev mailing list