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/dhcp_arch.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_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)
 
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_lease (struct dhcpv6_settings *dhcpv6set, void *data, size_t len)
 Fetch value of DHCPv6 leased 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 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, 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 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 53 of file dhcpv6.c.

◆ EINFO_EPROTO_UNSPECFAIL

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

Definition at line 54 of file dhcpv6.c.

◆ EPROTO_NOADDRSAVAIL

#define EPROTO_NOADDRSAVAIL   __einfo_error ( EINFO_EPROTO_NOADDRSAVAIL )

Definition at line 56 of file dhcpv6.c.

◆ EINFO_EPROTO_NOADDRSAVAIL

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

Definition at line 57 of file dhcpv6.c.

◆ EPROTO_NOBINDING

#define EPROTO_NOBINDING   __einfo_error ( EINFO_EPROTO_NOBINDING )

Definition at line 59 of file dhcpv6.c.

◆ EINFO_EPROTO_NOBINDING

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

Definition at line 60 of file dhcpv6.c.

◆ EPROTO_NOTONLINK

#define EPROTO_NOTONLINK   __einfo_error ( EINFO_EPROTO_NOTONLINK )

Definition at line 62 of file dhcpv6.c.

◆ EINFO_EPROTO_NOTONLINK

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

Definition at line 63 of file dhcpv6.c.

◆ EPROTO_USEMULTICAST

#define EPROTO_USEMULTICAST   __einfo_error ( EINFO_EPROTO_USEMULTICAST )

Definition at line 65 of file dhcpv6.c.

◆ EINFO_EPROTO_USEMULTICAST

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

Definition at line 66 of file dhcpv6.c.

◆ EPROTO_STATUS

#define EPROTO_STATUS (   status)
Value:
#define EPROTO_NOBINDING
Definition: dhcpv6.c:59
uint8_t status
Status.
Definition: ena.h:16
#define EPROTO_NOTONLINK
Definition: dhcpv6.c:62
#define EPROTO_NOADDRSAVAIL
Definition: dhcpv6.c:56
#define EUNIQ(einfo_base, uniq,...)
Disambiguate a base error based on non-constant information.
Definition: errno.h:225
#define EPROTO_USEMULTICAST
Definition: dhcpv6.c:65
#define EPROTO_UNSPECFAIL
Definition: dhcpv6.c:53
#define EINFO_EPROTO
Definition: errno.h:625

Definition at line 68 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 456 of file dhcpv6.c.

456  {
457  /** Include identity association within request */
458  DHCPV6_TX_IA_NA = 0x01,
459  /** Include leased IPv6 address within request */
460  DHCPV6_TX_IAADDR = 0x02,
461  /** Record received server ID */
463  /** Record received IPv6 address */
465 };
Record received server ID.
Definition: dhcpv6.c:462
Include leased IPv6 address within request.
Definition: dhcpv6.c:460
Record received IPv6 address.
Definition: dhcpv6.c:464
Include identity association within request.
Definition: dhcpv6.c:458

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ 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 100 of file dhcpv6.c.

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

References code, 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 137 of file dhcpv6.c.

