iPXE
Data Structures | Macros | Enumerations | Functions | Variables
dhcpv6.c File Reference

Dynamic Host Configuration Protocol for IPv6. More...

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/interface.h>
#include <ipxe/xfer.h>
#include <ipxe/iobuf.h>
#include <ipxe/open.h>
#include <ipxe/netdevice.h>
#include <ipxe/settings.h>
#include <ipxe/retry.h>
#include <ipxe/timer.h>
#include <ipxe/in.h>
#include <ipxe/crc32.h>
#include <ipxe/errortab.h>
#include <ipxe/ipv6.h>
#include <ipxe/dhcparch.h>
#include <ipxe/dhcpv6.h>

Go to the source code of this file.

Data Structures

struct  dhcpv6_option_list
 A DHCPv6 option list. More...
 
struct  dhcpv6_settings
 A DHCPv6 settings block. More...
 
struct  dhcpv6_address_operation
 A DHCPv6 address setting operation. More...
 
struct  dhcpv6_session_state
 A DHCPv6 session state. More...
 
struct  dhcpv6_session
 A DHCPv6 session. More...
 

Macros

#define EPROTO_UNSPECFAIL   __einfo_error ( EINFO_EPROTO_UNSPECFAIL )
 
#define EINFO_EPROTO_UNSPECFAIL   __einfo_uniqify ( EINFO_EPROTO, 1, "Unspecified server failure" )
 
#define EPROTO_NOADDRSAVAIL   __einfo_error ( EINFO_EPROTO_NOADDRSAVAIL )
 
#define EINFO_EPROTO_NOADDRSAVAIL   __einfo_uniqify ( EINFO_EPROTO, 2, "No addresses available" )
 
#define EPROTO_NOBINDING   __einfo_error ( EINFO_EPROTO_NOBINDING )
 
#define EINFO_EPROTO_NOBINDING   __einfo_uniqify ( EINFO_EPROTO, 3, "Client record unavailable" )
 
#define EPROTO_NOTONLINK   __einfo_error ( EINFO_EPROTO_NOTONLINK )
 
#define EINFO_EPROTO_NOTONLINK   __einfo_uniqify ( EINFO_EPROTO, 4, "Prefix not on link" )
 
#define EPROTO_USEMULTICAST   __einfo_error ( EINFO_EPROTO_USEMULTICAST )
 
#define EINFO_EPROTO_USEMULTICAST   __einfo_uniqify ( EINFO_EPROTO, 5, "Use multicast address" )
 
#define EPROTO_STATUS(status)
 

Enumerations

enum  dhcpv6_session_state_flags { DHCPV6_TX_IA_NA = 0x01, DHCPV6_TX_IAADDR = 0x02, DHCPV6_RX_RECORD_SERVER_ID = 0x04, DHCPV6_RX_RECORD_IAADDR = 0x08 }
 DHCPv6 session state flags. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FILE_SECBOOT (PERMITTED)
 
static const union dhcpv6_any_optiondhcpv6_option (struct dhcpv6_option_list *options, unsigned int code)
 Find DHCPv6 option. More...
 
static int dhcpv6_check_duid (struct dhcpv6_option_list *options, unsigned int code, const void *expected, size_t len)
 Check DHCPv6 client or server identifier. More...
 
static int dhcpv6_status_code (struct dhcpv6_option_list *options)
 Get DHCPv6 status code. More...
 
static int dhcpv6_iaaddr (struct dhcpv6_option_list *options, uint32_t iaid, struct in6_addr *address)
 Get DHCPv6 identity association address. More...
 
static int dhcpv6_applies (struct settings *settings __unused, const struct setting *setting)
 Check applicability of DHCPv6 setting. More...
 
static int dhcpv6_fetch_ip6 (struct dhcpv6_settings *dhcpv6set, void *data, size_t len)
 Fetch value of DHCPv6 leased address. More...
 
static int dhcpv6_fetch_len6 (struct dhcpv6_settings *dhcpv6set __unused, void *data, size_t len)
 Fetch value of DHCPv6 implicit address prefix length. More...
 
static int dhcpv6_fetch_gateway6 (struct dhcpv6_settings *dhcpv6set, void *data, size_t len)
 Fetch value of DHCPv6 router address. More...
 
static int dhcpv6_fetch (struct settings *settings, struct setting *setting, void *data, size_t len)
 Fetch value of DHCPv6 setting. More...
 
static int dhcpv6_register (struct in6_addr *lease, struct in6_addr *router, struct dhcpv6_option_list *options, struct settings *parent)
 Register DHCPv6 options as network device settings. More...
 
static const char * dhcpv6_type_name (unsigned int type)
 Name a DHCPv6 packet type. More...
 
static void dhcpv6_free (struct refcnt *refcnt)
 Free DHCPv6 session. More...
 
static void dhcpv6_finished (struct dhcpv6_session *dhcpv6, int rc)
 Terminate DHCPv6 session. More...
 
static void dhcpv6_set_state (struct dhcpv6_session *dhcpv6, struct dhcpv6_session_state *state)
 Transition to new DHCPv6 session state. More...
 
static size_t dhcpv6_user_class (void *data, size_t len)
 Get DHCPv6 user class. More...
 
static int dhcpv6_tx (struct dhcpv6_session *dhcpv6)
 Transmit current request. More...
 
static void dhcpv6_timer_expired (struct retry_timer *timer, int fail)
 Handle timer expiry. More...
 
