summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe/settings.h
blob: f463e6674dc34f0961eabf45081f0829638382dc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
#ifndef _IPXE_SETTINGS_H
#define _IPXE_SETTINGS_H

/** @file
 *
 * Configuration settings
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <ipxe/tables.h>
#include <ipxe/list.h>
#include <ipxe/refcnt.h>

struct settings;
struct in_addr;
struct in6_addr;
union uuid;

/** A setting */
struct setting {
	/** Name
	 *
	 * This is the human-readable name for the setting.
	 */
	const char *name;
	/** Description */
	const char *description;
	/** Setting type
	 *
	 * This identifies the type of setting (e.g. string, IPv4
	 * address, etc.).
	 */
	const struct setting_type *type;
	/** Setting tag, if applicable
	 *
	 * The setting tag is a numerical description of the setting
	 * (such as a DHCP option number, or an SMBIOS structure and
	 * field number).
	 */
	uint64_t tag;
	/** Setting scope (or NULL)
	 *
	 * For historic reasons, a NULL scope with a non-zero tag
	 * indicates a DHCPv4 option setting.
	 */
	const struct settings_scope *scope;
};

/** Configuration setting table */
#define SETTINGS __table ( struct setting, "settings" )

/** Declare a configuration setting */
#define __setting( setting_order, name ) \
	__table_entry ( SETTINGS, setting_order.name )

/** @defgroup setting_order Setting ordering
 * @{
 */

#define SETTING_NETDEV		01 /**< Network device settings */
#define SETTING_NETDEV_EXTRA	02 /**< Network device additional settings */
#define SETTING_IP4		03 /**< IPv4 settings */
#define SETTING_IP4_EXTRA	04 /**< IPv4 additional settings */
#define SETTING_IP6		05 /**< IPv6 settings */
#define SETTING_IP6_EXTRA	06 /**< IPv6 additional settings */
#define SETTING_IP		07 /**< IPv4 settings */
#define SETTING_IP_EXTRA	08 /**< IPv4 additional settings */
#define SETTING_BOOT		09 /**< Generic boot settings */
#define SETTING_BOOT_EXTRA	10 /**< Generic boot additional settings */
#define SETTING_SANBOOT		11 /**< SAN boot settings */
#define SETTING_SANBOOT_EXTRA	12 /**< SAN boot additional settings */
#define SETTING_HOST		13 /**< Host identity settings */
#define SETTING_HOST_EXTRA	14 /**< Host identity additional settings */
#define SETTING_AUTH		15 /**< Authentication settings */
#define SETTING_AUTH_EXTRA	16 /**< Authentication additional settings */
#define SETTING_CRYPTO		17 /**< Cryptography settings */
#define SETTING_MISC		18 /**< Miscellaneous settings */

/** @} */

/** Settings block operations */
struct settings_operations {
	/** Redirect to underlying settings block (if applicable)
	 *
	 * @v settings		Settings block
	 * @ret settings	Underlying settings block
	 */
	struct settings * ( * redirect ) ( struct settings *settings );
	/** Check applicability of setting
	 *
	 * @v settings		Settings block
	 * @v setting		Setting
	 * @ret applies		Setting applies within this settings block
	 */
	int ( * applies ) ( struct settings *settings,
			    const struct setting *setting );
	/** Store value of setting
	 *
	 * @v settings		Settings block
	 * @v setting		Setting to store
	 * @v data		Setting data, or NULL to clear setting
	 * @v len		Length of setting data
	 * @ret rc		Return status code
	 */
	int ( * store ) ( struct settings *settings,
			  const struct setting *setting,
			  const void *data, size_t len );
	/** Fetch value of setting
	 *
	 * @v settings		Settings block
	 * @v setting		Setting to fetch
	 * @v data		Buffer to fill with setting data
	 * @v len		Length of buffer
	 * @ret len		Length of setting data, or negative error
	 *
	 * The actual length of the setting will be returned even if
	 * the buffer was too small.
	 */
	int ( * fetch ) ( struct settings *settings, struct setting *setting,
			  void *data, size_t len );
	/** Clear settings block
	 *
	 * @v settings		Settings block
	 */
	void ( * clear ) ( struct settings *settings );
};

/** A settings block */
struct settings {
	/** Reference counter */
	struct refcnt *refcnt;
	/** Name */
	const char *name;
	/** Parent settings block */
	struct settings *parent;
	/** Sibling settings blocks */
	struct list_head siblings;
	/** Child settings blocks */
	struct list_head children;
	/** Settings block operations */
	struct settings_operations *op;
	/** Default scope for numerical settings constructed for this block */
	const struct settings_scope *default_scope;
	/** Sibling ordering */
	int order;
};

