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., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <byteswap.h>
32 #include <errno.h>
33 #include <assert.h>
34 #include <time.h>
35 #include <ipxe/in.h>
36 #include <ipxe/ip.h>
37 #include <ipxe/ipv6.h>
38 #include <ipxe/vsprintf.h>
39 #include <ipxe/dhcp.h>
40 #include <ipxe/uuid.h>
41 #include <ipxe/uri.h>
42 #include <ipxe/base16.h>
43 #include <ipxe/base64.h>
44 #include <ipxe/pci.h>
45 #include <ipxe/init.h>
46 #include <ipxe/version.h>
47 #include <ipxe/settings.h>
48 
49 /** @file
50  *
51  * Configuration settings
52  *
53  */
54 
55 /******************************************************************************
56  *
57  * Generic settings blocks
58  *
59  ******************************************************************************
60  */
61 
62 /**
63  * A generic setting
64  *
65  */
66 struct generic_setting {
67 	/** List of generic settings */
68 	struct list_head list;
69 	/** Setting */
70 	struct setting setting;
71 	/** Size of setting name */
72 	size_t name_len;
73 	/** Size of setting data */
74 	size_t data_len;
75 };
76 
77 /**
78  * Get generic setting name
79  *
80  * @v generic		Generic setting
81  * @ret name		Generic setting name
82  */
generic_setting_name(struct generic_setting * generic)83 static inline void * generic_setting_name ( struct generic_setting *generic ) {
84 	return ( ( ( void * ) generic ) + sizeof ( *generic ) );
85 }
86 
87 /**
88  * Get generic setting data
89  *
90  * @v generic		Generic setting
91  * @ret data		Generic setting data
92  */
generic_setting_data(struct generic_setting * generic)93 static inline void * generic_setting_data ( struct generic_setting *generic ) {
94 	return ( ( ( void * ) generic ) + sizeof ( *generic ) +
95 		 generic->name_len );
96 }
97 
98 /**
99  * Find generic setting
100  *
101  * @v generics		Generic settings block
102  * @v setting		Setting to find
103  * @ret generic		Generic setting, or NULL
104  */
105 static struct generic_setting *
find_generic_setting(struct generic_settings * generics,const struct setting * setting)106 find_generic_setting ( struct generic_settings *generics,
107 		       const struct setting *setting ) {
108 	struct generic_setting *generic;
109 
110 	list_for_each_entry ( generic, &generics->list, list ) {
111 		if ( setting_cmp ( &generic->setting, setting ) == 0 )
112 			return generic;
113 	}
114 	return NULL;
115 }
116 
117 /**
118  * Store value of generic setting
119  *
120  * @v settings		Settings block
121  * @v setting		Setting to store
122  * @v data		Setting data, or NULL to clear setting
123  * @v len		Length of setting data
124  * @ret rc		Return status code
125  */
generic_settings_store(struct settings * settings,const struct setting * setting,const void * data,size_t len)126 int generic_settings_store ( struct settings *settings,
127 			     const struct setting *setting,
128 			     const void *data, size_t len ) {
129 	struct generic_settings *generics =
130 		container_of ( settings, struct generic_settings, settings );
131 	struct generic_setting *old;
132 	struct generic_setting *new = NULL;
133 	size_t name_len;
134 
135 	/* Identify existing generic setting, if any */
136 	old = find_generic_setting ( generics, setting );
137 
138 	/* Create new generic setting, if required */
139 	if ( len ) {
140 		/* Allocate new generic setting */
141 		name_len = ( strlen ( setting->name ) + 1 );
142 		new = zalloc ( sizeof ( *new ) + name_len + len );
143 		if ( ! new )
144 			return -ENOMEM;
145 
146 		/* Populate new generic setting */
147 		new->name_len = name_len;
148 		new->data_len = len;
149 		memcpy ( &new->setting, setting, sizeof ( new->setting ) );
150 		new->setting.name = generic_setting_name ( new );
151 		memcpy ( generic_setting_name ( new ),
152 			 setting->name, name_len );
153 		memcpy ( generic_setting_data ( new ), data, len );
154 	}
155 
156 	/* Delete existing generic setting, if any */
157 	if ( old ) {
158 		list_del ( &old->list );
159 		free ( old );
160 	}
161 
162 	/* Add new setting to list, if any */
163 	if ( new )
164 		list_add ( &new->list, &generics->list );
165 
166 	return 0;
167 }
168 
169 /**
170  * Fetch value of generic setting
171  *
172  * @v settings		Settings block
173  * @v setting		Setting to fetch
174  * @v data		Buffer to fill with setting data
175  * @v len		Length of buffer
176  * @ret len		Length of setting data, or negative error
177  */
generic_settings_fetch(struct settings * settings,struct setting * setting,void * data,size_t len)178 int generic_settings_fetch ( struct settings *settings,
179 			     struct setting *setting,
180 			     void *data, size_t len ) {
181 	struct generic_settings *generics =
182 		container_of ( settings, struct generic_settings, settings );
183 	struct generic_setting *generic;
184 
185 	/* Find generic setting */
186 	generic = find_generic_setting ( generics, setting );
187 	if ( ! generic )
188 		return -ENOENT;
189 
190 	/* Copy out generic setting data */
191 	if ( len > generic->data_len )
192 		len = generic->data_len;
193 	memcpy ( data, generic_setting_data ( generic ), len );
194 
195 	/* Set setting type, if not yet specified */
196 	if ( ! setting->type )
197 		setting->type = generic->setting.type;
198 
199 	return generic->data_len;
200 }
201 
202 /**
203  * Clear generic settings block
204  *
205  * @v settings		Settings block
206  */
generic_settings_clear(struct settings * settings)207 void generic_settings_clear ( struct settings *settings ) {
208 	struct generic_settings *generics =
209 		container_of ( settings, struct generic_settings, settings );
210 	struct generic_setting *generic;
211 	struct generic_setting *tmp;
212 
213 	list_for_each_entry_safe ( generic, tmp, &generics->list, list ) {
214 		list_del ( &generic->list );
215 		free ( generic );
216 	}
217 	assert ( list_empty ( &generics->list ) );
218 }
219 
220 /** Generic settings operations */
221 struct settings_operations generic_settings_operations = {
222 	.store = generic_settings_store,
223 	.fetch = generic_settings_fetch,
224 	.clear = generic_settings_clear,
225 };
226 
227 /******************************************************************************
228  *
229  * Registered settings blocks
230  *
231  ******************************************************************************
232  */
233 
234 /** Root generic settings block */
235 struct generic_settings generic_settings_root = {
236 	.settings = {
237 		.refcnt = NULL,
238 		.name = "",
239 		.siblings =
240 		    LIST_HEAD_INIT ( generic_settings_root.settings.siblings ),
241 		.children =
242 		    LIST_HEAD_INIT ( generic_settings_root.settings.children ),
243 		.op = &generic_settings_operations,
244 	},
245 	.list = LIST_HEAD_INIT ( generic_settings_root.list ),
246 };
247 
248 /** Root settings block */
249 #define settings_root generic_settings_root.settings
250 
251 /** Autovivified settings block */
252 struct autovivified_settings {
253 	/** Reference count */
254 	struct refcnt refcnt;
255 	/** Generic settings block */
256 	struct generic_settings generic;
257 };
258 
259 /**
260  * Free autovivified settings block
261  *
262  * @v refcnt		Reference count
263  */
autovivified_settings_free(struct refcnt * refcnt)264 static void autovivified_settings_free ( struct refcnt *refcnt ) {
265 	struct autovivified_settings *autovivified =
266 		container_of ( refcnt, struct autovivified_settings, refcnt );
267 
268 	generic_settings_clear ( &autovivified->generic.settings );
269 	free ( autovivified );
270 }
271 
272 /**
273  * Find child settings block
274  *
275  * @v parent		Parent settings block
276  * @v name		Name within this parent
277  * @ret settings	Settings block, or NULL
278  */
find_child_settings(struct settings * parent,const char * name)279 struct settings * find_child_settings ( struct settings *parent,
280 					const char *name ) {
281 	struct settings *settings;
282 
283 	/* Find target parent settings block */
284 	parent = settings_target ( parent );
285 
286 	/* Treat empty name as meaning "this block" */
287 	if ( ! *name )
288 		return parent;
289 
290 	/* Look for child with matching name */
291 	list_for_each_entry ( settings, &parent->children, siblings ) {
292 		if ( strcmp ( settings->name, name ) == 0 )
293 			return settings_target ( settings );
294 	}
295 
296 	return NULL;
297 }
298 
299 /**
300  * Find or create child settings block
301  *
302  * @v parent		Parent settings block
303  * @v name		Name within this parent
304  * @ret settings	Settings block, or NULL
305  */
autovivify_child_settings(struct settings * parent,const char * name)306 struct settings * autovivify_child_settings ( struct settings *parent,
307 					      const char *name ) {
308 	struct {
309 		struct autovivified_settings autovivified;
310 		char name[ strlen ( name ) + 1 /* NUL */ ];
311 	} *new_child;
312 	struct settings *settings;
313 
314 	/* Find target parent settings block */
315 	parent = settings_target ( parent );
316 
317 	/* Return existing settings, if existent */
318 	if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
319 		return settings;
320 
321 	/* Create new generic settings block */
322 	new_child = zalloc ( sizeof ( *new_child ) );
323 	if ( ! new_child ) {
324 		DBGC ( parent, "Settings %p could not create child %s\n",
325 		       parent, name );
326 		return NULL;
327 	}
328 	memcpy ( new_child->name, name, sizeof ( new_child->name ) );
329 	ref_init ( &new_child->autovivified.refcnt,
330 		   autovivified_settings_free );
331 	generic_settings_init ( &new_child->autovivified.generic,
332 				&new_child->autovivified.refcnt );
333 	settings = &new_child->autovivified.generic.settings;
334 	register_settings ( settings, parent, new_child->name );
335 	ref_put ( settings->refcnt );
336 	return settings;
337 }
338 
339 /**
340  * Return settings block name
341  *
342  * @v settings		Settings block
343  * @ret name		Settings block name
344  */
settings_name(struct settings * settings)345 const char * settings_name ( struct settings *settings ) {
346 	static char buf[16];
347 	char tmp[ 1 /* '.' */ + sizeof ( buf ) ];
348 
349 	/* Find target settings block */
350 	settings = settings_target ( settings );
351 
352 	/* Construct name */
353 	buf[0] = '\0';
354 	tmp[0] = '\0';
355 	for ( ; settings->parent ; settings = settings->parent ) {
356 		memcpy ( ( tmp + 1 ), buf, ( sizeof ( tmp ) - 1 ) );
357 		snprintf ( buf, sizeof ( buf ), "%s%s", settings->name, tmp );
358 		tmp[0] = '.';
359 	}
360 	return buf;
361 }
362 
363 /**
364  * Parse settings block name
365  *
366  * @v name		Name
367  * @v get_child		Function to find or create child settings block
368  * @ret settings	Settings block, or NULL
369  */
370 static struct settings *
parse_settings_name(const char * name,get_child_settings_t get_child)371 parse_settings_name ( const char *name, get_child_settings_t get_child ) {
372 	struct settings *settings = &settings_root;
373 	char *name_copy;
374 	char *subname;
375 	char *remainder;
376 
377 	/* Create modifiable copy of name */
378 	name_copy = strdup ( name );
379 	if ( ! name_copy )
380 		return NULL;
381 	remainder = name_copy;
382 
383 	/* Parse each name component in turn */
384 	while ( remainder ) {
385 		subname = remainder;
386 		remainder = strchr ( subname, '.' );
387 		if ( remainder )
388 			*(remainder++) = '\0';
389 		settings = get_child ( settings, subname );
390 		if ( ! settings )
391 			break;
392 	}
393 
394 	/* Free modifiable copy of name */
395 	free ( name_copy );
396 
397 	return settings;
398 }
399 
400 /**
401  * Find settings block
402  *
403  * @v name		Name
404  * @ret settings	Settings block, or NULL
405  */
find_settings(const char * name)406 struct settings * find_settings ( const char *name ) {
407 
408 	return parse_settings_name ( name, find_child_settings );
409 }
410 
411 /**
412  * Apply all settings
413  *
414  * @ret rc		Return status code
415  */
apply_settings(void)416 static int apply_settings ( void ) {
417 	struct settings_applicator *applicator;
418 	int rc;
419 
420 	/* Call all settings applicators */
421 	for_each_table_entry ( applicator, SETTINGS_APPLICATORS ) {
422 		if ( ( rc = applicator->apply() ) != 0 ) {
423 			DBG ( "Could not apply settings using applicator "
424 			      "%p: %s\n", applicator, strerror ( rc ) );
425 			return rc;
426 		}
427 	}
428 
429 	return 0;
430 }
431 
432 /**
433  * Reprioritise settings
434  *
435  * @v settings		Settings block
436  *
437  * Reorders the settings block amongst its siblings according to its
438  * priority.
439  */
reprioritise_settings(struct settings * settings)440 static void reprioritise_settings ( struct settings *settings ) {
441 	struct settings *parent = settings->parent;
442 	long priority;
443 	struct settings *tmp;
444 	long tmp_priority;
445 
446 	/* Stop when we reach the top of the tree */
447 	if ( ! parent )
448 		return;
449 
450 	/* Read priority, if present */
451 	priority = fetch_intz_setting ( settings, &priority_setting );
452 
453 	/* Remove from siblings list */
454 	list_del ( &settings->siblings );
455 
456 	/* Reinsert after any existing blocks which have a higher priority */
457 	list_for_each_entry ( tmp, &parent->children, siblings ) {
458 		tmp_priority = fetch_intz_setting ( tmp, &priority_setting );
459 		if ( priority > tmp_priority )
460 			break;
461 		if ( settings->order > tmp->order )
462 			break;
463 	}
464 	list_add_tail ( &settings->siblings, &tmp->siblings );
465 
466 	/* Recurse up the tree */
467 	reprioritise_settings ( parent );
468 }
469 
470 /**
471  * Register settings block
472  *
473  * @v settings		Settings block
474  * @v parent		Parent settings block, or NULL
475  * @v name		Settings block name
476  * @ret rc		Return status code
477  */
register_settings(struct settings * settings,struct settings * parent,const char * name)478 int register_settings ( struct settings *settings, struct settings *parent,
479 			const char *name ) {
480 	struct settings *old_settings;
481 
482 	/* Sanity check */
483 	assert ( settings != NULL );
484 
485 	/* Find target parent settings block */
486 	parent = settings_target ( parent );
487 
488 	/* Apply settings block name */
489 	settings->name = name;
490 
491 	/* Remove any existing settings with the same name */
492 	if ( ( old_settings = find_child_settings ( parent, settings->name ) ))
493 		unregister_settings ( old_settings );
494 
495 	/* Add to list of settings */
496 	ref_get ( settings->refcnt );
497 	ref_get ( parent->refcnt );
498 	settings->parent = parent;
499 	list_add_tail ( &settings->siblings, &parent->children );
500 	DBGC ( settings, "Settings %p (\"%s\") registered\n",
501 	       settings, settings_name ( settings ) );
502 
503 	/* Fix up settings priority */
504 	reprioritise_settings ( settings );
505 
506 	/* Apply potentially-updated settings */
507 	apply_settings();
508 
509 	return 0;
510 }
511 
512 /**
513  * Unregister settings block
514  *
515  * @v settings		Settings block
516  */
unregister_settings(struct settings * settings)517 void unregister_settings ( struct settings *settings ) {
518 	struct settings *child;
519 
520 	/* Unregister child settings */
521 	while ( ( child = list_first_entry ( &settings->children,
522 					     struct settings, siblings ) ) ) {
523 		unregister_settings ( child );
524 	}
525 
526 	DBGC ( settings, "Settings %p (\"%s\") unregistered\n",
527 	       settings, settings_name ( settings ) );
528 
529 	/* Remove from list of settings */
530 	ref_put ( settings->parent->refcnt );
531 	settings->parent = NULL;
532 	list_del ( &settings->siblings );
533 	ref_put ( settings->refcnt );
534 
535 	/* Apply potentially-updated settings */
536 	apply_settings();
537 }
538 
539 /******************************************************************************
540  *
541  * Core settings routines
542  *
543  ******************************************************************************
544  */
545 
546 /**
547  * Redirect to target settings block
548  *
549  * @v settings		Settings block, or NULL
550  * @ret settings	Underlying settings block
551  */
settings_target(struct settings * settings)552 struct settings * settings_target ( struct settings *settings ) {
553 
554 	/* NULL settings implies the global settings root */
555 	if ( ! settings )
556 		settings = &settings_root;
557 
558 	/* Redirect to underlying settings block, if applicable */
559 	if ( settings->op->redirect )
560 		return settings->op->redirect ( settings );
561 
562 	/* Otherwise, return this settings block */
563 	return settings;
564 }
565 
566 /**
567  * Check applicability of setting
568  *
569  * @v settings		Settings block
570  * @v setting		Setting
571  * @ret applies		Setting applies within this settings block
572  */
setting_applies(struct settings * settings,const struct setting * setting)573 int setting_applies ( struct settings *settings,
574 		      const struct setting *setting ) {
575 
576 	/* Find target settings block */
577 	settings = settings_target ( settings );
578 
579 	/* Check applicability of setting */
580 	return ( settings->op->applies ?
581 		 settings->op->applies ( settings, setting ) : 1 );
582 }
583 
584 /**
585  * Find setting applicable to settings block, if any
586  *
587  * @v settings		Settings block
588  * @v setting		Setting
589  * @ret setting		Applicable setting, if any
590  */
591 static const struct setting *
applicable_setting(struct settings * settings,const struct setting * setting)592 applicable_setting ( struct settings *settings, const struct setting *setting ){
593 	const struct setting *applicable;
594 
595 	/* If setting is already applicable, use it */
596 	if ( setting_applies ( settings, setting ) )
597 		return setting;
598 
599 	/* Otherwise, look for a matching predefined setting which does apply */
600 	for_each_table_entry ( applicable, SETTINGS ) {
601 		if ( ( setting_cmp ( setting, applicable ) == 0 ) &&
602 		     ( setting_applies ( settings, applicable ) ) )
603 			return applicable;
604 	}
605 
606 	return NULL;
607 }
608 
609 /**
610  * Store value of setting
611  *
612  * @v settings		Settings block, or NULL
613  * @v setting		Setting to store
614  * @v data		Setting data, or NULL to clear setting
615  * @v len		Length of setting data
616  * @ret rc		Return status code
617  */
store_setting(struct settings * settings,const struct setting * setting,const void * data,size_t len)618 int store_setting ( struct settings *settings, const struct setting *setting,
619 		    const void *data, size_t len ) {
620 	int rc;
621 
622 	/* Find target settings block */
623 	settings = settings_target ( settings );
624 
625 	/* Fail if setting does not apply to this settings block */
626 	if ( ! setting_applies ( settings, setting ) )
627 		return -ENOTTY;
628 
629 	/* Sanity check */
630 	if ( ! settings->op->store )
631 		return -ENOTSUP;
632 
633 	/* Store setting */
634 	if ( ( rc = settings->op->store ( settings, setting,
635 					  data, len ) ) != 0 )
636 		return rc;
637 
638 	/* Reprioritise settings if necessary */
639 	if ( setting_cmp ( setting, &priority_setting ) == 0 )
640 		reprioritise_settings ( settings );
641 
642 	/* If these settings are registered, apply potentially-updated
643 	 * settings
644 	 */
645 	for ( ; settings ; settings = settings->parent ) {
646 		if ( settings == &settings_root ) {
647 			if ( ( rc = apply_settings() ) != 0 )
648 				return rc;
649 			break;
650 		}
651 	}
652 
653 	return 0;
654 }
655 
656 /**
657  * Fetch setting
658  *
659  * @v settings		Settings block, or NULL to search all blocks
660  * @v setting		Setting to fetch
661  * @v origin		Origin of setting to fill in, or NULL
662  * @v fetched		Fetched setting to fill in, or NULL
663  * @v data		Buffer to fill with setting data
664  * @v len		Length of buffer
665  * @ret len		Length of setting data, or negative error
666  *
667  * The actual length of the setting will be returned even if
668  * the buffer was too small.
669  */
fetch_setting(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,void * data,size_t len)670 int fetch_setting ( struct settings *settings, const struct setting *setting,
671 		    struct settings **origin, struct setting *fetched,
672 		    void *data, size_t len ) {
673 	const struct setting *applicable;
674 	struct settings *child;
675 	struct setting tmp;
676 	int ret;
677 
678 	/* Avoid returning uninitialised data on error */
679 	memset ( data, 0, len );
680 	if ( origin )
681 		*origin = NULL;
682 	if ( fetched )
683 		memcpy ( fetched, setting, sizeof ( *fetched ) );
684 
685 	/* Find target settings block */
686 	settings = settings_target ( settings );
687 
688 	/* Sanity check */
689 	if ( ! settings->op->fetch )
690 		return -ENOTSUP;
691 
692 	/* Try this block first, if an applicable setting exists */
693 	if ( ( applicable = applicable_setting ( settings, setting ) ) ) {
694 
695 		/* Create modifiable copy of setting */
696 		memcpy ( &tmp, applicable, sizeof ( tmp ) );
697 		if ( ( ret = settings->op->fetch ( settings, &tmp,
698 						   data, len ) ) >= 0 ) {
699 
700 			/* Default to string type, if not yet specified */
701 			if ( ! tmp.type )
702 				tmp.type = &setting_type_string;
703 
704 			/* Record origin, if applicable */
705 			if ( origin )
706 				*origin = settings;
707 
708 			/* Record fetched setting, if applicable */
709 			if ( fetched )
710 				memcpy ( fetched, &tmp, sizeof ( *fetched ) );
711 
712 			return ret;
713 		}
714 	}
715 
716 	/* Recurse into each child block in turn */
717 	list_for_each_entry ( child, &settings->children, siblings ) {
718 		if ( ( ret = fetch_setting ( child, setting, origin, fetched,
719 					     data, len ) ) >= 0 )
720 			return ret;
721 	}
722 
723 	return -ENOENT;
724 }
725 
726 /**
727  * Fetch allocated copy of setting
728  *
729  * @v settings		Settings block, or NULL to search all blocks
730  * @v setting		Setting to fetch
731  * @v origin		Origin of setting to fill in, or NULL
732  * @v fetched		Fetched setting to fill in, or NULL
733  * @v data		Buffer to allocate and fill with setting data
734  * @v alloc		Allocation function
735  * @ret len		Length of setting, or negative error
736  *
737  * The caller is responsible for eventually freeing the allocated
738  * buffer.
739  */
fetch_setting_alloc(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,void ** data,void * (* alloc)(size_t len))740 static int fetch_setting_alloc ( struct settings *settings,
741 				 const struct setting *setting,
742 				 struct settings **origin,
743 				 struct setting *fetched,
744 				 void **data,
745 				 void * ( * alloc ) ( size_t len ) ) {
746 	struct settings *tmp_origin;
747 	struct setting tmp_fetched;
748 	int len;
749 	int check_len;
750 
751 	/* Use local buffers if necessary */
752 	if ( ! origin )
753 		origin = &tmp_origin;
754 	if ( ! fetched )
755 		fetched = &tmp_fetched;
756 
757 	/* Avoid returning uninitialised data on error */
758 	*data = NULL;
759 
760 	/* Check existence, and fetch setting length */
761 	len = fetch_setting ( settings, setting, origin, fetched, NULL, 0 );
762 	if ( len < 0 )
763 		return len;
764 
765 	/* Allocate buffer */
766 	*data = alloc ( len );
767 	if ( ! *data )
768 		return -ENOMEM;
769 
770 	/* Fetch setting value */
771 	check_len = fetch_setting ( *origin, fetched, NULL, NULL, *data, len );
772 	assert ( check_len == len );
773 	return len;
774 }
775 
776 /**
777  * Fetch copy of setting
778  *
779  * @v settings		Settings block, or NULL to search all blocks
780  * @v setting		Setting to fetch
781  * @v origin		Origin of setting to fill in, or NULL
782  * @v fetched		Fetched setting to fill in, or NULL
783  * @v data		Buffer to allocate and fill with setting data
784  * @ret len		Length of setting, or negative error
785  *
786  * The caller is responsible for eventually freeing the allocated
787  * buffer.
788  */
fetch_setting_copy(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,void ** data)789 int fetch_setting_copy ( struct settings *settings,
790 			 const struct setting *setting,
791 			 struct settings **origin, struct setting *fetched,
792 			 void **data ) {
793 
794 	return fetch_setting_alloc ( settings, setting, origin, fetched,
795 				     data, malloc );
796 }
797 
798 /**
799  * Fetch value of setting
800  *
801  * @v settings		Settings block, or NULL to search all blocks
802  * @v setting		Setting to fetch
803  * @v data		Buffer to fill with setting string data
804  * @v len		Length of buffer
805  * @ret len		Length of setting, or negative error
806  */
fetch_raw_setting(struct settings * settings,const struct setting * setting,void * data,size_t len)807 int fetch_raw_setting ( struct settings *settings,
808 			const struct setting *setting,
809 			void *data, size_t len ) {
810 
811 	return fetch_setting ( settings, setting, NULL, NULL, data, len );
812 }
813 
814 /**
815  * Fetch value of setting
816  *
817  * @v settings		Settings block, or NULL to search all blocks
818  * @v setting		Setting to fetch
819  * @v data		Buffer to allocate and fill with setting data
820  * @ret len		Length of setting, or negative error
821  *
822  * The caller is responsible for eventually freeing the allocated
823  * buffer.
824  */
fetch_raw_setting_copy(struct settings * settings,const struct setting * setting,void ** data)825 int fetch_raw_setting_copy ( struct settings *settings,
826 			     const struct setting *setting,
827 			     void **data ) {
828 
829 	return fetch_setting_copy ( settings, setting, NULL, NULL, data );
830 }
831 
832 /**
833  * Fetch value of string setting
834  *
835  * @v settings		Settings block, or NULL to search all blocks
836  * @v setting		Setting to fetch
837  * @v data		Buffer to fill with setting string data
838  * @v len		Length of buffer
839  * @ret len		Length of string setting, or negative error
840  *
841  * The resulting string is guaranteed to be correctly NUL-terminated.
842  * The returned length will be the length of the underlying setting
843  * data.
844  */
fetch_string_setting(struct settings * settings,const struct setting * setting,char * data,size_t len)845 int fetch_string_setting ( struct settings *settings,
846 			   const struct setting *setting,
847 			   char *data, size_t len ) {
848 
849 	memset ( data, 0, len );
850 	return fetch_raw_setting ( settings, setting, data,
851 				   ( ( len > 0 ) ? ( len - 1 ) : 0 ) );
852 }
853 
854 /**
855  * Allocate memory for copy of string setting
856  *
857  * @v len		Length of setting
858  * @ret ptr		Allocated memory
859  */
fetch_string_setting_copy_alloc(size_t len)860 static void * fetch_string_setting_copy_alloc ( size_t len ) {
861 	return zalloc ( len + 1 /* NUL */ );
862 }
863 
864 /**
865  * Fetch value of string setting
866  *
867  * @v settings		Settings block, or NULL to search all blocks
868  * @v setting		Setting to fetch
869  * @v data		Buffer to allocate and fill with setting string data
870  * @ret len		Length of string setting, or negative error
871  *
872  * The resulting string is guaranteed to be correctly NUL-terminated.
873  * The returned length will be the length of the underlying setting
874  * data.  The caller is responsible for eventually freeing the
875  * allocated buffer.
876  */
fetch_string_setting_copy(struct settings * settings,const struct setting * setting,char ** data)877 int fetch_string_setting_copy ( struct settings *settings,
878 				const struct setting *setting, char **data ) {
879 
880 	return fetch_setting_alloc ( settings, setting, NULL, NULL,
881 				     ( ( void ** ) data ),
882 				     fetch_string_setting_copy_alloc );
883 }
884 
885 /**
886  * Fetch value of IPv4 address setting
887  *
888  * @v settings		Settings block, or NULL to search all blocks
889  * @v setting		Setting to fetch
890  * @v inp		IPv4 addresses to fill in
891  * @v count		Maximum number of IPv4 addresses
892  * @ret len		Length of setting, or negative error
893  */
fetch_ipv4_array_setting(struct settings * settings,const struct setting * setting,struct in_addr * inp,unsigned int count)894 int fetch_ipv4_array_setting ( struct settings *settings,
895 			       const struct setting *setting,
896 			       struct in_addr *inp, unsigned int count ) {
897 	int len;
898 
899 	len = fetch_raw_setting ( settings, setting, inp,
900 				  ( sizeof ( *inp ) * count ) );
901 	if ( len < 0 )
902 		return len;
903 	if ( ( len % sizeof ( *inp ) ) != 0 )
904 		return -ERANGE;
905 	return len;
906 }
907 
908 /**
909  * Fetch value of IPv4 address setting
910  *
911  * @v settings		Settings block, or NULL to search all blocks
912  * @v setting		Setting to fetch
913  * @v inp		IPv4 address to fill in
914  * @ret len		Length of setting, or negative error
915  */
fetch_ipv4_setting(struct settings * settings,const struct setting * setting,struct in_addr * inp)916 int fetch_ipv4_setting ( struct settings *settings,
917 			 const struct setting *setting,
918 			 struct in_addr *inp ) {
919 
920 	return fetch_ipv4_array_setting ( settings, setting, inp, 1 );
921 }
922 
923 /**
924  * Fetch value of IPv6 address setting
925  *
926  * @v settings		Settings block, or NULL to search all blocks
927  * @v setting		Setting to fetch
928  * @v inp		IPv6 addresses to fill in
929  * @v count		Maximum number of IPv6 addresses
930  * @ret len		Length of setting, or negative error
931  */
fetch_ipv6_array_setting(struct settings * settings,const struct setting * setting,struct in6_addr * inp,unsigned int count)932 int fetch_ipv6_array_setting ( struct settings *settings,
933 			       const struct setting *setting,
934 			       struct in6_addr *inp, unsigned int count ) {
935 	int len;
936 
937 	len = fetch_raw_setting ( settings, setting, inp,
938 				  ( sizeof ( *inp ) * count ) );
939 	if ( len < 0 )
940 		return len;
941 	if ( ( len % sizeof ( *inp ) ) != 0 )
942 		return -ERANGE;
943 	return len;
944 }
945 
946 /**
947  * Fetch value of IPv6 address setting
948  *
949  * @v settings		Settings block, or NULL to search all blocks
950  * @v setting		Setting to fetch
951  * @v inp		IPv6 address to fill in
952  * @ret len		Length of setting, or negative error
953  */
fetch_ipv6_setting(struct settings * settings,const struct setting * setting,struct in6_addr * inp)954 int fetch_ipv6_setting ( struct settings *settings,
955 			 const struct setting *setting,
956 			 struct in6_addr *inp ) {
957 
958 	return fetch_ipv6_array_setting ( settings, setting, inp, 1 );
959 }
960 
961 /**
962  * Extract numeric value of setting
963  *
964  * @v is_signed		Treat value as a signed integer
965  * @v raw		Raw setting data
966  * @v len		Length of raw setting data
967  * @ret value		Numeric value
968  * @ret len		Length of setting, or negative error
969  */
numeric_setting_value(int is_signed,const void * raw,size_t len,unsigned long * value)970 static int numeric_setting_value ( int is_signed, const void *raw, size_t len,
971 				   unsigned long *value ) {
972 	const uint8_t *unsigned_bytes = raw;
973 	const int8_t *signed_bytes = raw;
974 	int is_negative;
975 	unsigned int i;
976 	uint8_t pad;
977 	uint8_t byte;
978 
979 	/* Convert to host-ordered longs */
980 	is_negative = ( len && ( signed_bytes[0] < 0 ) );
981 	*value = ( ( is_signed && is_negative ) ? -1L : 0 );
982 	pad = *value;
983 	for ( i = 0 ; i < len ; i++ ) {
984 		byte = unsigned_bytes[i];
985 		*value = ( ( *value << 8 ) | byte );
986 		if ( ( ( i + sizeof ( *value ) ) < len ) && ( byte != pad ) )
987 			return -ERANGE;
988 	}
989 
990 	return len;
991 }
992 
993 /**
994  * Fetch value of numeric setting
995  *
996  * @v settings		Settings block, or NULL to search all blocks
997  * @v setting		Setting to fetch
998  * @v value		Integer value to fill in
999  * @ret len		Length of setting, or negative error
1000  */
fetch_numeric_setting(struct settings * settings,const struct setting * setting,unsigned long * value,int is_signed)1001 int fetch_numeric_setting ( struct settings *settings,
1002 			    const struct setting *setting,
1003 			    unsigned long *value, int is_signed ) {
1004 	unsigned long tmp;
1005 	int len;
1006 
1007 	/* Avoid returning uninitialised data on error */
1008 	*value = 0;
1009 
1010 	/* Fetch raw (network-ordered, variable-length) setting */
1011 	len = fetch_raw_setting ( settings, setting, &tmp, sizeof ( tmp ) );
1012 	if ( len < 0 )
1013 		return len;
1014 
1015 	/* Extract numeric value */
1016 	return numeric_setting_value ( is_signed, &tmp, len, value );
1017 }
1018 
1019 /**
1020  * Fetch value of signed integer setting
1021  *
1022  * @v settings		Settings block, or NULL to search all blocks
1023  * @v setting		Setting to fetch
1024  * @v value		Integer value to fill in
1025  * @ret len		Length of setting, or negative error
1026  */
fetch_int_setting(struct settings * settings,const struct setting * setting,long * value)1027 int fetch_int_setting ( struct settings *settings,
1028 			const struct setting *setting,
1029 			long *value ) {
1030 
1031 	return fetch_numeric_setting ( settings, setting,
1032 				       ( ( unsigned long * ) value ), 1 );
1033 }
1034 
1035 /**
1036  * Fetch value of unsigned integer setting
1037  *
1038  * @v settings		Settings block, or NULL to search all blocks
1039  * @v setting		Setting to fetch
1040  * @v value		Integer value to fill in
1041  * @ret len		Length of setting, or negative error
1042  */
fetch_uint_setting(struct settings * settings,const struct setting * setting,unsigned long * value)1043 int fetch_uint_setting ( struct settings *settings,
1044 			 const struct setting *setting,
1045 			 unsigned long *value ) {
1046 
1047 	return fetch_numeric_setting ( settings, setting, value, 0 );
1048 }
1049 
1050 /**
1051  * Fetch value of signed integer setting, or zero
1052  *
1053  * @v settings		Settings block, or NULL to search all blocks
1054  * @v setting		Setting to fetch
1055  * @ret value		Setting value, or zero
1056  */
fetch_intz_setting(struct settings * settings,const struct setting * setting)1057 long fetch_intz_setting ( struct settings *settings,
1058 			  const struct setting *setting ) {
1059 	unsigned long value;
1060 
1061 	fetch_numeric_setting ( settings, setting, &value, 1 );
1062 	return value;
1063 }
1064 
1065 /**
1066  * Fetch value of unsigned integer setting, or zero
1067  *
1068  * @v settings		Settings block, or NULL to search all blocks
1069  * @v setting		Setting to fetch
1070  * @ret value		Setting value, or zero
1071  */
fetch_uintz_setting(struct settings * settings,const struct setting * setting)1072 unsigned long fetch_uintz_setting ( struct settings *settings,
1073 				    const struct setting *setting ) {
1074 	unsigned long value;
1075 
1076 	fetch_numeric_setting ( settings, setting, &value, 0 );
1077 	return value;
1078 }
1079 
1080 /**
1081  * Fetch value of UUID setting
1082  *
1083  * @v settings		Settings block, or NULL to search all blocks
1084  * @v setting		Setting to fetch
1085  * @v uuid		UUID to fill in
1086  * @ret len		Length of setting, or negative error
1087  */
fetch_uuid_setting(struct settings * settings,const struct setting * setting,union uuid * uuid)1088 int fetch_uuid_setting ( struct settings *settings,
1089 			 const struct setting *setting,
1090 			 union uuid *uuid ) {
1091 	int len;
1092 
1093 	len = fetch_raw_setting ( settings, setting, uuid, sizeof ( *uuid ) );
1094 	if ( len < 0 )
1095 		return len;
1096 	if ( len != sizeof ( *uuid ) )
1097 		return -ERANGE;
1098 	return len;
1099 }
1100 
1101 /**
1102  * Clear settings block
1103  *
1104  * @v settings		Settings block
1105  */
clear_settings(struct settings * settings)1106 void clear_settings ( struct settings *settings ) {
1107 
1108 	/* Find target settings block */
1109 	settings = settings_target ( settings );
1110 
1111 	/* Clear settings, if applicable */
1112 	if ( settings->op->clear )
1113 		settings->op->clear ( settings );
1114 }
1115 
1116 /**
1117  * Compare two settings
1118  *
1119  * @v a			Setting to compare
1120  * @v b			Setting to compare
1121  * @ret 0		Settings are the same
1122  * @ret non-zero	Settings are not the same
1123  */
setting_cmp(const struct setting * a,const struct setting * b)1124 int setting_cmp ( const struct setting *a, const struct setting *b ) {
1125 
1126 	/* If the settings have tags, compare them */
1127 	if ( a->tag && ( a->tag == b->tag ) && ( a->scope == b->scope ) )
1128 		return 0;
1129 
1130 	/* Otherwise, if the settings have names, compare them */
1131 	if ( a->name && b->name && a->name[0] )
1132 		return strcmp ( a->name, b->name );
1133 
1134 	/* Otherwise, return a non-match */
1135 	return ( ! 0 );
1136 }
1137 
1138 /******************************************************************************
1139  *
1140  * Formatted setting routines
1141  *
1142  ******************************************************************************
1143  */
1144 
1145 /**
1146  * Format setting value as a string
1147  *
1148  * @v type		Setting type
1149  * @v raw		Raw setting value
1150  * @v raw_len		Length of raw setting value
1151  * @v buf		Buffer to contain formatted value
1152  * @v len		Length of buffer
1153  * @ret len		Length of formatted value, or negative error
1154  */
setting_format(const struct setting_type * type,const void * raw,size_t raw_len,char * buf,size_t len)1155 int setting_format ( const struct setting_type *type, const void *raw,
1156 		     size_t raw_len, char *buf, size_t len ) {
1157 
1158 	/* Sanity check */
1159 	if ( ! type->format )
1160 		return -ENOTSUP;
1161 
1162 	return type->format ( type, raw, raw_len, buf, len );
1163 }
1164 
1165 /**
1166  * Parse formatted string to setting value
1167  *
1168  * @v type		Setting type
1169  * @v value		Formatted setting value
1170  * @v buf		Buffer to contain raw value
1171  * @v len		Length of buffer
1172  * @ret len		Length of raw value, or negative error
1173  */
setting_parse(const struct setting_type * type,const char * value,void * buf,size_t len)1174 int setting_parse ( const struct setting_type *type, const char *value,
1175 		    void *buf, size_t len ) {
1176 
1177 	/* Sanity check */
1178 	if ( ! type->parse )
1179 		return -ENOTSUP;
1180 
1181 	return type->parse ( type, value, buf, len );
1182 }
1183 
1184 /**
1185  * Convert setting value to number
1186  *
1187  * @v type		Setting type
1188  * @v raw		Raw setting value
1189  * @v raw_len		Length of raw setting value
1190  * @ret value		Numeric value
1191  * @ret rc		Return status code
1192  */
setting_numerate(const struct setting_type * type,const void * raw,size_t raw_len,unsigned long * value)1193 int setting_numerate ( const struct setting_type *type, const void *raw,
1194 		       size_t raw_len, unsigned long *value ) {
1195 
1196 	/* Sanity check */
1197 	if ( ! type->numerate )
1198 		return -ENOTSUP;
1199 
1200 	return type->numerate ( type, raw, raw_len, value );
1201 }
1202 
1203 /**
1204  * Convert number to setting value
1205  *
1206  * @v type		Setting type
1207  * @v value		Numeric value
1208  * @v buf		Buffer to contain raw value
1209  * @v len		Length of buffer
1210  * @ret len		Length of raw value, or negative error
1211  */
setting_denumerate(const struct setting_type * type,unsigned long value,void * buf,size_t len)1212 int setting_denumerate ( const struct setting_type *type, unsigned long value,
1213 			 void *buf, size_t len ) {
1214 
1215 	/* Sanity check */
1216 	if ( ! type->denumerate )
1217 		return -ENOTSUP;
1218 
1219 	return type->denumerate ( type, value, buf, len );
1220 }
1221 
1222 /**
1223  * Fetch formatted value of setting
1224  *
1225  * @v settings		Settings block, or NULL to search all blocks
1226  * @v setting		Setting to fetch
1227  * @v origin		Origin of setting to fill in, or NULL
1228  * @v fetched		Fetched setting to fill in, or NULL
1229  * @v buf		Buffer to contain formatted value
1230  * @v len		Length of buffer
1231  * @ret len		Length of formatted value, or negative error
1232  */
fetchf_setting(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,char * buf,size_t len)1233 int fetchf_setting ( struct settings *settings, const struct setting *setting,
1234 		     struct settings **origin, struct setting *fetched,
1235 		     char *buf, size_t len ) {
1236 	struct setting tmp_fetched;
1237 	void *raw;
1238 	int raw_len;
1239 	int ret;
1240 
1241 	/* Use local buffers if necessary */
1242 	if ( ! fetched )
1243 		fetched = &tmp_fetched;
1244 
1245 	/* Fetch raw value */
1246 	raw_len = fetch_setting_copy ( settings, setting, origin, fetched,
1247 				       &raw );
1248 	if ( raw_len < 0 ) {
1249 		ret = raw_len;
1250 		goto err_fetch_copy;
1251 	}
1252 
1253 	/* Sanity check */
1254 	assert ( fetched->type != NULL );
1255 
1256 	/* Format setting */
1257 	if ( ( ret = setting_format ( fetched->type, raw, raw_len, buf,
1258 				      len ) ) < 0 )
1259 		goto err_format;
1260 
1261  err_format:
1262 	free ( raw );
1263  err_fetch_copy:
1264 	return ret;
1265 }
1266 
1267 /**
1268  * Fetch copy of formatted value of setting
1269  *
1270  * @v settings		Settings block, or NULL to search all blocks
1271  * @v setting		Setting to fetch
1272  * @v origin		Origin of setting to fill in, or NULL
1273  * @v fetched		Fetched setting to fill in, or NULL
1274  * @v value		Buffer to allocate and fill with formatted value
1275  * @ret len		Length of formatted value, or negative error
1276  *
1277  * The caller is responsible for eventually freeing the allocated
1278  * buffer.
1279  */
fetchf_setting_copy(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,char ** value)1280 int fetchf_setting_copy ( struct settings *settings,
1281 			  const struct setting *setting,
1282 			  struct settings **origin, struct setting *fetched,
1283 			  char **value ) {
1284 	struct settings *tmp_origin;
1285 	struct setting tmp_fetched;
1286 	int len;
1287 	int check_len;
1288 
1289 	/* Use local buffers if necessary */
1290 	if ( ! origin )
1291 		origin = &tmp_origin;
1292 	if ( ! fetched )
1293 		fetched = &tmp_fetched;
1294 
1295 	/* Avoid returning uninitialised data on error */
1296 	*value = NULL;
1297 
1298 	/* Check existence, and fetch formatted value length */
1299 	len = fetchf_setting ( settings, setting, origin, fetched, NULL, 0 );
1300 	if ( len < 0 )
1301 		return len;
1302 
1303 	/* Allocate buffer */
1304 	*value = zalloc ( len + 1 /* NUL */ );
1305 	if ( ! *value )
1306 		return -ENOMEM;
1307 
1308 	/* Fetch formatted value */
1309 	check_len = fetchf_setting ( *origin, fetched, NULL, NULL, *value,
1310 				     ( len + 1 /* NUL */ ) );
1311 	assert ( check_len == len );
1312 	return len;
1313 }
1314 
1315 /**
1316  * Store formatted value of setting
1317  *
1318  * @v settings		Settings block
1319  * @v setting		Setting to store
1320  * @v value		Formatted setting data, or NULL
1321  * @ret rc		Return status code
1322  */
storef_setting(struct settings * settings,const struct setting * setting,const char * value)1323 int storef_setting ( struct settings *settings, const struct setting *setting,
1324 		     const char *value ) {
1325 	void *raw;
1326 	int raw_len;
1327 	int check_len;
1328 	int rc;
1329 
1330 	/* NULL value or empty string implies deletion */
1331 	if ( ( ! value ) || ( ! value[0] ) )
1332 		return delete_setting ( settings, setting );
1333 
1334 	/* Sanity check */
1335 	assert ( setting->type != NULL );
1336 
1337 	/* Get raw value length */
1338 	raw_len = setting_parse ( setting->type, value, NULL, 0 );
1339 	if ( raw_len < 0 ) {
1340 		rc = raw_len;
1341 		goto err_raw_len;
1342 	}
1343 
1344 	/* Allocate buffer for raw value */
1345 	raw = malloc ( raw_len );
1346 	if ( ! raw ) {
1347 		rc = -ENOMEM;
1348 		goto err_alloc_raw;
1349 	}
1350 
1351 	/* Parse formatted value */
1352 	check_len = setting_parse ( setting->type, value, raw, raw_len );
1353 	assert ( check_len == raw_len );
1354 
1355 	/* Store raw value */
1356 	if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
1357 		goto err_store;
1358 
1359  err_store:
1360 	free ( raw );
1361  err_alloc_raw:
1362  err_raw_len:
1363 	return rc;
1364 }
1365 
1366 /**
1367  * Fetch numeric value of setting
1368  *
1369  * @v settings		Settings block, or NULL to search all blocks
1370  * @v setting		Setting to fetch
1371  * @v origin		Origin of setting to fill in, or NULL
1372  * @v fetched		Fetched setting to fill in, or NULL
1373  * @v value		Numeric value to fill in
1374  * @ret rc		Return status code
1375  */
fetchn_setting(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,unsigned long * value)1376 int fetchn_setting ( struct settings *settings, const struct setting *setting,
1377 		     struct settings **origin, struct setting *fetched,
1378 		     unsigned long *value ) {
1379 	struct setting tmp_fetched;
1380 	void *raw;
1381 	int raw_len;
1382 	int rc;
1383 
1384 	/* Use local buffers if necessary */
1385 	if ( ! fetched )
1386 		fetched = &tmp_fetched;
1387 
1388 	/* Fetch raw value */
1389 	raw_len = fetch_setting_copy ( settings, setting, origin, fetched,
1390 				       &raw );
1391 	if ( raw_len < 0 ) {
1392 		rc = raw_len;
1393 		goto err_fetch_copy;
1394 	}
1395 
1396 	/* Sanity check */
1397 	assert ( fetched->type != NULL );
1398 
1399 	/* Numerate setting */
1400 	if ( ( rc = setting_numerate ( fetched->type, raw, raw_len,
1401 				       value ) ) < 0 )
1402 		goto err_numerate;
1403 
1404  err_numerate:
1405 	free ( raw );
1406  err_fetch_copy:
1407 	return rc;
1408 }
1409 
1410 /**
1411  * Store numeric value of setting
1412  *
1413  * @v settings		Settings block
1414  * @v setting		Setting
1415  * @v value		Numeric value
1416  * @ret rc		Return status code
1417  */
storen_setting(struct settings * settings,const struct setting * setting,unsigned long value)1418 int storen_setting ( struct settings *settings, const struct setting *setting,
1419 		     unsigned long value ) {
1420 	void *raw;
1421 	int raw_len;
1422 	int check_len;
1423 	int rc;
1424 
1425 	/* Sanity check */
1426 	assert ( setting->type != NULL );
1427 
1428 	/* Get raw value length */
1429 	raw_len = setting_denumerate ( setting->type, value, NULL, 0 );
1430 	if ( raw_len < 0 ) {
1431 		rc = raw_len;
1432 		goto err_raw_len;
1433 	}
1434 
1435 	/* Allocate buffer for raw value */
1436 	raw = malloc ( raw_len );
1437 	if ( ! raw ) {
1438 		rc = -ENOMEM;
1439 		goto err_alloc_raw;
1440 	}
1441 
1442 	/* Denumerate value */
1443 	check_len = setting_denumerate ( setting->type, value, raw, raw_len );
1444 	assert ( check_len == raw_len );
1445 
1446 	/* Store raw value */
1447 	if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
1448 		goto err_store;
1449 
1450  err_store:
1451 	free ( raw );
1452  err_alloc_raw:
1453  err_raw_len:
1454 	return rc;
1455 }
1456 
1457 /******************************************************************************
1458  *
1459  * Named settings
1460  *
1461  ******************************************************************************
1462  */
1463 
1464 /**
1465  * Find predefined setting
1466  *
1467  * @v name		Name
1468  * @ret setting		Setting, or NULL
1469  */
find_setting(const char * name)1470 struct setting * find_setting ( const char *name ) {
1471 	struct setting *setting;
1472 
1473 	for_each_table_entry ( setting, SETTINGS ) {
1474 		if ( strcmp ( name, setting->name ) == 0 )
1475 			return setting;
1476 	}
1477 	return NULL;
1478 }
1479 
1480 /**
1481  * Parse setting name as tag number
1482  *
1483  * @v name		Name
1484  * @ret tag		Tag number, or 0 if not a valid number
1485  */
parse_setting_tag(const char * name)1486 static uint64_t parse_setting_tag ( const char *name ) {
1487 	char *tmp = ( ( char * ) name );
1488 	uint64_t tag = 0;
1489 
1490 	while ( 1 ) {
1491 		tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
1492 		if ( *tmp == 0 )
1493 			return tag;
1494 		if ( *tmp != '.' )
1495 			return 0;
1496 		tmp++;
1497 	}
1498 }
1499 
1500 /**
1501  * Find setting type
1502  *
1503  * @v name		Name
1504  * @ret type		Setting type, or NULL
1505  */
find_setting_type(const char * name)1506 static const struct setting_type * find_setting_type ( const char *name ) {
1507 	const struct setting_type *type;
1508 
1509 	for_each_table_entry ( type, SETTING_TYPES ) {
1510 		if ( strcmp ( name, type->name ) == 0 )
1511 			return type;
1512 	}
1513 	return NULL;
1514 }
1515 
1516 /**
1517  * Parse setting name
1518  *
1519  * @v name		Name of setting
1520  * @v get_child		Function to find or create child settings block
1521  * @v settings		Settings block to fill in
1522  * @v setting		Setting to fill in
1523  * @ret rc		Return status code
1524  *
1525  * Interprets a name of the form
1526  * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
1527  * fields.
1528  *
1529  * Note that on success, this function will have modified the original
1530  * setting @c name.
1531  */
parse_setting_name(char * name,get_child_settings_t get_child,struct settings ** settings,struct setting * setting)1532 int parse_setting_name ( char *name, get_child_settings_t get_child,
1533 			 struct settings **settings, struct setting *setting ) {
1534 	char *settings_name;
1535 	char *setting_name;
1536 	char *type_name;
1537 	struct setting *predefined;
1538 	int rc;
1539 
1540 	/* Set defaults */
1541 	*settings = &settings_root;
1542 	memset ( setting, 0, sizeof ( *setting ) );
1543 	setting->name = "";
1544 
1545 	/* Split name into "[settings_name/]setting_name[:type_name]" */
1546 	if ( ( setting_name = strchr ( name, '/' ) ) != NULL ) {
1547 		*(setting_name++) = 0;
1548 		settings_name = name;
1549 	} else {
1550 		setting_name = name;
1551 		settings_name = NULL;
1552 	}
1553 	if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
1554 		*(type_name++) = 0;
1555 
1556 	/* Identify settings block, if specified */
1557 	if ( settings_name ) {
1558 		*settings = parse_settings_name ( settings_name, get_child );
1559 		if ( *settings == NULL ) {
1560 			DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
1561 			      settings_name, name );
1562 			rc = -ENODEV;
1563 			goto err;
1564 		}
1565 	}
1566 
1567 	/* Identify setting */
1568 	setting->tag = parse_setting_tag ( setting_name );
1569 	setting->scope = (*settings)->default_scope;
1570 	setting->name = setting_name;
1571 	for_each_table_entry ( predefined, SETTINGS ) {
1572 		/* Matches a predefined setting; use that setting */
1573 		if ( setting_cmp ( predefined, setting ) == 0 ) {
1574 			memcpy ( setting, predefined, sizeof ( *setting ) );
1575 			break;
1576 		}
1577 	}
1578 
1579 	/* Identify setting type, if specified */
1580 	if ( type_name ) {
1581 		setting->type = find_setting_type ( type_name );
1582 		if ( setting->type == NULL ) {
1583 			DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
1584 			      type_name, name );
1585 			rc = -ENOTSUP;
1586 			goto err;
1587 		}
1588 	}
1589 
1590 	return 0;
1591 
1592  err:
1593 	/* Restore original name */
1594 	if ( settings_name )
1595 		*( setting_name - 1 ) = '/';
1596 	if ( type_name )
1597 		*( type_name - 1 ) = ':';
1598 	return rc;
1599 }
1600 
1601 /**
1602  * Return full setting name
1603  *
1604  * @v settings		Settings block, or NULL
1605  * @v setting		Setting
1606  * @v buf		Buffer
1607  * @v len		Length of buffer
1608  * @ret len		Length of setting name, or negative error
1609  */
setting_name(struct settings * settings,const struct setting * setting,char * buf,size_t len)1610 int setting_name ( struct settings *settings, const struct setting *setting,
1611 		   char *buf, size_t len ) {
1612 	const char *name;
1613 
1614 	settings = settings_target ( settings );
1615 	name = settings_name ( settings );
1616 	return snprintf ( buf, len, "%s%s%s:%s", name, ( name[0] ? "/" : "" ),
1617 			  setting->name, setting->type->name );
1618 }
1619 
1620 /******************************************************************************
1621  *
1622  * Setting types
1623  *
1624  ******************************************************************************
1625  */
1626 
1627 /**
1628  * Parse string setting value
1629  *
1630  * @v type		Setting type
1631  * @v value		Formatted setting value
1632  * @v buf		Buffer to contain raw value
1633  * @v len		Length of buffer
1634  * @ret len		Length of raw value, or negative error
1635  */
parse_string_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)1636 static int parse_string_setting ( const struct setting_type *type __unused,
1637 				  const char *value, void *buf, size_t len ) {
1638 	size_t raw_len = strlen ( value ); /* Exclude terminating NUL */
1639 
1640 	/* Copy string to buffer */
1641 	if ( len > raw_len )
1642 		len = raw_len;
1643 	memcpy ( buf, value, len );
1644 
1645 	return raw_len;
1646 }
1647 
1648 /**
1649  * Format string setting value
1650  *
1651  * @v type		Setting type
1652  * @v raw		Raw setting value
1653  * @v raw_len		Length of raw setting value
1654  * @v buf		Buffer to contain formatted value
1655  * @v len		Length of buffer
1656  * @ret len		Length of formatted value, or negative error
1657  */
format_string_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)1658 static int format_string_setting ( const struct setting_type *type __unused,
1659 				   const void *raw, size_t raw_len, char *buf,
1660 				   size_t len ) {
1661 
1662 	/* Copy string to buffer, and terminate */
1663 	memset ( buf, 0, len );
1664 	if ( len > raw_len )
1665 		len = raw_len;
1666 	memcpy ( buf, raw, len );
1667 
1668 	return raw_len;
1669 }
1670 
1671 /** A string setting type */
1672 const struct setting_type setting_type_string __setting_type = {
1673 	.name = "string",
1674 	.parse = parse_string_setting,
1675 	.format = format_string_setting,
1676 };
1677 
1678 /**
1679  * Parse URI-encoded string setting value
1680  *
1681  * @v type		Setting type
1682  * @v value		Formatted setting value
1683  * @v buf		Buffer to contain raw value
1684  * @v len		Length of buffer
1685  * @ret len		Length of raw value, or negative error
1686  */
parse_uristring_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)1687 static int parse_uristring_setting ( const struct setting_type *type __unused,
1688 				     const char *value, void *buf, size_t len ){
1689 
1690 	return uri_decode ( value, buf, len );
1691 }
1692 
1693 /**
1694  * Format URI-encoded string setting value
1695  *
1696  * @v type		Setting type
1697  * @v raw		Raw setting value
1698  * @v raw_len		Length of raw setting value
1699  * @v buf		Buffer to contain formatted value
1700  * @v len		Length of buffer
1701  * @ret len		Length of formatted value, or negative error
1702  */
format_uristring_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)1703 static int format_uristring_setting ( const struct setting_type *type __unused,
1704 				      const void *raw, size_t raw_len,
1705 				      char *buf, size_t len ) {
1706 
1707 	return uri_encode ( 0, raw, raw_len, buf, len );
1708 }
1709 
1710 /** A URI-encoded string setting type */
1711 const struct setting_type setting_type_uristring __setting_type = {
1712 	.name = "uristring",
1713 	.parse = parse_uristring_setting,
1714 	.format = format_uristring_setting,
1715 };
1716 
1717 /**
1718  * Parse IPv4 address setting value (when IPv4 support is not present)
1719  *
1720  * @v type		Setting type
1721  * @v value		Formatted setting value
1722  * @v buf		Buffer to contain raw value
1723  * @v len		Length of buffer
1724  * @ret len		Length of raw value, or negative error
1725  */
parse_ipv4_setting(const struct setting_type * type __unused,const char * value __unused,void * buf __unused,size_t len __unused)1726 __weak int parse_ipv4_setting ( const struct setting_type *type __unused,
1727 				const char *value __unused, void *buf __unused,
1728 				size_t len __unused ) {
1729 	return -ENOTSUP;
1730 }
1731 
1732 /**
1733  * Format IPv4 address setting value (when IPv4 support is not present)
1734  *
1735  * @v type		Setting type
1736  * @v raw		Raw setting value
1737  * @v raw_len		Length of raw setting value
1738  * @v buf		Buffer to contain formatted value
1739  * @v len		Length of buffer
1740  * @ret len		Length of formatted value, or negative error
1741  */
format_ipv4_setting(const struct setting_type * type __unused,const void * raw __unused,size_t raw_len __unused,char * buf __unused,size_t len __unused)1742 __weak int format_ipv4_setting ( const struct setting_type *type __unused,
1743 				 const void *raw __unused,
1744 				 size_t raw_len __unused, char *buf __unused,
1745 				 size_t len __unused ) {
1746 	return -ENOTSUP;
1747 }
1748 
1749 /** An IPv4 address setting type */
1750 const struct setting_type setting_type_ipv4 __setting_type = {
1751 	.name = "ipv4",
1752 	.parse = parse_ipv4_setting,
1753 	.format = format_ipv4_setting,
1754 };
1755 
1756 /**
1757  * Parse IPv6 address setting value (when IPv6 support is not present)
1758  *
1759  * @v type		Setting type
1760  * @v value		Formatted setting value
1761  * @v buf		Buffer to contain raw value
1762  * @v len		Length of buffer
1763  * @ret len		Length of raw value, or negative error
1764  */
parse_ipv6_setting(const struct setting_type * type __unused,const char * value __unused,void * buf __unused,size_t len __unused)1765 __weak int parse_ipv6_setting ( const struct setting_type *type __unused,
1766 				const char *value __unused, void *buf __unused,
1767 				size_t len __unused ) {
1768 	return -ENOTSUP;
1769 }
1770 
1771 /**
1772  * Format IPv6 address setting value (when IPv6 support is not present)
1773  *
1774  * @v type		Setting type
1775  * @v raw		Raw setting value
1776  * @v raw_len		Length of raw setting value
1777  * @v buf		Buffer to contain formatted value
1778  * @v len		Length of buffer
1779  * @ret len		Length of formatted value, or negative error
1780  */
format_ipv6_setting(const struct setting_type * type __unused,const void * raw __unused,size_t raw_len __unused,char * buf __unused,size_t len __unused)1781 __weak int format_ipv6_setting ( const struct setting_type *type __unused,
1782 				 const void *raw __unused,
1783 				 size_t raw_len __unused, char *buf __unused,
1784 				 size_t len __unused ) {
1785 	return -ENOTSUP;
1786 }
1787 
1788 /** An IPv6 address setting type */
1789 const struct setting_type setting_type_ipv6 __setting_type = {
1790 	.name = "ipv6",
1791 	.parse = parse_ipv6_setting,
1792 	.format = format_ipv6_setting,
1793 };
1794 
1795 /** IPv6 settings scope */
1796 const struct settings_scope dhcpv6_scope;
1797 
1798 /**
1799  * Integer setting type indices
1800  *
1801  * These indexes are defined such that (1<<index) gives the width of
1802  * the integer, in bytes.
1803  */
1804 enum setting_type_int_index {
1805 	SETTING_TYPE_INT8 = 0,
1806 	SETTING_TYPE_INT16 = 1,
1807 	SETTING_TYPE_INT32 = 2,
1808 };
1809 
1810 /**
1811  * Integer setting type names
1812  *
1813  * These names exist as a static array in order to allow the type's
1814  * integer size and signedness to be determined from the type's name.
1815  * Note that there are no separate entries for the signed integer
1816  * types: the name pointers simply point to the second character of
1817  * the relevant string.
1818  */
1819 static const char setting_type_int_name[][8] = {
1820 	[SETTING_TYPE_INT8] = "uint8",
1821 	[SETTING_TYPE_INT16] = "uint16",
1822 	[SETTING_TYPE_INT32] = "uint32",
1823 };
1824 
1825 /**
1826  * Get unsigned integer setting type name
1827  *
1828  * @v index		Integer setting type index
1829  * @ret name		Setting type name
1830  */
1831 #define SETTING_TYPE_UINT_NAME( index ) setting_type_int_name[index]
1832 
1833 /**
1834  * Get signed integer setting type name
1835  *
1836  * @v index		Integer setting type index
1837  * @ret name		Setting type name
1838  */
1839 #define SETTING_TYPE_INT_NAME( index ) ( setting_type_int_name[index] + 1 )
1840 
1841 /**
1842  * Get integer setting type index
1843  *
1844  * @v type		Setting type
1845  * @ret index		Integer setting type index
1846  */
setting_type_int_index(const struct setting_type * type)1847 static unsigned int setting_type_int_index ( const struct setting_type *type ) {
1848 
1849 	return ( ( type->name - setting_type_int_name[0] ) /
1850 		 sizeof ( setting_type_int_name[0] ) );
1851 }
1852 
1853 /**
1854  * Get integer setting type width
1855  *
1856  * @v type		Setting type
1857  * @ret index		Integer setting type width
1858  */
setting_type_int_width(const struct setting_type * type)1859 static unsigned int setting_type_int_width ( const struct setting_type *type ) {
1860 
1861 	return ( 1 << setting_type_int_index ( type ) );
1862 }
1863 
1864 /**
1865  * Get integer setting type signedness
1866  *
1867  * @v type		Setting type
1868  * @ret is_signed	Integer setting type is signed
1869  */
setting_type_int_is_signed(const struct setting_type * type)1870 static int setting_type_int_is_signed ( const struct setting_type *type ) {
1871 	return ( ( type->name - setting_type_int_name[0] ) & 1 );
1872 }
1873 
1874 /**
1875  * Convert number to setting value
1876  *
1877  * @v type		Setting type
1878  * @v value		Numeric value
1879  * @v buf		Buffer to contain raw value
1880  * @v len		Length of buffer
1881  * @ret len		Length of raw value, or negative error
1882  */
denumerate_int_setting(const struct setting_type * type,unsigned long value,void * buf,size_t len)1883 static int denumerate_int_setting ( const struct setting_type *type,
1884 				    unsigned long value, void *buf,
1885 				    size_t len ) {
1886 	unsigned int size = setting_type_int_width ( type );
1887 	union {
1888 		uint32_t num;
1889 		uint8_t bytes[4];
1890 	} u;
1891 
1892 	u.num = htonl ( value );
1893 	if ( len > size )
1894 		len = size;
1895 	memcpy ( buf, &u.bytes[ sizeof ( u ) - size ], len );
1896 
1897 	return size;
1898 }
1899 
1900 /**
1901  * Convert setting value to number
1902  *
1903  * @v type		Setting type
1904  * @v raw		Raw setting value
1905  * @v raw_len		Length of raw setting value
1906  * @v value		Numeric value to fill in
1907  * @ret rc		Return status code
1908  */
numerate_int_setting(const struct setting_type * type,const void * raw,size_t raw_len,unsigned long * value)1909 static int numerate_int_setting ( const struct setting_type *type,
1910 				  const void *raw, size_t raw_len,
1911 				  unsigned long *value ) {
1912 	int is_signed = setting_type_int_is_signed ( type );
1913 	int check_len;
1914 
1915 	/* Extract numeric value */
1916 	check_len = numeric_setting_value ( is_signed, raw, raw_len, value );
1917 	if ( check_len < 0 )
1918 		return check_len;
1919 	assert ( check_len == ( int ) raw_len );
1920 
1921 	return 0;
1922 }
1923 
1924 /**
1925  * Parse integer setting value
1926  *
1927  * @v type		Setting type
1928  * @v value		Formatted setting value
1929  * @v buf		Buffer to contain raw value
1930  * @v len		Length of buffer
1931  * @ret len		Length of raw value, or negative error
1932  */
parse_int_setting(const struct setting_type * type,const char * value,void * buf,size_t len)1933 static int parse_int_setting ( const struct setting_type *type,
1934 			       const char *value, void *buf, size_t len ) {
1935 	char *endp;
1936 	unsigned long num_value;
1937 
1938 	/* Parse value */
1939 	num_value = strtoul ( value, &endp, 0 );
1940 	if ( *endp )
1941 		return -EINVAL;
1942 
1943 	return type->denumerate ( type, num_value, buf, len );
1944 }
1945 
1946 /**
1947  * Format signed integer setting value
1948  *
1949  * @v type		Setting type
1950  * @v raw		Raw setting value
1951  * @v raw_len		Length of raw setting value
1952  * @v buf		Buffer to contain formatted value
1953  * @v len		Length of buffer
1954  * @ret len		Length of formatted value, or negative error
1955  */
format_int_setting(const struct setting_type * type,const void * raw,size_t raw_len,char * buf,size_t len)1956 static int format_int_setting ( const struct setting_type *type,
1957 				const void *raw, size_t raw_len,
1958 				char *buf, size_t len ) {
1959 	unsigned long value;
1960 	int ret;
1961 
1962 	/* Extract numeric value */
1963 	if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 )
1964 		return ret;
1965 
1966 	/* Format value */
1967 	return snprintf ( buf, len, "%ld", value );
1968 }
1969 
1970 /**
1971  * Format unsigned integer setting value
1972  *
1973  * @v type		Setting type
1974  * @v raw		Raw setting value
1975  * @v raw_len		Length of raw setting value
1976  * @v buf		Buffer to contain formatted value
1977  * @v len		Length of buffer
1978  * @ret len		Length of formatted value, or negative error
1979  */
format_uint_setting(const struct setting_type * type,const void * raw,size_t raw_len,char * buf,size_t len)1980 static int format_uint_setting ( const struct setting_type *type,
1981 				 const void *raw, size_t raw_len,
1982 				 char *buf, size_t len ) {
1983 	unsigned long value;
1984 	int ret;
1985 
1986 	/* Extract numeric value */
1987 	if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 )
1988 		return ret;
1989 
1990 	/* Format value */
1991 	return snprintf ( buf, len, "%#lx", value );
1992 }
1993 
1994 /**
1995  * Define a signed integer setting type
1996  *
1997  * @v index		Integer setting type index
1998  * @ret type		Setting type
1999  */
2000 #define SETTING_TYPE_INT( index ) {				\
2001 	.name = SETTING_TYPE_INT_NAME ( index ),		\
2002 	.parse = parse_int_setting,				\
2003 	.format = format_int_setting,				\
2004 	.denumerate = denumerate_int_setting,			\
2005 	.numerate = numerate_int_setting,			\
2006 }
2007 
2008 /**
2009  * Define an unsigned integer setting type
2010  *
2011  * @v index		Integer setting type index
2012  * @ret type		Setting type
2013  */
2014 #define SETTING_TYPE_UINT( index ) {				\
2015 	.name = SETTING_TYPE_UINT_NAME ( index ),		\
2016 	.parse = parse_int_setting,				\
2017 	.format = format_uint_setting,				\
2018 	.denumerate = denumerate_int_setting,			\
2019 	.numerate = numerate_int_setting,			\
2020 }
2021 
2022 /** A signed 8-bit integer setting type */
2023 const struct setting_type setting_type_int8 __setting_type =
2024 	SETTING_TYPE_INT ( SETTING_TYPE_INT8 );
2025 
2026 /** A signed 16-bit integer setting type */
2027 const struct setting_type setting_type_int16 __setting_type =
2028 	SETTING_TYPE_INT ( SETTING_TYPE_INT16 );
2029 
2030 /** A signed 32-bit integer setting type */
2031 const struct setting_type setting_type_int32 __setting_type =
2032 	SETTING_TYPE_INT ( SETTING_TYPE_INT32 );
2033 
2034 /** An unsigned 8-bit integer setting type */
2035 const struct setting_type setting_type_uint8 __setting_type =
2036 	SETTING_TYPE_UINT ( SETTING_TYPE_INT8 );
2037 
2038 /** An unsigned 16-bit integer setting type */
2039 const struct setting_type setting_type_uint16 __setting_type =
2040 	SETTING_TYPE_UINT ( SETTING_TYPE_INT16 );
2041 
2042 /** An unsigned 32-bit integer setting type */
2043 const struct setting_type setting_type_uint32 __setting_type =
2044 	SETTING_TYPE_UINT ( SETTING_TYPE_INT32 );
2045 
2046 /**
2047  * Parse hex string setting value (using colon delimiter)
2048  *
2049  * @v type		Setting type
2050  * @v value		Formatted setting value
2051  * @v buf		Buffer to contain raw value
2052  * @v len		Length of buffer
2053  * @v size		Integer size, in bytes
2054  * @ret len		Length of raw value, or negative error
2055  */
parse_hex_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)2056 static int parse_hex_setting ( const struct setting_type *type __unused,
2057 			       const char *value, void *buf, size_t len ) {
2058 	return hex_decode ( ':', value, buf, len );
2059 }
2060 
2061 /**
2062  * Format hex string setting value (using colon delimiter)
2063  *
2064  * @v type		Setting type
2065  * @v raw		Raw setting value
2066  * @v raw_len		Length of raw setting value
2067  * @v buf		Buffer to contain formatted value
2068  * @v len		Length of buffer
2069  * @ret len		Length of formatted value, or negative error
2070  */
format_hex_colon_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2071 static int format_hex_colon_setting ( const struct setting_type *type __unused,
2072 				      const void *raw, size_t raw_len,
2073 				      char *buf, size_t len ) {
2074 	return hex_encode ( ':', raw, raw_len, buf, len );
2075 }
2076 
2077 /**
2078  * Parse hex string setting value (using hyphen delimiter)
2079  *
2080  * @v type		Setting type
2081  * @v value		Formatted setting value
2082  * @v buf		Buffer to contain raw value
2083  * @v len		Length of buffer
2084  * @v size		Integer size, in bytes
2085  * @ret len		Length of raw value, or negative error
2086  */
parse_hex_hyphen_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)2087 static int parse_hex_hyphen_setting ( const struct setting_type *type __unused,
2088 				      const char *value, void *buf,
2089 				      size_t len ) {
2090 	return hex_decode ( '-', value, buf, len );
2091 }
2092 
2093 /**
2094  * Format hex string setting value (using hyphen delimiter)
2095  *
2096  * @v type		Setting type
2097  * @v raw		Raw setting value
2098  * @v raw_len		Length of raw setting value
2099  * @v buf		Buffer to contain formatted value
2100  * @v len		Length of buffer
2101  * @ret len		Length of formatted value, or negative error
2102  */
format_hex_hyphen_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2103 static int format_hex_hyphen_setting ( const struct setting_type *type __unused,
2104 				       const void *raw, size_t raw_len,
2105 				       char *buf, size_t len ) {
2106 	return hex_encode ( '-', raw, raw_len, buf, len );
2107 }
2108 
2109 /**
2110  * Parse hex string setting value (using no delimiter)
2111  *
2112  * @v type		Setting type
2113  * @v value		Formatted setting value
2114  * @v buf		Buffer to contain raw value
2115  * @v len		Length of buffer
2116  * @v size		Integer size, in bytes
2117  * @ret len		Length of raw value, or negative error
2118  */
parse_hex_raw_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)2119 static int parse_hex_raw_setting ( const struct setting_type *type __unused,
2120 				   const char *value, void *buf, size_t len ) {
2121 	return hex_decode ( 0, value, buf, len );
2122 }
2123 
2124 /**
2125  * Format hex string setting value (using no delimiter)
2126  *
2127  * @v type		Setting type
2128  * @v raw		Raw setting value
2129  * @v raw_len		Length of raw setting value
2130  * @v buf		Buffer to contain formatted value
2131  * @v len		Length of buffer
2132  * @ret len		Length of formatted value, or negative error
2133  */
format_hex_raw_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2134 static int format_hex_raw_setting ( const struct setting_type *type __unused,
2135 				    const void *raw, size_t raw_len,
2136 				    char *buf, size_t len ) {
2137 	return hex_encode ( 0, raw, raw_len, buf, len );
2138 }
2139 
2140 /** A hex-string setting (colon-delimited) */
2141 const struct setting_type setting_type_hex __setting_type = {
2142 	.name = "hex",
2143 	.parse = parse_hex_setting,
2144 	.format = format_hex_colon_setting,
2145 };
2146 
2147 /** A hex-string setting (hyphen-delimited) */
2148 const struct setting_type setting_type_hexhyp __setting_type = {
2149 	.name = "hexhyp",
2150 	.parse = parse_hex_hyphen_setting,
2151 	.format = format_hex_hyphen_setting,
2152 };
2153 
2154 /** A hex-string setting (non-delimited) */
2155 const struct setting_type setting_type_hexraw __setting_type = {
2156 	.name = "hexraw",
2157 	.parse = parse_hex_raw_setting,
2158 	.format = format_hex_raw_setting,
2159 };
2160 
2161 /**
2162  * Parse Base64-encoded setting value
2163  *
2164  * @v type		Setting type
2165  * @v value		Formatted setting value
2166  * @v buf		Buffer to contain raw value
2167  * @v len		Length of buffer
2168  * @v size		Integer size, in bytes
2169  * @ret len		Length of raw value, or negative error
2170  */
parse_base64_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)2171 static int parse_base64_setting ( const struct setting_type *type __unused,
2172 				  const char *value, void *buf, size_t len ) {
2173 
2174 	return base64_decode ( value, buf, len );
2175 }
2176 
2177 /**
2178  * Format Base64-encoded setting value
2179  *
2180  * @v type		Setting type
2181  * @v raw		Raw setting value
2182  * @v raw_len		Length of raw setting value
2183  * @v buf		Buffer to contain formatted value
2184  * @v len		Length of buffer
2185  * @ret len		Length of formatted value, or negative error
2186  */
format_base64_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2187 static int format_base64_setting ( const struct setting_type *type __unused,
2188 				   const void *raw, size_t raw_len,
2189 				   char *buf, size_t len ) {
2190 
2191 	return base64_encode ( raw, raw_len, buf, len );
2192 }
2193 
2194 /** A Base64-encoded setting */
2195 const struct setting_type setting_type_base64 __setting_type = {
2196 	.name = "base64",
2197 	.parse = parse_base64_setting,
2198 	.format = format_base64_setting,
2199 };
2200 
2201 /**
2202  * Format UUID setting value
2203  *
2204  * @v type		Setting type
2205  * @v raw		Raw setting value
2206  * @v raw_len		Length of raw setting value
2207  * @v buf		Buffer to contain formatted value
2208  * @v len		Length of buffer
2209  * @ret len		Length of formatted value, or negative error
2210  */
format_uuid_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2211 static int format_uuid_setting ( const struct setting_type *type __unused,
2212 				 const void *raw, size_t raw_len, char *buf,
2213 				 size_t len ) {
2214 	const union uuid *uuid = raw;
2215 
2216 	/* Range check */
2217 	if ( raw_len != sizeof ( *uuid ) )
2218 		return -ERANGE;
2219 
2220 	/* Format value */
2221 	return snprintf ( buf, len, "%s", uuid_ntoa ( uuid ) );
2222 }
2223 
2224 /** UUID setting type */
2225 const struct setting_type setting_type_uuid __setting_type = {
2226 	.name = "uuid",
2227 	.format = format_uuid_setting,
2228 };
2229 
2230 /**
2231  * Format PCI bus:dev.fn setting value
2232  *
2233  * @v type		Setting type
2234  * @v raw		Raw setting value
2235  * @v raw_len		Length of raw setting value
2236  * @v buf		Buffer to contain formatted value
2237  * @v len		Length of buffer
2238  * @ret len		Length of formatted value, or negative error
2239  */
format_busdevfn_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2240 static int format_busdevfn_setting ( const struct setting_type *type __unused,
2241 				     const void *raw, size_t raw_len, char *buf,
2242 				     size_t len ) {
2243 	unsigned long busdevfn;
2244 	unsigned int seg;
2245 	unsigned int bus;
2246 	unsigned int slot;
2247 	unsigned int func;
2248 	int check_len;
2249 
2250 	/* Extract numeric value */
2251 	check_len = numeric_setting_value ( 0, raw, raw_len, &busdevfn );
2252 	if ( check_len < 0 )
2253 		return check_len;
2254 	assert ( check_len == ( int ) raw_len );
2255 
2256 	/* Extract PCI address components */
2257 	seg = PCI_SEG ( busdevfn );
2258 	bus = PCI_BUS ( busdevfn );
2259 	slot = PCI_SLOT ( busdevfn );
2260 	func = PCI_FUNC ( busdevfn );
2261 
2262 	/* Format value */
2263 	return snprintf ( buf, len, "%04x:%02x:%02x.%x", seg, bus, slot, func );
2264 }
2265 
2266 /** PCI bus:dev.fn setting type */
2267 const struct setting_type setting_type_busdevfn __setting_type = {
2268 	.name = "busdevfn",
2269 	.format = format_busdevfn_setting,
2270 };
2271 
2272 /******************************************************************************
2273  *
2274  * Setting expansion
2275  *
2276  ******************************************************************************
2277  */
2278 
2279 /**
2280  * Expand variables within string
2281  *
2282  * @v string		String
2283  * @ret expstr		Expanded string
2284  *
2285  * The expanded string is allocated with malloc() and the caller must
2286  * eventually free() it.
2287  */
expand_settings(const char * string)2288 char * expand_settings ( const char *string ) {
2289 	struct settings *settings;
2290 	struct setting setting;
2291 	char *expstr;
2292 	char *start;
2293 	char *end;
2294 	char *head;
2295 	char *name;
2296 	char *tail;
2297 	char *value;
2298 	char *tmp;
2299 	int new_len;
2300 	int rc;
2301 
2302 	/* Obtain temporary modifiable copy of string */
2303 	expstr = strdup ( string );
2304 	if ( ! expstr )
2305 		return NULL;
2306 
2307 	/* Expand while expansions remain */
2308 	while ( 1 ) {
2309 
2310 		head = expstr;
2311 
2312 		/* Locate setting to be expanded */
2313 		start = NULL;
2314 		end = NULL;
2315 		for ( tmp = expstr ; *tmp ; tmp++ ) {
2316 			if ( ( tmp[0] == '$' ) && ( tmp[1] == '{' ) )
2317 				start = tmp;
2318 			if ( start && ( tmp[0] == '}' ) ) {
2319 				end = tmp;
2320 				break;
2321 			}
2322 		}
2323 		if ( ! end )
2324 			break;
2325 		*start = '\0';
2326 		name = ( start + 2 );
2327 		*end = '\0';
2328 		tail = ( end + 1 );
2329 
2330 		/* Expand setting */
2331 		if ( ( rc = parse_setting_name ( name, find_child_settings,
2332 						 &settings,
2333 						 &setting ) ) != 0 ) {
2334 			/* Treat invalid setting names as empty */
2335 			value = NULL;
2336 		} else {
2337 			/* Fetch and format setting value.  Ignore
2338 			 * errors; treat non-existent settings as empty.
2339 			 */
2340 			fetchf_setting_copy ( settings, &setting, NULL, NULL,
2341 					      &value );
2342 		}
2343 
2344 		/* Construct expanded string and discard old string */
2345 		tmp = expstr;
2346 		new_len = asprintf ( &expstr, "%s%s%s",
2347 				     head, ( value ? value : "" ), tail );
2348 		free ( value );
2349 		free ( tmp );
2350 		if ( new_len < 0 )
2351 			return NULL;
2352 	}
2353 
2354 	return expstr;
2355 }
2356 
2357 /******************************************************************************
2358  *
2359  * Settings
2360  *
2361  ******************************************************************************
2362  */
2363 
2364 /** Hostname setting */
2365 const struct setting hostname_setting __setting ( SETTING_HOST, hostname ) = {
2366 	.name = "hostname",
2367 	.description = "Host name",
2368 	.tag = DHCP_HOST_NAME,
2369 	.type = &setting_type_string,
2370 };
2371 
2372 /** Domain name setting */
2373 const struct setting domain_setting __setting ( SETTING_IP_EXTRA, domain ) = {
2374 	.name = "domain",
2375 	.description = "DNS domain",
2376 	.tag = DHCP_DOMAIN_NAME,
2377 	.type = &setting_type_string,
2378 };
2379 
2380 /** TFTP server setting */
2381 const struct setting next_server_setting __setting ( SETTING_BOOT,next-server)={
2382 	.name = "next-server",
2383 	.description = "TFTP server",
2384 	.tag = DHCP_EB_SIADDR,
2385 	.type = &setting_type_ipv4,
2386 };
2387 
2388 /** Filename setting */
2389 const struct setting filename_setting __setting ( SETTING_BOOT, filename ) = {
2390 	.name = "filename",
2391 	.description = "Boot filename",
2392 	.tag = DHCP_BOOTFILE_NAME,
2393 	.type = &setting_type_string,
2394 };
2395 
2396 /** Root path setting */
2397 const struct setting root_path_setting __setting ( SETTING_SANBOOT, root-path)={
2398 	.name = "root-path",
2399 	.description = "SAN root path",
2400 	.tag = DHCP_ROOT_PATH,
2401 	.type = &setting_type_string,
2402 };
2403 
2404 /** SAN filename setting */
2405 const struct setting san_filename_setting __setting ( SETTING_SANBOOT,
2406 						      san-filename ) = {
2407 	.name = "san-filename",
2408 	.description = "SAN filename",
2409 	.tag = DHCP_EB_SAN_FILENAME,
2410 	.type = &setting_type_string,
2411 };
2412 
2413 /** Username setting */
2414 const struct setting username_setting __setting ( SETTING_AUTH, username ) = {
2415 	.name = "username",
2416 	.description = "User name",
2417 	.tag = DHCP_EB_USERNAME,
2418 	.type = &setting_type_string,
2419 };
2420 
2421 /** Password setting */
2422 const struct setting password_setting __setting ( SETTING_AUTH, password ) = {
2423 	.name = "password",
2424 	.description = "Password",
2425 	.tag = DHCP_EB_PASSWORD,
2426 	.type = &setting_type_string,
2427 };
2428 
2429 /** Priority setting */
2430 const struct setting priority_setting __setting ( SETTING_MISC, priority ) = {
2431 	.name = "priority",
2432 	.description = "Settings priority",
2433 	.tag = DHCP_EB_PRIORITY,
2434 	.type = &setting_type_int8,
2435 };
2436 
2437 /** DHCP user class setting */
2438 const struct setting user_class_setting __setting ( SETTING_HOST_EXTRA,
2439 						    user-class ) = {
2440 	.name = "user-class",
2441 	.description = "DHCP user class",
2442 	.tag = DHCP_USER_CLASS_ID,
2443 	.type = &setting_type_string,
2444 };
2445 
2446 /** DHCP vendor class setting */
2447 const struct setting vendor_class_setting __setting ( SETTING_HOST_EXTRA,
2448 						      vendor-class ) = {
2449 	.name = "vendor-class",
2450 	.description = "DHCP vendor class",
2451 	.tag = DHCP_VENDOR_CLASS_ID,
2452 	.type = &setting_type_string,
2453 };
2454 
2455 /******************************************************************************
2456  *
2457  * Built-in settings block
2458  *
2459  ******************************************************************************
2460  */
2461 
2462 /** Built-in setting scope */
2463 const struct settings_scope builtin_scope;
2464 
2465 /**
2466  * Fetch error number setting
2467  *
2468  * @v data		Buffer to fill with setting data
2469  * @v len		Length of buffer
2470  * @ret len		Length of setting data, or negative error
2471  */
errno_fetch(void * data,size_t len)2472 static int errno_fetch ( void *data, size_t len ) {
2473 	uint32_t content;
2474 
2475 	/* Return current error */
2476 	content = htonl ( errno );
2477 	if ( len > sizeof ( content ) )
2478 		len = sizeof ( content );
2479 	memcpy ( data, &content, len );
2480 	return sizeof ( content );
2481 }
2482 
2483 /** Error number setting */
2484 const struct setting errno_setting __setting ( SETTING_MISC, errno ) = {
2485 	.name = "errno",
2486 	.description = "Last error",
2487 	.type = &setting_type_uint32,
2488 	.scope = &builtin_scope,
2489 };
2490 
2491 /** Error number built-in setting */
2492 struct builtin_setting errno_builtin_setting __builtin_setting = {
2493 	.setting = &errno_setting,
2494 	.fetch = errno_fetch,
2495 };
2496 
2497 /**
2498  * Fetch build architecture setting
2499  *
2500  * @v data		Buffer to fill with setting data
2501  * @v len		Length of buffer
2502  * @ret len		Length of setting data, or negative error
2503  */
buildarch_fetch(void * data,size_t len)2504 static int buildarch_fetch ( void *data, size_t len ) {
2505 	static const char buildarch[] = _S2 ( ARCH );
2506 
2507 	strncpy ( data, buildarch, len );
2508 	return ( sizeof ( buildarch ) - 1 /* NUL */ );
2509 }
2510 
2511 /** Build architecture setting */
2512 const struct setting buildarch_setting __setting ( SETTING_MISC, buildarch ) = {
2513 	.name = "buildarch",
2514 	.description = "Build architecture",
2515 	.type = &setting_type_string,
2516 	.scope = &builtin_scope,
2517 };
2518 
2519 /** Build architecture built-in setting */
2520 struct builtin_setting buildarch_builtin_setting __builtin_setting = {
2521 	.setting = &buildarch_setting,
2522 	.fetch = buildarch_fetch,
2523 };
2524 
2525 /**
2526  * Fetch platform setting
2527  *
2528  * @v data		Buffer to fill with setting data
2529  * @v len		Length of buffer
2530  * @ret len		Length of setting data, or negative error
2531  */
platform_fetch(void * data,size_t len)2532 static int platform_fetch ( void *data, size_t len ) {
2533 	static const char platform[] = _S2 ( PLATFORM );
2534 
2535 	strncpy ( data, platform, len );
2536 	return ( sizeof ( platform ) - 1 /* NUL */ );
2537 }
2538 
2539 /** Platform setting */
2540 const struct setting platform_setting __setting ( SETTING_MISC, platform ) = {
2541 	.name = "platform",
2542 	.description = "Platform",
2543 	.type = &setting_type_string,
2544 	.scope = &builtin_scope,
2545 };
2546 
2547 /** Platform built-in setting */
2548 struct builtin_setting platform_builtin_setting __builtin_setting = {
2549 	.setting = &platform_setting,
2550 	.fetch = platform_fetch,
2551 };
2552 
2553 /**
2554  * Fetch version setting
2555  *
2556  * @v data		Buffer to fill with setting data
2557  * @v len		Length of buffer
2558  * @ret len		Length of setting data, or negative error
2559  */
version_fetch(void * data,size_t len)2560 static int version_fetch ( void *data, size_t len ) {
2561 	strncpy ( data, product_version, len );
2562 	return ( strlen ( product_version ) );
2563 }
2564 
2565 /** Version setting */
2566 const struct setting version_setting __setting ( SETTING_MISC, version ) = {
2567 	.name = "version",
2568 	.description = "Version",
2569 	.type = &setting_type_string,
2570 	.scope = &builtin_scope,
2571 };
2572 
2573 /** Version built-in setting */
2574 struct builtin_setting version_builtin_setting __builtin_setting = {
2575 	.setting = &version_setting,
2576 	.fetch = version_fetch,
2577 };
2578 
2579 /**
2580  * Fetch current time setting
2581  *
2582  * @v data		Buffer to fill with setting data
2583  * @v len		Length of buffer
2584  * @ret len		Length of setting data, or negative error
2585  */
unixtime_fetch(void * data,size_t len)2586 static int unixtime_fetch ( void *data, size_t len ) {
2587 	uint32_t content;
2588 
2589 	/* Return current time */
2590 	content = htonl ( time(NULL) );
2591 	if ( len > sizeof ( content ) )
2592 		len = sizeof ( content );
2593 	memcpy ( data, &content, len );
2594 	return sizeof ( content );
2595 }
2596 
2597 /** Current time setting */
2598 const struct setting unixtime_setting __setting ( SETTING_MISC, unixtime ) = {
2599 	.name = "unixtime",
2600 	.description = "Seconds since the Epoch",
2601 	.type = &setting_type_uint32,
2602 	.scope = &builtin_scope,
2603 };
2604 
2605 /** Current time built-in setting */
2606 struct builtin_setting unixtime_builtin_setting __builtin_setting = {
2607 	.setting = &unixtime_setting,
2608 	.fetch = unixtime_fetch,
2609 };
2610 
2611 /**
2612  * Fetch built-in setting
2613  *
2614  * @v settings		Settings block
2615  * @v setting		Setting to fetch
2616  * @v data		Buffer to fill with setting data
2617  * @v len		Length of buffer
2618  * @ret len		Length of setting data, or negative error
2619  */
builtin_fetch(struct settings * settings __unused,struct setting * setting,void * data,size_t len)2620 static int builtin_fetch ( struct settings *settings __unused,
2621 			   struct setting *setting,
2622 			   void *data, size_t len ) {
2623 	struct builtin_setting *builtin;
2624 
2625 	for_each_table_entry ( builtin, BUILTIN_SETTINGS ) {
2626 		if ( setting_cmp ( setting, builtin->setting ) == 0 )
2627 			return builtin->fetch ( data, len );
2628 	}
2629 	return -ENOENT;
2630 }
2631 
2632 /**
2633  * Check applicability of built-in setting
2634  *
2635  * @v settings		Settings block
2636  * @v setting		Setting
2637  * @ret applies		Setting applies within this settings block
2638  */
builtin_applies(struct settings * settings __unused,const struct setting * setting)2639 static int builtin_applies ( struct settings *settings __unused,
2640 			     const struct setting *setting ) {
2641 
2642 	return ( setting->scope == &builtin_scope );
2643 }
2644 
2645 /** Built-in settings operations */
2646 static struct settings_operations builtin_settings_operations = {
2647 	.applies = builtin_applies,
2648 	.fetch = builtin_fetch,
2649 };
2650 
2651 /** Built-in settings */
2652 static struct settings builtin_settings = {
2653 	.refcnt = NULL,
2654 	.siblings = LIST_HEAD_INIT ( builtin_settings.siblings ),
2655 	.children = LIST_HEAD_INIT ( builtin_settings.children ),
2656 	.op = &builtin_settings_operations,
2657 };
2658 
2659 /** Initialise built-in settings */
builtin_init(void)2660 static void builtin_init ( void ) {
2661 	int rc;
2662 
2663 	if ( ( rc = register_settings ( &builtin_settings, NULL,
2664 					"builtin" ) ) != 0 ) {
2665 		DBG ( "Could not register built-in settings: %s\n",
2666 		      strerror ( rc ) );
2667 		return;
2668 	}
2669 }
2670 
2671 /** Built-in settings initialiser */
2672 struct init_fn builtin_init_fn __init_fn ( INIT_NORMAL ) = {
2673 	.initialise = builtin_init,
2674 };
2675