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

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

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 }
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
#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:321
#define htons(value)
Definition: byteswap.h:135

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 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:114

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
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
#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, 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 284 of file dhcpv6.c.

285  {
286 
287  return ( ( setting->scope == &dhcpv6_scope ) ||
288  ( setting->scope == &ipv6_settings_scope ) );
289 }
const struct settings_scope dhcpv6_scope
IPv6 settings scope.
Definition: settings.c:1792
A setting.
Definition: settings.h:23
const struct settings_scope ipv6_settings_scope
IPv6 settings scope.
Definition: ipv6.c:1120
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:49

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

300  {
301  struct in6_addr *lease = &dhcpv6set->lease;
302 
303  /* Copy leased address */
304  if ( len > sizeof ( *lease ) )
305  len = sizeof ( *lease );
306  memcpy ( data, lease, len );
307 
308  return sizeof ( *lease );
309 }
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:50
uint32_t lease
Definition: ib_mad.h:15
uint32_t len
Length.
Definition: ena.h:14
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 319 of file dhcpv6.c.

320  {
321  uint8_t *len6 = data;
322 
323  /* Default to assuming this is the only address on the link.
324  * If the address falls within a known prefix, then the IPv6
325  * routing table construction logic will match it against that
326  * prefix.
327  */
328  if ( len )
329  *len6 = IPV6_MAX_PREFIX_LEN;
330 
331  return sizeof ( *len6 );
332 }
#define IPV6_MAX_PREFIX_LEN
IPv6 maximum prefix length.
Definition: ipv6.h:32
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
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 342 of file dhcpv6.c.

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

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

388  {
389  struct dhcpv6_settings *dhcpv6set =
391  const union dhcpv6_any_option *option;
393  size_t option_len;
394  unsigned int i;
395 
396  /* Handle address settings */
397  for ( i = 0 ; i < ( sizeof ( dhcpv6_address_operations ) /
398  sizeof ( dhcpv6_address_operations[0] ) ) ; i++ ) {
400  if ( setting_cmp ( setting, op->setting ) != 0 )
401  continue;
402  if ( IN6_IS_ADDR_UNSPECIFIED ( &dhcpv6set->lease ) )
403  return -ENOENT;
404  return op->fetch ( dhcpv6set, data, len );
405  }
406 
407  /* Find option */
408  option = dhcpv6_option ( &dhcpv6set->options, setting->tag );
409  if ( ! option )
410  return -ENOENT;
411 
412  /* Copy option to data buffer */
413  option_len = ntohs ( option->header.len );
414  if ( len > option_len )
415  len = option_len;
416  memcpy ( data, option->header.data, len );
417  return option_len;
418 }
#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
struct in6_addr lease
Leased address.
Definition: dhcpv6.c:270
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:274
#define IN6_IS_ADDR_UNSPECIFIED(addr)
Definition: in.h:61
A settings block.
Definition: settings.h:132
static struct dhcpv6_address_operation dhcpv6_address_operations[]
DHCPv6 address settings operations.
Definition: dhcpv6.c:371
A setting.
Definition: settings.h:23
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
uint32_t len
Length.
Definition: ena.h:14
A DHCPv6 address setting operation.
Definition: dhcpv6.c:355
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:100
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:1120

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

