]>
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(const struct sockaddr_nl
*who
,
81 struct nlmsghdr
*n
, void *arg
)
85 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
87 struct rtattr
*tb
[IFLA_MAX
+1];
89 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
92 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ifi
)))
95 im
= ll_get_by_index(ifi
->ifi_index
);
96 if (n
->nlmsg_type
== RTM_DELLINK
) {
98 hlist_del(&im
->name_hash
);
99 hlist_del(&im
->idx_hash
);
105 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), IFLA_PAYLOAD(n
));
106 ifname
= rta_getattr_str(tb
[IFLA_IFNAME
]);
111 /* change to existing entry */
112 if (strcmp(im
->name
, ifname
) != 0) {
113 hlist_del(&im
->name_hash
);
114 h
= namehash(ifname
) & (IDXMAP_SIZE
- 1);
115 hlist_add_head(&im
->name_hash
, &name_head
[h
]);
118 im
->flags
= ifi
->ifi_flags
;
122 im
= malloc(sizeof(*im
) + strlen(ifname
) + 1);
125 im
->index
= ifi
->ifi_index
;
126 strcpy(im
->name
, ifname
);
127 im
->type
= ifi
->ifi_type
;
128 im
->flags
= ifi
->ifi_flags
;
130 h
= ifi
->ifi_index
& (IDXMAP_SIZE
- 1);
131 hlist_add_head(&im
->idx_hash
, &idx_head
[h
]);
133 h
= namehash(ifname
) & (IDXMAP_SIZE
- 1);
134 hlist_add_head(&im
->name_hash
, &name_head
[h
]);
139 const char *ll_idx_n2a(unsigned idx
, char *buf
)
141 const struct ll_cache
*im
;
146 im
= ll_get_by_index(idx
);
150 if (if_indextoname(idx
, buf
) == NULL
)
151 snprintf(buf
, IFNAMSIZ
, "if%d", idx
);
156 const char *ll_index_to_name(unsigned idx
)
158 static char nbuf
[IFNAMSIZ
];
160 return ll_idx_n2a(idx
, nbuf
);
163 int ll_index_to_type(unsigned idx
)
165 const struct ll_cache
*im
;
170 im
= ll_get_by_index(idx
);
171 return im
? im
->type
: -1;
174 int ll_index_to_flags(unsigned idx
)
176 const struct ll_cache
*im
;
181 im
= ll_get_by_index(idx
);
182 return im
? im
->flags
: -1;
185 unsigned ll_name_to_index(const char *name
)
187 const struct ll_cache
*im
;
193 im
= ll_get_by_name(name
);
197 idx
= if_nametoindex(name
);
199 sscanf(name
, "if%u", &idx
);
203 void ll_init_map(struct rtnl_handle
*rth
)
205 static int initialized
;
210 if (rtnl_wilddump_request(rth
, AF_UNSPEC
, RTM_GETLINK
) < 0) {
211 perror("Cannot send dump request");
215 if (rtnl_dump_filter(rth
, ll_remember_index
, NULL
) < 0) {
216 fprintf(stderr
, "Dump terminated\n");