[ovs-discuss] RSTP: ARP frames not flooded to internal interfaces when RSTP is enabled before virtual interfaces are created

Matthias May matthias.may at neratec.com
Tue Aug 8 13:00:01 UTC 2017


Hi
I'm observing some strange behaviour when configuring RSTP in combination with internal interfaces other than the br
interface itself.

I have 3 interfaces (eth0, 1, 2)
eth1 and eth2 are used with other devices to form a ring (hence rstp is in use).
Since eth1 and eth2 are connected to a hardware switch which offloads unicast forwarding they have the protected flag
set to prevent duplication of broadcast/multicast frames.
eth0 is not connected.

I use the following commands to configure the bridge:

ovs-vsctl add-br br0
ovs-vsctl -- set bridge br0 other-config:hwaddr=00:14:5a:03:52:05
ovs-vsctl -- set Bridge br0 other_config:rstp-priority=32768
ovs-vsctl -- set Bridge br0 other_config:rstp-forward-delay=15
ovs-vsctl -- set Bridge br0 other_config:rstp-max-age=20
ovs-vsctl -- set Bridge br0 other_config:rstp-transmit-hold-count=6
ovs-vsctl -- set Bridge br0 rstp_enable=true
ip l s br0 down

ovs-vsctl add-port br0 eth0
ovs-vsctl -- set port eth0 trunks=[]
ovs-vsctl -- set port eth0 tag=[]
ovs-vsctl -- set port eth0 vlan_mode=trunk
ovs-vsctl -- set port eth0 protected=false
ovs-vsctl -- set Interface eth0 ofport_request=100
ovs-vsctl -- set Port eth0 other_config:rstp-port-priority=128
ovs-vsctl -- set Port eth0 other_config:rstp-port-auto-edge=true
ovs-vsctl -- remove Port eth0 other_config rstp-path-cost
ovs-vsctl -- set Port eth0 other_config:rstp-enable=true
ip l s eth0 up

ovs-vsctl add-port br0 eth1
ovs-vsctl -- set port eth1 trunks=[]
ovs-vsctl -- set port eth1 tag=[]
ovs-vsctl -- set port eth1 vlan_mode=trunk
ovs-vsctl -- set port eth1 protected=true
ovs-vsctl -- set Interface eth1 ofport_request=101
ovs-vsctl -- set Port eth1 other_config:rstp-port-priority=128
ovs-vsctl -- set Port eth1 other_config:rstp-port-auto-edge=false
ovs-vsctl -- remove Port eth1 other_config rstp-path-cost
ovs-vsctl -- set Port eth1 other_config:rstp-enable=true
ip l s eth1 up

ovs-vsctl add-port br0 eth2
ovs-vsctl -- set port eth2 trunks=[]
ovs-vsctl -- set port eth2 tag=[]
ovs-vsctl -- set port eth2 vlan_mode=trunk
ovs-vsctl -- set port eth2 protected=true
ovs-vsctl -- set Interface eth2 ofport_request=102
ovs-vsctl -- set Port eth2 other_config:rstp-port-priority=128
ovs-vsctl -- set Port eth2 other_config:rstp-port-auto-edge=false
ovs-vsctl -- remove Port eth2 other_config rstp-path-cost
ovs-vsctl -- set Port eth2 other_config:rstp-enable=true
ip l s eth2 up

ovs-vsctl add-port br0 br0.vlan0
ovs-vsctl -- set interface br0.vlan0 type=internal
ovs-vsctl -- set port br0.vlan0 tag=0
ovs-vsctl -- set interface br0.vlan0 "mac=\"00:14:5a:03:52:05\""
ip l s br0.vlan0 up
ip a a 192.168.1.20/24 brd + dev br0.vlan0

RSTP is enabled directly when creating the bridge to prevent a look before the interfaces are added to the bridge.

Resulting in:
root at RM4:~# ovs-dpctl show
system at ovs-system:
        lookups: hit:190 missed:84 lost:
        flows: 5
        masks: hit:268 total:3 hit/pkt:0.98
        port 0: ovs-system (internal)
        port 1: br0 (internal)
        port 2: eth0
        port 3: eth1
        port 4: eth2
        port 5: br0.vlan0 (internal: open failed (File exists))

Notice that br0 is down and the IP is on br0.vlan0.
Now if I try to ping 192.168.1.20 ARP requests are not answered.
and I see in the datapath dump:

root at RM4:~# ovs-dpctl dump-flows
recirc_id(0),in_port(4),eth(dst=01:80:c2:00:00:00),eth_type(0/0xffff), packets:46, bytes:2760, used:1.417s,
actions:userspace(pid=4192251794,slow_path(stp))
recirc_id(0),in_port(3),eth(src=e8:39:35:34:d4:60,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.1.2,tip=192.168.1.20,op=1/0xff),
packets:70, bytes:4200, used:0.633s, actions:1
recirc_id(0),in_port(3),eth(src=00:14:5a:09:15:7c,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0800),ipv4(frag=no), packets:31,
bytes:10602, used:0.225s, actions:1
recirc_id(0),in_port(3),eth(dst=01:80:c2:00:00:00),eth_type(0/0xffff), packets:47, bytes:2820, used:0.069s,
actions:userspace(pid=4192251794,slow_path(stp))

For some reason the ARP frames are not flooded to all ports as they should but only to port 1.


