]>
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>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
22 #include "libnetlink.h"
27 struct hlist_node idx_hash
;
28 struct hlist_node name_hash
;
35 #define IDXMAP_SIZE 1024
36 static struct hlist_head idx_head
[IDXMAP_SIZE
];
37 static struct hlist_head name_head
[IDXMAP_SIZE
];
39 static struct ll_cache
*ll_get_by_index(unsigned index
)
42 unsigned h
= index
& (IDXMAP_SIZE
- 1);
44 hlist_for_each(n
, &idx_head
[h
]) {
46 = container_of(n
, struct ll_cache
, idx_hash
);
47 if (im
->index
== index
)
54 unsigned namehash(const char *str
)
59 hash
= ((hash
<< 5) + hash
) + *str
++; /* hash * 33 + c */
64 static struct ll_cache
*ll_get_by_name(const char *name
)
67 unsigned h
= namehash(name
) & (IDXMAP_SIZE
- 1);
69 hlist_for_each(n
, &name_head
[h
]) {
71 = container_of(n
, struct ll_cache
, name_hash
);
73 if (strncmp(im
->name
, name
, IFNAMSIZ
) == 0)
80 int ll_remember_index(struct nlmsghdr
*n
, void *arg
)
84 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
86 struct rtattr
*tb
[IFLA_MAX
+1];
88 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
91 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ifi
)))
94 im
= ll_get_by_index(ifi
->ifi_index
);
95 if (n
->nlmsg_type
== RTM_DELLINK
) {
97 hlist_del(&im
->name_hash
);
98 hlist_del(&im
->idx_hash
);
104 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), IFLA_PAYLOAD(n
));
105 ifname
= rta_getattr_str(tb
[IFLA_IFNAME
]);
110 /* change to existing entry */
111 if (strcmp(im
->name
, ifname
) != 0) {
112 hlist_del(&im
->name_hash
);
113 h
= namehash(ifname
) & (IDXMAP_SIZE
- 1);
114 hlist_add_head(&im
->name_hash
, &name_head
[h
]);
117 im
->flags
= ifi
->ifi_flags
;
121 im
= malloc(sizeof(*im
) + strlen(ifname
) + 1);
124 im
->index
= ifi
->ifi_index
;
125 strcpy(im
->name
, ifname
);
126 im
->type
= ifi
->ifi_type
;
127 im
->flags
= ifi
->ifi_flags
;
129 h
= ifi
->ifi_index
& (IDXMAP_SIZE
- 1);
130 hlist_add_head(&im
->idx_hash
, &idx_head
[h
]);
132 h
= namehash(ifname
) & (IDXMAP_SIZE
- 1);
133 hlist_add_head(&im
->name_hash
, &name_head
[h
]);
138 const char *ll_idx_n2a(unsigned int idx
)
140 static char buf
[IFNAMSIZ
];
142 snprintf(buf
, sizeof(buf
), "if%u", idx
);
146 static unsigned int ll_idx_a2n(const char *name
)
150 if (sscanf(name
, "if%u", &idx
) != 1)
155 const char *ll_index_to_name(unsigned int idx
)
157 static char buf
[IFNAMSIZ
];
158 const struct ll_cache
*im
;
163 im
= ll_get_by_index(idx
);
167 if (if_indextoname(idx
, buf
) == NULL
)
168 snprintf(buf
, IFNAMSIZ
, "if%u", idx
);
173 int ll_index_to_type(unsigned idx
)
175 const struct ll_cache
*im
;
180 im
= ll_get_by_index(idx
);
181 return im
? im
->type
: -1;
184 int ll_index_to_flags(unsigned idx
)
186 const struct ll_cache
*im
;
191 im
= ll_get_by_index(idx
);
192 return im
? im
->flags
: -1;
195 unsigned ll_name_to_index(const char *name
)
197 const struct ll_cache
*im
;
203 im
= ll_get_by_name(name
);
207 idx
= if_nametoindex(name
);
209 idx
= ll_idx_a2n(name
);
213 void ll_init_map(struct rtnl_handle
*rth
)
215 static int initialized
;
220 if (rtnl_linkdump_req(rth
, AF_UNSPEC
) < 0) {
221 perror("Cannot send dump request");
225 if (rtnl_dump_filter(rth
, ll_remember_index
, NULL
) < 0) {
226 fprintf(stderr
, "Dump terminated\n");