/**
 * A setting scope
 *
 * Users can construct tags for settings that are not explicitly known
 * to iPXE using the generic syntax for numerical settings.  For
 * example, the setting name "60" will be interpreted as referring to
 * DHCP option 60 (the vendor class identifier).
 *
 * This creates a potential for namespace collisions, since the
 * interpretation of the numerical description will vary according to
 * the settings block.  When a user attempts to fetch a generic
 * numerical setting, we need to ensure that only the intended
 * settings blocks interpret this numerical description.  (For
 * example, we do not want to attempt to retrieve the subnet mask from
 * SMBIOS, or the system UUID from DHCP.)
 *
 * This potential problem is resolved by including a user-invisible
 * "scope" within the definition of each setting.  Settings blocks may
 * use this to determine whether or not the setting is applicable.
 * Any settings constructed from a numerical description
 * (e.g. "smbios/1.4.0") will be assigned the default scope of the
 * settings block specified in the description (e.g. "smbios"); this
 * provides behaviour matching the user's expectations in most
 * circumstances.
 */
struct settings_scope {
	/** Dummy field
	 *
	 * This is included only to ensure that pointers to different
	 * scopes always compare differently.
	 */
	uint8_t dummy;
} __attribute__ (( packed ));

/**
 * A setting type
 *
 * This represents a type of setting (e.g. string, IPv4 address,
 * etc.).
 */
struct setting_type {
	/** Name
	 *
	 * This is the name exposed to the user (e.g. "string").
	 */
	const char *name;
	/** Parse formatted string to setting value
	 *
	 * @v type		Setting type
	 * @v value		Formatted setting value
	 * @v buf		Buffer to contain raw value
	 * @v len		Length of buffer
	 * @ret len		Length of raw value, or negative error
	 */
	int ( * parse ) ( const struct setting_type *type, const char *value,
			  void *buf, size_t len );
	/** Format setting value as a string
	 *
	 * @v type		Setting type
	 * @v raw		Raw setting value
	 * @v raw_len		Length of raw setting value
	 * @v buf		Buffer to contain formatted value
	 * @v len		Length of buffer
	 * @ret len		Length of formatted value, or negative error
	 */
	int ( * format ) ( const struct setting_type *type, const void *raw,
			   size_t raw_len, char *buf, size_t len );
	/** Convert number to setting value
	 *
	 * @v type		Setting type
	 * @v value		Numeric value
	 * @v buf		Buffer to contain raw value
	 * @v len		Length of buffer
	 * @ret len		Length of raw value, or negative error
	 */
	int ( * denumerate ) ( const struct setting_type *type,
			       unsigned long value,
			       void *buf, size_t len );
	/** Convert setting value to number
	 *
	 * @v type		Setting type
	 * @v raw		Raw setting value
	 * @v raw_len		Length of raw setting value
	 * @v value		Numeric value to fill in
	 * @ret rc		Return status code
	 */
	int ( * numerate ) ( const struct setting_type *type, const void *raw,
			     size_t raw_len, unsigned long *value );
};

/** Configuration setting type table */
#define SETTING_TYPES __table ( struct setting_type, "setting_types" )

/** Declare a configuration setting type */
#define __setting_type __table_entry ( SETTING_TYPES, 01 )

/**
 * A settings applicator
 *
 */
struct settings_applicator {
	/** Apply updated settings
	 *
	 * @ret rc		Return status code
	 */
	int ( * apply ) ( void );
};

/** Settings applicator table */
#define SETTINGS_APPLICATORS \
	__table ( struct settings_applicator, "settings_applicators" )

/** Declare a settings applicator */
#define __settings_applicator __table_entry ( SETTINGS_APPLICATORS, 01 )

/** A built-in setting */
struct builtin_setting {
	/** Setting */
	const struct setting *setting;
	/** Fetch setting value
	 *
	 * @v data		Buffer to fill with setting data
	 * @v len		Length of buffer
	 * @ret len		Length of setting data, or negative error
	 */
	int ( * fetch ) ( void *data, size_t len );
};

/** Built-in settings table */
#define BUILTIN_SETTINGS __table ( struct builtin_setting, "builtin_settings" )

/** Declare a built-in setting */
#define __builtin_setting __table_entry ( BUILTIN_SETTINGS, 01 )

/** Built-in setting scope */
extern const struct settings_scope builtin_scope;

/** IPv6 setting scope */
extern const struct settings_scope ipv6_settings_scope;

/** DHCPv6 setting scope */
extern const struct settings_scope dhcpv6_scope;

/**
 * A generic settings block
 *
 */
struct generic_settings {
	/** Settings block */
	struct settings settings;
	/** List of generic settings */
	struct list_head list;
};

/** A child settings block locator function */
typedef struct settings * ( *get_child_settings_t ) ( struct settings *settings,
						      const char *name );
