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)
 
 FILE_SECBOOT (PERMITTED)
 
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 45 of file ndp.c.

◆ IPV6CONF_MAX_TIMEOUT

#define IPV6CONF_MAX_TIMEOUT   ( TICKS_PER_SEC * 3 )

Router discovery maximum timeout.

Definition at line 48 of file ndp.c.

◆ IPV6CONF_BLOCK_TIMEOUT

#define IPV6CONF_BLOCK_TIMEOUT   ( TICKS_PER_SEC )

Router discovery blocked link retry timeout.

Definition at line 51 of file ndp.c.

◆ IPV6CONF_MAX_DEFERRALS

#define IPV6CONF_MAX_DEFERRALS   180

Router discovery maximum number of deferrals.

Definition at line 54 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 633 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 642 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 650 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 658 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 666 of file ndp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ 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 1119 of file ndp.c.

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

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 1192 of file ndp.c.

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

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 74 of file ndp.c.

78  {
79  struct sockaddr_tcpip *st_src =
80  ( ( struct sockaddr_tcpip * ) sin6_src );
81  struct sockaddr_tcpip *st_dest =
82  ( ( struct sockaddr_tcpip * ) sin6_dest );
84  struct io_buffer *iobuf;
85  struct ndp_ll_addr_option *ll_addr_opt;
86  union ndp_header *ndp;
87  size_t option_len;
88  int rc;
89 
90  /* Allocate and populate buffer */
91  option_len = ( ( sizeof ( *ll_addr_opt ) +
93  ~( NDP_OPTION_BLKSZ - 1 ) );
94  iobuf = alloc_iob ( MAX_LL_NET_HEADER_LEN + len + option_len );
95  if ( ! iobuf )
96  return -ENOMEM;
98  memcpy ( iob_put ( iobuf, len ), data, len );
99  ll_addr_opt = iob_put ( iobuf, option_len );
100  ll_addr_opt->header.type = option_type;
101  ll_addr_opt->header.blocks = ( option_len / NDP_OPTION_BLKSZ );
102  memcpy ( ll_addr_opt->ll_addr, netdev->ll_addr,
104  ndp = iobuf->data;
105  ndp->icmp.chksum = tcpip_chksum ( ndp, ( len + option_len ) );
106 
107  /* Transmit packet */
108  if ( ( rc = tcpip_tx ( iobuf, &icmpv6_protocol, st_src, st_dest,
109  netdev, &ndp->icmp.chksum ) ) != 0 ) {
110  DBGC ( netdev, "NDP %s could not transmit packet: %s\n",
111  netdev->name, strerror ( rc ) );
112  return rc;
113  }
114 
115  return 0;
116 }
TCP/IP socket address.
Definition: tcpip.h:76
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t blocks
Length (in blocks of 8 bytes)
Definition: ndp.h:24
#define iob_put(iobuf, len)
Definition: iobuf.h:125
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:199
uint8_t type
Type.
Definition: ndp.h:22
uint8_t ll_addr[0]
Link-layer address.
Definition: ndp.h:41
struct icmp_header icmp
ICMPv6 header.
Definition: ndp.h:175
uint16_t chksum
Checksum.
Definition: icmp.h:26
#define DBGC(...)
Definition: compiler.h:505
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:131
A link-layer protocol.
Definition: netdevice.h:115
NDP source or target link-layer address option.
Definition: ndp.h:37
struct ndp_option_header header
NDP option header.
Definition: ndp.h:39
#define ENOMEM
Not enough space.
Definition: errno.h:535
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:59
ring len
Length.
Definition: dwmac.h:231
static struct net_device * netdev
Definition: gdbudp.c:52
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
An NDP header.
Definition: ndp.h:173
#define iob_reserve(iobuf, len)
Definition: iobuf.h:72
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
void * data
Start of data.
Definition: iobuf.h:53
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:388
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:92
uint16_t tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checkum.
Definition: tcpip.c:204
#define NDP_OPTION_BLKSZ
NDP option block size.
Definition: ndp.h:28
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373
A persistent I/O buffer.
Definition: iobuf.h:38

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 127 of file ndp.c.

129  {
130  struct sockaddr_in6 sin6_src;
131  struct sockaddr_in6 sin6_dest;
132  struct ndp_neighbour_header neigh;
133  int rc;
134 
135  /* Construct source address */
136  memset ( &sin6_src, 0, sizeof ( sin6_src ) );
137  sin6_src.sin6_family = AF_INET6;
138  memcpy ( &sin6_src.sin6_addr, net_source,
139  sizeof ( sin6_src.sin6_addr ) );
140 
141  /* Construct multicast destination address */
142  memset ( &sin6_dest, 0, sizeof ( sin6_dest ) );
143  sin6_dest.sin6_family = AF_INET6;
144  sin6_dest.sin6_scope_id = netdev->scope_id;
145  ipv6_solicited_node ( &sin6_dest.sin6_addr, net_dest );
146 
147  /* Construct neighbour header */
148  memset ( &neigh, 0, sizeof ( neigh ) );
149  neigh.icmp.type = ICMPV6_NEIGHBOUR_SOLICITATION;
150  memcpy ( &neigh.target, net_dest, sizeof ( neigh.target ) );
151 
152  /* Transmit neighbour discovery packet */
153  if ( ( rc = ndp_tx_ll_addr ( netdev, &sin6_src, &sin6_dest, &neigh,
154  sizeof ( neigh ),
155  NDP_OPT_LL_SOURCE ) ) != 0 )
156  return rc;
157 
158  return 0;
159 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:65
#define ICMPV6_NEIGHBOUR_SOLICITATION
ICMPv6 neighbour solicitation.
Definition: icmpv6.h:69
static void ipv6_solicited_node(struct in6_addr *addr, const struct in6_addr *unicast)
Construct solicited-node multicast address.
Definition: ipv6.h:249
unsigned int scope_id
Scope ID.
Definition: netdevice.h:361
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:31
An NDP neighbour solicitation or advertisement header.
Definition: ndp.h:116
IPv6 socket address.
Definition: in.h:118
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:74
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 173 of file ndp.c.

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

211  {
212  struct ndp_neighbour_header *neigh = &ndp->neigh;
213  struct ndp_ll_addr_option *ll_addr_opt = &option->ll_addr;
215  int rc;
216 
217  /* Silently ignore neighbour solicitations for addresses we do
218  * not own.
219  */
220  if ( ! ipv6_has_addr ( netdev, &neigh->target ) )
221  return 0;
222 
223  /* Sanity check */
224  if ( offsetof ( typeof ( *ll_addr_opt ),
225  ll_addr[ll_protocol->ll_addr_len] ) > len ) {
226  DBGC ( netdev, "NDP %s neighbour solicitation link-layer "
227  "address option too short at %zd bytes\n",
228  netdev->name, len );
229  return -EINVAL;
230  }
231 
232  /* Create or update neighbour cache entry */
233  if ( ( rc = neighbour_define ( netdev, &ipv6_protocol,
234  &sin6_src->sin6_addr,
235  ll_addr_opt->ll_addr ) ) != 0 ) {
236  DBGC ( netdev, "NDP %s could not define %s => %s: %s\n",
237  netdev->name, inet6_ntoa ( &sin6_src->sin6_addr ),
238  ll_protocol->ntoa ( ll_addr_opt->ll_addr ),
239  strerror ( rc ) );
240  return rc;
241  }
242 
243  /* Convert neighbour header to advertisement */
244  memset ( neigh, 0, offsetof ( typeof ( *neigh ), target ) );
247 
248  /* Send neighbour advertisement */
249  if ( ( rc = ndp_tx_ll_addr ( netdev, NULL, sin6_src, neigh,
250  sizeof ( *neigh ),
251  NDP_OPT_LL_TARGET ) ) != 0 )
252  return rc;
253 
254  return 0;
255 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:199
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:895
uint8_t ll_addr[0]
Link-layer address.
Definition: ndp.h:41
struct in6_addr target
Target address.
Definition: ndp.h:124
#define DBGC(...)
Definition: compiler.h:505
#define NDP_OPT_LL_TARGET
NDP target link-layer address option.
Definition: ndp.h:34
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:25
uint8_t type
Type.
Definition: icmp.h:22
A link-layer protocol.
Definition: netdevice.h:115
NDP source or target link-layer address option.
Definition: ndp.h:37
#define NDP_NEIGHBOUR_SOLICITED
NDP solicited flag.
Definition: ndp.h:133
A long option, as used for getopt_long()
Definition: getopt.h:25
ring len
Length.
Definition: dwmac.h:231
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:466
static struct net_device * netdev
Definition: gdbudp.c:52
struct icmp_header icmp
ICMPv6 header.
Definition: ndp.h:118
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
#define NDP_NEIGHBOUR_OVERRIDE
NDP override flag.
Definition: ndp.h:136
An NDP neighbour solicitation or advertisement header.
Definition: ndp.h:116
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
#define ICMPV6_NEIGHBOUR_ADVERTISEMENT
ICMPv6 neighbour advertisement.
Definition: icmpv6.h:72
int ipv6_has_addr(struct net_device *netdev, struct in6_addr *addr)
Check if network device has a specific IPv6 address.
Definition: ipv6.c:142
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:164
uint8_t flags
Flags.
Definition: ndp.h:120
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:74
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:48
struct ndp_neighbour_header neigh
Neighbour solicitation or advertisement header.
Definition: ndp.h:177
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:135
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373
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 268 of file ndp.c.

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

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 312 of file ndp.c.

315  {
316  struct ndp_ll_addr_option *ll_addr_opt = &option->ll_addr;
318  int rc;
319 
320  /* Sanity check */
321  if ( offsetof ( typeof ( *ll_addr_opt ),
322  ll_addr[ll_protocol->ll_addr_len] ) > len ) {
323  DBGC ( netdev, "NDP %s router advertisement link-layer address "
324  "option too short at %zd bytes\n", netdev->name, len );
325  return -EINVAL;
326  }
327 
328  /* Define neighbour cache entry */
329  if ( ( rc = neighbour_define ( netdev, &ipv6_protocol,
330  &sin6_src->sin6_addr,
331  ll_addr_opt->ll_addr ) ) != 0 ) {
332  DBGC ( netdev, "NDP %s could not define %s => %s: %s\n",
333  netdev->name, inet6_ntoa ( &sin6_src->sin6_addr ),
334  ll_protocol->ntoa ( ll_addr_opt->ll_addr ),
335  strerror ( rc ) );
336  return rc;
337  }
338 
339  return 0;
340 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:199
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:895
uint8_t ll_addr[0]
Link-layer address.
Definition: ndp.h:41
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:25
A link-layer protocol.
Definition: netdevice.h:115
NDP source or target link-layer address option.
Definition: ndp.h:37
A long option, as used for getopt_long()
Definition: getopt.h:25
ring len
Length.
Definition: dwmac.h:231
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:466
static struct net_device * netdev
Definition: gdbudp.c:52
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:164
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:48
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:135
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373

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 353 of file ndp.c.

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

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 432 of file ndp.c.

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

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 463 of file ndp.c.

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

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 517 of file ndp.c.

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

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 547 of file ndp.c.

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

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 675 of file ndp.c.

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

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 690 of file ndp.c.

692  {
693  struct ndp_settings *ndpset =
695  struct net_device *netdev =
697  settings.settings );
698  union ndp_option *option;
699  unsigned int tag_type;
700  unsigned int tag_offset;
701  unsigned int tag_len;
702  unsigned int tag_instance;
703  size_t offset;
704  size_t option_len;
705  void *option_data;
706 
707  /* Parse setting tag */
708  tag_type = NDP_TAG_TYPE ( setting->tag );
709  tag_offset = NDP_TAG_OFFSET ( setting->tag );
710  tag_len = NDP_TAG_LEN ( setting->tag );
711  tag_instance = NDP_TAG_INSTANCE ( setting->tag );
712 
713  /* Scan through NDP options for requested type. We can assume
714  * that the options are well-formed, otherwise they would have
715  * been rejected prior to being stored.
716  */
717  for ( offset = 0 ; offset < ndpset->len ; offset += option_len ) {
718 
719  /* Calculate option length */
720  option = ( ( ( void * ) ndpset->options ) + offset );
721  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
722 
723  /* Skip options that do not match this tag */
724  if ( option->header.type != tag_type )
725  continue;
726 
727  /* Skip previous instances of this option */
728  if ( tag_instance-- != 0 )
729  continue;
730 
731  /* Sanity check */
732  if ( ( tag_offset + tag_len ) > option_len ) {
733  DBGC ( netdev, "NDP %s option %d too short\n",
734  netdev->name, tag_type );
735  return -EINVAL;
736  }
737  if ( ! tag_len )
738  tag_len = ( option_len - tag_offset );
739  option_data = ( ( ( void * ) option ) + tag_offset );
740 
741  /* Copy data to output buffer */
742  if ( len > tag_len )
743  len = tag_len;
744  memcpy ( data, option_data, len );
745 
746  /* Default to hex if no type is specified */
747  if ( ! setting->type )
748  setting->type = &setting_type_hex;
749 
750  return tag_len;
751  }
752 
753  return -ENOENT;
754 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
#define NDP_TAG_INSTANCE(tag)
Extract NDP tag instance.
Definition: ndp.c:666
struct settings * parent
Parent settings block.
Definition: settings.h:139
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:515
#define NDP_TAG_LEN(tag)
Extract NDP tag length.
Definition: ndp.c:658
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:44
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
A long option, as used for getopt_long()
Definition: getopt.h:25
size_t len
Length of NDP options.
Definition: ndp.c:617
ring len
Length.
Definition: dwmac.h:231
static struct net_device * netdev
Definition: gdbudp.c:52
const struct setting_type * type
Setting type.
Definition: settings.h:37
#define NDP_TAG_TYPE(tag)
Extract NDP tag type.
Definition: ndp.c:642
A network device.
Definition: netdevice.h:353
A settings block.
Definition: settings.h:133
An NDP settings block.
Definition: ndp.c:607
A setting.
Definition: settings.h:24
union ndp_option options[0]
NDP options.
Definition: ndp.c:619
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
#define NDP_TAG_OFFSET(tag)
Extract NDP tag offset.
Definition: ndp.c:650
uint8_t data[48]
Additional event data.
Definition: ena.h:22
An NDP option.
Definition: ndp.h:102
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define NDP_OPTION_BLKSZ
NDP option block size.
Definition: ndp.h:28

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 769 of file ndp.c.

770  {
771 
772  return ( setting->scope == &ipv6_settings_scope );
773 }
A setting.
Definition: settings.h:24
const struct settings_scope ipv6_settings_scope
IPv6 settings scope.
Definition: ipv6.c:1121
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:50

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 783 of file ndp.c.

784  {
785  struct ndp_prefix_settings *prefset =
787  struct ndp_settings *ndpset =
789  struct net_device *netdev =
790  container_of ( ndpset->settings.parent, struct net_device,
791  settings.settings );
792  struct ndp_prefix_information_option *prefix = prefset->prefix;
793  struct in6_addr *ip6 = &prefix->prefix;
794  struct in6_addr slaac;
795  int prefix_len;
796  int rc;
797 
798  /* Skip dead prefixes */
799  if ( ! prefix->valid )
800  return -ENOENT;
801 
802  /* Construct IPv6 address via SLAAC, if applicable */
803  if ( prefix->flags & NDP_PREFIX_AUTONOMOUS ) {
804  memcpy ( &slaac, ip6, sizeof ( slaac ) );
805  prefix_len = ipv6_eui64 ( &slaac, netdev );
806  if ( prefix_len == prefix->prefix_len ) {
807  /* Correctly configured prefix: use SLAAC address */
808  ip6 = &slaac;
809  } else if ( prefix_len < 0 ) {
810  /* Link layer does not support SLAAC */
811  rc = prefix_len;
812  DBGC ( netdev, "NDP %s does not support SLAAC: %s\n",
813  netdev->name, strerror ( rc ) );
814  } else {
815  /* Prefix length incorrect: assume a badly
816  * configured router and ignore SLAAC address.
817  */
818  DBGC ( netdev, "NDP %s ignoring misconfigured SLAAC "
819  "on prefix %s/%d\n", netdev->name,
820  inet6_ntoa ( ip6 ), prefix->prefix_len );
821  }
822  }
823 
824  /* Fill in IPv6 address */
825  if ( len > sizeof ( *ip6 ) )
826  len = sizeof ( *ip6 );
827  memcpy ( data, ip6, len );
828 
829  return sizeof ( *ip6 );
830 }
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:895
struct settings * parent
Parent settings block.
Definition: settings.h:139
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:515
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:36
ring len
Length.
Definition: dwmac.h:231
NDP prefix information.
Definition: ndp.h:48
static struct net_device * netdev
Definition: gdbudp.c:52
IP6 address structure.
Definition: in.h:51
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
A network device.
Definition: netdevice.h:353
struct ndp_prefix_information_option * prefix
Prefix information option.
Definition: ndp.c:603
A settings block.
Definition: settings.h:133
An NDP settings block.
Definition: ndp.c:607
An NDP prefix settings block.
Definition: ndp.c:597
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
struct settings settings
Settings interface.
Definition: ndp.c:611
#define NDP_PREFIX_AUTONOMOUS
NDP autonomous address configuration flag.
Definition: ndp.h:69
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:217

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 840 of file ndp.c.

841  {
842  struct ndp_prefix_settings *prefset =
844  struct ndp_prefix_information_option *prefix = prefset->prefix;
845  uint8_t *len6;
846 
847  /* Fill in prefix length */
848  if ( len >= sizeof ( *len6 ) ) {
849  /* We treat an off-link prefix as having a prefix
850  * length covering the entire IPv6 address.
851  */
852  len6 = data;
853  *len6 = ( ( prefix->flags & NDP_PREFIX_ON_LINK ) ?
854  prefix->prefix_len : -1UL );
855  }
856 
857  return sizeof ( *len6 );
858 }
char prefix[4]
Definition: vmconsole.c:53
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
ring len
Length.
Definition: dwmac.h:231
NDP prefix information.
Definition: ndp.h:48
#define NDP_PREFIX_ON_LINK
NDP on-link flag.
Definition: ndp.h:66
struct ndp_prefix_information_option * prefix
Prefix information option.
Definition: ndp.c:603
A settings block.
Definition: settings.h:133
unsigned char uint8_t
Definition: stdint.h:10
An NDP prefix settings block.
Definition: ndp.c:597
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 868 of file ndp.c.

869  {
870  struct ndp_settings *ndpset =
872 
873  /* Treat non-routing router as non-existent */
874  if ( ! ndpset->lifetime )
875  return -ENOENT;
876 
877  /* Fill in router address */
878  if ( len > sizeof ( ndpset->router ) )
879  len = sizeof ( ndpset->router );
880  memcpy ( data, &ndpset->router, len );
881 
882  return sizeof ( ndpset->router );
883 }
unsigned int lifetime
Router lifetime.
Definition: ndp.c:615
struct settings * parent
Parent settings block.
Definition: settings.h:139
#define ENOENT
No such file or directory.
Definition: errno.h:515
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
ring len
Length.
Definition: dwmac.h:231
A settings block.
Definition: settings.h:133
An NDP settings block.
Definition: ndp.c:607
struct in6_addr router
Router address.
Definition: ndp.c:613
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 916 of file ndp.c.

918  {
919  struct ndp_prefix_operation *op;
920  unsigned int i;
921 
922  /* Handle per-prefix settings */
923  for ( i = 0 ; i < ( sizeof ( ndp_prefix_operations ) /
924  sizeof ( ndp_prefix_operations[0] ) ) ; i++ ) {
926  if ( setting_cmp ( setting, op->setting ) == 0 )
927  return op->fetch ( settings, data, len );
928  }
929 
930  return -ENOENT;
931 }
An NDP per-prefix setting operation.
Definition: ndp.c:886
#define ENOENT
No such file or directory.
Definition: errno.h:515
ring len
Length.
Definition: dwmac.h:231
A settings block.
Definition: settings.h:133
A setting.
Definition: settings.h:24
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:901
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:1121

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 949 of file ndp.c.

952  {
953  struct settings *parent = netdev_settings ( netdev );
954  union ndp_option *option;
955  struct ndp_settings *ndpset;
956  struct ndp_prefix_settings *prefset;
957  size_t offset;
958  size_t option_len;
959  unsigned int prefixes;
960  unsigned int instance;
961  int order;
962  int rc;
963 
964  /* Count number of prefix options. We can assume that the
965  * options are well-formed, otherwise they would have been
966  * rejected prior to being stored.
967  */
968  order = IPV6_ORDER_PREFIX_ONLY;
969  for ( prefixes = 0, offset = 0 ; offset < len ; offset += option_len ) {
970 
971  /* Skip non-prefix options */
972  option = ( ( ( void * ) options ) + offset );
973  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
974  if ( option->header.type != NDP_OPT_PREFIX )
975  continue;
976 
977  /* Count number of prefixes */
978  prefixes++;
979 
980  /* Increase overall order if we have SLAAC addresses */
981  if ( option->prefix.flags & NDP_PREFIX_AUTONOMOUS )
982  order = IPV6_ORDER_SLAAC;
983  }
984 
985  /* Allocate and initialise structure */
986  ndpset = zalloc ( sizeof ( *ndpset ) + len +
987  ( prefixes * sizeof ( *prefset ) ) );
988  if ( ! ndpset ) {
989  rc = -ENOMEM;
990  goto err_alloc;
991  }
992  ref_init ( &ndpset->refcnt, NULL );
994  &ndpset->refcnt, &ndp_settings_scope );
995  ndpset->settings.order = order;
996  memcpy ( &ndpset->router, router, sizeof ( ndpset->router ) );
997  ndpset->lifetime = lifetime;
998  ndpset->len = len;
999  memcpy ( ndpset->options, options, len );
1000  prefset = ( ( ( void * ) ndpset->options ) + len );
1001 
1002  /* Register settings */
1003  if ( ( rc = register_settings ( &ndpset->settings, parent,
1004  NDP_SETTINGS_NAME ) ) != 0 )
1005  goto err_register;
1006 
1007  /* Construct and register per-prefix settings */
1008  for ( instance = 0, offset = 0 ; offset < len ; offset += option_len ) {
1009 
1010  /* Skip non-prefix options */
1011  option = ( ( ( void * ) ndpset->options ) + offset );
1012  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
1013  if ( option->header.type != NDP_OPT_PREFIX )
1014  continue;
1015 
1016  /* Initialise structure */
1017  settings_init ( &prefset->settings,
1019  &ndpset->refcnt, &ndp_settings_scope );
1020  prefset->settings.order =
1021  ( ( option->prefix.flags & NDP_PREFIX_AUTONOMOUS ) ?
1023  prefset->prefix = &option->prefix;
1024  snprintf ( prefset->name, sizeof ( prefset->name ), "%d",
1025  instance++ );
1026 
1027  /* Register settings */
1028  if ( ( rc = register_settings ( &prefset->settings,
1029  &ndpset->settings,
1030  prefset->name ) ) != 0 )
1031  goto err_register_prefix;
1032 
1033  /* Move to next per-prefix settings */
1034  prefset++;
1035  }
1036  assert ( instance == prefixes );
1037 
1038  ref_put ( &ndpset->refcnt );
1039  return 0;
1040 
1041  err_register_prefix:
1042  unregister_settings ( &ndpset->settings );
1043  err_register:
1044  ref_put ( &ndpset->refcnt );
1045  err_alloc:
1046  return rc;
1047 }
#define NDP_OPT_PREFIX
NDP prefix information option.
Definition: ndp.h:45
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define NDP_SETTINGS_NAME
NDP settings block name.
Definition: ndp.h:203
unsigned int lifetime
Router lifetime.
Definition: ndp.c:615
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition: settings.c:515
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
struct settings * parent
Parent settings block.
Definition: settings.h:139
static struct settings_operations ndp_settings_operations
NDP settings operations.
Definition: ndp.c:757
static const struct settings_scope ndp_settings_scope
NDP settings scope.
Definition: ndp.c:623
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:587
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:503
static struct settings_operations ndp_prefix_settings_operations
NDP per-prefix settings operations.
Definition: ndp.c:934
#define ENOMEM
Not enough space.
Definition: errno.h:535
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:25
static int options
Definition: 3c515.c:286
size_t len
Length of NDP options.
Definition: ndp.c:617
ring len
Length.
Definition: dwmac.h:231
static struct net_device * netdev
Definition: gdbudp.c:52
Address assigned via SLAAC.
Definition: ipv6.h:287
struct refcnt refcnt
Reference counter.
Definition: ndp.c:609
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
struct ndp_prefix_information_option * prefix
Prefix information option.
Definition: ndp.c:603
A settings block.
Definition: settings.h:133
u32 lifetime
For Lifetime-type KDEs, the lifetime in seconds.
Definition: wpa.h:54
An NDP settings block.
Definition: ndp.c:607
char name[4]
Name.
Definition: ndp.c:601
An NDP prefix settings block.
Definition: ndp.c:597
struct in6_addr router
Router address.
Definition: ndp.c:613
int order
Sibling ordering.
Definition: settings.h:149
union ndp_option options[0]
NDP options.
Definition: ndp.c:619
struct settings settings
Settings interface.
Definition: ndp.c:611
#define NDP_PREFIX_AUTONOMOUS
NDP autonomous address configuration flag.
Definition: ndp.h:69
No address.
Definition: ipv6.h:283
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:476
An NDP option.
Definition: ndp.h:102
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define NDP_OPTION_BLKSZ
NDP option block size.
Definition: ndp.h:28
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct settings settings
Settings interface.
Definition: ndp.c:599
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107

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 1105 of file ndp.c.

1105  {
1106  struct ipv6conf *ipv6conf =
1107  container_of ( refcnt, struct ipv6conf, refcnt );
1108 
1109  netdev_put ( ipv6conf->netdev );
1110  free ( ipv6conf );
1111 }
A reference counter.
Definition: refcnt.h:27
An IPv6 configurator.
Definition: ndp.c:1076
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:576
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1088
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55

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 1135 of file ndp.c.

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

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 1155 of file ndp.c.

1155  {
1156  struct ipv6conf *ipv6conf =
1157  container_of ( timer, struct ipv6conf, timer );
1158  struct net_device *netdev = ipv6conf->netdev;
1159 
1160  /* If we have failed, terminate autoconfiguration */
1161  if ( fail ) {
1163  return;
1164  }
1165 
1166  /* Otherwise, transmit router solicitation and restart timer */
1167  start_timer ( &ipv6conf->timer );
1169 
1170  /* If link is blocked, defer router discovery timeout */
1171  if ( netdev_link_blocked ( netdev ) &&
1173  DBGC ( netdev, "NDP %s deferring discovery timeout\n",
1174  netdev->name );
1176  }
1177 }
static int ndp_tx_router_solicitation(struct net_device *netdev)
Transmit NDP router solicitation.
Definition: ndp.c:173
#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:651
A timer.
Definition: timer.h:29
An IPv6 configurator.
Definition: ndp.c:1076
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
Definition: ndp.c:1135
static struct net_device * netdev
Definition: gdbudp.c:52
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1088
A network device.
Definition: netdevice.h:353
struct retry_timer timer
Retransmission timer.
Definition: ndp.c:1091
#define IPV6CONF_BLOCK_TIMEOUT
Router discovery blocked link retry timeout.
Definition: ndp.c:51
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:94
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:65
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
unsigned int deferred
Deferred discovery counter.
Definition: ndp.c:1094
#define IPV6CONF_MAX_DEFERRALS
Router discovery maximum number of deferrals.
Definition: ndp.c:54
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:670

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 1267 of file ndp.c.

1267  {
1268  struct ipv6conf *ipv6conf;
1269 
1270  /* Allocate and initialise structure */
1271  ipv6conf = zalloc ( sizeof ( *ipv6conf ) );
1272  if ( ! ipv6conf )
1273  return -ENOMEM;
1277  timer_init ( &ipv6conf->timer, ipv6conf_expired, &ipv6conf->refcnt );
1278  set_timer_limits ( &ipv6conf->timer, IPV6CONF_MIN_TIMEOUT,
1281 
1282  /* Start timer to initiate router solicitation */
1284 
1285  /* Attach parent interface, transfer reference to list, and return */
1286  intf_plug_plug ( &ipv6conf->job, job );
1287  list_add ( &ipv6conf->list, &ipv6confs );
1288  return 0;
1289 }
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:100
static void ipv6conf_expired(struct retry_timer *timer, int fail)
Handle IPv6 configurator timer expiry.
Definition: ndp.c:1155
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:70
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
struct refcnt refcnt
Reference count.
Definition: ndp.c:1078
struct interface dhcp
DHCPv6 interface.
Definition: ndp.c:1085
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:108
static void ipv6conf_free(struct refcnt *refcnt)
Free IPv6 configurator.
Definition: ndp.c:1105
#define ENOMEM
Not enough space.
Definition: errno.h:535
An IPv6 configurator.
Definition: ndp.c:1076
static struct net_device * netdev
Definition: gdbudp.c:52
struct list_head list
List of configurators.
Definition: ndp.c:1080
#define IPV6CONF_MAX_TIMEOUT
Router discovery maximum timeout.
Definition: ndp.c:48
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1088
struct interface job
Job control interface.
Definition: ndp.c:1083
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:565
struct retry_timer timer
Retransmission timer.
Definition: ndp.c:1091
#define IPV6CONF_MIN_TIMEOUT
Router discovery minimum timeout.
Definition: ndp.c:45
static struct interface_descriptor ipv6conf_job_desc
IPv6 configurator job interface descriptor.
Definition: ndp.c:1248
static struct interface_descriptor ipv6conf_dhcp_desc
IPv6 configurator DHCPv6 interface descriptor.
Definition: ndp.c:1257
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204

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

NDP neighbour discovery protocol.

Definition at line 162 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:45
#define ICMPV6_NEIGHBOUR_SOLICITATION
ICMPv6 neighbour solicitation.
Definition: icmpv6.h:69
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:207
#define NDP_OPT_LL_TARGET
NDP target link-layer address option.
Definition: ndp.h:34
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:268
#define NDP_OPT_LL_SOURCE
NDP source link-layer address option.
Definition: ndp.h:31
#define ICMPV6_ROUTER_ADVERTISEMENT
ICMPv6 router advertisement.
Definition: icmpv6.h:66
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:312
#define ICMPV6_NEIGHBOUR_ADVERTISEMENT
ICMPv6 neighbour advertisement.
Definition: icmpv6.h:72
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:353

NDP option handlers.

Definition at line 399 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:69
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:547
#define ICMPV6_ROUTER_ADVERTISEMENT
ICMPv6 router advertisement.
Definition: icmpv6.h:66
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:517
#define ICMPV6_NEIGHBOUR_ADVERTISEMENT
ICMPv6 neighbour advertisement.
Definition: icmpv6.h:72

NDP ICMPv6 handlers.

Definition at line 575 of file ndp.c.

◆ ndp_settings_scope

const struct settings_scope ndp_settings_scope
static

NDP settings scope.

Definition at line 623 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:675
static int ndp_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of NDP setting.
Definition: ndp.c:690

NDP settings operations.

Definition at line 757 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:868
static int ndp_prefix_fetch_len6(struct settings *settings, void *data, size_t len)
Fetch value of NDP prefix length setting.
Definition: ndp.c:840
static int ndp_prefix_fetch_ip6(struct settings *settings, void *data, size_t len)
Fetch value of NDP IPv6 address setting.
Definition: ndp.c:783

NDP per-prefix settings operations.

Definition at line 901 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:769
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:916

NDP per-prefix settings operations.

Definition at line 934 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:250
An IPv6 configurator.
Definition: ndp.c:1076
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
Definition: ndp.c:1135
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33

IPv6 configurator job interface operations.

Definition at line 1243 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:1243
An IPv6 configurator.
Definition: ndp.c:1076
struct interface job
Job control interface.
Definition: ndp.c:1083
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81

IPv6 configurator job interface descriptor.

Definition at line 1248 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:250
An IPv6 configurator.
Definition: ndp.c:1076
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
Definition: ndp.c:1135
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33

IPv6 configurator DHCPv6 interface operations.

Definition at line 1252 of file ndp.c.

◆ ipv6conf_dhcp_desc

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

IPv6 configurator DHCPv6 interface descriptor.

Definition at line 1257 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:1267

IPv6 network device configurator.

Definition at line 1292 of file ndp.c.