As a workaround I moved
ovs-vsctl -- set Bridge br0 rstp_enable=true
to the end and is executed after br0.vlan0 is created.
With this everything works as expected.
However this allows for a short window where the interfaces are already in the bridge but RSTP is not enabled yet.

--> commands:
ovs-vsctl add-br br0
ovs-vsctl -- set bridge br0 other-config:hwaddr=00:14:5a:03:52:05
ovs-vsctl -- set Bridge br0 other_config:rstp-priority=32768
ovs-vsctl -- set Bridge br0 other_config:rstp-forward-delay=15
ovs-vsctl -- set Bridge br0 other_config:rstp-max-age=20
ovs-vsctl -- set Bridge br0 other_config:rstp-transmit-hold-count=6
ip l s br0 down

ovs-vsctl add-port br0 eth0
ovs-vsctl -- set port eth0 trunks=[]
ovs-vsctl -- set port eth0 tag=[]
ovs-vsctl -- set port eth0 vlan_mode=trunk
ovs-vsctl -- set port eth0 protected=false
ovs-vsctl -- set Interface eth0 ofport_request=100
ovs-vsctl -- set Port eth0 other_config:rstp-port-priority=128
ovs-vsctl -- set Port eth0 other_config:rstp-port-auto-edge=true
ovs-vsctl -- remove Port eth0 other_config rstp-path-cost
ovs-vsctl -- set Port eth0 other_config:rstp-enable=true
ip l s eth0 up

ovs-vsctl add-port br0 eth1
ovs-vsctl -- set port eth1 trunks=[]
ovs-vsctl -- set port eth1 tag=[]
ovs-vsctl -- set port eth1 vlan_mode=trunk
ovs-vsctl -- set port eth1 protected=true
ovs-vsctl -- set Interface eth1 ofport_request=101
ovs-vsctl -- set Port eth1 other_config:rstp-port-priority=128
ovs-vsctl -- set Port eth1 other_config:rstp-port-auto-edge=false
ovs-vsctl -- remove Port eth1 other_config rstp-path-cost
ovs-vsctl -- set Port eth1 other_config:rstp-enable=true
ip l s eth1 up

ovs-vsctl add-port br0 eth2
ovs-vsctl -- set port eth2 trunks=[]
ovs-vsctl -- set port eth2 tag=[]
ovs-vsctl -- set port eth2 vlan_mode=trunk
ovs-vsctl -- set port eth2 protected=true
ovs-vsctl -- set Interface eth2 ofport_request=102
ovs-vsctl -- set Port eth2 other_config:rstp-port-priority=128
ovs-vsctl -- set Port eth2 other_config:rstp-port-auto-edge=false
ovs-vsctl -- remove Port eth2 other_config rstp-path-cost
ovs-vsctl -- set Port eth2 other_config:rstp-enable=true
ip l s eth2 up

ovs-vsctl add-port br0 br0.vlan0
ovs-vsctl -- set interface br0.vlan0 type=internal
ovs-vsctl -- set port br0.vlan0 tag=0
ovs-vsctl -- set interface br0.vlan0 "mac=\"00:14:5a:03:52:05\""
ip l s br0.vlan0 up
ip a a 192.168.1.20/24 brd + dev br0.vlan0

ovs-vsctl -- set Bridge br0 rstp_enable=true


!Notice that rstp_enable=true is set at the end.

This results again in:
root at RM4:~# ovs-dpctl show
system at ovs-system:
        lookups: hit:32 missed:183 lost:0
        flows: 0
        masks: hit:211 total:0 hit/pkt:0.98
        port 0: ovs-system (internal)
        port 1: br0 (internal)
        port 2: eth0
        port 3: eth1
        port 4: eth2
        port 5: br0.vlan0 (internal: open failed (File exists))

However the flow dump shows:
root at RM4:~# ovs-dpctl dump-flows
recirc_id(0),in_port(3),eth(src=e8:39:35:34:d4:60,dst=00:14:5a:03:52:05),eth_type(0x0800),ipv4(frag=no), packets:2,
bytes:196, used:0.940s, actions:5
recirc_id(0),in_port(3),eth(src=00:14:5a:09:15:7c,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0800),ipv4(frag=no), packets:0,
bytes:0, used:never, actions:1,5
recirc_id(0),in_port(3),eth(dst=01:80:c2:00:00:00),eth_type(0/0xffff), packets:1, bytes:60, used:1.273s,
actions:userspace(pid=3595029779,slow_path(stp))
recirc_id(0),in_port(4),eth(dst=01:80:c2:00:00:00),eth_type(0/0xffff), packets:1, bytes:60, used:1.353s,
actions:userspace(pid=3595029779,slow_path(stp))
recirc_id(0),in_port(5),eth(src=00:14:5a:03:52:05,dst=e8:39:35:34:d4:60),eth_type(0x0800),ipv4(frag=no), packets:2,
bytes:196, used:0.941s, actions:3
recirc_id(0),in_port(3),eth(src=e8:39:35:34:d4:60,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.1.2,tip=192.168.1.99,op=1/0xff),
packets:2, bytes:120, used:0.205s, actions:1,5

The ping to 192.168.1.20 works as expected.
I've run a ping to 192.168.1.99 which doesn't exist to see the flow which floods the ARP frame to all virtual ports
(1,5) and not only port 1 (br0).


Does anyone have any insight as why this happens?
What can I do to help debug this?

BR
Matthias


More information about the discuss mailing list