In case of we update existing entry we need not only rehash
but also update name in existing entry.

Need to update device type too since cached interface might
be deleted and new with same index, but different type
added (e.g. eth0 and ppp0).

Reuse new entry initialization path to avoid duplications.

Signed-off-by: Serhey Popovych <serhe.popov...@gmail.com>
---
 lib/ll_map.c |   33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/lib/ll_map.c b/lib/ll_map.c
index f65614f..abe7bdc 100644
--- a/lib/ll_map.c
+++ b/lib/ll_map.c
@@ -10,6 +10,7 @@
  *
  */
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -85,6 +86,7 @@ int ll_remember_index(const struct sockaddr_nl *who,
        struct ifinfomsg *ifi = NLMSG_DATA(n);
        struct ll_cache *im;
        struct rtattr *tb[IFLA_MAX+1];
+       bool rehash;
 
        if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
                return 0;
@@ -109,29 +111,30 @@ int ll_remember_index(const struct sockaddr_nl *who,
 
        if (im) {
                /* change to existing entry */
-               if (strcmp(im->name, ifname) != 0) {
+               rehash = strcmp(im->name, ifname);
+               if (rehash)
                        hlist_del(&im->name_hash);
-                       h = namehash(ifname) & (IDXMAP_SIZE - 1);
-                       hlist_add_head(&im->name_hash, &name_head[h]);
-               }
+       } else {
+               im = malloc(sizeof(*im) + strlen(ifname) + 1);
+               if (!im)
+                       return 0;
+               im->index = ifi->ifi_index;
 
-               im->flags = ifi->ifi_flags;
-               return 0;
+               h = ifi->ifi_index & (IDXMAP_SIZE - 1);
+               hlist_add_head(&im->idx_hash, &idx_head[h]);
+
+               rehash = true;
        }
 
-       im = malloc(sizeof(*im) + strlen(ifname) + 1);
-       if (im == NULL)
-               return 0;
-       im->index = ifi->ifi_index;
-       strcpy(im->name, ifname);
        im->type = ifi->ifi_type;
        im->flags = ifi->ifi_flags;
 
-       h = ifi->ifi_index & (IDXMAP_SIZE - 1);
-       hlist_add_head(&im->idx_hash, &idx_head[h]);
+       if (rehash) {
+               h = namehash(ifname) & (IDXMAP_SIZE - 1);
+               hlist_add_head(&im->name_hash, &name_head[h]);
 
-       h = namehash(ifname) & (IDXMAP_SIZE - 1);
-       hlist_add_head(&im->name_hash, &name_head[h]);
+               strcpy(im->name, ifname);
+       }
 
        return 0;
 }
-- 
1.7.10.4

Reply via email to