From 2d04bd98ac4196796217705ba40bd32def1e9de7 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Thu, 28 May 2020 11:40:29 -0700 Subject: [PATCH] zebra: handle protodown netlink for vxlan device Frr need to handle protocol down event for vxlan interface. In MLAG scenario, one of the pair switch can put vxlan port to protodown state, followed by tunnel-ip change from anycast IP to individual IP. In absence of protodown handling, evpn end up advertising locally learn EVPN (MAC-IP) routes with individual IP as nexthop. This leads an issue of overwriting locally learn entries as remote on MLAG pair. Ticket:CM-24545 Reviewed By:CCR-10310 Testing Done: In EVPN deployment, restart one of the MLAG daemon, which puts vxlan interfaces in protodown state. FRR treats protodown as oper down for vxlan interfaces. VNI down cleans up/withdraws locally learn routes. Followed by vxlan device UP event, re-advertise locally learn routes. Signed-off-by: Chirag Shah --- zebra/if_netlink.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index db8ee3236c..22be153057 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -1876,6 +1876,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) } else { bool was_bridge_slave, was_bond_slave; uint8_t chgflags = ZEBRA_BRIDGE_NO_ACTION; + zif = ifp->info; /* Interface update. */ if (IS_ZEBRA_DEBUG_KERNEL) @@ -1909,9 +1910,20 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) netlink_to_zebra_link_type(ifi->ifi_type); netlink_interface_update_hw_addr(tb, ifp); + if (tb[IFLA_PROTO_DOWN]) { + uint8_t protodown; + + protodown = *(uint8_t *)RTA_DATA( + tb[IFLA_PROTO_DOWN]); + netlink_proc_dplane_if_protodown(zif, + !!protodown); + } + if (if_is_no_ptm_operative(ifp)) { ifp->flags = ifi->ifi_flags & 0x0000fffff; - if (!if_is_no_ptm_operative(ifp)) { + if (!if_is_no_ptm_operative(ifp) || + CHECK_FLAG(zif->flags, + ZIF_FLAG_PROTODOWN)) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "Intf %s(%u) has gone DOWN", @@ -1956,7 +1968,9 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) } } else { ifp->flags = ifi->ifi_flags & 0x0000fffff; - if (if_is_operative(ifp)) { + if (if_is_operative(ifp) && + !CHECK_FLAG(zif->flags, + ZIF_FLAG_PROTODOWN)) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "Intf %s(%u) has come UP", @@ -1990,15 +2004,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave) zebra_l2if_update_bond_slave(ifp, bond_ifindex, !!bypass); - - if (tb[IFLA_PROTO_DOWN]) { - uint8_t protodown; - - protodown = *(uint8_t *)RTA_DATA( - tb[IFLA_PROTO_DOWN]); - netlink_proc_dplane_if_protodown(ifp->info, - !!protodown); - } } zif = ifp->info; -- 2.39.5