iPXE
Data Structures | Macros | Functions | Variables
ndp.c File Reference

IPv6 neighbour discovery protocol. More...

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/in.h>
#include <ipxe/iobuf.h>
#include <ipxe/tcpip.h>
#include <ipxe/ipv6.h>
#include <ipxe/icmpv6.h>
#include <ipxe/neighbour.h>
#include <ipxe/dhcpv6.h>
#include <ipxe/timer.h>
#include <ipxe/ndp.h>

Go to the source code of this file.

Data Structures

struct  ndp_option_handler
 An NDP option handler. More...
 
struct  ndp_prefix_settings
 An NDP prefix settings block. More...
 
struct  ndp_settings
 An NDP settings block. More...
 
struct  ndp_prefix_operation
 An NDP per-prefix setting operation. More...
 
struct  ipv6conf
 An IPv6 configurator. More...
 

Macros

#define IPV6CONF_MIN_TIMEOUT   ( TICKS_PER_SEC / 8 )
 Router discovery minimum timeout. More...
 
#define IPV6CONF_MAX_TIMEOUT   ( TICKS_PER_SEC * 3 )
 Router discovery maximum timeout. More...
 
#define IPV6CONF_BLOCK_TIMEOUT   ( TICKS_PER_SEC )
 Router discovery blocked link retry timeout. More...
 
#define IPV6CONF_MAX_DEFERRALS   180
 Router discovery maximum number of deferrals. More...
 
#define NDP_TAG(type, offset, len)   ( ( (len) << 16 ) | ( (offset) << 8 ) | (type) )
 Construct NDP tag. More...
 
#define NDP_TAG_TYPE(tag)   ( ( (tag) >> 0 ) & 0xff )
 Extract NDP tag type. More...
 
#define NDP_TAG_OFFSET(tag)   ( ( (tag) >> 8 ) & 0xff )
 Extract NDP tag offset. More...
 
#define NDP_TAG_LEN(tag)   ( ( (tag) >> 16 ) & 0xff )
 Extract NDP tag length. More...
 
#define NDP_TAG_INSTANCE(tag)   ( ( (tag) >> 24 ) & 0xff )
 Extract NDP tag instance. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
static struct ipv6confipv6conf_demux (struct net_device *netdev)
 Identify IPv6 configurator by network device. More...
 
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. More...
 
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. More...
 
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. More...
 
static int ndp_tx_router_solicitation (struct net_device *netdev)
 Transmit NDP router solicitation. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static int ndp_applies (struct settings *settings __unused, const struct setting *setting)
 Check applicability of NDP setting. More...
 
static int ndp_fetch (struct settings *settings, struct setting *setting, void *data, size_t len)
 Fetch value of NDP setting. More...
 
static int ndp_prefix_applies (struct settings *settings __unused, const struct setting *setting)
 Check applicability of NDP per-prefix setting. More...
 
static int ndp_prefix_fetch_ip6 (struct settings *settings, void *data, size_t len)
 Fetch value of NDP IPv6 address setting. More...
 
static int ndp_prefix_fetch_len6 (struct settings *settings, void *data, size_t len)
 Fetch value of NDP prefix length setting. More...
 
static int ndp_prefix_fetch_gateway6 (struct settings *settings, void *data, size_t len)
 Fetch value of NDP router address setting. More...
 
static int ndp_prefix_fetch (struct settings *settings, struct setting *setting, void *data, size_t len)
 Fetch value of NDP pre-prefix setting. More...
 
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. More...
 
const struct setting ndp_dns6_setting __setting (SETTING_IP6_EXTRA, dns6)
 DNS server setting. More...
 
const struct setting ndp_dnssl_setting __setting (SETTING_IP_EXTRA, dnssl)
 DNS search list setting. More...
 
static LIST_HEAD (ipv6confs)
 List of IPv6 configurators. More...
 
static void ipv6conf_free (struct refcnt *refcnt)
 Free IPv6 configurator. More...
 
static void ipv6conf_done (struct ipv6conf *ipv6conf, int rc)
 Finish IPv6 autoconfiguration. More...
 
static void ipv6conf_expired (struct retry_timer *timer, int fail)
 Handle IPv6 configurator timer expiry. More...
 
int start_ipv6conf (struct interface *job, struct net_device *netdev)
 Start IPv6 autoconfiguration. More...
 

Variables

struct neighbour_discovery ndp_discovery
 NDP neighbour discovery protocol. More...
 
static struct ndp_option_handler ndp_option_handlers []
 NDP option handlers. More...
 
struct icmpv6_handler ndp_handlers [] __icmpv6_handler
 NDP ICMPv6 handlers. More...
 
static const struct settings_scope ndp_settings_scope
 NDP settings scope. More...
 
static struct settings_operations ndp_settings_operations
 NDP settings operations. More...
 
static struct ndp_prefix_operation ndp_prefix_operations []
 NDP per-prefix settings operations. More...
 
static struct settings_operations ndp_prefix_settings_operations
 NDP per-prefix settings operations. More...
 
static struct interface_operation ipv6conf_job_op []
 IPv6 configurator job interface operations. More...
 
static struct interface_descriptor ipv6conf_job_desc
 IPv6 configurator job interface descriptor. More...
 
static struct interface_operation ipv6conf_dhcp_op []
 IPv6 configurator DHCPv6 interface operations. More...
 
static struct interface_descriptor ipv6conf_dhcp_desc
 IPv6 configurator DHCPv6 interface descriptor. More...
 
struct net_device_configurator ipv6_configurator __net_device_configurator
 IPv6 network device configurator. More...
 

Detailed Description

IPv6 neighbour discovery protocol.

Definition in file ndp.c.

Macro Definition Documentation

◆ IPV6CONF_MIN_TIMEOUT

#define IPV6CONF_MIN_TIMEOUT   ( TICKS_PER_SEC / 8 )

Router discovery minimum timeout.

Definition at line 44 of file ndp.c.

◆ IPV6CONF_MAX_TIMEOUT

#define IPV6CONF_MAX_TIMEOUT   ( TICKS_PER_SEC * 3 )

Router discovery maximum timeout.

Definition at line 47 of file ndp.c.

◆ IPV6CONF_BLOCK_TIMEOUT

#define IPV6CONF_BLOCK_TIMEOUT   ( TICKS_PER_SEC )

Router discovery blocked link retry timeout.

Definition at line 50 of file ndp.c.

◆ IPV6CONF_MAX_DEFERRALS

#define IPV6CONF_MAX_DEFERRALS   180

Router discovery maximum number of deferrals.

Definition at line 53 of file ndp.c.

◆ NDP_TAG

#define NDP_TAG (   type,
  offset,
  len 
)    ( ( (len) << 16 ) | ( (offset) << 8 ) | (type) )

Construct NDP tag.

Parameters
typeNDP option type
offsetStarting offset of data
lenLength of data (or 0 to use all remaining data)
Return values
tagNDP tag

Definition at line 632 of file ndp.c.

◆ NDP_TAG_TYPE

#define NDP_TAG_TYPE (   tag)    ( ( (tag) >> 0 ) & 0xff )

Extract NDP tag type.

Parameters
tagNDP tag
Return values
typeNDP option type

Definition at line 641 of file ndp.c.

◆ NDP_TAG_OFFSET

#define NDP_TAG_OFFSET (   tag)    ( ( (tag) >> 8 ) & 0xff )

Extract NDP tag offset.

Parameters
tagNDP tag
Return values
offsetStarting offset of data

Definition at line 649 of file ndp.c.

◆ NDP_TAG_LEN

#define NDP_TAG_LEN (   tag)    ( ( (tag) >> 16 ) & 0xff )

Extract NDP tag length.

Parameters
tagNDP tag
Return values
lenLength of data (or 0 to use all remaining data)

Definition at line 657 of file ndp.c.

◆ NDP_TAG_INSTANCE

#define NDP_TAG_INSTANCE (   tag)    ( ( (tag) >> 24 ) & 0xff )

Extract NDP tag instance.

Parameters
tagNDP tag
Return values
instanceInstance

Definition at line 665 of file ndp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ ipv6conf_demux()

static struct ipv6conf * ipv6conf_demux ( struct net_device netdev)
static

Identify IPv6 configurator by network device.

Parameters
netdevNetwork device
Return values
ipv6IPv6 configurator, or NULL

Definition at line 1118 of file ndp.c.

1118  {
1119  struct ipv6conf *ipv6conf;
1120 
1121  list_for_each_entry ( ipv6conf, &ipv6confs, list ) {
1122  if ( ipv6conf->netdev == netdev )
1123  return ipv6conf;
1124  }
1125  return NULL;
1126 }
An IPv6 configurator.
Definition: ndp.c:1075
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
struct list_head list
List of configurators.
Definition: ndp.c:1079
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1087
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References ipv6conf::list, list_for_each_entry, netdev, ipv6conf::netdev, and NULL.

Referenced by ipv6conf_rx_router_advertisement().

◆ ipv6conf_rx_router_advertisement()

static int ipv6conf_rx_router_advertisement ( struct net_device netdev,
struct in6_addr router,
struct ndp_router_advertisement_header radv,
size_t  len 
)
static

Handle router advertisement during IPv6 autoconfiguration.

Parameters
netdevNetwork device
routerRouter address
radvRouter advertisement
lenLength of router advertisement
Return values
rcReturn status code

