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

IPv6 protocol. More...

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/iobuf.h>
#include <ipxe/tcpip.h>
#include <ipxe/if_ether.h>
#include <ipxe/crc32.h>
#include <ipxe/fragment.h>
#include <ipxe/ipstat.h>
#include <ipxe/ndp.h>
#include <ipxe/ipv6.h>

Go to the source code of this file.

Data Structures

struct  ipv6_settings
 IPv6 link-local address settings. More...
 

Macros

#define EINVAL_LEN   __einfo_error ( EINFO_EINVAL_LEN )
 
#define EINFO_EINVAL_LEN   __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid length" )
 
#define ENOTSUP_VER   __einfo_error ( EINFO_ENOTSUP_VER )
 
#define EINFO_ENOTSUP_VER   __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported version" )
 
#define ENOTSUP_HDR   __einfo_error ( EINFO_ENOTSUP_HDR )
 
#define EINFO_ENOTSUP_HDR   __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported header type" )
 
#define ENOTSUP_OPT   __einfo_error ( EINFO_ENOTSUP_OPT )
 
#define EINFO_ENOTSUP_OPT   __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Unsupported option" )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
struct ip_statistics_family ipv6_statistics_family __ip_statistics_family (IP_STATISTICS_IPV6)
 IPv6 statistics family. More...
 
static uint32_t ipv6col (struct in6_addr *in)
 Determine debugging colour for IPv6 debug messages. More...
 
static unsigned int ipv6_scope (const struct in6_addr *addr)
 Determine IPv6 address scope. More...
 
static void ipv6_dump_miniroute (struct ipv6_miniroute *miniroute)
 Dump IPv6 routing table entry. More...
 
int ipv6_has_addr (struct net_device *netdev, struct in6_addr *addr)
 Check if network device has a specific IPv6 address. More...
 
static unsigned int ipv6_match_len (struct ipv6_miniroute *miniroute, struct in6_addr *address)
 Count matching bits of an IPv6 routing table entry prefix. More...
 
static struct ipv6_minirouteipv6_miniroute (struct net_device *netdev, struct in6_addr *address)
 Find IPv6 routing table entry for a given address. More...
 
int ipv6_add_miniroute (struct net_device *netdev, struct in6_addr *address, unsigned int prefix_len, struct in6_addr *router)
 Add IPv6 routing table entry. More...
 
void ipv6_del_miniroute (struct ipv6_miniroute *miniroute)
 Delete IPv6 minirouting table entry. More...
 
struct ipv6_minirouteipv6_route (unsigned int scope_id, struct in6_addr **dest)
 Perform IPv6 routing. More...
 
static struct net_deviceipv6_netdev (struct sockaddr_tcpip *st_dest)
 Determine transmitting network device. More...
 
static int ipv6_check_options (struct ipv6_header *iphdr, struct ipv6_options_header *options, size_t len)
 Check that received options can be safely ignored. More...
 
static int ipv6_is_fragment (struct fragment *fragment, struct io_buffer *iobuf, size_t hdrlen)
 Check if fragment matches fragment reassembly buffer. More...
 
static size_t ipv6_fragment_offset (struct io_buffer *iobuf, size_t hdrlen)
 Get fragment offset. More...
 
static int ipv6_more_fragments (struct io_buffer *iobuf, size_t hdrlen)
 Check if more fragments exist. More...
 
static uint16_t ipv6_pshdr_chksum (struct ipv6_header *iphdr, size_t len, int next_header, uint16_t csum)
 Calculate IPv6 pseudo-header checksum. More...
 
static int ipv6_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 IPv6 packet. More...
 
static int ipv6_rx (struct io_buffer *iobuf, struct net_device *netdev, const void *ll_dest __unused, const void *ll_source __unused, unsigned int flags __unused)
 Process incoming IPv6 packets. More...
 
int inet6_aton (const char *string, struct in6_addr *in)
 Parse IPv6 address. More...
 
char * inet6_ntoa (const struct in6_addr *in)
 Convert IPv6 address to standard notation. More...
 
static const char * ipv6_ntoa (const void *net_addr)
 Transcribe IPv6 address. More...
 
static const char * ipv6_sock_ntoa (struct sockaddr *sa)
 Transcribe IPv6 socket address. More...
 
static int ipv6_sock_aton (const char *string, struct sockaddr *sa)
 Parse IPv6 socket address. More...
 
int parse_ipv6_setting (const struct setting_type *type __unused, const char *value, void *buf, size_t len)
 Parse IPv6 address setting value. More...
 
int format_ipv6_setting (const struct setting_type *type __unused, const void *raw, size_t raw_len, char *buf, size_t len)
 Format IPv6 address setting value. More...
 
const struct setting ip6_setting __setting (SETTING_IP6, ip6)
 IPv6 address setting. More...
 
const struct setting len6_setting __setting (SETTING_IP6, len6)
 IPv6 prefix length setting. More...
 
const struct setting gateway6_setting __setting (SETTING_IP6, gateway6)
 Default gateway setting. More...
 
static int ipv6_applies (struct settings *settings __unused, const struct setting *setting)
 Check applicability of IPv6 link-local address setting. More...
 
static int ipv6_fetch (struct settings *settings, struct setting *setting, void *data, size_t len)
 Fetch IPv6 link-local address setting. More...
 
static int ipv6_register_settings (struct net_device *netdev)
 Register IPv6 link-local address settings. More...
 
static int ipv6_create_routes (struct net_device *netdev, struct settings *settings)
 Create IPv6 routing table based on configured settings. More...
 
static int ipv6_create_all_routes (void)
 Create IPv6 routing table based on configured settings. More...
 
 REQUIRING_SYMBOL (ipv6_protocol)
 
 REQUIRE_OBJECT (icmpv6)
 
 REQUIRE_OBJECT (ndp)
 

Variables

struct list_head ipv6_miniroutes = LIST_HEAD_INIT ( ipv6_miniroutes )
 List of IPv6 miniroutes. More...
 
static struct ip_statistics ipv6_stats
 IPv6 statistics. More...
 
static struct fragment_reassembler ipv6_reassembler
 Fragment reassembler. More...
 
struct net_protocol ipv6_protocol __net_protocol
 IPv6 protocol. More...
 
struct tcpip_net_protocol ipv6_tcpip_protocol __tcpip_net_protocol
 IPv6 TCPIP net protocol. More...
 
struct sockaddr_converter ipv6_sockaddr_converter __sockaddr_converter
 IPv6 socket address converter. More...
 
const struct settings_scope ipv6_settings_scope
 IPv6 settings scope. More...
 
static struct settings_operations ipv6_settings_operations
 IPv6 link-local address settings operations. More...
 
struct net_driver ipv6_driver __net_driver
 IPv6 network device driver. More...
 
struct settings_applicator ipv6_settings_applicator __settings_applicator
 IPv6 settings applicator. More...
 

Detailed Description

IPv6 protocol.

Definition in file ipv6.c.

Macro Definition Documentation

◆ EINVAL_LEN

#define EINVAL_LEN   __einfo_error ( EINFO_EINVAL_LEN )

Definition at line 46 of file ipv6.c.

◆ EINFO_EINVAL_LEN

#define EINFO_EINVAL_LEN   __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid length" )

Definition at line 47 of file ipv6.c.

◆ ENOTSUP_VER

#define ENOTSUP_VER   __einfo_error ( EINFO_ENOTSUP_VER )

Definition at line 49 of file ipv6.c.

◆ EINFO_ENOTSUP_VER

#define EINFO_ENOTSUP_VER   __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported version" )

Definition at line 50 of file ipv6.c.

◆ ENOTSUP_HDR

#define ENOTSUP_HDR   __einfo_error ( EINFO_ENOTSUP_HDR )

Definition at line 52 of file ipv6.c.

◆ EINFO_ENOTSUP_HDR

#define EINFO_ENOTSUP_HDR   __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported header type" )

Definition at line 53 of file ipv6.c.

◆ ENOTSUP_OPT

#define ENOTSUP_OPT   __einfo_error ( EINFO_ENOTSUP_OPT )

Definition at line 55 of file ipv6.c.

◆ EINFO_ENOTSUP_OPT

#define EINFO_ENOTSUP_OPT   __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Unsupported option" )

Definition at line 56 of file ipv6.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ __ip_statistics_family()

struct ip_statistics_family ipv6_statistics_family __ip_statistics_family ( IP_STATISTICS_IPV6  )

IPv6 statistics family.

◆ ipv6col()

static uint32_t ipv6col ( struct in6_addr in)
static

Determine debugging colour for IPv6 debug messages.

Parameters
inIPv6 address
Return values
colDebugging colour (for DBGC())

Definition at line 78 of file ipv6.c.

78  {
79  return crc32_le ( 0, in, sizeof ( *in ) );
80 }
__be32 in[4]
Definition: CIB_PRM.h:35
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition: crc32.c:39

References crc32_le(), and in.

Referenced by ipv6_check_options(), ipv6_rx(), and ipv6_tx().

◆ ipv6_scope()

static unsigned int ipv6_scope ( const struct in6_addr addr)
static

Determine IPv6 address scope.

Parameters
addrIPv6 address
Return values
scopeAddress scope

Definition at line 88 of file ipv6.c.

88  {
89 
90  /* Multicast addresses directly include a scope field */
91  if ( IN6_IS_ADDR_MULTICAST ( addr ) )
92  return ipv6_multicast_scope ( addr );
93 
94  /* Link-local addresses have link-local scope */
95  if ( IN6_IS_ADDR_LINKLOCAL ( addr ) )
96  return IPV6_SCOPE_LINK_LOCAL;
97 
98  /* Site-local addresses have site-local scope */
99  if ( IN6_IS_ADDR_SITELOCAL ( addr ) )
100  return IPV6_SCOPE_SITE_LOCAL;
101 
102  /* Unique local addresses do not directly map to a defined
103  * scope. They effectively have a scope which is wider than
104  * link-local but narrower than global. Since the only
105  * multicast packets that we transmit are link-local, we can
106  * simply choose an arbitrary scope between link-local and
107  * global.
108  */
109  if ( IN6_IS_ADDR_ULA ( addr ) )
111 
112  /* All other addresses are assumed to be global */
113  return IPV6_SCOPE_GLOBAL;
114 }
Global address scope.
Definition: ipv6.h:174
Link-local address scope.
Definition: ipv6.h:166
#define IN6_IS_ADDR_SITELOCAL(addr)
Definition: in.h:72
Organisation-local address scope.
Definition: ipv6.h:172
#define IN6_IS_ADDR_LINKLOCAL(addr)
Definition: in.h:68
u32 addr
Definition: sky2.h:8
Site-local address scope.
Definition: ipv6.h:170
#define IN6_IS_ADDR_MULTICAST(addr)
Definition: in.h:65
#define IN6_IS_ADDR_ULA(addr)
Definition: in.h:76
static unsigned int ipv6_multicast_scope(const struct in6_addr *addr)
Get multicast address scope.
Definition: ipv6.h:274

References addr, IN6_IS_ADDR_LINKLOCAL, IN6_IS_ADDR_MULTICAST, IN6_IS_ADDR_SITELOCAL, IN6_IS_ADDR_ULA, ipv6_multicast_scope(), IPV6_SCOPE_GLOBAL, IPV6_SCOPE_LINK_LOCAL, IPV6_SCOPE_ORGANISATION_LOCAL, and IPV6_SCOPE_SITE_LOCAL.

Referenced by ipv6_add_miniroute(), and ipv6_route().

◆ ipv6_dump_miniroute()

static void ipv6_dump_miniroute ( struct ipv6_miniroute miniroute)
inlinestatic

