[klibc] skip unconnected interfaces

Thayne Harbaugh tharbaugh at lnxi.com
Thu Jan 6 13:39:43 PST 2005


This patch makes it so that ipconfig only configures devices that are
connected:

--- klibc-0.194/ipconfig/main.c.orig	2005-01-06 15:20:24.749525888 -0700
+++ klibc-0.194/ipconfig/main.c	2005-01-06 15:24:48.038499880 -0700
@@ -27,6 +27,7 @@
 static char do_not_config;
 static unsigned int default_caps = CAP_DHCP | CAP_BOOTP | CAP_RARP;
 static int loop_timeout = -1;
+static int only_connected = 0;
 static int configured;
 
 struct state {
@@ -290,6 +291,38 @@
 	return ret;
 }
 
+static int ulong_from_sys_device_file(const char *path_prefix,
+				      const char *dev_name,
+				      const char *dev_file,
+				      unsigned long *val)
+{
+	char t[PATH_MAX], p[255];
+	int i, fd, rc = -1;
+
+	i = snprintf(t, PATH_MAX-1, "%s/%s/%s", path_prefix, dev_name, dev_file);
+	if (i < 0 || i >= PATH_MAX-1)
+		goto done;
+	t[i] = '\0';
+	DEBUG(("%s(%s)\n", __func__, t));
+	if ((fd = open(t, O_RDONLY)) < 0) {
+		perror(t);
+		goto done;
+	}
+
+	i = read(fd, &p, sizeof(p) - 1);
+	close(fd);
+	if (i < 0) {
+		perror(t);
+		goto done;
+	}
+	p[i] = '\0';
+	*val = strtoul(p, NULL, 0);
+
+	rc = 0;
+ done:
+	return rc;
+}
+
 static int loop(void)
 {
 #define NR_FDS	1
@@ -316,11 +349,27 @@
 		int pending = 0;
 		int timeout_ms;
 		int x;
+		unsigned long carrier;
 
 		for (s = slist; s; s = s->next) {
 			if (s->state == DEVST_COMPLETE)
 				continue;
 
+			/*
+			 * If we only want to configure net devices that
+			 * are connected and it's been 10 seconds then
+			 * ignore devices that don't have carriers.
+			 */
+			if (only_connected  && now.tv_sec - start > 10)
+				if (ulong_from_sys_device_file(sysfs_class_net,
+							       s->dev->name,
+							       "carrier",
+							       &carrier) < 0
+				    || !carrier) {
+					fprintf(stderr, "Skipping %s: NO CARRIER\n", s->dev->name);
+					continue;
+				}
+ 
 			pending++;
 
 			if (s->expire - now.tv_sec <= 0)
@@ -500,8 +549,11 @@
  done:
 	if (dev->name == NULL ||
 	    dev->name[0] == '\0' ||
-	    strcmp(dev->name, "all") == 0) {
+	    strcmp(dev->name, "all") == 0 ||
+	    strcmp(dev->name, "connected") == 0) {
 		add_all_devices(dev);
+		if (strcmp(dev->name, "connected") == 0)
+			only_connected = 1;
 		return 0;
 	}
 	return 1;
@@ -580,8 +632,6 @@
 	DIR *d;
 	struct dirent *de;
 	struct netdev *dev;
-	char t[PATH_MAX], p[255];
-	int i, fd;
 	unsigned long flags;
 
 	d = opendir(sysfs_class_net);
@@ -592,33 +642,16 @@
 		/* This excludes devices beginning with dots or "dummy", as well as . or .. */
 		if ( de->d_name[0] == '.' || !strcmp(de->d_name, "..") )
 			continue;
-		i = snprintf(t, PATH_MAX-1, "%s/%s/flags", sysfs_class_net, de->d_name);
-		if (i < 0 || i >= PATH_MAX-1)
+
+		if (ulong_from_sys_device_file(sysfs_class_net, de->d_name, "flags", &flags) < 0)
 			continue;
-		t[i] = '\0';
-		fd = open(t, O_RDONLY);
-		if (fd < 0) {
-			perror(t);
+		if ((flags & IFF_LOOPBACK)
+		    || !(flags & (IFF_BROADCAST|IFF_POINTOPOINT)))
 			continue;
-		}
-		i = read(fd, &p, sizeof(p) - 1);
-		close(fd);
-		if (i < 0) {
-			perror(t);
+
+		if ( !(dev = add_device(de->d_name)) )
 			continue;
-		}
-		p[i] = '\0';
-		flags = strtoul(p, NULL, 0);
-		/* Heuristic for if this is a reasonable boot interface.
-		   This is the same
-		   logic the in-kernel ipconfig uses... */
-		if ( !(flags & IFF_LOOPBACK) &&
-		     (flags & (IFF_BROADCAST|IFF_POINTOPOINT)) )
-		{
-			if ( !(dev = add_device(de->d_name)) )
-				continue;
-			bringup_one_dev(template, dev);
-		}
+		bringup_one_dev(template, dev);
 	}
 	closedir(d);
 	return 1;

-- 
Thayne Harbaugh
Linux Networx



More information about the klibc mailing list