summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@users.noreply.github.com>2021-04-13 17:26:51 +0200
committerGitHub <noreply@github.com>2021-04-13 17:26:51 +0200
commit54bb4ab3ecba420db3747be357ddfda8787c6f79 (patch)
treedfa8ba19b1baf18468e1b2c756c521863dceec49
parentMerge pull request #8145 from pguibert6WIND/nhrp_use_zebra (diff)
parentlib: fix interface nb stale pointers (diff)
downloadfrr-54bb4ab3ecba420db3747be357ddfda8787c6f79.tar.xz
frr-54bb4ab3ecba420db3747be357ddfda8787c6f79.zip
Merge pull request #8426 from idryzhov/fix-interface-nb-stale-pointers
lib: fix interface nb stale pointers
-rw-r--r--lib/if.c23
-rw-r--r--zebra/if_netlink.c3
2 files changed, 20 insertions, 6 deletions
diff --git a/lib/if.c b/lib/if.c
index 629ef4e70..f8a693d8f 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -1056,15 +1056,30 @@ struct connected *connected_get_linklocal(struct interface *ifp)
void if_terminate(struct vrf *vrf)
{
struct interface *ifp;
+ bool delete;
+
+ /*
+ * If the default VRF is being terminated or has
+ * already been terminated it means that
+ * the program is shutting down and we need to
+ * delete all the interfaces. Otherwise, we only
+ * need to move VRF's interfaces to the default VRF.
+ */
+ delete = vrf_is_backend_netns() || vrf->vrf_id == VRF_DEFAULT
+ || !vrf_lookup_by_id(VRF_DEFAULT);
while (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
ifp = RB_ROOT(if_name_head, &vrf->ifaces_by_name);
- if (ifp->node) {
- ifp->node->info = NULL;
- route_unlock_node(ifp->node);
+ if (delete) {
+ if (ifp->node) {
+ ifp->node->info = NULL;
+ route_unlock_node(ifp->node);
+ }
+ if_delete(&ifp);
+ } else {
+ if_update_to_new_vrf(ifp, VRF_DEFAULT);
}
- if_delete(&ifp);
}
}
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index af2c25160..6aaf9d94f 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -1661,8 +1661,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
else if (IS_ZEBRA_IF_VXLAN(ifp))
zebra_l2_vxlanif_del(ifp);
- if (!IS_ZEBRA_IF_VRF(ifp))
- if_delete_update(ifp);
+ if_delete_update(ifp);
}
return 0;