Dump IPv6 routing table entry.

Parameters
minirouteRouting table entry

Definition at line 122 of file ipv6.c.

122  {
123  struct net_device *netdev = miniroute->netdev;
124 
125  DBGC ( netdev, "IPv6 %s has %s %s/%d", netdev->name,
126  ( ( miniroute->flags & IPV6_HAS_ADDRESS ) ?
127  "address" : "prefix" ),
128  inet6_ntoa ( &miniroute->address ), miniroute->prefix_len );
129  if ( miniroute->flags & IPV6_HAS_ROUTER )
130  DBGC ( netdev, " router %s", inet6_ntoa ( &miniroute->router ));
131  DBGC ( netdev, "\n" );
132 }
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
#define DBGC(...)
Definition: compiler.h:505
unsigned int flags
Flags.
Definition: ipv6.h:198
struct in6_addr router
Router address.
Definition: ipv6.h:194
static struct net_device * netdev
Definition: gdbudp.c:52
A network device.
Definition: netdevice.h:348
struct net_device * netdev
Network device.
Definition: ipv6.h:185
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
Routing table entry address is valid.
Definition: ipv6.h:204
Routing table entry router address is valid.
Definition: ipv6.h:206
unsigned int prefix_len
Prefix length.
Definition: ipv6.h:190
struct in6_addr address
IPv6 address (or prefix if no address is defined)
Definition: ipv6.h:188

References ipv6_miniroute::address, DBGC, ipv6_miniroute::flags, inet6_ntoa(), IPV6_HAS_ADDRESS, IPV6_HAS_ROUTER, net_device::name, netdev, ipv6_miniroute::netdev, ipv6_miniroute::prefix_len, and ipv6_miniroute::router.

Referenced by ipv6_add_miniroute().

◆ ipv6_has_addr()

int ipv6_has_addr ( struct net_device netdev,
struct in6_addr addr 
)

Check if network device has a specific IPv6 address.

Parameters
netdevNetwork device
addrIPv6 address
Return values
has_addrNetwork device has this IPv6 address

Definition at line 141 of file ipv6.c.

141  {
142  struct ipv6_miniroute *miniroute;
143 
144  list_for_each_entry ( miniroute, &ipv6_miniroutes, list ) {
145  if ( ( miniroute->netdev == netdev ) &&
146  ( miniroute->flags & IPV6_HAS_ADDRESS ) &&
147  ( memcmp ( &miniroute->address, addr,
148  sizeof ( miniroute->address ) ) == 0 ) ) {
149  /* Found matching address */
150  return 1;
151  }
152  }
153  return 0;
154 }
unsigned int flags
Flags.
Definition: ipv6.h:198
An IPv6 address/routing table entry.
Definition: ipv6.h:180
#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 miniroutes.
Definition: ipv6.h:182
struct list_head ipv6_miniroutes
List of IPv6 miniroutes.
Definition: ipv6.c:60
u32 addr
Definition: sky2.h:8
struct net_device * netdev
Network device.
Definition: ipv6.h:185
Routing table entry address is valid.
Definition: ipv6.h:204
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:113
struct in6_addr address
IPv6 address (or prefix if no address is defined)
Definition: ipv6.h:188

References addr, ipv6_miniroute::address, ipv6_miniroute::flags, IPV6_HAS_ADDRESS, ipv6_miniroutes, ipv6_miniroute::list, list_for_each_entry, memcmp(), netdev, and ipv6_miniroute::netdev.

Referenced by ipv6_rx(), and ndp_rx_neighbour_solicitation_ll_source().

◆ ipv6_match_len()

static unsigned int ipv6_match_len ( struct ipv6_miniroute miniroute,
struct in6_addr address 
)
static

Count matching bits of an IPv6 routing table entry prefix.

Parameters
minirouteRouting table entry
addressIPv6 address
Return values
match_lenNumber of matching prefix bits

Definition at line 163 of file ipv6.c.