static int dhcpv6_rx (struct dhcpv6_session *dhcpv6, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive new data. More...
 
int start_dhcpv6 (struct interface *job, struct net_device *netdev, struct in6_addr *router, int stateful)
 Start DHCPv6. More...
 
const struct setting filename6_setting __setting (SETTING_BOOT, filename)
 Boot filename setting. More...
 
const struct setting dnssl6_setting __setting (SETTING_IP_EXTRA, dnssl)
 DNS search list setting. More...
 

Variables

struct errortab dhcpv6_errors [] __errortab
 Human-readable error messages. More...
 
static struct dhcpv6_address_operation dhcpv6_address_operations []
 DHCPv6 address settings operations. More...
 
static struct settings_operations dhcpv6_settings_operations
 DHCPv6 settings operations. More...
 
static uint8_t dhcpv6_request_options_data []
 Raw option data for options common to all DHCPv6 requests. More...
 
static struct dhcpv6_session_state dhcpv6_request
 DHCPv6 request state. More...
 
static struct dhcpv6_session_state dhcpv6_solicit
 DHCPv6 solicitation state. More...
 
static struct dhcpv6_session_state dhcpv6_information_request
 DHCPv6 information request state. More...
 
static struct interface_operation dhcpv6_job_op []
 DHCPv6 job control interface operations. More...
 
static struct interface_descriptor dhcpv6_job_desc
 DHCPv6 job control interface descriptor. More...
 
static struct interface_operation dhcpv6_xfer_op []
 DHCPv6 data transfer interface operations. More...
 
static struct interface_descriptor dhcpv6_xfer_desc
 DHCPv6 data transfer interface descriptor. More...
 

Detailed Description

Dynamic Host Configuration Protocol for IPv6.

Definition in file dhcpv6.c.

Macro Definition Documentation

◆ EPROTO_UNSPECFAIL

#define EPROTO_UNSPECFAIL   __einfo_error ( EINFO_EPROTO_UNSPECFAIL )

Definition at line 54 of file dhcpv6.c.

◆ EINFO_EPROTO_UNSPECFAIL

#define EINFO_EPROTO_UNSPECFAIL   __einfo_uniqify ( EINFO_EPROTO, 1, "Unspecified server failure" )

Definition at line 55 of file dhcpv6.c.

◆ EPROTO_NOADDRSAVAIL

#define EPROTO_NOADDRSAVAIL   __einfo_error ( EINFO_EPROTO_NOADDRSAVAIL )

Definition at line 57 of file dhcpv6.c.

◆ EINFO_EPROTO_NOADDRSAVAIL

#define EINFO_EPROTO_NOADDRSAVAIL   __einfo_uniqify ( EINFO_EPROTO, 2, "No addresses available" )

Definition at line 58 of file dhcpv6.c.

◆ EPROTO_NOBINDING

#define EPROTO_NOBINDING   __einfo_error ( EINFO_EPROTO_NOBINDING )

Definition at line 60 of file dhcpv6.c.

◆ EINFO_EPROTO_NOBINDING

#define EINFO_EPROTO_NOBINDING   __einfo_uniqify ( EINFO_EPROTO, 3, "Client record unavailable" )

Definition at line 61 of file dhcpv6.c.

◆ EPROTO_NOTONLINK

#define EPROTO_NOTONLINK   __einfo_error ( EINFO_EPROTO_NOTONLINK )

Definition at line 63 of file dhcpv6.c.

◆ EINFO_EPROTO_NOTONLINK

#define EINFO_EPROTO_NOTONLINK   __einfo_uniqify ( EINFO_EPROTO, 4, "Prefix not on link" )

Definition at line 64 of file dhcpv6.c.

◆ EPROTO_USEMULTICAST

#define EPROTO_USEMULTICAST   __einfo_error ( EINFO_EPROTO_USEMULTICAST )

Definition at line 66 of file dhcpv6.c.

◆ EINFO_EPROTO_USEMULTICAST

#define EINFO_EPROTO_USEMULTICAST   __einfo_uniqify ( EINFO_EPROTO, 5, "Use multicast address" )

Definition at line 67 of file dhcpv6.c.

◆ EPROTO_STATUS

#define EPROTO_STATUS (   status)
Value:
#define EPROTO_NOBINDING
Definition: dhcpv6.c:60
#define EPROTO_NOTONLINK
Definition: dhcpv6.c:63
#define EPROTO_NOADDRSAVAIL
Definition: dhcpv6.c:57
uint8_t status
Status.
Definition: ena.h:16
#define EUNIQ(einfo_base, uniq,...)
Disambiguate a base error based on non-constant information.
Definition: errno.h:226
#define EPROTO_USEMULTICAST
Definition: dhcpv6.c:66
#define EPROTO_UNSPECFAIL
Definition: dhcpv6.c:54
#define EINFO_EPROTO
Definition: errno.h:626

Definition at line 69 of file dhcpv6.c.

Enumeration Type Documentation

◆ dhcpv6_session_state_flags

DHCPv6 session state flags.

Enumerator
DHCPV6_TX_IA_NA 

Include identity association within request.

DHCPV6_TX_IAADDR 

Include leased IPv6 address within request.

DHCPV6_RX_RECORD_SERVER_ID 

Record received server ID.

DHCPV6_RX_RECORD_IAADDR 

Record received IPv6 address.

Definition at line 532 of file dhcpv6.c.

532  {
533  /** Include identity association within request */
534  DHCPV6_TX_IA_NA = 0x01,
535  /** Include leased IPv6 address within request */
536  DHCPV6_TX_IAADDR = 0x02,
537  /** Record received server ID */
539  /** Record received IPv6 address */
541 };
Record received server ID.
Definition: dhcpv6.c:538
Include leased IPv6 address within request.
Definition: dhcpv6.c:536
Record received IPv6 address.
Definition: dhcpv6.c:540
Include identity association within request.
Definition: dhcpv6.c:534

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ dhcpv6_option()

static const union dhcpv6_any_option* dhcpv6_option ( struct dhcpv6_option_list options,
unsigned int  code 
)
static

Find DHCPv6 option.

Parameters
optionsDHCPv6 option list
codeOption code
Return values
optionDHCPv6 option, or NULL if not found

Definition at line 101 of file dhcpv6.c.

101  {
102  const union dhcpv6_any_option *option = options->data;
103  size_t remaining = options->len;
104  size_t data_len;
105 
106  /* Scan through list of options */
107  while ( remaining >= sizeof ( option->header ) ) {
108 
109  /* Calculate and validate option length */
110  remaining -= sizeof ( option->header );
111  data_len = ntohs ( option->header.len );
112  if ( data_len > remaining ) {
113  /* Malformed option list */
114  return NULL;
115  }
116 
117  /* Return if we have found the specified option */
118  if ( option->header.code == htons ( code ) )
119  return option;
120 
121  /* Otherwise, move to the next option */
122  option = ( ( ( void * ) option->header.data ) + data_len );
123  remaining -= data_len;
124  }
125 
126  return NULL;
127 }
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
#define ntohs(value)
Definition: byteswap.h:137
static unsigned int code
Response code.
Definition: hyperv.h:26
Any DHCPv6 option.
Definition: dhcpv6.h:226
A long option, as used for getopt_long()
Definition: getopt.h:25
static int options
Definition: 3c515.c:286
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define htons(value)
Definition: byteswap.h:136

References code, data_len, htons, ntohs, NULL, and options.

Referenced by dhcpv6_check_duid(), dhcpv6_fetch(), dhcpv6_iaaddr(), dhcpv6_rx(), and dhcpv6_status_code().

◆ dhcpv6_check_duid()

static int dhcpv6_check_duid ( struct dhcpv6_option_list options,
unsigned int  code,
const void *  expected,
size_t  len 
)
static

Check DHCPv6 client or server identifier.

Parameters
optionsDHCPv6 option list
codeOption code
expectedExpected value
lenLength of expected value
Return values
rcReturn status code

Definition at line 138 of file dhcpv6.c.

140  {
141  const union dhcpv6_any_option *option;
142  const struct dhcpv6_duid_option *duid;
143 
144  /* Find option */
146  if ( ! option )
147  return -ENOENT;
148  duid = &option->duid;
149 
150  /* Check option length */
151  if ( ntohs ( duid->header.len ) != len )
152  return -EINVAL;
153 
154  /* Compare option value */
155  if ( memcmp ( duid->duid, expected, len ) != 0 )
156  return -EINVAL;
157 
158  return 0;
159 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
uint8_t duid[0]
DHCP unique identifier (DUID)
Definition: dhcpv6.h:52
#define ENOENT
No such file or directory.
Definition: errno.h:515
#define ntohs(value)
Definition: byteswap.h:137
static unsigned int code
Response code.
Definition: hyperv.h:26
Any DHCPv6 option.
Definition: dhcpv6.h:226
A long option, as used for getopt_long()
Definition: getopt.h:25
static int options
Definition: 3c515.c:286
ring len
Length.
Definition: dwmac.h:231
DHCPv6 client or server identifier option.
Definition: dhcpv6.h:48
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:101
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115

References code, dhcpv6_option(), dhcpv6_duid_option::duid, EINVAL, ENOENT, len, memcmp(), ntohs, and options.

Referenced by dhcpv6_rx().

◆ dhcpv6_status_code()

static int dhcpv6_status_code ( struct dhcpv6_option_list options)
static

Get DHCPv6 status code.

Parameters
optionsDHCPv6 option list
Return values
rcReturn status code

Definition at line 167 of file dhcpv6.c.

167  {
168  const union dhcpv6_any_option *option;
169  const struct dhcpv6_status_code_option *status_code;
170  unsigned int status;
171 
172  /* Find status code option, if present */
174  if ( ! option ) {
175  /* Omitted status code should be treated as "success" */
176  return 0;
177  }
178  status_code = &option->status_code;
179 
180  /* Sanity check */
181  if ( ntohs ( status_code->header.len ) <
182  ( sizeof ( *status_code ) - sizeof ( status_code->header ) ) ) {
183  return -EINVAL;
184  }
185 
186  /* Calculate iPXE error code from DHCPv6 status code */
187  status = ntohs ( status_code->status );
188  return ( status ? -EPROTO_STATUS ( status ) : 0 );
189 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
uint16_t status
Status code.
Definition: dhcpv6.h:122
#define EPROTO_STATUS(status)
Definition: dhcpv6.c:69
#define ntohs(value)
Definition: byteswap.h:137
Any DHCPv6 option.
Definition: dhcpv6.h:226
A long option, as used for getopt_long()
Definition: getopt.h:25
static int options
Definition: 3c515.c:286
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:120
DHCPv6 status code option.
Definition: dhcpv6.h:118
uint8_t status
Status.
Definition: ena.h:16
uint16_t len
Length of the data field.
Definition: dhcpv6.h:31
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:101
#define DHCPV6_STATUS_CODE
DHCPv6 status code option.
Definition: dhcpv6.h:128

References dhcpv6_option(), DHCPV6_STATUS_CODE, EINVAL, EPROTO_STATUS, dhcpv6_status_code_option::header, dhcpv6_option::len, ntohs, options, status, and dhcpv6_status_code_option::status.

Referenced by dhcpv6_iaaddr(), and dhcpv6_rx().

◆ dhcpv6_iaaddr()

static int dhcpv6_iaaddr ( struct dhcpv6_option_list options,
uint32_t  iaid,
struct in6_addr address 
)
static

Get DHCPv6 identity association address.

Parameters
optionsDHCPv6 option list
iaidIdentity association ID
addressIPv6 address to fill in
Return values
rcReturn status code

Definition at line 199 of file dhcpv6.c.

200  {
201  const union dhcpv6_any_option *option;
202  const struct dhcpv6_ia_na_option *ia_na;
203  const struct dhcpv6_iaaddr_option *iaaddr;
204  struct dhcpv6_option_list suboptions;
205  size_t len;
206  int rc;
207 
208  /* Find identity association option, if present */
210  if ( ! option )
211  return -ENOENT;
212  ia_na = &option->ia_na;
213 
214  /* Sanity check */
215  len = ntohs ( ia_na->header.len );
216  if ( len < ( sizeof ( *ia_na ) - sizeof ( ia_na->header ) ) )
217  return -EINVAL;
218 
219  /* Check identity association ID */
220  if ( ia_na->iaid != htonl ( iaid ) )
221  return -EINVAL;
222 
223  /* Construct IA_NA sub-options list */
224  suboptions.data = ia_na->options;
225  suboptions.len = ( len + sizeof ( ia_na->header ) -
226  offsetof ( typeof ( *ia_na ), options ) );
227 
228  /* Check IA_NA status code */
229  if ( ( rc = dhcpv6_status_code ( &suboptions ) ) != 0 )
230  return rc;
231 
232  /* Find identity association address, if present */
233  option = dhcpv6_option ( &suboptions, DHCPV6_IAADDR );
234  if ( ! option )
235  return -ENOENT;
236  iaaddr = &option->iaaddr;
237 
238  /* Sanity check */
239  len = ntohs ( iaaddr->header.len );
240  if ( len < ( sizeof ( *iaaddr ) - sizeof ( iaaddr->header ) ) )
241  return -EINVAL;
242 
243  /* Construct IAADDR sub-options list */
244  suboptions.data = iaaddr->options;
245  suboptions.len = ( len + sizeof ( iaaddr->header ) -
246  offsetof ( typeof ( *iaaddr ), options ) );
247 
248  /* Check IAADDR status code */
249  if ( ( rc = dhcpv6_status_code ( &suboptions ) ) != 0 )
250  return rc;
251 
252  /* Extract IPv6 address */
253  memcpy ( address, &iaaddr->address, sizeof ( *address ) );
254 
255  return 0;
256 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DHCPV6_IA_NA
DHCPv6 identity association for non-temporary address (IA_NA) option.
Definition: dhcpv6.h:76
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:81
uint64_t address
Base address.
Definition: ena.h:24
struct dhcpv6_option options[0]
IA_NA options.
Definition: dhcpv6.h:72
static int dhcpv6_status_code(struct dhcpv6_option_list *options)
Get DHCPv6 status code.
Definition: dhcpv6.c:167
uint32_t iaid
Identity association identifier (IAID)
Definition: dhcpv6.h:66
#define ENOENT
No such file or directory.
Definition: errno.h:515
#define ntohs(value)
Definition: byteswap.h:137
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:25
#define htonl(value)
Definition: byteswap.h:134
Any DHCPv6 option.
Definition: dhcpv6.h:226
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A long option, as used for getopt_long()
Definition: getopt.h:25
struct dhcpv6_option options[0]
IAADDR options.
Definition: dhcpv6.h:89
static int options
Definition: 3c515.c:286
ring len
Length.
Definition: dwmac.h:231
struct in6_addr address
IPv6 address.
Definition: dhcpv6.h:83
DHCPv6 identity association address (IAADDR) option.
Definition: dhcpv6.h:79
A DHCPv6 option list.
Definition: dhcpv6.c:86
uint16_t len
Length of the data field.
Definition: dhcpv6.h:31
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:64
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:101
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:48
#define DHCPV6_IAADDR
DHCPv6 identity association address (IAADDR) option.
Definition: dhcpv6.h:93
DHCPv6 identity association for non-temporary address (IA_NA) option.
Definition: dhcpv6.h:62

References address, dhcpv6_iaaddr_option::address, dhcpv6_option_list::data, DHCPV6_IA_NA, DHCPV6_IAADDR, dhcpv6_option(), dhcpv6_status_code(), EINVAL, ENOENT, dhcpv6_ia_na_option::header, dhcpv6_iaaddr_option::header, htonl, dhcpv6_ia_na_option::iaid, dhcpv6_option::len, dhcpv6_option_list::len, len, memcpy(), ntohs, offsetof, dhcpv6_ia_na_option::options, dhcpv6_iaaddr_option::options, options, rc, and typeof().

Referenced by dhcpv6_rx().

◆ dhcpv6_applies()

static int dhcpv6_applies ( struct settings *settings  __unused,
const struct setting setting 
)
static

Check applicability of DHCPv6 setting.

Parameters
settingsSettings block
settingSetting
Return values
appliesSetting applies within this settings block

Definition at line 285 of file dhcpv6.c.

286  {
287 
288  return ( ( setting->scope == &dhcpv6_scope ) ||
289  ( setting->scope == &ipv6_settings_scope ) );
290 }
const struct settings_scope dhcpv6_scope
IPv6 settings scope.
Definition: settings.c:1793
A setting.
Definition: settings.h:24
const struct settings_scope ipv6_settings_scope
IPv6 settings scope.
Definition: ipv6.c:1121
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:50

References dhcpv6_scope, ipv6_settings_scope, and setting::scope.

◆ dhcpv6_fetch_ip6()

static int dhcpv6_fetch_ip6 ( struct dhcpv6_settings dhcpv6set,
void *  data,
size_t  len 
)
static

Fetch value of DHCPv6 leased address.

Parameters
dhcpv6setDHCPv6 settings
dataBuffer to fill with setting data
lenLength of buffer
Return values
lenLength of setting data, or negative error

Definition at line 300 of file dhcpv6.c.

301  {
302  struct in6_addr *lease = &dhcpv6set->lease;
303 
304  /* Copy leased address */
305  if ( len > sizeof ( *lease ) )
306  len = sizeof ( *lease );
307  memcpy ( data, lease, len );
308 
309  return sizeof ( *lease );
310 }
struct in6_addr lease
Leased address.
Definition: dhcpv6.c:271
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
IP6 address structure.
Definition: in.h:51
uint32_t lease
Definition: ib_mad.h:16
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References data, lease, dhcpv6_settings::lease, len, and memcpy().

◆ dhcpv6_fetch_len6()

static int dhcpv6_fetch_len6 ( struct dhcpv6_settings *dhcpv6set  __unused,
void *  data,
size_t  len 
)
static

Fetch value of DHCPv6 implicit address prefix length.

Parameters
dhcpv6setDHCPv6 settings
dataBuffer to fill with setting data
lenLength of buffer
Return values
lenLength of setting data, or negative error

Definition at line 320 of file dhcpv6.c.

321  {
322  uint8_t *len6 = data;
323 
324  /* Default to assuming this is the only address on the link.
325  * If the address falls within a known prefix, then the IPv6
326  * routing table construction logic will match it against that
327  * prefix.
328  */
329  if ( len )
330  *len6 = IPV6_MAX_PREFIX_LEN;
331 
332  return sizeof ( *len6 );
333 }
#define IPV6_MAX_PREFIX_LEN
IPv6 maximum prefix length.
Definition: ipv6.h:33
ring len
Length.
Definition: dwmac.h:231
unsigned char uint8_t
Definition: stdint.h:10
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References data, IPV6_MAX_PREFIX_LEN, and len.

◆ dhcpv6_fetch_gateway6()

static int dhcpv6_fetch_gateway6 ( struct dhcpv6_settings dhcpv6set,
void *  data,
size_t  len 
)
static

Fetch value of DHCPv6 router address.

Parameters
dhcpv6setDHCPv6 settings
dataBuffer to fill with setting data
lenLength of buffer
Return values
lenLength of setting data, or negative error

Definition at line 343 of file dhcpv6.c.

344  {
345  struct in6_addr *router = &dhcpv6set->router;
346 
347  /* Copy router address */
348  if ( len > sizeof ( *router ) )
349  len = sizeof ( *router );
350  memcpy ( data, router, len );
351 
352  return sizeof ( *router );
353 }
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
IP6 address structure.
Definition: in.h:51
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct in6_addr router
Router address.
Definition: dhcpv6.c:273

References data, len, memcpy(), and dhcpv6_settings::router.

◆ dhcpv6_fetch()

static int dhcpv6_fetch ( struct settings settings,
struct setting setting,
void *  data,
size_t  len 
)
static

Fetch value of DHCPv6 setting.

Parameters
settingsSettings block
settingSetting to fetch
dataBuffer to fill with setting data
lenLength of buffer
Return values
lenLength of setting data, or negative error

Definition at line 387 of file dhcpv6.c.

389  {
390  struct dhcpv6_settings *dhcpv6set =
392  const union dhcpv6_any_option *option;
394  size_t option_len;
395  unsigned int i;
396 
397  /* Handle address settings */
398  for ( i = 0 ; i < ( sizeof ( dhcpv6_address_operations ) /
399  sizeof ( dhcpv6_address_operations[0] ) ) ; i++ ) {
401  if ( setting_cmp ( setting, op->setting ) != 0 )
402  continue;
403  if ( IN6_IS_ADDR_UNSPECIFIED ( &dhcpv6set->lease ) )
404  return -ENOENT;
405  return op->fetch ( dhcpv6set, data, len );
406  }
407 
408  /* Find option */
409  option = dhcpv6_option ( &dhcpv6set->options, setting->tag );
410  if ( ! option )
411  return -ENOENT;
412 
413  /* Copy option to data buffer */
414  option_len = ntohs ( option->header.len );
415  if ( len > option_len )
416  len = option_len;
417  memcpy ( data, option->header.data, len );
418  return option_len;
419 }
#define ENOENT
No such file or directory.
Definition: errno.h:515
#define ntohs(value)
Definition: byteswap.h:137
A DHCPv6 settings block.
Definition: dhcpv6.c:265
Any DHCPv6 option.
Definition: dhcpv6.h:226
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:44
struct in6_addr lease
Leased address.
Definition: dhcpv6.c:271
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
A long option, as used for getopt_long()
Definition: getopt.h:25
ring len
Length.
Definition: dwmac.h:231
struct dhcpv6_option_list options
Option list.
Definition: dhcpv6.c:275
#define IN6_IS_ADDR_UNSPECIFIED(addr)
Definition: in.h:62
A settings block.
Definition: settings.h:133
static struct dhcpv6_address_operation dhcpv6_address_operations[]
DHCPv6 address settings operations.
Definition: dhcpv6.c:372
A setting.
Definition: settings.h:24
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
A DHCPv6 address setting operation.
Definition: dhcpv6.c:356
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:101
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int setting_cmp(const struct setting *a, const struct setting *b)
Compare two settings.
Definition: settings.c:1121

References container_of, data, dhcpv6_address_operations, dhcpv6_option(), ENOENT, IN6_IS_ADDR_UNSPECIFIED, dhcpv6_settings::lease, len, memcpy(), ntohs, op, dhcpv6_settings::options, setting_cmp(), and setting::tag.

◆ dhcpv6_register()

static int dhcpv6_register ( struct in6_addr lease,
struct in6_addr router,
struct dhcpv6_option_list options,
struct settings parent 
)
static

Register DHCPv6 options as network device settings.

Parameters
leaseDHCPv6 leased address
routerDHCPv6 router address
optionsDHCPv6 option list
parentParent settings block
Return values
rcReturn status code

Definition at line 436 of file dhcpv6.c.

438  {
439  struct dhcpv6_settings *dhcpv6set;
440  void *data;
441  size_t len;
442  int rc;
443 
444  /* Allocate and initialise structure */
445  dhcpv6set = zalloc ( sizeof ( *dhcpv6set ) + options->len );
446  if ( ! dhcpv6set ) {
447  rc = -ENOMEM;
448  goto err_alloc;
449  }
450  ref_init ( &dhcpv6set->refcnt, NULL );
452  &dhcpv6set->refcnt, &dhcpv6_scope );
453  dhcpv6set->settings.order = IPV6_ORDER_DHCPV6;
454  data = ( ( ( void * ) dhcpv6set ) + sizeof ( *dhcpv6set ) );
455  len = options->len;
456  memcpy ( data, options->data, len );
457  dhcpv6set->options.data = data;
458  dhcpv6set->options.len = len;
459  memcpy ( &dhcpv6set->lease, lease, sizeof ( dhcpv6set->lease ) );
460  memcpy ( &dhcpv6set->router, router, sizeof ( dhcpv6set->router ) );
461 
462  /* Register settings */
463  if ( ( rc = register_settings ( &dhcpv6set->settings, parent,
464  DHCPV6_SETTINGS_NAME ) ) != 0 )
465  goto err_register;
466 
467  err_register:
468  ref_put ( &dhcpv6set->refcnt );
469  err_alloc:
470  return rc;
471 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const struct settings_scope dhcpv6_scope
IPv6 settings scope.
Definition: settings.c:1793
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
size_t len
Length of data buffer.
Definition: dhcpv6.c:90
#define DHCPV6_SETTINGS_NAME
DHCPv6 settings block name.
Definition: dhcpv6.h:266
static struct settings_operations dhcpv6_settings_operations
DHCPv6 settings operations.
Definition: dhcpv6.c:422
Address assigned via DHCPv6.
Definition: ipv6.h:289
A DHCPv6 settings block.
Definition: dhcpv6.c:265
static void settings_init(struct settings *settings, struct settings_operations *op, struct refcnt *refcnt, const struct settings_scope *default_scope)
Initialise a settings block.
Definition: settings.h:503
#define ENOMEM
Not enough space.
Definition: errno.h:535
struct in6_addr lease
Leased address.
Definition: dhcpv6.c:271
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int options
Definition: 3c515.c:286
struct settings settings
Settings block.
Definition: dhcpv6.c:269
ring len
Length.
Definition: dwmac.h:231
struct dhcpv6_option_list options
Option list.
Definition: dhcpv6.c:275
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
uint32_t lease
Definition: ib_mad.h:16
int order
Sibling ordering.
Definition: settings.h:149
struct refcnt refcnt
Reference count.
Definition: dhcpv6.c:267
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:476
struct in6_addr router
Router address.
Definition: dhcpv6.c:273
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
const void * data
Data buffer.
Definition: dhcpv6.c:88
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107

References data, dhcpv6_option_list::data, dhcpv6_scope, DHCPV6_SETTINGS_NAME, dhcpv6_settings_operations, ENOMEM, IPV6_ORDER_DHCPV6, lease, dhcpv6_settings::lease, dhcpv6_option_list::len, len, memcpy(), NULL, dhcpv6_settings::options, options, settings::order, rc, ref_init, ref_put, dhcpv6_settings::refcnt, register_settings(), dhcpv6_settings::router, dhcpv6_settings::settings, settings_init(), and zalloc().

Referenced by dhcpv6_rx().

◆ dhcpv6_type_name()

static const char* dhcpv6_type_name ( unsigned int  type)
static

Name a DHCPv6 packet type.

Parameters
typeDHCPv6 packet type
Return values
nameDHCPv6 packet type name

Definition at line 504 of file dhcpv6.c.

504  {
505  static char buf[ 12 /* "UNKNOWN-xxx" + NUL */ ];
506 
507  switch ( type ) {
508  case DHCPV6_SOLICIT: return "SOLICIT";
509  case DHCPV6_ADVERTISE: return "ADVERTISE";
510  case DHCPV6_REQUEST: return "REQUEST";
511  case DHCPV6_REPLY: return "REPLY";
512  case DHCPV6_INFORMATION_REQUEST: return "INFORMATION-REQUEST";
513  default:
514  snprintf ( buf, sizeof ( buf ), "UNKNOWN-%d", type );
515  return buf;
516  }
517 }
#define DHCPV6_SOLICIT
DHCPv6 solicitation.
Definition: dhcpv6.h:251
uint32_t type
Operating system type.
Definition: ena.h:12
#define DHCPV6_INFORMATION_REQUEST
DHCPv6 information request.
Definition: dhcpv6.h:263
#define DHCPV6_REPLY
DHCPv6 reply.
Definition: dhcpv6.h:260
#define DHCPV6_ADVERTISE
DHCPv6 advertisement.
Definition: dhcpv6.h:254
#define DHCPV6_REQUEST
DHCPv6 request.
Definition: dhcpv6.h:257
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383

References DHCPV6_ADVERTISE, DHCPV6_INFORMATION_REQUEST, DHCPV6_REPLY, DHCPV6_REQUEST, DHCPV6_SOLICIT, snprintf(), and type.

Referenced by dhcpv6_rx(), and dhcpv6_set_state().

◆ dhcpv6_free()

static void dhcpv6_free ( struct refcnt refcnt)
static

Free DHCPv6 session.

Parameters
refcntReference count

Definition at line 611 of file dhcpv6.c.

611  {
612  struct dhcpv6_session *dhcpv6 =
614 
615  netdev_put ( dhcpv6->netdev );
616  free ( dhcpv6->server_duid );
617  free ( dhcpv6 );
618 }
A DHCPv6 session.
Definition: dhcpv6.c:570
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:579
A reference counter.
Definition: refcnt.h:27
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:576
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
void * server_duid
Server DUID, if known.
Definition: dhcpv6.c:591
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55

References container_of, free, dhcpv6_session::netdev, netdev_put(), and dhcpv6_session::server_duid.

Referenced by start_dhcpv6().

◆ dhcpv6_finished()

static void dhcpv6_finished ( struct dhcpv6_session dhcpv6,
int  rc 
)
static

Terminate DHCPv6 session.

Parameters
dhcpv6DHCPv6 session
rcReason for close

Definition at line 626 of file dhcpv6.c.

626  {
627 
628  /* Stop timer */
629  stop_timer ( &dhcpv6->timer );
630 
631  /* Shut down interfaces */
632  intf_shutdown ( &dhcpv6->xfer, rc );
633  intf_shutdown ( &dhcpv6->job, rc );
634 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:279
struct interface xfer
Data transfer interface.
Definition: dhcpv6.c:576
struct interface job
Job control interface.
Definition: dhcpv6.c:574
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:598
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:118

References intf_shutdown(), dhcpv6_session::job, rc, stop_timer(), dhcpv6_session::timer, and dhcpv6_session::xfer.

Referenced by dhcpv6_rx(), dhcpv6_timer_expired(), and start_dhcpv6().

◆ dhcpv6_set_state()

static void dhcpv6_set_state ( struct dhcpv6_session dhcpv6,
struct dhcpv6_session_state state 
)
static

Transition to new DHCPv6 session state.

Parameters
dhcpv6DHCPv6 session
stateNew session state

Definition at line 642 of file dhcpv6.c.

643  {
644 
645  DBGC ( dhcpv6, "DHCPv6 %s entering %s state\n", dhcpv6->netdev->name,
646  dhcpv6_type_name ( state->tx_type ) );
647 
648  /* Record state */
649  dhcpv6->state = state;
650 
651  /* Default to -ETIMEDOUT if no more specific error is recorded */
652  dhcpv6->rc = -ETIMEDOUT;
653 
654  /* Start timer to trigger transmission */
655  start_timer_nodelay ( &dhcpv6->timer );
656 }
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:100
uint8_t state
State.
Definition: eth_slow.h:48
#define DBGC(...)
Definition: compiler.h:505
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:579
static const char * dhcpv6_type_name(unsigned int type)
Name a DHCPv6 packet type.
Definition: dhcpv6.c:504
struct dhcpv6_session_state * state
Current session state.
Definition: dhcpv6.c:601
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:598
int rc
Current timeout status code.
Definition: dhcpv6.c:603
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:670

References DBGC, dhcpv6_type_name(), ETIMEDOUT, net_device::name, dhcpv6_session::netdev, dhcpv6_session::rc, start_timer_nodelay(), state, dhcpv6_session::state, and dhcpv6_session::timer.

Referenced by dhcpv6_rx(), and start_dhcpv6().

◆ dhcpv6_user_class()

static size_t dhcpv6_user_class ( void *  data,
size_t  len 
)
static

Get DHCPv6 user class.

Parameters
dataData buffer
lenLength of data buffer
Return values
lenLength of user class

Definition at line 665 of file dhcpv6.c.

665  {
666  static const char default_user_class[4] = { 'i', 'P', 'X', 'E' };
667  int actual_len;
668 
669  /* Fetch user-class setting, if defined */
670  actual_len = fetch_raw_setting ( NULL, &user_class_setting, data, len );
671  if ( actual_len >= 0 )
672  return actual_len;
673 
674  /* Otherwise, use the default user class ("iPXE") */
675  if ( len > sizeof ( default_user_class ) )
676  len = sizeof ( default_user_class );
677  memcpy ( data, default_user_class, len );
678  return sizeof ( default_user_class );
679 }
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:804
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References data, fetch_raw_setting(), len, memcpy(), and NULL.

Referenced by dhcpv6_tx().

◆ dhcpv6_tx()

static int dhcpv6_tx ( struct dhcpv6_session dhcpv6)
static

Transmit current request.

Parameters
dhcpv6DHCPv6 session
Return values
rcReturn status code

Definition at line 687 of file dhcpv6.c.

687  {
688  struct dhcpv6_duid_option *client_id;
689  struct dhcpv6_duid_option *server_id;
690  struct dhcpv6_ia_na_option *ia_na;
691  struct dhcpv6_iaaddr_option *iaaddr;
694  struct dhcpv6_header *dhcphdr;
695  struct io_buffer *iobuf;
696  void *options;
697  size_t client_id_len;
698  size_t server_id_len;
699  size_t ia_na_len;
700  size_t user_class_string_len;
701  size_t user_class_len;
702  size_t elapsed_len;
703  size_t total_len;
704  int rc;
705 
706  /* Calculate lengths */
707  client_id_len = ( sizeof ( *client_id ) +
708  sizeof ( dhcpv6->client_duid ) );
709  server_id_len = ( dhcpv6->server_duid ? ( sizeof ( *server_id ) +
710  dhcpv6->server_duid_len ) :0);
711  if ( dhcpv6->state->flags & DHCPV6_TX_IA_NA ) {
712  ia_na_len = sizeof ( *ia_na );
713  if ( dhcpv6->state->flags & DHCPV6_TX_IAADDR )
714  ia_na_len += sizeof ( *iaaddr );
715  } else {
716  ia_na_len = 0;
717  }
718  user_class_string_len = dhcpv6_user_class ( NULL, 0 );
719  user_class_len = ( sizeof ( *user_class ) +
720  sizeof ( user_class->user_class[0] ) +
721  user_class_string_len );
722  elapsed_len = sizeof ( *elapsed );
723  total_len = ( sizeof ( *dhcphdr ) + client_id_len + server_id_len +
724  ia_na_len + sizeof ( dhcpv6_request_options_data ) +
725  user_class_len + elapsed_len );
726 
727  /* Allocate packet */
728  iobuf = xfer_alloc_iob ( &dhcpv6->xfer, total_len );
729  if ( ! iobuf )
730  return -ENOMEM;
731 
732  /* Construct header */
733  dhcphdr = iob_put ( iobuf, sizeof ( *dhcphdr ) );
734  dhcphdr->type = dhcpv6->state->tx_type;
735  memcpy ( dhcphdr->xid, dhcpv6->xid, sizeof ( dhcphdr->xid ) );
736 
737  /* Construct client identifier */
738  client_id = iob_put ( iobuf, client_id_len );
739  client_id->header.code = htons ( DHCPV6_CLIENT_ID );
740  client_id->header.len = htons ( client_id_len -
741  sizeof ( client_id->header ) );
742  memcpy ( client_id->duid, &dhcpv6->client_duid,
743  sizeof ( dhcpv6->client_duid ) );
744 
745  /* Construct server identifier, if applicable */
746  if ( server_id_len ) {
747  server_id = iob_put ( iobuf, server_id_len );
748  server_id->header.code = htons ( DHCPV6_SERVER_ID );
749  server_id->header.len = htons ( server_id_len -
750  sizeof ( server_id->header ) );
751  memcpy ( server_id->duid, dhcpv6->server_duid,
752  dhcpv6->server_duid_len );
753  }
754 
755  /* Construct identity association, if applicable */
756  if ( ia_na_len ) {
757  ia_na = iob_put ( iobuf, ia_na_len );
758  ia_na->header.code = htons ( DHCPV6_IA_NA );
759  ia_na->header.len = htons ( ia_na_len -
760  sizeof ( ia_na->header ) );
761  ia_na->iaid = htonl ( dhcpv6->iaid );
762  ia_na->renew = htonl ( 0 );
763  ia_na->rebind = htonl ( 0 );
764  if ( dhcpv6->state->flags & DHCPV6_TX_IAADDR ) {
765  iaaddr = ( ( void * ) ia_na->options );
766  iaaddr->header.code = htons ( DHCPV6_IAADDR );
767  iaaddr->header.len = htons ( sizeof ( *iaaddr ) -
768  sizeof ( iaaddr->header ));
769  memcpy ( &iaaddr->address, &dhcpv6->lease,
770  sizeof ( iaaddr->address ) );
771  iaaddr->preferred = htonl ( 0 );
772  iaaddr->valid = htonl ( 0 );
773  }
774  }
775 
776  /* Construct fixed request options */
777  options = iob_put ( iobuf, sizeof ( dhcpv6_request_options_data ) );
779  sizeof ( dhcpv6_request_options_data ) );
780 
781  /* Construct user class */
782  user_class = iob_put ( iobuf, user_class_len );
783  user_class->header.code = htons ( DHCPV6_USER_CLASS );
784  user_class->header.len = htons ( user_class_len -
785  sizeof ( user_class->header ) );
786  user_class->user_class[0].len = htons ( user_class_string_len );
787  dhcpv6_user_class ( user_class->user_class[0].string,
788  user_class_string_len );
789 
790  /* Construct elapsed time */
791  elapsed = iob_put ( iobuf, elapsed_len );
792  elapsed->header.code = htons ( DHCPV6_ELAPSED_TIME );
793  elapsed->header.len = htons ( elapsed_len -
794  sizeof ( elapsed->header ) );
795  elapsed->elapsed = htons ( ( ( currticks() - dhcpv6->start ) * 100 ) /
796  TICKS_PER_SEC );
797 
798  /* Sanity check */
799  assert ( iob_len ( iobuf ) == total_len );
800 
801  /* Transmit packet */
802  if ( ( rc = xfer_deliver_iob ( &dhcpv6->xfer, iobuf ) ) != 0 ) {
803  DBGC ( dhcpv6, "DHCPv6 %s could not transmit: %s\n",
804  dhcpv6->netdev->name, strerror ( rc ) );
805  return rc;
806  }
807 
808  return 0;
809 }
#define DHCPV6_SERVER_ID
DHCPv6 server identifier option.
Definition: dhcpv6.h:59
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
char string[0]
User class string.
Definition: dhcpv6.h:135
#define iob_put(iobuf, len)
Definition: iobuf.h:125
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:16
#define DHCPV6_ELAPSED_TIME
DHCPv6 elapsed time option.
Definition: dhcpv6.h:115
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:256
struct interface xfer
Data transfer interface.
Definition: dhcpv6.c:576
Include leased IPv6 address within request.
Definition: dhcpv6.c:536
static uint8_t dhcpv6_request_options_data[]
Raw option data for options common to all DHCPv6 requests.
Definition: dhcpv6.c:480
#define DHCPV6_IA_NA
DHCPv6 identity association for non-temporary address (IA_NA) option.
Definition: dhcpv6.h:76
uint16_t len
Length.
Definition: dhcpv6.h:133
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:81
uint8_t duid[0]
DHCP unique identifier (DUID)
Definition: dhcpv6.h:52
#define DHCPV6_USER_CLASS
DHCPv6 user class option.
Definition: dhcpv6.h:147
struct dhcpv6_option options[0]
IA_NA options.
Definition: dhcpv6.h:72
uint32_t iaid
Identity association identifier (IAID)
Definition: dhcpv6.h:66
#define DBGC(...)
Definition: compiler.h:505
uint32_t iaid
Identity association ID.
Definition: dhcpv6.c:585
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:579
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:159
uint32_t xid
Transaction ID.
Definition: dhcp.h:634
uint8_t tx_type
Current transmitted packet type.
Definition: dhcpv6.c:522
DHCPv6 user class option.
Definition: dhcpv6.h:139
A DHCPv6 header.
Definition: dhcpv6.h:241
struct in6_addr lease
Leased IPv6 address.
Definition: dhcpv6.c:595
#define htonl(value)
Definition: byteswap.h:134
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:109
struct dhcpv6_session_state * state
Current session state.
Definition: dhcpv6.c:601
#define ENOMEM
Not enough space.
Definition: errno.h:535
#define DHCPV6_CLIENT_ID
DHCPv6 client identifier option.
Definition: dhcpv6.h:56
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t valid
Valid lifetime (in seconds)
Definition: dhcpv6.h:87
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint8_t flags
Flags.
Definition: dhcpv6.c:526
static int options
Definition: 3c515.c:286
void * server_duid
Server DUID, if known.
Definition: dhcpv6.c:591
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
uint32_t rebind
Rebind time (in seconds)
Definition: dhcpv6.h:70
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
struct in6_addr address
IPv6 address.
Definition: dhcpv6.h:83
DHCPv6 client or server identifier option.
Definition: dhcpv6.h:48
DHCPv6 identity association address (IAADDR) option.
Definition: dhcpv6.h:79
A DHCP header.
Definition: dhcp.h:616
uint32_t renew
Renew time (in seconds)
Definition: dhcpv6.h:68
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
size_t server_duid_len
Server DUID length.
Definition: dhcpv6.c:593
uint16_t len
Length of the data field.
Definition: dhcpv6.h:31
unsigned long start
Start time (in ticks)
Definition: dhcpv6.c:587
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:64
struct dhcpv6_duid_uuid client_duid
Client DUID.
Definition: dhcpv6.c:589
uint8_t xid[3]
Transaction ID.
Definition: dhcpv6.c:583
#define DHCPV6_IAADDR
DHCPv6 identity association address (IAADDR) option.
Definition: dhcpv6.h:93
uint16_t elapsed
Elapsed time, in centiseconds.
Definition: dhcpv6.h:111
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:43
static size_t dhcpv6_user_class(void *data, size_t len)
Get DHCPv6 user class.
Definition: dhcpv6.c:665
uint32_t preferred
Preferred lifetime (in seconds)
Definition: dhcpv6.h:85
uint16_t code
Code.
Definition: dhcpv6.h:29
Include identity association within request.
Definition: dhcpv6.c:534
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:50
DHCPv6 identity association for non-temporary address (IA_NA) option.
Definition: dhcpv6.h:62
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define htons(value)
Definition: byteswap.h:136
struct dhcpv6_user_class user_class[0]
User class.
Definition: dhcpv6.h:143
A persistent I/O buffer.
Definition: iobuf.h:38
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:141
DHCPv6 elapsed time option.
Definition: dhcpv6.h:107

References dhcpv6_iaaddr_option::address, assert(), dhcpv6_session::client_duid, dhcpv6_option::code, currticks(), DBGC, DHCPV6_CLIENT_ID, DHCPV6_ELAPSED_TIME, DHCPV6_IA_NA, DHCPV6_IAADDR, dhcpv6_request_options_data, DHCPV6_SERVER_ID, DHCPV6_TX_IA_NA, DHCPV6_TX_IAADDR, DHCPV6_USER_CLASS, dhcpv6_user_class(), dhcpv6_duid_option::duid, dhcpv6_elapsed_time_option::elapsed, ENOMEM, dhcpv6_session_state::flags, dhcpv6_duid_option::header, dhcpv6_ia_na_option::header, dhcpv6_iaaddr_option::header, dhcpv6_elapsed_time_option::header, dhcpv6_user_class_option::header, htonl, htons, dhcpv6_ia_na_option::iaid, dhcpv6_session::iaid, iob_len(), iob_put, dhcpv6_session::lease, dhcpv6_option::len, dhcpv6_user_class::len, memcpy(), net_device::name, dhcpv6_session::netdev, NULL, dhcpv6_ia_na_option::options, options, dhcpv6_iaaddr_option::preferred, rc, dhcpv6_ia_na_option::rebind, dhcpv6_ia_na_option::renew, dhcpv6_session::server_duid, dhcpv6_session::server_duid_len, dhcpv6_session::start, dhcpv6_session::state, strerror(), dhcpv6_user_class::string, TICKS_PER_SEC, dhcpv6_session_state::tx_type, dhcpv6_user_class_option::user_class, dhcpv6_iaaddr_option::valid, dhcpv6_session::xfer, xfer_alloc_iob(), xfer_deliver_iob(), dhcpv6_session::xid, and dhcphdr::xid.

Referenced by dhcpv6_timer_expired().

◆ dhcpv6_timer_expired()

static void dhcpv6_timer_expired ( struct retry_timer timer,
int  fail 
)
static

Handle timer expiry.

Parameters
timerRetransmission timer
failFailure indicator

Definition at line 817 of file dhcpv6.c.

817  {
818  struct dhcpv6_session *dhcpv6 =
819  container_of ( timer, struct dhcpv6_session, timer );
820 
821  /* If we have failed, terminate DHCPv6 */
822  if ( fail ) {
823  dhcpv6_finished ( dhcpv6, dhcpv6->rc );
824  return;
825  }
826 
827  /* Restart timer */
828  start_timer ( &dhcpv6->timer );
829 
830  /* (Re)transmit current request */
831  dhcpv6_tx ( dhcpv6 );
832 }
static int dhcpv6_tx(struct dhcpv6_session *dhcpv6)
Transmit current request.
Definition: dhcpv6.c:687
A DHCPv6 session.
Definition: dhcpv6.c:570
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:626
A timer.
Definition: timer.h:29
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:598
int rc
Current timeout status code.
Definition: dhcpv6.c:603
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:94

References container_of, dhcpv6_finished(), dhcpv6_tx(), dhcpv6_session::rc, start_timer(), and dhcpv6_session::timer.

Referenced by start_dhcpv6().

◆ dhcpv6_rx()

static int dhcpv6_rx ( struct dhcpv6_session dhcpv6,
struct io_buffer iobuf,
struct xfer_metadata meta 
)
static

Receive new data.

Parameters
dhcpv6DHCPv6 session
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 842 of file dhcpv6.c.

844  {
845  struct settings *parent = netdev_settings ( dhcpv6->netdev );
846  struct sockaddr_in6 *src = ( ( struct sockaddr_in6 * ) meta->src );
847  struct dhcpv6_header *dhcphdr = iobuf->data;
849  const union dhcpv6_any_option *option;
850  int rc;
851 
852  /* Sanity checks */
853  if ( iob_len ( iobuf ) < sizeof ( *dhcphdr ) ) {
854  DBGC ( dhcpv6, "DHCPv6 %s received packet too short (%zd "
855  "bytes, min %zd bytes)\n", dhcpv6->netdev->name,
856  iob_len ( iobuf ), sizeof ( *dhcphdr ) );
857  rc = -EINVAL;
858  goto done;
859  }
860  assert ( src != NULL );
861  assert ( src->sin6_family == AF_INET6 );
862  DBGC ( dhcpv6, "DHCPv6 %s received %s from %s\n",
863  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
864  inet6_ntoa ( &src->sin6_addr ) );
865 
866  /* Construct option list */
867  options.data = dhcphdr->options;
868  options.len = ( iob_len ( iobuf ) -
869  offsetof ( typeof ( *dhcphdr ), options ) );
870 
871  /* Verify client identifier */
873  &dhcpv6->client_duid,
874  sizeof ( dhcpv6->client_duid ) ) ) !=0){
875  DBGC ( dhcpv6, "DHCPv6 %s received %s without correct client "
876  "ID: %s\n", dhcpv6->netdev->name,
877  dhcpv6_type_name ( dhcphdr->type ), strerror ( rc ) );
878  goto done;
879  }
880 
881  /* Verify server identifier, if applicable */
882  if ( dhcpv6->server_duid &&
884  dhcpv6->server_duid,
885  dhcpv6->server_duid_len ) ) != 0 ) ) {
886  DBGC ( dhcpv6, "DHCPv6 %s received %s without correct server "
887  "ID: %s\n", dhcpv6->netdev->name,
888  dhcpv6_type_name ( dhcphdr->type ), strerror ( rc ) );
889  goto done;
890  }
891 
892  /* Check message type */
893  if ( dhcphdr->type != dhcpv6->state->rx_type ) {
894  DBGC ( dhcpv6, "DHCPv6 %s received %s while expecting %s\n",
895  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
896  dhcpv6_type_name ( dhcpv6->state->rx_type ) );
897  rc = -ENOTTY;
898  goto done;
899  }
900 
901  /* Fetch status code, if present */
902  if ( ( rc = dhcpv6_status_code ( &options ) ) != 0 ) {
903  DBGC ( dhcpv6, "DHCPv6 %s received %s with error status: %s\n",
904  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
905  strerror ( rc ) );
906  /* This is plausibly the error we want to return */
907  dhcpv6->rc = rc;
908  goto done;
909  }
910 
911  /* Record identity association address, if applicable */
912  if ( dhcpv6->state->flags & DHCPV6_RX_RECORD_IAADDR ) {
913  if ( ( rc = dhcpv6_iaaddr ( &options, dhcpv6->iaid,
914  &dhcpv6->lease ) ) != 0 ) {
915  DBGC ( dhcpv6, "DHCPv6 %s received %s with unusable "
916  "IAADDR: %s\n", dhcpv6->netdev->name,
917  dhcpv6_type_name ( dhcphdr->type ),
918  strerror ( rc ) );
919  /* This is plausibly the error we want to return */
920  dhcpv6->rc = rc;
921  goto done;
922  }
923  DBGC ( dhcpv6, "DHCPv6 %s received %s is for %s\n",
924  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
925  inet6_ntoa ( &dhcpv6->lease ) );
926  }
927 
928  /* Record server ID, if applicable */
929  if ( dhcpv6->state->flags & DHCPV6_RX_RECORD_SERVER_ID ) {
930  assert ( dhcpv6->server_duid == NULL );
932  if ( ! option ) {
933  DBGC ( dhcpv6, "DHCPv6 %s received %s missing server "
934  "ID\n", dhcpv6->netdev->name,
935  dhcpv6_type_name ( dhcphdr->type ) );
936  rc = -EINVAL;
937  goto done;
938  }
939  dhcpv6->server_duid_len = ntohs ( option->duid.header.len );
940  dhcpv6->server_duid = malloc ( dhcpv6->server_duid_len );
941  if ( ! dhcpv6->server_duid ) {
942  rc = -ENOMEM;
943  goto done;
944  }
945  memcpy ( dhcpv6->server_duid, option->duid.duid,
946  dhcpv6->server_duid_len );
947  }
948 
949  /* Transition to next state, if applicable */
950  if ( dhcpv6->state->next ) {
951  dhcpv6_set_state ( dhcpv6, dhcpv6->state->next );
952  rc = 0;
953  goto done;
954  }
955 
956  /* Register settings */
957  if ( ( rc = dhcpv6_register ( &dhcpv6->lease, &dhcpv6->router,
958  &options, parent ) ) != 0 ) {
959  DBGC ( dhcpv6, "DHCPv6 %s could not register settings: %s\n",
960  dhcpv6->netdev->name, strerror ( rc ) );
961  goto done;
962  }
963 
964  /* Mark as complete */
965  dhcpv6_finished ( dhcpv6, 0 );
966  DBGC ( dhcpv6, "DHCPv6 %s complete\n", dhcpv6->netdev->name );
967 
968  done:
969  free_iob ( iobuf );
970  return rc;
971 }
uint8_t rx_type
Current expected received packet type.
Definition: dhcpv6.c:524
struct dhcpv6_session_state * next
Next state (or NULL to terminate)
Definition: dhcpv6.c:528
#define DHCPV6_SERVER_ID
DHCPv6 server identifier option.
Definition: dhcpv6.h:59
#define EINVAL
Invalid argument.
Definition: errno.h:429
Record received server ID.
Definition: dhcpv6.c:538
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:65
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:895
static void dhcpv6_set_state(struct dhcpv6_session *dhcpv6, struct dhcpv6_session_state *state)
Transition to new DHCPv6 session state.
Definition: dhcpv6.c:642
struct settings * parent
Parent settings block.
Definition: settings.h:139
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
static int dhcpv6_status_code(struct dhcpv6_option_list *options)
Get DHCPv6 status code.
Definition: dhcpv6.c:167
static int dhcpv6_check_duid(struct dhcpv6_option_list *options, unsigned int code, const void *expected, size_t len)
Check DHCPv6 client or server identifier.
Definition: dhcpv6.c:138
#define DBGC(...)
Definition: compiler.h:505
uint32_t iaid
Identity association ID.
Definition: dhcpv6.c:585
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:579
static const char * dhcpv6_type_name(unsigned int type)
Name a DHCPv6 packet type.
Definition: dhcpv6.c:504
uint8_t options[0]
DHCP options.
Definition: dhcp.h:684
#define ntohs(value)
Definition: byteswap.h:137
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:25
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:626
A DHCPv6 header.
Definition: dhcpv6.h:241
struct in6_addr lease
Leased IPv6 address.
Definition: dhcpv6.c:595
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:587
Any DHCPv6 option.
Definition: dhcpv6.h:226
Record received IPv6 address.
Definition: dhcpv6.c:540
struct dhcpv6_session_state * state
Current session state.
Definition: dhcpv6.c:601
#define ENOMEM
Not enough space.
Definition: errno.h:535
#define DHCPV6_CLIENT_ID
DHCPv6 client identifier option.
Definition: dhcpv6.h:56
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint8_t flags
Flags.
Definition: dhcpv6.c:526
static const void * src
Definition: string.h:48
A long option, as used for getopt_long()
Definition: getopt.h:25
static int dhcpv6_register(struct in6_addr *lease, struct in6_addr *router, struct dhcpv6_option_list *options, struct settings *parent)
Register DHCPv6 options as network device settings.
Definition: dhcpv6.c:436
static int options
Definition: 3c515.c:286
struct in6_addr router
Router address.
Definition: dhcpv6.c:581
void * server_duid
Server DUID, if known.
Definition: dhcpv6.c:591
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
A settings block.
Definition: settings.h:133
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
int rc
Current timeout status code.
Definition: dhcpv6.c:603
A DHCP header.
Definition: dhcp.h:616
A DHCPv6 option list.
Definition: dhcpv6.c:86
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
size_t server_duid_len
Server DUID length.
Definition: dhcpv6.c:593
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:595
void * data
Start of data.
Definition: iobuf.h:53
struct dhcpv6_duid_uuid client_duid
Client DUID.
Definition: dhcpv6.c:589
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:101
IPv6 socket address.
Definition: in.h:118
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:48
uint8_t meta
Metadata flags.
Definition: ena.h:14
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct bofm_section_header done
Definition: bofm_test.c:46
static int dhcpv6_iaaddr(struct dhcpv6_option_list *options, uint32_t iaid, struct in6_addr *address)
Get DHCPv6 identity association address.
Definition: dhcpv6.c:199

