Browse Source

[ifmgmt] Add ifconf() to carry out network device configuration

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
26b87b221b
2 changed files with 90 additions and 2 deletions
  1. 3
    0
      src/include/usr/ifmgmt.h
  2. 87
    2
      src/usr/ifmgmt.c

+ 3
- 0
src/include/usr/ifmgmt.h View File

@@ -10,8 +10,11 @@
10 10
 FILE_LICENCE ( GPL2_OR_LATER );
11 11
 
12 12
 struct net_device;
13
+struct net_device_configurator;
13 14
 
14 15
 extern int ifopen ( struct net_device *netdev );
16
+extern int ifconf ( struct net_device *netdev,
17
+		    struct net_device_configurator *configurator );
15 18
 extern void ifclose ( struct net_device *netdev );
16 19
 extern void ifstat ( struct net_device *netdev );
17 20
 extern int iflinkwait ( struct net_device *netdev, unsigned long timeout );

+ 87
- 2
src/usr/ifmgmt.c View File

@@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
29 29
 #include <ipxe/job.h>
30 30
 #include <ipxe/monojob.h>
31 31
 #include <ipxe/nap.h>
32
+#include <ipxe/timer.h>
32 33
 #include <usr/ifmgmt.h>
33 34
 
34 35
 /** @file
@@ -37,6 +38,15 @@ FILE_LICENCE ( GPL2_OR_LATER );
37 38
  *
38 39
  */
39 40
 
41
+/** Default time to wait for link-up */
42
+#define LINK_WAIT_TIMEOUT ( 15 * TICKS_PER_SEC )
43
+
44
+/** Default unsuccessful configuration status code */
45
+#define EADDRNOTAVAIL_CONFIG __einfo_error ( EINFO_EADDRNOTAVAIL_CONFIG )
46
+#define EINFO_EADDRNOTAVAIL_CONFIG					\
47
+	__einfo_uniqify ( EINFO_EADDRNOTAVAIL, 0x01,			\
48
+			  "No configuration methods succeeded" )
49
+
40 50
 /**
41 51
  * Open network device
42 52
  *
@@ -111,6 +121,8 @@ struct ifpoller {
111 121
 	struct interface job;
112 122
 	/** Network device */
113 123
 	struct net_device *netdev;
124
+	/** Network device configurator (if applicable) */
125
+	struct net_device_configurator *configurator;
114 126
 	/**
115 127
 	 * Check progress
116 128
 	 *
@@ -150,17 +162,21 @@ static struct interface_descriptor ifpoller_job_desc =
150 162
  * Poll network device until completion
151 163
  *
152 164
  * @v netdev		Network device
165
+ * @v configurator	Network device configurator (if applicable)
153 166
  * @v timeout		Timeout period, in ticks
154 167
  * @v progress		Method to check progress
155 168
  * @ret rc		Return status code
156 169
  */
157
-static int ifpoller_wait ( struct net_device *netdev, unsigned long timeout,
170
+static int ifpoller_wait ( struct net_device *netdev,
171
+			   struct net_device_configurator *configurator,
172
+			   unsigned long timeout,
158 173
 			   int ( * progress ) ( struct ifpoller *ifpoller ) ) {
159 174
 	static struct ifpoller ifpoller = {
160 175
 		.job = INTF_INIT ( ifpoller_job_desc ),
161 176
 	};
162 177
 
163 178
 	ifpoller.netdev = netdev;
179
+	ifpoller.configurator = configurator;
164 180
 	ifpoller.progress = progress;
165 181
 	intf_plug_plug ( &monojob, &ifpoller.job );
166 182
 	return monojob_wait ( "", timeout );
@@ -204,5 +220,74 @@ int iflinkwait ( struct net_device *netdev, unsigned long timeout ) {
204 220
 
205 221
 	/* Wait for link-up */
206 222
 	printf ( "Waiting for link-up on %s", netdev->name );
207
-	return ifpoller_wait ( netdev, timeout, iflinkwait_progress );
223
+	return ifpoller_wait ( netdev, NULL, timeout, iflinkwait_progress );
224
+}
225
+
226
+/**
227
+ * Check configuration progress
228
+ *
229
+ * @v ifpoller		Network device poller
230
+ * @ret ongoing_rc	Ongoing job status code (if known)
231
+ */
232
+static int ifconf_progress ( struct ifpoller *ifpoller ) {
233
+	struct net_device *netdev = ifpoller->netdev;
234
+	struct net_device_configurator *configurator = ifpoller->configurator;
235
+	struct net_device_configuration *config;
236
+	int rc;
237
+
238
+	/* Do nothing unless configuration has completed */
239
+	if ( netdev_configuration_in_progress ( netdev ) )
240
+		return 0;
241
+
242
+	/* Terminate with appropriate overall return status code */
243
+	if ( configurator ) {
244
+		config = netdev_configuration ( netdev, configurator );
245
+		rc = config->rc;
246
+	} else {
247
+		rc = ( netdev_configuration_ok ( netdev ) ?
248
+		       0 : -EADDRNOTAVAIL_CONFIG );
249
+	}
250
+	intf_close ( &ifpoller->job, rc );
251
+
252
+	return rc;
253
+}
254
+
255
+/**
256
+ * Perform network device configuration
257
+ *
258
+ * @v netdev		Network device
259
+ * @v configurator	Network device configurator, or NULL to use all
260
+ * @ret rc		Return status code
261
+ */
262
+int ifconf ( struct net_device *netdev,
263
+	     struct net_device_configurator *configurator ) {
264
+	int rc;
265
+
266
+	/* Ensure device is open and link is up */
267
+	if ( ( rc = iflinkwait ( netdev, LINK_WAIT_TIMEOUT ) ) != 0 )
268
+		return rc;
269
+
270
+	/* Start configuration */
271
+	if ( configurator ) {
272
+		if ( ( rc = netdev_configure ( netdev, configurator ) ) != 0 ) {
273
+			printf ( "Could not configure %s via %s: %s\n",
274
+				 netdev->name, configurator->name,
275
+				 strerror ( rc ) );
276
+			return rc;
277
+		}
278
+	} else {
279
+		if ( ( rc = netdev_configure_all ( netdev ) ) != 0 ) {
280
+			printf ( "Could not configure %s: %s\n",
281
+				 netdev->name, strerror ( rc ) );
282
+			return rc;
283
+		}
284
+	}
285
+
286
+	/* Wait for configuration to complete */
287
+	printf ( "Configuring %s%s%s(%s %s)",
288
+		 ( configurator ? "[" : "" ),
289
+		 ( configurator ? configurator->name : "" ),
290
+		 ( configurator ? "] " : "" ),
291
+		 netdev->name, netdev->ll_protocol->ntoa ( netdev->ll_addr ) );
292
+	return ifpoller_wait ( netdev, configurator, 0, ifconf_progress );
208 293
 }

Loading…
Cancel
Save