164  {
165  unsigned int match_len = 0;
166  unsigned int i;
167  uint32_t diff;
168 
169  for ( i = 0 ; i < ( sizeof ( address->s6_addr32 ) /
170  sizeof ( address->s6_addr32[0] ) ) ; i++ ) {
171 
172  diff = ntohl ( ~( ( ~( address->s6_addr32[i] ^
173  miniroute->address.s6_addr32[i] ) )
174  & miniroute->prefix_mask.s6_addr32[i] ) );
175  match_len += 32;
176  if ( diff ) {
177  match_len -= flsl ( diff );
178  break;
179  }
180  }
181 
182  return match_len;
183 }
uint64_t address
Base address.
Definition: ena.h:24
#define ntohl(value)
Definition: byteswap.h:134
unsigned int uint32_t
Definition: stdint.h:12
#define flsl(x)
Find last (i.e.
Definition: strings.h:157
struct in6_addr address
IPv6 address (or prefix if no address is defined)
Definition: ipv6.h:188
struct in6_addr prefix_mask
IPv6 prefix mask (derived from prefix length)
Definition: ipv6.h:192

References address, ipv6_miniroute::address, flsl, ntohl, and ipv6_miniroute::prefix_mask.

Referenced by ipv6_miniroute(), and ipv6_route().

◆ ipv6_miniroute()

static struct ipv6_miniroute* ipv6_miniroute ( struct net_device netdev,
struct in6_addr address 
)
static

Find IPv6 routing table entry for a given address.

Parameters
netdevNetwork device
addressIPv6 address
Return values
minirouteRouting table entry, or NULL if not found

Definition at line 192 of file ipv6.c.

193  {
194  struct ipv6_miniroute *miniroute;
195  unsigned int match_len;
196 
197  list_for_each_entry ( miniroute, &ipv6_miniroutes, list ) {
198  if ( miniroute->netdev != netdev )
199  continue;
200  match_len = ipv6_match_len ( miniroute, address );
201  if ( match_len < miniroute->prefix_len )
202  continue;
203  return miniroute;
204  }
205  return NULL;
206 }
uint64_t address
Base address.
Definition: ena.h:24
An IPv6 address/routing table entry.
Definition: ipv6.h:180
#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 miniroutes.
Definition: ipv6.h:182
struct list_head ipv6_miniroutes
List of IPv6 miniroutes.
Definition: ipv6.c:60
struct net_device * netdev
Network device.
Definition: ipv6.h:185
static unsigned int ipv6_match_len(struct ipv6_miniroute *miniroute, struct in6_addr *address)
Count matching bits of an IPv6 routing table entry prefix.
Definition: ipv6.c:163
unsigned int prefix_len
Prefix length.
Definition: ipv6.h:190
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References address, ipv6_match_len(), ipv6_miniroutes, ipv6_miniroute::list, list_for_each_entry, netdev, ipv6_miniroute::netdev, NULL, and ipv6_miniroute::prefix_len.

Referenced by ipv6_add_miniroute().

◆ ipv6_add_miniroute()

int ipv6_add_miniroute ( struct net_device netdev,
struct in6_addr address,
unsigned int  prefix_len,
struct in6_addr router 
)

Add IPv6 routing table entry.

Parameters
netdevNetwork device
addressIPv6 address (or prefix)
prefix_lenPrefix length
routerRouter address (if any)
Return values
rcReturn status code

Definition at line 217 of file ipv6.c.

218  {
219  struct ipv6_miniroute *miniroute;
221  unsigned int remaining;
222  unsigned int i;
223 
224  /* Find or create routing table entry */
225  miniroute = ipv6_miniroute ( netdev, address );
226  if ( miniroute ) {
227 
228  /* Remove from existing position in routing table */
229  list_del ( &miniroute->list );
230 
231  } else {
232 
233  /* Create new routing table entry */
234  miniroute = zalloc ( sizeof ( *miniroute ) );
235  if ( ! miniroute )
236  return -ENOMEM;
237  miniroute->netdev = netdev_get ( netdev );
238  memcpy ( &miniroute->address, address,
239  sizeof ( miniroute->address ) );
240 
241  /* Default to prefix length of 64 if none specified */
242  if ( ! prefix_len )
244  miniroute->prefix_len = prefix_len;
246 
247  /* Construct prefix mask */
248  remaining = prefix_len;
249  for ( prefix_mask = miniroute->prefix_mask.s6_addr ;
250  remaining >= 8 ; prefix_mask++, remaining -= 8 ) {
251  *prefix_mask = 0xff;
252  }
253  if ( remaining )
254  *prefix_mask <<= ( 8 - remaining );
255  }
256 
257  /* Add to start of routing table */
258  list_add ( &miniroute->list, &ipv6_miniroutes );
259 
260  /* Set or update address, if applicable */
261  for ( i = 0 ; i < ( sizeof ( address->s6_addr32 ) /
262  sizeof ( address->s6_addr32[0] ) ) ; i++ ) {
263  if ( ( address->s6_addr32[i] &
264  ~miniroute->prefix_mask.s6_addr32[i] ) != 0 ) {
265  memcpy ( &miniroute->address, address,
266  sizeof ( miniroute->address ) );
267  miniroute->flags |= IPV6_HAS_ADDRESS;
268  }
269  }
270  if ( miniroute->prefix_len == IPV6_MAX_PREFIX_LEN )
271  miniroute->flags |= IPV6_HAS_ADDRESS;
272 
273  /* Update scope */
274  miniroute->scope = ipv6_scope ( &miniroute->address );
275 
276  /* Set or update router, if applicable */
277  if ( router ) {
278  memcpy ( &miniroute->router, router,
279  sizeof ( miniroute->router ) );
280  miniroute->flags |= IPV6_HAS_ROUTER;
281  }
282 
283  ipv6_dump_miniroute ( miniroute );
284  return 0;
285 }
#define IPV6_DEFAULT_PREFIX_LEN
IPv6 default prefix length.
Definition: ipv6.h:29
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
#define IPV6_MAX_PREFIX_LEN
IPv6 maximum prefix length.
Definition: ipv6.h:32
static unsigned int ipv6_scope(const struct in6_addr *addr)
Determine IPv6 address scope.
Definition: ipv6.c:88
uint64_t address
Base address.
Definition: ena.h:24
unsigned int flags
Flags.
Definition: ipv6.h:198
An IPv6 address/routing table entry.
Definition: ipv6.h:180
struct in6_addr router
Router address.
Definition: ipv6.h:194
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned int scope
Scope.
Definition: ipv6.h:196
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static struct net_device * netdev
Definition: gdbudp.c:52
struct list_head list
List of miniroutes.
Definition: ipv6.h:182
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct list_head ipv6_miniroutes
List of IPv6 miniroutes.
Definition: ipv6.c:60
unsigned char uint8_t
Definition: stdint.h:10
struct net_device * netdev
Network device.
Definition: ipv6.h:185
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:544
static void ipv6_dump_miniroute(struct ipv6_miniroute *miniroute)
Dump IPv6 routing table entry.
Definition: ipv6.c:122
Routing table entry address is valid.
Definition: ipv6.h:204
Routing table entry router address is valid.
Definition: ipv6.h:206
unsigned int prefix_len
Prefix length.
Definition: ipv6.h:190
struct in6_addr address
IPv6 address (or prefix if no address is defined)
Definition: ipv6.h:188
static struct ipv6_miniroute * ipv6_miniroute(struct net_device *netdev, struct in6_addr *address)
Find IPv6 routing table entry for a given address.
Definition: ipv6.c:192
struct in6_addr prefix_mask
IPv6 prefix mask (derived from prefix length)
Definition: ipv6.h:192

References address, ipv6_miniroute::address, assert(), ENOMEM, ipv6_miniroute::flags, IPV6_DEFAULT_PREFIX_LEN, ipv6_dump_miniroute(), IPV6_HAS_ADDRESS, IPV6_HAS_ROUTER, IPV6_MAX_PREFIX_LEN, ipv6_miniroute(), ipv6_miniroutes, ipv6_scope(), ipv6_miniroute::list, list_add, list_del, memcpy(), netdev, ipv6_miniroute::netdev, netdev_get(), ipv6_miniroute::prefix_len, ipv6_miniroute::prefix_mask, ipv6_miniroute::router, ipv6_miniroute::scope, and zalloc().

Referenced by ipv6_create_routes(), and ipv6_table_okx().

◆ ipv6_del_miniroute()

void ipv6_del_miniroute ( struct ipv6_miniroute miniroute)

Delete IPv6 minirouting table entry.

Parameters
minirouteRouting table entry

Definition at line 292 of file ipv6.c.

292  {
293 
294  netdev_put ( miniroute->netdev );
295  list_del ( &miniroute->list );
296  free ( miniroute );
297 }
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:555
struct list_head list
List of miniroutes.
Definition: ipv6.h:182
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct net_device * netdev
Network device.
Definition: ipv6.h:185

References free, ipv6_miniroute::list, list_del, ipv6_miniroute::netdev, and netdev_put().

Referenced by ipv6_create_all_routes(), and ipv6_table_del().

◆ ipv6_route()

struct ipv6_miniroute* ipv6_route ( unsigned int  scope_id,
struct in6_addr **  dest 
)

Perform IPv6 routing.

Parameters
scope_idDestination address scope ID (for link-local addresses)
destFinal destination address
Return values
destNext hop destination address
minirouteRouting table entry to use, or NULL if no route

Definition at line 307 of file ipv6.c.

308  {
309  struct ipv6_miniroute *miniroute;
310  struct ipv6_miniroute *chosen = NULL;
311  unsigned int best = 0;
312  unsigned int match_len;
313  unsigned int score;
314  unsigned int scope;
315 
316  /* Calculate destination address scope */
317  scope = ipv6_scope ( *dest );
318 
319  /* Find first usable route in routing table */
320  list_for_each_entry ( miniroute, &ipv6_miniroutes, list ) {
321 
322  /* Skip closed network devices */
323  if ( ! netdev_is_open ( miniroute->netdev ) )
324  continue;
325 
326  /* Skip entries with no usable source address */
327  if ( ! ( miniroute->flags & IPV6_HAS_ADDRESS ) )
328  continue;
329 
330  /* Skip entries with a non-matching scope ID, if
331  * destination specifies a scope ID.
332  */
333  if ( scope_id && ( miniroute->netdev->index != scope_id ) )
334  continue;
335 
336  /* Skip entries that are out of scope */
337  if ( miniroute->scope < scope )
338  continue;
339 
340  /* Calculate match length */
341  match_len = ipv6_match_len ( miniroute, *dest );
342 
343  /* If destination is on-link, then use this route */
344  if ( match_len >= miniroute->prefix_len )
345  return miniroute;
346 
347  /* If destination is unicast, then skip off-link
348  * entries with no router.
349  */
350  if ( ! ( IN6_IS_ADDR_MULTICAST ( *dest ) ||
351  ( miniroute->flags & IPV6_HAS_ROUTER ) ) )
352  continue;
353 
354  /* Choose best route, defined as being the route with
355  * the smallest viable scope. If two routes both have
356  * the same scope, then prefer the route with the
357  * longest match length.
358  */
359  score = ( ( ( IPV6_SCOPE_MAX + 1 - miniroute->scope ) << 8 )
360  + match_len );
361  if ( score > best ) {
362  chosen = miniroute;
363  best = score;
364  }
365  }
366 
367  /* Return chosen route, if any */
368  if ( chosen ) {
369  if ( ! IN6_IS_ADDR_MULTICAST ( *dest ) )
370  *dest = &chosen->router;
371  return chosen;
372  }
373 
374  return NULL;
375 }
uint8_t scope
Scope.
Definition: ena.h:18
static unsigned int ipv6_scope(const struct in6_addr *addr)
Determine IPv6 address scope.
Definition: ipv6.c:88
unsigned int flags
Flags.
Definition: ipv6.h:198
An IPv6 address/routing table entry.
Definition: ipv6.h:180
struct in6_addr router
Router address.
Definition: ipv6.h:194
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:652
unsigned int scope
Scope.
Definition: ipv6.h:196
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
struct list_head list
List of miniroutes.
Definition: ipv6.h:182
static void * dest
Definition: strings.h:176
struct list_head ipv6_miniroutes
List of IPv6 miniroutes.
Definition: ipv6.c:60
struct net_device * netdev
Network device.
Definition: ipv6.h:185
static unsigned int ipv6_match_len(struct ipv6_miniroute *miniroute, struct in6_addr *address)
Count matching bits of an IPv6 routing table entry prefix.
Definition: ipv6.c:163
unsigned int index
Index of this network device.
Definition: netdevice.h:356
Routing table entry address is valid.
Definition: ipv6.h:204
#define IN6_IS_ADDR_MULTICAST(addr)
Definition: in.h:65
Routing table entry router address is valid.
Definition: ipv6.h:206
Maximum scope.
Definition: ipv6.h:176
unsigned int prefix_len
Prefix length.
Definition: ipv6.h:190
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References dest, ipv6_miniroute::flags, IN6_IS_ADDR_MULTICAST, net_device::index, IPV6_HAS_ADDRESS, IPV6_HAS_ROUTER, ipv6_match_len(), ipv6_miniroutes, ipv6_scope(), IPV6_SCOPE_MAX, ipv6_miniroute::list, list_for_each_entry, ipv6_miniroute::netdev, netdev_is_open(), NULL, ipv6_miniroute::prefix_len, ipv6_miniroute::router, scope, and ipv6_miniroute::scope.

Referenced by ipv6_netdev(), ipv6_route_okx(), and ipv6_tx().

◆ ipv6_netdev()

static struct net_device* ipv6_netdev ( struct sockaddr_tcpip st_dest)
static

Determine transmitting network device.

Parameters
st_destDestination network-layer address
Return values
netdevTransmitting network device, or NULL

Definition at line 383 of file ipv6.c.

383  {
384  struct sockaddr_in6 *sin6_dest = ( ( struct sockaddr_in6 * ) st_dest );
385  struct in6_addr *dest = &sin6_dest->sin6_addr;
386  struct ipv6_miniroute *miniroute;
387 
388  /* Find routing table entry */
389  miniroute = ipv6_route ( sin6_dest->sin6_scope_id, &dest );
390  if ( ! miniroute )
391  return NULL;
392 
393  return miniroute->netdev;
394 }
struct ipv6_miniroute * ipv6_route(unsigned int scope_id, struct in6_addr **dest)
Perform IPv6 routing.
Definition: ipv6.c:307
uint16_t sin6_scope_id
Scope ID (part of struct sockaddr_tcpip)
Definition: in.h:130
An IPv6 address/routing table entry.
Definition: ipv6.h:180
IP6 address structure.
Definition: in.h:48
static void * dest
Definition: strings.h:176
struct net_device * netdev
Network device.
Definition: ipv6.h:185
IPv6 socket address.
Definition: in.h:115
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:132

References dest, ipv6_route(), ipv6_miniroute::netdev, NULL, sockaddr_in6::sin6_addr, and sockaddr_in6::sin6_scope_id.

◆ ipv6_check_options()

static int ipv6_check_options ( struct ipv6_header iphdr,
struct ipv6_options_header options,
size_t  len 
)
static

Check that received options can be safely ignored.

Parameters
iphdrIPv6 header
optionsOptions extension header
lenMaximum length of header
Return values
rcReturn status code

Definition at line 404 of file ipv6.c.

406  {
407  struct ipv6_option *option = options->options;
408  struct ipv6_option *end = ( ( ( void * ) options ) + len );
409 
410  while ( option < end ) {
411  if ( ! IPV6_CAN_IGNORE_OPT ( option->type ) ) {
412  DBGC ( ipv6col ( &iphdr->src ), "IPv6 unrecognised "
413  "option type %#02x:\n", option->type );
414  DBGC_HDA ( ipv6col ( &iphdr->src ), 0,
415  options, len );
416  return -ENOTSUP_OPT;
417  }
418  if ( option->type == IPV6_OPT_PAD1 ) {
419  option = ( ( ( void * ) option ) + 1 );
420  } else {
421  option = ( ( ( void * ) option->value ) + option->len );
422  }
423  }
424  return 0;
425 }
#define ENOTSUP_OPT
Definition: ipv6.c:55
struct in_addr src
Definition: ip.h:44
#define IPV6_CAN_IGNORE_OPT(type)
Test if IPv6 option can be safely ignored.
Definition: ipv6.h:77
#define DBGC(...)
Definition: compiler.h:505
static uint32_t ipv6col(struct in6_addr *in)
Determine debugging colour for IPv6 debug messages.
Definition: ipv6.c:78
IPv6 type-length-value options.
Definition: ipv6.h:59
Pad1.
Definition: ipv6.h:71
An IPv4 packet header.
Definition: ip.h:35
A long option, as used for getopt_long()
Definition: getopt.h:24
static int options
Definition: 3c515.c:286
#define DBGC_HDA(...)
Definition: compiler.h:506
uint32_t len
Length.
Definition: ena.h:14
uint32_t end
Ending offset.
Definition: netvsc.h:18

References DBGC, DBGC_HDA, end, ENOTSUP_OPT, IPV6_CAN_IGNORE_OPT, IPV6_OPT_PAD1, ipv6col(), len, options, and iphdr::src.

Referenced by ipv6_rx().

◆ ipv6_is_fragment()

static int ipv6_is_fragment ( struct fragment fragment,
struct io_buffer iobuf,
size_t  hdrlen 
)
static

Check if fragment matches fragment reassembly buffer.

Parameters
fragmentFragment reassembly buffer
iobufI/O buffer
hdrlenLength of non-fragmentable potion of I/O buffer
Return values
is_fragmentFragment matches this reassembly buffer

Definition at line 435 of file ipv6.c.

436  {
437  struct ipv6_header *frag_iphdr = fragment->iobuf->data;
438  struct ipv6_fragment_header *frag_fhdr =
440  sizeof ( *frag_fhdr ) );
441  struct ipv6_header *iphdr = iobuf->data;
442  struct ipv6_fragment_header *fhdr =
443  ( iobuf->data + hdrlen - sizeof ( *fhdr ) );
444 
445  return ( ( memcmp ( &iphdr->src, &frag_iphdr->src,
446  sizeof ( iphdr->src ) ) == 0 ) &&
447  ( fhdr->ident == frag_fhdr->ident ) );
448 }
IPv6 header.
Definition: ipv6.h:35
struct in_addr src
Definition: ip.h:44
A fragment reassembly buffer.
Definition: fragment.h:21
IPv6 fragment header.
Definition: ipv6.h:100
An IPv4 packet header.
Definition: ip.h:35
struct io_buffer * iobuf
Reassembled packet.
Definition: fragment.h:25
void * data
Start of data.
Definition: iobuf.h:44
struct in6_addr src
Source address.
Definition: ipv6.h:45
uint32_t ident
Identification.
Definition: ipv6.h:106
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:113
size_t hdrlen
Length of non-fragmentable portion of reassembled packet.
Definition: fragment.h:27

References io_buffer::data, fragment::hdrlen, ipv6_fragment_header::ident, fragment::iobuf, memcmp(), ipv6_header::src, and iphdr::src.

◆ ipv6_fragment_offset()

