diff options
author | Don Slice <dslice@cumulusnetworks.com> | 2016-02-10 18:53:21 +0100 |
---|---|---|
committer | Don Slice <dslice@cumulusnetworks.com> | 2016-02-10 22:01:16 +0100 |
commit | 85f9da7f786a8f8d922e254b3a6159068f50b9f6 (patch) | |
tree | 0ef60c189f8c3b2e1f174ce9c88983f5c6b43d95 /lib/if.c | |
parent | zebra: display_vrf_name_on_interface (diff) | |
download | frr-85f9da7f786a8f8d922e254b3a6159068f50b9f6.tar.xz frr-85f9da7f786a8f8d922e254b3a6159068f50b9f6.zip |
zebra: fix interface lookup for vrf configuration
Ticket:CM-9073
Reviewed By: sharpd
Testing Done:Manual, see ticket
Changed logic when "interface swpxx <vrf foo>" entered so that:
1. it matches when the command is entered without a vrf but the interface already exists in a vrf.
2. If the command is entered with a vrf name that is different than is defined by the kernel, the command is rejected.
3. If the call is made from other than the vty session, believe the new information and update the vrf accordingly.
Diffstat (limited to 'lib/if.c')
-rw-r--r-- | lib/if.c | 51 |
1 files changed, 44 insertions, 7 deletions
@@ -454,18 +454,50 @@ if_get_by_name (const char *name) } struct interface * -if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id) +if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id, int vty) { struct interface *ifp; + struct listnode *node; + struct vrf *vrf = NULL; + vrf_iter_t iter; + + ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id); + if (ifp) + return ifp; - return ((ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id)) != NULL) ? \ - ifp : if_create_vrf (name, namelen, vrf_id); + /* Didn't find the interface on that vrf. Defined on a different one? */ + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + { + vrf = vrf_iter2vrf(iter); + for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf->vrf_id), node, ifp)) + { + if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0')) + { + /* Found a match. 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 by way of zclient, believe it and update + * the ifp accordingly. + */ + if (vrf_id == VRF_DEFAULT) + return ifp; + if (vty) + return NULL; + else + { + if_update_vrf (ifp, name, namelen, vrf_id); + return ifp; + } + } + } + } + return (if_create_vrf (name, namelen, vrf_id)); } struct interface * if_get_by_name_len (const char *name, size_t namelen) { - return if_get_by_name_len_vrf (name, namelen, VRF_DEFAULT); + return if_get_by_name_len_vrf (name, namelen, VRF_DEFAULT, 0); } /* Does interface up ? */ @@ -683,9 +715,9 @@ if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id) /* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */ if (seppos < nlen) - return if_get_by_name_len_vrf (name, seppos, vrf_id); + return if_get_by_name_len_vrf (name, seppos, vrf_id, 1); else - return if_get_by_name_len_vrf (name, nlen, vrf_id); + return if_get_by_name_len_vrf (name, nlen, vrf_id, 1); } #endif /* SUNOS_5 */ @@ -715,9 +747,14 @@ DEFUN (interface, #ifdef SUNOS_5 ifp = if_sunwzebra_get (argv[0], sl, vrf_id); #else - ifp = if_get_by_name_len_vrf (argv[0], sl, vrf_id); + ifp = if_get_by_name_len_vrf (argv[0], sl, vrf_id, 1); #endif /* SUNOS_5 */ + if (!ifp) + { + vty_out (vty, "%% interface %s not in %s%s", argv[0], argv[1], VTY_NEWLINE); + return CMD_WARNING; + } vty->index = ifp; vty->node = INTERFACE_NODE; |