Network device names are fixed in size and never exceed IFNAMSIZ (16 bytes).
Make name fixed size array to always malloc() same size chunk of memory and use memcpy()/memcmp() with constant IFNAMSIZ to benefit from possible compiler optimizations replacing call to a function with two/four load/store instructions on 64/32 bit systems. Check if IFLA_IFNAME attribute present in netlink message (should always) and use strncpy() to pad name with zeros. Signed-off-by: Serhey Popovych <serhe.popov...@gmail.com> --- lib/ll_map.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/ll_map.c b/lib/ll_map.c index abe7bdc..fcbf0fb 100644 --- a/lib/ll_map.c +++ b/lib/ll_map.c @@ -30,7 +30,7 @@ struct ll_cache { unsigned flags; unsigned index; unsigned short type; - char name[]; + char name[IFNAMSIZ]; }; #define IDXMAP_SIZE 1024 @@ -71,7 +71,7 @@ static struct ll_cache *ll_get_by_name(const char *name) struct ll_cache *im = container_of(n, struct ll_cache, name_hash); - if (strncmp(im->name, name, IFNAMSIZ) == 0) + if (!strcmp(im->name, name)) return im; } @@ -82,7 +82,7 @@ int ll_remember_index(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { unsigned int h; - const char *ifname; + char ifname[IFNAMSIZ]; struct ifinfomsg *ifi = NLMSG_DATA(n); struct ll_cache *im; struct rtattr *tb[IFLA_MAX+1]; @@ -105,17 +105,21 @@ int ll_remember_index(const struct sockaddr_nl *who, } parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n)); - ifname = rta_getattr_str(tb[IFLA_IFNAME]); - if (ifname == NULL) + + if (!tb[IFLA_IFNAME]) + return 0; + strncpy(ifname, rta_getattr_str(tb[IFLA_IFNAME]), IFNAMSIZ); + if (!ifname[0]) return 0; + ifname[IFNAMSIZ - 1] = '\0'; if (im) { /* change to existing entry */ - rehash = strcmp(im->name, ifname); + rehash = memcmp(im->name, ifname, IFNAMSIZ); if (rehash) hlist_del(&im->name_hash); } else { - im = malloc(sizeof(*im) + strlen(ifname) + 1); + im = malloc(sizeof(*im)); if (!im) return 0; im->index = ifi->ifi_index; @@ -133,7 +137,7 @@ int ll_remember_index(const struct sockaddr_nl *who, h = namehash(ifname) & (IDXMAP_SIZE - 1); hlist_add_head(&im->name_hash, &name_head[h]); - strcpy(im->name, ifname); + memcpy(im->name, ifname, IFNAMSIZ); } return 0; -- 1.7.10.4