437  {
438  struct dhcpv6_settings *dhcpv6set;
439  void *data;
440  size_t len;
441  int rc;
442 
443  /* Allocate and initialise structure */
444  dhcpv6set = zalloc ( sizeof ( *dhcpv6set ) + options->len );
445  if ( ! dhcpv6set ) {
446  rc = -ENOMEM;
447  goto err_alloc;
448  }
449  ref_init ( &dhcpv6set->refcnt, NULL );
451  &dhcpv6set->refcnt, &dhcpv6_scope );
452  dhcpv6set->settings.order = IPV6_ORDER_DHCPV6;
453  data = ( ( ( void * ) dhcpv6set ) + sizeof ( *dhcpv6set ) );
454  len = options->len;
455  memcpy ( data, options->data, len );
456  dhcpv6set->options.data = data;
457  dhcpv6set->options.len = len;
458  memcpy ( &dhcpv6set->lease, lease, sizeof ( dhcpv6set->lease ) );
459  memcpy ( &dhcpv6set->router, router, sizeof ( dhcpv6set->router ) );
460 
461  /* Register settings */
462  if ( ( rc = register_settings ( &dhcpv6set->settings, parent,
463  DHCPV6_SETTINGS_NAME ) ) != 0 )
464  goto err_register;
465 
466  err_register:
467  ref_put ( &dhcpv6set->refcnt );
468  err_alloc:
469  return rc;
470 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const struct settings_scope dhcpv6_scope
IPv6 settings scope.
Definition: settings.c:1792
#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:421
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:500
#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:274
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
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:475
struct in6_addr router
Router address.
Definition: dhcpv6.c:272
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
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::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 503 of file dhcpv6.c.

503  {
504  static char buf[ 12 /* "UNKNOWN-xxx" + NUL */ ];
505 
506  switch ( type ) {
507  case DHCPV6_SOLICIT: return "SOLICIT";
508  case DHCPV6_ADVERTISE: return "ADVERTISE";
509  case DHCPV6_REQUEST: return "REQUEST";
510  case DHCPV6_REPLY: return "REPLY";
511  case DHCPV6_INFORMATION_REQUEST: return "INFORMATION-REQUEST";
512  default:
513  snprintf ( buf, sizeof ( buf ), "UNKNOWN-%d", type );
514  return buf;
515  }
516 }
#define DHCPV6_SOLICIT
DHCPv6 solicitation.
Definition: dhcpv6.h:250
#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
uint32_t type
Operating system type.
Definition: ena.h:12
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 610 of file dhcpv6.c.

610  {
611  struct dhcpv6_session *dhcpv6 =
613 
614  netdev_put ( dhcpv6->netdev );
615  free ( dhcpv6->server_duid );
616  free ( dhcpv6 );
617 }
A DHCPv6 session.
Definition: dhcpv6.c:569
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:578
A reference counter.
Definition: refcnt.h:26
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
void * server_duid
Server DUID, if known.
Definition: dhcpv6.c:590
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 625 of file dhcpv6.c.

625  {
626 
627  /* Stop timer */
628  stop_timer ( &dhcpv6->timer );
629 
630  /* Shut down interfaces */
631  intf_shutdown ( &dhcpv6->xfer, rc );
632  intf_shutdown ( &dhcpv6->job, rc );
633 }
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:278
struct interface xfer
Data transfer interface.
Definition: dhcpv6.c:575
struct interface job
Job control interface.
Definition: dhcpv6.c:573
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:597
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 641 of file dhcpv6.c.

642  {
643 
644  DBGC ( dhcpv6, "DHCPv6 %s entering %s state\n", dhcpv6->netdev->name,
645  dhcpv6_type_name ( state->tx_type ) );
646 
647  /* Record state */
648  dhcpv6->state = state;
649 
650  /* Default to -ETIMEDOUT if no more specific error is recorded */
651  dhcpv6->rc = -ETIMEDOUT;
652 
653  /* Start timer to trigger transmission */
654  start_timer_nodelay ( &dhcpv6->timer );
655 }
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:578
static const char * dhcpv6_type_name(unsigned int type)
Name a DHCPv6 packet type.
Definition: dhcpv6.c:503
struct dhcpv6_session_state * state
Current session state.
Definition: dhcpv6.c:600
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:597
int rc
Current timeout status code.
Definition: dhcpv6.c:602
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
#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 664 of file dhcpv6.c.

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

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

