2 * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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.
28 #include <gpxe/vsprintf.h>
29 #include <gpxe/dhcp.h>
30 #include <gpxe/settings.h>
34 * Configuration settings
38 /** Registered setting types */
39 static struct setting_type setting_types[0]
40 __table_start ( struct setting_type, setting_types );
41 static struct setting_type setting_types_end[0]
42 __table_end ( struct setting_type, setting_types );
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 );
50 /** Registered settings applicators */
51 static struct settings_applicator settings_applicators[0]
52 __table_start ( struct settings_applicator, settings_applicators );
53 static struct settings_applicator settings_applicators_end[0]
54 __table_end ( struct settings_applicator, settings_applicators );
57 * Obtain printable version of a settings tag number
59 * @v tag Settings tag number
60 * @ret name String representation of the tag
62 static inline char * setting_tag_name ( unsigned int tag ) {
65 if ( DHCP_IS_ENCAP_OPT ( tag ) ) {
66 snprintf ( name, sizeof ( name ), "%d.%d",
67 DHCP_ENCAPSULATOR ( tag ),
68 DHCP_ENCAPSULATED ( tag ) );
70 snprintf ( name, sizeof ( name ), "%d", tag );
75 /******************************************************************************
77 * Registered settings blocks
79 ******************************************************************************
83 * Store value of simple setting
85 * @v options DHCP option block
86 * @v tag Setting tag number
87 * @v data Setting data, or NULL to clear setting
88 * @v len Length of setting data
89 * @ret rc Return status code
91 int simple_settings_store ( struct settings *settings, unsigned int tag,
92 const void *data, size_t len ) {
93 struct simple_settings *simple =
94 container_of ( settings, struct simple_settings, settings );
95 return dhcpopt_extensible_store ( &simple->dhcpopts, tag, data, len );
99 * Fetch value of simple setting
101 * @v options DHCP option block
102 * @v tag Setting tag number
103 * @v data Buffer to fill with setting data
104 * @v len Length of buffer
105 * @ret len Length of setting data, or negative error
107 int simple_settings_fetch ( struct settings *settings, unsigned int tag,
108 void *data, size_t len ) {
109 struct simple_settings *simple =
110 container_of ( settings, struct simple_settings, settings );
111 return dhcpopt_fetch ( &simple->dhcpopts, tag, data, len );
114 /** Simple settings operations */
115 struct settings_operations simple_settings_operations = {
116 .store = simple_settings_store,
117 .fetch = simple_settings_fetch,
120 /** Root simple settings block */
121 struct simple_settings simple_settings_root = {
126 LIST_HEAD_INIT ( simple_settings_root.settings.siblings ),
128 LIST_HEAD_INIT ( simple_settings_root.settings.children ),
129 .op = &simple_settings_operations,
133 /** Root settings block */
134 #define settings_root simple_settings_root.settings
139 * @ret rc Return status code
141 static int apply_settings ( void ) {
142 struct settings_applicator *applicator;
145 /* Call all settings applicators */
146 for ( applicator = settings_applicators ;
147 applicator < settings_applicators_end ; applicator++ ) {
148 if ( ( rc = applicator->apply() ) != 0 ) {
149 DBG ( "Could not apply settings using applicator "
150 "%p: %s\n", applicator, strerror ( rc ) );
159 * Reprioritise settings
161 * @v settings Settings block
163 * Reorders the settings block amongst its siblings according to its
166 static void reprioritise_settings ( struct settings *settings ) {
167 struct settings *parent = settings->parent;
169 struct settings *tmp;
172 /* Stop when we reach the top of the tree */
176 /* Read priority, if present */
177 priority = fetch_intz_setting ( settings, DHCP_EB_PRIORITY );
179 /* Remove from siblings list */
180 list_del ( &settings->siblings );
182 /* Reinsert after any existing blocks which have a higher priority */
183 list_for_each_entry ( tmp, &parent->children, siblings ) {
184 tmp_priority = fetch_intz_setting ( tmp, DHCP_EB_PRIORITY );
185 if ( priority > tmp_priority )
188 list_add_tail ( &settings->siblings, &tmp->siblings );
190 /* Recurse up the tree */
191 reprioritise_settings ( parent );
195 * Register settings block
197 * @v settings Settings block
198 * @v parent Parent settings block, or NULL
199 * @ret rc Return status code
201 int register_settings ( struct settings *settings, struct settings *parent ) {
203 /* NULL parent => add to settings root */
204 assert ( settings != NULL );
205 if ( parent == NULL )
206 parent = &settings_root;
208 /* Add to list of settings */
209 ref_get ( settings->refcnt );
210 ref_get ( parent->refcnt );
211 settings->parent = parent;
212 list_add_tail ( &settings->siblings, &parent->children );
213 DBGC ( settings, "Settings %p registered\n", settings );
215 /* Fix up settings priority */
216 reprioritise_settings ( settings );
218 /* Apply potentially-updated settings */
225 * Unregister settings block
227 * @v settings Settings block
229 void unregister_settings ( struct settings *settings ) {
231 /* Remove from list of settings */
232 ref_put ( settings->refcnt );
233 ref_put ( settings->parent->refcnt );
234 settings->parent = NULL;
235 list_del ( &settings->siblings );
236 DBGC ( settings, "Settings %p unregistered\n", settings );
238 /* Apply potentially-updated settings */
243 * Find child named settings block
245 * @v parent Parent settings block
246 * @v name Name within this parent
247 * @ret settings Settings block, or NULL
249 struct settings * find_child_settings ( struct settings *parent,
251 struct settings *settings;
254 /* Look for a child whose name matches the initial component */
255 list_for_each_entry ( settings, &parent->children, siblings ) {
256 len = strlen ( settings->name );
257 if ( strncmp ( name, settings->name, len ) != 0 )
259 if ( name[len] == 0 )
261 if ( name[len] == '.' )
262 return find_child_settings ( settings,
263 ( name + len + 1 ) );
270 * Find named settings block
273 * @ret settings Settings block, or NULL
275 struct settings * find_settings ( const char *name ) {
277 /* If name is empty, use the root */
279 return &settings_root;
281 return find_child_settings ( &settings_root, name );
284 /******************************************************************************
286 * Core settings routines
288 ******************************************************************************
292 * Store value of setting
294 * @v settings Settings block
295 * @v tag Setting tag number
296 * @v data Setting data, or NULL to clear setting
297 * @v len Length of setting data
298 * @ret rc Return status code
300 int store_setting ( struct settings *settings, unsigned int tag,
301 const void *data, size_t len ) {
302 struct settings *parent;
310 if ( ( rc = settings->op->store ( settings, tag, data, len ) ) != 0 )
313 /* Reprioritise settings if necessary */
314 if ( tag == DHCP_EB_PRIORITY )
315 reprioritise_settings ( settings );
317 /* If these settings are registered, apply potentially-updated
320 for ( parent = settings->parent ; parent ; parent = parent->parent ) {
321 if ( parent == &settings_root ) {
322 if ( ( rc = apply_settings() ) != 0 )
332 * Fetch value of setting
334 * @v settings Settings block, or NULL to search all blocks
335 * @v tag Setting tag number
336 * @v data Buffer to fill with setting data
337 * @v len Length of buffer
338 * @ret len Length of setting data, or negative error
340 * The actual length of the setting will be returned even if
341 * the buffer was too small.
343 int fetch_setting ( struct settings *settings, unsigned int tag,
344 void *data, size_t len ) {
345 struct settings *child;
348 /* NULL settings implies starting at the global settings root */
350 settings = &settings_root;
352 /* Try this block first */
353 if ( ( ret = settings->op->fetch ( settings, tag, data, len ) ) >= 0)
356 /* Recurse into each child block in turn */
357 list_for_each_entry ( child, &settings->children, siblings ) {
358 if ( ( ret = fetch_setting ( child, tag, data, len ) ) >= 0)
366 * Fetch length of setting
368 * @v settings Settings block, or NULL to search all blocks
369 * @v tag Setting tag number
370 * @ret len Length of setting data, or negative error
372 * This function can also be used as an existence check for the
375 int fetch_setting_len ( struct settings *settings, unsigned int tag ) {
376 return fetch_setting ( settings, tag, NULL, 0 );
380 * Fetch value of string setting
382 * @v settings Settings block, or NULL to search all blocks
383 * @v tag Setting tag number
384 * @v data Buffer to fill with setting string data
385 * @v len Length of buffer
386 * @ret len Length of string setting, or negative error
388 * The resulting string is guaranteed to be correctly NUL-terminated.
389 * The returned length will be the length of the underlying setting
392 int fetch_string_setting ( struct settings *settings, unsigned int tag,
393 char *data, size_t len ) {
394 memset ( data, 0, len );
395 return fetch_setting ( settings, tag, data, ( len - 1 ) );
399 * Fetch value of IPv4 address setting
401 * @v settings Settings block, or NULL to search all blocks
402 * @v tag Setting tag number
403 * @v inp IPv4 address to fill in
404 * @ret len Length of setting, or negative error
406 int fetch_ipv4_setting ( struct settings *settings, unsigned int tag,
407 struct in_addr *inp ) {
410 len = fetch_setting ( settings, tag, inp, sizeof ( *inp ) );
413 if ( len < ( int ) sizeof ( *inp ) )
419 * Fetch value of signed integer setting
421 * @v settings Settings block, or NULL to search all blocks
422 * @v tag Setting tag number
423 * @v value Integer value to fill in
424 * @ret len Length of setting, or negative error
426 int fetch_int_setting ( struct settings *settings, unsigned int tag,
430 uint8_t u8[ sizeof ( long ) ];
431 int8_t s8[ sizeof ( long ) ];
437 len = fetch_setting ( settings, tag, &buf, sizeof ( buf ) );
440 if ( len > ( int ) sizeof ( buf ) )
443 *value = ( ( buf.s8[0] >= 0 ) ? 0 : -1L );
444 for ( i = 0 ; i < len ; i++ ) {
445 *value = ( ( *value << 8 ) | buf.u8[i] );
452 * Fetch value of unsigned integer setting
454 * @v settings Settings block, or NULL to search all blocks
455 * @v tag Setting tag number
456 * @v value Integer value to fill in
457 * @ret len Length of setting, or negative error
459 int fetch_uint_setting ( struct settings *settings, unsigned int tag,
460 unsigned long *value ) {
464 len = fetch_int_setting ( settings, tag, &svalue );
468 *value = ( svalue & ( -1UL >> ( sizeof ( long ) - len ) ) );
474 * Fetch value of signed integer setting, or zero
476 * @v settings Settings block, or NULL to search all blocks
477 * @v tag Setting tag number
478 * @ret value Setting value, or zero
480 long fetch_intz_setting ( struct settings *settings, unsigned int tag ) {
483 fetch_int_setting ( settings, tag, &value );
488 * Fetch value of unsigned integer setting, or zero
490 * @v settings Settings block, or NULL to search all blocks
491 * @v tag Setting tag number
492 * @ret value Setting value, or zero
494 unsigned long fetch_uintz_setting ( struct settings *settings,
496 unsigned long value = 0;
498 fetch_uint_setting ( settings, tag, &value );
505 * @v dest Destination settings block
506 * @v dest_tag Destination setting tag number
507 * @v source Source settings block
508 * @v source_tag Source setting tag number
509 * @ret rc Return status code
511 int copy_setting ( struct settings *dest, unsigned int dest_tag,
512 struct settings *source, unsigned int source_tag ) {
517 len = fetch_setting_len ( source, source_tag );
524 check_len = fetch_setting ( source, source_tag, buf,
526 assert ( check_len == len );
528 if ( ( rc = store_setting ( dest, dest_tag, buf,
529 sizeof ( buf ) ) ) != 0 )
539 * @v dest Destination settings block
540 * @v source Source settings block
541 * @v encapsulator Encapsulating setting tag number, or zero
542 * @ret rc Return status code
544 static int copy_encap_settings ( struct settings *dest,
545 struct settings *source,
546 unsigned int encapsulator ) {
551 for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
552 tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
555 case DHCP_VENDOR_ENCAP:
556 /* Process encapsulated options field */
557 if ( ( rc = copy_encap_settings ( dest, source,
562 /* Copy option to reassembled packet */
563 if ( ( rc = copy_setting ( dest, tag, source,
576 * @v dest Destination settings block
577 * @v source Source settings block
578 * @ret rc Return status code
580 int copy_settings ( struct settings *dest, struct settings *source ) {
581 return copy_encap_settings ( dest, source, 0 );
584 /******************************************************************************
586 * Named and typed setting routines
588 ******************************************************************************
592 * Store value of typed setting
594 * @v settings Settings block
595 * @v tag Setting tag number
596 * @v type Settings type
597 * @v value Formatted setting data, or NULL
598 * @ret rc Return status code
600 int store_typed_setting ( struct settings *settings,
601 unsigned int tag, struct setting_type *type,
602 const char *value ) {
604 /* NULL value implies deletion. Avoid imposing the burden of
605 * checking for NULL values on each typed setting's storef()
609 return delete_setting ( settings, tag );
611 return type->storef ( settings, tag, value );
618 * @ret setting Named setting, or NULL
620 static struct named_setting * find_named_setting ( const char *name ) {
621 struct named_setting *setting;
623 for ( setting = named_settings ; setting < named_settings_end ;
625 if ( strcmp ( name, setting->name ) == 0 )
635 * @ret type Setting type, or NULL
637 static struct setting_type * find_setting_type ( const char *name ) {
638 struct setting_type *type;
640 for ( type = setting_types ; type < setting_types_end ; type++ ) {
641 if ( strcmp ( name, type->name ) == 0 )
650 * @v name Name of setting
651 * @ret settings Settings block, or NULL
652 * @ret tag Setting tag number
653 * @ret type Setting type
654 * @ret rc Return status code
656 * Interprets a name of the form
657 * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
660 static int parse_setting_name ( const char *name, struct settings **settings,
662 struct setting_type **type ) {
663 char tmp_name[ strlen ( name ) + 1 ];
667 struct named_setting *named_setting;
671 *settings = &settings_root;
673 *type = &setting_type_hex;
675 /* Split name into "[settings_name/]tag_name[:type_name]" */
676 memcpy ( tmp_name, name, sizeof ( tmp_name ) );
677 if ( ( tag_name = strchr ( tmp_name, '/' ) ) != NULL ) {
679 settings_name = tmp_name;
682 settings_name = NULL;
684 if ( ( type_name = strchr ( tag_name, ':' ) ) != NULL )
687 /* Identify settings block, if specified */
688 if ( settings_name ) {
689 *settings = find_settings ( settings_name );
690 if ( *settings == NULL ) {
691 DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
692 settings_name, name );
697 /* Identify tag number */
698 if ( ( named_setting = find_named_setting ( tag_name ) ) != NULL ) {
699 *tag = named_setting->tag;
700 *type = named_setting->type;
702 /* Unrecognised name: try to interpret as a tag number */
705 *tag = ( ( *tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
709 DBG ( "Invalid tag number \"%s\" in \"%s\"\n",
717 /* Identify setting type, if specified */
719 *type = find_setting_type ( type_name );
720 if ( *type == NULL ) {
721 DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
731 * Parse and store value of named setting
733 * @v name Name of setting
734 * @v value Formatted setting data, or NULL
735 * @ret rc Return status code
737 int store_named_setting ( const char *name, const char *value ) {
738 struct settings *settings;
740 struct setting_type *type;
743 if ( ( rc = parse_setting_name ( name, &settings, &tag,
746 return store_typed_setting ( settings, tag, type, value );
750 * Fetch and format value of named setting
752 * @v name Name of setting
753 * @v buf Buffer to contain formatted value
754 * @v len Length of buffer
755 * @ret len Length of formatted value, or negative error
757 int fetch_named_setting ( const char *name, char *buf, size_t len ) {
758 struct settings *settings;
760 struct setting_type *type;
763 if ( ( rc = parse_setting_name ( name, &settings, &tag,
766 return fetch_typed_setting ( settings, tag, type, buf, len );
769 /******************************************************************************
773 ******************************************************************************
777 * Parse and store value of string setting
779 * @v settings Settings block
780 * @v tag Setting tag number
781 * @v value Formatted setting data
782 * @ret rc Return status code
784 static int storef_string ( struct settings *settings, unsigned int tag,
785 const char *value ) {
786 return store_setting ( settings, tag, value, strlen ( value ) );
790 * Fetch and format value of string setting
792 * @v settings Settings block, or NULL to search all blocks
793 * @v tag Setting tag number
794 * @v buf Buffer to contain formatted value
795 * @v len Length of buffer
796 * @ret len Length of formatted value, or negative error
798 static int fetchf_string ( struct settings *settings, unsigned int tag,
799 char *buf, size_t len ) {
800 return fetch_string_setting ( settings, tag, buf, len );
803 /** A string setting type */
804 struct setting_type setting_type_string __setting_type = {
806 .storef = storef_string,
807 .fetchf = fetchf_string,
811 * Parse and store value of IPv4 address setting
813 * @v settings Settings block
814 * @v tag Setting tag number
815 * @v value Formatted setting data
816 * @ret rc Return status code
818 static int storef_ipv4 ( struct settings *settings, unsigned int tag,
819 const char *value ) {
822 if ( inet_aton ( value, &ipv4 ) == 0 )
824 return store_setting ( settings, tag, &ipv4, sizeof ( ipv4 ) );
828 * Fetch and format value of IPv4 address setting
830 * @v settings Settings block, or NULL to search all blocks
831 * @v tag Setting tag number
832 * @v buf Buffer to contain formatted value
833 * @v len Length of buffer
834 * @ret len Length of formatted value, or negative error
836 static int fetchf_ipv4 ( struct settings *settings, unsigned int tag,
837 char *buf, size_t len ) {
841 if ( ( rc = fetch_ipv4_setting ( settings, tag, &ipv4 ) ) < 0 )
843 return snprintf ( buf, len, inet_ntoa ( ipv4 ) );
846 /** An IPv4 address setting type */
847 struct setting_type setting_type_ipv4 __setting_type = {
849 .storef = storef_ipv4,
850 .fetchf = fetchf_ipv4,
854 * Parse and store value of integer setting
856 * @v settings Settings block
857 * @v tag Setting tag number
858 * @v value Formatted setting data
859 * @v size Integer size, in bytes
860 * @ret rc Return status code
862 static int storef_int ( struct settings *settings, unsigned int tag,
863 const char *value, unsigned int size ) {
870 u.num = htonl ( strtoul ( value, &endp, 0 ) );
873 return store_setting ( settings, tag,
874 &u.bytes[ sizeof ( u ) - size ], size );
878 * Parse and store value of 8-bit integer setting
880 * @v settings Settings block
881 * @v tag Setting tag number
882 * @v value Formatted setting data
883 * @v size Integer size, in bytes
884 * @ret rc Return status code
886 static int storef_int8 ( struct settings *settings, unsigned int tag,
887 const char *value ) {
888 return storef_int ( settings, tag, value, 1 );
892 * Parse and store value of 16-bit integer setting
894 * @v settings Settings block
895 * @v tag Setting tag number
896 * @v value Formatted setting data
897 * @v size Integer size, in bytes
898 * @ret rc Return status code
900 static int storef_int16 ( struct settings *settings, unsigned int tag,
901 const char *value ) {
902 return storef_int ( settings, tag, value, 2 );
906 * Parse and store value of 32-bit integer setting
908 * @v settings Settings block
909 * @v tag Setting tag number
910 * @v value Formatted setting data
911 * @v size Integer size, in bytes
912 * @ret rc Return status code
914 static int storef_int32 ( struct settings *settings, unsigned int tag,
915 const char *value ) {
916 return storef_int ( settings, tag, value, 4 );
920 * Fetch and format value of signed integer setting
922 * @v settings Settings block, or NULL to search all blocks
923 * @v tag Setting tag number
924 * @v buf Buffer to contain formatted value
925 * @v len Length of buffer
926 * @ret len Length of formatted value, or negative error
928 static int fetchf_int ( struct settings *settings, unsigned int tag,
929 char *buf, size_t len ) {
933 if ( ( rc = fetch_int_setting ( settings, tag, &value ) ) < 0 )
935 return snprintf ( buf, len, "%ld", value );
939 * Fetch and format value of unsigned integer setting
941 * @v settings Settings block, or NULL to search all blocks
942 * @v tag Setting tag number
943 * @v buf Buffer to contain formatted value
944 * @v len Length of buffer
945 * @ret len Length of formatted value, or negative error
947 static int fetchf_uint ( struct settings *settings, unsigned int tag,
948 char *buf, size_t len ) {
952 if ( ( rc = fetch_uint_setting ( settings, tag, &value ) ) < 0 )
954 return snprintf ( buf, len, "%#lx", value );
957 /** A signed 8-bit integer setting type */
958 struct setting_type setting_type_int8 __setting_type = {
960 .storef = storef_int8,
961 .fetchf = fetchf_int,
964 /** A signed 16-bit integer setting type */
965 struct setting_type setting_type_int16 __setting_type = {
967 .storef = storef_int16,
968 .fetchf = fetchf_int,
971 /** A signed 32-bit integer setting type */
972 struct setting_type setting_type_int32 __setting_type = {
974 .storef = storef_int32,
975 .fetchf = fetchf_int,
978 /** An unsigned 8-bit integer setting type */
979 struct setting_type setting_type_uint8 __setting_type = {
981 .storef = storef_int8,
982 .fetchf = fetchf_uint,
985 /** An unsigned 16-bit integer setting type */
986 struct setting_type setting_type_uint16 __setting_type = {
988 .storef = storef_int16,
989 .fetchf = fetchf_uint,
992 /** An unsigned 32-bit integer setting type */
993 struct setting_type setting_type_uint32 __setting_type = {
995 .storef = storef_int32,
996 .fetchf = fetchf_uint,
1000 * Parse and store value of hex string setting
1002 * @v settings Settings block
1003 * @v tag Setting tag number
1004 * @v value Formatted setting data
1005 * @ret rc Return status code
1007 static int storef_hex ( struct settings *settings, unsigned int tag,
1008 const char *value ) {
1009 char *ptr = ( char * ) value;
1010 uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
1011 unsigned int len = 0;
1014 bytes[len++] = strtoul ( ptr, &ptr, 16 );
1017 return store_setting ( settings, tag, bytes, len );
1028 * Fetch and format value of hex string setting
1030 * @v settings Settings block, or NULL to search all blocks
1031 * @v tag Setting tag number
1032 * @v buf Buffer to contain formatted value
1033 * @v len Length of buffer
1034 * @ret len Length of formatted value, or negative error
1036 static int fetchf_hex ( struct settings *settings, unsigned int tag,
1037 char *buf, size_t len ) {
1043 raw_len = fetch_setting_len ( settings, tag );
1048 uint8_t raw[raw_len];
1050 check_len = fetch_setting ( settings, tag, raw, sizeof (raw) );
1051 assert ( check_len == raw_len );
1054 buf[0] = 0; /* Ensure that a terminating NUL exists */
1055 for ( i = 0 ; i < raw_len ; i++ ) {
1056 used += ssnprintf ( ( buf + used ), ( len - used ),
1057 "%s%02x", ( used ? ":" : "" ),
1064 /** A hex-string setting */
1065 struct setting_type setting_type_hex __setting_type = {
1067 .storef = storef_hex,
1068 .fetchf = fetchf_hex,
1071 /******************************************************************************
1075 ******************************************************************************
1078 /** Some basic setting definitions */
1079 struct named_setting basic_named_settings[] __named_setting = {
1082 .description = "IPv4 address",
1083 .tag = DHCP_EB_YIADDR,
1084 .type = &setting_type_ipv4,
1088 .description = "IPv4 subnet mask",
1089 .tag = DHCP_SUBNET_MASK,
1090 .type = &setting_type_ipv4,
1094 .description = "Default gateway",
1095 .tag = DHCP_ROUTERS,
1096 .type = &setting_type_ipv4,
1100 .description = "DNS server",
1101 .tag = DHCP_DNS_SERVERS,
1102 .type = &setting_type_ipv4,
1106 .description = "Host name",
1107 .tag = DHCP_HOST_NAME,
1108 .type = &setting_type_string,
1112 .description = "Boot filename",
1113 .tag = DHCP_BOOTFILE_NAME,
1114 .type = &setting_type_string,
1117 .name = "root-path",
1118 .description = "NFS/iSCSI root path",
1119 .tag = DHCP_ROOT_PATH,
1120 .type = &setting_type_string,
1124 .description = "User name",
1125 .tag = DHCP_EB_USERNAME,
1126 .type = &setting_type_string,
1130 .description = "Password",
1131 .tag = DHCP_EB_PASSWORD,
1132 .type = &setting_type_string,
1135 .name = "initiator-iqn",
1136 .description = "iSCSI initiator name",
1137 .tag = DHCP_ISCSI_INITIATOR_IQN,
1138 .type = &setting_type_string,
1142 .description = "Priority of these settings",
1143 .tag = DHCP_EB_PRIORITY,
1144 .type = &setting_type_int8,