This function assumes that the router advertisement is well-formed, since it must have already passed through option processing.

Definition at line 1191 of file ndp.c.

1194  {
1195  struct ipv6conf *ipv6conf;
1196  size_t option_len;
1197  int stateful;
1198  int rc;
1199 
1200  /* Identify IPv6 configurator, if any */
1202 
1203  /* Do nothing unless IPv6 autoconfiguration is in progress */
1204  if ( ! ipv6conf )
1205  return 0;
1206 
1207  /* If this is not the first solicited router advertisement, ignore it */
1208  if ( ! timer_running ( &ipv6conf->timer ) )
1209  return 0;
1210 
1211  /* Stop router solicitation timer */
1212  stop_timer ( &ipv6conf->timer );
1213 
1214  /* Register NDP settings */
1215  option_len = ( len - offsetof ( typeof ( *radv ), option ) );
1216  if ( ( rc = ndp_register_settings ( netdev, router,
1217  ntohl ( radv->lifetime ),
1218  radv->option, option_len ) ) != 0 )
1219  return rc;
1220 
1221  /* Start DHCPv6 if required */
1222  if ( radv->flags & ( NDP_ROUTER_MANAGED | NDP_ROUTER_OTHER ) ) {
1223  stateful = ( radv->flags & NDP_ROUTER_MANAGED );
1224  if ( ( rc = start_dhcpv6 ( &ipv6conf->dhcp, netdev,
1225  stateful ) ) != 0 ) {
1226  DBGC ( netdev, "NDP %s could not start state%s DHCPv6: "
1227  "%s\n", netdev->name,
1228  ( stateful ? "ful" : "less" ), strerror ( rc ) );
1229  ipv6conf_done ( ipv6conf, rc );
1230  return rc;
1231  }
1232  return 0;
1233  }
1234 
1235  /* Otherwise, terminate autoconfiguration */
1236  ipv6conf_done ( ipv6conf, 0 );
1237 
1238  return 0;
1239 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct interface dhcp
DHCPv6 interface.
Definition: ndp.c:1084
#define DBGC(...)
Definition: compiler.h:505
#define ntohl(value)
Definition: byteswap.h:134
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
#define NDP_ROUTER_MANAGED
NDP managed address configuration.
Definition: ndp.h:156
An IPv6 configurator.
Definition: ndp.c:1075
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
Definition: ndp.c:1134
A long option, as used for getopt_long()
Definition: getopt.h:24
static struct net_device * netdev
Definition: gdbudp.c:52
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static struct ipv6conf * ipv6conf_demux(struct net_device *netdev)
Identify IPv6 configurator by network device.
Definition: ndp.c:1118
struct retry_timer timer
Retransmission timer.
Definition: ndp.c:1090
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
uint32_t len
Length.
Definition: ena.h:14
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.
Definition: ndp.c:948
union ndp_option option[0]
Options.
Definition: ndp.h:152
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
uint16_t lifetime
Router lifetime.
Definition: ndp.h:146
int start_dhcpv6(struct interface *job, struct net_device *netdev, int stateful)
Start DHCPv6.
Definition: dhcpv6.c:921
#define NDP_ROUTER_OTHER
NDP other configuration.
Definition: ndp.h:159

References DBGC, ipv6conf::dhcp, ndp_router_advertisement_header::flags, ipv6conf_demux(), ipv6conf_done(), len, ndp_router_advertisement_header::lifetime, net_device::name, ndp_register_settings(), NDP_ROUTER_MANAGED, NDP_ROUTER_OTHER, netdev, ntohl, offsetof, ndp_router_advertisement_header::option, rc, start_dhcpv6(), stop_timer(), strerror(), ipv6conf::timer, and typeof().

Referenced by ndp_rx_router_advertisement().

◆ ndp_tx_ll_addr()

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 
)
static

Transmit NDP packet with link-layer address option.

Parameters
netdevNetwork device
sin6_srcSource socket address
sin6_destDestination socket address
dataNDP header
lenSize of NDP header
option_typeNDP option type
Return values
rcReturn status code

Definition at line 73 of file ndp.c.

