lib: nuke the if_*_by_name_len() functions

Make use of strnlen() and strlcpy() so we can get rid of these
convoluted if_*_by_name_len() functions.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
Renato Westphal 2017-10-02 22:05:57 -03:00
parent e56ab0e971
commit bcc245799b
13 changed files with 71 additions and 133 deletions

View File

@ -334,8 +334,7 @@ static struct interface *zebra_interface_if_lookup(struct stream *s)
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
/* And look it up. */ /* And look it up. */
return if_lookup_by_name_len( return if_lookup_by_name(ifname_tmp, VRF_DEFAULT);
ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), VRF_DEFAULT);
} }
void eigrp_zebra_route_add(struct prefix *p, struct list *successors) void eigrp_zebra_route_add(struct prefix *p, struct list *successors)

130
lib/if.c
View File

@ -115,7 +115,7 @@ static int if_cmp_func(struct interface *ifp1, struct interface *ifp2)
} }
/* Create new interface structure. */ /* Create new interface structure. */
struct interface *if_create(const char *name, int namelen, vrf_id_t vrf_id) struct interface *if_create(const char *name, vrf_id_t vrf_id)
{ {
struct interface *ifp; struct interface *ifp;
struct list *intf_list = vrf_iflist_get(vrf_id); struct list *intf_list = vrf_iflist_get(vrf_id);
@ -124,9 +124,7 @@ struct interface *if_create(const char *name, int namelen, vrf_id_t vrf_id)
ifp->ifindex = IFINDEX_INTERNAL; ifp->ifindex = IFINDEX_INTERNAL;
assert(name); assert(name);
assert(namelen <= INTERFACE_NAMSIZ); /* Need space for '\0' at end. */ strlcpy(ifp->name, name, sizeof(ifp->name));
strncpy(ifp->name, name, namelen);
ifp->name[namelen] = '\0';
ifp->vrf_id = vrf_id; ifp->vrf_id = vrf_id;
if (if_lookup_by_name(ifp->name, vrf_id) == NULL) if (if_lookup_by_name(ifp->name, vrf_id) == NULL)
listnode_add_sort(intf_list, ifp); listnode_add_sort(intf_list, ifp);
@ -163,8 +161,8 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
listnode_add_sort(intf_list, ifp); listnode_add_sort(intf_list, ifp);
else else
zlog_err( zlog_err(
"if_create(%s): corruption detected -- interface with this " "%s(%s): corruption detected -- interface with this "
"name exists already in VRF %u!", "name exists already in VRF %u!", __func__,
ifp->name, vrf_id); ifp->name, vrf_id);
return; return;
@ -236,11 +234,14 @@ struct interface *if_lookup_by_name(const char *name, vrf_id_t vrf_id)
struct listnode *node; struct listnode *node;
struct interface *ifp; struct interface *ifp;
if (name) if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) { return NULL;
if (strcmp(name, ifp->name) == 0)
return ifp; for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) {
} if (strcmp(name, ifp->name) == 0)
return ifp;
}
return NULL; return NULL;
} }
@ -249,6 +250,9 @@ struct interface *if_lookup_by_name_all_vrf(const char *name)
struct vrf *vrf; struct vrf *vrf;
struct interface *ifp; struct interface *ifp;
if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
return NULL;
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { 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->vrf_id);
if (ifp) if (ifp)
@ -258,23 +262,6 @@ struct interface *if_lookup_by_name_all_vrf(const char *name)
return NULL; return NULL;
} }
struct interface *if_lookup_by_name_len(const char *name, size_t namelen,
vrf_id_t vrf_id)
{
struct listnode *node;
struct interface *ifp;
if (namelen > INTERFACE_NAMSIZ)
return NULL;
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) {
if (!memcmp(name, ifp->name, namelen)
&& (ifp->name[namelen] == '\0'))
return ifp;
}
return NULL;
}
/* Lookup interface by IPv4 address. */ /* Lookup interface by IPv4 address. */
struct interface *if_lookup_exact_address(void *src, int family, struct interface *if_lookup_exact_address(void *src, int family,
vrf_id_t vrf_id) vrf_id_t vrf_id)
@ -364,53 +351,33 @@ struct interface *if_lookup_prefix(struct prefix *prefix, vrf_id_t vrf_id)
/* Get interface by name if given name interface doesn't exist create /* Get interface by name if given name interface doesn't exist create
one. */ one. */
struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id) struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, int vty)
{ {
struct interface *ifp; struct interface *ifp;
return ((ifp = if_lookup_by_name(name, vrf_id)) != NULL) ifp = if_lookup_by_name_all_vrf(name);
? ifp if (ifp) {
: if_create(name, strlen(name), vrf_id); if (ifp->vrf_id == vrf_id)
} return ifp;
struct interface *if_get_by_name_len(const char *name, size_t namelen, /* Found a match on a different VRF. If the interface command
vrf_id_t vrf_id, int vty) * was entered in vty without a VRF (passed as VRF_DEFAULT),
{ * accept the ifp we found. If a vrf was entered and there is
struct interface *ifp; * a mismatch, reject it if from vty. If it came from the kernel
struct vrf *vrf; * or by way of zclient, believe it and update the ifp
struct listnode *node; * accordingly.
*/
ifp = if_lookup_by_name_len(name, namelen, vrf_id); if (vty) {
if (ifp) if (vrf_id == VRF_DEFAULT)
return ifp; return ifp;
return NULL;
/* Didn't find the interface on that vrf. Defined on a different one? */ } else {
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { if_update_to_new_vrf(ifp, vrf_id);
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf->vrf_id), node, ifp)) { return 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 (vty) {
if (vrf_id == VRF_DEFAULT)
return ifp;
return NULL;
} else {
if_update_to_new_vrf(ifp, vrf_id);
return ifp;
}
}
} }
} }
return (if_create(name, namelen, vrf_id));
return if_create(name, vrf_id);
} }
/* Does interface up ? */ /* Does interface up ? */
@ -597,24 +564,20 @@ DEFUN (no_interface_desc,
* if not: * if not:
* - no idea, just get the name in its entirety. * - no idea, just get the name in its entirety.
*/ */
static struct interface *if_sunwzebra_get(const char *name, size_t nlen, static struct interface *if_sunwzebra_get(char *name, vrf_id_t vrf_id)
vrf_id_t vrf_id)
{ {
struct interface *ifp; struct interface *ifp;
size_t seppos = 0; char *cp;
if ((ifp = if_lookup_by_name_len(name, nlen, vrf_id)) != NULL) if ((ifp = if_lookup_by_name(name, vrf_id)) != NULL)
return ifp; return ifp;
/* hunt the primary interface name... */ /* hunt the primary interface name... */
while (seppos < nlen && name[seppos] != ':') cp = strchr(name, ':');
seppos++; if (cp)
*cp = '\0';
/* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */ return if_get_by_name(name, vrf_id, 1);
if (seppos < nlen)
return if_get_by_name_len(name, seppos, vrf_id, 1);
else
return if_get_by_name_len(name, nlen, vrf_id, 1);
} }
#endif /* SUNOS_5 */ #endif /* SUNOS_5 */
@ -631,10 +594,9 @@ DEFUN (interface,
const char *vrfname = (argc > 2) ? argv[idx_vrf]->arg : NULL; const char *vrfname = (argc > 2) ? argv[idx_vrf]->arg : NULL;
struct interface *ifp; struct interface *ifp;
size_t sl;
vrf_id_t vrf_id = VRF_DEFAULT; vrf_id_t vrf_id = VRF_DEFAULT;
if ((sl = strlen(ifname)) > INTERFACE_NAMSIZ) { if (strlen(ifname) > INTERFACE_NAMSIZ) {
vty_out(vty, vty_out(vty,
"%% Interface name %s is invalid: length exceeds " "%% Interface name %s is invalid: length exceeds "
"%d characters\n", "%d characters\n",
@ -648,9 +610,9 @@ DEFUN (interface,
VRF_GET_ID(vrf_id, vrfname); VRF_GET_ID(vrf_id, vrfname);
#ifdef SUNOS_5 #ifdef SUNOS_5
ifp = if_sunwzebra_get(ifname, sl, vrf_id); ifp = if_sunwzebra_get(ifname, vrf_id);
#else #else
ifp = if_get_by_name_len(ifname, sl, vrf_id, 1); ifp = if_get_by_name(ifname, vrf_id, 1);
#endif /* SUNOS_5 */ #endif /* SUNOS_5 */
if (!ifp) { if (!ifp) {

View File

@ -209,7 +209,7 @@ struct interface {
To delete, just set ifindex to IFINDEX_INTERNAL to indicate that the To delete, just set ifindex to IFINDEX_INTERNAL to indicate that the
interface does not exist in the kernel. interface does not exist in the kernel.
*/ */
char name[INTERFACE_NAMSIZ + 1]; char name[INTERFACE_NAMSIZ];
/* Interface index (should be IFINDEX_INTERNAL for non-kernel or /* Interface index (should be IFINDEX_INTERNAL for non-kernel or
deleted interfaces). */ deleted interfaces). */
@ -408,8 +408,7 @@ struct nbr_connected {
extern int if_cmp_name_func(char *, char *); extern int if_cmp_name_func(char *, char *);
extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id); extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
extern struct interface *if_create(const char *name, int namelen, extern struct interface *if_create(const char *name, vrf_id_t vrf_id);
vrf_id_t vrf_id);
extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id); extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
extern struct interface *if_lookup_exact_address(void *matchaddr, int family, extern struct interface *if_lookup_exact_address(void *matchaddr, int family,
vrf_id_t vrf_id); vrf_id_t vrf_id);
@ -422,16 +421,8 @@ extern struct interface *if_lookup_prefix(struct prefix *prefix,
by a '\0' character: */ by a '\0' character: */
extern struct interface *if_lookup_by_name_all_vrf(const char *ifname); extern struct interface *if_lookup_by_name_all_vrf(const char *ifname);
extern struct interface *if_lookup_by_name(const char *ifname, vrf_id_t vrf_id); extern struct interface *if_lookup_by_name(const char *ifname, vrf_id_t vrf_id);
extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id); extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id,
int vty);
/* For these 2 functions, the namelen argument should be the precise length
of the ifname string (not counting any optional trailing '\0' character).
In most cases, strnlen should be used to calculate the namelen value. */
extern struct interface *if_lookup_by_name_len(const char *ifname,
size_t namelen, vrf_id_t vrf_id);
extern struct interface *if_get_by_name_len(const char *ifname, 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
interface list. It is often advisable to leave the pseudo interface interface list. It is often advisable to leave the pseudo interface

View File

@ -1230,8 +1230,7 @@ struct interface *zebra_interface_add_read(struct stream *s, vrf_id_t vrf_id)
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
/* Lookup/create interface by name. */ /* Lookup/create interface by name. */
ifp = if_get_by_name_len( ifp = if_get_by_name(ifname_tmp, vrf_id, 0);
ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id, 0);
zebra_interface_if_set_value(s, ifp); zebra_interface_if_set_value(s, ifp);
@ -1254,8 +1253,7 @@ struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
/* Lookup this by interface index. */ /* Lookup this by interface index. */
ifp = if_lookup_by_name_len( ifp = if_lookup_by_name(ifname_tmp, vrf_id);
ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id);
if (ifp == NULL) { if (ifp == NULL) {
zlog_warn("INTERFACE_STATE: Cannot find IF %s in VRF %d", zlog_warn("INTERFACE_STATE: Cannot find IF %s in VRF %d",
ifname_tmp, vrf_id); ifname_tmp, vrf_id);

View File

@ -595,7 +595,7 @@ DEFUN (ospf6_interface_area,
u_int32_t area_id; u_int32_t area_id;
/* find/create ospf6 interface */ /* find/create ospf6 interface */
ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT); ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT, 0);
oi = (struct ospf6_interface *)ifp->info; oi = (struct ospf6_interface *)ifp->info;
if (oi == NULL) if (oi == NULL)
oi = ospf6_interface_create(ifp); oi = ospf6_interface_create(ifp);

View File

@ -798,7 +798,7 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
{ {
struct ospf_interface *voi; struct ospf_interface *voi;
struct interface *vi; struct interface *vi;
char ifname[INTERFACE_NAMSIZ + 1]; char ifname[INTERFACE_NAMSIZ];
struct ospf_area *area; struct ospf_area *area;
struct in_addr area_id; struct in_addr area_id;
struct connected *co; struct connected *co;
@ -819,7 +819,7 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
ospf->vrf_id); ospf->vrf_id);
snprintf(ifname, sizeof(ifname), "VLINK%d", vlink_count); snprintf(ifname, sizeof(ifname), "VLINK%d", vlink_count);
vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), ospf->vrf_id); vi = if_create(ifname, ospf->vrf_id);
/* /*
* if_create sets ZEBRA_INTERFACE_LINKDETECTION * if_create sets ZEBRA_INTERFACE_LINKDETECTION
* virtual links don't need this. * virtual links don't need this.

View File

@ -413,7 +413,7 @@ DEFUN (ospf_passive_interface,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id); ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id, 0);
if (ifp == NULL) { if (ifp == NULL) {
vty_out(vty, "interface %s not found.\n", vty_out(vty, "interface %s not found.\n",
(char *)argv[1]->arg); (char *)argv[1]->arg);
@ -485,7 +485,7 @@ DEFUN (no_ospf_passive_interface,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id); ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id, 0);
if (ifp == NULL) { if (ifp == NULL) {
vty_out(vty, "interface %s not found.\n", vty_out(vty, "interface %s not found.\n",
(char *)argv[1]->arg); (char *)argv[1]->arg);

View File

@ -179,8 +179,7 @@ static struct interface *zebra_interface_if_lookup(struct stream *s,
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
/* And look it up. */ /* And look it up. */
return if_lookup_by_name_len( return if_lookup_by_name(ifname_tmp, vrf_id);
ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id);
} }
static int ospf_interface_state_up(int command, struct zclient *zclient, static int ospf_interface_state_up(int command, struct zclient *zclient,

View File

@ -1480,17 +1480,16 @@ void pim_if_update_assert_tracking_desired(struct interface *ifp)
*/ */
void pim_if_create_pimreg(struct pim_instance *pim) void pim_if_create_pimreg(struct pim_instance *pim)
{ {
char pimreg_name[100]; char pimreg_name[INTERFACE_NAMSIZ];
if (!pim->regiface) { if (!pim->regiface) {
if (pim->vrf_id == VRF_DEFAULT) if (pim->vrf_id == VRF_DEFAULT)
strcpy(pimreg_name, "pimreg"); strlcpy(pimreg_name, "pimreg", sizeof(pimreg_name));
else else
sprintf(pimreg_name, "pimreg%d", snprintf(pimreg_name, sizeof(pimreg_name), "pimreg%u",
pim->vrf->data.l.table_id); pim->vrf->data.l.table_id);
pim->regiface = if_create(pimreg_name, strlen(pimreg_name), pim->regiface = if_create(pimreg_name, pim->vrf_id);
pim->vrf_id);
pim->regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF; pim->regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF;
pim_if_new(pim->regiface, 0, 0); pim_if_new(pim->regiface, 0, 0);

View File

@ -105,10 +105,7 @@ static int interface_list_ioctl(void)
unsigned int size; unsigned int size;
ifreq = (struct ifreq *)((caddr_t)ifconf.ifc_req + n); ifreq = (struct ifreq *)((caddr_t)ifconf.ifc_req + n);
ifp = if_get_by_name_len( ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT, 0);
ifreq->ifr_name,
strnlen(ifreq->ifr_name, sizeof(ifreq->ifr_name)),
VRF_DEFAULT, 0);
if_add_update(ifp); if_add_update(ifp);
size = ifreq->ifr_addr.sa_len; size = ifreq->ifr_addr.sa_len;
if (size < sizeof(ifreq->ifr_addr)) if (size < sizeof(ifreq->ifr_addr))
@ -118,10 +115,7 @@ static int interface_list_ioctl(void)
} }
#else #else
for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq)) { for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq)) {
ifp = if_get_by_name_len( ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT, 0);
ifreq->ifr_name,
strnlen(ifreq->ifr_name, sizeof(ifreq->ifr_name)),
VRF_DEFAULT, 0);
if_add_update(ifp); if_add_update(ifp);
ifreq++; ifreq++;
} }

View File

@ -170,8 +170,7 @@ calculate_lifc_len: /* must hold privileges to enter here */
&& (*(lifreq->lifr_name + normallen) != ':')) && (*(lifreq->lifr_name + normallen) != ':'))
normallen++; normallen++;
ifp = if_get_by_name_len(lifreq->lifr_name, normallen, ifp = if_get_by_name(lifreq->lifr_name, VRF_DEFAULT, 0);
VRF_DEFAULT, 0);
if (lifreq->lifr_addr.ss_family == AF_INET) if (lifreq->lifr_addr.ss_family == AF_INET)
ifp->flags |= IFF_IPV4; ifp->flags |= IFF_IPV4;

View File

@ -666,7 +666,7 @@ static int netlink_interface(struct sockaddr_nl *snl, struct nlmsghdr *h,
link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]); link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
/* Add interface. */ /* Add interface. */
ifp = if_get_by_name(name, vrf_id); ifp = if_get_by_name(name, vrf_id, 0);
set_ifindex(ifp, ifi->ifi_index, zns); set_ifindex(ifp, ifi->ifi_index, zns);
ifp->flags = ifi->ifi_flags & 0x0000fffff; ifp->flags = ifi->ifi_flags & 0x0000fffff;
if (IS_ZEBRA_IF_VRF(ifp)) if (IS_ZEBRA_IF_VRF(ifp))
@ -1121,7 +1121,7 @@ int netlink_link_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
if (ifp == NULL) { if (ifp == NULL) {
/* unknown interface */ /* unknown interface */
ifp = if_get_by_name(name, vrf_id); ifp = if_get_by_name(name, vrf_id, 0);
} else { } else {
/* pre-configured interface, learnt now */ /* pre-configured interface, learnt now */
if (ifp->vrf_id != vrf_id) if (ifp->vrf_id != vrf_id)

View File

@ -323,10 +323,7 @@ static int ifan_read(struct if_announcemsghdr *ifan)
__func__, ifan->ifan_index, ifan->ifan_name); __func__, ifan->ifan_index, ifan->ifan_name);
/* Create Interface */ /* Create Interface */
ifp = if_get_by_name_len( ifp = if_get_by_name(ifan->ifan_name, VRF_DEFAULT, 0);
ifan->ifan_name,
strnlen(ifan->ifan_name, sizeof(ifan->ifan_name)),
VRF_DEFAULT, 0);
ifp->ifindex = ifan->ifan_index; ifp->ifindex = ifan->ifan_index;
if_get_metric(ifp); if_get_metric(ifp);
@ -517,7 +514,7 @@ int ifm_read(struct if_msghdr *ifm)
if (ifp == NULL) { if (ifp == NULL) {
/* Interface that zebra was not previously aware of, so /* Interface that zebra was not previously aware of, so
* create. */ * create. */
ifp = if_create(ifname, ifnlen, VRF_DEFAULT); ifp = if_create(ifname, VRF_DEFAULT);
if (IS_ZEBRA_DEBUG_KERNEL) if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("%s: creating ifp for ifindex %d", zlog_debug("%s: creating ifp for ifindex %d",
__func__, ifm->ifm_index); __func__, ifm->ifm_index);