44 #define IPV6CONF_MIN_TIMEOUT ( TICKS_PER_SEC / 8 ) 47 #define IPV6CONF_MAX_TIMEOUT ( TICKS_PER_SEC * 3 ) 50 #define IPV6CONF_BLOCK_TIMEOUT ( TICKS_PER_SEC ) 53 #define IPV6CONF_MAX_DEFERRALS 180 77 unsigned int option_type ) {
90 option_len = ( (
sizeof ( *ll_addr_opt ) +
98 ll_addr_opt =
iob_put ( iobuf, option_len );
107 if ( (
rc =
tcpip_tx ( iobuf, &icmpv6_protocol, st_src, st_dest,
109 DBGC (
netdev,
"NDP %s could not transmit packet: %s\n",
128 const void *net_dest,
const void *net_source ) {
135 memset ( &sin6_src, 0,
sizeof ( sin6_src ) );
141 memset ( &sin6_dest, 0,
sizeof ( sin6_dest ) );
147 memset ( &neigh, 0,
sizeof ( neigh ) );
178 memset ( &sin6_dest, 0,
sizeof ( sin6_dest ) );
184 memset ( &rsol, 0,
sizeof ( rsol ) );
225 DBGC (
netdev,
"NDP %s neighbour solicitation link-layer " 226 "address option too short at %zd bytes\n",
234 ll_addr_opt->
ll_addr ) ) != 0 ) {
235 DBGC (
netdev,
"NDP %s could not define %s => %s: %s\n",
281 DBGC (
netdev,
"NDP %s neighbour advertisement link-layer " 282 "address option too short at %zd bytes\n",
289 ll_addr_opt->
ll_addr ) ) != 0 ) {
290 DBGC (
netdev,
"NDP %s could not update %s => %s: %s\n",
322 DBGC (
netdev,
"NDP %s router advertisement link-layer address " 330 ll_addr_opt->
ll_addr ) ) != 0 ) {
331 DBGC (
netdev,
"NDP %s could not define %s => %s: %s\n",
360 if (
sizeof ( *prefix_opt ) >
len ) {
361 DBGC (
netdev,
"NDP %s router advertisement prefix option too " 366 DBGC (
netdev,
"NDP %s found %sdefault router %s ",
369 DBGC (
netdev,
"for %s-link %sautonomous prefix %s/%d\n",
443 return handler->
rx (
netdev, sin6_src, ndp,
472 DBGC (
netdev,
"NDP %s packet too short at %zd bytes (min %zd " 480 while ( remaining ) {
483 if ( ( remaining <
sizeof (
option->header ) ) ||
484 (
option->header.blocks == 0 ) ||
485 ( remaining < (
option->header.blocks *
496 option_len ) ) != 0 )
501 remaining -= option_len;
632 #define NDP_TAG( type, offset, len ) \ 633 ( ( (len) << 16 ) | ( (offset) << 8 ) | (type) ) 641 #define NDP_TAG_TYPE( tag ) ( ( (tag) >> 0 ) & 0xff ) 649 #define NDP_TAG_OFFSET( tag ) ( ( (tag) >> 8 ) & 0xff ) 657 #define NDP_TAG_LEN( tag ) ( ( (tag) >> 16 ) & 0xff ) 665 #define NDP_TAG_INSTANCE( tag ) ( ( (tag) >> 24 ) & 0xff ) 698 unsigned int tag_type;
699 unsigned int tag_offset;
700 unsigned int tag_len;
701 unsigned int tag_instance;
723 if (
option->header.type != tag_type )
727 if ( tag_instance-- != 0 )
731 if ( ( tag_offset + tag_len ) > option_len ) {
732 DBGC (
netdev,
"NDP %s option %d too short\n",
737 tag_len = ( option_len - tag_offset );
738 option_data = ( ( (
void * )
option ) + tag_offset );
803 memcpy ( &slaac, ip6,
sizeof ( slaac ) );
805 if ( prefix_len ==
prefix->prefix_len ) {
808 }
else if ( prefix_len < 0 ) {
811 DBGC (
netdev,
"NDP %s does not support SLAAC: %s\n",
817 DBGC (
netdev,
"NDP %s ignoring misconfigured SLAAC " 824 if (
len >
sizeof ( *ip6 ) )
825 len =
sizeof ( *ip6 );
828 return sizeof ( *ip6 );
847 if (
len >=
sizeof ( *len6 ) ) {
853 prefix->prefix_len : -1UL );
856 return sizeof ( *len6 );
881 return sizeof ( ndpset->
router );
958 unsigned int prefixes;
959 unsigned int instance;
985 ndpset =
zalloc (
sizeof ( *ndpset ) +
len +
986 ( prefixes *
sizeof ( *prefset ) ) );
999 prefset = ( ( (
void * ) ndpset->
options ) +
len );
1029 prefset->
name ) ) != 0 )
1030 goto err_register_prefix;
1035 assert ( instance == prefixes );
1040 err_register_prefix:
1051 .description =
"DNS server",
1054 .type = &setting_type_ipv6,
1061 .description =
"DNS search list",
1064 .type = &setting_type_dnssl,
1172 DBGC (
netdev,
"NDP %s deferring discovery timeout\n",
1218 radv->
option, option_len ) ) != 0 )
1225 stateful ) ) != 0 ) {
1226 DBGC (
netdev,
"NDP %s could not start state%s DHCPv6: " 1228 ( stateful ?
"ful" :
"less" ),
strerror (
rc ) );
#define NDP_OPT_RDNSS
NDP recursive DNS server option.
#define EINVAL
Invalid argument.
static int ipv6conf_rx_router_advertisement(struct net_device *netdev, struct in6_addr *router, struct ndp_router_advertisement_header *radv, size_t len)
Handle router advertisement during IPv6 autoconfiguration.
An object interface operation.
#define SETTING_IP_EXTRA
IPv4 additional settings.
static int ndp_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of NDP setting.
#define NDP_OPT_PREFIX
NDP prefix information option.
struct arbelprm_rc_send_wqe rc
void intf_close(struct interface *intf, int rc)
Close an object interface.
static int ndp_prefix_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of NDP per-prefix setting.
static int ndp_tx_router_solicitation(struct net_device *netdev)
Transmit NDP router solicitation.
#define iob_put(iobuf, len)
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
#define NDP_SETTINGS_NAME
NDP settings block name.
#define AF_INET6
IPv6 Internet addresses.
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
uint8_t ll_addr_len
Link-layer address length.
#define ICMPV6_NEIGHBOUR_SOLICITATION
ICMPv6 neighbour solicitation.
static int ndp_prefix_fetch_gateway6(struct settings *settings, void *data, size_t len)
Fetch value of NDP router address setting.
unsigned int lifetime
Router lifetime.
static int ndp_rx_neighbour_solicitation_ll_source(struct net_device *netdev, struct sockaddr_in6 *sin6_src, union ndp_header *ndp, union ndp_option *option, size_t len)
Process NDP neighbour solicitation source link-layer address option.
#define NDP_TAG_INSTANCE(tag)
Extract NDP tag instance.
static void ipv6conf_expired(struct retry_timer *timer, int fail)
Handle IPv6 configurator timer expiry.
void unregister_settings(struct settings *settings)
Unregister settings block.
static int ndp_prefix_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of NDP pre-prefix setting.
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
#define list_add(new, head)
Add a new entry to the head of a list.
int(* fetch)(struct settings *settings, void *data, size_t len)
Fetch value of setting.
uint8_t ll_addr[0]
Link-layer address.
#define ref_init(refcnt, free)
Initialise a reference counter.
struct settings * parent
Parent settings block.
An NDP per-prefix setting operation.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
static struct settings_operations ndp_settings_operations
NDP settings operations.
struct refcnt refcnt
Reference count.
NDP recursive DNS server.
static void ipv6_solicited_node(struct in6_addr *addr, const struct in6_addr *unicast)
Construct solicited-node multicast address.
struct interface dhcp
DHCPv6 interface.
#define NDP_TAG(type, offset, len)
Construct NDP tag.
static struct interface_operation ipv6conf_job_op[]
IPv6 configurator job interface operations.
static const struct settings_scope ndp_settings_scope
NDP settings scope.
static int ndp_rx_option(struct net_device *netdev, struct sockaddr_in6 *sin6_src, union ndp_header *ndp, union ndp_option *option, size_t len)
Process received NDP option.
int(* rx)(struct net_device *netdev, struct sockaddr_in6 *sin6_src, union ndp_header *ndp, union ndp_option *option, size_t len)
Handle received option.
static int ndp_tx_request(struct net_device *netdev, struct net_protocol *net_protocol __unused, const void *net_dest, const void *net_source)
Transmit NDP neighbour discovery request.
A neighbour discovery protocol.
#define ENOENT
No such file or directory.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
uint16_t sin6_scope_id
Scope ID (part of struct sockaddr_tcpip)
#define NDP_OPT_LL_TARGET
NDP target link-layer address option.
#define offsetof(type, field)
Get offset of a field within a structure.
static int ndp_rx_neighbour_advertisement_ll_target(struct net_device *netdev, struct sockaddr_in6 *sin6_src __unused, union ndp_header *ndp, union ndp_option *option, size_t len)
Process NDP neighbour advertisement target link-layer address option.
static void ipv6conf_free(struct refcnt *refcnt)
Free IPv6 configurator.
struct neighbour_discovery ndp_discovery
NDP neighbour discovery protocol.
static int netdev_link_blocked(struct net_device *netdev)
Check link block state of network device.
#define NDP_ROUTER_MANAGED
NDP managed address configuration.
uint8_t icmp_type
ICMPv6 type.
int neighbour_update(struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *ll_dest)
Update existing neighbour cache entry.
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
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.
A doubly-linked list entry (or list head)
NDP source or target link-layer address option.
static int ndp_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of NDP setting.
#define NDP_NEIGHBOUR_SOLICITED
NDP solicited flag.
static int ndp_rx_router_advertisement(struct io_buffer *iobuf, struct net_device *netdev, struct sockaddr_in6 *sin6_src, struct sockaddr_in6 *sin6_dest __unused)
Process received NDP router advertisement.
#define NDP_TAG_LEN(tag)
Extract NDP tag length.
uint64_t tag
Setting tag, if applicable.
#define list_del(list)
Delete an entry from a list.
struct ndp_option_header header
NDP option header.
static struct settings_operations ndp_prefix_settings_operations
NDP per-prefix settings operations.
#define ENOMEM
Not enough space.
int start_dhcpv6(struct interface *job, struct net_device *netdev, struct in6_addr *router, int stateful)
Start DHCPv6.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct net_device_configurator ipv6_configurator __net_device_configurator
IPv6 network device configurator.
FILE_LICENCE(GPL2_OR_LATER)
static void ipv6_all_routers(struct in6_addr *addr)
Construct all-routers multicast address.
#define MAX_LL_NET_HEADER_LEN
Maximum combined length of a link-layer and network-layer header.
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.
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
A long option, as used for getopt_long()
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
size_t len
Length of NDP options.
#define __unused
Declare a variable or data structure as unused.
int neighbour_define(struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *ll_dest)
Define neighbour cache entry.
static struct net_device * netdev
Transport-network layer interface.
Address assigned via SLAAC.
const struct setting_type * type
Setting type.
struct list_head list
List of configurators.
#define IPV6CONF_MAX_TIMEOUT
Router discovery maximum timeout.
#define NDP_OPT_LL_SOURCE
NDP source link-layer address option.
struct refcnt refcnt
Reference counter.
struct net_device * netdev
Network device being configured.
An object interface descriptor.
char * strerror(int errno)
Retrieve string representation of error number.
static void(* free)(struct refcnt *refcnt))
struct interface job
Job control interface.
#define NDP_TAG_TYPE(tag)
Extract NDP tag type.
void * zalloc(size_t size)
Allocate cleared memory.
#define NDP_OPT_DNSSL
NDP DNS search list option.
#define NDP_PREFIX_ON_LINK
NDP on-link flag.
static int ndp_rx_options(struct net_device *netdev, struct sockaddr_in6 *sin6_src, union ndp_header *ndp, size_t offset, size_t len)
Process received NDP packet options.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
static struct interface_operation ipv6conf_dhcp_op[]
IPv6 configurator DHCPv6 interface operations.
const struct setting * setting
Generic setting.
#define NDP_NEIGHBOUR_OVERRIDE
NDP override flag.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
static int ndp_prefix_fetch_len6(struct settings *settings, void *data, size_t len)
Fetch value of NDP prefix length setting.
struct ndp_prefix_information_option * prefix
Prefix information option.
Settings block operations.
static struct ipv6conf * ipv6conf_demux(struct net_device *netdev)
Identify IPv6 configurator by network device.
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
struct retry_timer timer
Retransmission timer.
uint8_t option_type
Option type.
u32 lifetime
For Lifetime-type KDEs, the lifetime in seconds.
#define ICMPV6_ROUTER_SOLICITATION
ICMPv6 router solicitation.
An NDP prefix settings block.
#define ICMPV6_ROUTER_ADVERTISEMENT
ICMPv6 router advertisement.
static int ndp_rx_neighbour(struct io_buffer *iobuf, struct net_device *netdev, struct sockaddr_in6 *sin6_src, struct sockaddr_in6 *sin6_dest __unused)
Process received NDP neighbour solicitation or advertisement.
#define IPV6CONF_BLOCK_TIMEOUT
Router discovery blocked link retry timeout.
void start_timer(struct retry_timer *timer)
Start timer.
A network-layer protocol.
static struct ndp_option_handler ndp_option_handlers[]
NDP option handlers.
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
struct icmpv6_handler ndp_handlers [] __icmpv6_handler
NDP ICMPv6 handlers.
#define IPV6CONF_MIN_TIMEOUT
Router discovery minimum timeout.
struct in6_addr router
Router address.
static int ndp_rx_router_advertisement_ll_source(struct net_device *netdev, struct sockaddr_in6 *sin6_src, union ndp_header *ndp __unused, union ndp_option *option, size_t len)
Process NDP router advertisement source link-layer address option.
#define iob_reserve(iobuf, len)
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.
void stop_timer(struct retry_timer *timer)
Stop timer.
union ndp_option options[0]
NDP options.
char name[NETDEV_NAME_LEN]
Name of this network device.
static struct ndp_prefix_operation ndp_prefix_operations[]
NDP per-prefix settings operations.
#define ICMPV6_NEIGHBOUR_ADVERTISEMENT
ICMPv6 neighbour advertisement.
struct settings settings
Settings interface.
#define NDP_TAG_OFFSET(tag)
Extract NDP tag offset.
static struct interface_descriptor ipv6conf_job_desc
IPv6 configurator job interface descriptor.
static int ndp_register_settings(struct net_device *netdev, struct in6_addr *router, unsigned int lifetime, union ndp_option *options, size_t len)
Register NDP settings.
#define SETTING_IP6_EXTRA
IPv6 additional settings.
static int ndp_prefix_fetch_ip6(struct settings *settings, void *data, size_t len)
Fetch value of NDP IPv6 address setting.
#define NDP_PREFIX_AUTONOMOUS
NDP autonomous address configuration flag.
void * data
Start of data.
A network device configurator.
int start_ipv6conf(struct interface *job, struct net_device *netdev)
Start IPv6 autoconfiguration.
uint8_t data[48]
Additional event data.
int ipv6_has_addr(struct net_device *netdev, struct in6_addr *addr)
Check if network device has a specific IPv6 address.
static int ipv6_eui64(struct in6_addr *addr, struct net_device *netdev)
Construct local IPv6 address via EUI-64.
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Neighbour discovery protocol.
static LIST_HEAD(ipv6confs)
List of IPv6 configurators.
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
unsigned int deferred
Deferred discovery counter.
int(* applies)(struct settings *settings, const struct setting *setting)
Check applicability of setting.
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
uint16_t offset
Offset to command line.
sa_family_t sin6_family
Socket address family (part of struct sockaddr)
static int ndp_rx_router_advertisement_prefix(struct net_device *netdev, struct sockaddr_in6 *sin6_src, union ndp_header *ndp, union ndp_option *option, size_t len)
Process NDP router advertisement prefix information option.
#define IPV6CONF_MAX_DEFERRALS
Router discovery maximum number of deferrals.
static int ndp_tx_ll_addr(struct net_device *netdev, struct sockaddr_in6 *sin6_src, struct sockaddr_in6 *sin6_dest, const void *data, size_t len, unsigned int option_type)
Transmit NDP packet with link-layer address option.
static struct interface_descriptor ipv6conf_dhcp_desc
IPv6 configurator DHCPv6 interface descriptor.
typeof(acpi_finder=acpi_find)
ACPI table finder.
const struct settings_scope ipv6_settings_scope
IPv6 settings scope.
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
const struct setting ndp_dns6_setting __setting(SETTING_IP6_EXTRA, dns6)
DNS server setting.
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)
int tcpip_tx(struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, struct net_device *netdev, uint16_t *trans_csum)
Transmit a TCP/IP packet.
uint16_t tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checkum.
#define NDP_OPTION_BLKSZ
NDP option block size.
int setting_cmp(const struct setting *a, const struct setting *b)
Compare two settings.
#define NULL
NULL pointer (VOID *)
#define ETIMEDOUT
Connection timed out.
struct settings settings
Settings interface.
#define NDP_ROUTER_OTHER
NDP other configuration.
struct in6_addr sin6_addr
IPv6 address.
struct ll_protocol * ll_protocol
Link-layer protocol.
static struct dns_server dns6
IPv6 DNS server list.
#define ref_put(refcnt)
Drop reference to object.
Dynamic Host Configuration Protocol for IPv6.
void * memset(void *dest, int character, size_t len) __nonnull