Просмотр исходного кода

[Settings] Remove assumption that all settings have DHCP tag values

Allow for settings to be described by something other than a DHCP option
tag if desirable.  Currently used only for the MAC address setting.

Separate out fake DHCP packet creation code from dhcp.c to fakedhcp.c.

Remove notion of settings from dhcppkt.c.

Rationalise dhcp.c to use settings API only for final registration of the
DHCP options, rather than using {store,fetch}_setting throughout.
tags/v0.9.4
Michael Brown 16 лет назад
Родитель
Сommit
92d15eff30

+ 3
- 4
src/arch/i386/image/nbi.c Просмотреть файл

@@ -8,8 +8,7 @@
8 8
 #include <gpxe/segment.h>
9 9
 #include <gpxe/init.h>
10 10
 #include <gpxe/netdevice.h>
11
-#include <gpxe/dhcp.h>
12
-#include <gpxe/dhcppkt.h>
11
+#include <gpxe/fakedhcp.h>
13 12
 #include <gpxe/image.h>
14 13
 #include <gpxe/features.h>
15 14
 
@@ -400,8 +399,8 @@ static int nbi_prepare_dhcp ( struct image *image ) {
400 399
 		return -ENODEV;
401 400
 	}
402 401
 
403
-	if ( ( rc = create_dhcpack ( boot_netdev, basemem_packet,
404
-				     sizeof ( basemem_packet ) ) ) != 0 ) {
402
+	if ( ( rc = create_fakedhcpack ( boot_netdev, basemem_packet,
403
+					 sizeof ( basemem_packet ) ) ) != 0 ) {
405 404
 		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
406 405
 		return rc;
407 406
 	}

+ 14
- 13
src/core/ibft.c Просмотреть файл

@@ -123,15 +123,16 @@ static void ibft_set_ipaddr ( struct ibft_ipaddr *ipaddr, struct in_addr in ) {
123 123
 }
124 124
 
125 125
 /**
126
- * Fill in an IP address within iBFT from DHCP option
126
+ * Fill in an IP address within iBFT from configuration setting
127 127
  *
128 128
  * @v ipaddr		IP address field
129
+ * @v setting		Configuration setting
129 130
  * @v tag		DHCP option tag
130 131
  */
131 132
 static void ibft_set_ipaddr_option ( struct ibft_ipaddr *ipaddr,
132
-				     unsigned int tag ) {
133
+				     struct setting *setting ) {
133 134
 	struct in_addr in = { 0 };
134
-	fetch_ipv4_setting ( NULL, tag, &in );
135
+	fetch_ipv4_setting ( NULL, setting, &in );
135 136
 	ibft_set_ipaddr ( ipaddr, in );
136 137
 }
137 138
 
@@ -182,21 +183,21 @@ static int ibft_set_string ( struct ibft_string_block *strings,
182 183
 }
183 184
 
184 185
 /**
185
- * Fill in a string field within iBFT from DHCP option
186
+ * Fill in a string field within iBFT from configuration setting
186 187
  *
187 188
  * @v strings		iBFT string block descriptor
188 189
  * @v string		String field
189
- * @v tag		DHCP option tag
190
+ * @v setting		Configuration setting
190 191
  * @ret rc		Return status code
191 192
  */
192 193
 static int ibft_set_string_option ( struct ibft_string_block *strings,
193 194
 				    struct ibft_string *string,
194
-				    unsigned int tag ) {
195
+				    struct setting *setting ) {
195 196
 	int len;
196 197
 	char *dest;
197 198
 	int rc;
198 199
 
199
-	len = fetch_setting_len ( NULL, tag );
200
+	len = fetch_setting_len ( NULL, setting );
200 201
 	if ( len < 0 ) {
201 202
 		string->offset = 0;
202 203
 		string->length = 0;
@@ -206,7 +207,7 @@ static int ibft_set_string_option ( struct ibft_string_block *strings,
206 207
 	if ( ( rc = ibft_alloc_string ( strings, string, len ) ) != 0 )
207 208
 		return rc;
208 209
 	dest = ( ( ( char * ) strings->table ) + string->offset );
209
-	fetch_string_setting ( NULL, tag, dest, ( len + 1 ) );
210
+	fetch_string_setting ( NULL, setting, dest, ( len + 1 ) );
210 211
 	return 0;
211 212
 }
212 213
 
@@ -226,15 +227,15 @@ static int ibft_fill_nic ( struct ibft_nic *nic,
226 227
 	int rc;
227 228
 
228 229
 	/* Extract values from DHCP configuration */
229
-	ibft_set_ipaddr_option ( &nic->ip_address, DHCP_EB_YIADDR );
230
-	ibft_set_ipaddr_option ( &nic->gateway, DHCP_ROUTERS );
231
-	ibft_set_ipaddr_option ( &nic->dns[0], DHCP_DNS_SERVERS );
230
+	ibft_set_ipaddr_option ( &nic->ip_address, &ip_setting );
231
+	ibft_set_ipaddr_option ( &nic->gateway, &gateway_setting );
232
+	ibft_set_ipaddr_option ( &nic->dns[0], &dns_setting );
232 233
 	if ( ( rc = ibft_set_string_option ( strings, &nic->hostname,
233
-					     DHCP_HOST_NAME ) ) != 0 )
234
+					     &hostname_setting ) ) != 0 )
234 235
 		return rc;
235 236
 
236 237
 	/* Derive subnet mask prefix from subnet mask */
237
-	fetch_ipv4_setting ( NULL, DHCP_SUBNET_MASK, &netmask_addr );
238
+	fetch_ipv4_setting ( NULL, &netmask_setting, &netmask_addr );
238 239
 	while ( netmask_addr.s_addr ) {
239 240
 		if ( netmask_addr.s_addr & 0x1 )
240 241
 			netmask_count++;

+ 7
- 6
src/core/nvo.c Просмотреть файл

@@ -138,19 +138,20 @@ static void nvo_init_dhcpopts ( struct nvo_block *nvo ) {
138 138
  * Store value of NVO setting
139 139
  *
140 140
  * @v settings		Settings block
141
- * @v tag		Setting tag number
141
+ * @v setting		Setting to store
142 142
  * @v data		Setting data, or NULL to clear setting
143 143
  * @v len		Length of setting data
144 144
  * @ret rc		Return status code
145 145
  */
146
-static int nvo_store ( struct settings *settings, unsigned int tag,
146
+static int nvo_store ( struct settings *settings, struct setting *setting,
147 147
 		       const void *data, size_t len ) {
148 148
 	struct nvo_block *nvo =
149 149
 		container_of ( settings, struct nvo_block, settings );
150 150
 	int rc;
151 151
 
152 152
 	/* Update stored options */
153
-	if ( ( rc = dhcpopt_store ( &nvo->dhcpopts, tag, data, len ) ) != 0 ) {
153
+	if ( ( rc = dhcpopt_store ( &nvo->dhcpopts, setting->tag,
154
+				    data, len ) ) != 0 ) {
154 155
 		DBGC ( nvo, "NVO %p could not store %zd bytes: %s\n",
155 156
 		       nvo, len, strerror ( rc ) );
156 157
 		return rc;
@@ -167,7 +168,7 @@ static int nvo_store ( struct settings *settings, unsigned int tag,
167 168
  * Fetch value of NVO setting
168 169
  *
169 170
  * @v settings		Settings block
170
- * @v tag		Setting tag number
171
+ * @v setting		Setting to fetch
171 172
  * @v data		Buffer to fill with setting data
172 173
  * @v len		Length of buffer
173 174
  * @ret len		Length of setting data, or negative error
@@ -175,12 +176,12 @@ static int nvo_store ( struct settings *settings, unsigned int tag,
175 176
  * The actual length of the setting will be returned even if
176 177
  * the buffer was too small.
177 178
  */
178
-static int nvo_fetch ( struct settings *settings, unsigned int tag,
179
+static int nvo_fetch ( struct settings *settings, struct setting *setting,
179 180
 		       void *data, size_t len ) {
180 181
 	struct nvo_block *nvo =
181 182
 		container_of ( settings, struct nvo_block, settings );
182 183
 
183
-	return dhcpopt_fetch ( &nvo->dhcpopts, tag, data, len );
184
+	return dhcpopt_fetch ( &nvo->dhcpopts, setting->tag, data, len );
184 185
 }
185 186
 
186 187
 /** NVO settings operations */

+ 181
- 273
src/core/settings.c Просмотреть файл

@@ -35,43 +35,24 @@
35 35
  *
36 36
  */
37 37
 
38
+/** Registered settings */
39
+static struct setting settings[0]
40
+	__table_start ( struct setting, settings );
41
+static struct setting settings_end[0]
42
+	__table_end ( struct setting, settings );
43
+
38 44
 /** Registered setting types */
39 45
 static struct setting_type setting_types[0]
40 46
 	__table_start ( struct setting_type, setting_types );
41 47
 static struct setting_type setting_types_end[0]
42 48
 	__table_end ( struct setting_type, setting_types );
43 49
 
44
-/** Registered named settings */
45
-static struct named_setting named_settings[0]
46
-	__table_start ( struct named_setting, named_settings );
47
-static struct named_setting named_settings_end[0]
48
-	__table_end ( struct named_setting, named_settings );
49
-
50 50
 /** Registered settings applicators */
51 51
 static struct settings_applicator settings_applicators[0]
52 52
 	__table_start ( struct settings_applicator, settings_applicators );
53 53
 static struct settings_applicator settings_applicators_end[0]
54 54
 	__table_end ( struct settings_applicator, settings_applicators );
55 55
 
56
-/**
57
- * Obtain printable version of a settings tag number
58
- *
59
- * @v tag		Settings tag number
60
- * @ret name		String representation of the tag
61
- */
62
-static inline char * setting_tag_name ( unsigned int tag ) {
63
-	static char name[8];
64
-
65
-	if ( DHCP_IS_ENCAP_OPT ( tag ) ) {
66
-		snprintf ( name, sizeof ( name ), "%d.%d",
67
-			   DHCP_ENCAPSULATOR ( tag ),
68
-			   DHCP_ENCAPSULATED ( tag ) );
69
-	} else {
70
-		snprintf ( name, sizeof ( name ), "%d", tag );
71
-	}
72
-	return name;
73
-}
74
-
75 56
 /******************************************************************************
76 57
  *
77 58
  * Registered settings blocks
@@ -83,32 +64,33 @@ static inline char * setting_tag_name ( unsigned int tag ) {
83 64
  * Store value of simple setting
84 65
  *
85 66
  * @v options		DHCP option block
86
- * @v tag		Setting tag number
67
+ * @v setting		Setting to store
87 68
  * @v data		Setting data, or NULL to clear setting
88 69
  * @v len		Length of setting data
89 70
  * @ret rc		Return status code
90 71
  */
91
-int simple_settings_store ( struct settings *settings, unsigned int tag,
72
+int simple_settings_store ( struct settings *settings, struct setting *setting,
92 73
 			    const void *data, size_t len ) {
93 74
 	struct simple_settings *simple =
94 75
 		container_of ( settings, struct simple_settings, settings );
95
-	return dhcpopt_extensible_store ( &simple->dhcpopts, tag, data, len );
76
+	return dhcpopt_extensible_store ( &simple->dhcpopts, setting->tag,
77
+					  data, len );
96 78
 }
97 79
 
98 80
 /**
99 81
  * Fetch value of simple setting
100 82
  *
101 83
  * @v options		DHCP option block
102
- * @v tag		Setting tag number
84
+ * @v setting		Setting to fetch
103 85
  * @v data		Buffer to fill with setting data
104 86
  * @v len		Length of buffer
105 87
  * @ret len		Length of setting data, or negative error
106 88
  */
107
-int simple_settings_fetch ( struct settings *settings, unsigned int tag,
89
+int simple_settings_fetch ( struct settings *settings, struct setting *setting,
108 90
 			    void *data, size_t len ) {
109 91
 	struct simple_settings *simple =
110 92
 		container_of ( settings, struct simple_settings, settings );
111
-	return dhcpopt_fetch ( &simple->dhcpopts, tag, data, len );
93
+	return dhcpopt_fetch ( &simple->dhcpopts, setting->tag, data, len );
112 94
 }
113 95
 
114 96
 /** Simple settings operations */
@@ -174,14 +156,14 @@ static void reprioritise_settings ( struct settings *settings ) {
174 156
 		return;
175 157
 
176 158
 	/* Read priority, if present */
177
-	priority = fetch_intz_setting ( settings, DHCP_EB_PRIORITY );
159
+	priority = fetch_intz_setting ( settings, &priority_setting );
178 160
 
179 161
 	/* Remove from siblings list */
180 162
 	list_del ( &settings->siblings );
181 163
 
182 164
 	/* Reinsert after any existing blocks which have a higher priority */
183 165
 	list_for_each_entry ( tmp, &parent->children, siblings ) {
184
-		tmp_priority = fetch_intz_setting ( tmp, DHCP_EB_PRIORITY );
166
+		tmp_priority = fetch_intz_setting ( tmp, &priority_setting );
185 167
 		if ( priority > tmp_priority )
186 168
 			break;
187 169
 	}
@@ -292,12 +274,12 @@ struct settings * find_settings ( const char *name ) {
292 274
  * Store value of setting
293 275
  *
294 276
  * @v settings		Settings block
295
- * @v tag		Setting tag number
277
+ * @v setting		Setting to store
296 278
  * @v data		Setting data, or NULL to clear setting
297 279
  * @v len		Length of setting data
298 280
  * @ret rc		Return status code
299 281
  */
300
-int store_setting ( struct settings *settings, unsigned int tag,
282
+int store_setting ( struct settings *settings, struct setting *setting,
301 283
 		    const void *data, size_t len ) {
302 284
 	int rc;
303 285
 
@@ -306,11 +288,12 @@ int store_setting ( struct settings *settings, unsigned int tag,
306 288
 		return -ENODEV;
307 289
 
308 290
 	/* Store setting */
309
-	if ( ( rc = settings->op->store ( settings, tag, data, len ) ) != 0 )
291
+	if ( ( rc = settings->op->store ( settings, setting,
292
+					  data, len ) ) != 0 )
310 293
 		return rc;
311 294
 
312 295
 	/* Reprioritise settings if necessary */
313
-	if ( tag == DHCP_EB_PRIORITY )
296
+	if ( setting_cmp ( setting, &priority_setting ) == 0 )
314 297
 		reprioritise_settings ( settings );
315 298
 
316 299
 	/* If these settings are registered, apply potentially-updated
@@ -331,7 +314,7 @@ int store_setting ( struct settings *settings, unsigned int tag,
331 314
  * Fetch value of setting
332 315
  *
333 316
  * @v settings		Settings block, or NULL to search all blocks
334
- * @v tag		Setting tag number
317
+ * @v setting		Setting to fetch
335 318
  * @v data		Buffer to fill with setting data
336 319
  * @v len		Length of buffer
337 320
  * @ret len		Length of setting data, or negative error
@@ -339,7 +322,7 @@ int store_setting ( struct settings *settings, unsigned int tag,
339 322
  * The actual length of the setting will be returned even if
340 323
  * the buffer was too small.
341 324
  */
342
-int fetch_setting ( struct settings *settings, unsigned int tag,
325
+int fetch_setting ( struct settings *settings, struct setting *setting,
343 326
 		    void *data, size_t len ) {
344 327
 	struct settings *child;
345 328
 	int ret;
@@ -349,12 +332,14 @@ int fetch_setting ( struct settings *settings, unsigned int tag,
349 332
 		settings = &settings_root;
350 333
 
351 334
 	/* Try this block first */
352
-	if ( ( ret = settings->op->fetch ( settings, tag, data, len ) ) >= 0)
335
+	if ( ( ret = settings->op->fetch ( settings, setting,
336
+					   data, len ) ) >= 0 )
353 337
 		return ret;
354 338
 
355 339
 	/* Recurse into each child block in turn */
356 340
 	list_for_each_entry ( child, &settings->children, siblings ) {
357
-		if ( ( ret = fetch_setting ( child, tag, data, len ) ) >= 0)
341
+		if ( ( ret = fetch_setting ( child, setting,
342
+					     data, len ) ) >= 0 )
358 343
 			return ret;
359 344
 	}
360 345
 
@@ -365,21 +350,21 @@ int fetch_setting ( struct settings *settings, unsigned int tag,
365 350
  * Fetch length of setting
366 351
  *
367 352
  * @v settings		Settings block, or NULL to search all blocks
368
- * @v tag		Setting tag number
353
+ * @v setting		Setting to fetch
369 354
  * @ret len		Length of setting data, or negative error
370 355
  *
371 356
  * This function can also be used as an existence check for the
372 357
  * setting.
373 358
  */
374
-int fetch_setting_len ( struct settings *settings, unsigned int tag ) {
375
-	return fetch_setting ( settings, tag, NULL, 0 );
359
+int fetch_setting_len ( struct settings *settings, struct setting *setting ) {
360
+	return fetch_setting ( settings, setting, NULL, 0 );
376 361
 }
377 362
 
378 363
 /**
379 364
  * Fetch value of string setting
380 365
  *
381 366
  * @v settings		Settings block, or NULL to search all blocks
382
- * @v tag		Setting tag number
367
+ * @v setting		Setting to fetch
383 368
  * @v data		Buffer to fill with setting string data
384 369
  * @v len		Length of buffer
385 370
  * @ret len		Length of string setting, or negative error
@@ -388,25 +373,25 @@ int fetch_setting_len ( struct settings *settings, unsigned int tag ) {
388 373
  * The returned length will be the length of the underlying setting
389 374
  * data.
390 375
  */
391
-int fetch_string_setting ( struct settings *settings, unsigned int tag,
376
+int fetch_string_setting ( struct settings *settings, struct setting *setting,
392 377
 			   char *data, size_t len ) {
393 378
 	memset ( data, 0, len );
394
-	return fetch_setting ( settings, tag, data, ( len - 1 ) );
379
+	return fetch_setting ( settings, setting, data, ( len - 1 ) );
395 380
 }
396 381
 
397 382
 /**
398 383
  * Fetch value of IPv4 address setting
399 384
  *
400 385
  * @v settings		Settings block, or NULL to search all blocks
401
- * @v tag		Setting tag number
386
+ * @v setting		Setting to fetch
402 387
  * @v inp		IPv4 address to fill in
403 388
  * @ret len		Length of setting, or negative error
404 389
  */
405
-int fetch_ipv4_setting ( struct settings *settings, unsigned int tag,
390
+int fetch_ipv4_setting ( struct settings *settings, struct setting *setting,
406 391
 			 struct in_addr *inp ) {
407 392
 	int len;
408 393
 
409
-	len = fetch_setting ( settings, tag, inp, sizeof ( *inp ) );
394
+	len = fetch_setting ( settings, setting, inp, sizeof ( *inp ) );
410 395
 	if ( len < 0 )
411 396
 		return len;
412 397
 	if ( len < ( int ) sizeof ( *inp ) )
@@ -418,11 +403,11 @@ int fetch_ipv4_setting ( struct settings *settings, unsigned int tag,
418 403
  * Fetch value of signed integer setting
419 404
  *
420 405
  * @v settings		Settings block, or NULL to search all blocks
421
- * @v tag		Setting tag number
406
+ * @v setting		Setting to fetch
422 407
  * @v value		Integer value to fill in
423 408
  * @ret len		Length of setting, or negative error
424 409
  */
425
-int fetch_int_setting ( struct settings *settings, unsigned int tag,
410
+int fetch_int_setting ( struct settings *settings, struct setting *setting,
426 411
 			long *value ) {
427 412
 	union {
428 413
 		long value;
@@ -433,7 +418,7 @@ int fetch_int_setting ( struct settings *settings, unsigned int tag,
433 418
 	int i;
434 419
 
435 420
 	buf.value = 0;
436
-	len = fetch_setting ( settings, tag, &buf, sizeof ( buf ) );
421
+	len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) );
437 422
 	if ( len < 0 )
438 423
 		return len;
439 424
 	if ( len > ( int ) sizeof ( buf ) )
@@ -451,16 +436,16 @@ int fetch_int_setting ( struct settings *settings, unsigned int tag,
451 436
  * Fetch value of unsigned integer setting
452 437
  *
453 438
  * @v settings		Settings block, or NULL to search all blocks
454
- * @v tag		Setting tag number
439
+ * @v setting		Setting to fetch
455 440
  * @v value		Integer value to fill in
456 441
  * @ret len		Length of setting, or negative error
457 442
  */
458
-int fetch_uint_setting ( struct settings *settings, unsigned int tag,
443
+int fetch_uint_setting ( struct settings *settings, struct setting *setting,
459 444
 			 unsigned long *value ) {
460 445
 	long svalue;
461 446
 	int len;
462 447
 
463
-	len = fetch_int_setting ( settings, tag, &svalue );
448
+	len = fetch_int_setting ( settings, setting, &svalue );
464 449
 	if ( len < 0 )
465 450
 		return len;
466 451
 
@@ -473,13 +458,13 @@ int fetch_uint_setting ( struct settings *settings, unsigned int tag,
473 458
  * Fetch value of signed integer setting, or zero
474 459
  *
475 460
  * @v settings		Settings block, or NULL to search all blocks
476
- * @v tag		Setting tag number
461
+ * @v setting		Setting to fetch
477 462
  * @ret value		Setting value, or zero
478 463
  */
479
-long fetch_intz_setting ( struct settings *settings, unsigned int tag ) {
464
+long fetch_intz_setting ( struct settings *settings, struct setting *setting ){
480 465
 	long value = 0;
481 466
 
482
-	fetch_int_setting ( settings, tag, &value );
467
+	fetch_int_setting ( settings, setting, &value );
483 468
 	return value;
484 469
 }
485 470
 
@@ -487,80 +472,38 @@ long fetch_intz_setting ( struct settings *settings, unsigned int tag ) {
487 472
  * Fetch value of unsigned integer setting, or zero
488 473
  *
489 474
  * @v settings		Settings block, or NULL to search all blocks
490
- * @v tag		Setting tag number
475
+ * @v setting		Setting to fetch
491 476
  * @ret value		Setting value, or zero
492 477
  */
493 478
 unsigned long fetch_uintz_setting ( struct settings *settings,
494
-				    unsigned int tag ) {
479
+				    struct setting *setting ) {
495 480
 	unsigned long value = 0;
496 481
 
497
-	fetch_uint_setting ( settings, tag, &value );
482
+	fetch_uint_setting ( settings, setting, &value );
498 483
 	return value;
499 484
 }
500 485
 
501 486
 /**
502
- * Copy settings
487
+ * Compare two settings
503 488
  *
504
- * @v dest		Destination settings block
505
- * @v source		Source settings block
506
- * @v encapsulator	Encapsulating setting tag number, or zero
507
- * @ret rc		Return status code
489
+ * @v a			Setting to compare
490
+ * @v b			Setting to compare
491
+ * @ret 0		Settings are the same
492
+ * @ret non-zero	Settings are not the same
508 493
  */
509
-static int copy_encap_settings ( struct settings *dest,
510
-				 struct settings *source,
511
-				 unsigned int encapsulator ) {
512
-	unsigned int subtag;
513
-	unsigned int tag;
514
-	int len;
515
-	int check_len;
516
-	int rc;
494
+int setting_cmp ( struct setting *a, struct setting *b ) {
517 495
 
518
-	for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
519
-		tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
520
-		switch ( tag ) {
521
-		case DHCP_EB_ENCAP:
522
-		case DHCP_VENDOR_ENCAP:
523
-			/* Process encapsulated settings */
524
-			if ( ( rc = copy_encap_settings ( dest, source,
525
-							  tag ) ) != 0 )
526
-				return rc;
527
-			break;
528
-		default:
529
-			/* Copy setting, if present */
530
-			len = fetch_setting_len ( source, tag );
531
-			if ( len < 0 )
532
-				break;
533
-			{
534
-				char buf[len];
535
-
536
-				check_len = fetch_setting ( source, tag, buf,
537
-							    sizeof ( buf ) );
538
-				assert ( check_len == len );
539
-				if ( ( rc = store_setting ( dest, tag, buf,
540
-							    sizeof(buf) )) !=0)
541
-					return rc;
542
-			}
543
-			break;
544
-		}
545
-	}
496
+	/* If the settings have tags, compare them */
497
+	if ( a->tag && ( a->tag == b->tag ) )
498
+		return 0;
546 499
 
547
-	return 0;
548
-}
549
-
550
-/**
551
- * Copy settings
552
- *
553
- * @v dest		Destination settings block
554
- * @v source		Source settings block
555
- * @ret rc		Return status code
556
- */
557
-int copy_settings ( struct settings *dest, struct settings *source ) {
558
-	return copy_encap_settings ( dest, source, 0 );
500
+	/* Otherwise, compare the names */
501
+	return strcmp ( a->name, b->name );
559 502
 }
560 503
 
561 504
 /******************************************************************************
562 505
  *
563
- * Named and typed setting routines
506
+ * Formatted setting routines
564 507
  *
565 508
  ******************************************************************************
566 509
  */
@@ -569,23 +512,22 @@ int copy_settings ( struct settings *dest, struct settings *source ) {
569 512
  * Store value of typed setting
570 513
  *
571 514
  * @v settings		Settings block
572
- * @v tag		Setting tag number
515
+ * @v setting		Setting to store
573 516
  * @v type		Settings type
574 517
  * @v value		Formatted setting data, or NULL
575 518
  * @ret rc		Return status code
576 519
  */
577
-int store_typed_setting ( struct settings *settings,
578
-			  unsigned int tag, struct setting_type *type,
579
-			  const char *value ) {
520
+int storef_setting ( struct settings *settings, struct setting *setting,
521
+		     const char *value ) {
580 522
 
581 523
 	/* NULL value implies deletion.  Avoid imposing the burden of
582 524
 	 * checking for NULL values on each typed setting's storef()
583 525
 	 * method.
584 526
 	 */
585 527
 	if ( ! value )
586
-		return delete_setting ( settings, tag );
528
+		return delete_setting ( settings, setting );
587 529
 		
588
-	return type->storef ( settings, tag, value );
530
+	return setting->type->storef ( settings, setting, value );
589 531
 }
590 532
 
591 533
 /**
@@ -594,11 +536,10 @@ int store_typed_setting ( struct settings *settings,
594 536
  * @v name		Name
595 537
  * @ret setting		Named setting, or NULL
596 538
  */
597
-static struct named_setting * find_named_setting ( const char *name ) {
598
-	struct named_setting *setting;
539
+static struct setting * find_setting ( const char *name ) {
540
+	struct setting *setting;
599 541
 
600
-	for ( setting = named_settings ; setting < named_settings_end ;
601
-	      setting++ ) {
542
+	for ( setting = settings ; setting < settings_end ; setting++ ) {
602 543
 		if ( strcmp ( name, setting->name ) == 0 )
603 544
 			return setting;
604 545
 	}
@@ -625,9 +566,8 @@ static struct setting_type * find_setting_type ( const char *name ) {
625 566
  * Parse setting name
626 567
  *
627 568
  * @v name		Name of setting
628
- * @ret settings	Settings block, or NULL
629
- * @ret tag		Setting tag number
630
- * @ret type		Setting type
569
+ * @v settings		Settings block to fill in
570
+ * @v setting		Setting to fill in
631 571
  * @ret rc		Return status code
632 572
  *
633 573
  * Interprets a name of the form
@@ -635,30 +575,29 @@ static struct setting_type * find_setting_type ( const char *name ) {
635 575
  * fields.
636 576
  */
637 577
 static int parse_setting_name ( const char *name, struct settings **settings,
638
-				unsigned int *tag,
639
-				struct setting_type **type ) {
578
+				struct setting *setting ) {
640 579
 	char tmp_name[ strlen ( name ) + 1 ];
641 580
 	char *settings_name;
642
-	char *tag_name;
581
+	char *setting_name;
643 582
 	char *type_name;
644
-	struct named_setting *named_setting;
583
+	struct setting *named_setting;
645 584
 	char *tmp;
646 585
 
647 586
 	/* Set defaults */
648 587
 	*settings = &settings_root;
649
-	*tag = 0;
650
-	*type = &setting_type_hex;
588
+	memset ( setting, 0, sizeof ( *setting ) );
589
+	setting->type = &setting_type_hex;
651 590
 
652
-	/* Split name into "[settings_name/]tag_name[:type_name]" */
591
+	/* Split name into "[settings_name/]setting_name[:type_name]" */
653 592
 	memcpy ( tmp_name, name, sizeof ( tmp_name ) );
654
-	if ( ( tag_name = strchr ( tmp_name, '/' ) ) != NULL ) {
655
-		*(tag_name++) = 0;
593
+	if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) {
594
+		*(setting_name++) = 0;
656 595
 		settings_name = tmp_name;
657 596
 	} else {
658
-		tag_name = tmp_name;
597
+		setting_name = tmp_name;
659 598
 		settings_name = NULL;
660 599
 	}
661
-	if ( ( type_name = strchr ( tag_name, ':' ) ) != NULL )
600
+	if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
662 601
 		*(type_name++) = 0;
663 602
 
664 603
 	/* Identify settings block, if specified */
@@ -672,19 +611,19 @@ static int parse_setting_name ( const char *name, struct settings **settings,
672 611
 	}
673 612
 
674 613
 	/* Identify tag number */
675
-	if ( ( named_setting = find_named_setting ( tag_name ) ) != NULL ) {
676
-		*tag = named_setting->tag;
677
-		*type = named_setting->type;
614
+	if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) {
615
+		memcpy ( setting, named_setting, sizeof ( *setting ) );
678 616
 	} else {
679 617
 		/* Unrecognised name: try to interpret as a tag number */
680
-		tmp = tag_name;
618
+		tmp = setting_name;
681 619
 		while ( 1 ) {
682
-			*tag = ( ( *tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
620
+			setting->tag = ( ( setting->tag << 8 ) |
621
+					 strtoul ( tmp, &tmp, 0 ) );
683 622
 			if ( *tmp == 0 )
684 623
 				break;
685 624
 			if ( *tmp != '.' ) {
686
-				DBG ( "Invalid tag number \"%s\" in \"%s\"\n",
687
-				      tag_name, name );
625
+				DBG ( "Invalid setting \"%s\" in \"%s\"\n",
626
+				      setting_name, name );
688 627
 				return -ENOENT;
689 628
 			}
690 629
 			tmp++;
@@ -693,8 +632,8 @@ static int parse_setting_name ( const char *name, struct settings **settings,
693 632
 
694 633
 	/* Identify setting type, if specified */
695 634
 	if ( type_name ) {
696
-		*type = find_setting_type ( type_name );
697
-		if ( *type == NULL ) {
635
+		setting->type = find_setting_type ( type_name );
636
+		if ( setting->type == NULL ) {
698 637
 			DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
699 638
 			      type_name, name );
700 639
 			return -ENOTSUP;
@@ -711,16 +650,14 @@ static int parse_setting_name ( const char *name, struct settings **settings,
711 650
  * @v value		Formatted setting data, or NULL
712 651
  * @ret rc		Return status code
713 652
  */
714
-int store_named_setting ( const char *name, const char *value ) {
653
+int storef_named_setting ( const char *name, const char *value ) {
715 654
 	struct settings *settings;
716
-	unsigned int tag;
717
-	struct setting_type *type;
655
+	struct setting setting;
718 656
 	int rc;
719 657
 
720
-	if ( ( rc = parse_setting_name ( name, &settings, &tag,
721
-					 &type ) ) != 0 )
658
+	if ( ( rc = parse_setting_name ( name, &settings, &setting ) ) != 0 )
722 659
 		return rc;
723
-	return store_typed_setting ( settings, tag, type, value );
660
+	return storef_setting ( settings, &setting, value );
724 661
 }
725 662
 
726 663
 /**
@@ -731,16 +668,14 @@ int store_named_setting ( const char *name, const char *value ) {
731 668
  * @v len		Length of buffer
732 669
  * @ret len		Length of formatted value, or negative error
733 670
  */
734
-int fetch_named_setting ( const char *name, char *buf, size_t len ) {
671
+int fetchf_named_setting ( const char *name, char *buf, size_t len ) {
735 672
 	struct settings *settings;
736
-	unsigned int tag;
737
-	struct setting_type *type;
673
+	struct setting setting;
738 674
 	int rc;
739 675
 
740
-	if ( ( rc = parse_setting_name ( name, &settings, &tag,
741
-					 &type ) ) != 0 )
676
+	if ( ( rc = parse_setting_name ( name, &settings, &setting ) ) != 0 )
742 677
 		return rc;
743
-	return fetch_typed_setting ( settings, tag, type, buf, len );
678
+	return fetchf_setting ( settings, &setting, buf, len );
744 679
 }
745 680
 
746 681
 /******************************************************************************
@@ -754,27 +689,27 @@ int fetch_named_setting ( const char *name, char *buf, size_t len ) {
754 689
  * Parse and store value of string setting
755 690
  *
756 691
  * @v settings		Settings block
757
- * @v tag		Setting tag number
692
+ * @v setting		Setting to store
758 693
  * @v value		Formatted setting data
759 694
  * @ret rc		Return status code
760 695
  */
761
-static int storef_string ( struct settings *settings, unsigned int tag,
696
+static int storef_string ( struct settings *settings, struct setting *setting,
762 697
 			   const char *value ) {
763
-	return store_setting ( settings, tag, value, strlen ( value ) );
698
+	return store_setting ( settings, setting, value, strlen ( value ) );
764 699
 }
765 700
 
766 701
 /**
767 702
  * Fetch and format value of string setting
768 703
  *
769 704
  * @v settings		Settings block, or NULL to search all blocks
770
- * @v tag		Setting tag number
705
+ * @v setting		Setting to fetch
771 706
  * @v buf		Buffer to contain formatted value
772 707
  * @v len		Length of buffer
773 708
  * @ret len		Length of formatted value, or negative error
774 709
  */
775
-static int fetchf_string ( struct settings *settings, unsigned int tag,
710
+static int fetchf_string ( struct settings *settings, struct setting *setting,
776 711
 			   char *buf, size_t len ) {
777
-	return fetch_string_setting ( settings, tag, buf, len );
712
+	return fetch_string_setting ( settings, setting, buf, len );
778 713
 }
779 714
 
780 715
 /** A string setting type */
@@ -788,34 +723,34 @@ struct setting_type setting_type_string __setting_type = {
788 723
  * Parse and store value of IPv4 address setting
789 724
  *
790 725
  * @v settings		Settings block
791
- * @v tag		Setting tag number
726
+ * @v setting		Setting to store
792 727
  * @v value		Formatted setting data
793 728
  * @ret rc		Return status code
794 729
  */
795
-static int storef_ipv4 ( struct settings *settings, unsigned int tag,
730
+static int storef_ipv4 ( struct settings *settings, struct setting *setting,
796 731
 			 const char *value ) {
797 732
 	struct in_addr ipv4;
798 733
 
799 734
 	if ( inet_aton ( value, &ipv4 ) == 0 )
800 735
 		return -EINVAL;
801
-	return store_setting ( settings, tag, &ipv4, sizeof ( ipv4 ) );
736
+	return store_setting ( settings, setting, &ipv4, sizeof ( ipv4 ) );
802 737
 }
803 738
 
804 739
 /**
805 740
  * Fetch and format value of IPv4 address setting
806 741
  *
807 742
  * @v settings		Settings block, or NULL to search all blocks
808
- * @v tag		Setting tag number
743
+ * @v setting		Setting to fetch
809 744
  * @v buf		Buffer to contain formatted value
810 745
  * @v len		Length of buffer
811 746
  * @ret len		Length of formatted value, or negative error
812 747
  */
813
-static int fetchf_ipv4 ( struct settings *settings, unsigned int tag,
748
+static int fetchf_ipv4 ( struct settings *settings, struct setting *setting,
814 749
 			 char *buf, size_t len ) {
815 750
 	struct in_addr ipv4;
816 751
 	int rc;
817 752
 
818
-	if ( ( rc = fetch_ipv4_setting ( settings, tag, &ipv4 ) ) < 0 )
753
+	if ( ( rc = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0 )
819 754
 		return rc;
820 755
 	return snprintf ( buf, len, inet_ntoa ( ipv4 ) );
821 756
 }
@@ -831,12 +766,12 @@ struct setting_type setting_type_ipv4 __setting_type = {
831 766
  * Parse and store value of integer setting
832 767
  *
833 768
  * @v settings		Settings block
834
- * @v tag		Setting tag number
769
+ * @v setting		Setting to store
835 770
  * @v value		Formatted setting data
836 771
  * @v size		Integer size, in bytes
837 772
  * @ret rc		Return status code
838 773
  */
839
-static int storef_int ( struct settings *settings, unsigned int tag,
774
+static int storef_int ( struct settings *settings, struct setting *setting,
840 775
 			const char *value, unsigned int size ) {
841 776
 	union {
842 777
 		uint32_t num;
@@ -847,7 +782,7 @@ static int storef_int ( struct settings *settings, unsigned int tag,
847 782
 	u.num = htonl ( strtoul ( value, &endp, 0 ) );
848 783
 	if ( *endp )
849 784
 		return -EINVAL;
850
-	return store_setting ( settings, tag, 
785
+	return store_setting ( settings, setting, 
851 786
 			       &u.bytes[ sizeof ( u ) - size ], size );
852 787
 }
853 788
 
@@ -855,59 +790,59 @@ static int storef_int ( struct settings *settings, unsigned int tag,
855 790
  * Parse and store value of 8-bit integer setting
856 791
  *
857 792
  * @v settings		Settings block
858
- * @v tag		Setting tag number
793
+ * @v setting		Setting to store
859 794
  * @v value		Formatted setting data
860 795
  * @v size		Integer size, in bytes
861 796
  * @ret rc		Return status code
862 797
  */
863
-static int storef_int8 ( struct settings *settings, unsigned int tag,
798
+static int storef_int8 ( struct settings *settings, struct setting *setting,
864 799
 			 const char *value ) {
865
-	return storef_int ( settings, tag, value, 1 );
800
+	return storef_int ( settings, setting, value, 1 );
866 801
 }
867 802
 
868 803
 /**
869 804
  * Parse and store value of 16-bit integer setting
870 805
  *
871 806
  * @v settings		Settings block
872
- * @v tag		Setting tag number
807
+ * @v setting		Setting to store
873 808
  * @v value		Formatted setting data
874 809
  * @v size		Integer size, in bytes
875 810
  * @ret rc		Return status code
876 811
  */
877
-static int storef_int16 ( struct settings *settings, unsigned int tag,
812
+static int storef_int16 ( struct settings *settings, struct setting *setting,
878 813
 			  const char *value ) {
879
-	return storef_int ( settings, tag, value, 2 );
814
+	return storef_int ( settings, setting, value, 2 );
880 815
 }
881 816
 
882 817
 /**
883 818
  * Parse and store value of 32-bit integer setting
884 819
  *
885 820
  * @v settings		Settings block
886
- * @v tag		Setting tag number
821
+ * @v setting		Setting to store
887 822
  * @v value		Formatted setting data
888 823
  * @v size		Integer size, in bytes
889 824
  * @ret rc		Return status code
890 825
  */
891
-static int storef_int32 ( struct settings *settings, unsigned int tag,
826
+static int storef_int32 ( struct settings *settings, struct setting *setting,
892 827
 			  const char *value ) {
893
-	return storef_int ( settings, tag, value, 4 );
828
+	return storef_int ( settings, setting, value, 4 );
894 829
 }
895 830
 
896 831
 /**
897 832
  * Fetch and format value of signed integer setting
898 833
  *
899 834
  * @v settings		Settings block, or NULL to search all blocks
900
- * @v tag		Setting tag number
835
+ * @v setting		Setting to fetch
901 836
  * @v buf		Buffer to contain formatted value
902 837
  * @v len		Length of buffer
903 838
  * @ret len		Length of formatted value, or negative error
904 839
  */
905
-static int fetchf_int ( struct settings *settings, unsigned int tag,
840
+static int fetchf_int ( struct settings *settings, struct setting *setting,
906 841
 			char *buf, size_t len ) {
907 842
 	long value;
908 843
 	int rc;
909 844
 
910
-	if ( ( rc = fetch_int_setting ( settings, tag, &value ) ) < 0 )
845
+	if ( ( rc = fetch_int_setting ( settings, setting, &value ) ) < 0 )
911 846
 		return rc;
912 847
 	return snprintf ( buf, len, "%ld", value );
913 848
 }
@@ -916,17 +851,17 @@ static int fetchf_int ( struct settings *settings, unsigned int tag,
916 851
  * Fetch and format value of unsigned integer setting
917 852
  *
918 853
  * @v settings		Settings block, or NULL to search all blocks
919
- * @v tag		Setting tag number
854
+ * @v setting		Setting to fetch
920 855
  * @v buf		Buffer to contain formatted value
921 856
  * @v len		Length of buffer
922 857
  * @ret len		Length of formatted value, or negative error
923 858
  */
924
-static int fetchf_uint ( struct settings *settings, unsigned int tag,
859
+static int fetchf_uint ( struct settings *settings, struct setting *setting,
925 860
 			 char *buf, size_t len ) {
926 861
 	unsigned long value;
927 862
 	int rc;
928 863
 
929
-	if ( ( rc = fetch_uint_setting ( settings, tag, &value ) ) < 0 )
864
+	if ( ( rc = fetch_uint_setting ( settings, setting, &value ) ) < 0 )
930 865
 		return rc;
931 866
 	return snprintf ( buf, len, "%#lx", value );
932 867
 }
@@ -977,11 +912,11 @@ struct setting_type setting_type_uint32 __setting_type = {
977 912
  * Parse and store value of hex string setting
978 913
  *
979 914
  * @v settings		Settings block
980
- * @v tag		Setting tag number
915
+ * @v setting		Setting to store
981 916
  * @v value		Formatted setting data
982 917
  * @ret rc		Return status code
983 918
  */
984
-static int storef_hex ( struct settings *settings, unsigned int tag,
919
+static int storef_hex ( struct settings *settings, struct setting *setting,
985 920
 			const char *value ) {
986 921
 	char *ptr = ( char * ) value;
987 922
 	uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
@@ -991,7 +926,7 @@ static int storef_hex ( struct settings *settings, unsigned int tag,
991 926
 		bytes[len++] = strtoul ( ptr, &ptr, 16 );
992 927
 		switch ( *ptr ) {
993 928
 		case '\0' :
994
-			return store_setting ( settings, tag, bytes, len );
929
+			return store_setting ( settings, setting, bytes, len );
995 930
 		case ':' :
996 931
 			ptr++;
997 932
 			break;
@@ -1005,26 +940,27 @@ static int storef_hex ( struct settings *settings, unsigned int tag,
1005 940
  * Fetch and format value of hex string setting
1006 941
  *
1007 942
  * @v settings		Settings block, or NULL to search all blocks
1008
- * @v tag		Setting tag number
943
+ * @v setting		Setting to fetch
1009 944
  * @v buf		Buffer to contain formatted value
1010 945
  * @v len		Length of buffer
1011 946
  * @ret len		Length of formatted value, or negative error
1012 947
  */
1013
-static int fetchf_hex ( struct settings *settings, unsigned int tag,
948
+static int fetchf_hex ( struct settings *settings, struct setting *setting,
1014 949
 			char *buf, size_t len ) {
1015 950
 	int raw_len;
1016 951
 	int check_len;
1017 952
 	int used = 0;
1018 953
 	int i;
1019 954
 
1020
-	raw_len = fetch_setting_len ( settings, tag );
955
+	raw_len = fetch_setting_len ( settings, setting );
1021 956
 	if ( raw_len < 0 )
1022 957
 		return raw_len;
1023 958
 
1024 959
 	{
1025 960
 		uint8_t raw[raw_len];
1026 961
 
1027
-		check_len = fetch_setting ( settings, tag, raw, sizeof (raw) );
962
+		check_len = fetch_setting ( settings, setting, raw,
963
+					    sizeof ( raw ) );
1028 964
 		assert ( check_len == raw_len );
1029 965
 		
1030 966
 		if ( len )
@@ -1047,83 +983,55 @@ struct setting_type setting_type_hex __setting_type = {
1047 983
 
1048 984
 /******************************************************************************
1049 985
  *
1050
- * Named settings
986
+ * Settings
1051 987
  *
1052 988
  ******************************************************************************
1053 989
  */
1054 990
 
1055
-/** Some basic setting definitions */
1056
-struct named_setting basic_named_settings[] __named_setting = {
1057
-	{
1058
-		.name = "ip",
1059
-		.description = "IPv4 address",
1060
-		.tag = DHCP_EB_YIADDR,
1061
-		.type = &setting_type_ipv4,
1062
-	},
1063
-	{
1064
-		.name = "netmask",
1065
-		.description = "IPv4 subnet mask",
1066
-		.tag = DHCP_SUBNET_MASK,
1067
-		.type = &setting_type_ipv4,
1068
-	},
1069
-	{
1070
-		.name = "gateway",
1071
-		.description = "Default gateway",
1072
-		.tag = DHCP_ROUTERS,
1073
-		.type = &setting_type_ipv4,
1074
-	},
1075
-	{
1076
-		.name = "dns",
1077
-		.description = "DNS server",
1078
-		.tag = DHCP_DNS_SERVERS,
1079
-		.type = &setting_type_ipv4,
1080
-	},
1081
-	{
1082
-		.name = "hostname",
1083
-		.description = "Host name",
1084
-		.tag = DHCP_HOST_NAME,
1085
-		.type = &setting_type_string,
1086
-	},
1087
-	{
1088
-		.name = "next-server",
1089
-		.description = "TFTP server",
1090
-		.tag = DHCP_EB_SIADDR,
1091
-		.type = &setting_type_ipv4,
1092
-	},
1093
-	{
1094
-		.name = "filename",
1095
-		.description = "Boot filename",
1096
-		.tag = DHCP_BOOTFILE_NAME,
1097
-		.type = &setting_type_string,
1098
-	},
1099
-	{
1100
-		.name = "root-path",
1101
-		.description = "NFS/iSCSI root path",
1102
-		.tag = DHCP_ROOT_PATH,
1103
-		.type = &setting_type_string,
1104
-	},
1105
-	{
1106
-		.name = "username",
1107
-		.description = "User name",
1108
-		.tag = DHCP_EB_USERNAME,
1109
-		.type = &setting_type_string,
1110
-	},
1111
-	{
1112
-		.name = "password",
1113
-		.description = "Password",
1114
-		.tag = DHCP_EB_PASSWORD,
1115
-		.type = &setting_type_string,
1116
-	},
1117
-	{
1118
-		.name = "initiator-iqn",
1119
-		.description = "iSCSI initiator name",
1120
-		.tag = DHCP_ISCSI_INITIATOR_IQN,
1121
-		.type = &setting_type_string,
1122
-	},
1123
-	{
1124
-		.name = "priority",
1125
-		.description = "Priority of these settings",
1126
-		.tag = DHCP_EB_PRIORITY,
1127
-		.type = &setting_type_int8,
1128
-	},
991
+/** Hostname setting */
992
+struct setting hostname_setting __setting = {
993
+	.name = "hostname",
994
+	.description = "Host name",
995
+	.tag = DHCP_HOST_NAME,
996
+	.type = &setting_type_string,
997
+};
998
+
999
+/** Filename setting */
1000
+struct setting filename_setting __setting = {
1001
+	.name = "filename",
1002
+	.description = "Boot filename",
1003
+	.tag = DHCP_BOOTFILE_NAME,
1004
+	.type = &setting_type_string,
1005
+};
1006
+
1007
+/** Root path setting */
1008
+struct setting root_path_setting __setting = {
1009
+	.name = "root-path",
1010
+	.description = "NFS/iSCSI root path",
1011
+	.tag = DHCP_ROOT_PATH,
1012
+	.type = &setting_type_string,
1013
+};
1014
+
1015
+/** Username setting */
1016
+struct setting username_setting __setting = {
1017
+	.name = "username",
1018
+	.description = "User name",
1019
+	.tag = DHCP_EB_USERNAME,
1020
+	.type = &setting_type_string,
1021
+};
1022
+
1023
+/** Password setting */
1024
+struct setting password_setting __setting = {
1025
+	.name = "password",
1026
+	.description = "Password",
1027
+	.tag = DHCP_EB_PASSWORD,
1028
+	.type = &setting_type_string,
1029
+};
1030
+
1031
+/** Priority setting */
1032
+struct setting priority_setting __setting = {
1033
+	.name = "priority",
1034
+	.description = "Priority of these settings",
1035
+	.tag = DHCP_EB_PRIORITY,
1036
+	.type = &setting_type_int8,
1129 1037
 };

+ 3
- 3
src/hci/commands/nvo_cmd.c Просмотреть файл

@@ -16,8 +16,8 @@ static int show_exec ( int argc, char **argv ) {
16 16
 		return 1;
17 17
 	}
18 18
 
19
-	if ( ( rc = fetch_named_setting ( argv[1], buf,
20
-					  sizeof ( buf ) ) ) < 0 ){
19
+	if ( ( rc = fetchf_named_setting ( argv[1], buf,
20
+					   sizeof ( buf ) ) ) < 0 ){
21 21
 		printf ( "Could not find \"%s\": %s\n",
22 22
 			 argv[1], strerror ( rc ) );
23 23
 		return 1;
@@ -35,7 +35,7 @@ static int set_exec ( int argc, char **argv ) {
35 35
 		return 1;
36 36
 	}
37 37
 
38
-	if ( ( rc = store_named_setting ( argv[1], argv[2] ) ) != 0 ) {
38
+	if ( ( rc = storef_named_setting ( argv[1], argv[2] ) ) != 0 ) {
39 39
 		printf ( "Could not set \"%s\"=\"%s\": %s\n",
40 40
 			 argv[1], argv[2], strerror ( rc ) );
41 41
 		return 1;

+ 15
- 16
src/hci/tui/settings_ui.c Просмотреть файл

@@ -64,7 +64,7 @@ struct setting_widget {
64 64
 	/** Settings block */
65 65
 	struct settings *settings;
66 66
 	/** Configuration setting */
67
-	struct named_setting *setting;
67
+	struct setting *setting;
68 68
 	/** Screen row */
69 69
 	unsigned int row;
70 70
 	/** Screen column */
@@ -78,17 +78,17 @@ struct setting_widget {
78 78
 };
79 79
 
80 80
 /** Registered configuration settings */
81
-static struct named_setting named_settings[0]
82
-	__table_start ( struct named_setting, named_settings );
83
-static struct named_setting named_settings_end[0]
84
-	__table_end ( struct named_setting, named_settings );
85
-#define NUM_SETTINGS ( ( unsigned ) ( named_settings_end - named_settings ) )
81
+static struct setting all_settings[0]
82
+	__table_start ( struct setting, settings );
83
+static struct setting all_settings_end[0]
84
+	__table_end ( struct setting, settings );
85
+#define NUM_SETTINGS ( ( unsigned ) ( all_settings_end - all_settings ) )
86 86
 
87 87
 static void load_setting ( struct setting_widget *widget ) __nonnull;
88 88
 static int save_setting ( struct setting_widget *widget ) __nonnull;
89 89
 static void init_setting ( struct setting_widget *widget,
90 90
                            struct settings *settings,
91
-                           struct named_setting *setting,
91
+                           struct setting *setting,
92 92
                            unsigned int row, unsigned int col ) __nonnull;
93 93
 static void draw_setting ( struct setting_widget *widget ) __nonnull;
94 94
 static int edit_setting ( struct setting_widget *widget, int key ) __nonnull;
@@ -99,7 +99,7 @@ static void vmsg ( unsigned int row, const char *fmt, va_list args ) __nonnull;
99 99
 static void msg ( unsigned int row, const char *fmt, ... ) __nonnull;
100 100
 static void valert ( const char *fmt, va_list args ) __nonnull;
101 101
 static void alert ( const char *fmt, ... ) __nonnull;
102
-static void draw_info_row ( struct named_setting *setting ) __nonnull;
102
+static void draw_info_row ( struct setting *setting ) __nonnull;
103 103
 static int main_loop ( struct settings *settings ) __nonnull;
104 104
 
105 105
 /**
@@ -114,9 +114,8 @@ static void load_setting ( struct setting_widget *widget ) {
114 114
 	widget->editing = 0;
115 115
 
116 116
 	/* Read current setting value */
117
-	if ( fetch_typed_setting ( widget->settings, widget->setting->tag,
118
-				   widget->setting->type, widget->value,
119
-				   sizeof ( widget->value ) ) < 0 ) {
117
+	if ( fetchf_setting ( widget->settings, widget->setting,
118
+			      widget->value, sizeof ( widget->value ) ) < 0 ) {
120 119
 		widget->value[0] = '\0';
121 120
 	}	
122 121
 
@@ -133,8 +132,8 @@ static void load_setting ( struct setting_widget *widget ) {
133 132
  * @v widget		Setting widget
134 133
  */
135 134
 static int save_setting ( struct setting_widget *widget ) {
136
-	return store_typed_setting ( widget->settings, widget->setting->tag,
137
-				     widget->setting->type, widget->value );
135
+	return storef_setting ( widget->settings, widget->setting,
136
+				widget->value );
138 137
 }
139 138
 
140 139
 /**
@@ -148,7 +147,7 @@ static int save_setting ( struct setting_widget *widget ) {
148 147
  */
149 148
 static void init_setting ( struct setting_widget *widget,
150 149
 			   struct settings *settings,
151
-			   struct named_setting *setting,
150
+			   struct setting *setting,
152 151
 			   unsigned int row, unsigned int col ) {
153 152
 
154 153
 	/* Initialise widget structure */
@@ -224,7 +223,7 @@ static int edit_setting ( struct setting_widget *widget, int key ) {
224 223
 static void init_setting_index ( struct setting_widget *widget,
225 224
 				 struct settings *settings,
226 225
 				 unsigned int index ) {
227
-	init_setting ( widget, settings, &named_settings[index],
226
+	init_setting ( widget, settings, &all_settings[index],
228 227
 		       ( SETTINGS_LIST_ROW + index ), SETTINGS_LIST_COL );
229 228
 }
230 229
 
@@ -311,7 +310,7 @@ static void draw_title_row ( void ) {
311 310
  *
312 311
  * @v setting		Current configuration setting
313 312
  */
314
-static void draw_info_row ( struct named_setting *setting ) {
313
+static void draw_info_row ( struct setting *setting ) {
315 314
 	clearmsg ( INFO_ROW );
316 315
 	attron ( A_BOLD );
317 316
 	msg ( INFO_ROW, "%s - %s", setting->name, setting->description );

+ 14
- 15
src/include/gpxe/dhcp.h Просмотреть файл

@@ -15,8 +15,8 @@
15 15
 
16 16
 struct net_device;
17 17
 struct job_interface;
18
+struct dhcp_options;
18 19
 struct dhcp_packet;
19
-struct settings;
20 20
 
21 21
 /** BOOTP/DHCP server port */
22 22
 #define BOOTPS_PORT 67
@@ -179,15 +179,6 @@ struct settings;
179 179
  */
180 180
 #define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 3 )
181 181
 
182
-/** MAC address
183
- *
184
- * This option is used internally to contain the network device
185
- * hardware address, in order to provide a consistent approach to
186
- * storing and processing options.  It should never be present in a
187
- * DHCP packet.
188
- */
189
-#define DHCP_EB_MAC DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 4 )
190
-
191 182
 /*
192 183
  * Tags in the range 0x10-0x7f are reserved for feature markers
193 184
  *
@@ -445,11 +436,19 @@ struct dhcphdr {
445 436
 /** Maximum time that we will wait for ProxyDHCP offers */
446 437
 #define PROXYDHCP_WAIT_TIME ( TICKS_PER_SEC * 1 )
447 438
 
448
-extern int create_dhcpdiscover ( struct net_device *netdev,
449
-				 void *data, size_t max_len );
450
-extern int create_dhcpack ( struct net_device *netdev,
451
-			    void *data, size_t max_len );
452
-extern int create_proxydhcpack ( struct net_device *netdev,
439
+/** Settings block name used for DHCP responses */
440
+#define DHCP_SETTINGS_NAME "dhcp"
441
+
442
+/** Settings block name used for ProxyDHCP responses */
443
+#define PROXYDHCP_SETTINGS_NAME "proxydhcp"
444
+
445
+extern int create_dhcp_packet ( struct dhcp_packet *dhcppkt,
446
+				struct net_device *netdev, uint8_t msgtype,
447
+				struct dhcp_options *options, 
448
+				void *data, size_t max_len );
449
+extern int create_dhcp_request ( struct dhcp_packet *dhcppkt,
450
+				 struct net_device *netdev,
451
+				 struct dhcp_packet *dhcpoffer,
453 452
 				 void *data, size_t max_len );
454 453
 extern int start_dhcp ( struct job_interface *job, struct net_device *netdev );
455 454
 

+ 1
- 1
src/include/gpxe/dhcpopts.h Просмотреть файл

@@ -7,7 +7,7 @@
7 7
  *
8 8
  */
9 9
 
10
-#include <gpxe/dhcp.h>
10
+#include <stdint.h>
11 11
 
12 12
 /** A DHCP options block */
13 13
 struct dhcp_options {

+ 5
- 4
src/include/gpxe/dhcppkt.h Просмотреть файл

@@ -9,15 +9,12 @@
9 9
 
10 10
 #include <gpxe/dhcp.h>
11 11
 #include <gpxe/dhcpopts.h>
12
-#include <gpxe/settings.h>
13 12
 
14 13
 /**
15 14
  * A DHCP packet
16 15
  *
17 16
  */
18 17
 struct dhcp_packet {
19
-	/** Settings block */
20
-	struct settings settings;
21 18
 	/** The DHCP packet contents */
22 19
 	struct dhcphdr *dhcphdr;
23 20
 	/** Maximum length of the DHCP packet buffer */
@@ -28,7 +25,11 @@ struct dhcp_packet {
28 25
 	struct dhcp_options options;
29 26
 };
30 27
 
31
-extern void dhcppkt_init ( struct dhcp_packet *dhcppkt, struct refcnt *refcnt,
28
+extern int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag,
29
+			   const void *data, size_t len );
30
+extern int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag,
31
+			   void *data, size_t len );
32
+extern void dhcppkt_init ( struct dhcp_packet *dhcppkt, 
32 33
 			   void *data, size_t len );
33 34
 
34 35
 #endif /* _GPXE_DHCPPKT_H */

+ 21
- 0
src/include/gpxe/fakedhcp.h Просмотреть файл

@@ -0,0 +1,21 @@
1
+#ifndef _GPXE_FAKEDHCP_H
2
+#define _GPXE_FAKEDHCP_H
3
+
4
+/** @file
5
+ *
6
+ * Fake DHCP packets
7
+ *
8
+ */
9
+
10
+#include <stdint.h>
11
+
12
+struct net_device;
13
+
14
+extern int create_fakedhcpdiscover ( struct net_device *netdev,
15
+				     void *data, size_t max_len );
16
+extern int create_fakedhcpack ( struct net_device *netdev,
17
+				void *data, size_t max_len );
18
+extern int create_fakeproxydhcpack ( struct net_device *netdev,
19
+				     void *data, size_t max_len );
20
+
21
+#endif /* _GPXE_FAKEDHCP_H */

+ 81
- 67
src/include/gpxe/settings.h Просмотреть файл

@@ -16,22 +16,44 @@
16 16
 struct settings;
17 17
 struct in_addr;
18 18
 
19
+/** A setting */
20
+struct setting {
21
+	/** Name
22
+	 *
23
+	 * This is the human-readable name for the setting.
24
+	 */
25
+	const char *name;
26
+	/** Description */
27
+	const char *description;
28
+	/** Setting type
29
+	 *
30
+	 * This identifies the type of setting (e.g. string, IPv4
31
+	 * address, etc.).
32
+	 */
33
+	struct setting_type *type;
34
+	/** DHCP option number, if applicable */
35
+	unsigned int tag;
36
+};
37
+
38
+/** Declare a configuration setting */
39
+#define	__setting __table ( struct setting, settings, 01 )
40
+
19 41
 /** Settings block operations */
20 42
 struct settings_operations {
21 43
 	/** Store value of setting
22 44
 	 *
23 45
 	 * @v settings		Settings block
24
-	 * @v tag		Setting tag number
46
+	 * @v setting		Setting to store
25 47
 	 * @v data		Setting data, or NULL to clear setting
26 48
 	 * @v len		Length of setting data
27 49
 	 * @ret rc		Return status code
28 50
 	 */
29
-	int ( * store ) ( struct settings *settings, unsigned int tag,
51
+	int ( * store ) ( struct settings *settings, struct setting *setting,
30 52
 			  const void *data, size_t len );
31 53
 	/** Fetch value of setting
32 54
 	 *
33 55
 	 * @v settings		Settings block
34
-	 * @v tag		Setting tag number
56
+	 * @v setting		Setting to fetch
35 57
 	 * @v data		Buffer to fill with setting data
36 58
 	 * @v len		Length of buffer
37 59
 	 * @ret len		Length of setting data, or negative error
@@ -39,7 +61,7 @@ struct settings_operations {
39 61
 	 * The actual length of the setting will be returned even if
40 62
 	 * the buffer was too small.
41 63
 	 */
42
-	int ( * fetch ) ( struct settings *settings, unsigned int tag,
64
+	int ( * fetch ) ( struct settings *settings, struct setting *setting,
43 65
 			  void *data, size_t len );
44 66
 };
45 67
 
@@ -74,21 +96,21 @@ struct setting_type {
74 96
 	/** Parse and set value of setting
75 97
 	 *
76 98
 	 * @v settings		Settings block
77
-	 * @v tag		Setting tag number
99
+	 * @v setting		Setting to store
78 100
 	 * @v value		Formatted setting data
79 101
 	 * @ret rc		Return status code
80 102
 	 */
81
-	int ( * storef ) ( struct settings *settings, unsigned int tag,
103
+	int ( * storef ) ( struct settings *settings, struct setting *setting,
82 104
 			   const char *value );
83 105
 	/** Fetch and format value of setting
84 106
 	 *
85
-	 * @v settings		Settings block, or NULL to search all blocks
86
-	 * @v tag		Setting tag number
107
+	 * @v settings		Settings block
108
+	 * @v setting		Setting to fetch
87 109
 	 * @v buf		Buffer to contain formatted value
88 110
 	 * @v len		Length of buffer
89 111
 	 * @ret len		Length of formatted value, or negative error
90 112
 	 */
91
-	int ( * fetchf ) ( struct settings *settings, unsigned int tag,
113
+	int ( * fetchf ) ( struct settings *settings, struct setting *setting,
92 114
 			   char *buf, size_t len );
93 115
 };
94 116
 
@@ -96,33 +118,6 @@ struct setting_type {
96 118
 #define	__setting_type \
97 119
 	__table ( struct setting_type, setting_types, 01 )
98 120
 
99
-/**
100
- * A named setting
101
- *
102
- * This represents a single setting (e.g. "hostname"), encapsulating
103
- * the information about the setting's tag number and type.
104
- */
105
-struct named_setting {
106
-	/** Name
107
-	 *
108
-	 * This is the human-readable name for the setting.
109
-	 */
110
-	const char *name;
111
-	/** Description */
112
-	const char *description;
113
-	/** Setting tag number */
114
-	unsigned int tag;
115
-	/** Setting type
116
-	 *
117
-	 * This identifies the type of setting (e.g. string, IPv4
118
-	 * address, etc.).
119
-	 */
120
-	struct setting_type *type;
121
-};
122
-
123
-/** Declare a configuration setting */
124
-#define	__named_setting __table ( struct named_setting, named_settings, 01 )
125
-
126 121
 /**
127 122
  * A settings applicator
128 123
  *
@@ -151,41 +146,49 @@ struct simple_settings {
151 146
 };
152 147
 
153 148
 extern struct settings_operations simple_settings_operations;
154
-
155
-extern int simple_settings_store ( struct settings *settings, unsigned int tag,
149
+extern int simple_settings_store ( struct settings *settings,
150
+				   struct setting *setting,
156 151
 				   const void *data, size_t len );
157
-extern int simple_settings_fetch ( struct settings *settings, unsigned int tag,
152
+extern int simple_settings_fetch ( struct settings *settings,
153
+				   struct setting *setting,
158 154
 				   void *data, size_t len );
155
+
159 156
 extern int register_settings ( struct settings *settings,
160 157
 			       struct settings *parent );
161 158
 extern void unregister_settings ( struct settings *settings );
162
-extern int store_setting ( struct settings *settings, unsigned int tag,
159
+
160
+extern int store_setting ( struct settings *settings, struct setting *setting,
163 161
 			   const void *data, size_t len );
164
-extern int fetch_setting ( struct settings *settings, unsigned int tag,
162
+extern int fetch_setting ( struct settings *settings, struct setting *setting,
165 163
 			   void *data, size_t len );
166
-extern int copy_settings ( struct settings *dest, struct settings *source );
167
-extern int fetch_setting_len ( struct settings *settings, unsigned int tag );
168
-extern int fetch_string_setting ( struct settings *settings, unsigned int tag,
164
+extern int fetch_setting_len ( struct settings *settings,
165
+			       struct setting *setting );
166
+extern int fetch_string_setting ( struct settings *settings,
167
+				  struct setting *setting,
169 168
 				  char *data, size_t len );
170
-extern int fetch_ipv4_setting ( struct settings *settings, unsigned int tag,
171
-				struct in_addr *inp );
172
-extern int fetch_int_setting ( struct settings *settings, unsigned int tag,
173
-			       long *value );
174
-extern int fetch_uint_setting ( struct settings *settings, unsigned int tag,
169
+extern int fetch_ipv4_setting ( struct settings *settings,
170
+				struct setting *setting, struct in_addr *inp );
171
+extern int fetch_int_setting ( struct settings *settings,
172
+			       struct setting *setting, long *value );
173
+extern int fetch_uint_setting ( struct settings *settings,
174
+				struct setting *setting,
175 175
 				unsigned long *value );
176
-extern long fetch_intz_setting ( struct settings *settings, unsigned int tag );
176
+extern long fetch_intz_setting ( struct settings *settings,
177
+				 struct setting *setting );
177 178
 extern unsigned long fetch_uintz_setting ( struct settings *settings,
178
-					   unsigned int tag );
179
+					   struct setting *setting );
180
+extern int setting_cmp ( struct setting *a, struct setting *b );
181
+
179 182
 extern struct settings * find_child_settings ( struct settings *parent,
180 183
 					       const char *name );
181 184
 extern struct settings * find_settings ( const char *name );
182
-extern int store_typed_setting ( struct settings *settings,
183
-				 unsigned int tag, struct setting_type *type,
184
-				 const char *value );
185
-extern int store_named_setting ( const char *name, const char *value );
186
-extern int fetch_named_setting ( const char *name, char *buf, size_t len );
187 185
 
188
-extern struct setting_type setting_type_ __setting_type;
186
+extern int storef_setting ( struct settings *settings,
187
+			    struct setting *setting,
188
+			    const char *value );
189
+extern int storef_named_setting ( const char *name, const char *value );
190
+extern int fetchf_named_setting ( const char *name, char *buf, size_t len );
191
+
189 192
 extern struct setting_type setting_type_string __setting_type;
190 193
 extern struct setting_type setting_type_ipv4 __setting_type;
191 194
 extern struct setting_type setting_type_int8 __setting_type;
@@ -196,6 +199,18 @@ extern struct setting_type setting_type_uint16 __setting_type;
196 199
 extern struct setting_type setting_type_uint32 __setting_type;
197 200
 extern struct setting_type setting_type_hex __setting_type;
198 201
 
202
+extern struct setting ip_setting __setting;
203
+extern struct setting netmask_setting __setting;
204
+extern struct setting gateway_setting __setting;
205
+extern struct setting dns_setting __setting;
206
+extern struct setting hostname_setting __setting;
207
+extern struct setting filename_setting __setting;
208
+extern struct setting root_path_setting __setting;
209
+extern struct setting username_setting __setting;
210
+extern struct setting password_setting __setting;
211
+extern struct setting priority_setting __setting;
212
+extern struct setting bios_drive_setting __setting;
213
+
199 214
 /**
200 215
  * Initialise a settings block
201 216
  *
@@ -233,29 +248,28 @@ static inline void simple_settings_init ( struct simple_settings *simple,
233 248
  * Delete setting
234 249
  *
235 250
  * @v settings		Settings block
236
- * @v tag		Setting tag number
251
+ * @v setting		Setting to delete
237 252
  * @ret rc		Return status code
238 253
  */
239 254
 static inline int delete_setting ( struct settings *settings,
240
-				   unsigned int tag ) {
241
-	return store_setting ( settings, tag, NULL, 0 );
255
+				   struct setting *setting ) {
256
+	return store_setting ( settings, setting, NULL, 0 );
242 257
 }
243 258
 
244 259
 /**
245 260
  * Fetch and format value of setting
246 261
  *
247 262
  * @v settings		Settings block, or NULL to search all blocks
248
- * @v tag		Setting tag number
263
+ * @v setting		Setting to fetch
249 264
  * @v type		Settings type
250 265
  * @v buf		Buffer to contain formatted value
251 266
  * @v len		Length of buffer
252 267
  * @ret len		Length of formatted value, or negative error
253 268
  */
254
-static inline int fetch_typed_setting ( struct settings *settings,
255
-					unsigned int tag,
256
-					struct setting_type *type,
257
-					char *buf, size_t len ) {
258
-	return type->fetchf ( settings, tag, buf, len );
269
+static inline int fetchf_setting ( struct settings *settings,
270
+				   struct setting *setting,
271
+				   char *buf, size_t len ) {
272
+	return setting->type->fetchf ( settings, setting, buf, len );
259 273
 }
260 274
 
261 275
 /**
@@ -265,7 +279,7 @@ static inline int fetch_typed_setting ( struct settings *settings,
265 279
  * @ret rc		Return status code
266 280
  */
267 281
 static inline int delete_named_setting ( const char *name ) {
268
-	return store_named_setting ( name, NULL );
282
+	return storef_named_setting ( name, NULL );
269 283
 }
270 284
 
271 285
 #endif /* _GPXE_SETTINGS_H */

+ 4
- 4
src/interface/pxe/pxe_preboot.c Просмотреть файл

@@ -28,7 +28,7 @@
28 28
 #include <stdlib.h>
29 29
 #include <gpxe/uaccess.h>
30 30
 #include <gpxe/dhcp.h>
31
-#include <gpxe/dhcppkt.h>
31
+#include <gpxe/fakedhcp.h>
32 32
 #include <gpxe/device.h>
33 33
 #include <gpxe/netdevice.h>
34 34
 #include <gpxe/isapnp.h>
@@ -80,9 +80,9 @@ struct pxe_dhcp_packet_creator {
80 80
 
81 81
 /** PXE DHCP packet creators */
82 82
 static struct pxe_dhcp_packet_creator pxe_dhcp_packet_creators[] = {
83
-	[CACHED_INFO_DHCPDISCOVER] = { create_dhcpdiscover },
84
-	[CACHED_INFO_DHCPACK] = { create_dhcpack },
85
-	[CACHED_INFO_BINL] = { create_proxydhcpack },
83
+	[CACHED_INFO_DHCPDISCOVER] = { create_fakedhcpdiscover },
84
+	[CACHED_INFO_DHCPACK] = { create_fakedhcpack },
85
+	[CACHED_INFO_BINL] = { create_fakeproxydhcpack },
86 86
 };
87 87
 
88 88
 /* The case in which the caller doesn't supply a buffer is really

+ 13
- 3
src/net/dhcpopts.c Просмотреть файл

@@ -118,6 +118,11 @@ static int find_dhcp_option_with_encap ( struct dhcp_options *options,
118 118
 	ssize_t remaining = options->len;
119 119
 	unsigned int option_len;
120 120
 
121
+	/* Sanity check */
122
+	if ( tag == DHCP_PAD )
123
+		return -ENOENT;
124
+
125
+	/* Search for option */
121 126
 	while ( remaining ) {
122 127
 		/* Calculate length of this option.  Abort processing
123 128
 		 * if the length is malformed (i.e. takes us beyond
@@ -128,6 +133,9 @@ static int find_dhcp_option_with_encap ( struct dhcp_options *options,
128 133
 		remaining -= option_len;
129 134
 		if ( remaining < 0 )
130 135
 			break;
136
+		/* Check for explicit end marker */
137
+		if ( option->tag == DHCP_END )
138
+			break;
131 139
 		/* Check for matching tag */
132 140
 		if ( option->tag == tag ) {
133 141
 			DBGC ( options, "DHCPOPT %p found %s (length %d)\n",
@@ -135,9 +143,6 @@ static int find_dhcp_option_with_encap ( struct dhcp_options *options,
135 143
 			       option_len );
136 144
 			return offset;
137 145
 		}
138
-		/* Check for explicit end marker */
139
-		if ( option->tag == DHCP_END )
140
-			break;
141 146
 		/* Check for start of matching encapsulation block */
142 147
 		if ( DHCP_IS_ENCAP_OPT ( tag ) &&
143 148
 		     ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) {
@@ -151,6 +156,7 @@ static int find_dhcp_option_with_encap ( struct dhcp_options *options,
151 156
 		}
152 157
 		offset += option_len;
153 158
 	}
159
+
154 160
 	return -ENOENT;
155 161
 }
156 162
 
@@ -255,6 +261,10 @@ static int set_dhcp_option ( struct dhcp_options *options, unsigned int tag,
255 261
 	size_t new_len = ( len ? ( len + DHCP_OPTION_HEADER_LEN ) : 0 );
256 262
 	int rc;
257 263
 
264
+	/* Sanity check */
265
+	if ( tag == DHCP_PAD )
266
+		return -ENOTTY;
267
+
258 268
 	/* Find old instance of this option, if any */
259 269
 	offset = find_dhcp_option_with_encap ( options, tag, &encap_offset );
260 270
 	if ( offset >= 0 ) {

+ 8
- 22
src/net/dhcppkt.c Просмотреть файл

@@ -92,20 +92,18 @@ find_dhcp_packet_field ( unsigned int tag ) {
92 92
 	}
93 93
 	return NULL;
94 94
 }
95
-				    
95
+
96 96
 /**
97 97
  * Store value of DHCP packet setting
98 98
  *
99
- * @v settings		Settings block
99
+ * @v dhcppkt		DHCP packet
100 100
  * @v tag		Setting tag number
101 101
  * @v data		Setting data, or NULL to clear setting
102 102
  * @v len		Length of setting data
103 103
  * @ret rc		Return status code
104 104
  */
105
-static int dhcppkt_store ( struct settings *settings, unsigned int tag,
106
-			   const void *data, size_t len ) {
107
-	struct dhcp_packet *dhcppkt =
108
-		container_of ( settings, struct dhcp_packet, settings );
105
+int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag,
106
+		    const void *data, size_t len ) {
109 107
 	struct dhcp_packet_field *field;
110 108
 	int rc;
111 109
 
@@ -131,16 +129,14 @@ static int dhcppkt_store ( struct settings *settings, unsigned int tag,
131 129
 /**
132 130
  * Fetch value of DHCP packet setting
133 131
  *
134
- * @v settings		Settings block
132
+ * @v dhcppkt		DHCP packet
135 133
  * @v tag		Setting tag number
136 134
  * @v data		Buffer to fill with setting data
137 135
  * @v len		Length of buffer
138 136
  * @ret len		Length of setting data, or negative error
139 137
  */
140
-static int dhcppkt_fetch ( struct settings *settings, unsigned int tag,
141
-			   void *data, size_t len ) {
142
-	struct dhcp_packet *dhcppkt =
143
-		container_of ( settings, struct dhcp_packet, settings );
138
+int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag,
139
+		    void *data, size_t len ) {
144 140
 	struct dhcp_packet_field *field;
145 141
 	
146 142
 	/* If this is a special field, return it */
@@ -156,31 +152,21 @@ static int dhcppkt_fetch ( struct settings *settings, unsigned int tag,
156 152
 	return dhcpopt_fetch ( &dhcppkt->options, tag, data, len );
157 153
 }
158 154
 
159
-/** DHCP settings operations */
160
-static struct settings_operations dhcppkt_settings_operations = {
161
-	.store = dhcppkt_store,
162
-	.fetch = dhcppkt_fetch,
163
-};
164
-
165 155
 /**
166 156
  * Initialise prepopulated DHCP packet
167 157
  *
168 158
  * @v dhcppkt		Uninitialised DHCP packet
169
- * @v refcnt		Reference counter of containing object, or NULL
170 159
  * @v data		Memory for DHCP packet data
171 160
  * @v max_len		Length of memory for DHCP packet data
172 161
  *
173 162
  * The memory content must already be filled with valid DHCP options.
174 163
  * A zeroed block counts as a block of valid DHCP options.
175 164
  */
176
-void dhcppkt_init ( struct dhcp_packet *dhcppkt, struct refcnt *refcnt,
177
-		    void *data, size_t len ) {
165
+void dhcppkt_init ( struct dhcp_packet *dhcppkt, void *data, size_t len ) {
178 166
 	dhcppkt->dhcphdr = data;
179 167
 	dhcppkt->max_len = len;
180 168
 	dhcpopt_init ( &dhcppkt->options, &dhcppkt->dhcphdr->options,
181 169
 		       ( len - offsetof ( struct dhcphdr, options ) ) );
182 170
 	dhcppkt->len = ( offsetof ( struct dhcphdr, options ) +
183 171
 			 dhcppkt->options.len );
184
-	settings_init ( &dhcppkt->settings, &dhcppkt_settings_operations,
185
-			refcnt, "dhcp" );
186 172
 }

+ 205
- 0
src/net/fakedhcp.c Просмотреть файл

@@ -0,0 +1,205 @@
1
+/*
2
+ * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdint.h>
20
+#include <stdlib.h>
21
+#include <stdio.h>
22
+#include <errno.h>
23
+#include <string.h>
24
+#include <gpxe/settings.h>
25
+#include <gpxe/netdevice.h>
26
+#include <gpxe/dhcppkt.h>
27
+#include <gpxe/fakedhcp.h>
28
+
29
+/** @file
30
+ *
31
+ * Fake DHCP packets
32
+ *
33
+ */
34
+
35
+/**
36
+ * Copy settings to DHCP packet
37
+ *
38
+ * @v dest		Destination DHCP packet
39
+ * @v source		Source settings block
40
+ * @v encapsulator	Encapsulating setting tag number, or zero
41
+ * @ret rc		Return status code
42
+ */
43
+static int copy_encap_settings ( struct dhcp_packet *dest,
44
+				 struct settings *source,
45
+				 unsigned int encapsulator ) {
46
+	struct setting setting = { .name = "" };
47
+	unsigned int subtag;
48
+	unsigned int tag;
49
+	int len;
50
+	int check_len;
51
+	int rc;
52
+
53
+	for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
54
+		tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
55
+		switch ( tag ) {
56
+		case DHCP_EB_ENCAP:
57
+		case DHCP_VENDOR_ENCAP:
58
+			/* Process encapsulated settings */
59
+			if ( ( rc = copy_encap_settings ( dest, source,
60
+							  tag ) ) != 0 )
61
+				return rc;
62
+			break;
63
+		default:
64
+			/* Copy setting, if present */
65
+			setting.tag = tag;
66
+			len = fetch_setting_len ( source, &setting );
67
+			if ( len < 0 )
68
+				break;
69
+			{
70
+				char buf[len];
71
+
72
+				check_len = fetch_setting ( source, &setting,
73
+							    buf, sizeof (buf));
74
+				assert ( check_len == len );
75
+				if ( ( rc = dhcppkt_store ( dest, tag, buf,
76
+							    sizeof(buf) )) !=0)
77
+					return rc;
78
+			}
79
+			break;
80
+		}
81
+	}
82
+
83
+	return 0;
84
+}
85
+
86
+/**
87
+ * Copy settings to DHCP packet
88
+ *
89
+ * @v dest		Destination DHCP packet
90
+ * @v source		Source settings block
91
+ * @ret rc		Return status code
92
+ */
93
+static int copy_settings ( struct dhcp_packet *dest,
94
+			   struct settings *source ) {
95
+	return copy_encap_settings ( dest, source, 0 );
96
+}
97
+
98
+/**
99
+ * Create fake DHCPDISCOVER packet
100
+ *
101
+ * @v netdev		Network device
102
+ * @v data		Buffer for DHCP packet
103
+ * @v max_len		Size of DHCP packet buffer
104
+ * @ret rc		Return status code
105
+ *
106
+ * Used by external code.
107
+ */
108
+int create_fakedhcpdiscover ( struct net_device *netdev,
109
+			      void *data, size_t max_len ) {
110
+	struct dhcp_packet dhcppkt;
111
+	int rc;
112
+
113
+	if ( ( rc = create_dhcp_request ( &dhcppkt, netdev, NULL, data,
114
+					  max_len ) ) != 0 ) {
115
+		DBG ( "Could not create DHCPDISCOVER: %s\n",
116
+		      strerror ( rc ) );
117
+		return rc;
118
+	}
119
+
120
+	return 0;
121
+}
122
+
123
+/**
124
+ * Create fake DHCPACK packet
125
+ *
126
+ * @v netdev		Network device
127
+ * @v data		Buffer for DHCP packet
128
+ * @v max_len		Size of DHCP packet buffer
129
+ * @ret rc		Return status code
130
+ *
131
+ * Used by external code.
132
+ */
133
+int create_fakedhcpack ( struct net_device *netdev,
134
+			 void *data, size_t max_len ) {
135
+	struct dhcp_packet dhcppkt;
136
+	int rc;
137
+
138
+	/* Create base DHCPACK packet */
139
+	if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
140
+					 data, max_len ) ) != 0 ) {
141
+		DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) );
142
+		return rc;
143
+	}
144
+
145
+	/* Merge in globally-scoped settings, then netdev-specific
146
+	 * settings.  Do it in this order so that netdev-specific
147
+	 * settings take precedence regardless of stated priorities.
148
+	 */
149
+	if ( ( rc = copy_settings ( &dhcppkt, NULL ) ) != 0 ) {
150
+		DBG ( "Could not set DHCPACK global settings: %s\n",
151
+		      strerror ( rc ) );
152
+		return rc;
153
+	}
154
+	if ( ( rc = copy_settings ( &dhcppkt,
155
+				    netdev_settings ( netdev ) ) ) != 0 ) {
156
+		DBG ( "Could not set DHCPACK netdev settings: %s\n",
157
+		      strerror ( rc ) );
158
+		return rc;
159
+	}
160
+
161
+	return 0;
162
+}
163
+
164
+/**
165
+ * Create ProxyDHCPACK packet
166
+ *
167
+ * @v netdev		Network device
168
+ * @v data		Buffer for DHCP packet
169
+ * @v max_len		Size of DHCP packet buffer
170
+ * @ret rc		Return status code
171
+ *
172
+ * Used by external code.
173
+ */
174
+int create_fakeproxydhcpack ( struct net_device *netdev,
175
+			      void *data, size_t max_len ) {
176
+	struct dhcp_packet dhcppkt;
177
+	struct settings *settings;
178
+	int rc;
179
+
180
+	/* Identify ProxyDHCP settings */
181
+	settings = find_settings ( PROXYDHCP_SETTINGS_NAME );
182
+
183
+	/* No ProxyDHCP settings => return empty block */
184
+	if ( ! settings ) {
185
+		memset ( data, 0, max_len );
186
+		return 0;
187
+	}
188
+
189
+	/* Create base DHCPACK packet */
190
+	if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
191
+					 data, max_len ) ) != 0 ) {
192
+		DBG ( "Could not create ProxyDHCPACK: %s\n",
193
+		      strerror ( rc ) );
194
+		return rc;
195
+	}
196
+
197
+	/* Merge in ProxyDHCP options */
198
+	if ( ( rc = copy_settings ( &dhcppkt, settings ) ) != 0 ) {
199
+		DBG ( "Could not set ProxyDHCPACK settings: %s\n",
200
+		      strerror ( rc ) );
201
+		return rc;
202
+	}
203
+
204
+	return 0;
205
+}

+ 87
- 56
src/net/ipv4.c Просмотреть файл

@@ -95,62 +95,6 @@ static void del_ipv4_miniroute ( struct ipv4_miniroute *miniroute ) {
95 95
 	free ( miniroute );
96 96
 }
97 97
 
98
-/**
99
- * Create IPv4 routing table
100
- *
101
- * @ret rc		Return status code
102
- */
103
-static int ipv4_create_routes ( void ) {
104
-	struct ipv4_miniroute *miniroute;
105
-	struct ipv4_miniroute *tmp;
106
-	struct net_device *netdev;
107
-	struct settings *settings;
108
-	struct in_addr address = { 0 };
109
-	struct in_addr netmask = { 0 };
110
-	struct in_addr gateway = { INADDR_NONE };
111
-
112
-	/* Delete all existing routes */
113
-	list_for_each_entry_safe ( miniroute, tmp, &ipv4_miniroutes, list )
114
-		del_ipv4_miniroute ( miniroute );
115
-
116
-	/* Create a route for each configured network device */
117
-	for_each_netdev ( netdev ) {
118
-		settings = netdev_settings ( netdev );
119
-		/* Get IPv4 address */
120
-		address.s_addr = 0;
121
-		fetch_ipv4_setting ( settings, DHCP_EB_YIADDR, &address );
122
-		if ( ! address.s_addr )
123
-			continue;
124
-		/* Calculate default netmask */
125
-		if ( IN_CLASSA ( ntohl ( address.s_addr ) ) ) {
126
-			netmask.s_addr = htonl ( IN_CLASSA_NET );
127
-		} else if ( IN_CLASSB ( ntohl ( address.s_addr ) ) ) {
128
-			netmask.s_addr = htonl ( IN_CLASSB_NET );
129
-		} else if ( IN_CLASSC ( ntohl ( address.s_addr ) ) ) {
130
-			netmask.s_addr = htonl ( IN_CLASSC_NET );
131
-		} else {
132
-			netmask.s_addr = 0;
133
-		}
134
-		/* Override with subnet mask, if present */
135
-		fetch_ipv4_setting ( settings, DHCP_SUBNET_MASK, &netmask );
136
-		/* Get default gateway, if present */
137
-		gateway.s_addr = INADDR_NONE;
138
-		fetch_ipv4_setting ( settings, DHCP_ROUTERS, &gateway );
139
-		/* Configure route */
140
-		miniroute = add_ipv4_miniroute ( netdev, address,
141
-						 netmask, gateway );
142
-		if ( ! miniroute )
143
-			return -ENOMEM;
144
-	}
145
-
146
-	return 0;
147
-}
148
-
149
-/** IPv4 settings applicator */
150
-struct settings_applicator ipv4_settings_applicator __settings_applicator = {
151
-	.apply = ipv4_create_routes,
152
-};
153
-
154 98
 /**
155 99
  * Perform IPv4 routing
156 100
  *
@@ -600,3 +544,90 @@ struct arp_net_protocol ipv4_arp_protocol __arp_net_protocol = {
600 544
 	.net_protocol = &ipv4_protocol,
601 545
 	.check = ipv4_arp_check,
602 546
 };
547
+
548
+/******************************************************************************
549
+ *
550
+ * Settings
551
+ *
552
+ ******************************************************************************
553
+ */
554
+
555
+/** IPv4 address setting */
556
+struct setting ip_setting __setting = {
557
+	.name = "ip",
558
+	.description = "IPv4 address",
559
+	.tag = DHCP_EB_YIADDR,
560
+	.type = &setting_type_ipv4,
561
+};
562
+
563
+/** IPv4 subnet mask setting */
564
+struct setting netmask_setting __setting = {
565
+	.name = "netmask",
566
+	.description = "IPv4 subnet mask",
567
+	.tag = DHCP_SUBNET_MASK,
568
+	.type = &setting_type_ipv4,
569
+};
570
+
571
+/** Default gateway setting */
572
+struct setting gateway_setting __setting = {
573
+	.name = "gateway",
574
+	.description = "Default gateway",
575
+	.tag = DHCP_ROUTERS,
576
+	.type = &setting_type_ipv4,
577
+};
578
+
579
+/**
580
+ * Create IPv4 routing table based on configured settings
581
+ *
582
+ * @ret rc		Return status code
583
+ */
584
+static int ipv4_create_routes ( void ) {
585
+	struct ipv4_miniroute *miniroute;
586
+	struct ipv4_miniroute *tmp;
587
+	struct net_device *netdev;
588
+	struct settings *settings;
589
+	struct in_addr address = { 0 };
590
+	struct in_addr netmask = { 0 };
591
+	struct in_addr gateway = { INADDR_NONE };
592
+
593
+	/* Delete all existing routes */
594
+	list_for_each_entry_safe ( miniroute, tmp, &ipv4_miniroutes, list )
595
+		del_ipv4_miniroute ( miniroute );
596
+
597
+	/* Create a route for each configured network device */
598
+	for_each_netdev ( netdev ) {
599
+		settings = netdev_settings ( netdev );
600
+		/* Get IPv4 address */
601
+		address.s_addr = 0;
602
+		fetch_ipv4_setting ( settings, &ip_setting, &address );
603
+		if ( ! address.s_addr )
604
+			continue;
605
+		/* Calculate default netmask */
606
+		if ( IN_CLASSA ( ntohl ( address.s_addr ) ) ) {
607
+			netmask.s_addr = htonl ( IN_CLASSA_NET );
608
+		} else if ( IN_CLASSB ( ntohl ( address.s_addr ) ) ) {
609
+			netmask.s_addr = htonl ( IN_CLASSB_NET );
610
+		} else if ( IN_CLASSC ( ntohl ( address.s_addr ) ) ) {
611
+			netmask.s_addr = htonl ( IN_CLASSC_NET );
612
+		} else {
613
+			netmask.s_addr = 0;
614
+		}
615
+		/* Override with subnet mask, if present */
616
+		fetch_ipv4_setting ( settings, &netmask_setting, &netmask );
617
+		/* Get default gateway, if present */
618
+		gateway.s_addr = INADDR_NONE;
619
+		fetch_ipv4_setting ( settings, &gateway_setting, &gateway );
620
+		/* Configure route */
621
+		miniroute = add_ipv4_miniroute ( netdev, address,
622
+						 netmask, gateway );
623
+		if ( ! miniroute )
624
+			return -ENOMEM;
625
+	}
626
+
627
+	return 0;
628
+}
629
+
630
+/** IPv4 settings applicator */
631
+struct settings_applicator ipv4_settings_applicator __settings_applicator = {
632
+	.apply = ipv4_create_routes,
633
+};

+ 17
- 22
src/net/netdev_settings.c Просмотреть файл

@@ -28,28 +28,34 @@
28 28
  *
29 29
  */
30 30
 
31
+/** Network device named settings */
32
+struct setting mac_setting __setting = {
33
+	.name = "mac",
34
+	.description = "MAC address",
35
+	.type = &setting_type_hex,
36
+};
37
+
31 38
 /**
32 39
  * Store value of network device setting
33 40
  *
34 41
  * @v settings		Settings block
35
- * @v tag		Setting tag number
42
+ * @v setting		Setting to store
36 43
  * @v data		Setting data, or NULL to clear setting
37 44
  * @v len		Length of setting data
38 45
  * @ret rc		Return status code
39 46
  */
40
-static int netdev_store ( struct settings *settings, unsigned int tag,
47
+static int netdev_store ( struct settings *settings, struct setting *setting,
41 48
 			  const void *data, size_t len ) {
42 49
 	struct net_device *netdev = container_of ( settings, struct net_device,
43 50
 						   settings.settings );
44 51
 
45
-	switch ( tag ) {
46
-	case DHCP_EB_MAC:
52
+	if ( setting_cmp ( setting, &mac_setting ) == 0 ) {
47 53
 		if ( len != netdev->ll_protocol->ll_addr_len )
48 54
 			return -EINVAL;
49 55
 		memcpy ( netdev->ll_addr, data, len );
50 56
 		return 0;
51
-	default :
52
-		return simple_settings_store ( settings, tag, data, len );
57
+	} else {
58
+		return simple_settings_store ( settings, setting, data, len );
53 59
 	}
54 60
 }
55 61
 
@@ -57,24 +63,23 @@ static int netdev_store ( struct settings *settings, unsigned int tag,
57 63
  * Fetch value of network device setting
58 64
  *
59 65
  * @v settings		Settings block
60
- * @v tag		Setting tag number
66
+ * @v setting		Setting to fetch
61 67
  * @v data		Setting data, or NULL to clear setting
62 68
  * @v len		Length of setting data
63 69
  * @ret rc		Return status code
64 70
  */
65
-static int netdev_fetch ( struct settings *settings, unsigned int tag,
71
+static int netdev_fetch ( struct settings *settings, struct setting *setting,
66 72
 			  void *data, size_t len ) {
67 73
 	struct net_device *netdev = container_of ( settings, struct net_device,
68 74
 						   settings.settings );
69 75
 
70
-	switch ( tag ) {
71
-	case DHCP_EB_MAC:
76
+	if ( setting_cmp ( setting, &mac_setting ) == 0 ) {
72 77
 		if ( len > netdev->ll_protocol->ll_addr_len )
73 78
 			len = netdev->ll_protocol->ll_addr_len;
74 79
 		memcpy ( data, netdev->ll_addr, len );
75 80
 		return netdev->ll_protocol->ll_addr_len;
76
-	default :
77
-		return simple_settings_fetch ( settings, tag, data, len );
81
+	} else {
82
+		return simple_settings_fetch ( settings, setting, data, len );
78 83
 	}
79 84
 }
80 85
 
@@ -83,13 +88,3 @@ struct settings_operations netdev_settings_operations = {
83 88
 	.store = netdev_store,
84 89
 	.fetch = netdev_fetch,
85 90
 };
86
-
87
-/** Network device named settings */
88
-struct named_setting netdev_named_settings[] __named_setting = {
89
-	{
90
-		.name = "mac",
91
-		.description = "MAC address",
92
-		.tag = DHCP_EB_MAC,
93
-		.type = &setting_type_hex,
94
-	},
95
-};

+ 19
- 11
src/net/tcp/iscsi.c Просмотреть файл

@@ -1591,14 +1591,22 @@ int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) {
1591 1591
 
1592 1592
 /****************************************************************************
1593 1593
  *
1594
- * Settings applicators
1594
+ * Settings
1595 1595
  *
1596 1596
  */
1597 1597
 
1598
+/** iSCSI initiator IQN setting */
1599
+struct setting initiator_iqn_setting __setting = {
1600
+	.name = "initiator-iqn",
1601
+	.description = "iSCSI initiator name",
1602
+	.tag = DHCP_ISCSI_INITIATOR_IQN,
1603
+	.type = &setting_type_string,
1604
+};
1605
+
1598 1606
 /** An iSCSI string setting */
1599 1607
 struct iscsi_string_setting {
1600
-	/** Setting tag number */
1601
-	unsigned int tag;
1608
+	/** Setting */
1609
+	struct setting *setting;
1602 1610
 	/** String to update */
1603 1611
 	char **string;
1604 1612
 	/** String prefix */
@@ -1608,22 +1616,22 @@ struct iscsi_string_setting {
1608 1616
 /** iSCSI string settings */
1609 1617
 static struct iscsi_string_setting iscsi_string_settings[] = {
1610 1618
 	{
1611
-		.tag = DHCP_ISCSI_INITIATOR_IQN,
1619
+		.setting = &initiator_iqn_setting,
1612 1620
 		.string = &iscsi_explicit_initiator_iqn,
1613 1621
 		.prefix = "",
1614 1622
 	},
1615 1623
 	{
1616
-		.tag = DHCP_EB_USERNAME,
1624
+		.setting = &username_setting,
1617 1625
 		.string = &iscsi_username,
1618 1626
 		.prefix = "",
1619 1627
 	},
1620 1628
 	{
1621
-		.tag = DHCP_EB_PASSWORD,
1629
+		.setting = &password_setting,
1622 1630
 		.string = &iscsi_password,
1623 1631
 		.prefix = "",
1624 1632
 	},
1625 1633
 	{
1626
-		.tag = DHCP_HOST_NAME,
1634
+		.setting = &hostname_setting,
1627 1635
 		.string = &iscsi_default_initiator_iqn,
1628 1636
 		.prefix = "iqn.2000-09.org.etherboot:",
1629 1637
 	},
@@ -1648,7 +1656,7 @@ static int apply_iscsi_string_setting ( struct iscsi_string_setting *setting ){
1648 1656
 
1649 1657
 	/* Allocate new string */
1650 1658
 	prefix_len = strlen ( setting->prefix );
1651
-	setting_len = fetch_setting_len ( NULL, setting->tag );
1659
+	setting_len = fetch_setting_len ( NULL, setting->setting );
1652 1660
 	if ( setting_len < 0 ) {
1653 1661
 		/* Missing settings are not errors; leave strings as NULL */
1654 1662
 		return 0;
@@ -1660,7 +1668,7 @@ static int apply_iscsi_string_setting ( struct iscsi_string_setting *setting ){
1660 1668
 
1661 1669
 	/* Fill new string */
1662 1670
 	strcpy ( p, setting->prefix );
1663
-	check_len = fetch_string_setting ( NULL, setting->tag,
1671
+	check_len = fetch_string_setting ( NULL, setting->setting,
1664 1672
 					   ( p + prefix_len ),
1665 1673
 					   ( len - prefix_len ) );
1666 1674
 	assert ( check_len == setting_len );
@@ -1682,8 +1690,8 @@ static int apply_iscsi_settings ( void ) {
1682 1690
 			    sizeof ( iscsi_string_settings[0] ) ) ; i++ ) {
1683 1691
 		setting = &iscsi_string_settings[i];
1684 1692
 		if ( ( rc = apply_iscsi_string_setting ( setting ) ) != 0 ) {
1685
-			DBG ( "iSCSI could not apply setting %d\n",
1686
-			      setting->tag );
1693
+			DBG ( "iSCSI could not apply setting %s\n",
1694
+			      setting->setting->name );
1687 1695
 			return rc;
1688 1696
 		}
1689 1697
 	}

+ 122
- 181
src/net/udp/dhcp.c Просмотреть файл

@@ -130,9 +130,6 @@ static uint32_t dhcp_xid ( struct net_device *netdev ) {
130 130
 	return xid;
131 131
 }
132 132
 
133
-/** Settings block name used for ProxyDHCP responses */
134
-#define PROXYDHCP_SETTINGS_NAME "proxydhcp"
135
-
136 133
 /**
137 134
  * Create a DHCP packet
138 135
  *
@@ -180,12 +177,12 @@ int create_dhcp_packet ( struct dhcp_packet *dhcppkt,
180 177
 	memcpy ( dhcphdr->chaddr, netdev->ll_addr, hlen );
181 178
 	memcpy ( dhcphdr->options, options->data, options_len );
182 179
 
183
-	/* Initialise DHCP packet structure and settings interface */
180
+	/* Initialise DHCP packet structure */
184 181
 	memset ( dhcppkt, 0, sizeof ( *dhcppkt ) );
185
-	dhcppkt_init ( dhcppkt, NULL, data, max_len );
182
+	dhcppkt_init ( dhcppkt, data, max_len );
186 183
 	
187 184
 	/* Set DHCP_MESSAGE_TYPE option */
188
-	if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_MESSAGE_TYPE,
185
+	if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_MESSAGE_TYPE,
189 186
 				    &msgtype, sizeof ( msgtype ) ) ) != 0 )
190 187
 		return rc;
191 188
 
@@ -230,10 +227,10 @@ struct dhcp_client_uuid {
230 227
  * @v max_len		Size of DHCP packet buffer
231 228
  * @ret rc		Return status code
232 229
  */
233
-static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
234
-				 struct net_device *netdev,
235
-				 struct dhcp_packet *dhcpoffer,
236
-				 void *data, size_t max_len ) {
230
+int create_dhcp_request ( struct dhcp_packet *dhcppkt,
231
+			  struct net_device *netdev,
232
+			  struct dhcp_packet *dhcpoffer,
233
+			  void *data, size_t max_len ) {
237 234
 	struct device_description *desc = &netdev->dev->desc;
238 235
 	struct dhcp_netdev_desc dhcp_desc;
239 236
 	struct dhcp_client_id client_id;
@@ -258,27 +255,26 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
258 255
 		struct in_addr server_id;
259 256
 		struct in_addr requested_ip;
260 257
 
261
-		if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings,
262
-						 DHCP_SERVER_IDENTIFIER,
263
-						 &server_id ) ) < 0 ) {
258
+		if ( dhcppkt_fetch ( dhcpoffer, DHCP_SERVER_IDENTIFIER,
259
+				     &server_id, sizeof ( server_id ) )
260
+		     != sizeof ( server_id ) ) {
264 261
 			DBG ( "DHCP offer missing server identifier\n" );
265 262
 			return -EINVAL;
266 263
 		}
267
-		if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings,
268
-						 DHCP_EB_YIADDR,
269
-						 &requested_ip ) ) < 0 ) {
264
+		if ( dhcppkt_fetch ( dhcpoffer, DHCP_EB_YIADDR,
265
+				     &requested_ip, sizeof ( requested_ip ) )
266
+		     != sizeof ( requested_ip ) ) {
270 267
 			DBG ( "DHCP offer missing IP address\n" );
271 268
 			return -EINVAL;
272 269
 		}
273
-		if ( ( rc = store_setting ( &dhcppkt->settings,
274
-					    DHCP_SERVER_IDENTIFIER, &server_id,
270
+		if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
271
+					    &server_id,
275 272
 					    sizeof ( server_id ) ) ) != 0 ) {
276 273
 			DBG ( "DHCP could not set server identifier: %s\n ",
277 274
 			      strerror ( rc ) );
278 275
 			return rc;
279 276
 		}
280
-		if ( ( rc = store_setting ( &dhcppkt->settings,
281
-					    DHCP_REQUESTED_ADDRESS,
277
+		if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS,
282 278
 					    &requested_ip,
283 279
 					    sizeof ( requested_ip ) ) ) != 0 ){
284 280
 			DBG ( "DHCP could not set requested address: %s\n",
@@ -289,8 +285,8 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
289 285
 
290 286
 	/* Add options to identify the feature list */
291 287
 	dhcp_features_len = ( dhcp_features_end - dhcp_features );
292
-	if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_EB_ENCAP,
293
-				    dhcp_features, dhcp_features_len ) ) !=0 ){
288
+	if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_ENCAP, dhcp_features,
289
+				    dhcp_features_len ) ) != 0 ) {
294 290
 		DBG ( "DHCP could not set features list option: %s\n",
295 291
 		      strerror ( rc ) );
296 292
 		return rc;
@@ -300,8 +296,8 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
300 296
 	dhcp_desc.type = desc->bus_type;
301 297
 	dhcp_desc.vendor = htons ( desc->vendor );
302 298
 	dhcp_desc.device = htons ( desc->device );
303
-	if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_EB_BUS_ID,
304
-				    &dhcp_desc, sizeof ( dhcp_desc ) ) ) !=0 ){
299
+	if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_BUS_ID, &dhcp_desc,
300
+				    sizeof ( dhcp_desc ) ) ) != 0 ) {
305 301
 		DBG ( "DHCP could not set bus ID option: %s\n",
306 302
 		      strerror ( rc ) );
307 303
 		return rc;
@@ -314,8 +310,8 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
314 310
 	ll_addr_len = netdev->ll_protocol->ll_addr_len;
315 311
 	assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) );
316 312
 	memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len );
317
-	if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_CLIENT_ID,
318
-				    &client_id, ( ll_addr_len + 1 ) ) ) != 0 ){
313
+	if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_ID, &client_id,
314
+				    ( ll_addr_len + 1 ) ) ) != 0 ) {
319 315
 		DBG ( "DHCP could not set client ID: %s\n",
320 316
 		      strerror ( rc ) );
321 317
 		return rc;
@@ -324,8 +320,8 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
324 320
 	/* Add client UUID, if we have one.  Required for PXE. */
325 321
 	client_uuid.type = DHCP_CLIENT_UUID_TYPE;
326 322
 	if ( ( rc = get_uuid ( &client_uuid.uuid ) ) == 0 ) {
327
-		if ( ( rc = store_setting ( &dhcppkt->settings,
328
-					    DHCP_CLIENT_UUID, &client_uuid,
323
+		if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID,
324
+					    &client_uuid,
329 325
 					    sizeof ( client_uuid ) ) ) != 0 ) {
330 326
 			DBG ( "DHCP could not set client UUID: %s\n",
331 327
 			      strerror ( rc ) );
@@ -336,169 +332,109 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
336 332
 	return 0;
337 333
 }
338 334
 
339
-/**
340
- * Create DHCPDISCOVER packet
335
+/****************************************************************************
341 336
  *
342
- * @v netdev		Network device
343
- * @v data		Buffer for DHCP packet
344
- * @v max_len		Size of DHCP packet buffer
345
- * @ret rc		Return status code
337
+ * DHCP settings
346 338
  *
347
- * Used by external code.
348 339
  */
349
-int create_dhcpdiscover ( struct net_device *netdev,
350
-			  void *data, size_t max_len ) {
351
-	struct dhcp_packet dhcppkt;
352
-	int rc;
353 340
 
354
-	if ( ( rc = create_dhcp_request ( &dhcppkt, netdev, NULL, data,
355
-					  max_len ) ) != 0 ) {
356
-		DBG ( "Could not create DHCPDISCOVER: %s\n",
357
-		      strerror ( rc ) );
358
-		return rc;
359
-	}
360
-
361
-	return 0;
362
-}
341
+/** A DHCP settings block */
342
+struct dhcp_settings {
343
+	/** Reference counter */
344
+	struct refcnt refcnt;
345
+	/** Containing I/O buffer */
346
+	struct io_buffer *iobuf;
347
+	/** DHCP packet */
348
+	struct dhcp_packet dhcppkt;
349
+	/** Setting interface */
350
+	struct settings settings;
351
+};
363 352
 
364 353
 /**
365
- * Create DHCPACK packet
354
+ * Free DHCP settings block
366 355
  *
367
- * @v netdev		Network device
368
- * @v data		Buffer for DHCP packet
369
- * @v max_len		Size of DHCP packet buffer
370
- * @ret rc		Return status code
371
- *
372
- * Used by external code.
356
+ * @v refcnt		Reference counter
373 357
  */
374
-int create_dhcpack ( struct net_device *netdev,
375
-		     void *data, size_t max_len ) {
376
-	struct dhcp_packet dhcppkt;
377
-	int rc;
378
-
379
-	/* Create base DHCPACK packet */
380
-	if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
381
-					 data, max_len ) ) != 0 ) {
382
-		DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) );
383
-		return rc;
384
-	}
385
-
386
-	/* Merge in globally-scoped settings, then netdev-specific
387
-	 * settings.  Do it in this order so that netdev-specific
388
-	 * settings take precedence regardless of stated priorities.
389
-	 */
390
-	if ( ( rc = copy_settings ( &dhcppkt.settings, NULL ) ) != 0 ) {
391
-		DBG ( "Could not set DHCPACK global settings: %s\n",
392
-		      strerror ( rc ) );
393
-		return rc;
394
-	}
395
-	if ( ( rc = copy_settings ( &dhcppkt.settings,
396
-				    netdev_settings ( netdev ) ) ) != 0 ) {
397
-		DBG ( "Could not set DHCPACK netdev settings: %s\n",
398
-		      strerror ( rc ) );
399
-		return rc;
400
-	}
358
+static void dhcpset_free ( struct refcnt *refcnt ) {
359
+	struct dhcp_settings *dhcpset =
360
+		container_of ( refcnt, struct dhcp_settings, refcnt );
401 361
 
402
-	return 0;
362
+	free_iob ( dhcpset->iobuf );
363
+	free ( dhcpset );
403 364
 }
404 365
 
405 366
 /**
406
- * Create ProxyDHCPACK packet
407
- *
408
- * @v netdev		Network device
409
- * @v data		Buffer for DHCP packet
410
- * @v max_len		Size of DHCP packet buffer
411
- * @ret rc		Return status code
367
+ * Decrement reference count on DHCP settings block
412 368
  *
413
- * Used by external code.
369
+ * @v dhcpset		DHCP settings block
414 370
  */
415
-int create_proxydhcpack ( struct net_device *netdev,
416
-			  void *data, size_t max_len ) {
417
-	struct dhcp_packet dhcppkt;
418
-	struct settings *settings;
419
-	int rc;
420
-
421
-	/* Identify ProxyDHCP settings */
422
-	settings = find_settings ( PROXYDHCP_SETTINGS_NAME );
423
-
424
-	/* No ProxyDHCP settings => return empty block */
425
-	if ( ! settings ) {
426
-		memset ( data, 0, max_len );
427
-		return 0;
428
-	}
429
-
430
-	/* Create base DHCPACK packet */
431
-	if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
432
-					 data, max_len ) ) != 0 ) {
433
-		DBG ( "Could not create ProxyDHCPACK: %s\n",
434
-		      strerror ( rc ) );
435
-		return rc;
436
-	}
437
-
438
-	/* Merge in ProxyDHCP options */
439
-	if ( ( rc = copy_settings ( &dhcppkt.settings, settings ) ) != 0 ) {
440
-		DBG ( "Could not set ProxyDHCPACK settings: %s\n",
441
-		      strerror ( rc ) );
442
-		return rc;
443
-	}
444
-
445
-	return 0;
371
+static inline void dhcpset_put ( struct dhcp_settings *dhcpset ) {
372
+	ref_put ( &dhcpset->refcnt );
446 373
 }
447 374
 
448
-/****************************************************************************
449
- *
450
- * DHCP packets contained in I/O buffers
375
+/**
376
+ * Store value of DHCP setting
451 377
  *
378
+ * @v settings		Settings block
379
+ * @v setting		Setting to store
380
+ * @v data		Setting data, or NULL to clear setting
381
+ * @v len		Length of setting data
382
+ * @ret rc		Return status code
452 383
  */
384
+static int dhcpset_store ( struct settings *settings, struct setting *setting,
385
+			   const void *data, size_t len ) {
386
+	struct dhcp_settings *dhcpset =
387
+		container_of ( settings, struct dhcp_settings, settings );
453 388
 
454
-/** A DHCP packet contained in an I/O buffer */
455
-struct dhcp_iobuf_packet {
456
-	/** DHCP packet */
457
-	struct dhcp_packet dhcppkt;
458
-	/** Reference counter */
459
-	struct refcnt refcnt;
460
-	/** Containing I/O buffer */
461
-	struct io_buffer *iobuf;
462
-};
389
+	return dhcppkt_store ( &dhcpset->dhcppkt, setting->tag, data, len );
390
+}
463 391
 
464 392
 /**
465
- * Free DHCP packet contained in an I/O buffer
393
+ * Fetch value of setting
466 394
  *
467
- * @v refcnt		Reference counter
395
+ * @v settings		Settings block, or NULL to search all blocks
396
+ * @v setting		Setting to fetch
397
+ * @v data		Buffer to fill with setting data
398
+ * @v len		Length of buffer
399
+ * @ret len		Length of setting data, or negative error
468 400
  */
469
-static void dhcpiob_free ( struct refcnt *refcnt ) {
470
-	struct dhcp_iobuf_packet *dhcpiob =
471
-		container_of ( refcnt, struct dhcp_iobuf_packet, refcnt );
401
+static int dhcpset_fetch ( struct settings *settings, struct setting *setting,
402
+			   void *data, size_t len ) {
403
+	struct dhcp_settings *dhcpset =
404
+		container_of ( settings, struct dhcp_settings, settings );
472 405
 
473
-	free_iob ( dhcpiob->iobuf );
474
-	free ( dhcpiob );
406
+	return dhcppkt_fetch ( &dhcpset->dhcppkt, setting->tag, data, len );
475 407
 }
476 408
 
409
+/** DHCP settings operations */
410
+static struct settings_operations dhcpset_settings_operations = {
411
+	.store = dhcpset_store,
412
+	.fetch = dhcpset_fetch,
413
+};
414
+
477 415
 /**
478
- * Create DHCP packet from I/O buffer
416
+ * Create DHCP setting block from I/O buffer
479 417
  *
480 418
  * @v iobuf		I/O buffer
481
- * @ret dhcpiob		DHCP packet contained in I/O buffer
419
+ * @ret dhcpset		DHCP settings block
482 420
  *
483 421
  * This function takes ownership of the I/O buffer.  Future accesses
484
- * must be via the @c dhcpiob data structure.
422
+ * must be via the @c dhcpset data structure.
485 423
  */
486
-static struct dhcp_iobuf_packet * dhcpiob_create ( struct io_buffer *iobuf ) {
487
-	struct dhcp_iobuf_packet *dhcpiob;
488
-
489
-	dhcpiob = zalloc ( sizeof ( *dhcpiob ) );
490
-	if ( dhcpiob ) {
491
-		dhcpiob->refcnt.free = dhcpiob_free;
492
-		dhcpiob->iobuf = iobuf;
493
-		dhcppkt_init ( &dhcpiob->dhcppkt, &dhcpiob->refcnt,
424
+static struct dhcp_settings * dhcpset_create_iob ( struct io_buffer *iobuf ) {
425
+	struct dhcp_settings *dhcpset;
426
+
427
+	dhcpset = zalloc ( sizeof ( *dhcpset ) );
428
+	if ( dhcpset ) {
429
+		dhcpset->refcnt.free = dhcpset_free;
430
+		dhcpset->iobuf = iobuf;
431
+		dhcppkt_init ( &dhcpset->dhcppkt,
494 432
 			       iobuf->data, iob_len ( iobuf ) );
433
+		settings_init ( &dhcpset->settings,
434
+				&dhcpset_settings_operations, &dhcpset->refcnt,
435
+				DHCP_SETTINGS_NAME );
495 436
 	}
496
-	return dhcpiob;
497
-}
498
-
499
-static void dhcpiob_put ( struct dhcp_iobuf_packet *dhcpiob ) {
500
-	if ( dhcpiob )
501
-		ref_put ( &dhcpiob->refcnt );
437
+	return dhcpset;
502 438
 }
503 439
 
504 440
 /****************************************************************************
@@ -526,9 +462,9 @@ struct dhcp_session {
526 462
 	 */
527 463
 	int state;
528 464
 	/** Response obtained from DHCP server */
529
-	struct dhcp_iobuf_packet *response;
465
+	struct dhcp_settings *response;
530 466
 	/** Response obtained from ProxyDHCP server */
531
-	struct dhcp_iobuf_packet *proxy_response;
467
+	struct dhcp_settings *proxy_response;
532 468
 	/** Retransmission timer */
533 469
 	struct retry_timer timer;
534 470
 	/** Session start time (in ticks) */
@@ -545,8 +481,8 @@ static void dhcp_free ( struct refcnt *refcnt ) {
545 481
 		container_of ( refcnt, struct dhcp_session, refcnt );
546 482
 
547 483
 	netdev_put ( dhcp->netdev );
548
-	dhcpiob_put ( dhcp->response );
549
-	dhcpiob_put ( dhcp->proxy_response );
484
+	dhcpset_put ( dhcp->response );
485
+	dhcpset_put ( dhcp->proxy_response );
550 486
 	free ( dhcp );
551 487
 }
552 488
 
@@ -584,7 +520,7 @@ static int dhcp_register_settings ( struct dhcp_session *dhcp ) {
584 520
 
585 521
 	/* Register ProxyDHCP settings, if present */
586 522
 	if ( dhcp->proxy_response ) {
587
-		settings = &dhcp->proxy_response->dhcppkt.settings;
523
+		settings = &dhcp->proxy_response->settings;
588 524
 		settings->name = PROXYDHCP_SETTINGS_NAME;
589 525
 		old_settings = find_settings ( settings->name );
590 526
 		if ( old_settings )
@@ -595,7 +531,7 @@ static int dhcp_register_settings ( struct dhcp_session *dhcp ) {
595 531
 
596 532
 	/* Register DHCP settings */
597 533
 	parent = netdev_settings ( dhcp->netdev );
598
-	settings = &dhcp->response->dhcppkt.settings;
534
+	settings = &dhcp->response->settings;
599 535
 	old_settings = find_child_settings ( parent, settings->name );
600 536
 	if ( old_settings )
601 537
 		unregister_settings ( old_settings );
@@ -701,24 +637,24 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
701 637
 			      struct xfer_metadata *meta __unused ) {
702 638
 	struct dhcp_session *dhcp =
703 639
 		container_of ( xfer, struct dhcp_session, xfer );
704
-	struct dhcp_iobuf_packet *response;
705
-	struct dhcp_iobuf_packet **store_response;
640
+	struct dhcp_settings *response;
641
+	struct dhcp_settings **store_response;
706 642
 	struct dhcphdr *dhcphdr;
707
-	struct settings *settings;
708
-	unsigned int msgtype;
643
+	uint8_t msgtype = 0;
644
+	uint8_t priority = 0;
645
+	uint8_t existing_priority = 0;
709 646
 	unsigned long elapsed;
710 647
 	int is_proxy;
711
-	int ignore_proxy;
648
+	uint8_t ignore_proxy = 0;
712 649
 	int rc;
713 650
 
714 651
 	/* Convert packet into a DHCP-packet-in-iobuf */
715
-	response = dhcpiob_create ( iobuf );
652
+	response = dhcpset_create_iob ( iobuf );
716 653
 	if ( ! response ) {
717 654
 		DBGC ( dhcp, "DHCP %p could not store DHCP packet\n", dhcp );
718 655
 		return -ENOMEM;
719 656
 	}
720 657
 	dhcphdr = response->dhcppkt.dhcphdr;
721
-	settings = &response->dhcppkt.settings;
722 658
 
723 659
 	/* Check for matching transaction ID */
724 660
 	if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
@@ -730,7 +666,8 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
730 666
 
731 667
 	/* Determine and verify message type */
732 668
 	is_proxy = ( dhcphdr->yiaddr.s_addr == 0 );
733
-	msgtype = fetch_uintz_setting ( settings, DHCP_MESSAGE_TYPE );
669
+	dhcppkt_fetch ( &response->dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
670
+			sizeof ( msgtype ) );
734 671
 	DBGC ( dhcp, "DHCP %p received %s%s\n", dhcp,
735 672
 	       ( is_proxy ? "Proxy" : "" ), dhcp_msgtype_name ( msgtype ) );
736 673
 	if ( ( ( dhcp->state != DHCPDISCOVER ) || ( msgtype != DHCPOFFER ) ) &&
@@ -746,14 +683,18 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
746 683
 	 * currently-stored options.
747 684
 	 */
748 685
 	store_response = ( is_proxy ? &dhcp->proxy_response : &dhcp->response);
749
-	if ( ( ! *store_response ) || 
750
-	     ( fetch_uintz_setting ( settings, DHCP_EB_PRIORITY ) >=
751
-	       fetch_uintz_setting ( &(*store_response)->dhcppkt.settings,
752
-				     DHCP_EB_PRIORITY ) ) ) {
753
-		dhcpiob_put ( *store_response );
686
+	if ( *store_response ) {
687
+		dhcppkt_fetch ( &(*store_response)->dhcppkt, DHCP_EB_PRIORITY,
688
+				&existing_priority,
689
+				sizeof ( existing_priority ) );
690
+	}
691
+	dhcppkt_fetch ( &response->dhcppkt, DHCP_EB_PRIORITY, &priority,
692
+			sizeof ( priority ) );
693
+	if ( priority >= existing_priority ) {
694
+		dhcpset_put ( *store_response );
754 695
 		*store_response = response;
755 696
 	} else {
756
-		dhcpiob_put ( response );
697
+		dhcpset_put ( response );
757 698
 	}
758 699
 
759 700
 	/* If we don't yet have a standard DHCP response (i.e. one
@@ -763,8 +704,8 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
763 704
 		goto out;
764 705
 
765 706
 	/* Handle DHCP response */
766
-	ignore_proxy = fetch_uintz_setting ( &dhcp->response->dhcppkt.settings,
767
-					     DHCP_EB_NO_PROXYDHCP );
707
+	dhcppkt_fetch ( &dhcp->response->dhcppkt, DHCP_EB_NO_PROXYDHCP,
708
+			&ignore_proxy, sizeof ( ignore_proxy ) );
768 709
 	switch ( dhcp->state ) {
769 710
 	case DHCPDISCOVER:
770 711
 		/* If we have allowed sufficient time for ProxyDHCP
@@ -780,7 +721,7 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
780 721
 	case DHCPREQUEST:
781 722
 		/* DHCP finished; register options and exit */
782 723
 		if ( ignore_proxy && dhcp->proxy_response ) {
783
-			dhcpiob_put ( dhcp->proxy_response );
724
+			dhcpset_put ( dhcp->proxy_response );
784 725
 			dhcp->proxy_response = NULL;
785 726
 		}
786 727
 		if ( ( rc = dhcp_register_settings ( dhcp ) ) != 0 ) {
@@ -797,7 +738,7 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
797 738
 	return 0;
798 739
 
799 740
  out_discard:
800
-	dhcpiob_put ( response );
741
+	dhcpset_put ( response );
801 742
 	return 0;
802 743
 }
803 744
 

+ 16
- 1
src/net/udp/dns.c Просмотреть файл

@@ -506,6 +506,21 @@ struct resolver dns_resolver __resolver ( RESOLV_NORMAL ) = {
506 506
 	.resolv = dns_resolv,
507 507
 };
508 508
 
509
+/******************************************************************************
510
+ *
511
+ * Settings
512
+ *
513
+ ******************************************************************************
514
+ */
515
+
516
+/** DNS server setting */
517
+struct setting dns_setting __setting = {
518
+	.name = "dns",
519
+	.description = "DNS server",
520
+	.tag = DHCP_DNS_SERVERS,
521
+	.type = &setting_type_ipv4,
522
+};
523
+
509 524
 /**
510 525
  * Apply nameserver setting
511 526
  *
@@ -516,7 +531,7 @@ static int apply_nameserver_setting ( void ) {
516 531
 		( struct sockaddr_in * ) &nameserver;
517 532
 	int len;
518 533
 
519
-	if ( ( len = fetch_ipv4_setting ( NULL, DHCP_DNS_SERVERS,
534
+	if ( ( len = fetch_ipv4_setting ( NULL, &dns_setting,
520 535
 					  &sin_nameserver->sin_addr ) ) >= 0 ){
521 536
 		sin_nameserver->sin_family = AF_INET;
522 537
 		DBG ( "DNS using nameserver %s\n",

+ 16
- 1
src/net/udp/tftp.c Просмотреть файл

@@ -1093,6 +1093,21 @@ struct uri_opener mtftp_uri_opener __uri_opener = {
1093 1093
 	.open	= mtftp_open,
1094 1094
 };
1095 1095
 
1096
+/******************************************************************************
1097
+ *
1098
+ * Settings
1099
+ *
1100
+ ******************************************************************************
1101
+ */
1102
+
1103
+/** TFTP server setting */
1104
+struct setting next_server_setting __setting = {
1105
+	.name = "next-server",
1106
+	.description = "TFTP server",
1107
+	.tag = DHCP_EB_SIADDR,
1108
+	.type = &setting_type_ipv4,
1109
+};
1110
+
1096 1111
 /**
1097 1112
  * Apply TFTP configuration settings
1098 1113
  *
@@ -1106,7 +1121,7 @@ static int tftp_apply_settings ( void ) {
1106 1121
 
1107 1122
 	/* Retrieve TFTP server setting */
1108 1123
 	last_tftp_server = tftp_server;
1109
-	fetch_ipv4_setting ( NULL, DHCP_EB_SIADDR, &tftp_server );
1124
+	fetch_ipv4_setting ( NULL, &next_server_setting, &tftp_server );
1110 1125
 
1111 1126
 	/* If TFTP server setting has changed, set the current working
1112 1127
 	 * URI to match.  Do it only when the TFTP server has changed

+ 0
- 2
src/usr/aoeboot.c Просмотреть файл

@@ -5,7 +5,6 @@
5 5
 #include <gpxe/aoe.h>
6 6
 #include <gpxe/ata.h>
7 7
 #include <gpxe/netdevice.h>
8
-#include <gpxe/dhcp.h>
9 8
 #include <gpxe/settings.h>
10 9
 #include <gpxe/abft.h>
11 10
 #include <int13.h>
@@ -56,7 +55,6 @@ int aoeboot ( const char *root_path ) {
56 55
 		container_of ( ata.backend, struct aoe_session, refcnt );
57 56
 	abft_fill_data ( aoe );
58 57
 
59
-	drive.drive = fetch_uintz_setting ( NULL, DHCP_EB_BIOS_DRIVE );
60 58
 	drive.blockdev = &ata.blockdev;
61 59
 
62 60
 	register_int13_drive ( &drive );

+ 2
- 2
src/usr/autoboot.c Просмотреть файл

@@ -147,14 +147,14 @@ static int netboot ( struct net_device *netdev ) {
147 147
 		return rc;
148 148
 
149 149
 	/* Try to download and boot whatever we are given as a filename */
150
-	fetch_string_setting ( NULL, DHCP_BOOTFILE_NAME, buf, sizeof ( buf ) );
150
+	fetch_string_setting ( NULL, &filename_setting, buf, sizeof ( buf ) );
151 151
 	if ( buf[0] ) {
152 152
 		printf ( "Booting from filename \"%s\"\n", buf );
153 153
 		return boot_filename ( buf );
154 154
 	}
155 155
 	
156 156
 	/* No filename; try the root path */
157
-	fetch_string_setting ( NULL, DHCP_ROOT_PATH, buf, sizeof ( buf ) );
157
+	fetch_string_setting ( NULL, &root_path_setting, buf, sizeof ( buf ) );
158 158
 	if ( buf[0] ) {
159 159
 		printf ( "Booting from root path \"%s\"\n", buf );
160 160
 		return boot_root_path ( buf );

+ 0
- 2
src/usr/iscsiboot.c Просмотреть файл

@@ -2,7 +2,6 @@
2 2
 #include <string.h>
3 3
 #include <stdio.h>
4 4
 #include <gpxe/iscsi.h>
5
-#include <gpxe/dhcp.h>
6 5
 #include <gpxe/settings.h>
7 6
 #include <gpxe/netdevice.h>
8 7
 #include <gpxe/ibft.h>
@@ -46,7 +45,6 @@ int iscsiboot ( const char *root_path ) {
46 45
 		goto error_init;
47 46
 	}
48 47
 
49
-	drive.drive = fetch_uintz_setting ( NULL, DHCP_EB_BIOS_DRIVE );
50 48
 	drive.blockdev = &scsi.blockdev;
51 49
 
52 50
 	/* FIXME: ugly, ugly hack */

Загрузка…
Отмена
Сохранить