53 #define EPROTO_UNSPECFAIL __einfo_error ( EINFO_EPROTO_UNSPECFAIL ) 54 #define EINFO_EPROTO_UNSPECFAIL \ 55 __einfo_uniqify ( EINFO_EPROTO, 1, "Unspecified server failure" ) 56 #define EPROTO_NOADDRSAVAIL __einfo_error ( EINFO_EPROTO_NOADDRSAVAIL ) 57 #define EINFO_EPROTO_NOADDRSAVAIL \ 58 __einfo_uniqify ( EINFO_EPROTO, 2, "No addresses available" ) 59 #define EPROTO_NOBINDING __einfo_error ( EINFO_EPROTO_NOBINDING ) 60 #define EINFO_EPROTO_NOBINDING \ 61 __einfo_uniqify ( EINFO_EPROTO, 3, "Client record unavailable" ) 62 #define EPROTO_NOTONLINK __einfo_error ( EINFO_EPROTO_NOTONLINK ) 63 #define EINFO_EPROTO_NOTONLINK \ 64 __einfo_uniqify ( EINFO_EPROTO, 4, "Prefix not on link" ) 65 #define EPROTO_USEMULTICAST __einfo_error ( EINFO_EPROTO_USEMULTICAST ) 66 #define EINFO_EPROTO_USEMULTICAST \ 67 __einfo_uniqify ( EINFO_EPROTO, 5, "Use multicast address" ) 68 #define EPROTO_STATUS( status ) \ 69 EUNIQ ( EINFO_EPROTO, ( (status) & 0x0f ), EPROTO_UNSPECFAIL, \ 70 EPROTO_NOADDRSAVAIL, EPROTO_NOBINDING, \ 71 EPROTO_NOTONLINK, EPROTO_USEMULTICAST ) 102 size_t remaining =
options->len;
106 while ( remaining >=
sizeof (
option->header ) ) {
109 remaining -=
sizeof (
option->header );
138 unsigned int code,
const void *expected,
177 status_code = &
option->status_code;
181 ( sizeof ( *status_code ) -
sizeof ( status_code->
header ) ) ) {
215 if (
len < (
sizeof ( *ia_na ) -
sizeof ( ia_na->
header ) ) )
239 if (
len < (
sizeof ( *iaaddr ) -
sizeof ( iaaddr->
header ) ) )
305 len =
sizeof ( *lease );
308 return sizeof ( *lease );
331 return sizeof ( *len6 );
347 if (
len >
sizeof ( *router ) )
348 len =
sizeof ( *router );
351 return sizeof ( *router );
404 return op->fetch ( dhcpv6set,
data,
len );
414 if (
len > option_len )
453 data = ( ( (
void * ) dhcpv6set ) +
sizeof ( *dhcpv6set ) );
504 static char buf[ 12 ];
644 DBGC ( dhcpv6,
"DHCPv6 %s entering %s state\n", dhcpv6->
netdev->
name,
665 static const char default_user_class[4] = {
'i',
'P',
'X',
'E' };
670 if ( actual_len >= 0 )
674 if (
len >
sizeof ( default_user_class ) )
675 len =
sizeof ( default_user_class );
677 return sizeof ( default_user_class );
696 size_t client_id_len;
697 size_t server_id_len;
699 size_t user_class_string_len;
700 size_t user_class_len;
706 client_id_len = (
sizeof ( *client_id ) +
708 server_id_len = ( dhcpv6->
server_duid ? (
sizeof ( *server_id ) +
711 ia_na_len =
sizeof ( *ia_na );
713 ia_na_len +=
sizeof ( *iaaddr );
718 user_class_len = (
sizeof ( *user_class ) +
720 user_class_string_len );
721 elapsed_len =
sizeof ( *elapsed );
722 total_len = (
sizeof ( *dhcphdr ) + client_id_len + server_id_len +
724 user_class_len + elapsed_len );
737 client_id =
iob_put ( iobuf, client_id_len );
740 sizeof ( client_id->
header ) );
745 if ( server_id_len ) {
746 server_id =
iob_put ( iobuf, server_id_len );
749 sizeof ( server_id->
header ) );
756 ia_na =
iob_put ( iobuf, ia_na_len );
759 sizeof ( ia_na->
header ) );
764 iaaddr = ( (
void * ) ia_na->
options );
767 sizeof ( iaaddr->
header ));
781 user_class =
iob_put ( iobuf, user_class_len );
784 sizeof ( user_class->
header ) );
787 user_class_string_len );
790 elapsed =
iob_put ( iobuf, elapsed_len );
793 sizeof ( elapsed->
header ) );
802 DBGC ( dhcpv6,
"DHCPv6 %s could not transmit: %s\n",
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,
861 DBGC ( dhcpv6,
"DHCPv6 %s received %s from %s\n",
874 DBGC ( dhcpv6,
"DHCPv6 %s received %s without correct client " 885 DBGC ( dhcpv6,
"DHCPv6 %s received %s without correct server " 893 DBGC ( dhcpv6,
"DHCPv6 %s received %s while expecting %s\n",
902 DBGC ( dhcpv6,
"DHCPv6 %s received %s with error status: %s\n",
913 &dhcpv6->
lease ) ) != 0 ) {
914 DBGC ( dhcpv6,
"DHCPv6 %s received %s with unusable " 922 DBGC ( dhcpv6,
"DHCPv6 %s received %s is for %s\n",
932 DBGC ( dhcpv6,
"DHCPv6 %s received %s missing server " 958 DBGC ( dhcpv6,
"DHCPv6 %s could not register settings: %s\n",
1000 struct in6_addr *router,
int stateful ) {
1018 dhcpv6 =
zalloc (
sizeof ( *dhcpv6 ) );
1032 memset ( &addresses, 0,
sizeof ( addresses ) );
1033 addresses.client.sin6.sin6_family =
AF_INET6;
1035 addresses.server.sin6.sin6_family =
AF_INET6;
1045 DBGC ( dhcpv6,
"DHCPv6 %s could not create DUID-UUID: %s\n",
1047 goto err_client_duid;
1052 DBGC ( dhcpv6,
"DHCPv6 %s has XID %02x%02x%02x\n", dhcpv6->
netdev->
name,
1053 dhcpv6->
xid[0], dhcpv6->
xid[1], dhcpv6->
xid[2] );
1061 &addresses.server.sa,
1062 &addresses.client.sa ) ) != 0 ) {
1063 DBGC ( dhcpv6,
"DHCPv6 %s could not open socket: %s\n",
1065 goto err_open_socket;
1083 .description =
"Boot filename",
1085 .type = &setting_type_string,
1092 .description =
"DNS search list",
1094 .type = &setting_type_dnssl,
uint8_t rx_type
Current expected received packet type.
static struct dhcpv6_session_state dhcpv6_solicit
DHCPv6 solicitation state.
struct dhcpv6_session_state * next
Next state (or NULL to terminate)
#define DHCPV6_SERVER_ID
DHCPv6 server identifier option.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static int dhcpv6_tx(struct dhcpv6_session *dhcpv6)
Transmit current request.
#define EINVAL
Invalid argument.
An object interface operation.
#define SETTING_IP_EXTRA
IPv4 additional settings.
#define DHCPV6_BOOTFILE_PARAM
DHCPv6 bootfile parameters option.
Record received server ID.
struct arbelprm_rc_send_wqe rc
void intf_close(struct interface *intf, int rc)
Close an object interface.
char string[0]
User class string.
#define DHCPV6_SOLICIT
DHCPv6 solicitation.
#define iob_put(iobuf, len)
#define TICKS_PER_SEC
Number of ticks per second.
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
#define DHCPV6_ELAPSED_TIME
DHCPv6 elapsed time option.
#define AF_INET6
IPv6 Internet addresses.
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
static int dhcpv6_fetch_ip6(struct dhcpv6_settings *dhcpv6set, void *data, size_t len)
Fetch value of DHCPv6 leased address.
DHCP unique identifier based on UUID (DUID-UUID)
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
uint8_t ll_addr_len
Link-layer address length.
static struct interface_descriptor dhcpv6_xfer_desc
DHCPv6 data transfer interface descriptor.
struct interface xfer
Data transfer interface.
const struct settings_scope dhcpv6_scope
IPv6 settings scope.
struct interface job
Job control interface.
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
static void dhcpv6_set_state(struct dhcpv6_session *dhcpv6, struct dhcpv6_session_state *state)
Transition to new DHCPv6 session state.
static struct interface_operation dhcpv6_job_op[]
DHCPv6 job control interface operations.
uint32_t next
Next descriptor address.
Include leased IPv6 address within request.
static uint8_t dhcpv6_request_options_data[]
Raw option data for options common to all DHCPv6 requests.
#define DHCPV6_IA_NA
DHCPv6 identity association for non-temporary address (IA_NA) option.
#define ref_init(refcnt, free)
Initialise a reference counter.
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
struct settings * parent
Parent settings block.
struct dhcpv6_option header
Option header.
uint8_t duid[0]
DHCP unique identifier (DUID)
#define IPV6_MAX_PREFIX_LEN
IPv6 maximum prefix length.
#define DHCPV6_USER_CLASS
DHCPv6 user class option.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
size_t len
Length of data buffer.
uint64_t address
Base address.
struct dhcpv6_option options[0]
IA_NA options.
uint32_t type
Operating system type.
uint16_t status
Status code.
static int dhcpv6_status_code(struct dhcpv6_option_list *options)
Get DHCPv6 status code.
#define EPROTO_STATUS(status)
#define __einfo_errortab(einfo)
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.
uint32_t iaid
Identity association identifier (IAID)
#define DHCPV6_VENDOR_CLASS_PXE
DHCPv6 PXE vendor class.
#define DHCPV6_SETTINGS_NAME
DHCPv6 settings block name.
static int dhcpv6_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of DHCPv6 setting.
uint32_t iaid
Identity association ID.
#define ENOENT
No such file or directory.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
int(* fetch)(struct dhcpv6_settings *dhcpv6set, void *data, size_t len)
Fetch value of setting.
struct net_device * netdev
Network device being configured.
#define DHCPV6_INFORMATION_REQUEST
DHCPv6 information request.
static const char * dhcpv6_type_name(unsigned int type)
Name a DHCPv6 packet type.
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
uint8_t options[0]
DHCP options.
uint32_t xid
Transaction ID.
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
uint8_t tx_type
Current transmitted packet type.
static struct settings_operations dhcpv6_settings_operations
DHCPv6 settings operations.
#define offsetof(type, field)
Get offset of a field within a structure.
Address assigned via DHCPv6.
#define DHCPV6_VENDOR_CLASS
DHCPv6 vendor class option.
static void dhcpv6_finished(struct dhcpv6_session *dhcpv6, int rc)
Terminate DHCPv6 session.
DHCPv6 user class option.
#define DHCPV6_REPLY
DHCPv6 reply.
static unsigned int code
Response code.
struct in6_addr lease
Leased IPv6 address.
unsigned int scope_id
Scope ID.
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
static void settings_init(struct settings *settings, struct settings_operations *op, struct refcnt *refcnt, const struct settings_scope *default_scope)
Initialise a settings block.
Record received IPv6 address.
#define DHCPV6_DWORD_VALUE(value)
Construct a DHCPv6 dword value.
Data transfer interfaces.
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
struct dhcpv6_option header
Option header.
struct dhcpv6_session_state * state
Current session state.
uint64_t tag
Setting tag, if applicable.
#define ENOMEM
Not enough space.
struct in6_addr lease
Leased address.
int start_dhcpv6(struct interface *job, struct net_device *netdev, struct in6_addr *router, int stateful)
Start DHCPv6.
#define DHCPV6_CLIENT_ID
DHCPv6 client identifier option.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
const struct setting filename6_setting __setting(SETTING_BOOT, filename)
Boot filename setting.
DHCP client architecture definitions.
uint32_t valid
Valid lifetime (in seconds)
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
#define container_of(ptr, type, field)
Get containing structure.
A long option, as used for getopt_long()
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.
struct dhcpv6_option options[0]
IAADDR options.
struct settings settings
Settings block.
struct dhcpv6_option header
Option header.
#define __unused
Declare a variable or data structure as unused.
#define DHCPV6_ADVERTISE
DHCPv6 advertisement.
struct dhcpv6_option_list options
Option list.
static struct net_device * netdev
struct in6_addr router
Router address.
void * server_duid
Server DUID, if known.
struct refcnt refcnt
Reference counter.
#define DHCP_ARCH_CLIENT_ARCHITECTURE
DHCP client architecture.
dhcpv6_session_state_flags
DHCPv6 session state flags.
#define IN6_IS_ADDR_UNSPECIFIED(addr)
static struct interface_operation dhcpv6_xfer_op[]
DHCPv6 data transfer interface operations.
static void dhcpv6_free(struct refcnt *refcnt)
Free DHCPv6 session.
static void dhcpv6_timer_expired(struct retry_timer *timer, int fail)
Handle timer expiry.
#define DHCPV6_CODE(code)
Construct a DHCPv6 option code.
Generalized socket address structure.
An object interface descriptor.
static struct dhcpv6_session_state dhcpv6_information_request
DHCPv6 information request state.
char * strerror(int errno)
Retrieve string representation of error number.
static void(* free)(struct refcnt *refcnt))
void * zalloc(size_t size)
Allocate cleared memory.
uint32_t rebind
Rebind time (in seconds)
static int dhcpv6_fetch_len6(struct dhcpv6_settings *dhcpv6set __unused, void *data, size_t len)
Fetch value of DHCPv6 implicit address prefix length.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
#define EINFO_EPROTO_NOADDRSAVAIL
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Settings block operations.
#define DHCPV6_DNS_SERVERS
DHCPv6 DNS recursive name server option.
struct in6_addr address
IPv6 address.
#define SETTING_BOOT
Generic boot settings.
Data transfer interface opening.
DHCPv6 client or server identifier option.
DHCPv6 identity association address (IAADDR) option.
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
#define DHCPV6_OPTION_REQUEST
DHCPv6 option request option.
#define DHCPV6_REQUEST
DHCPv6 request.
struct retry_timer timer
Retransmission timer.
#define DHCPV6_DOMAIN_LIST
DHCPv6 domain search list option.
void * malloc(size_t size)
Allocate memory.
static struct dhcpv6_address_operation dhcpv6_address_operations[]
DHCPv6 address settings operations.
int rc
Current timeout status code.
DHCPv6 status code option.
static int dhcpv6_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of DHCPv6 setting.
void start_timer(struct retry_timer *timer)
Start timer.
static int dhcpv6_rx(struct dhcpv6_session *dhcpv6, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new data.
Network device management.
uint32_t renew
Renew time (in seconds)
static uint16_t struct vmbus_xfer_pages_operations * op
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
int order
Sibling ordering.
struct refcnt refcnt
Reference count.
void stop_timer(struct retry_timer *timer)
Stop timer.
char name[NETDEV_NAME_LEN]
Name of this network device.
size_t server_duid_len
Server DUID length.
uint16_t len
Length of the data field.
#define ENOTTY
Inappropriate I/O control operation.
unsigned long start
Start time (in ticks)
#define DHCP_ARCH_CLIENT_NDI
DHCP client network device interface.
A DHCPv6 address setting operation.
struct dhcpv6_option header
Option header.
void * data
Start of data.
const struct setting * setting
Generic setting.
struct dhcpv6_duid_uuid client_duid
Client DUID.
static void ipv6_all_dhcp_relay_and_servers(struct in6_addr *addr)
Construct all-DHCP-relay-agents-and-servers multicast address.
uint8_t xid[3]
Transaction ID.
#define DHCPV6_WORD(value)
Construct a word-valued DHCPv6 option.
uint8_t data[48]
Additional event data.
static const union dhcpv6_any_option * dhcpv6_option(struct dhcpv6_option_list *options, unsigned int code)
Find DHCPv6 option.
#define DHCPV6_CLIENT_PORT
DHCPv6 client port.
static struct interface_descriptor dhcpv6_job_desc
DHCPv6 job control interface descriptor.
static int dhcpv6_fetch_gateway6(struct dhcpv6_settings *dhcpv6set, void *data, size_t len)
Fetch value of DHCPv6 router address.
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
#define DHCPV6_STRING(...)
Construct a DHCPv6 option from a list of characters.
int(* applies)(struct settings *settings, const struct setting *setting)
Check applicability of setting.
#define DHCPV6_DUID_UUID
DHCP unique identifier based on UUID (DUID-UUID)
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
#define DHCPV6_SERVER_PORT
DHCPv6 server port.
typeof(acpi_finder=acpi_find)
ACPI table finder.
const struct settings_scope ipv6_settings_scope
IPv6 settings scope.
#define DHCP_VENDOR_PXECLIENT(arch, ndi)
Vendor class identifier for PXE clients.
#define DHCPV6_IAADDR
DHCPv6 identity association address (IAADDR) option.
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
uint16_t elapsed
Elapsed time, in centiseconds.
unsigned long currticks(void)
Get current system time in ticks.
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
const struct settings_scope * scope
Setting scope (or NULL)
static size_t dhcpv6_user_class(void *data, size_t len)
Get DHCPv6 user class.
#define DHCPV6_STATUS_CODE
DHCPv6 status code option.
uint32_t preferred
Preferred lifetime (in seconds)
struct in6_addr router
Router address.
Include identity association within request.
struct dhcpv6_option header
Option header.
int setting_cmp(const struct setting *a, const struct setting *b)
Compare two settings.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
#define DHCPV6_CLIENT_ARCHITECTURE
DHCPv6 client system architecture option.
DHCPv6 identity association for non-temporary address (IA_NA) option.
static struct dhcpv6_session_state dhcpv6_request
DHCPv6 request state.
#define NULL
NULL pointer (VOID *)
#define ETIMEDOUT
Connection timed out.
const void * data
Data buffer.
struct bofm_section_header done
static int dhcpv6_iaaddr(struct dhcpv6_option_list *options, uint32_t iaid, struct in6_addr *address)
Get DHCPv6 identity association address.
struct ll_protocol * ll_protocol
Link-layer protocol.
struct dhcpv6_user_class user_class[0]
User class.
#define DHCPV6_BOOTFILE_URL
DHCPv6 bootfile URI option.
#define ref_put(refcnt)
Drop reference to object.
Dynamic Host Configuration Protocol for IPv6.
struct errortab dhcpv6_errors [] __errortab
Human-readable error messages.
#define DHCPV6_CLIENT_NDI
DHCPv6 client network interface identifier option.
void * memset(void *dest, int character, size_t len) __nonnull
struct dhcpv6_option header
Option header.
#define DHCPV6_OPTION(...)
Construct a DHCPv6 option from a list of bytes.
DHCPv6 elapsed time option.