]>
git.proxmox.com Git - mirror_iproute2.git/blob - lib/ll_map.c
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
23 #include "libnetlink.h"
28 struct hlist_node idx_hash
;
29 struct hlist_node name_hash
;
36 #define IDXMAP_SIZE 1024
37 static struct hlist_head idx_head
[IDXMAP_SIZE
];
38 static struct hlist_head name_head
[IDXMAP_SIZE
];
40 static struct ll_cache
*ll_get_by_index(unsigned index
)
43 unsigned h
= index
& (IDXMAP_SIZE
- 1);
45 hlist_for_each(n
, &idx_head
[h
]) {
47 = container_of(n
, struct ll_cache
, idx_hash
);
48 if (im
->index
== index
)
55 static unsigned namehash(const char *str
)
60 hash
= ((hash
<< 5) + hash
) + *str
++; /* hash * 33 + c */
65 static struct ll_cache
*ll_get_by_name(const char *name
)
68 unsigned h
= namehash(name
) & (IDXMAP_SIZE
- 1);
70 hlist_for_each(n
, &name_head
[h
]) {
72 = container_of(n
, struct ll_cache
, name_hash
);
74 if (strncmp(im
->name
, name
, IFNAMSIZ
) == 0)
81 int ll_remember_index(const struct sockaddr_nl
*who
,
82 struct nlmsghdr
*n
, void *arg
)
86 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
88 struct rtattr
*tb
[IFLA_MAX
+1];
90 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
93 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(ifi
)))
96 im
= ll_get_by_index(ifi
->ifi_index
);
97 if (n
->nlmsg_type
== RTM_DELLINK
) {
99 hlist_del(&im
->name_hash
);
100 hlist_del(&im
->idx_hash
);
106 memset(tb
, 0, sizeof(tb
));
107 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), IFLA_PAYLOAD(n
));
108 ifname
= rta_getattr_str(tb
[IFLA_IFNAME
]);
113 /* change to existing entry */
114 if (strcmp(im
->name
, ifname
) != 0) {
115 hlist_del(&im
->name_hash
);
116 h
= namehash(ifname
) & (IDXMAP_SIZE
- 1);
117 hlist_add_head(&im
->name_hash
, &name_head
[h
]);
120 im
->flags
= ifi
->ifi_flags
;
124 im
= malloc(sizeof(*im
));
127 im
->index
= ifi
->ifi_index
;
128 strcpy(im
->name
, ifname
);
129 im
->type
= ifi
->ifi_type
;
130 im
->flags
= ifi
->ifi_flags
;
132 h
= ifi
->ifi_index
& (IDXMAP_SIZE
- 1);
133 hlist_add_head(&im
->idx_hash
, &idx_head
[h
]);
135 h
= namehash(ifname
) & (IDXMAP_SIZE
- 1);
136 hlist_add_head(&im
->name_hash
, &name_head
[h
]);
141 const char *ll_idx_n2a(unsigned idx
, char *buf
)
143 const struct ll_cache
*im
;
148 im
= ll_get_by_index(idx
);
152 if (if_indextoname(idx
, buf
) == NULL
)
153 snprintf(buf
, IFNAMSIZ
, "if%d", idx
);
158 const char *ll_index_to_name(unsigned idx
)
160 static char nbuf
[IFNAMSIZ
];
162 return ll_idx_n2a(idx
, nbuf
);
165 int ll_index_to_type(unsigned idx
)
167 const struct ll_cache
*im
;
172 im
= ll_get_by_index(idx
);
173 return im
? im
->type
: -1;
176 int ll_index_to_flags(unsigned idx
)
178 const struct ll_cache
*im
;
183 im
= ll_get_by_index(idx
);
184 return im
? im
->flags
: -1;
187 unsigned ll_name_to_index(const char *name
)
189 const struct ll_cache
*im
;
195 im
= ll_get_by_name(name
);
199 idx
= if_nametoindex(name
);
201 sscanf(name
, "if%u", &idx
);
205 void ll_init_map(struct rtnl_handle
*rth
)
207 static int initialized
;
212 if (rtnl_wilddump_request(rth
, AF_UNSPEC
, RTM_GETLINK
) < 0) {
213 perror("Cannot send dump request");
217 if (rtnl_dump_filter(rth
, ll_remember_index
, NULL
) < 0) {
218 fprintf(stderr
, "Dump terminated\n");