]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/blobdiff - lib/ll_map.c
libnetlink: remove unused junk callback
[lisovros/iproute2_canprio.git] / lib / ll_map.c
index dee498f7e09476fe189ca1458e029b74afc63272..1ca781e9130877613fd4c0a0239790c5af59504e 100644 (file)
 #include <fcntl.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <net/if.h>
 #include <string.h>
+#include <linux/if.h>
 
 #include "libnetlink.h"
 #include "ll_map.h"
 
-struct idxmap
+extern unsigned int if_nametoindex (const char *);
+
+struct ll_cache
 {
-       struct idxmap * next;
-       unsigned        index;
-       int             type;
-       int             alen;
+       struct ll_cache   *idx_next;
        unsigned        flags;
-       unsigned char   addr[8];
-       char            name[16];
+       int             index;
+       unsigned short  type;
+       unsigned short  alen;
+       char            name[IFNAMSIZ];
+       unsigned char   addr[20];
 };
 
-static struct idxmap *idxmap[16];
+#define IDXMAP_SIZE    1024
+static struct ll_cache *idx_head[IDXMAP_SIZE];
+
+static inline struct ll_cache *idxhead(int idx)
+{
+       return idx_head[idx & (IDXMAP_SIZE - 1)];
+}
 
 int ll_remember_index(const struct sockaddr_nl *who,
                      struct nlmsghdr *n, void *arg)
 {
        int h;
        struct ifinfomsg *ifi = NLMSG_DATA(n);
-       struct idxmap *im, **imp;
+       struct ll_cache *im, **imp;
        struct rtattr *tb[IFLA_MAX+1];
 
        if (n->nlmsg_type != RTM_NEWLINK)
@@ -50,15 +58,13 @@ int ll_remember_index(const struct sockaddr_nl *who,
        if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
                return -1;
 
-
        memset(tb, 0, sizeof(tb));
        parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
        if (tb[IFLA_IFNAME] == NULL)
                return 0;
 
-       h = ifi->ifi_index&0xF;
-
-       for (imp=&idxmap[h]; (im=*imp)!=NULL; imp = &im->next)
+       h = ifi->ifi_index & (IDXMAP_SIZE - 1);
+       for (imp = &idx_head[h]; (im=*imp)!=NULL; imp = &im->idx_next)
                if (im->index == ifi->ifi_index)
                        break;
 
@@ -66,7 +72,7 @@ int ll_remember_index(const struct sockaddr_nl *who,
                im = malloc(sizeof(*im));
                if (im == NULL)
                        return 0;
-               im->next = *imp;
+               im->idx_next = *imp;
                im->index = ifi->ifi_index;
                *imp = im;
        }
@@ -89,32 +95,34 @@ int ll_remember_index(const struct sockaddr_nl *who,
 
 const char *ll_idx_n2a(unsigned idx, char *buf)
 {
-       struct idxmap *im;
+       const struct ll_cache *im;
 
        if (idx == 0)
                return "*";
-       for (im = idxmap[idx&0xF]; im; im = im->next)
+
+       for (im = idxhead(idx); im; im = im->idx_next)
                if (im->index == idx)
                        return im->name;
-       snprintf(buf, 16, "if%d", idx);
+
+       snprintf(buf, IFNAMSIZ, "if%d", idx);
        return buf;
 }
 
 
 const char *ll_index_to_name(unsigned idx)
 {
-       static char nbuf[16];
+       static char nbuf[IFNAMSIZ];
 
        return ll_idx_n2a(idx, nbuf);
 }
 
 int ll_index_to_type(unsigned idx)
 {
-       struct idxmap *im;
+       const struct ll_cache *im;
 
        if (idx == 0)
                return -1;
-       for (im = idxmap[idx&0xF]; im; im = im->next)
+       for (im = idxhead(idx); im; im = im->idx_next)
                if (im->index == idx)
                        return im->type;
        return -1;
@@ -122,30 +130,54 @@ int ll_index_to_type(unsigned idx)
 
 unsigned ll_index_to_flags(unsigned idx)
 {
-       struct idxmap *im;
+       const struct ll_cache *im;
 
        if (idx == 0)
                return 0;
 
-       for (im = idxmap[idx&0xF]; im; im = im->next)
+       for (im = idxhead(idx); im; im = im->idx_next)
                if (im->index == idx)
                        return im->flags;
        return 0;
 }
 
+unsigned ll_index_to_addr(unsigned idx, unsigned char *addr,
+                         unsigned alen)
+{
+       const struct ll_cache *im;
+
+       if (idx == 0)
+               return 0;
+
+       for (im = idxhead(idx); im; im = im->idx_next) {
+               if (im->index == idx) {
+                       if (alen > sizeof(im->addr))
+                               alen = sizeof(im->addr);
+                       if (alen > im->alen)
+                               alen = im->alen;
+                       memcpy(addr, im->addr, alen);
+                       return alen;
+               }
+       }
+       return 0;
+}
+
 unsigned ll_name_to_index(const char *name)
 {
-       static char ncache[16];
+       static char ncache[IFNAMSIZ];
        static int icache;
-       struct idxmap *im;
+       struct ll_cache *im;
        int i;
+       unsigned idx;
 
        if (name == NULL)
                return 0;
+
        if (icache && strcmp(name, ncache) == 0)
                return icache;
-       for (i=0; i<16; i++) {
-               for (im = idxmap[i]; im; im = im->next) {
+
+       for (i=0; i<IDXMAP_SIZE; i++) {
+               for (im = idx_head[i]; im; im = im->idx_next) {
                        if (strcmp(im->name, name) == 0) {
                                icache = im->index;
                                strcpy(ncache, name);
@@ -154,19 +186,30 @@ unsigned ll_name_to_index(const char *name)
                }
        }
 
-       return if_nametoindex(name);
+       idx = if_nametoindex(name);
+       if (idx == 0)
+               sscanf(name, "if%u", &idx);
+       return idx;
 }
 
 int ll_init_map(struct rtnl_handle *rth)
 {
+       static int initialized;
+
+       if (initialized)
+               return 0;
+
        if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) {
                perror("Cannot send dump request");
                exit(1);
        }
 
-       if (rtnl_dump_filter(rth, ll_remember_index, &idxmap, NULL, NULL) < 0) {
+       if (rtnl_dump_filter(rth, ll_remember_index, NULL) < 0) {
                fprintf(stderr, "Dump terminated\n");
                exit(1);
        }
+
+       initialized = 1;
+
        return 0;
 }