static size_t ipv6_fragment_offset ( struct io_buffer iobuf,
size_t  hdrlen 
)
static

Get fragment offset.

Parameters
iobufI/O buffer
hdrlenLength of non-fragmentable potion of I/O buffer
Return values
offsetOffset

Definition at line 457 of file ipv6.c.

457  {
458  struct ipv6_fragment_header *fhdr =
459  ( iobuf->data + hdrlen - sizeof ( *fhdr ) );
460 
461  return ( ntohs ( fhdr->offset_more ) & IPV6_MASK_OFFSET );
462 }
#define ntohs(value)
Definition: byteswap.h:136
IPv6 fragment header.
Definition: ipv6.h:100
void * data
Start of data.
Definition: iobuf.h:44
#define IPV6_MASK_OFFSET
Fragment offset mask.
Definition: ipv6.h:110
uint16_t offset_more
Fragment offset (13 bits), reserved, more fragments (1 bit)
Definition: ipv6.h:104

References io_buffer::data, IPV6_MASK_OFFSET, ntohs, and ipv6_fragment_header::offset_more.

◆ ipv6_more_fragments()

static int ipv6_more_fragments ( struct io_buffer iobuf,
size_t  hdrlen 
)
static

Check if more fragments exist.

Parameters
iobufI/O buffer
hdrlenLength of non-fragmentable potion of I/O buffer
Return values
more_fragsMore fragments exist

Definition at line 471 of file ipv6.c.

471  {
472  struct ipv6_fragment_header *fhdr =
473  ( iobuf->data + hdrlen - sizeof ( *fhdr ) );
474 
475  return ( fhdr->offset_more & htons ( IPV6_MASK_MOREFRAGS ) );
476 }
IPv6 fragment header.
Definition: ipv6.h:100
void * data
Start of data.
Definition: iobuf.h:44
#define IPV6_MASK_MOREFRAGS
More fragments.
Definition: ipv6.h:113
uint16_t offset_more
Fragment offset (13 bits), reserved, more fragments (1 bit)
Definition: ipv6.h:104
#define htons(value)
Definition: byteswap.h:135

References io_buffer::data, htons, IPV6_MASK_MOREFRAGS, and ipv6_fragment_header::offset_more.

◆ ipv6_pshdr_chksum()

static uint16_t ipv6_pshdr_chksum ( struct ipv6_header iphdr,
size_t  len,
int  next_header,
uint16_t  csum 
)
static

Calculate IPv6 pseudo-header checksum.

Parameters
iphdrIPv6 header
lenPayload length
next_headerNext header type
csumExisting checksum
Return values
csumUpdated checksum

Definition at line 496 of file ipv6.c.

497  {
498  struct ipv6_pseudo_header pshdr;
499 
500  /* Build pseudo-header */
501  memcpy ( &pshdr.src, &iphdr->src, sizeof ( pshdr.src ) );
502  memcpy ( &pshdr.dest, &iphdr->dest, sizeof ( pshdr.dest ) );
503  pshdr.len = htonl ( len );
504  memset ( pshdr.zero, 0, sizeof ( pshdr.zero ) );
505  pshdr.next_header = next_header;
506 
507  /* Update the checksum value */
508  return tcpip_continue_chksum ( csum, &pshdr, sizeof ( pshdr ) );
509 }
struct in_addr src
Definition: ip.h:44
An IPv4 packet header.
Definition: ip.h:35
#define htonl(value)
Definition: byteswap.h:133
void * memcpy(void *dest, const void *src, size_t len) __nonnull
IPv6 pseudo-header.
Definition: ipv6.h:148
struct in_addr dest
Definition: ip.h:45
uint32_t len
Length.
Definition: ena.h:14
uint8_t next_header
Next header.
Definition: ipv6.h:158
uint16_t tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition: x86_tcpip.c:45
void * memset(void *dest, int character, size_t len) __nonnull

References iphdr::dest, ipv6_pseudo_header::dest, htonl, len, ipv6_pseudo_header::len, memcpy(), memset(), ipv6_pseudo_header::next_header, iphdr::src, ipv6_pseudo_header::src, tcpip_continue_chksum(), and ipv6_pseudo_header::zero.

Referenced by ipv6_rx(), and ipv6_tx().

◆ ipv6_tx()

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

Transmit IPv6 packet.

Parameters
iobufI/O buffer
tcpipTransport-layer protocol
st_srcSource network-layer address
st_destDestination network-layer address
netdevNetwork device to use if no route found, or NULL
trans_csumTransport-layer checksum to complete, or NULL
Return values
rcStatus

This function expects a transport-layer segment and prepends the IPv6 header

Definition at line 525 of file ipv6.c.

