diff options
-rw-r--r-- | networking/libiproute/ll_map.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/networking/libiproute/ll_map.c b/networking/libiproute/ll_map.c index 48775122c..a14fa4e42 100644 --- a/networking/libiproute/ll_map.c +++ b/networking/libiproute/ll_map.c | |||
@@ -17,8 +17,11 @@ | |||
17 | #include "libnetlink.h" | 17 | #include "libnetlink.h" |
18 | #include "ll_map.h" | 18 | #include "ll_map.h" |
19 | 19 | ||
20 | struct idxmap | 20 | #include <sys/socket.h> /* socket() */ |
21 | { | 21 | #include <net/if.h> /* struct ifreq and co. */ |
22 | #include <sys/ioctl.h> /* ioctl() & SIOCGIFINDEX */ | ||
23 | |||
24 | struct idxmap { | ||
22 | struct idxmap * next; | 25 | struct idxmap * next; |
23 | int index; | 26 | int index; |
24 | int type; | 27 | int type; |
@@ -129,6 +132,7 @@ int ll_name_to_index(char *name) | |||
129 | static char ncache[16]; | 132 | static char ncache[16]; |
130 | static int icache; | 133 | static int icache; |
131 | struct idxmap *im; | 134 | struct idxmap *im; |
135 | int sock_fd; | ||
132 | int i; | 136 | int i; |
133 | 137 | ||
134 | if (name == NULL) | 138 | if (name == NULL) |
@@ -144,19 +148,39 @@ int ll_name_to_index(char *name) | |||
144 | } | 148 | } |
145 | } | 149 | } |
146 | } | 150 | } |
151 | /* We have not found the interface in our cache, but the kernel | ||
152 | * may still know about it. One reason is that we may be using | ||
153 | * module on-demand loading, which means that the kernel will | ||
154 | * load the module and make the interface exist only when | ||
155 | * we explicitely request it (check for dev_load() in net/core/dev.c). | ||
156 | * I can think of other similar scenario, but they are less common... | ||
157 | * Jean II */ | ||
158 | sock_fd = socket(AF_INET, SOCK_DGRAM, 0); | ||
159 | if (sock_fd) { | ||
160 | struct ifreq ifr; | ||
161 | int ret; | ||
162 | strncpy(ifr.ifr_name, name, IFNAMSIZ); | ||
163 | ifr.ifr_ifindex = -1; | ||
164 | ret = ioctl(sock_fd, SIOCGIFINDEX, &ifr); | ||
165 | close(sock_fd); | ||
166 | if (ret >= 0) | ||
167 | /* In theory, we should redump the interface list | ||
168 | * to update our cache, this is left as an exercise | ||
169 | * to the reader... Jean II */ | ||
170 | return ifr.ifr_ifindex; | ||
171 | } | ||
172 | |||
147 | return 0; | 173 | return 0; |
148 | } | 174 | } |
149 | 175 | ||
150 | int ll_init_map(struct rtnl_handle *rth) | 176 | int ll_init_map(struct rtnl_handle *rth) |
151 | { | 177 | { |
152 | if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) { | 178 | if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) { |
153 | perror("Cannot send dump request"); | 179 | bb_perror_msg_and_die("cannot send dump request"); |
154 | exit(1); | ||
155 | } | 180 | } |
156 | 181 | ||
157 | if (rtnl_dump_filter(rth, ll_remember_index, &idxmap, NULL, NULL) < 0) { | 182 | if (rtnl_dump_filter(rth, ll_remember_index, &idxmap, NULL, NULL) < 0) { |
158 | fprintf(stderr, "Dump terminated\n"); | 183 | bb_error_msg_and_die("dump terminated"); |
159 | exit(1); | ||
160 | } | 184 | } |
161 | return 0; | 185 | return 0; |
162 | } | 186 | } |