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.
This commit is contained in:
Don Slice 2016-02-10 09:53:21 -08:00
parent e6a59b3505
commit 85f9da7f78
3 changed files with 46 additions and 9 deletions

View File

@ -454,18 +454,50 @@ if_get_by_name (const char *name)
} }
struct interface * 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 interface *ifp;
struct listnode *node;
struct vrf *vrf = NULL;
vrf_iter_t iter;
return ((ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id)) != NULL) ? \ ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id);
ifp : if_create_vrf (name, namelen, vrf_id); if (ifp)
return ifp;
/* 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 * struct interface *
if_get_by_name_len (const char *name, size_t namelen) 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 ? */ /* 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 */ /* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */
if (seppos < nlen) 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 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 */ #endif /* SUNOS_5 */
@ -715,9 +747,14 @@ DEFUN (interface,
#ifdef SUNOS_5 #ifdef SUNOS_5
ifp = if_sunwzebra_get (argv[0], sl, vrf_id); ifp = if_sunwzebra_get (argv[0], sl, vrf_id);
#else #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 */ #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->index = ifp;
vty->node = INTERFACE_NODE; vty->node = INTERFACE_NODE;

View File

@ -300,7 +300,7 @@ extern struct interface *if_get_by_name_len(const char *ifname,size_t namelen);
extern struct interface *if_lookup_by_name_len_vrf(const char *ifname, extern struct interface *if_lookup_by_name_len_vrf(const char *ifname,
size_t namelen, vrf_id_t vrf_id); size_t namelen, vrf_id_t vrf_id);
extern struct interface *if_get_by_name_len_vrf(const char *ifname, extern struct interface *if_get_by_name_len_vrf(const char *ifname,
size_t namelen, vrf_id_t vrf_id); size_t namelen, vrf_id_t vrf_id, int vty);
/* Delete the interface, but do not free the structure, and leave it in the /* Delete the interface, but do not free the structure, and leave it in the

View File

@ -902,7 +902,7 @@ zebra_interface_add_read (struct stream *s, vrf_id_t vrf_id)
/* Lookup/create interface by name. */ /* Lookup/create interface by name. */
ifp = if_get_by_name_len_vrf (ifname_tmp, ifp = if_get_by_name_len_vrf (ifname_tmp,
strnlen (ifname_tmp, INTERFACE_NAMSIZ), strnlen (ifname_tmp, INTERFACE_NAMSIZ),
vrf_id); vrf_id, 0);
zebra_interface_if_set_value (s, ifp); zebra_interface_if_set_value (s, ifp);