]>
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 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 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), IFLA_PAYLOAD(n
));
107 ifname
= rta_getattr_str(tb
[IFLA_IFNAME
]);
112 /* change to existing entry */
113 if (strcmp(im
->name
, ifname
) != 0) {
114 hlist_del(&im
->name_hash
);
115 h
= namehash(ifname
) & (IDXMAP_SIZE
- 1);
116 hlist_add_head(&im
->name_hash
, &name_head
[h
]);
119 im
->flags
= ifi
->ifi_flags
;
123 im
= malloc(sizeof(*im
) + strlen(ifname
) + 1);
126 im
->index
= ifi
->ifi_index
;
127 strcpy(im
->name
, ifname
);
128 im
->type
= ifi
->ifi_type
;
129 im
->flags
= ifi
->ifi_flags
;
131 h
= ifi
->ifi_index
& (IDXMAP_SIZE
- 1);
132 hlist_add_head(&im
->idx_hash
, &idx_head
[h
]);
134 h
= namehash(ifname
) & (IDXMAP_SIZE
- 1);
135 hlist_add_head(&im
->name_hash
, &name_head
[h
]);
140 const char *ll_idx_n2a(unsigned idx
, char *buf
)
142 const struct ll_cache
*im
;
147 im
= ll_get_by_index(idx
);
151 if (if_indextoname(idx
, buf
) == NULL
)
152 snprintf(buf
, IFNAMSIZ
, "if%d", idx
);
157 const char *ll_index_to_name(unsigned idx
)
159 static char nbuf
[IFNAMSIZ
];
161 return ll_idx_n2a(idx
, nbuf
);
164 int ll_index_to_type(unsigned idx
)
166 const struct ll_cache
*im
;
171 im
= ll_get_by_index(idx
);
172 return im
? im
->type
: -1;
175 int ll_index_to_flags(unsigned idx
)
177 const struct ll_cache
*im
;
182 im
= ll_get_by_index(idx
);
183 return im
? im
->flags
: -1;
186 unsigned ll_name_to_index(const char *name
)
188 const struct ll_cache
*im
;
194 im
= ll_get_by_name(name
);
198 idx
= if_nametoindex(name
);
200 sscanf(name
, "if%u", &idx
);
204 void ll_init_map(struct rtnl_handle
*rth
)
206 static int initialized
;
211 if (rtnl_wilddump_request(rth
, AF_UNSPEC
, RTM_GETLINK
) < 0) {
212 perror("Cannot send dump request");
216 if (rtnl_dump_filter(rth
, ll_remember_index
, NULL
) < 0) {
217 fprintf(stderr
, "Dump terminated\n");