139  {
140  const union dhcpv6_any_option *option;
141  const struct dhcpv6_duid_option *duid;
142 
143  /* Find option */
145  if ( ! option )
146  return -ENOENT;
147  duid = &option->duid;
148 
149  /* Check option length */
150  if ( ntohs ( duid->header.len ) != len )
151  return -EINVAL;
152 
153  /* Compare option value */
154  if ( memcmp ( duid->duid, expected, len ) != 0 )
155  return -EINVAL;
156 
157  return 0;
158 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
uint8_t duid[0]
DHCP unique identifier (DUID)
Definition: dhcpv6.h:51
#define ENOENT
No such file or directory.
Definition: errno.h:514
#define ntohs(value)
Definition: byteswap.h:136
Any DHCPv6 option.
Definition: dhcpv6.h:225
A long option, as used for getopt_long()
Definition: getopt.h:24
static int options
Definition: 3c515.c:286
DHCPv6 client or server identifier option.
Definition: dhcpv6.h:47
uint8_t code
Response code.
Definition: scsi.h:16
uint32_t len
Length.
Definition: ena.h:14
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:100
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98

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 166 of file dhcpv6.c.

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

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 198 of file dhcpv6.c.

199  {
200  const union dhcpv6_any_option *option;
201  const struct dhcpv6_ia_na_option *ia_na;
202  const struct dhcpv6_iaaddr_option *iaaddr;
203  struct dhcpv6_option_list suboptions;
204  size_t len;
205  int rc;
206 
207  /* Find identity association option, if present */
209  if ( ! option )
210  return -ENOENT;
211  ia_na = &option->ia_na;
212 
213  /* Sanity check */
214  len = ntohs ( ia_na->header.len );
215  if ( len < ( sizeof ( *ia_na ) - sizeof ( ia_na->header ) ) )
216  return -EINVAL;
217 
218  /* Check identity association ID */
219  if ( ia_na->iaid != htonl ( iaid ) )
220  return -EINVAL;
221 
222  /* Construct IA_NA sub-options list */
223  suboptions.data = ia_na->options;
224  suboptions.len = ( len + sizeof ( ia_na->header ) -
225  offsetof ( typeof ( *ia_na ), options ) );
226 
227  /* Check IA_NA status code */
228  if ( ( rc = dhcpv6_status_code ( &suboptions ) ) != 0 )
229  return rc;
230 
231  /* Find identity association address, if present */
232  option = dhcpv6_option ( &suboptions, DHCPV6_IAADDR );
233  if ( ! option )
234  return -ENOENT;
235  iaaddr = &option->iaaddr;
236 
237  /* Sanity check */
238  len = ntohs ( iaaddr->header.len );
239  if ( len < ( sizeof ( *iaaddr ) - sizeof ( iaaddr->header ) ) )
240  return -EINVAL;
241 
242  /* Construct IAADDR sub-options list */
243  suboptions.data = iaaddr->options;
244  suboptions.len = ( len + sizeof ( iaaddr->header ) -
245  offsetof ( typeof ( *iaaddr ), options ) );
246 
247  /* Check IAADDR status code */
248  if ( ( rc = dhcpv6_status_code ( &suboptions ) ) != 0 )
249  return rc;
250 
251  /* Extract IPv6 address */
252  memcpy ( address, &iaaddr->address, sizeof ( *address ) );
253 
254  return 0;
255 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
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:75
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:80
uint64_t address
Base address.
Definition: ena.h:24
struct dhcpv6_option options[0]
IA_NA options.
Definition: dhcpv6.h:71
static int dhcpv6_status_code(struct dhcpv6_option_list *options)
Get DHCPv6 status code.
Definition: dhcpv6.c:166
uint32_t iaid
Identity association identifier (IAID)
Definition: dhcpv6.h:65
#define ENOENT
No such file or directory.
Definition: errno.h:514
#define ntohs(value)
Definition: byteswap.h:136
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
#define htonl(value)
Definition: byteswap.h:133
Any DHCPv6 option.
Definition: dhcpv6.h:225
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A long option, as used for getopt_long()
Definition: getopt.h:24
struct dhcpv6_option options[0]
IAADDR options.
Definition: dhcpv6.h:88
static int options
Definition: 3c515.c:286
struct in6_addr address
IPv6 address.
Definition: dhcpv6.h:82
DHCPv6 identity association address (IAADDR) option.
Definition: dhcpv6.h:78
A DHCPv6 option list.
Definition: dhcpv6.c:85
uint16_t len
Length of the data field.
Definition: dhcpv6.h:30
uint32_t len
Length.
Definition: ena.h:14
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:63
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:100
#define DHCPV6_IAADDR
DHCPv6 identity association address (IAADDR) option.
Definition: dhcpv6.h:92
DHCPv6 identity association for non-temporary address (IA_NA) option.
Definition: dhcpv6.h:61

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, len, dhcpv6_option::len, dhcpv6_option_list::len, memcpy(), ntohs, offsetof, dhcpv6_ia_na_option::options, dhcpv6_iaaddr_option::options, options, and rc.

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 282 of file dhcpv6.c.

283  {
284 
285  return ( ( setting->scope == &dhcpv6_scope ) ||
286  ( setting_cmp ( setting, &ip6_setting ) == 0 ) );
287 }
const struct settings_scope dhcpv6_scope
IPv6 settings scope.
Definition: settings.c:1796
A setting.
Definition: settings.h:23
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:49
int setting_cmp(const struct setting *a, const struct setting *b)
Compare two settings.
Definition: settings.c:1124

References dhcpv6_scope, setting::scope, and setting_cmp().

◆ dhcpv6_fetch_lease()

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

Fetch value of DHCPv6 leased address.

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

Definition at line 297 of file dhcpv6.c.

298  {
299  struct in6_addr *lease = &dhcpv6set->lease;
300 
301  /* Do nothing unless a leased address exists */
302  if ( IN6_IS_ADDR_UNSPECIFIED ( lease ) )
303  return -ENOENT;
304 
305  /* Copy leased address */
306  if ( len > sizeof ( *lease ) )
307  len = sizeof ( *lease );
308  memcpy ( data, lease, len );
309 
310  return sizeof ( *lease );
311 }
#define ENOENT
No such file or directory.
Definition: errno.h:514
struct in6_addr lease
Leased address.
Definition: dhcpv6.c:270
void * memcpy(void *dest, const void *src, size_t len) __nonnull
IP6 address structure.
Definition: in.h:48
#define IN6_IS_ADDR_UNSPECIFIED(addr)
Definition: in.h:59
uint32_t lease
Definition: ib_mad.h:15
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

Referenced by dhcpv6_fetch().

◆ 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 322 of file dhcpv6.c.

324  {
325  struct dhcpv6_settings *dhcpv6set =
327  const union dhcpv6_any_option *option;
328  size_t option_len;
329 
330  /* Handle leased address */
331  if ( setting_cmp ( setting, &ip6_setting ) == 0 )
332  return dhcpv6_fetch_lease ( dhcpv6set, data, len );
333 
334  /* Find option */
335  option = dhcpv6_option ( &dhcpv6set->options, setting->tag );
336  if ( ! option )
337  return -ENOENT;
338 
339  /* Copy option to data buffer */
340  option_len = ntohs ( option->header.len );
341  if ( len > option_len )
342  len = option_len;
343  memcpy ( data, option->header.data, len );
344  return option_len;
345 }
#define ENOENT
No such file or directory.
Definition: errno.h:514
#define ntohs(value)
Definition: byteswap.h:136
A DHCPv6 settings block.
Definition: dhcpv6.c:264
Any DHCPv6 option.
Definition: dhcpv6.h:225
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
A long option, as used for getopt_long()
Definition: getopt.h:24
struct dhcpv6_option_list options
Option list.
Definition: dhcpv6.c:272
static int dhcpv6_fetch_lease(struct dhcpv6_settings *dhcpv6set, void *data, size_t len)
Fetch value of DHCPv6 leased address.
Definition: dhcpv6.c:297
A settings block.
Definition: settings.h:132
A setting.
Definition: settings.h:23
uint32_t len
Length.
Definition: ena.h:14
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:100
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
int setting_cmp(const struct setting *a, const struct setting *b)
Compare two settings.
Definition: settings.c:1124

References container_of, data, dhcpv6_fetch_lease(), dhcpv6_option(), ENOENT, len, memcpy(), ntohs, dhcpv6_settings::options, setting_cmp(), and setting::tag.

◆ dhcpv6_register()

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

Register DHCPv6 options as network device settings.

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

Definition at line 361 of file dhcpv6.c.

363  {
364  struct dhcpv6_settings *dhcpv6set;
365  void *data;
366  size_t len;
367  int rc;
368 
369  /* Allocate and initialise structure */
370  dhcpv6set = zalloc ( sizeof ( *dhcpv6set ) + options->len );
371  if ( ! dhcpv6set ) {
372  rc = -ENOMEM;
373  goto err_alloc;
374  }
375  ref_init ( &dhcpv6set->refcnt, NULL );
377  &dhcpv6set->refcnt, &dhcpv6_scope );
378  dhcpv6set->settings.order = IPV6_ORDER_DHCPV6;
379  data = ( ( ( void * ) dhcpv6set ) + sizeof ( *dhcpv6set ) );
380  len = options->len;
381  memcpy ( data, options->data, len );
382  dhcpv6set->options.data = data;
383  dhcpv6set->options.len = len;
384  memcpy ( &dhcpv6set->lease, lease, sizeof ( dhcpv6set->lease ) );
385 
386  /* Register settings */
387  if ( ( rc = register_settings ( &dhcpv6set->settings, parent,
388  DHCPV6_SETTINGS_NAME ) ) != 0 )
389  goto err_register;
390 
391  err_register:
392  ref_put ( &dhcpv6set->refcnt );
393  err_alloc:
394  return rc;
395 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const struct settings_scope dhcpv6_scope
IPv6 settings scope.
Definition: settings.c:1796
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
size_t len
Length of data buffer.
Definition: dhcpv6.c:89
#define DHCPV6_SETTINGS_NAME
DHCPv6 settings block name.
Definition: dhcpv6.h:265
static struct settings_operations dhcpv6_settings_operations
DHCPv6 settings operations.
Definition: dhcpv6.c:348
Address assigned via DHCPv6.
Definition: ipv6.h:288
A DHCPv6 settings block.
Definition: dhcpv6.c:264
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:495
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct in6_addr lease
Leased address.
Definition: dhcpv6.c:270
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:268
struct dhcpv6_option_list options
Option list.
Definition: dhcpv6.c:272
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
uint32_t lease
Definition: ib_mad.h:15
int order
Sibling ordering.
Definition: settings.h:148
struct refcnt refcnt
Reference count.
Definition: dhcpv6.c:266
uint32_t len
Length.
Definition: ena.h:14
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:478
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
const void * data
Data buffer.
Definition: dhcpv6.c:87
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References data, dhcpv6_option_list::data, dhcpv6_scope, DHCPV6_SETTINGS_NAME, dhcpv6_settings_operations, ENOMEM, IPV6_ORDER_DHCPV6, lease, dhcpv6_settings::lease, len, dhcpv6_option_list::len, memcpy(), NULL, dhcpv6_settings::options, options, settings::order, rc, ref_init, ref_put, dhcpv6_settings::refcnt, register_settings(), 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 428 of file dhcpv6.c.

428  {
429  static char buf[ 12 /* "UNKNOWN-xxx" + NUL */ ];
430 
431  switch ( type ) {
432  case DHCPV6_SOLICIT: return "SOLICIT";
433  case DHCPV6_ADVERTISE: return "ADVERTISE";
434  case DHCPV6_REQUEST: return "REQUEST";
435  case DHCPV6_REPLY: return "REPLY";
436  case DHCPV6_INFORMATION_REQUEST: return "INFORMATION-REQUEST";
437  default:
438  snprintf ( buf, sizeof ( buf ), "UNKNOWN-%d", type );
439  return buf;
440  }
441 }
#define DHCPV6_SOLICIT
DHCPv6 solicitation.
Definition: dhcpv6.h:250
uint8_t type
Type.
Definition: ena.h:16
#define DHCPV6_INFORMATION_REQUEST
DHCPv6 information request.
Definition: dhcpv6.h:262
#define DHCPV6_REPLY
DHCPv6 reply.
Definition: dhcpv6.h:259
#define DHCPV6_ADVERTISE
DHCPv6 advertisement.
Definition: dhcpv6.h:253
#define DHCPV6_REQUEST
DHCPv6 request.
Definition: dhcpv6.h:256
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382

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 533 of file dhcpv6.c.

533  {
534  struct dhcpv6_session *dhcpv6 =
536 
537  netdev_put ( dhcpv6->netdev );
538  free ( dhcpv6->server_duid );
539  free ( dhcpv6 );
540 }
A DHCPv6 session.
Definition: dhcpv6.c:494
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:503
A reference counter.
Definition: refcnt.h:26
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:555
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
void * server_duid
Server DUID, if known.
Definition: dhcpv6.c:513
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54

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 548 of file dhcpv6.c.

548  {
549 
550  /* Stop timer */
551  stop_timer ( &dhcpv6->timer );
552 
553  /* Shut down interfaces */
554  intf_shutdown ( &dhcpv6->xfer, rc );
555  intf_shutdown ( &dhcpv6->job, rc );
556 }
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:273
struct interface xfer
Data transfer interface.
Definition: dhcpv6.c:500
struct interface job
Job control interface.
Definition: dhcpv6.c:498
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:520
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117

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 564 of file dhcpv6.c.

565  {
566 
567  DBGC ( dhcpv6, "DHCPv6 %s entering %s state\n", dhcpv6->netdev->name,
568  dhcpv6_type_name ( state->tx_type ) );
569 
570  /* Record state */
571  dhcpv6->state = state;
572 
573  /* Default to -ETIMEDOUT if no more specific error is recorded */
574  dhcpv6->rc = -ETIMEDOUT;
575 
576  /* Start timer to trigger transmission */
577  start_timer_nodelay ( &dhcpv6->timer );
578 }
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:99
uint8_t state
State.
Definition: eth_slow.h:47
#define DBGC(...)
Definition: compiler.h:505
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:503
static const char * dhcpv6_type_name(unsigned int type)
Name a DHCPv6 packet type.
Definition: dhcpv6.c:428
struct dhcpv6_session_state * state
Current session state.
Definition: dhcpv6.c:523
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:520
int rc
Current timeout status code.
Definition: dhcpv6.c:525
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669

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 587 of file dhcpv6.c.

587  {
588  static const char default_user_class[4] = { 'i', 'P', 'X', 'E' };
589  int actual_len;
590 
591  /* Fetch user-class setting, if defined */
592  actual_len = fetch_raw_setting ( NULL, &user_class_setting, data, len );
593  if ( actual_len >= 0 )
594  return actual_len;
595 
596  /* Otherwise, use the default user class ("iPXE") */
597  if ( len > sizeof ( default_user_class ) )
598  len = sizeof ( default_user_class );
599  memcpy ( data, default_user_class, len );
600  return sizeof ( default_user_class );
601 }
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:807
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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 609 of file dhcpv6.c.

609  {
610  struct dhcpv6_duid_option *client_id;
611  struct dhcpv6_duid_option *server_id;
612  struct dhcpv6_ia_na_option *ia_na;
613  struct dhcpv6_iaaddr_option *iaaddr;
616  struct dhcpv6_header *dhcphdr;
617  struct io_buffer *iobuf;
618  void *options;
619  size_t client_id_len;
620  size_t server_id_len;
621  size_t ia_na_len;
622  size_t user_class_string_len;
623  size_t user_class_len;
624  size_t elapsed_len;
625  size_t total_len;
626  int rc;
627 
628  /* Calculate lengths */
629  client_id_len = ( sizeof ( *client_id ) +
630  sizeof ( dhcpv6->client_duid ) );
631  server_id_len = ( dhcpv6->server_duid ? ( sizeof ( *server_id ) +
632  dhcpv6->server_duid_len ) :0);
633  if ( dhcpv6->state->flags & DHCPV6_TX_IA_NA ) {
634  ia_na_len = sizeof ( *ia_na );
635  if ( dhcpv6->state->flags & DHCPV6_TX_IAADDR )
636  ia_na_len += sizeof ( *iaaddr );
637  } else {
638  ia_na_len = 0;
639  }
640  user_class_string_len = dhcpv6_user_class ( NULL, 0 );
641  user_class_len = ( sizeof ( *user_class ) +
642  sizeof ( user_class->user_class[0] ) +
643  user_class_string_len );
644  elapsed_len = sizeof ( *elapsed );
645  total_len = ( sizeof ( *dhcphdr ) + client_id_len + server_id_len +
646  ia_na_len + sizeof ( dhcpv6_request_options_data ) +
647  user_class_len + elapsed_len );
648 
649  /* Allocate packet */
650  iobuf = xfer_alloc_iob ( &dhcpv6->xfer, total_len );
651  if ( ! iobuf )
652  return -ENOMEM;
653 
654  /* Construct header */
655  dhcphdr = iob_put ( iobuf, sizeof ( *dhcphdr ) );
656  dhcphdr->type = dhcpv6->state->tx_type;
657  memcpy ( dhcphdr->xid, dhcpv6->xid, sizeof ( dhcphdr->xid ) );
658 
659  /* Construct client identifier */
660  client_id = iob_put ( iobuf, client_id_len );
661  client_id->header.code = htons ( DHCPV6_CLIENT_ID );
662  client_id->header.len = htons ( client_id_len -
663  sizeof ( client_id->header ) );
664  memcpy ( client_id->duid, &dhcpv6->client_duid,
665  sizeof ( dhcpv6->client_duid ) );
666 
667  /* Construct server identifier, if applicable */
668  if ( server_id_len ) {
669  server_id = iob_put ( iobuf, server_id_len );
670  server_id->header.code = htons ( DHCPV6_SERVER_ID );
671  server_id->header.len = htons ( server_id_len -
672  sizeof ( server_id->header ) );
673  memcpy ( server_id->duid, dhcpv6->server_duid,
674  dhcpv6->server_duid_len );
675  }
676 
677  /* Construct identity association, if applicable */
678  if ( ia_na_len ) {
679  ia_na = iob_put ( iobuf, ia_na_len );
680  ia_na->header.code = htons ( DHCPV6_IA_NA );
681  ia_na->header.len = htons ( ia_na_len -
682  sizeof ( ia_na->header ) );
683  ia_na->iaid = htonl ( dhcpv6->iaid );
684  ia_na->renew = htonl ( 0 );
685  ia_na->rebind = htonl ( 0 );
686  if ( dhcpv6->state->flags & DHCPV6_TX_IAADDR ) {
687  iaaddr = ( ( void * ) ia_na->options );
688  iaaddr->header.code = htons ( DHCPV6_IAADDR );
689  iaaddr->header.len = htons ( sizeof ( *iaaddr ) -
690  sizeof ( iaaddr->header ));
691  memcpy ( &iaaddr->address, &dhcpv6->lease,
692  sizeof ( iaaddr->address ) );
693  iaaddr->preferred = htonl ( 0 );
694  iaaddr->valid = htonl ( 0 );
695  }
696  }
697 
698  /* Construct fixed request options */
699  options = iob_put ( iobuf, sizeof ( dhcpv6_request_options_data ) );
701  sizeof ( dhcpv6_request_options_data ) );
702 
703  /* Construct user class */
704  user_class = iob_put ( iobuf, user_class_len );
705  user_class->header.code = htons ( DHCPV6_USER_CLASS );
706  user_class->header.len = htons ( user_class_len -
707  sizeof ( user_class->header ) );
708  user_class->user_class[0].len = htons ( user_class_string_len );
709  dhcpv6_user_class ( user_class->user_class[0].string,
710  user_class_string_len );
711 
712  /* Construct elapsed time */
713  elapsed = iob_put ( iobuf, elapsed_len );
714  elapsed->header.code = htons ( DHCPV6_ELAPSED_TIME );
715  elapsed->header.len = htons ( elapsed_len -
716  sizeof ( elapsed->header ) );
717  elapsed->elapsed = htons ( ( ( currticks() - dhcpv6->start ) * 100 ) /
718  TICKS_PER_SEC );
719 
720  /* Sanity check */
721  assert ( iob_len ( iobuf ) == total_len );
722 
723  /* Transmit packet */
724  if ( ( rc = xfer_deliver_iob ( &dhcpv6->xfer, iobuf ) ) != 0 ) {
725  DBGC ( dhcpv6, "DHCPv6 %s could not transmit: %s\n",
726  dhcpv6->netdev->name, strerror ( rc ) );
727  return rc;
728  }
729 
730  return 0;
731 }
#define DHCPV6_SERVER_ID
DHCPv6 server identifier option.
Definition: dhcpv6.h:58
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
char string[0]
User class string.
Definition: dhcpv6.h:134
#define iob_put(iobuf, len)
Definition: iobuf.h:116
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
#define DHCPV6_ELAPSED_TIME
DHCPv6 elapsed time option.
Definition: dhcpv6.h:114
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:254
struct interface xfer
Data transfer interface.
Definition: dhcpv6.c:500
Include leased IPv6 address within request.
Definition: dhcpv6.c:460
static uint8_t dhcpv6_request_options_data[]
Raw option data for options common to all DHCPv6 requests.
Definition: dhcpv6.c:404
#define DHCPV6_IA_NA
DHCPv6 identity association for non-temporary address (IA_NA) option.
Definition: dhcpv6.h:75
uint16_t len
Length.
Definition: dhcpv6.h:132
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:80
uint8_t duid[0]
DHCP unique identifier (DUID)
Definition: dhcpv6.h:51
#define DHCPV6_USER_CLASS
DHCPv6 user class option.
Definition: dhcpv6.h:146
struct dhcpv6_option options[0]
IA_NA options.
Definition: dhcpv6.h:71
uint32_t iaid
Identity association identifier (IAID)
Definition: dhcpv6.h:65
#define DBGC(...)
Definition: compiler.h:505
uint32_t iaid
Identity association ID.
Definition: dhcpv6.c:507
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:503
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:157
uint32_t xid
Transaction ID.
Definition: dhcp.h:609
uint8_t tx_type
Current transmitted packet type.
Definition: dhcpv6.c:446
DHCPv6 user class option.
Definition: dhcpv6.h:138
A DHCPv6 header.
Definition: dhcpv6.h:240
struct in6_addr lease
Leased IPv6 address.
Definition: dhcpv6.c:517
#define htonl(value)
Definition: byteswap.h:133
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:108
struct dhcpv6_session_state * state
Current session state.
Definition: dhcpv6.c:523
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define DHCPV6_CLIENT_ID
DHCPv6 client identifier option.
Definition: dhcpv6.h:55
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t valid
Valid lifetime (in seconds)
Definition: dhcpv6.h:86
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint8_t flags
Flags.
Definition: dhcpv6.c:450
static int options
Definition: 3c515.c:286
void * server_duid
Server DUID, if known.
Definition: dhcpv6.c:513
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint32_t rebind
Rebind time (in seconds)
Definition: dhcpv6.h:69
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
struct in6_addr address
IPv6 address.
Definition: dhcpv6.h:82
DHCPv6 client or server identifier option.
Definition: dhcpv6.h:47
DHCPv6 identity association address (IAADDR) option.
Definition: dhcpv6.h:78
A DHCP header.
Definition: dhcp.h:591
uint32_t renew
Renew time (in seconds)
Definition: dhcpv6.h:67
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
size_t server_duid_len
Server DUID length.
Definition: dhcpv6.c:515
uint16_t len
Length of the data field.
Definition: dhcpv6.h:30
unsigned long start
Start time (in ticks)
Definition: dhcpv6.c:509
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:63
struct dhcpv6_duid_uuid client_duid
Client DUID.
Definition: dhcpv6.c:511
uint8_t xid[3]
Transaction ID.
Definition: dhcpv6.c:505
#define DHCPV6_IAADDR
DHCPv6 identity association address (IAADDR) option.
Definition: dhcpv6.h:92
uint16_t elapsed
Elapsed time, in centiseconds.
Definition: dhcpv6.h:110
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
static size_t dhcpv6_user_class(void *data, size_t len)
Get DHCPv6 user class.
Definition: dhcpv6.c:587
uint32_t preferred
Preferred lifetime (in seconds)
Definition: dhcpv6.h:84
uint16_t code
Code.
Definition: dhcpv6.h:28
Include identity association within request.
Definition: dhcpv6.c:458
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:49
DHCPv6 identity association for non-temporary address (IA_NA) option.
Definition: dhcpv6.h:61
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define htons(value)
Definition: byteswap.h:135
struct dhcpv6_user_class user_class[0]
User class.
Definition: dhcpv6.h:142
A persistent I/O buffer.
Definition: iobuf.h:32
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:140
DHCPv6 elapsed time option.
Definition: dhcpv6.h:106

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 739 of file dhcpv6.c.

739  {
740  struct dhcpv6_session *dhcpv6 =
741  container_of ( timer, struct dhcpv6_session, timer );
742 
743  /* If we have failed, terminate DHCPv6 */
744  if ( fail ) {
745  dhcpv6_finished ( dhcpv6, dhcpv6->rc );
746  return;
747  }
748 
749  /* Restart timer */
750  start_timer ( &dhcpv6->timer );
751 
752  /* (Re)transmit current request */
753  dhcpv6_tx ( dhcpv6 );
754 }
static int dhcpv6_tx(struct dhcpv6_session *dhcpv6)
Transmit current request.
Definition: dhcpv6.c:609
A DHCPv6 session.
Definition: dhcpv6.c:494
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:548
A timer.
Definition: timer.h:28
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:520
int rc
Current timeout status code.
Definition: dhcpv6.c:525
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:93

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 764 of file dhcpv6.c.

766  {
767  struct settings *parent = netdev_settings ( dhcpv6->netdev );
768  struct sockaddr_in6 *src = ( ( struct sockaddr_in6 * ) meta->src );
769  struct dhcpv6_header *dhcphdr = iobuf->data;
771  const union dhcpv6_any_option *option;
772  int rc;
773 
774  /* Sanity checks */
775  if ( iob_len ( iobuf ) < sizeof ( *dhcphdr ) ) {
776  DBGC ( dhcpv6, "DHCPv6 %s received packet too short (%zd "
777  "bytes, min %zd bytes)\n", dhcpv6->netdev->name,
778  iob_len ( iobuf ), sizeof ( *dhcphdr ) );
779  rc = -EINVAL;
780  goto done;
781  }
782  assert ( src != NULL );
783  assert ( src->sin6_family == AF_INET6 );
784  DBGC ( dhcpv6, "DHCPv6 %s received %s from %s\n",
785  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
786  inet6_ntoa ( &src->sin6_addr ) );
787 
788  /* Construct option list */
789  options.data = dhcphdr->options;
790  options.len = ( iob_len ( iobuf ) -
791  offsetof ( typeof ( *dhcphdr ), options ) );
792 
793  /* Verify client identifier */
795  &dhcpv6->client_duid,
796  sizeof ( dhcpv6->client_duid ) ) ) !=0){
797  DBGC ( dhcpv6, "DHCPv6 %s received %s without correct client "
798  "ID: %s\n", dhcpv6->netdev->name,
799  dhcpv6_type_name ( dhcphdr->type ), strerror ( rc ) );
800  goto done;
801  }
802 
803  /* Verify server identifier, if applicable */
804  if ( dhcpv6->server_duid &&
806  dhcpv6->server_duid,
807  dhcpv6->server_duid_len ) ) != 0 ) ) {
808  DBGC ( dhcpv6, "DHCPv6 %s received %s without correct server "
809  "ID: %s\n", dhcpv6->netdev->name,
810  dhcpv6_type_name ( dhcphdr->type ), strerror ( rc ) );
811  goto done;
812  }
813 
814  /* Check message type */
815  if ( dhcphdr->type != dhcpv6->state->rx_type ) {
816  DBGC ( dhcpv6, "DHCPv6 %s received %s while expecting %s\n",
817  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
818  dhcpv6_type_name ( dhcpv6->state->rx_type ) );
819  rc = -ENOTTY;
820  goto done;
821  }
822 
823  /* Fetch status code, if present */
824  if ( ( rc = dhcpv6_status_code ( &options ) ) != 0 ) {
825  DBGC ( dhcpv6, "DHCPv6 %s received %s with error status: %s\n",
826  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
827  strerror ( rc ) );
828  /* This is plausibly the error we want to return */
829  dhcpv6->rc = rc;
830  goto done;
831  }
832 
833  /* Record identity association address, if applicable */
834  if ( dhcpv6->state->flags & DHCPV6_RX_RECORD_IAADDR ) {
835  if ( ( rc = dhcpv6_iaaddr ( &options, dhcpv6->iaid,
836  &dhcpv6->lease ) ) != 0 ) {
837  DBGC ( dhcpv6, "DHCPv6 %s received %s with unusable "
838  "IAADDR: %s\n", dhcpv6->netdev->name,
839  dhcpv6_type_name ( dhcphdr->type ),
840  strerror ( rc ) );
841  /* This is plausibly the error we want to return */
842  dhcpv6->rc = rc;
843  goto done;
844  }
845  DBGC ( dhcpv6, "DHCPv6 %s received %s is for %s\n",
846  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
847  inet6_ntoa ( &dhcpv6->lease ) );
848  }
849 
850  /* Record server ID, if applicable */
851  if ( dhcpv6->state->flags & DHCPV6_RX_RECORD_SERVER_ID ) {
852  assert ( dhcpv6->server_duid == NULL );
854  if ( ! option ) {
855  DBGC ( dhcpv6, "DHCPv6 %s received %s missing server "
856  "ID\n", dhcpv6->netdev->name,
857  dhcpv6_type_name ( dhcphdr->type ) );
858  rc = -EINVAL;
859  goto done;
860  }
861  dhcpv6->server_duid_len = ntohs ( option->duid.header.len );
862  dhcpv6->server_duid = malloc ( dhcpv6->server_duid_len );
863  if ( ! dhcpv6->server_duid ) {
864  rc = -ENOMEM;
865  goto done;
866  }
867  memcpy ( dhcpv6->server_duid, option->duid.duid,
868  dhcpv6->server_duid_len );
869  }
870 
871  /* Transition to next state, if applicable */
872  if ( dhcpv6->state->next ) {
873  dhcpv6_set_state ( dhcpv6, dhcpv6->state->next );
874  rc = 0;
875  goto done;
876  }
877 
878  /* Register settings */
879  if ( ( rc = dhcpv6_register ( &dhcpv6->lease, &options,
880  parent ) ) != 0 ) {
881  DBGC ( dhcpv6, "DHCPv6 %s could not register settings: %s\n",
882  dhcpv6->netdev->name, strerror ( rc ) );
883  goto done;
884  }
885 
886  /* Mark as complete */
887  dhcpv6_finished ( dhcpv6, 0 );
888  DBGC ( dhcpv6, "DHCPv6 %s complete\n", dhcpv6->netdev->name );
889 
890  done:
891  free_iob ( iobuf );
892  return rc;
893 }
uint8_t rx_type
Current expected received packet type.
Definition: dhcpv6.c:448
struct dhcpv6_session_state * next
Next state (or NULL to terminate)
Definition: dhcpv6.c:452
#define DHCPV6_SERVER_ID
DHCPv6 server identifier option.
Definition: dhcpv6.h:58
#define EINVAL
Invalid argument.
Definition: errno.h:428
Record received server ID.
Definition: dhcpv6.c:462
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
static void dhcpv6_set_state(struct dhcpv6_session *dhcpv6, struct dhcpv6_session_state *state)
Transition to new DHCPv6 session state.
Definition: dhcpv6.c:564
struct settings * parent
Parent settings block.
Definition: settings.h:138
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
static int dhcpv6_status_code(struct dhcpv6_option_list *options)
Get DHCPv6 status code.
Definition: dhcpv6.c:166
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:137
#define DBGC(...)
Definition: compiler.h:505
uint32_t iaid
Identity association ID.
Definition: dhcpv6.c:507
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:503
static const char * dhcpv6_type_name(unsigned int type)
Name a DHCPv6 packet type.
Definition: dhcpv6.c:428
uint8_t options[0]
DHCP options.
Definition: dhcp.h:659
#define ntohs(value)
Definition: byteswap.h:136
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:548
A DHCPv6 header.
Definition: dhcpv6.h:240
struct in6_addr lease
Leased IPv6 address.
Definition: dhcpv6.c:517
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:577
Any DHCPv6 option.
Definition: dhcpv6.h:225
Record received IPv6 address.
Definition: dhcpv6.c:464
struct dhcpv6_session_state * state
Current session state.
Definition: dhcpv6.c:523
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define DHCPV6_CLIENT_ID
DHCPv6 client identifier option.
Definition: dhcpv6.h:55
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:450
A long option, as used for getopt_long()
Definition: getopt.h:24
static int options
Definition: 3c515.c:286
void * server_duid
Server DUID, if known.
Definition: dhcpv6.c:513
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
int meta(WINDOW *, bool)
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
A settings block.
Definition: settings.h:132
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
int rc
Current timeout status code.
Definition: dhcpv6.c:525
A DHCP header.
Definition: dhcp.h:591
A DHCPv6 option list.
Definition: dhcpv6.c:85
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
size_t server_duid_len
Server DUID length.
Definition: dhcpv6.c:515
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
void * data
Start of data.
Definition: iobuf.h:44
struct dhcpv6_duid_uuid client_duid
Client DUID.
Definition: dhcpv6.c:511
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:100
static int dhcpv6_register(struct in6_addr *lease, struct dhcpv6_option_list *options, struct settings *parent)
Register DHCPv6 options as network device settings.
Definition: dhcpv6.c:361
IPv6 socket address.
Definition: in.h:115
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
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:198

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_state::rx_type, dhcpv6_session::server_duid, dhcpv6_session::server_duid_len, src, dhcpv6_session::state, and strerror().

