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/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 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

◆ 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 619 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 628 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 636 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 644 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 652 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 1088 of file ndp.c.

1088  {
1089  struct ipv6conf *ipv6conf;
1090 
1091  list_for_each_entry ( ipv6conf, &ipv6confs, list ) {
1092  if ( ipv6conf->netdev == netdev )
1093  return ipv6conf;
1094  }
1095  return NULL;
1096 }
An IPv6 configurator.
Definition: ndp.c:1048
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
static struct net_device * netdev
Definition: gdbudp.c:52
struct list_head list
List of configurators.
Definition: ndp.c:1052
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1060
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

1155  {
1156  struct ipv6conf *ipv6conf;
1157  size_t option_len;
1158  int stateful;
1159  int rc;
1160 
1161  /* Identify IPv6 configurator, if any */
1163 
1164  /* Do nothing unless IPv6 autoconfiguration is in progress */
1165  if ( ! ipv6conf )
1166  return 0;
1167 
1168  /* If this is not the first solicited router advertisement, ignore it */
1169  if ( ! timer_running ( &ipv6conf->timer ) )
1170  return 0;
1171 
1172  /* Stop router solicitation timer */
1173  stop_timer ( &ipv6conf->timer );
1174 
1175  /* Register NDP settings */
1176  option_len = ( len - offsetof ( typeof ( *radv ), option ) );
1177  if ( ( rc = ndp_register_settings ( netdev, router,
1178  ntohl ( radv->lifetime ),
1179  radv->option, option_len ) ) != 0 )
1180  return rc;
1181 
1182  /* Start DHCPv6 if required */
1183  if ( radv->flags & ( NDP_ROUTER_MANAGED | NDP_ROUTER_OTHER ) ) {
1184  stateful = ( radv->flags & NDP_ROUTER_MANAGED );
1185  if ( ( rc = start_dhcpv6 ( &ipv6conf->dhcp, netdev,
1186  stateful ) ) != 0 ) {
1187  DBGC ( netdev, "NDP %s could not start state%s DHCPv6: "
1188  "%s\n", netdev->name,
1189  ( stateful ? "ful" : "less" ), strerror ( rc ) );
1190  ipv6conf_done ( ipv6conf, rc );
1191  return rc;
1192  }
1193  return 0;
1194  }
1195 
1196  /* Otherwise, terminate autoconfiguration */
1197  ipv6conf_done ( ipv6conf, 0 );
1198 
1199  return 0;
1200 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct interface dhcp
DHCPv6 interface.
Definition: ndp.c:1057
#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:1048
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
Definition: ndp.c:1104
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:1088
struct retry_timer timer
Retransmission timer.
Definition: ndp.c:1063
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:358
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:921
union ndp_option option[0]
Options.
Definition: ndp.h:152
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(), and ipv6conf::timer.

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

64  {
65  struct sockaddr_tcpip *st_src =
66  ( ( struct sockaddr_tcpip * ) sin6_src );
67  struct sockaddr_tcpip *st_dest =
68  ( ( struct sockaddr_tcpip * ) sin6_dest );
70  struct io_buffer *iobuf;
71  struct ndp_ll_addr_option *ll_addr_opt;
72  union ndp_header *ndp;
73  size_t option_len;
74  int rc;
75 
76  /* Allocate and populate buffer */
77  option_len = ( ( sizeof ( *ll_addr_opt ) +
79  ~( NDP_OPTION_BLKSZ - 1 ) );
80  iobuf = alloc_iob ( MAX_LL_NET_HEADER_LEN + len + option_len );
81  if ( ! iobuf )
82  return -ENOMEM;
84  memcpy ( iob_put ( iobuf, len ), data, len );
85  ll_addr_opt = iob_put ( iobuf, option_len );
86  ll_addr_opt->header.type = option_type;
87  ll_addr_opt->header.blocks = ( option_len / NDP_OPTION_BLKSZ );
88  memcpy ( ll_addr_opt->ll_addr, netdev->ll_addr,
90  ndp = iobuf->data;
91  ndp->icmp.chksum = tcpip_chksum ( ndp, ( len + option_len ) );
92 
93  /* Transmit packet */
94  if ( ( rc = tcpip_tx ( iobuf, &icmpv6_protocol, st_src, st_dest,
95  netdev, &ndp->icmp.chksum ) ) != 0 ) {
96  DBGC ( netdev, "NDP %s could not transmit packet: %s\n",
97  netdev->name, strerror ( rc ) );
98  return rc;
99  }
100 
101  return 0;
102 }
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:116
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:128
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:63
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:44
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:381
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:366
A persistent I/O buffer.
Definition: iobuf.h:32

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

115  {
116  struct sockaddr_in6 sin6_src;
117  struct sockaddr_in6 sin6_dest;
118  struct ndp_neighbour_header neigh;
119  int rc;
120 
121  /* Construct source address */
122  memset ( &sin6_src, 0, sizeof ( sin6_src ) );
123  sin6_src.sin6_family = AF_INET6;
124  memcpy ( &sin6_src.sin6_addr, net_source,
125  sizeof ( sin6_src.sin6_addr ) );
126 
127  /* Construct multicast destination address */
128  memset ( &sin6_dest, 0, sizeof ( sin6_dest ) );
129  sin6_dest.sin6_family = AF_INET6;
130  sin6_dest.sin6_scope_id = netdev->index;
131  ipv6_solicited_node ( &sin6_dest.sin6_addr, net_dest );
132 
133  /* Construct neighbour header */
134  memset ( &neigh, 0, sizeof ( neigh ) );
135  neigh.icmp.type = ICMPV6_NEIGHBOUR_SOLICITATION;
136  memcpy ( &neigh.target, net_dest, sizeof ( neigh.target ) );
137 
138  /* Transmit neighbour discovery packet */
139  if ( ( rc = ndp_tx_ll_addr ( netdev, &sin6_src, &sin6_dest, &neigh,
140  sizeof ( neigh ),
141  NDP_OPT_LL_SOURCE ) ) != 0 )
142  return rc;
143 
144  return 0;
145 }
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
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
unsigned int index
Index of this network device.
Definition: netdevice.h:356
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:60
void * memset(void *dest, int character, size_t len) __nonnull

References AF_INET6, ndp_neighbour_header::icmp, ICMPV6_NEIGHBOUR_SOLICITATION, net_device::index, ipv6_solicited_node(), memcpy(), memset(), NDP_OPT_LL_SOURCE, ndp_tx_ll_addr(), netdev, rc, 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 159 of file ndp.c.

159  {
160  struct ndp_router_solicitation_header rsol;
161  struct sockaddr_in6 sin6_dest;
162  int rc;
163 
164  /* Construct multicast destination address */
165  memset ( &sin6_dest, 0, sizeof ( sin6_dest ) );
166  sin6_dest.sin6_family = AF_INET6;
167  sin6_dest.sin6_scope_id = netdev->index;
168  ipv6_all_routers ( &sin6_dest.sin6_addr );
169 
170  /* Construct router solicitation */
171  memset ( &rsol, 0, sizeof ( rsol ) );
172  rsol.icmp.type = ICMPV6_ROUTER_SOLICITATION;
173 
174  /* Transmit packet */
175  if ( ( rc = ndp_tx_ll_addr ( netdev, NULL, &sin6_dest, &rsol,
176  sizeof ( rsol ), NDP_OPT_LL_SOURCE ) ) !=0)
177  return rc;
178 
179  return 0;
180 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
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
unsigned int index
Index of this network device.
Definition: netdevice.h:356
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:60
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
void * memset(void *dest, int character, size_t len) __nonnull

References AF_INET6, ndp_router_solicitation_header::icmp, ICMPV6_ROUTER_SOLICITATION, net_device::index, ipv6_all_routers(), memset(), NDP_OPT_LL_SOURCE, ndp_tx_ll_addr(), netdev, NULL, rc, 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 193 of file ndp.c.

197  {
198  struct ndp_neighbour_header *neigh = &ndp->neigh;
199  struct ndp_ll_addr_option *ll_addr_opt = &option->ll_addr;
201  int rc;
202 
203  /* Silently ignore neighbour solicitations for addresses we do
204  * not own.
205  */
206  if ( ! ipv6_has_addr ( netdev, &neigh->target ) )
207  return 0;
208 
209  /* Sanity check */
210  if ( offsetof ( typeof ( *ll_addr_opt ),
211  ll_addr[ll_protocol->ll_addr_len] ) > len ) {
212  DBGC ( netdev, "NDP %s neighbour solicitation link-layer "
213  "address option too short at %zd bytes\n",
214  netdev->name, len );
215  return -EINVAL;
216  }
217 
218  /* Create or update neighbour cache entry */
219  if ( ( rc = neighbour_define ( netdev, &ipv6_protocol,
220  &sin6_src->sin6_addr,
221  ll_addr_opt->ll_addr ) ) != 0 ) {
222  DBGC ( netdev, "NDP %s could not define %s => %s: %s\n",
223  netdev->name, inet6_ntoa ( &sin6_src->sin6_addr ),
224  ll_protocol->ntoa ( ll_addr_opt->ll_addr ),
225  strerror ( rc ) );
226  return rc;
227  }
228 
229  /* Convert neighbour header to advertisement */
230  memset ( neigh, 0, offsetof ( typeof ( *neigh ), target ) );
233 
234  /* Send neighbour advertisement */
235  if ( ( rc = ndp_tx_ll_addr ( netdev, NULL, sin6_src, neigh,
236  sizeof ( *neigh ),
237  NDP_OPT_LL_TARGET ) ) != 0 )
238  return rc;
239 
240  return 0;
241 }
#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:358
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:60
struct ndp_neighbour_header neigh
Neighbour solicitation or advertisement header.
Definition: ndp.h:176
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:132
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:366
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, and icmp_header::type.

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

259  {
260  struct ndp_neighbour_header *neigh = &ndp->neigh;
261  struct ndp_ll_addr_option *ll_addr_opt = &option->ll_addr;
263  int rc;
264 
265  /* Sanity check */
266  if ( offsetof ( typeof ( *ll_addr_opt ),
267  ll_addr[ll_protocol->ll_addr_len] ) > len ) {
268  DBGC ( netdev, "NDP %s neighbour advertisement link-layer "
269  "address option too short at %zd bytes\n",
270  netdev->name, len );
271  return -EINVAL;
272  }
273 
274  /* Update neighbour cache entry, if any */
275  if ( ( rc = neighbour_update ( netdev, &ipv6_protocol, &neigh->target,
276  ll_addr_opt->ll_addr ) ) != 0 ) {
277  DBGC ( netdev, "NDP %s could not update %s => %s: %s\n",
278  netdev->name, inet6_ntoa ( &neigh->target ),
279  ll_protocol->ntoa ( ll_addr_opt->ll_addr ),
280  strerror ( rc ) );
281  return rc;
282  }
283 
284  return 0;
285 }
#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:358
uint32_t len
Length.
Definition: ena.h:14
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
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:366

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(), and ndp_neighbour_header::target.

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

301  {
302  struct ndp_ll_addr_option *ll_addr_opt = &option->ll_addr;
304  int rc;
305 
306  /* Sanity check */
307  if ( offsetof ( typeof ( *ll_addr_opt ),
308  ll_addr[ll_protocol->ll_addr_len] ) > len ) {
309  DBGC ( netdev, "NDP %s router advertisement link-layer address "
310  "option too short at %zd bytes\n", netdev->name, len );
311  return -EINVAL;
312  }
313 
314  /* Define neighbour cache entry */
315  if ( ( rc = neighbour_define ( netdev, &ipv6_protocol,
316  &sin6_src->sin6_addr,
317  ll_addr_opt->ll_addr ) ) != 0 ) {
318  DBGC ( netdev, "NDP %s could not define %s => %s: %s\n",
319  netdev->name, inet6_ntoa ( &sin6_src->sin6_addr ),
320  ll_protocol->ntoa ( ll_addr_opt->ll_addr ),
321  strerror ( rc ) );
322  return rc;
323  }
324 
325  return 0;
326 }
#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:358
uint32_t len
Length.
Definition: ena.h:14
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:132
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:366

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, and strerror().

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

342  {
343  struct ndp_router_advertisement_header *radv = &ndp->radv;
344  struct ndp_prefix_information_option *prefix_opt = &option->prefix;
345 
346  /* Sanity check */
347  if ( sizeof ( *prefix_opt ) > len ) {
348  DBGC ( netdev, "NDP %s router advertisement prefix option too "
349  "short at %zd bytes\n", netdev->name, len );
350  return -EINVAL;
351  }
352 
353  DBGC ( netdev, "NDP %s found %sdefault router %s ",
354  netdev->name, ( radv->lifetime ? "" : "non-" ),
355  inet6_ntoa ( &sin6_src->sin6_addr ) );
356  DBGC ( netdev, "for %s-link %sautonomous prefix %s/%d\n",
357  ( ( prefix_opt->flags & NDP_PREFIX_ON_LINK ) ? "on" : "off" ),
358  ( ( prefix_opt->flags & NDP_PREFIX_AUTONOMOUS ) ? "" : "non-" ),
359  inet6_ntoa ( &prefix_opt->prefix ), prefix_opt->prefix_len );
360 
361  return 0;
362 }
#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:358
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 418 of file ndp.c.

420  {
421  struct ndp_option_handler *handler;
422  unsigned int i;
423 
424  /* Locate a suitable option handler, if any */
425  for ( i = 0 ; i < ( sizeof ( ndp_option_handlers ) /
426  sizeof ( ndp_option_handlers[0] ) ) ; i++ ) {
427  handler = &ndp_option_handlers[i];
428  if ( ( handler->icmp_type == ndp->icmp.type ) &&
429  ( handler->option_type == option->header.type ) ) {
430  return handler->rx ( netdev, sin6_src, ndp,
431  option, len );
432  }
433  }
434 
435  /* Silently ignore unknown options as per RFC 4861 */
436  return 0;
437 }
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:379
uint8_t icmp_type
ICMPv6 type.
Definition: ndp.c:367
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:369
An NDP option handler.
Definition: ndp.c:365
static struct ndp_option_handler ndp_option_handlers[]
NDP option handlers.
Definition: ndp.c:385
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 449 of file ndp.c.

451  {
452  union ndp_option *option;
453  size_t remaining;
454  size_t option_len;
455  int rc;
456 
457  /* Sanity check */
458  if ( len < offset ) {
459  DBGC ( netdev, "NDP %s packet too short at %zd bytes (min %zd "
460  "bytes)\n", netdev->name, len, offset );
461  return -EINVAL;
462  }
463 
464  /* Search for option */
465  option = ( ( ( void * ) ndp ) + offset );
466  remaining = ( len - offset );
467  while ( remaining ) {
468 
469  /* Sanity check */
470  if ( ( remaining < sizeof ( option->header ) ) ||
471  ( option->header.blocks == 0 ) ||
472  ( remaining < ( option->header.blocks *
473  NDP_OPTION_BLKSZ ) ) ) {
474  DBGC ( netdev, "NDP %s bad option length:\n",
475  netdev->name );
476  DBGC_HDA ( netdev, 0, option, remaining );
477  return -EINVAL;
478  }
479  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
480 
481  /* Handle option */
482  if ( ( rc = ndp_rx_option ( netdev, sin6_src, ndp, option,
483  option_len ) ) != 0 )
484  return rc;
485 
486  /* Move to next option */
487  option = ( ( ( void * ) option ) + option_len );
488  remaining -= option_len;
489  }
490 
491  return 0;
492 }
#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:418
#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:358
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 503 of file ndp.c.

506  {
507  union ndp_header *ndp = iobuf->data;
508  struct ndp_neighbour_header *neigh = &ndp->neigh;
509  size_t len = iob_len ( iobuf );
510  int rc;
511 
512  /* Process options */
513  if ( ( rc = ndp_rx_options ( netdev, sin6_src, ndp,
514  offsetof ( typeof ( *neigh ), option ),
515  len ) ) != 0 )
516  goto err_options;
517 
518  err_options:
519  free_iob ( iobuf );
520  return rc;
521 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#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:449
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
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:44
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, and rc.

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

536  {
537  union ndp_header *ndp = iobuf->data;
538  struct ndp_router_advertisement_header *radv = &ndp->radv;
539  struct in6_addr *router = &sin6_src->sin6_addr;
540  size_t len = iob_len ( iobuf );
541  int rc;
542 
543  /* Process options */
544  if ( ( rc = ndp_rx_options ( netdev, sin6_src, ndp,
545  offsetof ( typeof ( *radv ), option ),
546  len ) ) != 0 )
547  goto err_options;
548 
549  /* Pass to IPv6 autoconfiguration */
550  if ( ( rc = ipv6conf_rx_router_advertisement ( netdev, router,
551  radv, len ) ) != 0 )
552  goto err_ipv6conf;
553 
554  err_ipv6conf:
555  err_options:
556  free_iob ( iobuf );
557  return rc;
558 }
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:1152
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#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:449
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
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:44
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, and sockaddr_in6::sin6_addr.

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

662  {
663 
664  return ( setting->scope == &ndp_settings_scope );
665 }
static const struct settings_scope ndp_settings_scope
NDP settings scope.
Definition: ndp.c:609
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 676 of file ndp.c.

678  {
679  struct ndp_settings *ndpset =
681  struct net_device *netdev =
683  settings.settings );
684  union ndp_option *option;
685  unsigned int tag_type;
686  unsigned int tag_offset;
687  unsigned int tag_len;
688  unsigned int tag_instance;
689  size_t offset;
690  size_t option_len;
691  void *option_data;
692 
693  /* Parse setting tag */
694  tag_type = NDP_TAG_TYPE ( setting->tag );
695  tag_offset = NDP_TAG_OFFSET ( setting->tag );
696  tag_len = NDP_TAG_LEN ( setting->tag );
697  tag_instance = NDP_TAG_INSTANCE ( setting->tag );
698 
699  /* Scan through NDP options for requested type. We can assume
700  * that the options are well-formed, otherwise they would have
701  * been rejected prior to being stored.
702  */
703  for ( offset = 0 ; offset < ndpset->len ; offset += option_len ) {
704 
705  /* Calculate option length */
706  option = ( ( ( void * ) ndpset->options ) + offset );
707  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
708 
709  /* Skip options that do not match this tag */
710  if ( option->header.type != tag_type )
711  continue;
712 
713  /* Skip previous instances of this option */
714  if ( tag_instance-- != 0 )
715  continue;
716 
717  /* Sanity check */
718  if ( ( tag_offset + tag_len ) > option_len ) {
719  DBGC ( netdev, "NDP %s option %d too short\n",
720  netdev->name, tag_type );
721  return -EINVAL;
722  }
723  if ( ! tag_len )
724  tag_len = ( option_len - tag_offset );
725  option_data = ( ( ( void * ) option ) + tag_offset );
726 
727  /* Copy data to output buffer */
728  if ( len > tag_len )
729  len = tag_len;
730  memcpy ( data, option_data, len );
731 
732  /* Default to hex if no type is specified */
733  if ( ! setting->type )
734  setting->type = &setting_type_hex;
735 
736  return tag_len;
737  }
738 
739  return -ENOENT;
740 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define NDP_TAG_INSTANCE(tag)
Extract NDP tag instance.
Definition: ndp.c:652
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:644
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:603
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:628
A network device.
Definition: netdevice.h:348
A settings block.
Definition: settings.h:132
An NDP settings block.
Definition: ndp.c:593
A setting.
Definition: settings.h:23
union ndp_option options[0]
NDP options.
Definition: ndp.c:605
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
uint32_t len
Length.
Definition: ena.h:14
#define NDP_TAG_OFFSET(tag)
Extract NDP tag offset.
Definition: ndp.c:636
An NDP option.
Definition: ndp.h:101
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#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 755 of file ndp.c.

756  {
757 
758  return ( setting->scope == &ipv6_settings_scope );
759 }
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 769 of file ndp.c.

770  {
771  struct ndp_prefix_settings *prefset =
773  struct ndp_settings *ndpset =
775  struct net_device *netdev =
776  container_of ( ndpset->settings.parent, struct net_device,
777  settings.settings );
778  struct ndp_prefix_information_option *prefix = prefset->prefix;
779  struct in6_addr ip6;
780  int prefix_len;
781 
782  /* Skip dead prefixes */
783  if ( ! prefix->valid )
784  return -ENOENT;
785 
786  /* Construct IPv6 address via SLAAC, if applicable */
787  memcpy ( &ip6, &prefix->prefix, sizeof ( ip6 ) );
788  if ( prefix->flags & NDP_PREFIX_AUTONOMOUS ) {
789  prefix_len = ipv6_eui64 ( &ip6, netdev );
790  if ( prefix_len < 0 )
791  return prefix_len;
792  if ( prefix_len != prefix->prefix_len )
793  return -EINVAL;
794  }
795 
796  /* Fill in IPv6 address */
797  if ( len > sizeof ( ip6 ) )
798  len = sizeof ( ip6 );
799  memcpy ( data, &ip6, len );
800 
801  return sizeof ( ip6 );
802 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct settings * parent
Parent settings block.
Definition: settings.h:138
#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
A network device.
Definition: netdevice.h:348
struct ndp_prefix_information_option * prefix
Prefix information option.
Definition: ndp.c:589
A settings block.
Definition: settings.h:132
An NDP settings block.
Definition: ndp.c:593
An NDP prefix settings block.
Definition: ndp.c:583
uint32_t len
Length.
Definition: ena.h:14
struct settings settings
Settings interface.
Definition: ndp.c:597
#define NDP_PREFIX_AUTONOMOUS
NDP autonomous address configuration flag.
Definition: ndp.h:68
static int ipv6_eui64(struct in6_addr *addr, struct net_device *netdev)
Construct local IPv6 address via EUI-64.
Definition: ipv6.h:216
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

References container_of, data, EINVAL, ENOENT, ipv6_eui64(), len, memcpy(), NDP_PREFIX_AUTONOMOUS, netdev, settings::parent, prefix, ndp_prefix_settings::prefix, and ndp_settings::settings.

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

813  {
814  struct ndp_prefix_settings *prefset =
816  struct ndp_prefix_information_option *prefix = prefset->prefix;
817  uint8_t *len6;
818 
819  /* Fill in prefix length */
820  if ( len >= sizeof ( *len6 ) ) {
821  /* We treat an off-link prefix as having a prefix
822  * length covering the entire IPv6 address.
823  */
824  len6 = data;
825  *len6 = ( ( prefix->flags & NDP_PREFIX_ON_LINK ) ?
826  prefix->prefix_len : -1UL );
827  }
828 
829  return sizeof ( *len6 );
830 }
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:589
A settings block.
Definition: settings.h:132
unsigned char uint8_t
Definition: stdint.h:10
An NDP prefix settings block.
Definition: ndp.c:583
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

841  {
842  struct ndp_settings *ndpset =
844 
845  /* Treat non-routing router as non-existent */
846  if ( ! ndpset->lifetime )
847  return -ENOENT;
848 
849  /* Fill in router address */
850  if ( len > sizeof ( ndpset->router ) )
851  len = sizeof ( ndpset->router );
852  memcpy ( data, &ndpset->router, len );
853 
854  return sizeof ( ndpset->router );
855 }
unsigned int lifetime
Router lifetime.
Definition: ndp.c:601
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:593
struct in6_addr router
Router address.
Definition: ndp.c:599
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

890  {
891  struct ndp_prefix_operation *op;
892  unsigned int i;
893 
894  /* Handle per-prefix settings */
895  for ( i = 0 ; i < ( sizeof ( ndp_prefix_operations ) /
896  sizeof ( ndp_prefix_operations[0] ) ) ; i++ ) {
898  if ( setting_cmp ( setting, op->setting ) == 0 )
899  return op->fetch ( settings, data, len );
900  }
901 
902  return -ENOENT;
903 }
An NDP per-prefix setting operation.
Definition: ndp.c:858
#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:873
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
int setting_cmp(const struct setting *a, const struct setting *b)
Compare two settings.
Definition: settings.c:1119

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

924  {
925  struct settings *parent = netdev_settings ( netdev );
926  union ndp_option *option;
927  struct ndp_settings *ndpset;
928  struct ndp_prefix_settings *prefset;
929  size_t offset;
930  size_t option_len;
931  unsigned int prefixes;
932  unsigned int instance;
933  int order;
934  int rc;
935 
936  /* Count number of prefix options. We can assume that the
937  * options are well-formed, otherwise they would have been
938  * rejected prior to being stored.
939  */
940  order = IPV6_ORDER_PREFIX_ONLY;
941  for ( prefixes = 0, offset = 0 ; offset < len ; offset += option_len ) {
942 
943  /* Skip non-prefix options */
944  option = ( ( ( void * ) options ) + offset );
945  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
946  if ( option->header.type != NDP_OPT_PREFIX )
947  continue;
948 
949  /* Count number of prefixes */
950  prefixes++;
951 
952  /* Increase overall order if we have SLAAC addresses */
953  if ( option->prefix.flags & NDP_PREFIX_AUTONOMOUS )
954  order = IPV6_ORDER_SLAAC;
955  }
956 
957  /* Allocate and initialise structure */
958  ndpset = zalloc ( sizeof ( *ndpset ) + len +
959  ( prefixes * sizeof ( *prefset ) ) );
960  if ( ! ndpset ) {
961  rc = -ENOMEM;
962  goto err_alloc;
963  }
964  ref_init ( &ndpset->refcnt, NULL );
966  &ndpset->refcnt, &ndp_settings_scope );
967  ndpset->settings.order = order;
968  memcpy ( &ndpset->router, router, sizeof ( ndpset->router ) );
969  ndpset->lifetime = lifetime;
970  ndpset->len = len;
971  memcpy ( ndpset->options, options, len );
972  prefset = ( ( ( void * ) ndpset->options ) + len );
973 
974  /* Register settings */
975  if ( ( rc = register_settings ( &ndpset->settings, parent,
976  NDP_SETTINGS_NAME ) ) != 0 )
977  goto err_register;
978 
979  /* Construct and register per-prefix settings */
980  for ( instance = 0, offset = 0 ; offset < len ; offset += option_len ) {
981 
982  /* Skip non-prefix options */
983  option = ( ( ( void * ) ndpset->options ) + offset );
984  option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
985  if ( option->header.type != NDP_OPT_PREFIX )
986  continue;
987 
988  /* Initialise structure */
989  settings_init ( &prefset->settings,
991  &ndpset->refcnt, &ndp_settings_scope );
992  prefset->settings.order =
993  ( ( option->prefix.flags & NDP_PREFIX_AUTONOMOUS ) ?
995  prefset->prefix = &option->prefix;
996  snprintf ( prefset->name, sizeof ( prefset->name ), "%d",
997  instance++ );
998 
999  /* Register settings */
1000  if ( ( rc = register_settings ( &prefset->settings,
1001  &ndpset->settings,
1002  prefset->name ) ) != 0 )
1003  goto err_register_prefix;
1004 
1005  /* Move to next per-prefix settings */
1006  prefset++;
1007  }
1008  assert ( instance == prefixes );
1009 
1010  ref_put ( &ndpset->refcnt );
1011  return 0;
1012 
1013  err_register_prefix:
1014  unregister_settings ( &ndpset->settings );
1015  err_register:
1016  ref_put ( &ndpset->refcnt );
1017  err_alloc:
1018  return rc;
1019 }
#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:601
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition: settings.c:512
#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:743
static const struct settings_scope ndp_settings_scope
NDP settings scope.
Definition: ndp.c:609
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:577
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:495
static struct settings_operations ndp_prefix_settings_operations
NDP per-prefix settings operations.
Definition: ndp.c:906
#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:603
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:595
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct ndp_prefix_information_option * prefix
Prefix information option.
Definition: ndp.c:589
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:593
char name[4]
Name.
Definition: ndp.c:587
An NDP prefix settings block.
Definition: ndp.c:583
struct in6_addr router
Router address.
Definition: ndp.c:599
int order
Sibling ordering.
Definition: settings.h:148
union ndp_option options[0]
NDP options.
Definition: ndp.c:605
uint32_t len
Length.
Definition: ena.h:14
struct settings settings
Settings interface.
Definition: ndp.c:597
#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:473
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:362
struct settings settings
Settings interface.
Definition: ndp.c:585
#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 1074 of file ndp.c.

1074  {
1075  struct ipv6conf *ipv6conf =
1076  container_of ( refcnt, struct ipv6conf, refcnt );
1077 
1078  netdev_put ( ipv6conf->netdev );
1079  free ( ipv6conf );
1080 }
A reference counter.
Definition: refcnt.h:26
An IPv6 configurator.
Definition: ndp.c:1048
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:555
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1060
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 1104 of file ndp.c.

1104  {
1105 
1106  /* Shut down interfaces */
1107  intf_shutdown ( &ipv6conf->job, rc );
1108  intf_shutdown ( &ipv6conf->dhcp, rc );
1109 
1110  /* Stop timer */
1111  stop_timer ( &ipv6conf->timer );
1112 
1113  /* Remove from list and drop list's reference */
1114  list_del ( &ipv6conf->list );
1115  ref_put ( &ipv6conf->refcnt );
1116 }
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:273
struct refcnt refcnt
Reference count.
Definition: ndp.c:1050
struct interface dhcp
DHCPv6 interface.
Definition: ndp.c:1057
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
An IPv6 configurator.
Definition: ndp.c:1048
struct list_head list
List of configurators.
Definition: ndp.c:1052
struct interface job
Job control interface.
Definition: ndp.c:1055
struct retry_timer timer
Retransmission timer.
Definition: ndp.c:1063
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 1124 of file ndp.c.

1124  {
1125  struct ipv6conf *ipv6conf =
1126  container_of ( timer, struct ipv6conf, timer );
1127 
1128  /* If we have failed, terminate autoconfiguration */
1129  if ( fail ) {
1131  return;
1132  }
1133 
1134  /* Otherwise, transmit router solicitation and restart timer */
1135  start_timer ( &ipv6conf->timer );
1137 }
static int ndp_tx_router_solicitation(struct net_device *netdev)
Transmit NDP router solicitation.
Definition: ndp.c:159
A timer.
Definition: timer.h:28
An IPv6 configurator.
Definition: ndp.c:1048
#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:1104
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1060
struct retry_timer timer
Retransmission timer.
Definition: ndp.c:1063
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:93
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669

References container_of, ETIMEDOUT, ipv6conf_done(), ndp_tx_router_solicitation(), ipv6conf::netdev, start_timer(), 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 1227 of file ndp.c.

1227  {
1228  struct ipv6conf *ipv6conf;
1229 
1230  /* Allocate and initialise structure */
1231  ipv6conf = zalloc ( sizeof ( *ipv6conf ) );
1232  if ( ! ipv6conf )
1233  return -ENOMEM;
1237  timer_init ( &ipv6conf->timer, ipv6conf_expired, &ipv6conf->refcnt );
1239 
1240  /* Start timer to initiate router solicitation */
1242 
1243  /* Attach parent interface, transfer reference to list, and return */
1244  intf_plug_plug ( &ipv6conf->job, job );
1245  list_add ( &ipv6conf->list, &ipv6confs );
1246  return 0;
1247 }
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:1124
#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:1050
struct interface dhcp
DHCPv6 interface.
Definition: ndp.c:1057
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
static void ipv6conf_free(struct refcnt *refcnt)
Free IPv6 configurator.
Definition: ndp.c:1074
#define ENOMEM
Not enough space.
Definition: errno.h:534
An IPv6 configurator.
Definition: ndp.c:1048
static struct net_device * netdev
Definition: gdbudp.c:52
struct list_head list
List of configurators.
Definition: ndp.c:1052
struct net_device * netdev
Network device being configured.
Definition: ndp.c:1060
struct interface job
Job control interface.
Definition: ndp.c:1055
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:544
struct retry_timer timer
Retransmission timer.
Definition: ndp.c:1063
static struct interface_descriptor ipv6conf_job_desc
IPv6 configurator job interface descriptor.
Definition: ndp.c:1208
static struct interface_descriptor ipv6conf_dhcp_desc
IPv6 configurator DHCPv6 interface descriptor.
Definition: ndp.c:1217
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173

References ipv6conf::dhcp, ENOMEM, intf_init(), intf_plug_plug(), ipv6conf_dhcp_desc, ipv6conf_expired(), ipv6conf_free(), ipv6conf_job_desc, 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:113

NDP neighbour discovery protocol.

Definition at line 148 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:193
#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:254
#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:298
#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:339

NDP option handlers.

Definition at line 385 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:533
#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:503
#define ICMPV6_NEIGHBOUR_ADVERTISEMENT
ICMPv6 neighbour advertisement.
Definition: icmpv6.h:71

NDP ICMPv6 handlers.

Definition at line 561 of file ndp.c.

◆ ndp_settings_scope

const struct settings_scope ndp_settings_scope
static

NDP settings scope.

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

NDP settings operations.

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

NDP per-prefix settings operations.

Definition at line 873 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:755
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:888

NDP per-prefix settings operations.

Definition at line 906 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:244
An IPv6 configurator.
Definition: ndp.c:1048
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
Definition: ndp.c:1104
#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 1203 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:1203
An IPv6 configurator.
Definition: ndp.c:1048
struct interface job
Job control interface.
Definition: ndp.c:1055
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

IPv6 configurator job interface descriptor.

Definition at line 1208 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:244
An IPv6 configurator.
Definition: ndp.c:1048
static void ipv6conf_done(struct ipv6conf *ipv6conf, int rc)
Finish IPv6 autoconfiguration.
Definition: ndp.c:1104
#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 1212 of file ndp.c.

◆ ipv6conf_dhcp_desc

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

IPv6 configurator DHCPv6 interface descriptor.

Definition at line 1217 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:1227

IPv6 network device configurator.

Definition at line 1250 of file ndp.c.