aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/libiproute/ll_map.c36
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
20struct 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
24struct 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
150int ll_init_map(struct rtnl_handle *rth) 176int 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}