◆ start_dhcpv6()

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

Start DHCPv6.

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

Definition at line 921 of file dhcpv6.c.

922  {
924  struct dhcpv6_session *dhcpv6;
925  struct {
926  union {
927  struct sockaddr_in6 sin6;
928  struct sockaddr sa;
929  } client;
930  union {
931  struct sockaddr_in6 sin6;
932  struct sockaddr sa;
933  } server;
934  } addresses;
935  uint32_t xid;
936  int len;
937  int rc;
938 
939  /* Allocate and initialise structure */
940  dhcpv6 = zalloc ( sizeof ( *dhcpv6 ) );
941  if ( ! dhcpv6 )
942  return -ENOMEM;
943  ref_init ( &dhcpv6->refcnt, dhcpv6_free );
944  intf_init ( &dhcpv6->job, &dhcpv6_job_desc, &dhcpv6->refcnt );
945  intf_init ( &dhcpv6->xfer, &dhcpv6_xfer_desc, &dhcpv6->refcnt );
946  dhcpv6->netdev = netdev_get ( netdev );
947  xid = random();
948  memcpy ( dhcpv6->xid, &xid, sizeof ( dhcpv6->xid ) );
949  dhcpv6->start = currticks();
950  timer_init ( &dhcpv6->timer, dhcpv6_timer_expired, &dhcpv6->refcnt );
951 
952  /* Construct client and server addresses */
953  memset ( &addresses, 0, sizeof ( addresses ) );
954  addresses.client.sin6.sin6_family = AF_INET6;
955  addresses.client.sin6.sin6_port = htons ( DHCPV6_CLIENT_PORT );
956  addresses.server.sin6.sin6_family = AF_INET6;
957  ipv6_all_dhcp_relay_and_servers ( &addresses.server.sin6.sin6_addr );
958  addresses.server.sin6.sin6_scope_id = netdev->index;
959  addresses.server.sin6.sin6_port = htons ( DHCPV6_SERVER_PORT );
960 
961  /* Construct client DUID from system UUID */
962  dhcpv6->client_duid.type = htons ( DHCPV6_DUID_UUID );
963  if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting,
964  &dhcpv6->client_duid.uuid ) ) < 0 ) {
965  rc = len;
966  DBGC ( dhcpv6, "DHCPv6 %s could not create DUID-UUID: %s\n",
967  dhcpv6->netdev->name, strerror ( rc ) );
968  goto err_client_duid;
969  }
970 
971  /* Construct IAID from link-layer address */
972  dhcpv6->iaid = crc32_le ( 0, netdev->ll_addr, ll_protocol->ll_addr_len);
973  DBGC ( dhcpv6, "DHCPv6 %s has XID %02x%02x%02x\n", dhcpv6->netdev->name,
974  dhcpv6->xid[0], dhcpv6->xid[1], dhcpv6->xid[2] );
975 
976  /* Enter initial state */
977  dhcpv6_set_state ( dhcpv6, ( stateful ? &dhcpv6_solicit :
979 
980  /* Open socket */
981  if ( ( rc = xfer_open_socket ( &dhcpv6->xfer, SOCK_DGRAM,
982  &addresses.server.sa,
983  &addresses.client.sa ) ) != 0 ) {
984  DBGC ( dhcpv6, "DHCPv6 %s could not open socket: %s\n",
985  dhcpv6->netdev->name, strerror ( rc ) );
986  goto err_open_socket;
987  }
988 
989  /* Attach parent interface, mortalise self, and return */
990  intf_plug_plug ( &dhcpv6->job, job );
991  ref_put ( &dhcpv6->refcnt );
992  return 0;
993 
994  err_open_socket:
995  dhcpv6_finished ( dhcpv6, rc );
996  err_client_duid:
997  ref_put ( &dhcpv6->refcnt );
998  return rc;
999 }
static struct dhcpv6_session_state dhcpv6_solicit
DHCPv6 solicitation state.
Definition: dhcpv6.c:477
A DHCPv6 session.
Definition: dhcpv6.c:494
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
static struct interface_descriptor dhcpv6_xfer_desc
DHCPv6 data transfer interface descriptor.
Definition: dhcpv6.c:910
struct interface xfer
Data transfer interface.
Definition: dhcpv6.c:500
struct sockaddr sa
Definition: dns.c:68
struct interface job
Job control interface.
Definition: dhcpv6.c:498
static void dhcpv6_set_state(struct dhcpv6_session *dhcpv6, struct dhcpv6_session_state *state)
Transition to new DHCPv6 session state.
Definition: dhcpv6.c:564
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:141
#define SOCK_DGRAM
Definition: socket.h:29
#define DBGC(...)
Definition: compiler.h:505
uint32_t iaid
Identity association ID.
Definition: dhcpv6.c:507
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:503
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:548
A link-layer protocol.
Definition: netdevice.h:114
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition: crc32.c:39
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static struct net_device * netdev
Definition: gdbudp.c:52
struct refcnt refcnt
Reference counter.
Definition: dhcpv6.c:496
static void dhcpv6_free(struct refcnt *refcnt)
Free DHCPv6 session.
Definition: dhcpv6.c:533
static void dhcpv6_timer_expired(struct retry_timer *timer, int fail)
Handle timer expiry.
Definition: dhcpv6.c:739
Generalized socket address structure.
Definition: socket.h:96
static struct dhcpv6_session_state dhcpv6_information_request
DHCPv6 information request state.
Definition: dhcpv6.c:486
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:30
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:544
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:520
unsigned int uint32_t
Definition: stdint.h:12
uint16_t type
Type.
Definition: dhcpv6.h:38
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
uint32_t len
Length.
Definition: ena.h:14
unsigned int index
Index of this network device.
Definition: netdevice.h:356
unsigned long start
Start time (in ticks)
Definition: dhcpv6.c:509
struct sockaddr_in6 sin6
Definition: dns.c:71
struct dhcpv6_duid_uuid client_duid
Client DUID.
Definition: dhcpv6.c:511
static void ipv6_all_dhcp_relay_and_servers(struct in6_addr *addr)
Construct all-DHCP-relay-agents-and-servers multicast address.
Definition: dhcpv6.h:272
uint8_t xid[3]
Transaction ID.
Definition: dhcpv6.c:505
#define DHCPV6_CLIENT_PORT
DHCPv6 client port.
Definition: dhcpv6.h:20
static struct interface_descriptor dhcpv6_job_desc
DHCPv6 job control interface descriptor.
Definition: dhcpv6.c:901
IPv6 socket address.
Definition: in.h:115
#define DHCPV6_DUID_UUID
DHCP unique identifier based on UUID (DUID-UUID)
Definition: dhcpv6.h:44
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
Definition: settings.c:1088
#define DHCPV6_SERVER_PORT
DHCPv6 server port.
Definition: dhcpv6.h:17
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:381
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define htons(value)
Definition: byteswap.h:135
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:366
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
void * memset(void *dest, int character, size_t len) __nonnull
union uuid uuid
UUID.
Definition: dhcpv6.h:40

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, net_device::index, 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, sa, 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:23
#define EINFO_EPROTO_NOADDRSAVAIL
Definition: dhcpv6.c:57

Human-readable error messages.

Definition at line 74 of file dhcpv6.c.

◆ 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:282
static int dhcpv6_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of DHCPv6 setting.
Definition: dhcpv6.c:322

DHCPv6 settings operations.

Definition at line 348 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:173
#define DHCP_ARCH_CLIENT_NDI
Definition: dhcp_arch.h:38
#define DHCPV6_VENDOR_CLASS_PXE
DHCPv6 PXE vendor class.
Definition: dhcpv6.h:161
#define DHCPV6_VENDOR_CLASS
DHCPv6 vendor class option.
Definition: dhcpv6.h:149
#define DHCPV6_DWORD_VALUE(value)
Construct a DHCPv6 dword value.
Definition: dhcpv6.h:196
#define DHCPV6_CODE(code)
Construct a DHCPv6 option code.
Definition: dhcpv6.h:200
#define DHCPV6_DNS_SERVERS
DHCPv6 DNS recursive name server option.
Definition: dhcpv6.h:164
#define DHCPV6_OPTION_REQUEST
DHCPv6 option request option.
Definition: dhcpv6.h:103
#define DHCPV6_DOMAIN_LIST
DHCPv6 domain search list option.
Definition: dhcpv6.h:167
#define DHCPV6_WORD(value)
Construct a word-valued DHCPv6 option.
Definition: dhcpv6.h:216
#define DHCPV6_STRING(...)
Construct a DHCPv6 option from a list of characters.
Definition: dhcpv6.h:210
#define DHCP_VENDOR_PXECLIENT(arch, ndi)
Vendor class identifier for PXE clients.
Definition: dhcp.h:217
#define DHCPV6_CLIENT_ARCHITECTURE
DHCPv6 client system architecture option.
Definition: dhcpv6.h:176
#define DHCP_ARCH_CLIENT_ARCHITECTURE
Definition: dhcp_arch.h:36
#define DHCPV6_BOOTFILE_URL
DHCPv6 bootfile URI option.
Definition: dhcpv6.h:170
#define DHCPV6_CLIENT_NDI
DHCPv6 client network interface identifier option.
Definition: dhcpv6.h:179
#define DHCPV6_OPTION(...)
Construct a DHCPv6 option from a list of bytes.
Definition: dhcpv6.h:206

Raw option data for options common to all DHCPv6 requests.

Definition at line 404 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,
}
uint32_t next
Next descriptor address.
Definition: myson.h:18
Include leased IPv6 address within request.
Definition: dhcpv6.c:460
#define DHCPV6_REPLY
DHCPv6 reply.
Definition: dhcpv6.h:259
Record received IPv6 address.
Definition: dhcpv6.c:464
#define DHCPV6_REQUEST
DHCPv6 request.
Definition: dhcpv6.h:256
Include identity association within request.
Definition: dhcpv6.c:458
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