extern struct settings_operations generic_settings_operations;
extern int generic_settings_store ( struct settings *settings,
				    const struct setting *setting,
				    const void *data, size_t len );
extern int generic_settings_fetch ( struct settings *settings,
				    struct setting *setting,
				    void *data, size_t len );
extern void generic_settings_clear ( struct settings *settings );

extern int register_settings ( struct settings *settings,
			       struct settings *parent, const char *name );
extern void unregister_settings ( struct settings *settings );

extern struct settings * settings_target ( struct settings *settings );
extern int setting_applies ( struct settings *settings,
			     const struct setting *setting );
extern int store_setting ( struct settings *settings,
			   const struct setting *setting,
			   const void *data, size_t len );
extern int fetch_setting ( struct settings *settings,
			   const struct setting *setting,
			   struct settings **origin, struct setting *fetched,
			   void *data, size_t len );
extern int fetch_setting_copy ( struct settings *settings,
				const struct setting *setting,
				struct settings **origin,
				struct setting *fetched, void **data );
extern int fetch_raw_setting ( struct settings *settings,
			       const struct setting *setting,
			       void *data, size_t len );
extern int fetch_raw_setting_copy ( struct settings *settings,
				    const struct setting *setting,
				    void **data );
extern int fetch_string_setting ( struct settings *settings,
				  const struct setting *setting,
				  char *data, size_t len );
extern int fetch_string_setting_copy ( struct settings *settings,
				       const struct setting *setting,
				       char **data );
extern int fetch_ipv4_array_setting ( struct settings *settings,
				      const struct setting *setting,
				      struct in_addr *inp, unsigned int count );
extern int fetch_ipv4_setting ( struct settings *settings,
				const struct setting *setting,
				struct in_addr *inp );
extern int fetch_ipv6_array_setting ( struct settings *settings,
				      const struct setting *setting,
				      struct in6_addr *inp, unsigned int count);
extern int fetch_ipv6_setting ( struct settings *settings,
				const struct setting *setting,
				struct in6_addr *inp );
extern int fetch_int_setting ( struct settings *settings,
			       const struct setting *setting, long *value );
extern int fetch_uint_setting ( struct settings *settings,
				const struct setting *setting,
				unsigned long *value );
extern long fetch_intz_setting ( struct settings *settings,
				 const struct setting *setting );
extern unsigned long fetch_uintz_setting ( struct settings *settings,
					   const struct setting *setting );
extern int fetch_uuid_setting ( struct settings *settings,
				const struct setting *setting,
				union uuid *uuid );
extern void clear_settings ( struct settings *settings );
extern int setting_cmp ( const struct setting *a, const struct setting *b );

extern struct settings * find_child_settings ( struct settings *parent,
					       const char *name );
extern struct settings * autovivify_child_settings ( struct settings *parent,
						     const char *name );
extern const char * settings_name ( struct settings *settings );
extern struct settings * find_settings ( const char *name );
extern struct setting * find_setting ( const char *name );
extern int parse_setting_name ( char *name, get_child_settings_t get_child,
				struct settings **settings,
				struct setting *setting );
extern int setting_name ( struct settings *settings,
			  const struct setting *setting,
			  char *buf, size_t len );
extern int setting_format ( const struct setting_type *type, const void *raw,
			    size_t raw_len, char *buf, size_t len );
extern int setting_parse ( const struct setting_type *type, const char *value,
			   void *buf, size_t len );
extern int setting_numerate ( const struct setting_type *type, const void *raw,
			      size_t raw_len, unsigned long *value );
extern int setting_denumerate ( const struct setting_type *type,
				unsigned long value, void *buf, size_t len );
extern int fetchf_setting ( struct settings *settings,
			    const struct setting *setting,
			    struct settings **origin, struct setting *fetched,
			    char *buf, size_t len );
extern int fetchf_setting_copy ( struct settings *settings,
				 const struct setting *setting,
				 struct settings **origin,
				 struct setting *fetched, char **value );
extern int storef_setting ( struct settings *settings,
			    const struct setting *setting, const char *value );
extern int fetchn_setting ( struct settings *settings,
			    const struct setting *setting,
			    struct settings **origin, struct setting *fetched,
			    unsigned long *value );
extern int storen_setting ( struct settings *settings,
			    const struct setting *setting,
			    unsigned long value );
extern char * expand_settings ( const char *string );