686  {
687  struct dhcpv6_duid_option *client_id;
688  struct dhcpv6_duid_option *server_id;
689  struct dhcpv6_ia_na_option *ia_na;
690  struct dhcpv6_iaaddr_option *iaaddr;
693  struct dhcpv6_header *dhcphdr;
694  struct io_buffer *iobuf;
695  void *options;
696  size_t client_id_len;
697  size_t server_id_len;
698  size_t ia_na_len;
699  size_t user_class_string_len;
700  size_t user_class_len;
701  size_t elapsed_len;
702  size_t total_len;
703  int rc;
704 
705  /* Calculate lengths */
706  client_id_len = ( sizeof ( *client_id ) +
707  sizeof ( dhcpv6->client_duid ) );
708  server_id_len = ( dhcpv6->server_duid ? ( sizeof ( *server_id ) +
709  dhcpv6->server_duid_len ) :0);
710  if ( dhcpv6->state->flags & DHCPV6_TX_IA_NA ) {
711  ia_na_len = sizeof ( *ia_na );
712  if ( dhcpv6->state->flags & DHCPV6_TX_IAADDR )
713  ia_na_len += sizeof ( *iaaddr );
714  } else {
715  ia_na_len = 0;
716  }
717  user_class_string_len = dhcpv6_user_class ( NULL, 0 );
718  user_class_len = ( sizeof ( *user_class ) +
719  sizeof ( user_class->user_class[0] ) +
720  user_class_string_len );
721  elapsed_len = sizeof ( *elapsed );
722  total_len = ( sizeof ( *dhcphdr ) + client_id_len + server_id_len +
723  ia_na_len + sizeof ( dhcpv6_request_options_data ) +
724  user_class_len + elapsed_len );
725 
726  /* Allocate packet */
727  iobuf = xfer_alloc_iob ( &dhcpv6->xfer, total_len );
728  if ( ! iobuf )
729  return -ENOMEM;
730 
731  /* Construct header */
732  dhcphdr = iob_put ( iobuf, sizeof ( *dhcphdr ) );
733  dhcphdr->type = dhcpv6->state->tx_type;
734  memcpy ( dhcphdr->xid, dhcpv6->xid, sizeof ( dhcphdr->xid ) );
735 
736  /* Construct client identifier */
737  client_id = iob_put ( iobuf, client_id_len );
738  client_id->header.code = htons ( DHCPV6_CLIENT_ID );
739  client_id->header.len = htons ( client_id_len -
740  sizeof ( client_id->header ) );
741  memcpy ( client_id->duid, &dhcpv6->client_duid,
742  sizeof ( dhcpv6->client_duid ) );
743 
744  /* Construct server identifier, if applicable */
745  if ( server_id_len ) {
746  server_id = iob_put ( iobuf, server_id_len );
747  server_id->header.code = htons ( DHCPV6_SERVER_ID );
748  server_id->header.len = htons ( server_id_len -
749  sizeof ( server_id->header ) );
750  memcpy ( server_id->duid, dhcpv6->server_duid,
751  dhcpv6->server_duid_len );
752  }
753 
754  /* Construct identity association, if applicable */
755  if ( ia_na_len ) {
756  ia_na = iob_put ( iobuf, ia_na_len );
757  ia_na->header.code = htons ( DHCPV6_IA_NA );
758  ia_na->header.len = htons ( ia_na_len -
759  sizeof ( ia_na->header ) );
760  ia_na->iaid = htonl ( dhcpv6->iaid );
761  ia_na->renew = htonl ( 0 );
762  ia_na->rebind = htonl ( 0 );
763  if ( dhcpv6->state->flags & DHCPV6_TX_IAADDR ) {
764  iaaddr = ( ( void * ) ia_na->options );
765  iaaddr->header.code = htons ( DHCPV6_IAADDR );
766  iaaddr->header.len = htons ( sizeof ( *iaaddr ) -
767  sizeof ( iaaddr->header ));
768  memcpy ( &iaaddr->address, &dhcpv6->lease,
769  sizeof ( iaaddr->address ) );
770  iaaddr->preferred = htonl ( 0 );
771  iaaddr->valid = htonl ( 0 );
772  }
773  }
774 
775  /* Construct fixed request options */
776  options = iob_put ( iobuf, sizeof ( dhcpv6_request_options_data ) );
778  sizeof ( dhcpv6_request_options_data ) );
779 
780  /* Construct user class */
781  user_class = iob_put ( iobuf, user_class_len );
782  user_class->header.code = htons ( DHCPV6_USER_CLASS );
783  user_class->header.len = htons ( user_class_len -
784  sizeof ( user_class->header ) );
785  user_class->user_class[0].len = htons ( user_class_string_len );
786  dhcpv6_user_class ( user_class->user_class[0].string,
787  user_class_string_len );
788 
789  /* Construct elapsed time */
790  elapsed = iob_put ( iobuf, elapsed_len );
791  elapsed->header.code = htons ( DHCPV6_ELAPSED_TIME );
792  elapsed->header.len = htons ( elapsed_len -
793  sizeof ( elapsed->header ) );
794  elapsed->elapsed = htons ( ( ( currticks() - dhcpv6->start ) * 100 ) /
795  TICKS_PER_SEC );
796 
797  /* Sanity check */
798  assert ( iob_len ( iobuf ) == total_len );
799 
800  /* Transmit packet */
801  if ( ( rc = xfer_deliver_iob ( &dhcpv6->xfer, iobuf ) ) != 0 ) {
802  DBGC ( dhcpv6, "DHCPv6 %s could not transmit: %s\n",
803  dhcpv6->netdev->name, strerror ( rc ) );
804  return rc;
805  }
806 
807  return 0;
808 }
#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:120
#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:255
struct interface xfer
Data transfer interface.
Definition: dhcpv6.c:575
Include leased IPv6 address within request.
Definition: dhcpv6.c:535
static uint8_t dhcpv6_request_options_data[]
Raw option data for options common to all DHCPv6 requests.
Definition: dhcpv6.c:479
#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:584
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:578
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
uint32_t xid
Transaction ID.
Definition: dhcp.h:631
uint8_t tx_type
Current transmitted packet type.
Definition: dhcpv6.c:521
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:594
#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:600
#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:525
static int options
Definition: 3c515.c:286
void * server_duid
Server DUID, if known.
Definition: dhcpv6.c:590
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:155
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:613
uint32_t renew
Renew time (in seconds)
Definition: dhcpv6.h:67
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
size_t server_duid_len
Server DUID length.
Definition: dhcpv6.c:592
uint16_t len
Length of the data field.
Definition: dhcpv6.h:30
unsigned long start
Start time (in ticks)
Definition: dhcpv6.c:586
struct dhcpv6_option header
Option header.
Definition: dhcpv6.h:63
struct dhcpv6_duid_uuid client_duid
Client DUID.
Definition: dhcpv6.c:588
uint8_t xid[3]
Transaction ID.
Definition: dhcpv6.c:582
#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:664
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:533
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:321
#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:33
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 816 of file dhcpv6.c.

