From: anlan_cs Date: Mon, 1 Aug 2022 07:30:07 +0000 (-0400) Subject: zebra: fix bond down for evpn-mh X-Git-Tag: frr-8.5.1~620^2 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=df6c1982691df0f7a4712f1618fac2e15d076335;p=mirror_frr.git zebra: fix bond down for evpn-mh The test case is with `redirect-off` in evpn multi-homing environment: ``` evpn mh redirect-off ``` After the environment is setup, do the following steps: 1) Let one member of ES learn one mac: ``` 2e:52:bb:bb:2f:46 dev ae1 vlan 100 master bridge0 static ``` Now everything is ok and the mac can be synced to other ES peers. 2) Shutdown bond1. At this time, zebra will get three netlink messages, not one as current code expected. Like: ``` e4:f0:04:89:b6:46 dev vxlan10030 vlan 30 master bridge0 static <-A e4:f0:04:89:b6:46 dev vxlan10030 nhid 536870913 self extern_learn <-B e4:f0:04:89:b6:46 dev vxlan10030 vlan 30 self <-C ``` With A), zebra will wrongly remove this mac again: ``` ZEBRA: dpAdd remote MAC e4:f0:04:89:b6:46 VID 30 ZEBRA: Add/update remote MAC e4:f0:04:89:b6:46 intf vxlan10030(26) VNI 10030 flags 0xa01 - del local ZEBRA: Send MACIP Del f None MAC e4:f0:04:89:b6:46 IP (null) seq 0 L2-VNI 10030 ESI - to bgp ``` With C), zebra will wrongly add this mac again: ``` ZEBRA: Rx RTM_NEWNEIGH AF_BRIDGE IF 26 VLAN 30 st 0x2 fl 0x2 MAC e4:f0:04:89:b6:46 nhg 0 ZEBRA: dpAdd remote MAC e4:f0:04:89:b6:46 VID 30 ``` zebra should skip the two messages with `vid`. Otherwise, it will send many *wrong* messages to bgpd, and the logic is wrong. `nhg/dst` is in 2nd message without `vid`, it is useful to call `zebra_evpn_add_update_local_mac()`. But it will fail with "could not find EVPN" warning for no `vid`, can't call `zebra_evpn_add_update_local_mac()`: With B): ``` ZEBRA: Rx RTM_NEWNEIGH AF_BRIDGE IF 26 st 0x2 fl 0x12 MAC e4:f0:04:89:b6:46 nhg 536870913 ZEBRA: dpAdd local-nw-MAC e4:f0:04:89:b6:46 VID 0 ZEBRA: Add/Update MAC e4:f0:04:89:b6:46 intf ae1(18) VID 0, could not find EVPN ``` Here, we can get `vid` from vxlan interface instead of from netlink message. In summary, `zebra_vxlan_dp_network_mac_add()` will process the three messages wrongly expecting only one messsage, so its logic is wrong. Just skip the two unuseful messages with `vid`. Signed-off-by: anlan_cs --- diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index dbe1ce3e4..49689c6ac 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -4038,6 +4038,19 @@ int zebra_vxlan_dp_network_mac_add(struct interface *ifp, struct zebra_evpn_es *es; struct interface *acc_ifp; + /* If netlink message is with vid, it will have no nexthop. + * So skip it. + */ + if (vid) { + if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) + zlog_debug("dpAdd MAC %pEA VID %u - ignore as no nhid", + macaddr, vid); + return 0; + } + + /* Get vxlan's vid for netlink message has no it. */ + vid = ((struct zebra_if *)ifp->info)->l2info.vxl.access_vlan; + /* if remote mac delete the local entry */ if (!nhg_id || !zebra_evpn_nhg_is_local_es(nhg_id, &es) || !zebra_evpn_es_local_mac_via_network_port(es)) {