Browse Source

[dhcp] Allow multiple interfaces in dhcp command

The "dhcp" command now accepts a list of interfaces to try until one
succeeds.  For example:

 iPXE> dhcp net0 net1 net2

If no interfaces are specified, all interfaces will be tried.

Note that interfaces that fail to DHCP are closed in order to avoid
memory exhaustion.  This behavior differs from the previous "dhcp"
command implementation but should not affect any existing scripts
since a "dhcp" command failure would in any case cause the script to
abort.

Originally-implemented-by: Lars Kellogg-Stedman <lars@oddbit.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
e3c7a1948d
1 changed files with 56 additions and 22 deletions
  1. 56
    22
      src/hci/commands/dhcp_cmd.c

+ 56
- 22
src/hci/commands/dhcp_cmd.c View File

@@ -45,12 +45,52 @@ FILE_LICENCE ( GPL2_OR_LATER );
45 45
  */
46 46
 static void dhcp_syntax ( char **argv ) {
47 47
 	printf ( "Usage:\n"
48
-		 "  %s <interface>\n"
48
+		 "  %s [<interface>] [<interface>...]\n"
49 49
 		 "\n"
50 50
 		 "Configure a network interface using DHCP\n",
51 51
 		 argv[0] );
52 52
 }
53 53
 
54
+/**
55
+ * Execute "dhcp" command for a network device
56
+ *
57
+ * @v netdev		Network device
58
+ * @ret rc		Exit code
59
+ */
60
+static int dhcp_exec_netdev ( struct net_device *netdev ) {
61
+	int rc;
62
+
63
+	if ( ( rc = dhcp ( netdev ) ) != 0 ) {
64
+		printf ( "Could not configure %s: %s\n",
65
+			 netdev->name, strerror ( rc ) );
66
+
67
+		/* Close device on failure, to avoid memory exhaustion */
68
+		netdev_close ( netdev );
69
+
70
+		return 1;
71
+	}
72
+
73
+	return 0;
74
+}
75
+
76
+/**
77
+ * Execute "dhcp" command for a named network device
78
+ *
79
+ * @v netdev_name	Network device name
80
+ * @ret rc		Exit code
81
+ */
82
+static int dhcp_exec_name ( const char *netdev_name ) {
83
+	struct net_device *netdev;
84
+
85
+	netdev = find_netdev ( netdev_name );
86
+	if ( ! netdev ) {
87
+		printf ( "No such interface \"%s\"\n", netdev_name );
88
+		return 1;
89
+	}
90
+
91
+	return dhcp_exec_netdev ( netdev );
92
+}
93
+
54 94
 /**
55 95
  * The "dhcp" command
56 96
  *
@@ -63,7 +103,7 @@ static int dhcp_exec ( int argc, char **argv ) {
63 103
 		{ "help", 0, NULL, 'h' },
64 104
 		{ NULL, 0, NULL, 0 },
65 105
 	};
66
-	const char *netdev_txt;
106
+	const char *netdev_name;
67 107
 	struct net_device *netdev;
68 108
 	int c;
69 109
 	int rc;
@@ -80,28 +120,22 @@ static int dhcp_exec ( int argc, char **argv ) {
80 120
 		}
81 121
 	}
82 122
 
83
-	/* Need exactly one interface name remaining after the options */
84
-	if ( optind != ( argc - 1 ) ) {
85
-		dhcp_syntax ( argv );
86
-		return 1;
87
-	}
88
-	netdev_txt = argv[optind];
89
-
90
-	/* Parse arguments */
91
-	netdev = find_netdev ( netdev_txt );
92
-	if ( ! netdev ) {
93
-		printf ( "No such interface: %s\n", netdev_txt );
94
-		return 1;
95
-	}
96
-
97
-	/* Perform DHCP */
98
-	if ( ( rc = dhcp ( netdev ) ) != 0 ) {
99
-		printf ( "Could not configure %s: %s\n", netdev->name,
100
-			 strerror ( rc ) );
101
-		return 1;
123
+	if ( optind != argc ) {
124
+		/* Treat arguments as a list of interfaces to try */
125
+		while ( optind != argc ) {
126
+			netdev_name = argv[optind++];
127
+			if ( ( rc = dhcp_exec_name ( netdev_name ) ) == 0 )
128
+				return 0;
129
+		}
130
+	} else {
131
+		/* Try all interfaces */
132
+		for_each_netdev ( netdev ) {
133
+			if ( ( rc = dhcp_exec_netdev ( netdev ) ) == 0 )
134
+				return 0;
135
+		}
102 136
 	}
103 137
 
104
-	return 0;
138
+	return 1;
105 139
 }
106 140
 
107 141
 /**

Loading…
Cancel
Save