DHCPv6 request state.

Definition at line 468 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:462
#define DHCPV6_SOLICIT
DHCPv6 solicitation.
Definition: dhcpv6.h:250
uint32_t next
Next descriptor address.
Definition: myson.h:18
Record received IPv6 address.
Definition: dhcpv6.c:464
#define DHCPV6_ADVERTISE
DHCPv6 advertisement.
Definition: dhcpv6.h:253
Include identity association within request.
Definition: dhcpv6.c:458
static struct dhcpv6_session_state dhcpv6_request
DHCPv6 request state.
Definition: dhcpv6.c:468

DHCPv6 solicitation state.

Definition at line 477 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:262
#define DHCPV6_REPLY
DHCPv6 reply.
Definition: dhcpv6.h:259
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

DHCPv6 information request state.

Definition at line 486 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:494
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:548
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32

DHCPv6 job control interface operations.

Definition at line 896 of file dhcpv6.c.

◆ dhcpv6_job_desc

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

DHCPv6 job control interface descriptor.

Definition at line 901 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:494
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
static int dhcpv6_rx(struct dhcpv6_session *dhcpv6, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new data.
Definition: dhcpv6.c:764

DHCPv6 data transfer interface operations.

Definition at line 905 of file dhcpv6.c.

◆ dhcpv6_xfer_desc

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

DHCPv6 data transfer interface descriptor.

Definition at line 910 of file dhcpv6.c.

Referenced by start_dhcpv6().