[gPXE-devel] [gPXE] PATCH: Allow "dhcp" command to iterate over multiple interfaces like autoboot()

Stefan Hajnoczi stefanha at gmail.com
Sat Jul 24 14:04:43 EDT 2010


CCed to the gpxe-devel at etherboot.org mailing list.  The original mail went to
gpxe at etherboot.org.

Here is the dhcp multiple interface patch from Lars Kellogg-Stedman
<lars at oddbit.com> inline for easy reviewing:

diff --git a/src/hci/commands/dhcp_cmd.c b/src/hci/commands/dhcp_cmd.c
index 96aac8d..a494068 100644
--- a/src/hci/commands/dhcp_cmd.c
+++ b/src/hci/commands/dhcp_cmd.c
@@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <gpxe/in.h>
 #include <gpxe/command.h>
 #include <usr/dhcpmgmt.h>
+#include <usr/ifmgmt.h>
 
 /** @file
  *
@@ -45,10 +46,87 @@ FILE_LICENCE ( GPL2_OR_LATER );
  */
 static void dhcp_syntax ( char **argv ) {
 	printf ( "Usage:\n"
-		 "  %s <interface>\n"
+		 "  %s [-c] <interface> [<interface> ...]\n"
+		 "  %s any\n"
 		 "\n"
 		 "Configure a network interface using DHCP\n",
-		 argv[0] );
+		 argv[0], argv[0] );
+}
+
+/**
+ * Given a device name, attempt to configure that device using dhcp.
+ *
+ * @netdev_name		Name of the network device
+ */
+static int dhcp_one_device_name (char *netdev_name) {
+	int rc;
+	struct net_device *netdev;
+
+	netdev = find_netdev ( netdev_name );
+
+	if ( ! netdev ) {
+		printf ( "No such interface: %s\n", netdev_name );
+		return 2;
+	}
+
+	/* Perform DHCP */
+	if ( ( rc = dhcp ( netdev ) ) != 0 ) {
+		printf ( "Could not configure %s: %s\n", netdev->name,
+				strerror ( rc ) );
+		return 1;
+	} 
+
+	return 0;
+}
+
+/**
+ * Call dhcp_one_device_name() for each name in argv.
+ *
+ * @argc		Number of devices
+ * @argv		List of device names
+ * @keep_going		If TRUE, ignore errors caused by unknown device names.
+ */
+static int dhcp_each_device_name (int argc, char *argv[], int keep_going) {
+	int i;
+
+	for (i=0; i<argc; i++) {
+		switch ( dhcp_one_device_name ( argv[i] ) ) {
+			case 0:
+				return 0;
+			case 1:
+				break;
+			case 2:
+				if (! keep_going)
+					return 1;
+		}
+	}
+
+	printf( "Could not configure any interface.\n" );
+	return 1;
+}
+
+/**
+ * Call dhcp_one_device_name() for each device in net_devices.
+ */
+static int dhcp_each_device () {
+	struct net_device *netdev;
+
+	for_each_netdev ( netdev ) {
+		switch ( dhcp_one_device_name ( netdev->name ) ) {
+			case 0:
+				return 0;
+			case 1:
+				break;
+			case 2:
+				/* we should never get here, since we're working
+				 * from a list of known device names.
+				 */
+				return 1;
+		}
+	}
+
+	printf( "Could not configure any interface.\n" );
+	return 1;
 }
 
 /**
@@ -61,16 +139,18 @@ static void dhcp_syntax ( char **argv ) {
 static int dhcp_exec ( int argc, char **argv ) {
 	static struct option longopts[] = {
 		{ "help", 0, NULL, 'h' },
+		{ "continue", 0, NULL, 'c' },
 		{ NULL, 0, NULL, 0 },
 	};
-	const char *netdev_txt;
-	struct net_device *netdev;
 	int c;
-	int rc;
+	int keep_going = 0;
 
 	/* Parse options */
-	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
+	while ( ( c = getopt_long ( argc, argv, "ch", longopts, NULL ) ) >= 0 ){
 		switch ( c ) {
+		case 'c':
+			keep_going = 1;
+			break;
 		case 'h':
 			/* Display help text */
 		default:
@@ -81,27 +161,19 @@ static int dhcp_exec ( int argc, char **argv ) {
 	}
 
 	/* Need exactly one interface name remaining after the options */
-	if ( optind != ( argc - 1 ) ) {
+	if ( ( argc - optind ) < 1 ) {
 		dhcp_syntax ( argv );
 		return 1;
 	}
-	netdev_txt = argv[optind];
 
-	/* Parse arguments */
-	netdev = find_netdev ( netdev_txt );
-	if ( ! netdev ) {
-		printf ( "No such interface: %s\n", netdev_txt );
-		return 1;
+	if (strcmp(argv[optind], "any") == 0) {
+		return dhcp_each_device ();
+	} else {
+		return dhcp_each_device_name (argc-optind, argv+optind, keep_going);
 	}
 
-	/* Perform DHCP */
-	if ( ( rc = dhcp ( netdev ) ) != 0 ) {
-		printf ( "Could not configure %s: %s\n", netdev->name,
-			 strerror ( rc ) );
-		return 1;
-	}
-
-	return 0;
+	/* we should never get here. */
+	return 1;
 }
 
 /**


More information about the gPXE-devel mailing list