816  {
817  struct dhcpv6_session *dhcpv6 =
818  container_of ( timer, struct dhcpv6_session, timer );
819 
820  /* If we have failed, terminate DHCPv6 */
821  if ( fail ) {
822  dhcpv6_finished ( dhcpv6, dhcpv6->rc );
823  return;
824  }
825 
826  /* Restart timer */
827  start_timer ( &dhcpv6->timer );
828 
829  /* (Re)transmit current request */
830  dhcpv6_tx ( dhcpv6 );
831 }
static int dhcpv6_tx(struct dhcpv6_session *dhcpv6)
Transmit current request.
Definition: dhcpv6.c:686
A DHCPv6 session.
Definition: dhcpv6.c:569
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:625
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:597
int rc
Current timeout status code.
Definition: dhcpv6.c:602
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 841 of file dhcpv6.c.

843  {
844  struct settings *parent = netdev_settings ( dhcpv6->netdev );
845  struct sockaddr_in6 *src = ( ( struct sockaddr_in6 * ) meta->src );
846  struct dhcpv6_header *dhcphdr = iobuf->data;
848  const union dhcpv6_any_option *option;
849  int rc;
850 
851  /* Sanity checks */
852  if ( iob_len ( iobuf ) < sizeof ( *dhcphdr ) ) {
853  DBGC ( dhcpv6, "DHCPv6 %s received packet too short (%zd "
854  "bytes, min %zd bytes)\n", dhcpv6->netdev->name,
855  iob_len ( iobuf ), sizeof ( *dhcphdr ) );
856  rc = -EINVAL;
857  goto done;
858  }
859  assert ( src != NULL );
860  assert ( src->sin6_family == AF_INET6 );
861  DBGC ( dhcpv6, "DHCPv6 %s received %s from %s\n",
862  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
863  inet6_ntoa ( &src->sin6_addr ) );
864 
865  /* Construct option list */
866  options.data = dhcphdr->options;
867  options.len = ( iob_len ( iobuf ) -
868  offsetof ( typeof ( *dhcphdr ), options ) );
869 
870  /* Verify client identifier */
872  &dhcpv6->client_duid,
873  sizeof ( dhcpv6->client_duid ) ) ) !=0){
874  DBGC ( dhcpv6, "DHCPv6 %s received %s without correct client "
875  "ID: %s\n", dhcpv6->netdev->name,
876  dhcpv6_type_name ( dhcphdr->type ), strerror ( rc ) );
877  goto done;
878  }
879 
880  /* Verify server identifier, if applicable */
881  if ( dhcpv6->server_duid &&
883  dhcpv6->server_duid,
884  dhcpv6->server_duid_len ) ) != 0 ) ) {
885  DBGC ( dhcpv6, "DHCPv6 %s received %s without correct server "
886  "ID: %s\n", dhcpv6->netdev->name,
887  dhcpv6_type_name ( dhcphdr->type ), strerror ( rc ) );
888  goto done;
889  }
890 
891  /* Check message type */
892  if ( dhcphdr->type != dhcpv6->state->rx_type ) {
893  DBGC ( dhcpv6, "DHCPv6 %s received %s while expecting %s\n",
894  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
895  dhcpv6_type_name ( dhcpv6->state->rx_type ) );
896  rc = -ENOTTY;
897  goto done;
898  }
899 
900  /* Fetch status code, if present */
901  if ( ( rc = dhcpv6_status_code ( &options ) ) != 0 ) {
902  DBGC ( dhcpv6, "DHCPv6 %s received %s with error status: %s\n",
903  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
904  strerror ( rc ) );
905  /* This is plausibly the error we want to return */
906  dhcpv6->rc = rc;
907  goto done;
908  }
909 
910  /* Record identity association address, if applicable */
911  if ( dhcpv6->state->flags & DHCPV6_RX_RECORD_IAADDR ) {
912  if ( ( rc = dhcpv6_iaaddr ( &options, dhcpv6->iaid,
913  &dhcpv6->lease ) ) != 0 ) {
914  DBGC ( dhcpv6, "DHCPv6 %s received %s with unusable "
915  "IAADDR: %s\n", dhcpv6->netdev->name,
916  dhcpv6_type_name ( dhcphdr->type ),
917  strerror ( rc ) );
918  /* This is plausibly the error we want to return */
919  dhcpv6->rc = rc;
920  goto done;
921  }
922  DBGC ( dhcpv6, "DHCPv6 %s received %s is for %s\n",
923  dhcpv6->netdev->name, dhcpv6_type_name ( dhcphdr->type ),
924  inet6_ntoa ( &dhcpv6->lease ) );
925  }
926 
927  /* Record server ID, if applicable */
928  if ( dhcpv6->state->flags & DHCPV6_RX_RECORD_SERVER_ID ) {
929  assert ( dhcpv6->server_duid == NULL );
931  if ( ! option ) {
932  DBGC ( dhcpv6, "DHCPv6 %s received %s missing server "
933  "ID\n", dhcpv6->netdev->name,
934  dhcpv6_type_name ( dhcphdr->type ) );
935  rc = -EINVAL;
936  goto done;
937  }
938  dhcpv6->server_duid_len = ntohs ( option->duid.header.len );
939  dhcpv6->server_duid = malloc ( dhcpv6->server_duid_len );
940  if ( ! dhcpv6->server_duid ) {
941  rc = -ENOMEM;
942  goto done;
943  }
944  memcpy ( dhcpv6->server_duid, option->duid.duid,
945  dhcpv6->server_duid_len );
946  }
947 
948  /* Transition to next state, if applicable */
949  if ( dhcpv6->state->next ) {
950  dhcpv6_set_state ( dhcpv6, dhcpv6->state->next );
951  rc = 0;
952  goto done;
953  }
954 
955  /* Register settings */
956  if ( ( rc = dhcpv6_register ( &dhcpv6->lease, &dhcpv6->router,
957  &options, parent ) ) != 0 ) {
958  DBGC ( dhcpv6, "DHCPv6 %s could not register settings: %s\n",
959  dhcpv6->netdev->name, strerror ( rc ) );
960  goto done;
961  }
962 
963  /* Mark as complete */
964  dhcpv6_finished ( dhcpv6, 0 );
965  DBGC ( dhcpv6, "DHCPv6 %s complete\n", dhcpv6->netdev->name );
966 
967  done:
968  free_iob ( iobuf );
969  return rc;
970 }
uint8_t rx_type
Current expected received packet type.
Definition: dhcpv6.c:523
struct dhcpv6_session_state * next
Next state (or NULL to terminate)
Definition: dhcpv6.c:527
#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:537
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:641
struct settings * parent
Parent settings block.
Definition: settings.h:138
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
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
static void const void * src
Definition: crypto.h:244
#define DBGC(...)
Definition: compiler.h:505
uint32_t iaid
Identity association ID.
Definition: dhcpv6.c:584
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:578
static const char * dhcpv6_type_name(unsigned int type)
Name a DHCPv6 packet type.
Definition: dhcpv6.c:503
uint8_t options[0]
DHCP options.
Definition: dhcp.h:681
#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:625
A DHCPv6 header.
Definition: dhcpv6.h:240
struct in6_addr lease
Leased IPv6 address.
Definition: dhcpv6.c:594
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
Any DHCPv6 option.
Definition: dhcpv6.h:225
Record received IPv6 address.
Definition: dhcpv6.c:539
struct dhcpv6_session_state * state
Current session state.
Definition: dhcpv6.c:600
#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:525
A long option, as used for getopt_long()
Definition: getopt.h:24
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:435
static int options
Definition: 3c515.c:286
struct in6_addr router
Router address.
Definition: dhcpv6.c:580
void * server_duid
Server DUID, if known.
Definition: dhcpv6.c:590
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:155
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:602
A DHCP header.
Definition: dhcp.h:613
A DHCPv6 option list.
Definition: dhcpv6.c:85
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
size_t server_duid_len
Server DUID length.
Definition: dhcpv6.c:592
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
void * data
Start of data.
Definition: iobuf.h:48
struct dhcpv6_duid_uuid client_duid
Client DUID.
Definition: dhcpv6.c:588
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
Definition: dhcpv6.c:100
IPv6 socket address.
Definition: in.h:117
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
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::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 999 of file dhcpv6.c.

