diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-06-22 13:35:45 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-06-22 13:35:45 -0400 |
| commit | a12bb225a6681b7e7eb0aac105cbc8b745675131 (patch) | |
| tree | adb8d7935dcb1da93d6cf4082f903e412e292640 /lib/if.c | |
| parent | efe42c51c48da8bc89df4891235fb3be0e502cf8 (diff) | |
| parent | a41c4e1b1f577443ad26222704a69649c280cd9e (diff) | |
Merge pull request #3775 from pguibert6WIND/ospf_missing_interface_handling_2
Ospf missing interface handling 2
Diffstat (limited to 'lib/if.c')
| -rw-r--r-- | lib/if.c | 107 |
1 files changed, 60 insertions, 47 deletions
@@ -132,9 +132,8 @@ static int if_cmp_index_func(const struct interface *ifp1, } /* Create new interface structure. */ -struct interface *if_create(const char *name, vrf_id_t vrf_id) +struct interface *if_create(const char *name, struct vrf *vrf) { - struct vrf *vrf = vrf_get(vrf_id, NULL); struct interface *ifp; ifp = XCALLOC(MTYPE_IF, sizeof(struct interface)); @@ -142,7 +141,7 @@ struct interface *if_create(const char *name, vrf_id_t vrf_id) assert(name); strlcpy(ifp->name, name, sizeof(ifp->name)); - ifp->vrf_id = vrf_id; + ifp->vrf = vrf; IFNAME_RB_INSERT(vrf, ifp); ifp->connected = list_new(); ifp->connected->del = (void (*)(void *))connected_free; @@ -158,26 +157,34 @@ struct interface *if_create(const char *name, vrf_id_t vrf_id) return ifp; } -/* Create new interface structure. */ -void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id) +/* Create new interface structure. + * vrf must be created outside of this routing + */ +void if_update_to_new_vrf(struct interface *ifp, struct vrf *vrf) { - struct vrf *old_vrf, *vrf; + struct vrf *old_vrf; + if (!vrf) { + flog_err(EC_LIB_INTERFACE, "interface %s. Unknown VRF", + ifp->name); + return; + } /* remove interface from old master vrf list */ - old_vrf = vrf_lookup_by_id(ifp->vrf_id); + old_vrf = ifp->vrf; if (old_vrf) { IFNAME_RB_REMOVE(old_vrf, ifp); if (ifp->ifindex != IFINDEX_INTERNAL) IFINDEX_RB_REMOVE(old_vrf, ifp); } - ifp->vrf_id = vrf_id; - vrf = vrf_get(ifp->vrf_id, NULL); + ifp->vrf = vrf; IFNAME_RB_INSERT(vrf, ifp); if (ifp->ifindex != IFINDEX_INTERNAL) IFINDEX_RB_INSERT(vrf, ifp); + if (!old_vrf->name) + return; /* * HACK: Change the interface VRF in the running configuration directly, * bypassing the northbound layer. This is necessary to avoid deleting @@ -218,9 +225,8 @@ void if_delete_retain(struct interface *ifp) /* Delete and free interface structure. */ void if_delete(struct interface *ifp) { - struct vrf *vrf; + struct vrf *vrf = ifp->vrf; - vrf = vrf_lookup_by_id(ifp->vrf_id); assert(vrf); IFNAME_RB_REMOVE(vrf, ifp); @@ -265,16 +271,16 @@ const char *ifindex2ifname(ifindex_t ifindex, vrf_id_t vrf_id) ifindex_t ifname2ifindex(const char *name, vrf_id_t vrf_id) { struct interface *ifp; + struct vrf *vrf = vrf_lookup_by_id(vrf_id); - return ((ifp = if_lookup_by_name(name, vrf_id)) != NULL) + return ((ifp = if_lookup_by_name(name, vrf)) != NULL) ? ifp->ifindex : IFINDEX_INTERNAL; } /* Interface existance check by interface name. */ -struct interface *if_lookup_by_name(const char *name, vrf_id_t vrf_id) +struct interface *if_lookup_by_name(const char *name, struct vrf *vrf) { - struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct interface if_tmp; if (!vrf || !name @@ -294,7 +300,7 @@ struct interface *if_lookup_by_name_all_vrf(const char *name) return NULL; RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - ifp = if_lookup_by_name(name, vrf->vrf_id); + ifp = if_lookup_by_name(name, vrf); if (ifp) return ifp; } @@ -419,29 +425,29 @@ size_t if_lookup_by_hwaddr(const uint8_t *hw_addr, size_t addrsz, /* Get interface by name if given name interface doesn't exist create one. */ -struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id) +struct interface *if_get_by_name(const char *name, struct vrf *vrf) { struct interface *ifp; switch (vrf_get_backend()) { case VRF_BACKEND_UNKNOWN: case VRF_BACKEND_NETNS: - ifp = if_lookup_by_name(name, vrf_id); + ifp = if_lookup_by_name(name, vrf); if (ifp) return ifp; - return if_create(name, vrf_id); + return if_create(name, vrf); case VRF_BACKEND_VRF_LITE: ifp = if_lookup_by_name_all_vrf(name); if (ifp) { - if (ifp->vrf_id == vrf_id) + if (ifp->vrf == vrf) return ifp; /* 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); + if_update_to_new_vrf(ifp, vrf); return ifp; } - return if_create(name, vrf_id); + return if_create(name, vrf); } return NULL; @@ -451,7 +457,7 @@ void if_set_index(struct interface *ifp, ifindex_t ifindex) { struct vrf *vrf; - vrf = vrf_lookup_by_id(ifp->vrf_id); + vrf = ifp->vrf; assert(vrf); if (ifp->ifindex == ifindex) @@ -595,7 +601,8 @@ static void if_dump(const struct interface *ifp) zlog_info( "Interface %s vrf %u index %d metric %d mtu %d " "mtu6 %d %s", - ifp->name, ifp->vrf_id, ifp->ifindex, ifp->metric, + ifp->name, vrf_to_id(ifp->vrf), + ifp->ifindex, ifp->metric, ifp->mtu, ifp->mtu6, if_flag_dump(ifp->flags)); } @@ -631,12 +638,12 @@ void if_dump_all(void) * if not: * - no idea, just get the name in its entirety. */ -static struct interface *if_sunwzebra_get(const char *name, vrf_id_t vrf_id) +static struct interface *if_sunwzebra_get(const char *name, struct vrf *vrf) { struct interface *ifp; char *cp; - if ((ifp = if_lookup_by_name(name, vrf_id)) != NULL) + if ((ifp = if_lookup_by_name(name, vrf)) != NULL) return ifp; /* hunt the primary interface name... */ @@ -644,7 +651,7 @@ static struct interface *if_sunwzebra_get(const char *name, vrf_id_t vrf_id) if (cp) *cp = '\0'; - return if_get_by_name(name, vrf_id); + return if_get_by_name(name, vrf); } #endif /* SUNOS_5 */ @@ -777,7 +784,8 @@ connected_log(struct connected *connected, char *str) p = connected->address; snprintf(logbuf, BUFSIZ, "%s interface %s vrf %u %s %s/%d ", str, - ifp->name, ifp->vrf_id, prefix_family_str(p), + ifp->name, vrf_to_id(ifp->vrf), + prefix_family_str(p), inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); p = connected->destination; @@ -1126,9 +1134,9 @@ DEFPY_NOSH (interface, VRF_CMD_HELP_STR) { char xpath_list[XPATH_MAXLEN]; - vrf_id_t vrf_id; - struct interface *ifp; + struct interface *ifp = NULL; int ret; + struct vrf *vrf; if (!vrfname) vrfname = VRF_DEFAULT_NAME; @@ -1140,16 +1148,24 @@ DEFPY_NOSH (interface, * interface is found, then a new one should be created on the default * VRF. */ - VRF_GET_ID(vrf_id, vrfname, false); - ifp = if_lookup_by_name_all_vrf(ifname); - if (ifp && ifp->vrf_id != vrf_id) { - struct vrf *vrf; - + VRF_GET_INSTANCE(vrf, vrfname, false, true); + /* + * within vrf context, vrf_id may be unknown + * this happens on daemons relying on zebra + * on this specific case, interface creation may + * be forced + */ + if (vrf && (vrf->vrf_id == VRF_UNKNOWN || + vrf_get_backend() == VRF_BACKEND_UNKNOWN)) + ifp = if_lookup_by_name(ifname, vrf); + else + ifp = if_lookup_by_name_all_vrf(ifname); + if (ifp && ifp->vrf != vrf) { /* * Special case 1: a VRF name was specified, but the found * interface is associated to different VRF. Reject the command. */ - if (vrf_id != VRF_DEFAULT) { + if (vrf->vrf_id != VRF_DEFAULT) { vty_out(vty, "%% interface %s not in %s vrf\n", ifname, vrfname); return CMD_WARNING_CONFIG_FAILED; @@ -1160,9 +1176,8 @@ DEFPY_NOSH (interface, * interface is associated to a VRF other than the default one. * Update vrf_id and vrfname to account for that. */ - vrf = vrf_lookup_by_id(ifp->vrf_id); + vrf = ifp->vrf; assert(vrf); - vrf_id = ifp->vrf_id; vrfname = vrf->name; } @@ -1181,7 +1196,7 @@ DEFPY_NOSH (interface, * all interface-level commands are converted to the new * northbound model. */ - ifp = if_lookup_by_name(ifname, vrf_id); + ifp = if_lookup_by_name(ifname, vrf); if (ifp) VTY_PUSH_CONTEXT(INTERFACE_NODE, ifp); } @@ -1303,7 +1318,7 @@ static int lib_interface_create(enum nb_event event, const char *ifname; const char *vrfname; struct vrf *vrf; - struct interface *ifp; + struct interface *ifp = NULL; ifname = yang_dnode_get_string(dnode, "./name"); vrfname = yang_dnode_get_string(dnode, "./vrf"); @@ -1316,11 +1331,9 @@ static int lib_interface_create(enum nb_event event, vrfname); return NB_ERR_VALIDATION; } - if (vrf->vrf_id == VRF_UNKNOWN) { - zlog_warn("%s: VRF %s is not active", __func__, - vrf->name); - return NB_ERR_VALIDATION; - } + if (vrf->vrf_id == VRF_UNKNOWN) + zlog_warn("%s: VRF %s is not active. Using interface however.", + __func__, vrf->name); /* if VRF is netns or not yet known - init for instance * then assumption is that passed config is exact @@ -1328,7 +1341,7 @@ static int lib_interface_create(enum nb_event event, */ if (vrf_get_backend() == VRF_BACKEND_VRF_LITE) { ifp = if_lookup_by_name_all_vrf(ifname); - if (ifp && ifp->vrf_id != vrf->vrf_id) { + if (ifp && ifp->vrf != vrf) { zlog_warn( "%s: interface %s already exists in another VRF", __func__, ifp->name); @@ -1343,9 +1356,9 @@ static int lib_interface_create(enum nb_event event, vrf = vrf_lookup_by_name(vrfname); assert(vrf); #ifdef SUNOS_5 - ifp = if_sunwzebra_get(ifname, vrf->vrf_id); + ifp = if_sunwzebra_get(ifname, vrf); #else - ifp = if_get_by_name(ifname, vrf->vrf_id); + ifp = if_get_by_name(ifname, vrf); #endif /* SUNOS_5 */ nb_running_set_entry(dnode, ifp); break; |
