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

David Marchand david.marchand at redhat.com
Thu Nov 25 14:19:53 UTC 2021


On Wed, Nov 24, 2021 at 5:08 PM Eelco Chaudron <echaudro at redhat.com> wrote:
>
> 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!

Thanks for the review.

I did another pass.

I see issues in the documentation that still describes use of pcap pmd.
And some more nits below.


>
> > ---
> > 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

With the pcap file now dropped, this block is useless and can be dropped.
genpkts.py is already added to EXTRA_DIST via CHECK_PYFILES.


> >
> >  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.

"Not my fault", but ok, I can change it :-).

I think this file is also missing a copyright banner from Intel.
Not sure it is important, but this is not my place to touch this.


>
> > +
> > +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()

Missing a:
AT_SKIP_IF([! $PYTHON3 -c "import scapy"], [], [])


> >
> >  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()

Missing a:
AT_SKIP_IF([! $PYTHON3 -c "import scapy"], [], [])

> >  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


-- 
David Marchand



More information about the dev mailing list