mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-12 14:01:11 +00:00
Merge pull request #1927 from pguibert6WIND/issue_1926
zebra: delete interface that disappeared
This commit is contained in:
commit
02031f109e
@ -1015,6 +1015,54 @@ int netlink_interface_addr(struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* helper function called by if_netlink_change
|
||||
* to delete interfaces in case the interface moved
|
||||
* to an other netns
|
||||
*/
|
||||
static void if_netlink_check_ifp_instance_consistency(uint16_t cmd,
|
||||
struct interface *ifp,
|
||||
ns_id_t ns_id)
|
||||
{
|
||||
struct interface *old_ifp;
|
||||
|
||||
/*
|
||||
* look if interface name is also found on other netns
|
||||
* - only if vrf backend is netns
|
||||
* - do not concern lo interface
|
||||
* - then remove previous one
|
||||
* - for new link case, check found interface is not active
|
||||
*/
|
||||
if (!vrf_is_backend_netns() ||
|
||||
!strcmp(ifp->name, "lo"))
|
||||
return;
|
||||
old_ifp = if_lookup_by_name_not_ns(ns_id, ifp->name);
|
||||
if (!old_ifp)
|
||||
return;
|
||||
if ((cmd == RTM_NEWLINK)
|
||||
&& (CHECK_FLAG(old_ifp->status, ZEBRA_INTERFACE_ACTIVE)))
|
||||
return;
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug("%s %s(%u) %s VRF %u",
|
||||
cmd == RTM_DELLINK ?
|
||||
"RTM_DELLINK replaced by" :
|
||||
"RTM_NEWLINK replaces",
|
||||
ifp->name,
|
||||
old_ifp->ifindex,
|
||||
cmd == RTM_DELLINK ?
|
||||
"in" : "from",
|
||||
old_ifp->vrf_id);
|
||||
/* the found interface replaces the current one
|
||||
* remove it
|
||||
*/
|
||||
if (cmd == RTM_DELLINK)
|
||||
if_delete(ifp);
|
||||
else
|
||||
if_delete(old_ifp);
|
||||
/* the found interface is replaced by the current one
|
||||
* suppress it
|
||||
*/
|
||||
}
|
||||
|
||||
int netlink_link_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
ns_id_t ns_id, int startup)
|
||||
{
|
||||
@ -1175,6 +1223,8 @@ int netlink_link_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
|
||||
zebra_l2if_update_bridge_slave(ifp,
|
||||
bridge_ifindex);
|
||||
if_netlink_check_ifp_instance_consistency(RTM_NEWLINK,
|
||||
ifp, ns_id);
|
||||
} else if (ifp->vrf_id != vrf_id) {
|
||||
/* VRF change for an interface. */
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
@ -1242,6 +1292,8 @@ int netlink_link_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
|
||||
zebra_l2if_update_bridge_slave(ifp,
|
||||
bridge_ifindex);
|
||||
if_netlink_check_ifp_instance_consistency(RTM_NEWLINK,
|
||||
ifp, ns_id);
|
||||
}
|
||||
} else {
|
||||
/* Delete interface notification from kernel */
|
||||
@ -1265,6 +1317,8 @@ int netlink_link_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
|
||||
if (!IS_ZEBRA_IF_VRF(ifp))
|
||||
if_delete_update(ifp);
|
||||
if_netlink_check_ifp_instance_consistency(RTM_DELLINK,
|
||||
ifp, ns_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -252,6 +252,30 @@ struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* this function must be used only if the vrf backend
|
||||
* is a netns backend
|
||||
*/
|
||||
struct interface *if_lookup_by_name_not_ns(ns_id_t ns_id,
|
||||
const char *ifname)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct ns *ns;
|
||||
|
||||
RB_FOREACH (ns, ns_head, &ns_tree) {
|
||||
if (ns->ns_id == ns_id)
|
||||
continue;
|
||||
/* if_delete_update has removed interface
|
||||
* from zns->if_table
|
||||
* so to look for interface, use the vrf list
|
||||
*/
|
||||
ifp = if_lookup_by_name(ifname, (vrf_id_t)ns->ns_id);
|
||||
if (!ifp)
|
||||
continue;
|
||||
return ifp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex)
|
||||
{
|
||||
struct interface *ifp;
|
||||
|
@ -317,6 +317,8 @@ extern void zebra_if_init(void);
|
||||
extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, uint32_t);
|
||||
extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *,
|
||||
const char *);
|
||||
extern struct interface *if_lookup_by_name_not_ns(ns_id_t ns_id,
|
||||
const char *ifname);
|
||||
extern struct interface *if_link_per_ns(struct zebra_ns *, struct interface *);
|
||||
extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user