extern const struct setting_type setting_type_string __setting_type;
extern const struct setting_type setting_type_uristring __setting_type;
extern const struct setting_type setting_type_ipv4 __setting_type;
extern const struct setting_type setting_type_ipv6 __setting_type;
extern const struct setting_type setting_type_int8 __setting_type;
extern const struct setting_type setting_type_int16 __setting_type;
extern const struct setting_type setting_type_int32 __setting_type;
extern const struct setting_type setting_type_uint8 __setting_type;
extern const struct setting_type setting_type_uint16 __setting_type;
extern const struct setting_type setting_type_uint32 __setting_type;
extern const struct setting_type setting_type_hex __setting_type;
extern const struct setting_type setting_type_hexhyp __setting_type;
extern const struct setting_type setting_type_hexraw __setting_type;
extern const struct setting_type setting_type_base64 __setting_type;
extern const struct setting_type setting_type_uuid __setting_type;
extern const struct setting_type setting_type_busdevfn __setting_type;
extern const struct setting_type setting_type_dnssl __setting_type;

extern const struct setting
ip_setting __setting ( SETTING_IP4, ip );
extern const struct setting
netmask_setting __setting ( SETTING_IP4, netmask );
extern const struct setting
gateway_setting __setting ( SETTING_IP4, gateway );
extern const struct setting
dns_setting __setting ( SETTING_IP4_EXTRA, dns );
extern const struct setting
ip6_setting __setting ( SETTING_IP6, ip6 );
extern const struct setting
len6_setting __setting ( SETTING_IP6, len6 );
extern const struct setting
gateway6_setting __setting ( SETTING_IP6, gateway6 );
extern const struct setting
hostname_setting __setting ( SETTING_HOST, hostname );
extern const struct setting
domain_setting __setting ( SETTING_IP_EXTRA, domain );
extern const struct setting
filename_setting __setting ( SETTING_BOOT, filename );
extern const struct setting
root_path_setting __setting ( SETTING_SANBOOT, root-path );
extern const struct setting
san_filename_setting __setting ( SETTING_SANBOOT, san-filename );
extern const struct setting
username_setting __setting ( SETTING_AUTH, username );
extern const struct setting
password_setting __setting ( SETTING_AUTH, password );
extern const struct setting
priority_setting __setting ( SETTING_MISC, priority );
extern const struct setting
uuid_setting __setting ( SETTING_HOST, uuid );
extern const struct setting
next_server_setting __setting ( SETTING_BOOT, next-server );
extern const struct setting
mac_setting __setting ( SETTING_NETDEV, mac );
extern const struct setting
busid_setting __setting ( SETTING_NETDEV, busid );
extern const struct setting
user_class_setting __setting ( SETTING_HOST_EXTRA, user-class );
extern const struct setting
vendor_class_setting __setting ( SETTING_HOST_EXTRA, vendor-class );
extern const struct setting
manufacturer_setting __setting ( SETTING_HOST_EXTRA, manufacturer );
extern const struct setting
product_setting __setting ( SETTING_HOST_EXTRA, product );
extern const struct setting
serial_setting __setting ( SETTING_HOST_EXTRA, serial );
extern const struct setting
asset_setting __setting ( SETTING_HOST_EXTRA, asset );
extern const struct setting
board_serial_setting __setting ( SETTING_HOST_EXTRA, board-serial );
extern const struct setting dhcp_server_setting __setting ( SETTING_MISC,
							    dhcp-server );

/**
 * Initialise a settings block
 *
 * @v settings		Settings block
 * @v op		Settings block operations
 * @v refcnt		Containing object reference counter, or NULL
 * @v default_scope	Default scope
 */
static inline void settings_init ( struct settings *settings,
				   struct settings_operations *op,
				   struct refcnt *refcnt,
				   const struct settings_scope *default_scope ){
	INIT_LIST_HEAD ( &settings->siblings );
	INIT_LIST_HEAD ( &settings->children );
	settings->op = op;
	settings->refcnt = refcnt;
	settings->default_scope = default_scope;
}

/**
 * Initialise a settings block
 *
 * @v generics		Generic settings block
 * @v refcnt		Containing object reference counter, or NULL
 */
static inline void generic_settings_init ( struct generic_settings *generics,
					   struct refcnt *refcnt ) {
	settings_init ( &generics->settings, &generic_settings_operations,
			refcnt, NULL );
	INIT_LIST_HEAD ( &generics->list );
}

/**
 * Delete setting
 *
 * @v settings		Settings block
 * @v setting		Setting to delete
 * @ret rc		Return status code
 */
static inline int delete_setting ( struct settings *settings,
				   const struct setting *setting ) {
	return store_setting ( settings, setting, NULL, 0 );
}

/**
 * Check existence of predefined setting
 *
 * @v settings		Settings block, or NULL to search all blocks
 * @v setting		Setting to fetch
 * @ret exists		Setting exists
 */
static inline int setting_exists ( struct settings *settings,
				   const struct setting *setting ) {
	return ( fetch_setting ( settings, setting, NULL, NULL,
				 NULL, 0 ) >= 0 );
}

#endif /* _IPXE_SETTINGS_H */