mirror of https://github.com/ipxe/ipxe.git
[dhcpv6] Expose IPv6 address setting acquired through DHCPv6
Originally-implemented-by: Hannes Reinecke <hare@suse.de> Originally-implemented-by: Marin Hannache <git@mareo.fr> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/56/head
parent
3b783d7fd2
commit
03d19cf14d
|
@ -266,6 +266,8 @@ struct dhcpv6_settings {
|
||||||
struct refcnt refcnt;
|
struct refcnt refcnt;
|
||||||
/** Settings block */
|
/** Settings block */
|
||||||
struct settings settings;
|
struct settings settings;
|
||||||
|
/** Leased address */
|
||||||
|
struct in6_addr lease;
|
||||||
/** Option list */
|
/** Option list */
|
||||||
struct dhcpv6_option_list options;
|
struct dhcpv6_option_list options;
|
||||||
};
|
};
|
||||||
|
@ -280,7 +282,32 @@ struct dhcpv6_settings {
|
||||||
static int dhcpv6_applies ( struct settings *settings __unused,
|
static int dhcpv6_applies ( struct settings *settings __unused,
|
||||||
const struct setting *setting ) {
|
const struct setting *setting ) {
|
||||||
|
|
||||||
return ( setting->scope == &dhcpv6_scope );
|
return ( ( setting->scope == &dhcpv6_scope ) ||
|
||||||
|
( setting_cmp ( setting, &ip6_setting ) == 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch value of DHCPv6 leased address
|
||||||
|
*
|
||||||
|
* @v dhcpset DHCPv6 settings
|
||||||
|
* @v data Buffer to fill with setting data
|
||||||
|
* @v len Length of buffer
|
||||||
|
* @ret len Length of setting data, or negative error
|
||||||
|
*/
|
||||||
|
static int dhcpv6_fetch_lease ( struct dhcpv6_settings *dhcpv6set,
|
||||||
|
void *data, size_t len ) {
|
||||||
|
struct in6_addr *lease = &dhcpv6set->lease;
|
||||||
|
|
||||||
|
/* Do nothing unless a leased address exists */
|
||||||
|
if ( IN6_IS_ADDR_UNSPECIFIED ( lease ) )
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
/* Copy leased address */
|
||||||
|
if ( len > sizeof ( *lease ) )
|
||||||
|
len = sizeof ( *lease );
|
||||||
|
memcpy ( data, lease, len );
|
||||||
|
|
||||||
|
return sizeof ( *lease );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -300,6 +327,10 @@ static int dhcpv6_fetch ( struct settings *settings,
|
||||||
const union dhcpv6_any_option *option;
|
const union dhcpv6_any_option *option;
|
||||||
size_t option_len;
|
size_t option_len;
|
||||||
|
|
||||||
|
/* Handle leased address */
|
||||||
|
if ( setting_cmp ( setting, &ip6_setting ) == 0 )
|
||||||
|
return dhcpv6_fetch_lease ( dhcpv6set, data, len );
|
||||||
|
|
||||||
/* Find option */
|
/* Find option */
|
||||||
option = dhcpv6_option ( &dhcpv6set->options, setting->tag );
|
option = dhcpv6_option ( &dhcpv6set->options, setting->tag );
|
||||||
if ( ! option )
|
if ( ! option )
|
||||||
|
@ -322,11 +353,13 @@ static struct settings_operations dhcpv6_settings_operations = {
|
||||||
/**
|
/**
|
||||||
* Register DHCPv6 options as network device settings
|
* Register DHCPv6 options as network device settings
|
||||||
*
|
*
|
||||||
|
* @v lease DHCPv6 leased address
|
||||||
* @v options DHCPv6 option list
|
* @v options DHCPv6 option list
|
||||||
* @v parent Parent settings block
|
* @v parent Parent settings block
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int dhcpv6_register ( struct dhcpv6_option_list *options,
|
static int dhcpv6_register ( struct in6_addr *lease,
|
||||||
|
struct dhcpv6_option_list *options,
|
||||||
struct settings *parent ) {
|
struct settings *parent ) {
|
||||||
struct dhcpv6_settings *dhcpv6set;
|
struct dhcpv6_settings *dhcpv6set;
|
||||||
void *data;
|
void *data;
|
||||||
|
@ -347,6 +380,7 @@ static int dhcpv6_register ( struct dhcpv6_option_list *options,
|
||||||
memcpy ( data, options->data, len );
|
memcpy ( data, options->data, len );
|
||||||
dhcpv6set->options.data = data;
|
dhcpv6set->options.data = data;
|
||||||
dhcpv6set->options.len = len;
|
dhcpv6set->options.len = len;
|
||||||
|
memcpy ( &dhcpv6set->lease, lease, sizeof ( dhcpv6set->lease ) );
|
||||||
|
|
||||||
/* Register settings */
|
/* Register settings */
|
||||||
if ( ( rc = register_settings ( &dhcpv6set->settings, parent,
|
if ( ( rc = register_settings ( &dhcpv6set->settings, parent,
|
||||||
|
@ -848,28 +882,25 @@ static int dhcpv6_rx ( struct dhcpv6_session *dhcpv6,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transition to next state or complete DHCPv6, as applicable */
|
/* Transition to next state, if applicable */
|
||||||
if ( dhcpv6->state->next ) {
|
if ( dhcpv6->state->next ) {
|
||||||
|
|
||||||
/* Transition to next state */
|
|
||||||
dhcpv6_set_state ( dhcpv6, dhcpv6->state->next );
|
dhcpv6_set_state ( dhcpv6, dhcpv6->state->next );
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
goto done;
|
||||||
} else {
|
|
||||||
|
|
||||||
/* Register settings */
|
|
||||||
if ( ( rc = dhcpv6_register ( &options, parent ) ) != 0 ) {
|
|
||||||
DBGC ( dhcpv6, "DHCPv6 %s could not register "
|
|
||||||
"settings: %s\n", dhcpv6->netdev->name,
|
|
||||||
strerror ( rc ) );
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark as complete */
|
|
||||||
dhcpv6_finished ( dhcpv6, 0 );
|
|
||||||
DBGC ( dhcpv6, "DHCPv6 %s complete\n", dhcpv6->netdev->name );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Register settings */
|
||||||
|
if ( ( rc = dhcpv6_register ( &dhcpv6->lease, &options,
|
||||||
|
parent ) ) != 0 ) {
|
||||||
|
DBGC ( dhcpv6, "DHCPv6 %s could not register settings: %s\n",
|
||||||
|
dhcpv6->netdev->name, strerror ( rc ) );
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark as complete */
|
||||||
|
dhcpv6_finished ( dhcpv6, 0 );
|
||||||
|
DBGC ( dhcpv6, "DHCPv6 %s complete\n", dhcpv6->netdev->name );
|
||||||
|
|
||||||
done:
|
done:
|
||||||
free_iob ( iobuf );
|
free_iob ( iobuf );
|
||||||
return rc;
|
return rc;
|
||||||
|
|
Loading…
Reference in New Issue