diff options
| author | Russ White <russ@riw.us> | 2018-09-11 11:33:27 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-09-11 11:33:27 -0400 |
| commit | 88f47ef36536a040b30652bc22c253e7c5bc1c2e (patch) | |
| tree | 272285fef5319101109e4148f7784155bebe5fdc /lib/if.c | |
| parent | 5297438f5976b9a4460b07866413dfb990957af2 (diff) | |
| parent | c3568c4d1a080bc0510894374e16c157be28e8e4 (diff) | |
Merge pull request #2944 from thbtcllt/master
fix zebra crash when a vrf interface changes with netns implementation for vrf
Diffstat (limited to 'lib/if.c')
| -rw-r--r-- | lib/if.c | 64 |
1 files changed, 37 insertions, 27 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) + } + /* vrf is based on vrf-lite */ + ifp = if_lookup_by_name_all_vrf(name); + if (ifp) { + if (ifp->vrf_id == vrf_id) return ifp; - return NULL; + /* 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; } - /* 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; + return if_create(name, vrf_id); } void if_set_index(struct interface *ifp, ifindex_t ifindex) |