References AF_INET6, assert(), dhcpv6_session::client_duid, io_buffer::data, DBGC, dhcpv6_check_duid(), DHCPV6_CLIENT_ID, dhcpv6_finished(), dhcpv6_iaaddr(), dhcpv6_option(), dhcpv6_register(), DHCPV6_RX_RECORD_IAADDR, DHCPV6_RX_RECORD_SERVER_ID, DHCPV6_SERVER_ID, dhcpv6_set_state(), dhcpv6_status_code(), dhcpv6_type_name(), done, EINVAL, ENOMEM, ENOTTY, dhcpv6_session_state::flags, free_iob(), dhcpv6_session::iaid, inet6_ntoa(), iob_len(), dhcpv6_session::lease, malloc(), memcpy(), meta, net_device::name, dhcpv6_session::netdev, netdev_settings(), dhcpv6_session_state::next, ntohs, NULL, offsetof, options, dhcphdr::options, settings::parent, rc, dhcpv6_session::rc, dhcpv6_session::router, dhcpv6_session_state::rx_type, dhcpv6_session::server_duid, dhcpv6_session::server_duid_len, src, dhcpv6_session::state, strerror(), and typeof().

◆ start_dhcpv6()

int start_dhcpv6 ( struct interface job,
struct net_device netdev,
struct in6_addr router,
int  stateful 
)

