#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_guid __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
dns6_setting __setting ( SETTING_IP6_EXTRA, dns6 );
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
linktype_setting __setting ( SETTING_NETDEV, linktype );
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 */