530  {
531  struct sockaddr_in6 *sin6_src = ( ( struct sockaddr_in6 * ) st_src );
532  struct sockaddr_in6 *sin6_dest = ( ( struct sockaddr_in6 * ) st_dest );
533  struct ipv6_miniroute *miniroute;
534  struct ipv6_header *iphdr;
535  struct in6_addr *src = NULL;
536  struct in6_addr *next_hop;
537  uint8_t ll_dest_buf[MAX_LL_ADDR_LEN];
538  const void *ll_dest;
539  size_t len;
540  int rc;
541 
542  /* Update statistics */
544 
545  /* Fill up the IPv6 header, except source address */
546  len = iob_len ( iobuf );
547  iphdr = iob_push ( iobuf, sizeof ( *iphdr ) );
548  memset ( iphdr, 0, sizeof ( *iphdr ) );
549  iphdr->ver_tc_label = htonl ( IPV6_VER );
550  iphdr->len = htons ( len );
551  iphdr->next_header = tcpip_protocol->tcpip_proto;
552  iphdr->hop_limit = IPV6_HOP_LIMIT;
553  memcpy ( &iphdr->dest, &sin6_dest->sin6_addr, sizeof ( iphdr->dest ) );
554 
555  /* Use routing table to identify next hop and transmitting netdev */
556  next_hop = &iphdr->dest;
557  if ( ( miniroute = ipv6_route ( sin6_dest->sin6_scope_id,
558  &next_hop ) ) != NULL ) {
559  src = &miniroute->address;
560  netdev = miniroute->netdev;
561  }
562  if ( ! netdev ) {
563  DBGC ( ipv6col ( &iphdr->dest ), "IPv6 has no route to %s\n",
564  inet6_ntoa ( &iphdr->dest ) );
566  rc = -ENETUNREACH;
567  goto err;
568  }
569  if ( sin6_src && ! IN6_IS_ADDR_UNSPECIFIED ( &sin6_src->sin6_addr ) )
570  src = &sin6_src->sin6_addr;
571  if ( src )
572  memcpy ( &iphdr->src, src, sizeof ( iphdr->src ) );
573 
574  /* Fix up checksums */
575  if ( trans_csum ) {
576  *trans_csum = ipv6_pshdr_chksum ( iphdr, len,
578  *trans_csum );
579  if ( ! *trans_csum )
580  *trans_csum = tcpip_protocol->zero_csum;
581  }
582 
583  /* Print IPv6 header for debugging */
584  DBGC2 ( ipv6col ( &iphdr->dest ), "IPv6 TX %s->",
585  inet6_ntoa ( &iphdr->src ) );
586  DBGC2 ( ipv6col ( &iphdr->dest ), "%s len %zd next %d\n",
587  inet6_ntoa ( &iphdr->dest ), len, iphdr->next_header );
588 
589  /* Calculate link-layer destination address, if possible */
590  if ( IN6_IS_ADDR_MULTICAST ( next_hop ) ) {
591  /* Multicast address */
593  if ( ( rc = netdev->ll_protocol->mc_hash ( AF_INET6, next_hop,
594  ll_dest_buf ) ) !=0){
595  DBGC ( ipv6col ( &iphdr->dest ), "IPv6 could not hash "
596  "multicast %s: %s\n", inet6_ntoa ( next_hop ),
597  strerror ( rc ) );
598  goto err;
599  }
600  ll_dest = ll_dest_buf;
601  } else {
602  /* Unicast address */
603  ll_dest = NULL;
604  }
605 
606  /* Update statistics */
608  ipv6_stats.out_octets += iob_len ( iobuf );
609 
610  /* Hand off to link layer (via NDP if applicable) */
611  if ( ll_dest ) {
612  if ( ( rc = net_tx ( iobuf, netdev, &ipv6_protocol, ll_dest,
613  netdev->ll_addr ) ) != 0 ) {
614  DBGC ( ipv6col ( &iphdr->dest ), "IPv6 could not "
615  "transmit packet via %s: %s\n",
616  netdev->name, strerror ( rc ) );
617  return rc;
618  }
619  } else {
620  if ( ( rc = ndp_tx ( iobuf, netdev, next_hop, &iphdr->src,
621  netdev->ll_addr ) ) != 0 ) {
622  DBGC ( ipv6col ( &iphdr->dest ), "IPv6 could not "
623  "transmit packet via %s: %s\n",
624  netdev->name, strerror ( rc ) );
625  return rc;
626  }
627  }
628 
629  return 0;
630 
631  err:
632  free_iob ( iobuf );
633  return rc;
634 }
static struct ip_statistics ipv6_stats
IPv6 statistics.
Definition: ipv6.c:63
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
IPv6 header.
Definition: ipv6.h:35
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
struct in_addr src
Definition: ip.h:44
#define iob_push(iobuf, len)
Definition: iobuf.h:80
struct ipv6_miniroute * ipv6_route(unsigned int scope_id, struct in6_addr **dest)
Perform IPv6 routing.
Definition: ipv6.c:307
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
uint8_t tcpip_proto
Transport-layer protocol number.
Definition: tcpip.h:134
#define DBGC(...)
Definition: compiler.h:505
static uint32_t ipv6col(struct in6_addr *in)
Determine debugging colour for IPv6 debug messages.
Definition: ipv6.c:78
static uint16_t ipv6_pshdr_chksum(struct ipv6_header *iphdr, size_t len, int next_header, uint16_t csum)
Calculate IPv6 pseudo-header checksum.
Definition: ipv6.c:496
uint16_t sin6_scope_id
Scope ID (part of struct sockaddr_tcpip)
Definition: in.h:130
An IPv4 packet header.
Definition: ip.h:35
#define htonl(value)
Definition: byteswap.h:133
An IPv6 address/routing table entry.
Definition: ipv6.h:180
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define MAX_LL_ADDR_LEN
Maximum length of a link-layer address.
Definition: netdevice.h:36
unsigned long out_no_routes
ipSystemStatsOutNoRoutes
Definition: ipstat.h:130
uint16_t len
Definition: ip.h:38
static struct net_device * netdev
Definition: gdbudp.c:52
#define IPV6_HOP_LIMIT
IPv6 maximum hop limit.
Definition: ipv6.h:26
IP6 address structure.
Definition: in.h:48
#define IN6_IS_ADDR_UNSPECIFIED(addr)
Definition: in.h:59
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
unsigned char uint8_t
Definition: stdint.h:10
unsigned long out_mcast_pkts
ipSystemStatsOutMcastPkts
Definition: ipstat.h:155
struct net_device * netdev
Network device.
Definition: ipv6.h:185
struct in_addr dest
Definition: ip.h:45
int(* mc_hash)(unsigned int af, const void *net_addr, void *ll_addr)
Hash multicast address.
Definition: netdevice.h:172
A transport-layer protocol of the TCP/IP stack (eg.
Definition: tcpip.h:104
uint16_t zero_csum
Preferred zero checksum value.
Definition: tcpip.h:128
#define IPV6_VER
IPv6 version.
Definition: ipv6.h:20
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
int net_tx(struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *ll_dest, const void *ll_source)
Transmit network-layer packet.
Definition: netdevice.c:999
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
unsigned long out_requests
ipSystemStatsOutRequests
Definition: ipstat.h:123
static int ndp_tx(struct io_buffer *iobuf, struct net_device *netdev, const void *net_dest, const void *net_source, const void *ll_source)
Transmit packet, determining link-layer address via NDP.
Definition: ndp.h:195
#define IN6_IS_ADDR_MULTICAST(addr)
Definition: in.h:65
IPv6 socket address.
Definition: in.h:115
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:381
#define ENETUNREACH
Network unreachable.
Definition: errno.h:488
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct in6_addr address
IPv6 address (or prefix if no address is defined)
Definition: ipv6.h:188
#define htons(value)
Definition: byteswap.h:135
unsigned long out_octets
ipSystemStatsOutOctets
Definition: ipstat.h:145
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:132
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:366
unsigned long out_transmits
ipSystemStatsOutTransmits
Definition: ipstat.h:138
void * memset(void *dest, int character, size_t len) __nonnull

References ipv6_miniroute::address, AF_INET6, DBGC, DBGC2, iphdr::dest, ENETUNREACH, free_iob(), htonl, htons, IN6_IS_ADDR_MULTICAST, IN6_IS_ADDR_UNSPECIFIED, inet6_ntoa(), iob_len(), iob_push, IPV6_HOP_LIMIT, ipv6_pshdr_chksum(), ipv6_route(), ipv6_stats, IPV6_VER, ipv6col(), len, iphdr::len, net_device::ll_addr, net_device::ll_protocol, MAX_LL_ADDR_LEN, ll_protocol::mc_hash, memcpy(), memset(), net_device::name, ndp_tx(), net_tx(), netdev, ipv6_miniroute::netdev, NULL, ip_statistics::out_mcast_pkts, ip_statistics::out_no_routes, ip_statistics::out_octets, ip_statistics::out_requests, ip_statistics::out_transmits, rc, sockaddr_in6::sin6_addr, sockaddr_in6::sin6_scope_id, iphdr::src, src, strerror(), tcpip_protocol::tcpip_proto, and tcpip_protocol::zero_csum.

◆ ipv6_rx()

static int ipv6_rx ( struct io_buffer iobuf,
struct net_device netdev,
const void *ll_dest  __unused,
const void *ll_source  __unused,
unsigned int flags  __unused 
)
static

Process incoming IPv6 packets.

Parameters
iobufI/O buffer
netdevNetwork device
ll_destLink-layer destination address
ll_sourceLink-layer destination source
flagsPacket flags
Return values
rcReturn status code

This function expects an IPv6 network datagram. It processes the headers and sends it to the transport layer.

Definition at line 649 of file ipv6.c.

652  {
653  struct ipv6_header *iphdr = iobuf->data;
654  union ipv6_extension_header *ext;
655  union {
656  struct sockaddr_in6 sin6;
657  struct sockaddr_tcpip st;
658  } src, dest;
659  uint16_t pshdr_csum;
660  size_t len;
661  size_t hdrlen;
662  size_t extlen;
663  int this_header;
664  int next_header;
665  int rc;
666 
667  /* Update statistics */
669  ipv6_stats.in_octets += iob_len ( iobuf );
670  if ( flags & LL_BROADCAST ) {
672  } else if ( flags & LL_MULTICAST ) {
674  }
675 
676  /* Sanity check the IPv6 header */
677  if ( iob_len ( iobuf ) < sizeof ( *iphdr ) ) {
678  DBGC ( ipv6col ( &iphdr->src ), "IPv6 packet too short at %zd "
679  "bytes (min %zd bytes)\n", iob_len ( iobuf ),
680  sizeof ( *iphdr ) );
681  rc = -EINVAL_LEN;
682  goto err_header;
683  }
684  if ( ( iphdr->ver_tc_label & htonl ( IPV6_MASK_VER ) ) !=
685  htonl ( IPV6_VER ) ) {
686  DBGC ( ipv6col ( &iphdr->src ), "IPv6 version %#08x not "
687  "supported\n", ntohl ( iphdr->ver_tc_label ) );
688  rc = -ENOTSUP_VER;
689  goto err_header;
690  }
691 
692  /* Truncate packet to specified length */
693  len = ntohs ( iphdr->len );
694  if ( len > iob_len ( iobuf ) ) {
695  DBGC ( ipv6col ( &iphdr->src ), "IPv6 length too long at %zd "
696  "bytes (packet is %zd bytes)\n", len, iob_len ( iobuf ));
698  rc = -EINVAL_LEN;
699  goto err_other;
700  }
701  iob_unput ( iobuf, ( iob_len ( iobuf ) - len - sizeof ( *iphdr ) ) );
702  hdrlen = sizeof ( *iphdr );
703 
704  /* Print IPv6 header for debugging */
705  DBGC2 ( ipv6col ( &iphdr->src ), "IPv6 RX %s<-",
706  inet6_ntoa ( &iphdr->dest ) );
707  DBGC2 ( ipv6col ( &iphdr->src ), "%s len %zd next %d\n",
708  inet6_ntoa ( &iphdr->src ), len, iphdr->next_header );
709 
710  /* Discard unicast packets not destined for us */
711  if ( ( ! ( flags & LL_MULTICAST ) ) &&
712  ( ! ipv6_has_addr ( netdev, &iphdr->dest ) ) ) {
713  DBGC ( ipv6col ( &iphdr->src ), "IPv6 discarding non-local "
714  "unicast packet for %s\n", inet6_ntoa ( &iphdr->dest ) );
716  rc = -EPIPE;
717  goto err_other;
718  }
719 
720  /* Process any extension headers */
721  next_header = iphdr->next_header;
722  while ( 1 ) {
723 
724  /* Extract extension header */
725  this_header = next_header;
726  ext = ( iobuf->data + hdrlen );
727  extlen = sizeof ( ext->pad );
728  if ( iob_len ( iobuf ) < ( hdrlen + extlen ) ) {
729  DBGC ( ipv6col ( &iphdr->src ), "IPv6 too short for "
730  "extension header type %d at %zd bytes (min "
731  "%zd bytes)\n", this_header,
732  ( iob_len ( iobuf ) - hdrlen ), extlen );
733  rc = -EINVAL_LEN;
734  goto err_header;
735  }
736 
737  /* Determine size of extension header (if applicable) */
738  if ( ( this_header == IPV6_HOPBYHOP ) ||
739  ( this_header == IPV6_DESTINATION ) ||
740  ( this_header == IPV6_ROUTING ) ) {
741  /* Length field is present */
742  extlen += ext->common.len;
743  } else if ( this_header == IPV6_FRAGMENT ) {
744  /* Length field is reserved and ignored (RFC2460) */
745  } else {
746  /* Not an extension header; assume rest is payload */
747  break;
748  }
749  if ( iob_len ( iobuf ) < ( hdrlen + extlen ) ) {
750  DBGC ( ipv6col ( &iphdr->src ), "IPv6 too short for "
751  "extension header type %d at %zd bytes (min "
752  "%zd bytes)\n", this_header,
753  ( iob_len ( iobuf ) - hdrlen ), extlen );
754  rc = -EINVAL_LEN;
755  goto err_header;
756  }
757  hdrlen += extlen;
758  next_header = ext->common.next_header;
759  DBGC2 ( ipv6col ( &iphdr->src ), "IPv6 RX %s<-",
760  inet6_ntoa ( &iphdr->dest ) );
761  DBGC2 ( ipv6col ( &iphdr->src ), "%s ext type %d len %zd next "
762  "%d\n", inet6_ntoa ( &iphdr->src ), this_header,
763  extlen, next_header );
764 
765  /* Process this extension header */
766  if ( ( this_header == IPV6_HOPBYHOP ) ||
767  ( this_header == IPV6_DESTINATION ) ) {
768 
769  /* Check that all options can be ignored */
770  if ( ( rc = ipv6_check_options ( iphdr, &ext->options,
771  extlen ) ) != 0 )
772  goto err_header;
773 
774  } else if ( this_header == IPV6_FRAGMENT ) {
775 
776  /* Reassemble fragments */
777  iobuf = fragment_reassemble ( &ipv6_reassembler, iobuf,
778  &hdrlen );
779  if ( ! iobuf )
780  return 0;
781  iphdr = iobuf->data;
782  }
783  }
784 
785  /* Construct socket address, calculate pseudo-header checksum,
786  * and hand off to transport layer
787  */
788  memset ( &src, 0, sizeof ( src ) );
789  src.sin6.sin6_family = AF_INET6;
790  memcpy ( &src.sin6.sin6_addr, &iphdr->src,
791  sizeof ( src.sin6.sin6_addr ) );
792  src.sin6.sin6_scope_id = netdev->index;
793  memset ( &dest, 0, sizeof ( dest ) );
794  dest.sin6.sin6_family = AF_INET6;
795  memcpy ( &dest.sin6.sin6_addr, &iphdr->dest,
796  sizeof ( dest.sin6.sin6_addr ) );
797  dest.sin6.sin6_scope_id = netdev->index;
798  iob_pull ( iobuf, hdrlen );
799  pshdr_csum = ipv6_pshdr_chksum ( iphdr, iob_len ( iobuf ),
800  next_header, TCPIP_EMPTY_CSUM );
801  if ( ( rc = tcpip_rx ( iobuf, netdev, next_header, &src.st, &dest.st,
802  pshdr_csum, &ipv6_stats ) ) != 0 ) {
803  DBGC ( ipv6col ( &src.sin6.sin6_addr ), "IPv6 received packet "
804  "rejected by stack: %s\n", strerror ( rc ) );
805  return rc;
806  }
807 
808  return 0;
809 
810  err_header:
812  err_other:
813  free_iob ( iobuf );
814  return rc;
815 }
#define LL_MULTICAST
Packet is a multicast (including broadcast) packet.
Definition: netdevice.h:105
#define iob_pull(iobuf, len)
Definition: iobuf.h:98
static struct ip_statistics ipv6_stats
IPv6 statistics.
Definition: ipv6.c:63
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
IPv6 header.
Definition: ipv6.h:35
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
unsigned long in_receives
ipSystemStatsInReceives
Definition: ipstat.h:50
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
#define TCPIP_EMPTY_CSUM
Empty checksum value.
Definition: tcpip.h:57
struct in_addr src
Definition: ip.h:44
#define ENOTSUP_VER
Definition: ipv6.c:49
IPv6 hop-by-hop options header type.
Definition: ipv6.h:136
unsigned long in_addr_errors
ipSystemStatsInAddrErrors
Definition: ipstat.h:76
int tcpip_rx(struct io_buffer *iobuf, struct net_device *netdev, uint8_t tcpip_proto, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum, struct ip_statistics *stats)
Process a received TCP/IP packet.
Definition: tcpip.c:40
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define EPIPE
Broken pipe.
Definition: errno.h:619
#define DBGC(...)
Definition: compiler.h:505
static uint32_t ipv6col(struct in6_addr *in)
Determine debugging colour for IPv6 debug messages.
Definition: ipv6.c:78
struct sockaddr_in6 sin6
Definition: syslog.c:58
static uint16_t ipv6_pshdr_chksum(struct ipv6_header *iphdr, size_t len, int next_header, uint16_t csum)
Calculate IPv6 pseudo-header checksum.
Definition: ipv6.c:496
IPv6 destination options header type.
Definition: ipv6.h:144
#define ntohl(value)
Definition: byteswap.h:134
#define ntohs(value)
Definition: byteswap.h:136
An IPv4 packet header.
Definition: ip.h:35
#define htonl(value)
Definition: byteswap.h:133
struct sockaddr_tcpip st
Definition: syslog.c:56
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned long in_mcast_pkts
ipSystemStatsInMcastPkts
Definition: ipstat.h:150
IPv6 fragment header type.
Definition: ipv6.h:140
struct io_buffer * fragment_reassemble(struct fragment_reassembler *fragments, struct io_buffer *iobuf, size_t *hdrlen)
Reassemble packet.
Definition: fragment.c:88
IPv6 extension header.
Definition: ipv6.h:116
static struct fragment_reassembler ipv6_reassembler
Fragment reassembler.
Definition: ipv6.c:479
uint16_t len
Definition: ip.h:38
unsigned long in_truncated_pkts
ipSystemStatsInTruncatedPkts
Definition: ipstat.h:89
static struct net_device * netdev
Definition: gdbudp.c:52
IPv6 routing header type.
Definition: ipv6.h:138
static void * dest
Definition: strings.h:176
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
#define iob_unput(iobuf, len)
Definition: iobuf.h:131
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
#define IPV6_MASK_VER
IPv6 version mask.
Definition: ipv6.h:23
struct in_addr dest
Definition: ip.h:45
#define EINVAL_LEN
Definition: ipv6.c:46
static int ipv6_check_options(struct ipv6_header *iphdr, struct ipv6_options_header *options, size_t len)
Check that received options can be safely ignored.
Definition: ipv6.c:404
uint16_t ext
Extended status.
Definition: ena.h:20
#define LL_BROADCAST
Packet is a broadcast packet.
Definition: netdevice.h:108
#define IPV6_VER
IPv6 version.
Definition: ipv6.h:20
uint32_t len
Length.
Definition: ena.h:14
unsigned int index
Index of this network device.
Definition: netdevice.h:356
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:44
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
IPv6 socket address.
Definition: in.h:115
unsigned long in_hdr_errors
ipSystemStatsInHdrErrors
Definition: ipstat.h:65
unsigned long in_bcast_pkts
ipSystemStatsInBcastPkts
Definition: ipstat.h:160
unsigned long in_octets
ipSystemStatsInOctets
Definition: ipstat.h:57
void * memset(void *dest, int character, size_t len) __nonnull
uint8_t flags
Flags.
Definition: ena.h:18

References AF_INET6, io_buffer::data, DBGC, DBGC2, iphdr::dest, dest, EINVAL_LEN, ENOTSUP_VER, EPIPE, ext, flags, fragment_reassemble(), free_iob(), htonl, ip_statistics::in_addr_errors, ip_statistics::in_bcast_pkts, ip_statistics::in_hdr_errors, ip_statistics::in_mcast_pkts, ip_statistics::in_octets, ip_statistics::in_receives, ip_statistics::in_truncated_pkts, net_device::index, inet6_ntoa(), iob_len(), iob_pull, iob_unput, ipv6_check_options(), IPV6_DESTINATION, IPV6_FRAGMENT, ipv6_has_addr(), IPV6_HOPBYHOP, IPV6_MASK_VER, ipv6_pshdr_chksum(), ipv6_reassembler, IPV6_ROUTING, ipv6_stats, IPV6_VER, ipv6col(), len, iphdr::len, LL_BROADCAST, LL_MULTICAST, memcpy(), memset(), netdev, ntohl, ntohs, rc, sin6, iphdr::src, src, st, strerror(), TCPIP_EMPTY_CSUM, and tcpip_rx().

◆ inet6_aton()

int inet6_aton ( const char *  string,
struct in6_addr in 
)

Parse IPv6 address.

Parameters
stringIPv6 address string
Return values
inIPv6 address to fill in
rcReturn status code

Definition at line 824 of file ipv6.c.

824  {
825  uint16_t *word = in->s6_addr16;
826  uint16_t *end = ( word + ( sizeof ( in->s6_addr16 ) /
827  sizeof ( in->s6_addr16[0] ) ) );
828  uint16_t *pad = NULL;
829  const char *nptr = string;
830  char *endptr;
831  unsigned long value;
832  size_t pad_len;
833  size_t move_len;
834 
835  /* Parse string */
836  while ( 1 ) {
837 
838  /* Parse current word */
839  value = strtoul ( nptr, &endptr, 16 );
840  if ( value > 0xffff ) {
841  DBG ( "IPv6 invalid word value %#lx in \"%s\"\n",
842  value, string );
843  return -EINVAL;
844  }
845  *(word++) = htons ( value );
846 
847  /* Parse separator */
848  if ( ! *endptr )
849  break;
850  if ( *endptr != ':' ) {
851  DBG ( "IPv6 invalid separator '%c' in \"%s\"\n",
852  *endptr, string );
853  return -EINVAL;
854  }
855  if ( ( endptr == nptr ) && ( nptr != string ) ) {
856  if ( pad ) {
857  DBG ( "IPv6 invalid multiple \"::\" in "
858  "\"%s\"\n", string );
859  return -EINVAL;
860  }
861  pad = word;
862  }
863  nptr = ( endptr + 1 );
864 
865  /* Check for overrun */
866  if ( word == end ) {
867  DBG ( "IPv6 too many words in \"%s\"\n", string );
868  return -EINVAL;
869  }
870  }
871 
872  /* Insert padding if specified */
873  if ( pad ) {
874  move_len = ( ( ( void * ) word ) - ( ( void * ) pad ) );
875  pad_len = ( ( ( void * ) end ) - ( ( void * ) word ) );
876  memmove ( ( ( ( void * ) pad ) + pad_len ), pad, move_len );
877  memset ( pad, 0, pad_len );
878  } else if ( word != end ) {
879  DBG ( "IPv6 underlength address \"%s\"\n", string );
880  return -EINVAL;
881  }
882 
883  return 0;
884 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
unsigned short uint16_t
Definition: stdint.h:11
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:456
__be32 in[4]
Definition: CIB_PRM.h:35
uint32_t string
Definition: multiboot.h:14
u32 pad[9]
Padding.
Definition: ar9003_mac.h:90
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
void * memmove(void *dest, const void *src, size_t len) __nonnull
unsigned short word
Definition: smc9000.h:39
uint32_t end
Ending offset.
Definition: netvsc.h:18
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define htons(value)
Definition: byteswap.h:135
void * memset(void *dest, int character, size_t len) __nonnull

References DBG, EINVAL, end, htons, in, memmove(), memset(), NULL, pad, string, strtoul(), and value.

Referenced by inet6_aton_fail_okx(), inet6_aton_okx(), ipv6_route_okx(), ipv6_sock_aton(), ipv6_table_okx(), and parse_ipv6_setting().

◆ inet6_ntoa()

char* inet6_ntoa ( const struct in6_addr in)

Convert IPv6 address to standard notation.

Parameters
inIPv6 address
Return values
stringIPv6 address string in canonical format

RFC5952 defines the canonical format for IPv6 textual representation.

Definition at line 894 of file ipv6.c.

894  {
895  static char buf[41]; /* ":xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" */
896  char *out = buf;
897  char *longest_start = NULL;
898  char *start = NULL;
899  int longest_len = 1;
900  int len = 0;
901  char *dest;
902  unsigned int i;
903  uint16_t value;
904 
905  /* Format address, keeping track of longest run of zeros */
906  for ( i = 0 ; i < ( sizeof ( in->s6_addr16 ) /
907  sizeof ( in->s6_addr16[0] ) ) ; i++ ) {
908  value = ntohs ( in->s6_addr16[i] );
909  if ( value == 0 ) {
910  if ( len++ == 0 )
911  start = out;
912  if ( len > longest_len ) {
913  longest_start = start;
914  longest_len = len;
915  }
916  } else {
917  len = 0;
918  }
919  out += sprintf ( out, ":%x", value );
920  }
921 
922  /* Abbreviate longest run of zeros, if applicable */
923  if ( longest_start ) {
924  dest = strcpy ( ( longest_start + 1 ),
925  ( longest_start + ( 2 * longest_len ) ) );
926  if ( dest[0] == '\0' )
927  dest[1] = '\0';
928  dest[0] = ':';
929  }
930  return ( ( longest_start == buf ) ? buf : ( buf + 1 ) );
931 }
unsigned short uint16_t
Definition: stdint.h:11
__be32 in[4]
Definition: CIB_PRM.h:35
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition: stdio.h:36
#define ntohs(value)
Definition: byteswap.h:136
uint32_t start
Starting offset.
Definition: netvsc.h:12
__be32 out[4]
Definition: CIB_PRM.h:36
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:311
static void * dest
Definition: strings.h:176
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
uint32_t len
Length.
Definition: ena.h:14
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References dest, in, len, ntohs, NULL, out, sprintf, start, strcpy(), and value.

Referenced by dhcpv6_rx(), format_ipv6_setting(), inet6_aton_okx(), inet6_ntoa_okx(), ipv6_dump_miniroute(), ipv6_ntoa(), ipv6_route_okx(), ipv6_rx(), ipv6_sock_ntoa(), ipv6_tx(), ndp_rx_neighbour_advertisement_ll_target(), ndp_rx_neighbour_solicitation_ll_source(), ndp_rx_router_advertisement_ll_source(), ndp_rx_router_advertisement_prefix(), and route_ipv6_print().

◆ ipv6_ntoa()

static const char* ipv6_ntoa ( const void *  net_addr)
static

Transcribe IPv6 address.

Parameters
net_addrIPv6 address
Return values
stringIPv6 address in standard notation

Definition at line 940 of file ipv6.c.

940  {
941  return inet6_ntoa ( net_addr );
942 }
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894

References inet6_ntoa().

◆ ipv6_sock_ntoa()

static const char* ipv6_sock_ntoa ( struct sockaddr sa)
static

Transcribe IPv6 socket address.

Parameters
saSocket address
Return values
stringSocket address in standard notation

Definition at line 950 of file ipv6.c.

950  {
951  static char buf[ 39 /* "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" */ +
952  1 /* "%" */ + NETDEV_NAME_LEN + 1 /* NUL */ ];
953  struct sockaddr_in6 *sin6 = ( ( struct sockaddr_in6 * ) sa );
954  struct in6_addr *in = &sin6->sin6_addr;
955  struct net_device *netdev;
956  const char *netdev_name;
957 
958  /* Identify network device, if applicable */
961  netdev_name = ( netdev ? netdev->name : "UNKNOWN" );
962  } else {
963  netdev_name = NULL;
964  }
965 
966  /* Format socket address */
967  snprintf ( buf, sizeof ( buf ), "%s%s%s", inet6_ntoa ( in ),
968  ( netdev_name ? "%" : "" ),
969  ( netdev_name ? netdev_name : "" ) );
970  return buf;
971 }
__be32 in[4]
Definition: CIB_PRM.h:35
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
struct sockaddr_in6 sin6
Definition: syslog.c:58
struct net_device * find_netdev_by_index(unsigned int index)
Get network device by index.
Definition: netdevice.c:915
uint16_t sin6_scope_id
Scope ID (part of struct sockaddr_tcpip)
Definition: in.h:130
#define NETDEV_NAME_LEN
Maximum length of a network device name.
Definition: netdevice.h:336
static struct net_device * netdev
Definition: gdbudp.c:52
struct sockaddr sa
Definition: syslog.c:55
IP6 address structure.
Definition: in.h:48
#define IN6_IS_ADDR_LINKLOCAL(addr)
Definition: in.h:68
A network device.
Definition: netdevice.h:348
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
#define IN6_IS_ADDR_MULTICAST(addr)
Definition: in.h:65
IPv6 socket address.
Definition: in.h:115
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:132

References find_netdev_by_index(), in, IN6_IS_ADDR_LINKLOCAL, IN6_IS_ADDR_MULTICAST, inet6_ntoa(), net_device::name, netdev, NETDEV_NAME_LEN, NULL, sa, sin6, sockaddr_in6::sin6_addr, sockaddr_in6::sin6_scope_id, and snprintf().

◆ ipv6_sock_aton()

static int ipv6_sock_aton ( const char *  string,
struct sockaddr sa 
)
static

Parse IPv6 socket address.

Parameters
stringSocket address string
saSocket address to fill in
Return values
rcReturn status code

Definition at line 980 of file ipv6.c.

980  {
981  struct sockaddr_in6 *sin6 = ( ( struct sockaddr_in6 * ) sa );
982  struct in6_addr in;
983  struct net_device *netdev;
984  size_t len;
985  char *tmp;
986  char *in_string;
987  char *netdev_string;
988  int rc;
989 
990  /* Create modifiable copy of string */
991  tmp = strdup ( string );
992  if ( ! tmp ) {
993  rc = -ENOMEM;
994  goto err_alloc;
995  }
996  in_string = tmp;
997 
998  /* Strip surrounding "[...]", if present */
999  len = strlen ( in_string );
1000  if ( ( in_string[0] == '[' ) && ( in_string[ len - 1 ] == ']' ) ) {
1001  in_string[ len - 1 ] = '\0';
1002  in_string++;
1003  }
1004 
1005  /* Split at network device name, if present */
1006  netdev_string = strchr ( in_string, '%' );
1007  if ( netdev_string )
1008  *(netdev_string++) = '\0';
1009 
1010  /* Parse IPv6 address portion */
1011  if ( ( rc = inet6_aton ( in_string, &in ) ) != 0 )
1012  goto err_inet6_aton;
1013 
1014  /* Parse scope ID, if applicable */
1015  if ( netdev_string ) {
1016 
1017  /* Parse explicit network device name, if present */
1018  netdev = find_netdev ( netdev_string );
1019  if ( ! netdev ) {
1020  rc = -ENODEV;
1021  goto err_find_netdev;
1022  }
1024 
1025  } else if ( IN6_IS_ADDR_LINKLOCAL ( &in ) ||
1026  IN6_IS_ADDR_MULTICAST ( &in ) ) {
1027 
1028  /* If no network device is explicitly specified for a
1029  * link-local or multicast address, default to using
1030  * "netX" (if existent).
1031  */
1033  if ( netdev )
1035  }
1036 
1037  /* Copy IPv6 address portion to socket address */
1038  memcpy ( &sin6->sin6_addr, &in, sizeof ( sin6->sin6_addr ) );
1039 
1040  err_find_netdev:
1041  err_inet6_aton:
1042  free ( tmp );
1043  err_alloc:
1044  return rc;
1045 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
__be32 in[4]
Definition: CIB_PRM.h:35
struct sockaddr_in6 sin6
Definition: syslog.c:58
uint16_t sin6_scope_id
Scope ID (part of struct sockaddr_tcpip)
Definition: in.h:130
int inet6_aton(const char *string, struct in6_addr *in)
Parse IPv6 address.
Definition: ipv6.c:824
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static struct net_device * netdev
Definition: gdbudp.c:52
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition: netdevice.c:973
struct sockaddr sa
Definition: syslog.c:55
IP6 address structure.
Definition: in.h:48
#define IN6_IS_ADDR_LINKLOCAL(addr)
Definition: in.h:68
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
char * strchr(const char *src, int character)
Find character within a string.
Definition: string.c:256
uint8_t * tmp
Definition: entropy.h:156
char * strdup(const char *src)
Duplicate string.
Definition: string.c:365
A network device.
Definition: netdevice.h:348
#define ENODEV
No such device.
Definition: errno.h:509
size_t strlen(const char *src)
Get length of string.
Definition: string.c:228
uint32_t len
Length.
Definition: ena.h:14
unsigned int index
Index of this network device.
Definition: netdevice.h:356
struct net_device * find_netdev(const char *name)
Get network device by name.
Definition: netdevice.c:893
#define IN6_IS_ADDR_MULTICAST(addr)
Definition: in.h:65
IPv6 socket address.
Definition: in.h:115
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:132

References ENODEV, ENOMEM, find_netdev(), free, in, IN6_IS_ADDR_LINKLOCAL, IN6_IS_ADDR_MULTICAST, net_device::index, inet6_aton(), last_opened_netdev(), len, memcpy(), netdev, rc, sa, sin6, sockaddr_in6::sin6_addr, sockaddr_in6::sin6_scope_id, strchr(), strdup(), strlen(), and tmp.

◆ parse_ipv6_setting()

int parse_ipv6_setting ( const struct setting_type *type  __unused,
const char *  value,
void *  buf,
size_t  len 
)

Parse IPv6 address setting value.

Parameters
typeSetting type
valueFormatted setting value
bufBuffer to contain raw value
lenLength of buffer
Return values
lenLength of raw value, or negative error

Definition at line 1082 of file ipv6.c.

1083  {
1084  struct in6_addr ipv6;
1085  int rc;
1086 
1087  /* Parse IPv6 address */
1088  if ( ( rc = inet6_aton ( value, &ipv6 ) ) != 0 )
1089  return rc;
1090 
1091  /* Copy to buffer */
1092  if ( len > sizeof ( ipv6 ) )
1093  len = sizeof ( ipv6 );
1094  memcpy ( buf, &ipv6, len );
1095 
1096  return ( sizeof ( ipv6 ) );
1097 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int inet6_aton(const char *string, struct in6_addr *in)
Parse IPv6 address.
Definition: ipv6.c:824
void * memcpy(void *dest, const void *src, size_t len) __nonnull
IP6 address structure.
Definition: in.h:48
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
uint32_t len
Length.
Definition: ena.h:14

References inet6_aton(), len, memcpy(), rc, and value.

◆ format_ipv6_setting()

int format_ipv6_setting ( const struct setting_type *type  __unused,
const void *  raw,
size_t  raw_len,
char *  buf,
size_t  len 
)

Format IPv6 address setting value.

Parameters
typeSetting type
rawRaw setting value
raw_lenLength of raw setting value
bufBuffer to contain formatted value
lenLength of buffer
Return values
lenLength of formatted value, or negative error

Definition at line 1109 of file ipv6.c.

1111  {
1112  const struct in6_addr *ipv6 = raw;
1113 
1114  if ( raw_len < sizeof ( *ipv6 ) )
1115  return -EINVAL;
1116  return snprintf ( buf, len, "%s", inet6_ntoa ( ipv6 ) );
1117 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
IP6 address structure.
Definition: in.h:48
static size_t raw_len
Definition: base16.h:50
uint32_t len
Length.
Definition: ena.h:14
__be32 raw[7]
Definition: CIB_PRM.h:28
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382

References EINVAL, inet6_ntoa(), len, raw, raw_len, and snprintf().

◆ __setting() [1/3]

const struct setting ip6_setting __setting ( SETTING_IP6  ,
ip6   
)

IPv6 address setting.

◆ __setting() [2/3]

const struct setting len6_setting __setting ( SETTING_IP6  ,
len6   
)

IPv6 prefix length setting.

◆ __setting() [3/3]

const struct setting gateway6_setting __setting ( SETTING_IP6  ,
gateway6   
)

Default gateway setting.

◆ ipv6_applies()

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

Check applicability of IPv6 link-local address setting.

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

Definition at line 1153 of file ipv6.c.

1154  {
1155 
1156  return ( setting->scope == &ipv6_settings_scope );
1157 }
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.

◆ ipv6_fetch()

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

Fetch IPv6 link-local address 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 1168 of file ipv6.c.

1169  {
1170  struct net_device *netdev =
1172  settings.settings );
1173  struct in6_addr ip6;
1174  uint8_t *len6;
1175  int prefix_len;
1176  int rc;
1177 
1178  /* Construct link-local address from EUI-64 as per RFC 2464 */
1179  memset ( &ip6, 0, sizeof ( ip6 ) );
1180  prefix_len = ipv6_link_local ( &ip6, netdev );
1181  if ( prefix_len < 0 ) {
1182  rc = prefix_len;
1183  return rc;
1184  }
1185 
1186  /* Handle setting */
1187  if ( setting_cmp ( setting, &ip6_setting ) == 0 ) {
1188 
1189  /* Return link-local ip6 */
1190  if ( len > sizeof ( ip6 ) )
1191  len = sizeof ( ip6 );
1192  memcpy ( data, &ip6, len );
1193  return sizeof ( ip6 );
1194 
1195  } else if ( setting_cmp ( setting, &len6_setting ) == 0 ) {
1196 
1197  /* Return prefix length */
1198  if ( len ) {
1199  len6 = data;
1200  *len6 = prefix_len;
1201  }
1202  return sizeof ( *len6 );
1203 
1204  }
1205 
1206  return -ENOENT;
1207 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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
static struct net_device * netdev
Definition: gdbudp.c:52
IP6 address structure.
Definition: in.h:48
A network device.
Definition: netdevice.h:348
A settings block.
Definition: settings.h:132
unsigned char uint8_t
Definition: stdint.h:10
A setting.
Definition: settings.h:23
uint32_t len
Length.
Definition: ena.h:14
static int ipv6_link_local(struct in6_addr *addr, struct net_device *netdev)
Construct link-local address via EUI-64.
Definition: ipv6.h:235
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:1124
void * memset(void *dest, int character, size_t len) __nonnull

References container_of, data, ENOENT, ipv6_link_local(), len, memcpy(), memset(), netdev, settings::parent, rc, and setting_cmp().

◆ ipv6_register_settings()

static int ipv6_register_settings ( struct net_device netdev)
static

Register IPv6 link-local address settings.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 1229 of file ipv6.c.

1229  {
1230  struct settings *parent = netdev_settings ( netdev );
1231  struct ipv6_settings *ipv6set;
1232  int rc;
1233 
1234  /* Allocate and initialise structure */
1235  ipv6set = zalloc ( sizeof ( *ipv6set ) );
1236  if ( ! ipv6set ) {
1237  rc = -ENOMEM;
1238  goto err_alloc;
1239  }
1240  ref_init ( &ipv6set->refcnt, NULL );
1242  &ipv6set->refcnt, &ipv6_settings_scope );
1244 
1245  /* Register settings */
1246  if ( ( rc = register_settings ( &ipv6set->settings, parent,
1247  IPV6_SETTINGS_NAME ) ) != 0 )
1248  goto err_register;
1249 
1250  err_register:
1251  ref_put ( &ipv6set->refcnt );
1252  err_alloc:
1253  return rc;
1254 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Link-local address.
Definition: ipv6.h:284
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
struct settings * parent
Parent settings block.
Definition: settings.h:138
struct settings settings
Settings interface.
Definition: ipv6.c:1220
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
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct refcnt refcnt
Reference counter.
Definition: ipv6.c:1218
#define IPV6_SETTINGS_NAME
IPv6 link-local address settings block name.
Definition: ipv6.h:292
static struct net_device * netdev
Definition: gdbudp.c:52
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
static struct settings_operations ipv6_settings_operations
IPv6 link-local address settings operations.
Definition: ipv6.c:1210
A settings block.
Definition: settings.h:132
int order
Sibling ordering.
Definition: settings.h:148
IPv6 link-local address settings.
Definition: ipv6.c:1216
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:478
const struct settings_scope ipv6_settings_scope
IPv6 settings scope.
Definition: ipv6.c:1120
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References ENOMEM, IPV6_ORDER_LINK_LOCAL, IPV6_SETTINGS_NAME, ipv6_settings_operations, ipv6_settings_scope, netdev, netdev_settings(), NULL, settings::order, settings::parent, rc, ref_init, ref_put, ipv6_settings::refcnt, register_settings(), ipv6_settings::settings, settings_init(), and zalloc().

◆ ipv6_create_routes()

static int ipv6_create_routes ( struct net_device netdev,
struct settings settings 
)
static

Create IPv6 routing table based on configured settings.

Parameters
netdevNetwork device
settingsSettings block
Return values
rcReturn status code

Definition at line 1269 of file ipv6.c.

1270  {
1271  struct settings *child;
1272  struct settings *origin;
1273  struct in6_addr ip6_buf;
1274  struct in6_addr gateway6_buf;
1275  struct in6_addr *ip6 = &ip6_buf;
1276  struct in6_addr *gateway6 = &gateway6_buf;
1277  uint8_t len6;
1278  size_t len;
1279  int rc;
1280 
1281  /* First, create routing table for any child settings. We do
1282  * this depth-first and in reverse order so that the end
1283  * result reflects the relative priorities of the settings
1284  * blocks.
1285  */
1286  list_for_each_entry_reverse ( child, &settings->children, siblings )
1287  ipv6_create_routes ( netdev, child );
1288 
1289  /* Fetch IPv6 address, if any */
1290  len = fetch_setting ( settings, &ip6_setting, &origin, NULL,
1291  ip6, sizeof ( *ip6 ) );
1292  if ( ( len != sizeof ( *ip6 ) ) || ( origin != settings ) )
1293  return 0;
1294 
1295  /* Fetch prefix length, if defined */
1296  len = fetch_setting ( settings, &len6_setting, &origin, NULL,
1297  &len6, sizeof ( len6 ) );
1298  if ( ( len != sizeof ( len6 ) ) || ( origin != settings ) )
1299  len6 = 0;
1300  if ( len6 > IPV6_MAX_PREFIX_LEN )
1301  len6 = IPV6_MAX_PREFIX_LEN;
1302 
1303  /* Fetch gateway, if defined */
1304  len = fetch_setting ( settings, &gateway6_setting, &origin, NULL,
1305  gateway6, sizeof ( *gateway6 ) );
1306  if ( ( len != sizeof ( *gateway6 ) ) || ( origin != settings ) )
1307  gateway6 = NULL;
1308 
1309  /* Create or update route */
1310  if ( ( rc = ipv6_add_miniroute ( netdev, ip6, len6, gateway6 ) ) != 0){
1311  DBGC ( netdev, "IPv6 %s could not add route: %s\n",
1312  netdev->name, strerror ( rc ) );
1313  return rc;
1314  }
1315 
1316  return 0;
1317 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint64_t origin
Origin.
Definition: hyperv.h:20
#define IPV6_MAX_PREFIX_LEN
IPv6 maximum prefix length.
Definition: ipv6.h:32
#define DBGC(...)
Definition: compiler.h:505
int ipv6_add_miniroute(struct net_device *netdev, struct in6_addr *address, unsigned int prefix_len, struct in6_addr *router)
Add IPv6 routing table entry.
Definition: ipv6.c:217
#define list_for_each_entry_reverse(pos, head, member)
Iterate over entries in a list in reverse order.
Definition: list.h:433
static struct net_device * netdev
Definition: gdbudp.c:52
IP6 address structure.
Definition: in.h:48
int fetch_setting(struct settings *settings, const struct setting *setting, struct settings **origin, struct setting *fetched, void *data, size_t len)
Fetch setting.
Definition: settings.c:670
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
A settings block.
Definition: settings.h:132
unsigned char uint8_t
Definition: stdint.h:10
static int ipv6_create_routes(struct net_device *netdev, struct settings *settings)
Create IPv6 routing table based on configured settings.
Definition: ipv6.c:1269
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
uint32_t len
Length.
Definition: ena.h:14
struct list_head children
Child settings blocks.
Definition: settings.h:142
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References settings::children, DBGC, fetch_setting(), ipv6_add_miniroute(), IPV6_MAX_PREFIX_LEN, len, list_for_each_entry_reverse, net_device::name, netdev, NULL, origin, rc, and strerror().

Referenced by ipv6_create_all_routes().

◆ ipv6_create_all_routes()

static int ipv6_create_all_routes ( void  )
static

Create IPv6 routing table based on configured settings.

Return values
rcReturn status code

Definition at line 1324 of file ipv6.c.

1324  {
1325  struct ipv6_miniroute *miniroute;
1326  struct ipv6_miniroute *tmp;
1327  struct net_device *netdev;
1328  struct settings *settings;
1329  int rc;
1330 
1331  /* Delete all existing routes */
1332  list_for_each_entry_safe ( miniroute, tmp, &ipv6_miniroutes, list )
1333  ipv6_del_miniroute ( miniroute );
1334 
1335  /* Create routes for each configured network device */
1336  for_each_netdev ( netdev ) {
1338  if ( ( rc = ipv6_create_routes ( netdev, settings ) ) != 0 )
1339  return rc;
1340  }
1341 
1342  return 0;
1343 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:577
An IPv6 address/routing table entry.
Definition: ipv6.h:180
void ipv6_del_miniroute(struct ipv6_miniroute *miniroute)
Delete IPv6 minirouting table entry.
Definition: ipv6.c:292
static struct net_device * netdev
Definition: gdbudp.c:52
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:447
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:526
uint8_t * tmp
Definition: entropy.h:156
A network device.
Definition: netdevice.h:348
struct list_head ipv6_miniroutes
List of IPv6 miniroutes.
Definition: ipv6.c:60
A settings block.
Definition: settings.h:132
static int ipv6_create_routes(struct net_device *netdev, struct settings *settings)
Create IPv6 routing table based on configured settings.
Definition: ipv6.c:1269

References for_each_netdev, ipv6_create_routes(), ipv6_del_miniroute(), ipv6_miniroutes, list_for_each_entry_safe, netdev, netdev_settings(), rc, and tmp.

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( ipv6_protocol  )

◆ REQUIRE_OBJECT() [1/2]

REQUIRE_OBJECT ( icmpv6  )

◆ REQUIRE_OBJECT() [2/2]

REQUIRE_OBJECT ( ndp  )

Variable Documentation

◆ ipv6_miniroutes

struct list_head ipv6_miniroutes = LIST_HEAD_INIT ( ipv6_miniroutes )

◆ ipv6_stats

struct ip_statistics ipv6_stats
static

IPv6 statistics.

Definition at line 63 of file ipv6.c.

Referenced by ipv6_rx(), and ipv6_tx().

◆ ipv6_reassembler

struct fragment_reassembler ipv6_reassembler
static
Initial value:
= {
.is_fragment = ipv6_is_fragment,
.fragment_offset = ipv6_fragment_offset,
.more_fragments = ipv6_more_fragments,
.stats = &ipv6_stats,
}
static struct ip_statistics ipv6_stats
IPv6 statistics.
Definition: ipv6.c:63
static int ipv6_is_fragment(struct fragment *fragment, struct io_buffer *iobuf, size_t hdrlen)
Check if fragment matches fragment reassembly buffer.
Definition: ipv6.c:435
static struct fragment_reassembler ipv6_reassembler
Fragment reassembler.
Definition: ipv6.c:479
static size_t ipv6_fragment_offset(struct io_buffer *iobuf, size_t hdrlen)
Get fragment offset.
Definition: ipv6.c:457
static int ipv6_more_fragments(struct io_buffer *iobuf, size_t hdrlen)
Check if more fragments exist.
Definition: ipv6.c:471
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30
struct list_head list
List of fragment reassembly buffers.
Definition: fragment.h:37

Fragment reassembler.

Definition at line 479 of file ipv6.c.

Referenced by ipv6_rx().

◆ __net_protocol

struct net_protocol ipv6_protocol __net_protocol
Initial value:
= {
.name = "IPv6",
.net_proto = htons ( ETH_P_IPV6 ),
.net_addr_len = sizeof ( struct in6_addr ),
.rx = ipv6_rx,
.ntoa = ipv6_ntoa,
}
static int ipv6_rx(struct io_buffer *iobuf, struct net_device *netdev, const void *ll_dest __unused, const void *ll_source __unused, unsigned int flags __unused)
Process incoming IPv6 packets.
Definition: ipv6.c:649
static const char * ipv6_ntoa(const void *net_addr)
Transcribe IPv6 address.
Definition: ipv6.c:940
IP6 address structure.
Definition: in.h:48
uint32_t rx
Maximum number of receive queues.
Definition: intelvf.h:16
#define ETH_P_IPV6
Definition: if_ether.h:22
#define htons(value)
Definition: byteswap.h:135

IPv6 protocol.

AoE protocol.

Definition at line 1048 of file ipv6.c.

◆ __tcpip_net_protocol

struct tcpip_net_protocol ipv6_tcpip_protocol __tcpip_net_protocol
Initial value:
= {
.name = "IPv6",
.sa_family = AF_INET6,
.header_len = sizeof ( struct ipv6_header ),
.net_protocol = &ipv6_protocol,
.tx = ipv6_tx,
.netdev = ipv6_netdev,
}
IPv6 header.
Definition: ipv6.h:35
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
static struct net_device * ipv6_netdev(struct sockaddr_tcpip *st_dest)
Determine transmitting network device.
Definition: ipv6.c:383
A network-layer protocol.
Definition: netdevice.h:64
static int ipv6_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 IPv6 packet.
Definition: ipv6.c:525

IPv6 TCPIP net protocol.

Definition at line 1057 of file ipv6.c.

◆ __sockaddr_converter

struct sockaddr_converter ipv6_sockaddr_converter __sockaddr_converter
Initial value:
= {
.family = AF_INET6,
.ntoa = ipv6_sock_ntoa,
.aton = ipv6_sock_aton,
}
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
static int ipv6_sock_aton(const char *string, struct sockaddr *sa)
Parse IPv6 socket address.
Definition: ipv6.c:980
static const char * ipv6_sock_ntoa(struct sockaddr *sa)
Transcribe IPv6 socket address.
Definition: ipv6.c:950

IPv6 socket address converter.

Definition at line 1067 of file ipv6.c.

◆ ipv6_settings_scope

const struct settings_scope ipv6_settings_scope

IPv6 settings scope.

IPv6 setting scope.

Definition at line 1120 of file ipv6.c.

Referenced by ipv6_applies(), ipv6_register_settings(), and ndp_prefix_applies().

◆ ipv6_settings_operations

struct settings_operations ipv6_settings_operations
static
Initial value:
= {
.applies = ipv6_applies,
.fetch = ipv6_fetch,
}
static int ipv6_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of IPv6 link-local address setting.
Definition: ipv6.c:1153
static int ipv6_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch IPv6 link-local address setting.
Definition: ipv6.c:1168

IPv6 link-local address settings operations.

Definition at line 1210 of file ipv6.c.

Referenced by ipv6_register_settings().

◆ __net_driver

struct net_driver ipv6_driver __net_driver
Initial value:
= {
.name = "IPv6",
}
static int ipv6_register_settings(struct net_device *netdev)
Register IPv6 link-local address settings.
Definition: ipv6.c:1229

IPv6 network device driver.

Definition at line 1257 of file ipv6.c.

◆ __settings_applicator

struct settings_applicator ipv6_settings_applicator __settings_applicator
Initial value:
= {
}
static int ipv6_create_all_routes(void)
Create IPv6 routing table based on configured settings.
Definition: ipv6.c:1324

IPv6 settings applicator.

Definition at line 1346 of file ipv6.c.