Start DHCPv6.

Parameters
jobJob control interface
netdevNetwork device
routerRouter address
statefulPerform stateful address autoconfiguration
Return values
rcReturn status code

Definition at line 1000 of file dhcpv6.c.

1001  {
1003  struct dhcpv6_session *dhcpv6;
1004  struct {
1005  union {
1006  struct sockaddr_in6 sin6;
1007  struct sockaddr sa;
1008  } client;
1009  union {
1010  struct sockaddr_in6 sin6;
1011  struct sockaddr sa;
1012  } server;
1013  } addresses;
1014  uint32_t xid;
1015  int len;
1016  int rc;
1017 
1018  /* Allocate and initialise structure */
1019  dhcpv6 = zalloc ( sizeof ( *dhcpv6 ) );
1020  if ( ! dhcpv6 )
1021  return -ENOMEM;
1022  ref_init ( &dhcpv6->refcnt, dhcpv6_free );
1023  intf_init ( &dhcpv6->job, &dhcpv6_job_desc, &dhcpv6->refcnt );
1024  intf_init ( &dhcpv6->xfer, &dhcpv6_xfer_desc, &dhcpv6->refcnt );
1025  dhcpv6->netdev = netdev_get ( netdev );
1026  memcpy ( &dhcpv6->router, router, sizeof ( dhcpv6->router ) );
1027  xid = random();
1028  memcpy ( dhcpv6->xid, &xid, sizeof ( dhcpv6->xid ) );
1029  dhcpv6->start = currticks();
1030  timer_init ( &dhcpv6->timer, dhcpv6_timer_expired, &dhcpv6->refcnt );
1031 
1032  /* Construct client and server addresses */
1033  memset ( &addresses, 0, sizeof ( addresses ) );
1034  addresses.client.sin6.sin6_family = AF_INET6;
1035  addresses.client.sin6.sin6_port = htons ( DHCPV6_CLIENT_PORT );
1036  addresses.server.sin6.sin6_family = AF_INET6;
1037  ipv6_all_dhcp_relay_and_servers ( &addresses.server.sin6.sin6_addr );
1038  addresses.server.sin6.sin6_scope_id = netdev->scope_id;
1039  addresses.server.sin6.sin6_port = htons ( DHCPV6_SERVER_PORT );
1040 
1041  /* Construct client DUID from system UUID */
1042  dhcpv6->client_duid.type = htons ( DHCPV6_DUID_UUID );
1043  if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting,
1044  &dhcpv6->client_duid.uuid ) ) < 0 ) {
1045  rc = len;
1046  DBGC ( dhcpv6, "DHCPv6 %s could not create DUID-UUID: %s\n",
1047  dhcpv6->netdev->name, strerror ( rc ) );
1048  goto err_client_duid;
1049  }
1050 
1051  /* Construct IAID from link-layer address */
1052  dhcpv6->iaid = crc32_le ( 0, netdev->ll_addr, ll_protocol->ll_addr_len);
1053  DBGC ( dhcpv6, "DHCPv6 %s has XID %02x%02x%02x\n", dhcpv6->netdev->name,
1054  dhcpv6->xid[0], dhcpv6->xid[1], dhcpv6->xid[2] );
1055 
1056  /* Enter initial state */
1057  dhcpv6_set_state ( dhcpv6, ( stateful ? &dhcpv6_solicit :
1059 
1060  /* Open socket */
1061  if ( ( rc = xfer_open_socket ( &dhcpv6->xfer, SOCK_DGRAM,
1062  &addresses.server.sa,
1063  &addresses.client.sa ) ) != 0 ) {
1064  DBGC ( dhcpv6, "DHCPv6 %s could not open socket: %s\n",
1065  dhcpv6->netdev->name, strerror ( rc ) );
1066  goto err_open_socket;
1067  }
1068 
1069  /* Attach parent interface, mortalise self, and return */
1070  intf_plug_plug ( &dhcpv6->job, job );
1071  ref_put ( &dhcpv6->refcnt );
1072  return 0;
1073 
1074  err_open_socket:
1075  dhcpv6_finished ( dhcpv6, rc );
1076  err_client_duid:
1077  ref_put ( &dhcpv6->refcnt );
1078  return rc;
1079 }
static struct dhcpv6_session_state dhcpv6_solicit
DHCPv6 solicitation state.
Definition: dhcpv6.c:553
A DHCPv6 session.
Definition: dhcpv6.c:570
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:65
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:199
static struct interface_descriptor dhcpv6_xfer_desc
DHCPv6 data transfer interface descriptor.
Definition: dhcpv6.c:988
struct interface xfer
Data transfer interface.
Definition: dhcpv6.c:576
struct interface job
Job control interface.
Definition: dhcpv6.c:574
static void dhcpv6_set_state(struct dhcpv6_session *dhcpv6, struct dhcpv6_session_state *state)
Transition to new DHCPv6 session state.
Definition: dhcpv6.c:642
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:143
#define SOCK_DGRAM
Definition: socket.h:30
#define DBGC(...)
Definition: compiler.h:505
struct sockaddr_in6 sin6
Definition: syslog.c:60
uint32_t iaid
Identity association ID.
Definition: dhcpv6.c:585
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:108
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:579
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:626
unsigned int scope_id
Scope ID.
Definition: netdevice.h:361
A link-layer protocol.
Definition: netdevice.h:115
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition: crc32.c:40
#define ENOMEM
Not enough space.
Definition: errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
static struct net_device * netdev
Definition: gdbudp.c:52
struct sockaddr sa
Definition: syslog.c:57
struct in6_addr router
Router address.
Definition: dhcpv6.c:581
struct refcnt refcnt
Reference counter.
Definition: dhcpv6.c:572
static void dhcpv6_free(struct refcnt *refcnt)
Free DHCPv6 session.
Definition: dhcpv6.c:611
static void dhcpv6_timer_expired(struct retry_timer *timer, int fail)
Handle timer expiry.
Definition: dhcpv6.c:817
Generalized socket address structure.
Definition: socket.h:97
static struct dhcpv6_session_state dhcpv6_information_request
DHCPv6 information request state.
Definition: dhcpv6.c:562
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:32
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:565
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:598
unsigned int uint32_t
Definition: stdint.h:12
uint16_t type
Type.
Definition: dhcpv6.h:39
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
unsigned long start
Start time (in ticks)
Definition: dhcpv6.c:587
struct dhcpv6_duid_uuid client_duid
Client DUID.
Definition: dhcpv6.c:589
static void ipv6_all_dhcp_relay_and_servers(struct in6_addr *addr)
Construct all-DHCP-relay-agents-and-servers multicast address.
Definition: dhcpv6.h:273
uint8_t xid[3]
Transaction ID.
Definition: dhcpv6.c:583
#define DHCPV6_CLIENT_PORT
DHCPv6 client port.
Definition: dhcpv6.h:21
static struct interface_descriptor dhcpv6_job_desc
DHCPv6 job control interface descriptor.
Definition: dhcpv6.c:979
IPv6 socket address.
Definition: in.h:118
#define DHCPV6_DUID_UUID
DHCP unique identifier based on UUID (DUID-UUID)
Definition: dhcpv6.h:45
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
Definition: settings.c:1085
#define DHCPV6_SERVER_PORT
DHCPv6 server port.
Definition: dhcpv6.h:18
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:388
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:43
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define htons(value)
Definition: byteswap.h:136
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
void * memset(void *dest, int character, size_t len) __nonnull
union uuid uuid
UUID.
Definition: dhcpv6.h:41

References AF_INET6, dhcpv6_session::client_duid, crc32_le(), currticks(), DBGC, DHCPV6_CLIENT_PORT, DHCPV6_DUID_UUID, dhcpv6_finished(), dhcpv6_free(), dhcpv6_information_request, dhcpv6_job_desc, DHCPV6_SERVER_PORT, dhcpv6_set_state(), dhcpv6_solicit, dhcpv6_timer_expired(), dhcpv6_xfer_desc, ENOMEM, fetch_uuid_setting(), htons, dhcpv6_session::iaid, intf_init(), intf_plug_plug(), ipv6_all_dhcp_relay_and_servers(), dhcpv6_session::job, len, net_device::ll_addr, ll_protocol::ll_addr_len, net_device::ll_protocol, memcpy(), memset(), net_device::name, netdev, dhcpv6_session::netdev, netdev_get(), NULL, random(), rc, ref_init, ref_put, dhcpv6_session::refcnt, dhcpv6_session::router, sa, net_device::scope_id, sin6, SOCK_DGRAM, dhcpv6_session::start, strerror(), dhcpv6_session::timer, dhcpv6_duid_uuid::type, dhcpv6_duid_uuid::uuid, dhcpv6_session::xfer, xfer_open_socket(), dhcpv6_session::xid, and zalloc().

Referenced by ipv6conf_rx_router_advertisement().

◆ __setting() [1/2]

const struct setting filename6_setting __setting ( SETTING_BOOT  ,
filename   
)

Boot filename setting.

◆ __setting() [2/2]

const struct setting dnssl6_setting __setting ( SETTING_IP_EXTRA  ,
dnssl   
)

DNS search list setting.

Variable Documentation

◆ __errortab

struct errortab dhcpv6_errors [] __errortab
Initial value:
= {
}
#define __einfo_errortab(einfo)
Definition: errortab.h:24
#define EINFO_EPROTO_NOADDRSAVAIL
Definition: dhcpv6.c:58

Human-readable error messages.

Definition at line 75 of file dhcpv6.c.

◆ dhcpv6_address_operations

struct dhcpv6_address_operation dhcpv6_address_operations[]
static
Initial value:
= {
{ &ip6_setting, dhcpv6_fetch_ip6 },
{ &len6_setting, dhcpv6_fetch_len6 },
{ &gateway6_setting, dhcpv6_fetch_gateway6 },
}
static int dhcpv6_fetch_ip6(struct dhcpv6_settings *dhcpv6set, void *data, size_t len)
Fetch value of DHCPv6 leased address.
Definition: dhcpv6.c:300
static int dhcpv6_fetch_len6(struct dhcpv6_settings *dhcpv6set __unused, void *data, size_t len)
Fetch value of DHCPv6 implicit address prefix length.
Definition: dhcpv6.c:320
static int dhcpv6_fetch_gateway6(struct dhcpv6_settings *dhcpv6set, void *data, size_t len)
Fetch value of DHCPv6 router address.
Definition: dhcpv6.c:343

DHCPv6 address settings operations.

Definition at line 372 of file dhcpv6.c.

Referenced by dhcpv6_fetch().

◆ dhcpv6_settings_operations

struct settings_operations dhcpv6_settings_operations
static
Initial value:
= {
.applies = dhcpv6_applies,
.fetch = dhcpv6_fetch,
}
static int dhcpv6_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of DHCPv6 setting.
Definition: dhcpv6.c:285
static int dhcpv6_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of DHCPv6 setting.
Definition: dhcpv6.c:387

DHCPv6 settings operations.

Definition at line 422 of file dhcpv6.c.

Referenced by dhcpv6_register().

◆ dhcpv6_request_options_data

uint8_t dhcpv6_request_options_data[]
static
Initial value:
= {
}
#define DHCPV6_BOOTFILE_PARAM
DHCPv6 bootfile parameters option.
Definition: dhcpv6.h:174
#define DHCPV6_VENDOR_CLASS_PXE
DHCPv6 PXE vendor class.
Definition: dhcpv6.h:162
#define DHCPV6_VENDOR_CLASS
DHCPv6 vendor class option.
Definition: dhcpv6.h:150
#define DHCPV6_DWORD_VALUE(value)
Construct a DHCPv6 dword value.
Definition: dhcpv6.h:197
#define DHCP_ARCH_CLIENT_ARCHITECTURE
DHCP client architecture.
Definition: dhcparch.h:15
#define DHCPV6_CODE(code)
Construct a DHCPv6 option code.
Definition: dhcpv6.h:201
#define DHCPV6_DNS_SERVERS
DHCPv6 DNS recursive name server option.
Definition: dhcpv6.h:165
#define DHCPV6_OPTION_REQUEST
DHCPv6 option request option.
Definition: dhcpv6.h:104
#define DHCPV6_DOMAIN_LIST
DHCPv6 domain search list option.
Definition: dhcpv6.h:168
#define DHCP_ARCH_CLIENT_NDI
DHCP client network device interface.
Definition: dhcparch.h:18
#define DHCPV6_WORD(value)
Construct a word-valued DHCPv6 option.
Definition: dhcpv6.h:217
#define DHCPV6_STRING(...)
Construct a DHCPv6 option from a list of characters.
Definition: dhcpv6.h:211
#define DHCP_VENDOR_PXECLIENT(arch, ndi)
Vendor class identifier for PXE clients.
Definition: dhcp.h:220
#define DHCPV6_CLIENT_ARCHITECTURE
DHCPv6 client system architecture option.
Definition: dhcpv6.h:177
#define DHCPV6_BOOTFILE_URL
DHCPv6 bootfile URI option.
Definition: dhcpv6.h:171
#define DHCPV6_CLIENT_NDI
DHCPv6 client network interface identifier option.
Definition: dhcpv6.h:180
#define DHCPV6_OPTION(...)
Construct a DHCPv6 option from a list of bytes.
Definition: dhcpv6.h:207

Raw option data for options common to all DHCPv6 requests.

Definition at line 480 of file dhcpv6.c.

Referenced by dhcpv6_tx().

◆ dhcpv6_request

struct dhcpv6_session_state dhcpv6_request
static
Initial value:
= {
.tx_type = DHCPV6_REQUEST,
.rx_type = DHCPV6_REPLY,
.next = NULL,
}
Include leased IPv6 address within request.
Definition: dhcpv6.c:536
#define DHCPV6_REPLY
DHCPv6 reply.
Definition: dhcpv6.h:260
Record received IPv6 address.
Definition: dhcpv6.c:540
#define DHCPV6_REQUEST
DHCPv6 request.
Definition: dhcpv6.h:257
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
Include identity association within request.
Definition: dhcpv6.c:534
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

DHCPv6 request state.

Definition at line 544 of file dhcpv6.c.

◆ dhcpv6_solicit

struct dhcpv6_session_state dhcpv6_solicit
static
Initial value:
= {
.tx_type = DHCPV6_SOLICIT,
.rx_type = DHCPV6_ADVERTISE,
}
Record received server ID.
Definition: dhcpv6.c:538
#define DHCPV6_SOLICIT
DHCPv6 solicitation.
Definition: dhcpv6.h:251
Record received IPv6 address.
Definition: dhcpv6.c:540
#define DHCPV6_ADVERTISE
DHCPv6 advertisement.
Definition: dhcpv6.h:254
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
Include identity association within request.
Definition: dhcpv6.c:534
static struct dhcpv6_session_state dhcpv6_request
DHCPv6 request state.
Definition: dhcpv6.c:544

DHCPv6 solicitation state.

Definition at line 553 of file dhcpv6.c.

Referenced by start_dhcpv6().

◆ dhcpv6_information_request

struct dhcpv6_session_state dhcpv6_information_request
static
Initial value:
= {
.rx_type = DHCPV6_REPLY,
.flags = 0,
.next = NULL,
}
#define DHCPV6_INFORMATION_REQUEST
DHCPv6 information request.
Definition: dhcpv6.h:263
#define DHCPV6_REPLY
DHCPv6 reply.
Definition: dhcpv6.h:260
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

DHCPv6 information request state.

Definition at line 562 of file dhcpv6.c.

Referenced by start_dhcpv6().

◆ dhcpv6_job_op

struct interface_operation dhcpv6_job_op[]
static
Initial value:
= {
}
A DHCPv6 session.
Definition: dhcpv6.c:570
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:626
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33

DHCPv6 job control interface operations.

Definition at line 974 of file dhcpv6.c.

◆ dhcpv6_job_desc

struct interface_descriptor dhcpv6_job_desc
static
Initial value:
=
A DHCPv6 session.
Definition: dhcpv6.c:570
static struct interface_operation dhcpv6_job_op[]
DHCPv6 job control interface operations.
Definition: dhcpv6.c:974
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81

DHCPv6 job control interface descriptor.

Definition at line 979 of file dhcpv6.c.

Referenced by start_dhcpv6().

◆ dhcpv6_xfer_op

struct interface_operation dhcpv6_xfer_op[]
static
Initial value:
= {
}
A DHCPv6 session.
Definition: dhcpv6.c:570
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:195
static int dhcpv6_rx(struct dhcpv6_session *dhcpv6, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new data.
Definition: dhcpv6.c:842

DHCPv6 data transfer interface operations.

Definition at line 983 of file dhcpv6.c.

◆ dhcpv6_xfer_desc

struct interface_descriptor dhcpv6_xfer_desc
static
Initial value:
=
A DHCPv6 session.
Definition: dhcpv6.c:570
static struct interface_operation dhcpv6_xfer_op[]
DHCPv6 data transfer interface operations.
Definition: dhcpv6.c:983
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81

DHCPv6 data transfer interface descriptor.

Definition at line 988 of file dhcpv6.c.

Referenced by start_dhcpv6().