[ovs-dev] bond/mirror: fix duplicate output when mix bond and mirror

? ? kevinhuangs at hotmail.com
Fri Apr 5 13:24:07 UTC 2019


Hi,

The following link series discussed a bug and its patch to fix it when involves mirror and bond:
https://mail.openvswitch.org/pipermail/ovs-dev/2018-February/344053.html #Link1 https://mail.openvswitch.org/pipermail/ovs-dev/2018-February/344172.html

I test the master branch (till commit 63c71), still can reproduce the problem by the below script (bond_mirror_bug.sh, it can be viewed as complementary script of #Link1 above). The script actually implements the following topology. 

 +---------------------+ bond1       bond2 +--------------------+
 |                 ovs1.....................e1                  |
 |                 ovs2+-------------------+e2                  |
 |       br1           |                   |         br2        |
 | ovs3    ovs4   ovs5 |                   |                    |
 +--+-------+------+---+                   +--------------------+
    |       |      |
   e3      e4     e5
         mirror
         dest

Note:
1) This script may be changed to an autotest case without net namespace and no veth pair, but I failed to so first time, and I didn't to go
  further investigation why failed. 
2) One mirror for the condition to happen is insufficient, so I use 2 mirrors.

To see the script bond_mirror_bug.sh(below) to reproduce the bug:
1. run ovs
2. run bond_mirror_bug.sh
3. ping from e3 to e5 by: ip netns exec ns3 ping 1.1.1.5 4. will see duplicate output in another terminal by: ip netns exec ns4 tcpdump -lni e4 icmp, like
18:29:50.356586 IP 1.1.1.3 > 1.1.1.5: ICMP echo request, id 37991, seq 40, length 64
18:29:50.356592 IP 1.1.1.3 > 1.1.1.5: ICMP echo request, id 37991, seq 40, length 64
18:29:51.357221 IP 1.1.1.3 > 1.1.1.5: ICMP echo request, id 37991, seq 41, length 64
18:29:51.357230 IP 1.1.1.3 > 1.1.1.5: ICMP echo request, id 37991, seq 41, length 64
18:29:52.357034 IP 1.1.1.3 > 1.1.1.5: ICMP echo request, id 37991, seq 42, length 64
18:29:52.357044 IP 1.1.1.3 > 1.1.1.5: ICMP echo request, id 37991, seq 42, length 64

# ovs-appctl dpif/dump-flows br1|grep hash recirc_id(0),in_port(5),eth(src=2a:c9:d2:48:af:7f,dst=ee:d9:32:14:0c:d8),eth_type(0x0800),ipv4(frag=no), packets:20, bytes:1960, used:0.955s, actions:push_vlan(vid=44,pcp=0),10,pop_vlan,7,push_vlan(vid=44,pcp=0),hash(l4(0)),recirc(0x9),pop_vlan,8
recirc_id(0x9),dp_hash(0x39/0xff),in_port(5),eth(),eth_type(0x8100),vlan(vid=44,pcp=0),encap(eth_type(0x0800),ipv4(frag=no)), packets:20, bytes:2040, used:0.955s, actions:1,pop_vlan,7

You will see packets from mirror source are output to mirror destination port 7 twice (both output without vlan tag).

# ovs-appctl dpif/show
netdev at ovs-netdev: hit:0 missed:0
  br0:
    br0 65534/1: (tap)
system at ovs-system: hit:8857 missed:47655
  br1:
    br1 65534/10: (internal)
    ovs1 41/1: (system)
    ovs2 43/6: (system)
    ovs3 42/5: (system)
    ovs4 44/7: (system)
    ovs5 45/8: (system)
  br2:
    br2 65534/3: (internal)
    e1 22/4: (system)
    e2 21/2: (system)
    ovs6 19/9: (system)

# ovs-vsctl show
5d252700-fc31-4ae2-9149-a3f9b3e99352
    Bridge "br1"
        Port "br1"
            Interface "br1"
                type: internal
        Port "ovs3"
            tag: 199
            Interface "ovs3"
        Port "ovs4"
            tag: 199
            Interface "ovs4"
        Port "ovs5"
            tag: 199
            Interface "ovs5"
        Port "bond1"
            Interface "ovs2"
            Interface "ovs1"
    Bridge "br2"
        Port "bond2"
            Interface "e1"
            Interface "e2"
        Port "br2"
            Interface "br2"
                type: internal
    ovs_version: "2.11.90"

cat bond_mirror_bug.sh
#!/bin/bash

set_line() {
    NS=$1
    PNAME=$2
    SNAME=$3
    IPADDR=$4
    if test "$NS" != "nons"; then
        if ip netns list | grep -E "\b$NS\b"; then
            :;
        else
            ip netns add $NS
        fi
    fi
    ip link add name $SNAME type veth peer name $PNAME  # pname public, sname in namespace
    ip l set dev $SNAME up
    ip l set dev $PNAME up
    if test "$NS" != "nons"; then
        ip link set $SNAME netns $NS
        ip netns exec $NS ip addr add $IPADDR dev $SNAME
        ip netns exec $NS ip link set $SNAME up
        ip netns exec $NS ip link set lo up
    fi
    ip link set $PNAME up
}

ip netns del ns3
ip netns del ns4
ip netns del ns5
ip l del dev ovs1
ip l del dev ovs2
ip l del dev ovs3
ip l del dev ovs4
ip l dev dev ovs5
set_line nons ovs1 e1 1.1.1.1/16
set_line nons ovs2 e2 1.1.1.2/16
set_line ns3 ovs3 e3 1.1.1.3/16
set_line ns4 ovs4 e4 1.1.1.4/16
set_line ns5 ovs5 e5 1.1.1.5/16

br=br1
bond_iface1=ovs1
bond_iface2=ovs2

src_port=ovs3
mirror_port=ovs4

ovs-vsctl --if-exists del-br $br -- add-br $br \
    -- add-bond $br bond1 $bond_iface1 $bond_iface2 bond_mode=balance-tcp lacp=active \
    -- --if-exists del-br br2 -- add-br br2 \
    -- add-bond br2 bond2 e1 e2 bond_mode=balance-tcp lacp=active \
    -- add-port $br $mirror_port tag=199 \
    -- add-port $br $src_port tag=199 \
    -- add-port $br ovs5 tag=199 

ovs-vsctl set Bridge $br mirrors=@m -- \
    --id=@ovs3 get Port ovs3 -- \
    --id=@m create Mirror select_all=false name=m select_src_port=@ovs3 output_vlan=44

ovs-vsctl add Bridge $br mirrors @m2 -- \
    --id=@ovs4 get Port ovs4 -- \
    --id=@m2 create Mirror select_all=true name=m2 select_vlan=44 output_port=@ovs4






More information about the dev mailing list