svn commit: trunk/busybox/networking/libiproute

vda at busybox.net vda at busybox.net
Sat Sep 30 00:18:17 UTC 2006


Author: vda
Date: 2006-09-29 17:18:16 -0700 (Fri, 29 Sep 2006)
New Revision: 16268

Log:
libiproute/ll_map.c: fix bug 279
("On-demand net module loading fails with CONFIG_FEATURE_IFUPDOWN_IP")


Modified:
   trunk/busybox/networking/libiproute/ll_map.c


Changeset:
Modified: trunk/busybox/networking/libiproute/ll_map.c
===================================================================
--- trunk/busybox/networking/libiproute/ll_map.c	2006-09-29 23:41:59 UTC (rev 16267)
+++ trunk/busybox/networking/libiproute/ll_map.c	2006-09-30 00:18:16 UTC (rev 16268)
@@ -17,8 +17,11 @@
 #include "libnetlink.h"
 #include "ll_map.h"
 
-struct idxmap
-{
+#include <sys/socket.h>	/* socket() */
+#include <net/if.h>	/* struct ifreq and co. */
+#include <sys/ioctl.h>	/* ioctl() & SIOCGIFINDEX */
+
+struct idxmap {
 	struct idxmap * next;
 	int		index;
 	int		type;
@@ -129,6 +132,7 @@
 	static char ncache[16];
 	static int icache;
 	struct idxmap *im;
+	int sock_fd;
 	int i;
 
 	if (name == NULL)
@@ -144,19 +148,39 @@
 			}
 		}
 	}
+	/* We have not found the interface in our cache, but the kernel
+	 * may still know about it. One reason is that we may be using
+	 * module on-demand loading, which means that the kernel will
+	 * load the module and make the interface exist only when
+	 * we explicitely request it (check for dev_load() in net/core/dev.c).
+	 * I can think of other similar scenario, but they are less common...
+	 * Jean II */
+	sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sock_fd) {
+		struct ifreq ifr;
+		int ret;
+		strncpy(ifr.ifr_name, name, IFNAMSIZ);
+		ifr.ifr_ifindex = -1;
+		ret = ioctl(sock_fd, SIOCGIFINDEX, &ifr);
+		close(sock_fd);
+		if (ret >= 0)
+			/* In theory, we should redump the interface list
+			 * to update our cache, this is left as an exercise
+			 * to the reader... Jean II */
+			return ifr.ifr_ifindex;
+	}
+	
 	return 0;
 }
 
 int ll_init_map(struct rtnl_handle *rth)
 {
 	if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) {
-		perror("Cannot send dump request");
-		exit(1);
+		bb_perror_msg_and_die("cannot send dump request");
 	}
 
 	if (rtnl_dump_filter(rth, ll_remember_index, &idxmap, NULL, NULL) < 0) {
-		fprintf(stderr, "Dump terminated\n");
-		exit(1);
+		bb_error_msg_and_die("dump terminated");
 	}
 	return 0;
 }




More information about the busybox-cvs mailing list