diff options
| -rw-r--r-- | lib/if.c | 64 | ||||
| -rw-r--r-- | zebra/if_netlink.c | 67 | ||||
| -rw-r--r-- | zebra/interface.c | 33 | ||||
| -rw-r--r-- | zebra/interface.h | 2 |
4 files changed, 43 insertions, 123 deletions
@@ -371,37 +371,47 @@ struct interface *if_lookup_prefix(struct prefix *prefix, vrf_id_t vrf_id) one. */ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, int vty) { - struct interface *ifp; + struct interface *ifp = NULL; - ifp = if_lookup_by_name(name, vrf_id); - if (ifp) - return ifp; - /* Not Found on same VRF. If the interface command - * was entered in vty without a VRF (passed as VRF_DEFAULT), - * accept the ifp we found. If a vrf was entered and there is - * a mismatch, reject it if from vty. - */ - ifp = if_lookup_by_name_all_vrf(name); - if (!ifp) + if (vrf_is_mapped_on_netns(vrf_lookup_by_id(vrf_id))) { + ifp = if_lookup_by_name(name, vrf_id); + if (ifp) + return ifp; + if (vty) { + /* If the interface command was entered in vty without a + * VRF (passed as VRF_DEFAULT), search an interface with + * this name in all VRs + */ + if (vrf_id == VRF_DEFAULT) + return if_lookup_by_name_all_vrf(name); + return NULL; + } return if_create(name, vrf_id); - if (vty) { - if (vrf_id == VRF_DEFAULT) + } else { + ifp = if_lookup_by_name_all_vrf(name); + if (ifp) { + if (ifp->vrf_id == vrf_id) + return ifp; + /* Found a match on a different VRF. If the interface + * command was entered in vty without a VRF (passed as + * VRF_DEFAULT), accept the ifp we found. If a vrf was + * entered and there is a mismatch, reject it if from + * vty. If it came from the kernel or by way of zclient, + * believe it and update the ifp accordingly. + */ + if (vty) { + if (vrf_id == VRF_DEFAULT) + return ifp; + return NULL; + } + /* If it came from the kernel or by way of zclient, + * believe it and update the ifp accordingly. + */ + if_update_to_new_vrf(ifp, vrf_id); return ifp; - return NULL; - } - /* if vrf backend uses NETNS, then - * this should not be considered as an update - * then create the new interface - */ - if (ifp->vrf_id != vrf_id && vrf_is_mapped_on_netns( - vrf_lookup_by_id(vrf_id))) + } return if_create(name, vrf_id); - /* If it came from the kernel - * or by way of zclient, believe it and update - * the ifp accordingly. - */ - if_update_to_new_vrf(ifp, vrf_id); - return ifp; + } } void if_set_index(struct interface *ifp, ifindex_t ifindex) diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index a15d914243..1fc3e61a3b 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -1042,67 +1042,6 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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 *other_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; - other_ifp = if_lookup_by_name_not_ns(ns_id, ifp->name); - if (!other_ifp) - return; - /* because previous interface may be inactive, - * interface is moved back to default vrf - * then one may find the same pointer; ignore - */ - if (other_ifp == ifp) - return; - if ((cmd == RTM_NEWLINK) - && (CHECK_FLAG(other_ifp->status, ZEBRA_INTERFACE_ACTIVE))) - return; - if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_NEWLINK) { - zlog_debug("RTM_NEWLINK %s(%u, VRF %u) replaces %s(%u, VRF %u)\n", - ifp->name, - ifp->ifindex, - ifp->vrf_id, - other_ifp->name, - other_ifp->ifindex, - other_ifp->vrf_id); - } else if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_DELLINK) { - zlog_debug("RTM_DELLINK %s(%u, VRF %u) is replaced by %s(%u, VRF %u)\n", - ifp->name, - ifp->ifindex, - ifp->vrf_id, - other_ifp->name, - other_ifp->ifindex, - other_ifp->vrf_id); - } - /* the found interface replaces the current one - * remove it - */ - if (cmd == RTM_DELLINK) - if_delete(ifp); - else - if_delete(other_ifp); - /* the found interface is replaced by the current one - * suppress it - */ -} - int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) { int len; @@ -1276,8 +1215,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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) @@ -1351,8 +1288,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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 */ @@ -1376,8 +1311,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (!IS_ZEBRA_IF_VRF(ifp)) if_delete_update(ifp); - if_netlink_check_ifp_instance_consistency(RTM_DELLINK, - ifp, ns_id); } return 0; diff --git a/zebra/interface.c b/zebra/interface.c index 763931d350..bb87728b5d 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -202,7 +202,6 @@ struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp) if (rn->info) { ifp = (struct interface *)rn->info; route_unlock_node(rn); /* get */ - ifp->node = rn; return ifp; } @@ -253,30 +252,6 @@ 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; @@ -753,8 +728,12 @@ void if_delete_update(struct interface *ifp) ifp->node = NULL; /* if the ifp is in a vrf, move it to default so vrf can be deleted if - * desired */ - if (ifp->vrf_id) + * desired. This operation is not done for netns implementation to avoid + * collision with interface with the same name in the default vrf (can + * occur with this implementation whereas it is not possible with + * vrf-lite). + */ + if ((ifp->vrf_id) && !vrf_is_backend_netns()) if_handle_vrf_change(ifp, VRF_DEFAULT); /* Reset some zebra interface params to default values. */ diff --git a/zebra/interface.h b/zebra/interface.h index 9634bfdb3f..2add0a2de6 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -324,8 +324,6 @@ 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); |