1000  {
1002  struct dhcpv6_session *dhcpv6;
1003  struct {
1004  union {
1005  struct sockaddr_in6 sin6;
1006  struct sockaddr sa;
1007  } client;
1008  union {
1009  struct sockaddr_in6 sin6;
1010  struct sockaddr sa;
1011  } server;
1012  } addresses;
1013  uint32_t xid;
1014  int len;
1015  int rc;
1016 
1017  /* Allocate and initialise structure */
1018  dhcpv6 = zalloc ( sizeof ( *dhcpv6 ) );
1019  if ( ! dhcpv6 )
1020  return -ENOMEM;
1021  ref_init ( &dhcpv6->refcnt, dhcpv6_free );
1022  intf_init ( &dhcpv6->job, &dhcpv6_job_desc, &dhcpv6->refcnt );
1023  intf_init ( &dhcpv6->xfer, &dhcpv6_xfer_desc, &dhcpv6->refcnt );
1024  dhcpv6->netdev = netdev_get ( netdev );
1025  memcpy ( &dhcpv6->router, router, sizeof ( dhcpv6->router ) );
1026  xid = random();
1027  memcpy ( dhcpv6->xid, &xid, sizeof ( dhcpv6->xid ) );
1028  dhcpv6->start = currticks();
1029  timer_init ( &dhcpv6->timer, dhcpv6_timer_expired, &dhcpv6->refcnt );
1030 
1031  /* Construct client and server addresses */
1032  memset ( &addresses, 0, sizeof ( addresses ) );
1033  addresses.client.sin6.sin6_family = AF_INET6;
1034  addresses.client.sin6.sin6_port = htons ( DHCPV6_CLIENT_PORT );
1035  addresses.server.sin6.sin6_family = AF_INET6;
1036  ipv6_all_dhcp_relay_and_servers ( &addresses.server.sin6.sin6_addr );
1037  addresses.server.sin6.sin6_scope_id = netdev->scope_id;
1038  addresses.server.sin6.sin6_port = htons ( DHCPV6_SERVER_PORT );
1039 
1040  /* Construct client DUID from system UUID */
1041  dhcpv6->client_duid.type = htons ( DHCPV6_DUID_UUID );
1042  if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting,
1043  &dhcpv6->client_duid.uuid ) ) < 0 ) {
1044  rc = len;
1045  DBGC ( dhcpv6, "DHCPv6 %s could not create DUID-UUID: %s\n",
1046  dhcpv6->netdev->name, strerror ( rc ) );
1047  goto err_client_duid;
1048  }
1049 
1050  /* Construct IAID from link-layer address */
1051  dhcpv6->iaid = crc32_le ( 0, netdev->ll_addr, ll_protocol->ll_addr_len);
1052  DBGC ( dhcpv6, "DHCPv6 %s has XID %02x%02x%02x\n", dhcpv6->netdev->name,
1053  dhcpv6->xid[0], dhcpv6->xid[1], dhcpv6->xid[2] );
1054 
1055  /* Enter initial state */
1056  dhcpv6_set_state ( dhcpv6, ( stateful ? &dhcpv6_solicit :
1058 
1059  /* Open socket */
1060  if ( ( rc = xfer_open_socket ( &dhcpv6->xfer, SOCK_DGRAM,
1061  &addresses.server.sa,
1062  &addresses.client.sa ) ) != 0 ) {
1063  DBGC ( dhcpv6, "DHCPv6 %s could not open socket: %s\n",
1064  dhcpv6->netdev->name, strerror ( rc ) );
1065  goto err_open_socket;
1066  }
1067 
1068  /* Attach parent interface, mortalise self, and return */
1069  intf_plug_plug ( &dhcpv6->job, job );
1070  ref_put ( &dhcpv6->refcnt );
1071  return 0;
1072 
1073  err_open_socket:
1074  dhcpv6_finished ( dhcpv6, rc );
1075  err_client_duid:
1076  ref_put ( &dhcpv6->refcnt );
1077  return rc;
1078 }
static struct dhcpv6_session_state dhcpv6_solicit
DHCPv6 solicitation state.
Definition: dhcpv6.c:552
A DHCPv6 session.
Definition: dhcpv6.c:569
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:987
struct interface xfer
Data transfer interface.
Definition: dhcpv6.c:575
struct interface job
Job control interface.
Definition: dhcpv6.c:573
static void dhcpv6_set_state(struct dhcpv6_session *dhcpv6, struct dhcpv6_session_state *state)
Transition to new DHCPv6 session state.
Definition: dhcpv6.c:641
#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:142
#define SOCK_DGRAM
Definition: socket.h:29
#define DBGC(...)
Definition: compiler.h:505
struct sockaddr_in6 sin6
Definition: syslog.c:58
uint32_t iaid
Identity association ID.
Definition: dhcpv6.c:584
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:107
struct net_device * netdev
Network device being configured.
Definition: dhcpv6.c:578
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:625
unsigned int scope_id
Scope ID.
Definition: netdevice.h:360
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 sockaddr sa
Definition: syslog.c:55
struct in6_addr router
Router address.
Definition: dhcpv6.c:580
struct refcnt refcnt
Reference counter.
Definition: dhcpv6.c:571
static void dhcpv6_free(struct refcnt *refcnt)
Free DHCPv6 session.
Definition: dhcpv6.c:610
static void dhcpv6_timer_expired(struct retry_timer *timer, int fail)
Handle timer expiry.
Definition: dhcpv6.c:816
Generalized socket address structure.
Definition: socket.h:96
static struct dhcpv6_session_state dhcpv6_information_request
DHCPv6 information request state.
Definition: dhcpv6.c:561
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:31
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:561
struct retry_timer timer
Retransmission timer.
Definition: dhcpv6.c:597
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:362
uint32_t len
Length.
Definition: ena.h:14
unsigned long start
Start time (in ticks)
Definition: dhcpv6.c:586
struct dhcpv6_duid_uuid client_duid
Client DUID.
Definition: dhcpv6.c:588
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:582
#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:978
IPv6 socket address.
Definition: in.h:117
#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:1084
#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:387
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:203
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
#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, 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:23
#define EINFO_EPROTO_NOADDRSAVAIL
Definition: dhcpv6.c:57

Human-readable error messages.

Definition at line 74 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:299
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:319
static int dhcpv6_fetch_gateway6(struct dhcpv6_settings *dhcpv6set, void *data, size_t len)
Fetch value of DHCPv6 router address.
Definition: dhcpv6.c:342

DHCPv6 address settings operations.

Definition at line 371 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:284
static int dhcpv6_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of DHCPv6 setting.
Definition: dhcpv6.c:386

DHCPv6 settings operations.

Definition at line 421 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
DHCP client network device interface.
Definition: dhcparch.h:18
#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 DHCP_ARCH_CLIENT_ARCHITECTURE
DHCP client architecture.
Definition: dhcparch.h:15
#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:220
#define DHCPV6_CLIENT_ARCHITECTURE
DHCPv6 client system architecture option.
Definition: dhcpv6.h:176
#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 479 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:535
#define DHCPV6_REPLY
DHCPv6 reply.
Definition: dhcpv6.h:259
Record received IPv6 address.
Definition: dhcpv6.c:539
#define DHCPV6_REQUEST
DHCPv6 request.
Definition: dhcpv6.h:256
Include identity association within request.
Definition: dhcpv6.c:533
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

DHCPv6 request state.

Definition at line 543 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:537
#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:539
#define DHCPV6_ADVERTISE
DHCPv6 advertisement.
Definition: dhcpv6.h:253
Include identity association within request.
Definition: dhcpv6.c:533
static struct dhcpv6_session_state dhcpv6_request
DHCPv6 request state.
Definition: dhcpv6.c:543

DHCPv6 solicitation state.

Definition at line 552 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:321

DHCPv6 information request state.

Definition at line 561 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:569
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
Definition: dhcpv6.c:625
#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 973 of file dhcpv6.c.

◆ dhcpv6_job_desc

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

DHCPv6 job control interface descriptor.

Definition at line 978 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:569
#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:194
static int dhcpv6_rx(struct dhcpv6_session *dhcpv6, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new data.
Definition: dhcpv6.c:841

DHCPv6 data transfer interface operations.

Definition at line 982 of file dhcpv6.c.

◆ dhcpv6_xfer_desc

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

DHCPv6 data transfer interface descriptor.

Definition at line 987 of file dhcpv6.c.

Referenced by start_dhcpv6().