Recently I've noticed that after vrrp macvlan undelying interface flap vrrp backup starts replying to arp. The backup macvlan interface used for vrrp does not retain oper state and appears oper up after the flap.
Reproduced on a bit dated frr, but I do not see the code in the master that is supposed to handle this.
Version
FRRouting 8.4.4 (debian) on Linux(6.1.0-25-amd64).
How to reproduce
configure 3 namespaces connected with bridge; in 2 namespaces start frr
instances and configure vrrp
#!/bin/sh
[r0]-[br0]-[r1]
|
[h0]
r0 - master, r1 - backup
ip l add br0h0 up type veth peer h0br0
ip l add br0r0 up type veth peer r0br0
ip l add br0r1 up type veth peer r1br0
ip netns add br0
ip netns exec br0 sysctl -w net.ipv6.conf.all.disable_ipv6=1
ip netns exec br0 sysctl -w net.ipv4.ip_forward=0
ip -n br0 l add br0 type bridge
ip l set br0h0 netns br0 arp off
ip l set br0r0 netns br0 arp off
ip l set br0r1 netns br0 arp off
ip -n br0 l set br0h0 up master br0
ip -n br0 l set br0r0 up master br0
ip -n br0 l set br0r1 up master br0
ip -n br0 l set br0 up arp off
ip netns add r0
ip l set r0br0 up netns r0 name eth0
ip netns exec r0 sysctl -w net.ipv4.conf.all.accept_local=0
ip netns exec r0 sysctl -w net.ipv4.conf.all.arp_announce=1
ip netns exec r0 sysctl -w net.ipv4.conf.all.arp_filter=0
ip netns exec r0 sysctl -w net.ipv4.conf.all.arp_ignore=0
ip netns exec r0 sysctl -w net.ipv4.conf.all.rp_filter=0
ip netns exec r0 sysctl -w net.ipv4.conf.eth0.accept_local=1
ip netns exec r0 sysctl -w net.ipv4.conf.eth0.arp_announce=2
ip netns exec r0 sysctl -w net.ipv4.conf.eth0.arp_filter=1
ip netns exec r0 sysctl -w net.ipv4.conf.eth0.arp_ignore=2
ip netns exec r0 sysctl -w net.ipv4.conf.eth0.rp_filter=2
ip -n r0 l set lo up
ip -n r0 l add link name vrrp1 up addr 00:00:5e:00:01:01 link eth0 type macvlan mode bridge
ip netns exec r0 sysctl -w net.ipv4.conf.vrrp1.arp_filter=0
ip netns exec r0 sysctl -w net.ipv4.conf.vrrp1.arp_ignore=1
ip -n r0 a add dev vrrp1 10.0.0.1/32
ip -n r0 r add 10.0.0.0/24 dev eth0
ip netns exec r0 bash -l -c "/usr/lib/frr/frrinit.sh start myfrr0"
vtysh -N myfrr0 -f /dev/stdin <<EOF
!
frr defaults traditional
hostname r0
!
interface eth0
ip address 192.168.67.1/24
exit
!
interface eth0
vrrp 1 version 2
vrrp 1 priority 254
vrrp 1 advertisement-interval 1000
vrrp 1 ip 10.0.0.1
exit
!
line vty
!
EOF
ip netns add r1
ip l set r1br0 up netns r1 name eth0
ip netns exec r1 sysctl -w net.ipv4.conf.all.accept_local=0
ip netns exec r1 sysctl -w net.ipv4.conf.all.arp_announce=1
ip netns exec r1 sysctl -w net.ipv4.conf.all.arp_filter=0
ip netns exec r1 sysctl -w net.ipv4.conf.all.arp_ignore=0
ip netns exec r1 sysctl -w net.ipv4.conf.all.rp_filter=0
ip netns exec r1 sysctl -w net.ipv4.conf.eth0.accept_local=1
ip netns exec r1 sysctl -w net.ipv4.conf.eth0.arp_announce=2
ip netns exec r1 sysctl -w net.ipv4.conf.eth0.arp_filter=1
ip netns exec r1 sysctl -w net.ipv4.conf.eth0.arp_ignore=2
ip netns exec r1 sysctl -w net.ipv4.conf.eth0.rp_filter=2
ip -n r1 l set lo up
ip -n r1 l add link name vrrp1 up addr 00:00:5e:00:01:01 link eth0 type macvlan mode bridge
ip netns exec r1 sysctl -w net.ipv4.conf.vrrp1.arp_filter=0
ip netns exec r1 sysctl -w net.ipv4.conf.vrrp1.arp_ignore=1
ip -n r1 a add dev vrrp1 10.0.0.1/32
ip -n r1 r add 10.0.0.0/24 dev eth0
ip netns exec r1 bash -l -c "/usr/lib/frr/frrinit.sh start myfrr1"
vtysh -N myfrr1 -f /dev/stdin <<EOF
!
frr defaults traditional
hostname r1
!
interface eth0
ip address 192.168.67.2/24
exit
!
interface eth0
vrrp 1 version 2
vrrp 1 priority 253
vrrp 1 advertisement-interval 1000
vrrp 1 ip 10.0.0.1
exit
!
line vty
!
EOF
2. observe there is single arp reply on the network from vrrp router:
3. observe master macvlan is oper up and backup macvlan interface is oper down due to portodown on.
flap backup veth interface from bridge side; simulate carrier down
ip -n r0 l show vrrp1
2: vrrp1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 00:00:5e:00:01:01 brd ff:ff:ff:ff:ff:ff
ip -n r1 l show vrrp1
2: vrrp1@eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN mode DEFAULT group default qlen 1000
link/ether 00:00:5e:00:01:01 brd ff:ff:ff:ff:ff:ff protodown on protodown_reason <7>
ip -n br0 l set br0r1 down; ip -n br0 l set br0r1 up;
4. observe backup macvlan interface is oper up despite protodown is on
ip -n r1 l show vrrp1
2: vrrp1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 00:00:5e:00:01:01 brd ff:ff:ff:ff:ff:ff protodown on protodown_reason <7>
5. observe there are two arp replies on the network from vrrp routers:
ip netns pids h0 | xargs -I_P kill -9 _P
ip netns pids r0 | xargs -I_P kill -9 _P
ip netns pids r1 | xargs -I_P kill -9 _P
ip netns pids br0 | xargs -I_P kill -9 _P
ip netns del h0
ip netns del r0
ip netns del r1
ip netns del br0
### Expected behavior
upon flap macvlan interface is oper down and down not reply to arp
### Actual behavior
upon flap macvlan interface is oper up and does reply to arp
### Additional context
_No response_
### Checklist
- [X] I have searched the open issues for this bug.
- [X] I have not included sensitive information in this report.
Description
Recently I've noticed that after vrrp macvlan undelying interface flap vrrp backup starts replying to arp. The backup macvlan interface used for vrrp does not retain oper state and appears oper up after the flap. Reproduced on a bit dated frr, but I do not see the code in the master that is supposed to handle this.
Version
How to reproduce
[r0]-[br0]-[r1]
|
[h0]
r0 - master, r1 - backup
ip l add br0h0 up type veth peer h0br0 ip l add br0r0 up type veth peer r0br0 ip l add br0r1 up type veth peer r1br0
- br0 config -------------------------------------------------------------------
ip netns add br0 ip netns exec br0 sysctl -w net.ipv6.conf.all.disable_ipv6=1 ip netns exec br0 sysctl -w net.ipv4.ip_forward=0 ip -n br0 l add br0 type bridge ip l set br0h0 netns br0 arp off ip l set br0r0 netns br0 arp off ip l set br0r1 netns br0 arp off ip -n br0 l set br0h0 up master br0 ip -n br0 l set br0r0 up master br0 ip -n br0 l set br0r1 up master br0 ip -n br0 l set br0 up arp off
- h0 config -------------------------------------------------------------------
ip netns add h0 ip -n h0 l set lo up ip l set h0br0 up netns h0 name eth0 ip -n h0 a add dev eth0 10.0.0.2/24
- r0 config -------------------------------------------------------------------
ip netns add r0 ip l set r0br0 up netns r0 name eth0 ip netns exec r0 sysctl -w net.ipv4.conf.all.accept_local=0 ip netns exec r0 sysctl -w net.ipv4.conf.all.arp_announce=1 ip netns exec r0 sysctl -w net.ipv4.conf.all.arp_filter=0 ip netns exec r0 sysctl -w net.ipv4.conf.all.arp_ignore=0 ip netns exec r0 sysctl -w net.ipv4.conf.all.rp_filter=0
ip netns exec r0 sysctl -w net.ipv4.conf.eth0.accept_local=1 ip netns exec r0 sysctl -w net.ipv4.conf.eth0.arp_announce=2 ip netns exec r0 sysctl -w net.ipv4.conf.eth0.arp_filter=1 ip netns exec r0 sysctl -w net.ipv4.conf.eth0.arp_ignore=2 ip netns exec r0 sysctl -w net.ipv4.conf.eth0.rp_filter=2 ip -n r0 l set lo up ip -n r0 l add link name vrrp1 up addr 00:00:5e:00:01:01 link eth0 type macvlan mode bridge ip netns exec r0 sysctl -w net.ipv4.conf.vrrp1.arp_filter=0 ip netns exec r0 sysctl -w net.ipv4.conf.vrrp1.arp_ignore=1 ip -n r0 a add dev vrrp1 10.0.0.1/32 ip -n r0 r add 10.0.0.0/24 dev eth0 ip netns exec r0 bash -l -c "/usr/lib/frr/frrinit.sh start myfrr0" vtysh -N myfrr0 -f /dev/stdin <<EOF ! frr defaults traditional hostname r0 ! interface eth0 ip address 192.168.67.1/24 exit ! interface eth0 vrrp 1 version 2 vrrp 1 priority 254 vrrp 1 advertisement-interval 1000 vrrp 1 ip 10.0.0.1 exit ! line vty ! EOF
- r1 config -------------------------------------------------------------------
ip netns add r1 ip l set r1br0 up netns r1 name eth0 ip netns exec r1 sysctl -w net.ipv4.conf.all.accept_local=0 ip netns exec r1 sysctl -w net.ipv4.conf.all.arp_announce=1 ip netns exec r1 sysctl -w net.ipv4.conf.all.arp_filter=0 ip netns exec r1 sysctl -w net.ipv4.conf.all.arp_ignore=0 ip netns exec r1 sysctl -w net.ipv4.conf.all.rp_filter=0
ip netns exec r1 sysctl -w net.ipv4.conf.eth0.accept_local=1 ip netns exec r1 sysctl -w net.ipv4.conf.eth0.arp_announce=2 ip netns exec r1 sysctl -w net.ipv4.conf.eth0.arp_filter=1 ip netns exec r1 sysctl -w net.ipv4.conf.eth0.arp_ignore=2 ip netns exec r1 sysctl -w net.ipv4.conf.eth0.rp_filter=2 ip -n r1 l set lo up ip -n r1 l add link name vrrp1 up addr 00:00:5e:00:01:01 link eth0 type macvlan mode bridge ip netns exec r1 sysctl -w net.ipv4.conf.vrrp1.arp_filter=0 ip netns exec r1 sysctl -w net.ipv4.conf.vrrp1.arp_ignore=1 ip -n r1 a add dev vrrp1 10.0.0.1/32 ip -n r1 r add 10.0.0.0/24 dev eth0 ip netns exec r1 bash -l -c "/usr/lib/frr/frrinit.sh start myfrr1" vtysh -N myfrr1 -f /dev/stdin <<EOF ! frr defaults traditional hostname r1 ! interface eth0 ip address 192.168.67.2/24 exit ! interface eth0 vrrp 1 version 2 vrrp 1 priority 253 vrrp 1 advertisement-interval 1000 vrrp 1 ip 10.0.0.1 exit ! line vty ! EOF
ip netns exec h0 tcpdump -i eth0 arp & ip netns exec h0 arping 10.0.0.1 & 42 bytes from 00:00:5e:00:01:01 (10.0.0.1): index=0 time=191.263 usec 16:43:16.862708 ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 44 16:43:16.862850 ARP, Reply 10.0.0.1 is-at 00:00:5e:00:01:01 (oui IANA), length 28 42 bytes from 00:00:5e:00:01:01 (10.0.0.1): index=1 time=180.122 usec 16:43:16.862708 ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 44 16:43:16.862850 ARP, Reply 10.0.0.1 is-at 00:00:5e:00:01:01 (oui IANA), length 28 kill %2 kill %1
ip -n r0 l show vrrp1 2: vrrp1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 00:00:5e:00:01:01 brd ff:ff:ff:ff:ff:ff ip -n r1 l show vrrp1 2: vrrp1@eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN mode DEFAULT group default qlen 1000 link/ether 00:00:5e:00:01:01 brd ff:ff:ff:ff:ff:ff protodown on protodown_reason <7> ip -n br0 l set br0r1 down; ip -n br0 l set br0r1 up;
ip -n r1 l show vrrp1 2: vrrp1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 00:00:5e:00:01:01 brd ff:ff:ff:ff:ff:ff protodown on protodown_reason <7>
ip netns exec h0 tcpdump -i eth0 arp & ip netns exec h0 arping 10.0.0.1 & 16:49:25.278566 ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 44 16:49:25.278716 ARP, Reply 10.0.0.1 is-at 00:00:5e:00:01:01 (oui IANA), length 28 16:49:25.278721 ARP, Reply 10.0.0.1 is-at 00:00:5e:00:01:01 (oui IANA), length 28 kill %2 kill %1
ip netns pids h0 | xargs -I_P kill -9 _P ip netns pids r0 | xargs -I_P kill -9 _P ip netns pids r1 | xargs -I_P kill -9 _P ip netns pids br0 | xargs -I_P kill -9 _P ip netns del h0 ip netns del r0 ip netns del r1 ip netns del br0