77  {
78  struct sockaddr_tcpip *st_src =
79  ( ( struct sockaddr_tcpip * ) sin6_src );
80  struct sockaddr_tcpip *st_dest =
81  ( ( struct sockaddr_tcpip * ) sin6_dest );
83  struct io_buffer *iobuf;
84  struct ndp_ll_addr_option *ll_addr_opt;
85  union ndp_header *ndp;
86  size_t option_len;
87  int rc;
88 
89  /* Allocate and populate buffer */
90  option_len = ( ( sizeof ( *ll_addr_opt ) +
92  ~( NDP_OPTION_BLKSZ - 1 ) );
93  iobuf = alloc_iob ( MAX_LL_NET_HEADER_LEN + len + option_len );
94  if ( ! iobuf )
95  return -ENOMEM;
97  memcpy ( iob_put ( iobuf, len ), data, len );
98  ll_addr_opt = iob_put ( iobuf, option_len );
99  ll_addr_opt->header.type = option_type;
100  ll_addr_opt->header.blocks = ( option_len / NDP_OPTION_BLKSZ );
101  memcpy ( ll_addr_opt->ll_addr, netdev->ll_addr,
103  ndp = iobuf->data;
104  ndp->icmp.chksum = tcpip_chksum ( ndp, ( len + option_len ) );
105 
106  /* Transmit packet */
107  if ( ( rc = tcpip_tx ( iobuf, &icmpv6_protocol, st_src, st_dest,
108  netdev, &ndp->icmp.chksum ) ) != 0 ) {
109  DBGC ( netdev, "NDP %s could not transmit packet: %s\n",
110  netdev->name, strerror ( rc ) );
111  return rc;
112  }
113 
114  return 0;
115 }
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t blocks
Length (in blocks of 8 bytes)
Definition: ndp.h:23
#define iob_put(iobuf, len)
Definition: iobuf.h:120
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
uint8_t type
Type.
Definition: ndp.h:21
uint8_t ll_addr[0]
Link-layer address.
Definition: ndp.h:40
struct icmp_header icmp
ICMPv6 header.
Definition: ndp.h:174
uint16_t chksum
Checksum.
Definition: icmp.h:25
#define DBGC(...)
Definition: compiler.h:505
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
A link-layer protocol.
Definition: netdevice.h:114
NDP source or target link-layer address option.
Definition: ndp.h:36
struct ndp_option_header header
NDP option header.
Definition: ndp.h:38
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define MAX_LL_NET_HEADER_LEN
Maximum combined length of a link-layer and network-layer header.
Definition: netdevice.h:58
static struct net_device * netdev
Definition: gdbudp.c:52
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An NDP header.
Definition: ndp.h:172
#define iob_reserve(iobuf, len)
Definition: iobuf.h:67
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:48
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
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.
Definition: tcpip.c:91
uint16_t tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checkum.
Definition: tcpip.c:203
#define NDP_OPTION_BLKSZ
NDP option block size.
Definition: ndp.h:27
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
A persistent I/O buffer.
Definition: iobuf.h:33

References alloc_iob(), ndp_option_header::blocks, icmp_header::chksum, data, io_buffer::data, DBGC, ENOMEM, ndp_ll_addr_option::header, ndp_header::icmp, iob_put, iob_reserve, len, ndp_ll_addr_option::ll_addr, net_device::ll_addr, ll_protocol::ll_addr_len, net_device::ll_protocol, MAX_LL_NET_HEADER_LEN, memcpy(), net_device::name, NDP_OPTION_BLKSZ, netdev, rc, strerror(), tcpip_chksum(), tcpip_tx(), and ndp_option_header::type.

Referenced by ndp_rx_neighbour_solicitation_ll_source(), ndp_tx_request(), and ndp_tx_router_solicitation().

◆ ndp_tx_request()

static int ndp_tx_request ( struct net_device netdev,
struct net_protocol *net_protocol  __unused,
const void *  net_dest,
const void *  net_source 
)
static

Transmit NDP neighbour discovery request.

Parameters
netdevNetwork device
net_protocolNetwork-layer protocol
net_destDestination network-layer address
net_sourceSource network-layer address
Return values
rcReturn status code

Definition at line 126 of file ndp.c.

128  {
129  struct sockaddr_in6 sin6_src;
130  struct sockaddr_in6 sin6_dest;
131  struct ndp_neighbour_header neigh;
132  int rc;
133 
134  /* Construct source address */
135  memset ( &sin6_src, 0, sizeof ( sin6_src ) );
136  sin6_src.sin6_family = AF_INET6;
137  memcpy ( &sin6_src.sin6_addr, net_source,
138  sizeof ( sin6_src.sin6_addr ) );
139 
140  /* Construct multicast destination address */
141  memset ( &sin6_dest, 0, sizeof ( sin6_dest ) );
142  sin6_dest.sin6_family = AF_INET6;
143  sin6_dest.sin6_scope_id = netdev->scope_id;
144  ipv6_solicited_node ( &sin6_dest.sin6_addr, net_dest );
145 
146  /* Construct neighbour header */
147  memset ( &neigh, 0, sizeof ( neigh ) );
148  neigh.icmp.type = ICMPV6_NEIGHBOUR_SOLICITATION;
149  memcpy ( &neigh.target, net_dest, sizeof ( neigh.target ) );
150 
151  /* Transmit neighbour discovery packet */
152  if ( ( rc = ndp_tx_ll_addr ( netdev, &sin6_src, &sin6_dest, &neigh,
153  sizeof ( neigh ),
154  NDP_OPT_LL_SOURCE ) ) != 0 )
155  return rc;
156 
157  return 0;
158 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
#define ICMPV6_NEIGHBOUR_SOLICITATION
ICMPv6 neighbour solicitation.
Definition: icmpv6.h:68
static void ipv6_solicited_node(struct in6_addr *addr, const struct in6_addr *unicast)
Construct solicited-node multicast address.
Definition: ipv6.h:248
unsigned int scope_id
Scope ID.
Definition: netdevice.h:360
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static struct net_device * netdev
Definition: gdbudp.c:52
#define NDP_OPT_LL_SOURCE
NDP source link-layer address option.
Definition: ndp.h:30
An NDP neighbour solicitation or advertisement header.
Definition: ndp.h:115
IPv6 socket address.
Definition: in.h:115
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.
Definition: ndp.c:73
void * memset(void *dest, int character, size_t len) __nonnull

References AF_INET6, ndp_neighbour_header::icmp, ICMPV6_NEIGHBOUR_SOLICITATION, ipv6_solicited_node(), memcpy(), memset(), NDP_OPT_LL_SOURCE, ndp_tx_ll_addr(), netdev, rc, net_device::scope_id, sockaddr_in6::sin6_addr, sockaddr_in6::sin6_family, sockaddr_in6::sin6_scope_id, ndp_neighbour_header::target, and icmp_header::type.

◆ ndp_tx_router_solicitation()

static int ndp_tx_router_solicitation ( struct net_device netdev)
static

Transmit NDP router solicitation.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 172 of file ndp.c.

172  {
173  struct ndp_router_solicitation_header rsol;
174  struct sockaddr_in6 sin6_dest;
175  int rc;
176 
177  /* Construct multicast destination address */
178  memset ( &sin6_dest, 0, sizeof ( sin6_dest ) );
179  sin6_dest.sin6_family = AF_INET6;
180  sin6_dest.sin6_scope_id = netdev->scope_id;
181  ipv6_all_routers ( &sin6_dest.sin6_addr );
182 
183  /* Construct router solicitation */
184  memset ( &rsol, 0, sizeof ( rsol ) );
185  rsol.icmp.type = ICMPV6_ROUTER_SOLICITATION;
186 
187  /* Transmit packet */
188  if ( ( rc = ndp_tx_ll_addr ( netdev, NULL, &sin6_dest, &rsol,
189  sizeof ( rsol ), NDP_OPT_LL_SOURCE ) ) !=0)
190  return rc;
191 
192  return 0;
193 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
unsigned int scope_id
Scope ID.
Definition: netdevice.h:360
static void ipv6_all_routers(struct in6_addr *addr)
Construct all-routers multicast address.
Definition: ipv6.h:262
static struct net_device * netdev
Definition: gdbudp.c:52
#define NDP_OPT_LL_SOURCE
NDP source link-layer address option.
Definition: ndp.h:30
#define ICMPV6_ROUTER_SOLICITATION
ICMPv6 router solicitation.
Definition: icmpv6.h:62
An NDP router solicitation header.
Definition: ndp.h:162
IPv6 socket address.
Definition: in.h:115
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.
Definition: ndp.c:73
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
void * memset(void *dest, int character, size_t len) __nonnull

References AF_INET6, ndp_router_solicitation_header::icmp, ICMPV6_ROUTER_SOLICITATION, ipv6_all_routers(), memset(), NDP_OPT_LL_SOURCE, ndp_tx_ll_addr(), netdev, NULL, rc, net_device::scope_id, sockaddr_in6::sin6_addr, sockaddr_in6::sin6_family, sockaddr_in6::sin6_scope_id, and icmp_header::type.

Referenced by ipv6conf_expired().

◆ ndp_rx_neighbour_solicitation_ll_source()

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 
)
static

Process NDP neighbour solicitation source link-layer address option.

Parameters
netdevNetwork device
sin6_srcSource socket address
ndpNDP packet
optionNDP option
lenNDP option length
Return values
rcReturn status code

Definition at line 206 of file ndp.c.

210  {
211  struct ndp_neighbour_header *neigh = &ndp->neigh;
212  struct ndp_ll_addr_option *ll_addr_opt = &option->ll_addr;
214  int rc;
215 
216  /* Silently ignore neighbour solicitations for addresses we do
217  * not own.
218  */
219  if ( ! ipv6_has_addr ( netdev, &neigh->target ) )
220  return 0;
221 
222  /* Sanity check */
223  if ( offsetof ( typeof ( *ll_addr_opt ),
224  ll_addr[ll_protocol->ll_addr_len] ) > len ) {
225  DBGC ( netdev, "NDP %s neighbour solicitation link-layer "
226  "address option too short at %zd bytes\n",
227  netdev->name, len );
228  return -EINVAL;
229  }
230 
231  /* Create or update neighbour cache entry */
232  if ( ( rc = neighbour_define ( netdev, &ipv6_protocol,
233  &sin6_src->sin6_addr,
234  ll_addr_opt->ll_addr ) ) != 0 ) {
235  DBGC ( netdev, "NDP %s could not define %s => %s: %s\n",
236  netdev->name, inet6_ntoa ( &sin6_src->sin6_addr ),
237  ll_protocol->ntoa ( ll_addr_opt->ll_addr ),
238  strerror ( rc ) );
239  return rc;
240  }
241 
242  /* Convert neighbour header to advertisement */
243  memset ( neigh, 0, offsetof ( typeof ( *neigh ), target ) );
246 
247  /* Send neighbour advertisement */
248  if ( ( rc = ndp_tx_ll_addr ( netdev, NULL, sin6_src, neigh,
249  sizeof ( *neigh ),
250  NDP_OPT_LL_TARGET ) ) != 0 )
251  return rc;
252 
253  return 0;
254 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
uint8_t ll_addr[0]
Link-layer address.
Definition: ndp.h:40
struct in6_addr target
Target address.
Definition: ndp.h:123
#define DBGC(...)
Definition: compiler.h:505
#define NDP_OPT_LL_TARGET
NDP target link-layer address option.
Definition: ndp.h:33
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
uint8_t type
Type.
Definition: icmp.h:21
A link-layer protocol.
Definition: netdevice.h:114
NDP source or target link-layer address option.
Definition: ndp.h:36
#define NDP_NEIGHBOUR_SOLICITED
NDP solicited flag.
Definition: ndp.h:132
A long option, as used for getopt_long()
Definition: getopt.h:24
int neighbour_define(struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *ll_dest)
Define neighbour cache entry.
Definition: neighbour.c:363
static struct net_device * netdev
Definition: gdbudp.c:52
struct icmp_header icmp
ICMPv6 header.
Definition: ndp.h:117
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define NDP_NEIGHBOUR_OVERRIDE
NDP override flag.
Definition: ndp.h:135
An NDP neighbour solicitation or advertisement header.
Definition: ndp.h:115
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
uint32_t len
Length.
Definition: ena.h:14
#define ICMPV6_NEIGHBOUR_ADVERTISEMENT
ICMPv6 neighbour advertisement.
Definition: icmpv6.h:71
int ipv6_has_addr(struct net_device *netdev, struct in6_addr *addr)
Check if network device has a specific IPv6 address.
Definition: ipv6.c:141
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
uint8_t flags
Flags.
Definition: ndp.h:119
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.
Definition: ndp.c:73
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
struct ndp_neighbour_header neigh
Neighbour solicitation or advertisement header.
Definition: ndp.h:176
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:132
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
void * memset(void *dest, int character, size_t len) __nonnull

References DBGC, EINVAL, ndp_neighbour_header::flags, ndp_neighbour_header::icmp, ICMPV6_NEIGHBOUR_ADVERTISEMENT, inet6_ntoa(), ipv6_has_addr(), len, ndp_ll_addr_option::ll_addr, ll_protocol::ll_addr_len, net_device::ll_protocol, memset(), net_device::name, NDP_NEIGHBOUR_OVERRIDE, NDP_NEIGHBOUR_SOLICITED, NDP_OPT_LL_TARGET, ndp_tx_ll_addr(), ndp_header::neigh, neighbour_define(), netdev, ll_protocol::ntoa, NULL, offsetof, rc, sockaddr_in6::sin6_addr, strerror(), ndp_neighbour_header::target, icmp_header::type, and typeof().

◆ ndp_rx_neighbour_advertisement_ll_target()

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 
)
static

Process NDP neighbour advertisement target link-layer address option.

Parameters
netdevNetwork device
sin6_srcSource socket address
ndpNDP packet
optionNDP option
lenNDP option length
Return values
rcReturn status code

Definition at line 267 of file ndp.c.

272  {
273  struct ndp_neighbour_header *neigh = &ndp->neigh;
274  struct ndp_ll_addr_option *ll_addr_opt = &option->ll_addr;
276  int rc;
277 
278  /* Sanity check */
279  if ( offsetof ( typeof ( *ll_addr_opt ),
280  ll_addr[ll_protocol->ll_addr_len] ) > len ) {
281  DBGC ( netdev, "NDP %s neighbour advertisement link-layer "
282  "address option too short at %zd bytes\n",
283  netdev->name, len );
284  return -EINVAL;
285  }
286 
287  /* Update neighbour cache entry, if any */
288  if ( ( rc = neighbour_update ( netdev, &ipv6_protocol, &neigh->target,
289  ll_addr_opt->ll_addr ) ) != 0 ) {
290  DBGC ( netdev, "NDP %s could not update %s => %s: %s\n",
291  netdev->name, inet6_ntoa ( &neigh->target ),
292  ll_protocol->ntoa ( ll_addr_opt->ll_addr ),
293  strerror ( rc ) );
294  return rc;
295  }
296 
297  return 0;
298 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
uint8_t ll_addr[0]
Link-layer address.
Definition: ndp.h:40
struct in6_addr target
Target address.
Definition: ndp.h:123
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
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.
Definition: neighbour.c:338
A link-layer protocol.
Definition: netdevice.h:114
NDP source or target link-layer address option.
Definition: ndp.h:36
A long option, as used for getopt_long()
Definition: getopt.h:24
static struct net_device * netdev
Definition: gdbudp.c:52
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An NDP neighbour solicitation or advertisement header.
Definition: ndp.h:115
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
uint32_t len
Length.
Definition: ena.h:14
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
struct ndp_neighbour_header neigh
Neighbour solicitation or advertisement header.
Definition: ndp.h:176
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372

References DBGC, EINVAL, inet6_ntoa(), len, ndp_ll_addr_option::ll_addr, ll_protocol::ll_addr_len, net_device::ll_protocol, net_device::name, ndp_header::neigh, neighbour_update(), netdev, ll_protocol::ntoa, offsetof, rc, strerror(), ndp_neighbour_header::target, and typeof().

◆ ndp_rx_router_advertisement_ll_source()

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 
)
static

Process NDP router advertisement source link-layer address option.

Parameters
netdevNetwork device
sin6_srcSource socket address
ndpNDP packet
optionNDP option
lenNDP option length
Return values
rcReturn status code

Definition at line 311 of file ndp.c.

314  {
315  struct ndp_ll_addr_option *ll_addr_opt = &option->ll_addr;
317  int rc;
318 
319  /* Sanity check */
320  if ( offsetof ( typeof ( *ll_addr_opt ),
321  ll_addr[ll_protocol->ll_addr_len] ) > len ) {
322  DBGC ( netdev, "NDP %s router advertisement link-layer address "
323  "option too short at %zd bytes\n", netdev->name, len );
324  return -EINVAL;
325  }
326 
327  /* Define neighbour cache entry */
328  if ( ( rc = neighbour_define ( netdev, &ipv6_protocol,
329  &sin6_src->sin6_addr,
330  ll_addr_opt->ll_addr ) ) != 0 ) {
331  DBGC ( netdev, "NDP %s could not define %s => %s: %s\n",
332  netdev->name, inet6_ntoa ( &sin6_src->sin6_addr ),
333  ll_protocol->ntoa ( ll_addr_opt->ll_addr ),
334  strerror ( rc ) );
335  return rc;
336  }
337 
338  return 0;
339 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
uint8_t ll_addr[0]
Link-layer address.
Definition: ndp.h:40
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
A link-layer protocol.
Definition: netdevice.h:114
NDP source or target link-layer address option.
Definition: ndp.h:36
A long option, as used for getopt_long()
Definition: getopt.h:24
int neighbour_define(struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *ll_dest)
Define neighbour cache entry.
Definition: neighbour.c:363
static struct net_device * netdev
Definition: gdbudp.c:52
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
uint32_t len
Length.
Definition: ena.h:14
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:132
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372

References DBGC, EINVAL, inet6_ntoa(), len, ndp_ll_addr_option::ll_addr, ll_protocol::ll_addr_len, net_device::ll_protocol, net_device::name, neighbour_define(), netdev, ll_protocol::ntoa, offsetof, rc, sockaddr_in6::sin6_addr, strerror(), and typeof().

◆ ndp_rx_router_advertisement_prefix()

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 
)
static

Process NDP router advertisement prefix information option.

Parameters
netdevNetwork device
sin6_srcSource socket address
ndpNDP packet
optionNDP option
lenNDP option length
Return values
rcReturn status code

Definition at line 352 of file ndp.c.

355  {
356  struct ndp_router_advertisement_header *radv = &ndp->radv;
357  struct ndp_prefix_information_option *prefix_opt = &option->prefix;
358 
359  /* Sanity check */
360  if ( sizeof ( *prefix_opt ) > len ) {
361  DBGC ( netdev, "NDP %s router advertisement prefix option too "
362  "short at %zd bytes\n", netdev->name, len );
363  return -EINVAL;
364  }
365 
366  DBGC ( netdev, "NDP %s found %sdefault router %s ",
367  netdev->name, ( radv->lifetime ? "" : "non-" ),
368  inet6_ntoa ( &sin6_src->sin6_addr ) );
369  DBGC ( netdev, "for %s-link %sautonomous prefix %s/%d\n",
370  ( ( prefix_opt->flags & NDP_PREFIX_ON_LINK ) ? "on" : "off" ),
371  ( ( prefix_opt->flags & NDP_PREFIX_AUTONOMOUS ) ? "" : "non-" ),
372  inet6_ntoa ( &prefix_opt->prefix ), prefix_opt->prefix_len );
373 
374  return 0;
375 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
uint8_t flags
Flags.
Definition: ndp.h:53
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
#define DBGC(...)
Definition: compiler.h:505
struct ndp_router_advertisement_header radv
Router advertisement header.
Definition: ndp.h:180
A long option, as used for getopt_long()
Definition: getopt.h:24
NDP prefix information.
Definition: ndp.h:47
static struct net_device * netdev
Definition: gdbudp.c:52
#define NDP_PREFIX_ON_LINK
NDP on-link flag.
Definition: ndp.h:65
An NDP router advertisement header.
Definition: ndp.h:138
uint8_t prefix_len
Prefix length.
Definition: ndp.h:51
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
uint32_t len
Length.
Definition: ena.h:14
#define NDP_PREFIX_AUTONOMOUS
NDP autonomous address configuration flag.
Definition: ndp.h:68
struct in6_addr prefix
Prefix.
Definition: ndp.h:61
uint16_t lifetime
Router lifetime.
Definition: ndp.h:146
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:132

References DBGC, EINVAL, ndp_prefix_information_option::flags, inet6_ntoa(), len, ndp_router_advertisement_header::lifetime, net_device::name, NDP_PREFIX_AUTONOMOUS, NDP_PREFIX_ON_LINK, netdev, ndp_prefix_information_option::prefix, ndp_prefix_information_option::prefix_len, ndp_header::radv, and sockaddr_in6::sin6_addr.

◆ ndp_rx_option()

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 
)
static

Process received NDP option.

Parameters
netdevNetwork device
sin6_srcSource socket address
ndpNDP packet
optionNDP option
lenOption length
Return values
rcReturn status code

Definition at line 431 of file ndp.c.

433  {
434  struct ndp_option_handler *handler;
435  unsigned int i;
436 
437  /* Locate a suitable option handler, if any */
438  for ( i = 0 ; i < ( sizeof ( ndp_option_handlers ) /
439  sizeof ( ndp_option_handlers[0] ) ) ; i++ ) {
440  handler = &ndp_option_handlers[i];
441  if ( ( handler->icmp_type == ndp->icmp.type ) &&
442  ( handler->option_type == option->header.type ) ) {
443  return handler->rx ( netdev, sin6_src, ndp,
444  option, len );
445  }
446  }
447 
448  /* Silently ignore unknown options as per RFC 4861 */
449  return 0;
450 }
struct icmp_header icmp
ICMPv6 header.
Definition: ndp.h:174
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.
Definition: ndp.c:392
uint8_t icmp_type
ICMPv6 type.
Definition: ndp.c:380
uint8_t type
Type.
Definition: icmp.h:21
A long option, as used for getopt_long()
Definition: getopt.h:24
static struct net_device * netdev
Definition: gdbudp.c:52
uint8_t option_type
Option type.
Definition: ndp.c:382
An NDP option handler.
Definition: ndp.c:378
static struct ndp_option_handler ndp_option_handlers[]
NDP option handlers.
Definition: ndp.c:398
uint32_t len
Length.
Definition: ena.h:14

References ndp_header::icmp, ndp_option_handler::icmp_type, len, ndp_option_handlers, netdev, ndp_option_handler::option_type, ndp_option_handler::rx, and icmp_header::type.

Referenced by ndp_rx_options().

◆ ndp_rx_options()

static int ndp_rx_options ( struct net_device netdev,
struct sockaddr_in6 sin6_src,
union ndp_header ndp,
size_t  offset,
size_t  len 
)
static

Process received NDP packet options.

Parameters
netdevNetwork device
sin6_srcSource socket address
ndpNDP header
offsetOffset to NDP options
lenLength of NDP packet
Return values
rcReturn status code

Definition at line 462 of file ndp.c.

464  {
465  union ndp_option *option;
466  size_t remaining;
467  size_t option_len;
468  int rc;
469 
470  /* Sanity check */
471  if ( len < offset ) {
472  DBGC ( netdev, "NDP %s packet too short at %zd bytes (min %zd "
473  "bytes)\n", netdev->name, len, offset );
474  return -EINVAL;
475  }
476 
477  /* Search for option */
478  option = ( ( ( void * ) ndp ) + offset );
479  remaining = ( len - offset );
480  while ( remaining ) {
481 
482  /* Sanity check */
483  if ( ( remaining < sizeof ( option->header ) ) ||
484  ( option->header.blocks == 0 ) ||
485  ( remaining < ( option->header.blocks *
486  NDP_OPTION_BLKSZ ) ) ) {
487  DBGC ( netdev, "NDP %s bad option length:\n",
488  netdev->name );
489  DBGC_HDA ( netdev, 0, option, remaining );
490  return -EINVAL;
491  }
492  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
493 
494  /* Handle option */
495  if ( ( rc = ndp_rx_option ( netdev, sin6_src, ndp, option,
496  option_len ) ) != 0 )
497  return rc;
498 
499  /* Move to next option */
500  option = ( ( ( void * ) option ) + option_len );
501  remaining -= option_len;
502  }
503 
504  return 0;
505 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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.
Definition: ndp.c:431
#define DBGC(...)
Definition: compiler.h:505
A long option, as used for getopt_long()
Definition: getopt.h:24
#define DBGC_HDA(...)
Definition: compiler.h:506
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static struct net_device * netdev
Definition: gdbudp.c:52
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
uint32_t len
Length.
Definition: ena.h:14
An NDP option.
Definition: ndp.h:101
#define NDP_OPTION_BLKSZ
NDP option block size.
Definition: ndp.h:27

References DBGC, DBGC_HDA, EINVAL, len, net_device::name, NDP_OPTION_BLKSZ, ndp_rx_option(), netdev, offset, and rc.

Referenced by ndp_rx_neighbour(), and ndp_rx_router_advertisement().

◆ ndp_rx_neighbour()

static int ndp_rx_neighbour ( struct io_buffer iobuf,
struct net_device netdev,
struct sockaddr_in6 sin6_src,
struct sockaddr_in6 *sin6_dest  __unused 
)
static

Process received NDP neighbour solicitation or advertisement.

Parameters
iobufI/O buffer
netdevNetwork device
sin6_srcSource socket address
sin6_destDestination socket address
Return values
rcReturn status code

Definition at line 516 of file ndp.c.

519  {
520  union ndp_header *ndp = iobuf->data;
521  struct ndp_neighbour_header *neigh = &ndp->neigh;
522  size_t len = iob_len ( iobuf );
523  int rc;
524 
525  /* Process options */
526  if ( ( rc = ndp_rx_options ( netdev, sin6_src, ndp,
527  offsetof ( typeof ( *neigh ), option ),
528  len ) ) != 0 )
529  goto err_options;
530 
531  err_options:
532  free_iob ( iobuf );
533  return rc;
534 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
A long option, as used for getopt_long()
Definition: getopt.h:24
static struct net_device * netdev
Definition: gdbudp.c:52
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.
Definition: ndp.c:462
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
An NDP neighbour solicitation or advertisement header.
Definition: ndp.h:115
An NDP header.
Definition: ndp.h:172
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:48
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
struct ndp_neighbour_header neigh
Neighbour solicitation or advertisement header.
Definition: ndp.h:176

References io_buffer::data, free_iob(), iob_len(), len, ndp_rx_options(), ndp_header::neigh, netdev, offsetof, rc, and typeof().

◆ ndp_rx_router_advertisement()

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 
)
static

Process received NDP router advertisement.

Parameters
iobufI/O buffer
netdevNetwork device
sin6_srcSource socket address
sin6_destDestination socket address
Return values
rcReturn status code

Definition at line 546 of file ndp.c.

549  {
550  union ndp_header *ndp = iobuf->data;
551  struct ndp_router_advertisement_header *radv = &ndp->radv;
552  struct in6_addr *router = &sin6_src->sin6_addr;
553  size_t len = iob_len ( iobuf );
554  int rc;
555 
556  /* Process options */
557  if ( ( rc = ndp_rx_options ( netdev, sin6_src, ndp,
558  offsetof ( typeof ( *radv ), option ),
559  len ) ) != 0 )
560  goto err_options;
561 
562  /* Pass to IPv6 autoconfiguration */
563  if ( ( rc = ipv6conf_rx_router_advertisement ( netdev, router,
564  radv, len ) ) != 0 )
565  goto err_ipv6conf;
566 
567  err_ipv6conf:
568  err_options:
569  free_iob ( iobuf );
570  return rc;
571 }
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.
Definition: ndp.c:1191
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
struct ndp_router_advertisement_header radv
Router advertisement header.
Definition: ndp.h:180
A long option, as used for getopt_long()
Definition: getopt.h:24
static struct net_device * netdev
Definition: gdbudp.c:52
IP6 address structure.
Definition: in.h:48
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.
Definition: ndp.c:462
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
An NDP router advertisement header.
Definition: ndp.h:138
An NDP header.
Definition: ndp.h:172
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:48
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:132

References io_buffer::data, free_iob(), iob_len(), ipv6conf_rx_router_advertisement(), len, ndp_rx_options(), netdev, offsetof, ndp_header::radv, rc, sockaddr_in6::sin6_addr, and typeof().

◆ ndp_applies()

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

Check applicability of NDP setting.

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

Definition at line 674 of file ndp.c.

675  {
676 
677  return ( setting->scope == &ndp_settings_scope );
678 }
static const struct settings_scope ndp_settings_scope
NDP settings scope.
Definition: ndp.c:622
A setting.
Definition: settings.h:23
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:49

References ndp_settings_scope, and setting::scope.

◆ ndp_fetch()

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

Fetch value of NDP 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 689 of file ndp.c.

691  {
692  struct ndp_settings *ndpset =
694  struct net_device *netdev =
696  settings.settings );
697  union ndp_option *option;
698  unsigned int tag_type;
699  unsigned int tag_offset;
700  unsigned int tag_len;
701  unsigned int tag_instance;
702  size_t offset;
703  size_t option_len;
704  void *option_data;
705 
706  /* Parse setting tag */
707  tag_type = NDP_TAG_TYPE ( setting->tag );
708  tag_offset = NDP_TAG_OFFSET ( setting->tag );
709  tag_len = NDP_TAG_LEN ( setting->tag );
710  tag_instance = NDP_TAG_INSTANCE ( setting->tag );
711 
712  /* Scan through NDP options for requested type. We can assume
713  * that the options are well-formed, otherwise they would have
714  * been rejected prior to being stored.
715  */
716  for ( offset = 0 ; offset < ndpset->len ; offset += option_len ) {
717 
718  /* Calculate option length */
719  option = ( ( ( void * ) ndpset->options ) + offset );
720  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
721 
722  /* Skip options that do not match this tag */
723  if ( option->header.type != tag_type )
724  continue;
725 
726  /* Skip previous instances of this option */
727  if ( tag_instance-- != 0 )
728  continue;
729 
730  /* Sanity check */
731  if ( ( tag_offset + tag_len ) > option_len ) {
732  DBGC ( netdev, "NDP %s option %d too short\n",
733  netdev->name, tag_type );
734  return -EINVAL;
735  }
736  if ( ! tag_len )
737  tag_len = ( option_len - tag_offset );
738  option_data = ( ( ( void * ) option ) + tag_offset );
739 
740  /* Copy data to output buffer */
741  if ( len > tag_len )
742  len = tag_len;
743  memcpy ( data, option_data, len );
744 
745  /* Default to hex if no type is specified */
746  if ( ! setting->type )
747  setting->type = &setting_type_hex;
748 
749  return tag_len;
750  }
751 
752  return -ENOENT;
753 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define NDP_TAG_INSTANCE(tag)
Extract NDP tag instance.
Definition: ndp.c:665
struct settings * parent
Parent settings block.
Definition: settings.h:138
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
#define NDP_TAG_LEN(tag)
Extract NDP tag length.
Definition: ndp.c:657
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
A long option, as used for getopt_long()
Definition: getopt.h:24
size_t len
Length of NDP options.
Definition: ndp.c:616
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static struct net_device * netdev
Definition: gdbudp.c:52
const struct setting_type * type
Setting type.
Definition: settings.h:36
#define NDP_TAG_TYPE(tag)
Extract NDP tag type.
Definition: ndp.c:641
A network device.
Definition: netdevice.h:352
A settings block.
Definition: settings.h:132
An NDP settings block.
Definition: ndp.c:606
A setting.
Definition: settings.h:23
union ndp_option options[0]
NDP options.
Definition: ndp.c:618
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
uint32_t len
Length.
Definition: ena.h:14
#define NDP_TAG_OFFSET(tag)
Extract NDP tag offset.
Definition: ndp.c:649
uint8_t data[48]
Additional event data.
Definition: ena.h:22
An NDP option.
Definition: ndp.h:101
#define NDP_OPTION_BLKSZ
NDP option block size.
Definition: ndp.h:27

References container_of, data, DBGC, EINVAL, ENOENT, len, ndp_settings::len, memcpy(), net_device::name, NDP_OPTION_BLKSZ, NDP_TAG_INSTANCE, NDP_TAG_LEN, NDP_TAG_OFFSET, NDP_TAG_TYPE, netdev, offset, ndp_settings::options, settings::parent, setting::tag, and setting::type.

◆ ndp_prefix_applies()

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

Check applicability of NDP per-prefix setting.

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

Definition at line 768 of file ndp.c.

769  {
770 
771  return ( setting->scope == &ipv6_settings_scope );
772 }
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 ipv6_settings_scope, and setting::scope.

◆ ndp_prefix_fetch_ip6()

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

Fetch value of NDP IPv6 address setting.

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

Definition at line 782 of file ndp.c.

783  {
784  struct ndp_prefix_settings *prefset =
786  struct ndp_settings *ndpset =
788  struct net_device *netdev =
789  container_of ( ndpset->settings.parent, struct net_device,
790  settings.settings );
791  struct ndp_prefix_information_option *prefix = prefset->prefix;
792  struct in6_addr *ip6 = &prefix->prefix;
793  struct in6_addr slaac;
794  int prefix_len;
795  int rc;
796 
797  /* Skip dead prefixes */
798  if ( ! prefix->valid )
799  return -ENOENT;
800 
801  /* Construct IPv6 address via SLAAC, if applicable */
802  if ( prefix->flags & NDP_PREFIX_AUTONOMOUS ) {
803  memcpy ( &slaac, ip6, sizeof ( slaac ) );
804  prefix_len = ipv6_eui64 ( &slaac, netdev );
805  if ( prefix_len == prefix->prefix_len ) {
806  /* Correctly configured prefix: use SLAAC address */
807  ip6 = &slaac;
808  } else if ( prefix_len < 0 ) {
809  /* Link layer does not support SLAAC */
810  rc = prefix_len;
811  DBGC ( netdev, "NDP %s does not support SLAAC: %s\n",
812  netdev->name, strerror ( rc ) );
813  } else {
814  /* Prefix length incorrect: assume a badly
815  * configured router and ignore SLAAC address.
816  */
817  DBGC ( netdev, "NDP %s ignoring misconfigured SLAAC "
818  "on prefix %s/%d\n", netdev->name,
819  inet6_ntoa ( ip6 ), prefix->prefix_len );
820  }
821  }
822 
823  /* Fill in IPv6 address */
824  if ( len > sizeof ( *ip6 ) )
825  len = sizeof ( *ip6 );
826  memcpy ( data, ip6, len );
827 
828  return sizeof ( *ip6 );
829 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
struct settings * parent
Parent settings block.
Definition: settings.h:138
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
char prefix[4]
Definition: vmconsole.c:53
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
NDP prefix information.
Definition: ndp.h:47
static struct net_device * netdev
Definition: gdbudp.c:52
IP6 address structure.
Definition: in.h:48
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
A network device.
Definition: netdevice.h:352
struct ndp_prefix_information_option * prefix
Prefix information option.
Definition: ndp.c:602
A settings block.
Definition: settings.h:132
An NDP settings block.
Definition: ndp.c:606
An NDP prefix settings block.
Definition: ndp.c:596
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
uint32_t len
Length.
Definition: ena.h:14
struct settings settings
Settings interface.
Definition: ndp.c:610
#define NDP_PREFIX_AUTONOMOUS
NDP autonomous address configuration flag.
Definition: ndp.h:68
uint8_t data[48]
Additional event data.
Definition: ena.h:22
static int ipv6_eui64(struct in6_addr *addr, struct net_device *netdev)
Construct local IPv6 address via EUI-64.
Definition: ipv6.h:216

References container_of, data, DBGC, ENOENT, inet6_ntoa(), ipv6_eui64(), len, memcpy(), net_device::name, NDP_PREFIX_AUTONOMOUS, netdev, settings::parent, prefix, ndp_prefix_settings::prefix, rc, ndp_settings::settings, and strerror().

◆ ndp_prefix_fetch_len6()

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

Fetch value of NDP prefix length setting.

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

Definition at line 839 of file ndp.c.

840  {
841  struct ndp_prefix_settings *prefset =
843  struct ndp_prefix_information_option *prefix = prefset->prefix;
844  uint8_t *len6;
845 
846  /* Fill in prefix length */
847  if ( len >= sizeof ( *len6 ) ) {
848  /* We treat an off-link prefix as having a prefix
849  * length covering the entire IPv6 address.
850  */
851  len6 = data;
852  *len6 = ( ( prefix->flags & NDP_PREFIX_ON_LINK ) ?
853  prefix->prefix_len : -1UL );
854  }
855 
856  return sizeof ( *len6 );
857 }
char prefix[4]
Definition: vmconsole.c:53
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
NDP prefix information.
Definition: ndp.h:47
#define NDP_PREFIX_ON_LINK
NDP on-link flag.
Definition: ndp.h:65
struct ndp_prefix_information_option * prefix
Prefix information option.
Definition: ndp.c:602
A settings block.
Definition: settings.h:132
unsigned char uint8_t
Definition: stdint.h:10
An NDP prefix settings block.
Definition: ndp.c:596
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References container_of, data, len, NDP_PREFIX_ON_LINK, prefix, and ndp_prefix_settings::prefix.

◆ ndp_prefix_fetch_gateway6()

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

Fetch value of NDP router address setting.

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

Definition at line 867 of file ndp.c.

868  {
869  struct ndp_settings *ndpset =
871 
872  /* Treat non-routing router as non-existent */
873  if ( ! ndpset->lifetime )
874  return -ENOENT;
875 
876  /* Fill in router address */
877  if ( len > sizeof ( ndpset->router ) )
878  len = sizeof ( ndpset->router );
879  memcpy ( data, &ndpset->router, len );
880 
881  return sizeof ( ndpset->router );
882 }
unsigned int lifetime
Router lifetime.
Definition: ndp.c:614
struct settings * parent
Parent settings block.
Definition: settings.h:138
#define ENOENT
No such file or directory.
Definition: errno.h:514
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 settings block.
Definition: settings.h:132
An NDP settings block.
Definition: ndp.c:606
struct in6_addr router
Router address.
Definition: ndp.c:612
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References container_of, data, ENOENT, len, ndp_settings::lifetime, memcpy(), settings::parent, and ndp_settings::router.

◆ ndp_prefix_fetch()

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

Fetch value of NDP pre-prefix 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 915 of file ndp.c.

917  {
918  struct ndp_prefix_operation *op;
919  unsigned int i;
920 
921  /* Handle per-prefix settings */
922  for ( i = 0 ; i < ( sizeof ( ndp_prefix_operations ) /
923  sizeof ( ndp_prefix_operations[0] ) ) ; i++ ) {
925  if ( setting_cmp ( setting, op->setting ) == 0 )
926  return op->fetch ( settings, data, len );
927  }
928 
929  return -ENOENT;
930 }
An NDP per-prefix setting operation.
Definition: ndp.c:885
#define ENOENT
No such file or directory.
Definition: errno.h:514
A settings block.
Definition: settings.h:132
A setting.
Definition: settings.h:23
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
static struct ndp_prefix_operation ndp_prefix_operations[]
NDP per-prefix settings operations.
Definition: ndp.c:900
uint32_t len
Length.
Definition: ena.h:14
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 data, ENOENT, len, ndp_prefix_operations, op, and setting_cmp().

◆ ndp_register_settings()

static int ndp_register_settings ( struct net_device netdev,
struct in6_addr router,
unsigned int  lifetime,
union ndp_option options,
size_t  len 
)
static

Register NDP settings.

Parameters
netdevNetwork device
routerRouter address
lifetimeRouter lifetime
optionsNDP options
lenLength of options
Return values
rcReturn status code

Definition at line 948 of file ndp.c.

951  {
952  struct settings *parent = netdev_settings ( netdev );
953  union ndp_option *option;
954  struct ndp_settings *ndpset;
955  struct ndp_prefix_settings *prefset;
956  size_t offset;
957  size_t option_len;
958  unsigned int prefixes;
959  unsigned int instance;
960  int order;
961  int rc;
962 
963  /* Count number of prefix options. We can assume that the
964  * options are well-formed, otherwise they would have been
965  * rejected prior to being stored.
966  */
967  order = IPV6_ORDER_PREFIX_ONLY;
968  for ( prefixes = 0, offset = 0 ; offset < len ; offset += option_len ) {
969 
970  /* Skip non-prefix options */
971  option = ( ( ( void * ) options ) + offset );
972  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
973  if ( option->header.type != NDP_OPT_PREFIX )
974  continue;
975 
976  /* Count number of prefixes */
977  prefixes++;
978 
979  /* Increase overall order if we have SLAAC addresses */
980  if ( option->prefix.flags & NDP_PREFIX_AUTONOMOUS )
981  order = IPV6_ORDER_SLAAC;
982  }
983 
984  /* Allocate and initialise structure */
985  ndpset = zalloc ( sizeof ( *ndpset ) + len +
986  ( prefixes * sizeof ( *prefset ) ) );
987  if ( ! ndpset ) {
988  rc = -ENOMEM;
989  goto err_alloc;
990  }
991  ref_init ( &ndpset->refcnt, NULL );
993  &ndpset->refcnt, &ndp_settings_scope );
994  ndpset->settings.order = order;
995  memcpy ( &ndpset->router, router, sizeof ( ndpset->router ) );
996  ndpset->lifetime = lifetime;
997  ndpset->len = len;
998  memcpy ( ndpset->options, options, len );
999  prefset = ( ( ( void * ) ndpset->options ) + len );
1000 
1001  /* Register settings */
1002  if ( ( rc = register_settings ( &ndpset->settings, parent,
1003  NDP_SETTINGS_NAME ) ) != 0 )
1004  goto err_register;
1005 
1006  /* Construct and register per-prefix settings */
1007  for ( instance = 0, offset = 0 ; offset < len ; offset += option_len ) {
1008 
1009  /* Skip non-prefix options */
1010  option = ( ( ( void * ) ndpset->options ) + offset );
1011  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
1012  if ( option->header.type != NDP_OPT_PREFIX )
1013  continue;
1014 
1015  /* Initialise structure */
1016  settings_init ( &prefset->settings,
1018  &ndpset->refcnt, &ndp_settings_scope );
1019  prefset->settings.order =
1020  ( ( option->prefix.flags & NDP_PREFIX_AUTONOMOUS ) ?
1022  prefset->prefix = &option->prefix;
1023  snprintf ( prefset->name, sizeof ( prefset->name ), "%d",
1024  instance++ );
1025 
1026  /* Register settings */
1027  if ( ( rc = register_settings ( &prefset->settings,
1028  &ndpset->settings,
1029  prefset->name ) ) != 0 )
1030  goto err_register_prefix;
1031 
1032  /* Move to next per-prefix settings */
1033  prefset++;
1034  }
1035  assert ( instance == prefixes );
1036 
1037  ref_put ( &ndpset->refcnt );
1038  return 0;
1039 
1040  err_register_prefix:
1041  unregister_settings ( &ndpset->settings );
1042  err_register:
1043  ref_put ( &ndpset->refcnt );
1044  err_alloc:
1045  return rc;
1046 }
#define NDP_OPT_PREFIX
NDP prefix information option.
Definition: ndp.h:44
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define NDP_SETTINGS_NAME
NDP settings block name.
Definition: ndp.h:204
unsigned int lifetime
Router lifetime.
Definition: ndp.c:614
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition: settings.c:514
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
struct settings * parent
Parent settings block.
Definition: settings.h:138
static struct settings_operations ndp_settings_operations
NDP settings operations.
Definition: ndp.c:756
static const struct settings_scope ndp_settings_scope
NDP settings scope.
Definition: ndp.c:622
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
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
static struct settings_operations ndp_prefix_settings_operations
NDP per-prefix settings operations.
Definition: ndp.c:933
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A long option, as used for getopt_long()
Definition: getopt.h:24
static int options
Definition: 3c515.c:286
size_t len
Length of NDP options.
Definition: ndp.c:616
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static struct net_device * netdev
Definition: gdbudp.c:52
Address assigned via SLAAC.
Definition: ipv6.h:286
struct refcnt refcnt
Reference counter.
Definition: ndp.c:608
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct ndp_prefix_information_option * prefix
Prefix information option.
Definition: ndp.c:602
A settings block.
Definition: settings.h:132
u32 lifetime
For Lifetime-type KDEs, the lifetime in seconds.
Definition: wpa.h:54
An NDP settings block.
Definition: ndp.c:606
char name[4]
Name.
Definition: ndp.c:600
An NDP prefix settings block.
Definition: ndp.c:596
struct in6_addr router
Router address.
Definition: ndp.c:612
int order
Sibling ordering.
Definition: settings.h:148
union ndp_option options[0]
NDP options.
Definition: ndp.c:618
uint32_t len
Length.
Definition: ena.h:14
struct settings settings
Settings interface.
Definition: ndp.c:610
#define NDP_PREFIX_AUTONOMOUS
NDP autonomous address configuration flag.
Definition: ndp.h:68
No address.
Definition: ipv6.h:282
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:475
An NDP option.
Definition: ndp.h:101
#define NDP_OPTION_BLKSZ
NDP option block size.
Definition: ndp.h:27
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct settings settings
Settings interface.
Definition: ndp.c:598
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References assert(), ENOMEM, IPV6_ORDER_PREFIX_ONLY, IPV6_ORDER_SLAAC, len, ndp_settings::len, lifetime, ndp_settings::lifetime, memcpy(), ndp_prefix_settings::name, NDP_OPT_PREFIX, NDP_OPTION_BLKSZ, NDP_PREFIX_AUTONOMOUS, ndp_prefix_settings_operations, NDP_SETTINGS_NAME, ndp_settings_operations, ndp_settings_scope, netdev, netdev_settings(), NULL, offset, options, ndp_settings::options, settings::order, settings::parent, ndp_prefix_settings::prefix, rc, ref_init, ref_put, ndp_settings::refcnt, register_settings(), ndp_settings::router, ndp_prefix_settings::settings, ndp_settings::settings, settings_init(), snprintf(), unregister_settings(), and zalloc().

Referenced by ipv6conf_rx_router_advertisement().

◆ __setting() [1/2]

const struct setting ndp_dns6_setting __setting ( SETTING_IP6_EXTRA  ,
dns6   
)

DNS server setting.

◆ __setting() [2/2]

const struct setting ndp_dnssl_setting __setting ( SETTING_IP_EXTRA  ,
dnssl   
)

DNS search list setting.

◆ LIST_HEAD()

static LIST_HEAD ( ipv6confs  )
static

List of IPv6 configurators.

◆ ipv6conf_free()

static void ipv6conf_free ( struct refcnt refcnt)
static

Free IPv6 configurator.

Parameters
refcntReference count

Definition at line 1104 of file ndp.c.

1104  {
1105  struct ipv6conf *ipv6conf =
1106  container_of ( refcnt, struct ipv6conf, refcnt );
1107 
1108  netdev_put ( ipv6conf->netdev );
1109  free ( ipv6conf );
1110 }
A reference counter.
Definition: refcnt.h:26
An IPv6 configurator.
Definition: ndp.c:1075
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
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1087
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54

References container_of, free, ipv6conf::netdev, and netdev_put().

Referenced by start_ipv6conf().

◆ ipv6conf_done()

static void ipv6conf_done ( struct ipv6conf ipv6conf,
int  rc 
)
static

Finish IPv6 autoconfiguration.

Parameters
ipv6IPv6 configurator
rcReason for finishing

Definition at line 1134 of file ndp.c.

1134  {
1135 
1136  /* Shut down interfaces */
1137  intf_shutdown ( &ipv6conf->job, rc );
1138  intf_shutdown ( &ipv6conf->dhcp, rc );
1139 
1140  /* Stop timer */
1141  stop_timer ( &ipv6conf->timer );
1142 
1143  /* Remove from list and drop list's reference */
1144  list_del ( &ipv6conf->list );
1145  ref_put ( &ipv6conf->refcnt );
1146 }
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 refcnt refcnt
Reference count.
Definition: ndp.c:1077
struct interface dhcp
DHCPv6 interface.
Definition: ndp.c:1084
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
An IPv6 configurator.
Definition: ndp.c:1075
struct list_head list
List of configurators.
Definition: ndp.c:1079
struct interface job
Job control interface.
Definition: ndp.c:1082
struct retry_timer timer
Retransmission timer.
Definition: ndp.c:1090
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References ipv6conf::dhcp, intf_shutdown(), ipv6conf::job, ipv6conf::list, list_del, rc, ref_put, ipv6conf::refcnt, stop_timer(), and ipv6conf::timer.

Referenced by ipv6conf_expired(), and ipv6conf_rx_router_advertisement().

◆ ipv6conf_expired()

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

Handle IPv6 configurator timer expiry.

Parameters
timerRetry timer
failFailure indicator

Definition at line 1154 of file ndp.c.

1154  {
1155  struct ipv6conf *ipv6conf =
1156  container_of ( timer, struct ipv6conf, timer );
1157  struct net_device *netdev = ipv6conf->netdev;
1158 
1159  /* If we have failed, terminate autoconfiguration */
1160  if ( fail ) {
1162  return;
1163  }
1164 
1165  /* Otherwise, transmit router solicitation and restart timer */
1166  start_timer ( &ipv6conf->timer );
1168 
1169  /* If link is blocked, defer router discovery timeout */
1170  if ( netdev_link_blocked ( netdev ) &&
1172  DBGC ( netdev, "NDP %s deferring discovery timeout\n",
1173  netdev->name );
1175  }
1176 }
static int ndp_tx_router_solicitation(struct net_device *netdev)
Transmit NDP router solicitation.
Definition: ndp.c:172
#define DBGC(...)
Definition: compiler.h:505
static int netdev_link_blocked(struct net_device *netdev)
Check link block state of network device.
Definition: netdevice.h:647
A timer.
Definition: timer.h:28
An IPv6 configurator.
Definition: ndp.c:1075
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
Definition: ndp.c:1134
static struct net_device * netdev
Definition: gdbudp.c:52
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1087
A network device.
Definition: netdevice.h:352
struct retry_timer timer
Retransmission timer.
Definition: ndp.c:1090
#define IPV6CONF_BLOCK_TIMEOUT
Router discovery blocked link retry timeout.
Definition: ndp.c:50
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:93
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
unsigned int deferred
Deferred discovery counter.
Definition: ndp.c:1093
#define IPV6CONF_MAX_DEFERRALS
Router discovery maximum number of deferrals.
Definition: ndp.c:53
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669

References container_of, DBGC, ipv6conf::deferred, ETIMEDOUT, IPV6CONF_BLOCK_TIMEOUT, ipv6conf_done(), IPV6CONF_MAX_DEFERRALS, net_device::name, ndp_tx_router_solicitation(), netdev, ipv6conf::netdev, netdev_link_blocked(), start_timer(), start_timer_fixed(), and ipv6conf::timer.

Referenced by start_ipv6conf().

◆ start_ipv6conf()

int start_ipv6conf ( struct interface job,
struct net_device netdev 
)

Start IPv6 autoconfiguration.

Parameters
jobJob control interface
netdevNetwork device
Return values
rcReturn status code

Definition at line 1266 of file ndp.c.

1266  {
1267  struct ipv6conf *ipv6conf;
1268 
1269  /* Allocate and initialise structure */
1270  ipv6conf = zalloc ( sizeof ( *ipv6conf ) );
1271  if ( ! ipv6conf )
1272  return -ENOMEM;
1276  timer_init ( &ipv6conf->timer, ipv6conf_expired, &ipv6conf->refcnt );
1277  set_timer_limits ( &ipv6conf->timer, IPV6CONF_MIN_TIMEOUT,
1280 
1281  /* Start timer to initiate router solicitation */
1283 
1284  /* Attach parent interface, transfer reference to list, and return */
1285  intf_plug_plug ( &ipv6conf->job, job );
1286  list_add ( &ipv6conf->list, &ipv6confs );
1287  return 0;
1288 }
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:99
static void ipv6conf_expired(struct retry_timer *timer, int fail)
Handle IPv6 configurator timer expiry.
Definition: ndp.c:1154
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
struct refcnt refcnt
Reference count.
Definition: ndp.c:1077
struct interface dhcp
DHCPv6 interface.
Definition: ndp.c:1084
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:107
static void ipv6conf_free(struct refcnt *refcnt)
Free IPv6 configurator.
Definition: ndp.c:1104
#define ENOMEM
Not enough space.
Definition: errno.h:534
An IPv6 configurator.
Definition: ndp.c:1075
static struct net_device * netdev
Definition: gdbudp.c:52
struct list_head list
List of configurators.
Definition: ndp.c:1079
#define IPV6CONF_MAX_TIMEOUT
Router discovery maximum timeout.
Definition: ndp.c:47
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1087
struct interface job
Job control interface.
Definition: ndp.c:1082
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
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: ndp.c:1090
#define IPV6CONF_MIN_TIMEOUT
Router discovery minimum timeout.
Definition: ndp.c:44
static struct interface_descriptor ipv6conf_job_desc
IPv6 configurator job interface descriptor.
Definition: ndp.c:1247
static struct interface_descriptor ipv6conf_dhcp_desc
IPv6 configurator DHCPv6 interface descriptor.
Definition: ndp.c:1256
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203

References ipv6conf::dhcp, ENOMEM, intf_init(), intf_plug_plug(), ipv6conf_dhcp_desc, ipv6conf_expired(), ipv6conf_free(), ipv6conf_job_desc, IPV6CONF_MAX_TIMEOUT, IPV6CONF_MIN_TIMEOUT, ipv6conf::job, ipv6conf::list, list_add, netdev, ipv6conf::netdev, netdev_get(), ref_init, ipv6conf::refcnt, start_timer_nodelay(), ipv6conf::timer, and zalloc().

Variable Documentation

◆ ndp_discovery

struct neighbour_discovery ndp_discovery
Initial value:
= {
.name = "NDP",
.tx_request = ndp_tx_request,
}
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.
Definition: ndp.c:126

NDP neighbour discovery protocol.

Definition at line 161 of file ndp.c.

Referenced by ndp_tx().

◆ ndp_option_handlers

struct ndp_option_handler ndp_option_handlers[]
static
Initial value:
= {
{
.option_type = NDP_OPT_LL_SOURCE,
},
{
.option_type = NDP_OPT_LL_TARGET,
},
{
.option_type = NDP_OPT_LL_SOURCE,
},
{
.option_type = NDP_OPT_PREFIX,
},
}
#define NDP_OPT_PREFIX
NDP prefix information option.
Definition: ndp.h:44
#define ICMPV6_NEIGHBOUR_SOLICITATION
ICMPv6 neighbour solicitation.
Definition: icmpv6.h:68
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.
Definition: ndp.c:206
#define NDP_OPT_LL_TARGET
NDP target link-layer address option.
Definition: ndp.h:33
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.
Definition: ndp.c:267
#define NDP_OPT_LL_SOURCE
NDP source link-layer address option.
Definition: ndp.h:30
#define ICMPV6_ROUTER_ADVERTISEMENT
ICMPv6 router advertisement.
Definition: icmpv6.h:65
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.
Definition: ndp.c:311
#define ICMPV6_NEIGHBOUR_ADVERTISEMENT
ICMPv6 neighbour advertisement.
Definition: icmpv6.h:71
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.
Definition: ndp.c:352

NDP option handlers.

Definition at line 398 of file ndp.c.

Referenced by ndp_rx_option().

◆ __icmpv6_handler

struct icmpv6_handler ndp_handlers [] __icmpv6_handler
Initial value:
= {
{
},
{
},
{
},
}
#define ICMPV6_NEIGHBOUR_SOLICITATION
ICMPv6 neighbour solicitation.
Definition: icmpv6.h:68
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.
Definition: ndp.c:546
#define ICMPV6_ROUTER_ADVERTISEMENT
ICMPv6 router advertisement.
Definition: icmpv6.h:65
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.
Definition: ndp.c:516
#define ICMPV6_NEIGHBOUR_ADVERTISEMENT
ICMPv6 neighbour advertisement.
Definition: icmpv6.h:71

NDP ICMPv6 handlers.

Definition at line 574 of file ndp.c.

◆ ndp_settings_scope

const struct settings_scope ndp_settings_scope
static

NDP settings scope.

Definition at line 622 of file ndp.c.

Referenced by ndp_applies(), and ndp_register_settings().

◆ ndp_settings_operations

struct settings_operations ndp_settings_operations
static
Initial value:
= {
.applies = ndp_applies,
.fetch = ndp_fetch,
}
static int ndp_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of NDP setting.
Definition: ndp.c:674
static int ndp_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of NDP setting.
Definition: ndp.c:689

NDP settings operations.

Definition at line 756 of file ndp.c.

Referenced by ndp_register_settings().

◆ ndp_prefix_operations

struct ndp_prefix_operation ndp_prefix_operations[]
static
Initial value:
= {
{ &ip6_setting, ndp_prefix_fetch_ip6 },
{ &len6_setting, ndp_prefix_fetch_len6 },
{ &gateway6_setting, ndp_prefix_fetch_gateway6 },
}
static int ndp_prefix_fetch_gateway6(struct settings *settings, void *data, size_t len)
Fetch value of NDP router address setting.
Definition: ndp.c:867
static int ndp_prefix_fetch_len6(struct settings *settings, void *data, size_t len)
Fetch value of NDP prefix length setting.
Definition: ndp.c:839
static int ndp_prefix_fetch_ip6(struct settings *settings, void *data, size_t len)
Fetch value of NDP IPv6 address setting.
Definition: ndp.c:782

NDP per-prefix settings operations.

Definition at line 900 of file ndp.c.

Referenced by ndp_prefix_fetch().

◆ ndp_prefix_settings_operations

struct settings_operations ndp_prefix_settings_operations
static
Initial value:
= {
.applies = ndp_prefix_applies,
.fetch = ndp_prefix_fetch,
}
static int ndp_prefix_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of NDP per-prefix setting.
Definition: ndp.c:768
static int ndp_prefix_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of NDP pre-prefix setting.
Definition: ndp.c:915

NDP per-prefix settings operations.

Definition at line 933 of file ndp.c.

Referenced by ndp_register_settings().

◆ ipv6conf_job_op

struct interface_operation ipv6conf_job_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
An IPv6 configurator.
Definition: ndp.c:1075
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
Definition: ndp.c:1134
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32

IPv6 configurator job interface operations.

Definition at line 1242 of file ndp.c.

◆ ipv6conf_job_desc

struct interface_descriptor ipv6conf_job_desc
static
Initial value:
=
static struct interface_operation ipv6conf_job_op[]
IPv6 configurator job interface operations.
Definition: ndp.c:1242
An IPv6 configurator.
Definition: ndp.c:1075
struct interface job
Job control interface.
Definition: ndp.c:1082
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

IPv6 configurator job interface descriptor.

Definition at line 1247 of file ndp.c.

Referenced by start_ipv6conf().

◆ ipv6conf_dhcp_op

struct interface_operation ipv6conf_dhcp_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
An IPv6 configurator.
Definition: ndp.c:1075
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
Definition: ndp.c:1134
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32

IPv6 configurator DHCPv6 interface operations.

Definition at line 1251 of file ndp.c.

◆ ipv6conf_dhcp_desc

struct interface_descriptor ipv6conf_dhcp_desc
static
Initial value:
=
struct interface dhcp
DHCPv6 interface.
Definition: ndp.c:1084
An IPv6 configurator.
Definition: ndp.c:1075
static struct interface_operation ipv6conf_dhcp_op[]
IPv6 configurator DHCPv6 interface operations.
Definition: ndp.c:1251
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

IPv6 configurator DHCPv6 interface descriptor.

Definition at line 1256 of file ndp.c.

Referenced by start_ipv6conf().

◆ __net_device_configurator

struct net_device_configurator ipv6_configurator __net_device_configurator
Initial value:
= {
.name = "ipv6",
.start = start_ipv6conf,
}
int start_ipv6conf(struct interface *job, struct net_device *netdev)
Start IPv6 autoconfiguration.
Definition: ndp.c:1266

IPv6 network device configurator.

Definition at line 1291 of file ndp.c.