From 41414503e41e1d50513d8e7ba3bf6d4562dde77f Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Fri, 28 Apr 2023 13:39:59 +0800 Subject: [PATCH] zebra: Fix missing VRF flag 1. No any configuration in FRR, and `ip link add vrf1 type vrf ...`. Currently, everything is ok. 2. `ip link del vrf1`. `zebra` will wrongly/redundantly notify clients to add "vrf1" as a normal interface after correct deletion of "vrf1". ``` ZEBRA: [KMXEB-K771Y] netlink_parse_info: netlink-listen (NS 0) type RTM_DELLINK(17), len=588, seq=0, pid=0 ZEBRA: [TDJW2-B9KJW] RTM_DELLINK for vrf1(93) <- Wrongly as normal interface, not vrf ZEBRA: [WEEJX-M4HA0] interface vrf1 vrf vrf1(93) index 93 is now inactive. ZEBRA: [NXAHW-290AC] MESSAGE: ZEBRA_INTERFACE_DELETE vrf1 vrf vrf1(93) ZEBRA: [H97XA-ABB3A] MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL vrf1 VRF Id 93 -> 0 ZEBRA: [HP8PZ-7D6D2] MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD vrf1 VRF Id 93 -> 0 <- ZEBRA: [Y6R2N-EF2N4] interface vrf1 is being deleted from the system ZEBRA: [KNFMR-AFZ53] RTM_DELLINK for VRF vrf1(93) ZEBRA: [P0CZ5-RF5FH] VRF vrf1 id 93 is now inactive ZEBRA: [XC3P3-1DG4D] MESSAGE: ZEBRA_VRF_DELETE vrf1 ZEBRA: [ZMS2F-6K837] VRF vrf1 id 4294967295 deleted OSPF: [JKWE3-97M3J] Zebra: interface add vrf1 vrf default[0] index 0 flags 480 metric 0 mtu 65575 speed 0 <- Wrongly add interface ``` `if_handle_vrf_change()` moved the interface from specific vrf to default vrf. But it doesn't skip interface of vrf type. So, the wrong/redundant add operation is done. Note, the wrong add operation is regarded as an normal interface because the `ifp->status` is cleared too early, so it is without VRF flag ( `ZEBRA_INTERFACE_VRF_LOOPBACK` ). Now, ospfd will initialize `ifp->type` to `OSPF_IFTYPE_BROADCAST`. 3. `ip link add vrf1 type vrf ...`, add "vrf1" again. FRR will be with wrong display: ``` interface vrf1 ip ospf network broadcast exit ``` Here, zebra will send `ZEBRA_INTERFACE_ADD` again for "vrf1" with correct `ifp->status`, so it will be updated into vrf type. But it can't update `ifp->type` from `OSPF_IFTYPE_BROADCAST` to `OSPF_IFTYPE_LOOPBACK` because it had been already configured in above step 2. Two changes to fix it: 1. Skip the procedure of switching VRF for interfaces of vrf type. It means, don't send `ZEBRA_INTERFACE_ADD` to clients when deleting vrf. 2. Put the deletion of this flag at the last. It means, clients should get correct `ifp->status`. Signed-off-by: anlan_cs --- zebra/if_netlink.c | 2 -- zebra/interface.c | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 3a325df06c..fcb692b715 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -2323,8 +2323,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) zlog_debug("RTM_DELLINK for %s(%u)", name, ifp->ifindex); - UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK); - if (IS_ZEBRA_IF_BOND(ifp)) zebra_l2if_update_bond(ifp, false); if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) diff --git a/zebra/interface.c b/zebra/interface.c index 496a85e676..231ddc51db 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -800,6 +800,8 @@ void if_delete_update(struct interface **pifp) if (ifp->vrf->vrf_id && !vrf_is_backend_netns()) if_handle_vrf_change(ifp, VRF_DEFAULT); + UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK); + /* Reset some zebra interface params to default values. */ zif = ifp->info; if (zif) { @@ -840,6 +842,9 @@ void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id) /* This is to issue an UPDATE or a DELETE, as appropriate. */ zebra_interface_vrf_update_del(ifp, vrf_id); + if (if_is_vrf(ifp)) + return; + /* update VRF */ if_update_to_new_vrf(ifp, vrf_id);