mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 10:37:29 +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;
|
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,
|
int netlink_link_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||||
ns_id_t ns_id, int startup)
|
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))
|
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
|
||||||
zebra_l2if_update_bridge_slave(ifp,
|
zebra_l2if_update_bridge_slave(ifp,
|
||||||
bridge_ifindex);
|
bridge_ifindex);
|
||||||
|
if_netlink_check_ifp_instance_consistency(RTM_NEWLINK,
|
||||||
|
ifp, ns_id);
|
||||||
} else if (ifp->vrf_id != vrf_id) {
|
} else if (ifp->vrf_id != vrf_id) {
|
||||||
/* VRF change for an interface. */
|
/* VRF change for an interface. */
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
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)
|
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
|
||||||
zebra_l2if_update_bridge_slave(ifp,
|
zebra_l2if_update_bridge_slave(ifp,
|
||||||
bridge_ifindex);
|
bridge_ifindex);
|
||||||
|
if_netlink_check_ifp_instance_consistency(RTM_NEWLINK,
|
||||||
|
ifp, ns_id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Delete interface notification from kernel */
|
/* 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 (!IS_ZEBRA_IF_VRF(ifp))
|
||||||
if_delete_update(ifp);
|
if_delete_update(ifp);
|
||||||
|
if_netlink_check_ifp_instance_consistency(RTM_DELLINK,
|
||||||
|
ifp, ns_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -252,6 +252,30 @@ struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns,
|
|||||||
return NULL;
|
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)
|
const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
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_index_per_ns(struct zebra_ns *, uint32_t);
|
||||||
extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *,
|
extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *,
|
||||||
const char *);
|
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 struct interface *if_link_per_ns(struct zebra_ns *, struct interface *);
|
||||||
extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int);
|
extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user