iPXE
Data Structures | Defines | Enumerations | Functions | Variables
ipv6.h File Reference

IPv6 protocol. More...

#include <stdint.h>
#include <string.h>
#include <byteswap.h>
#include <ipxe/in.h>
#include <ipxe/list.h>
#include <ipxe/netdevice.h>

Go to the source code of this file.

Data Structures

struct  ipv6_header
 IPv6 header. More...
struct  ipv6_extension_header_common
 IPv6 extension header common fields. More...
struct  ipv6_option
 IPv6 type-length-value options. More...
struct  ipv6_options_header
 IPv6 option-based extension header. More...
struct  ipv6_routing_header
 IPv6 routing header. More...
struct  ipv6_fragment_header
 IPv6 fragment header. More...
union  ipv6_extension_header
 IPv6 extension header. More...
struct  ipv6_pseudo_header
 IPv6 pseudo-header. More...
struct  ipv6_miniroute
 An IPv6 address/routing table entry. More...

Defines

#define IPV6_VER   0x60000000UL
 IPv6 version.
#define IPV6_MASK_VER   0xf0000000UL
 IPv6 version mask.
#define IPV6_HOP_LIMIT   0xff
 IPv6 maximum hop limit.
#define IPV6_DEFAULT_PREFIX_LEN   64
 IPv6 default prefix length.
#define IPV6_MAX_PREFIX_LEN   128
 IPv6 maximum prefix length.
#define IPV6_CAN_IGNORE_OPT(type)   ( ( (type) & 0xc0 ) == 0x00 )
 Test if IPv6 option can be safely ignored.
#define IPV6_MASK_OFFSET   0xfff8
 Fragment offset mask.
#define IPV6_MASK_MOREFRAGS   0x0001
 More fragments.
#define IPV6_SETTINGS_NAME   "link"
 IPv6 link-local address settings block name.

Enumerations

enum  ipv6_option_type { IPV6_OPT_PAD1 = 0x00, IPV6_OPT_PADN = 0x01 }
 IPv6 option types. More...
enum  ipv6_header_type {
  IPV6_HOPBYHOP = 0, IPV6_ROUTING = 43, IPV6_FRAGMENT = 44, IPV6_NO_HEADER = 59,
  IPV6_DESTINATION = 60
}
 IPv6 header types. More...
enum  ipv6_address_scope {
  IPV6_SCOPE_INTERFACE_LOCAL = 0x1, IPV6_SCOPE_LINK_LOCAL = 0x2, INV6_SCOPE_ADMIN_LOCAL = 0x4, IPV6_SCOPE_SITE_LOCAL = 0x5,
  IPV6_SCOPE_ORGANISATION_LOCAL = 0x8, IPV6_SCOPE_GLOBAL = 0xe, IPV6_SCOPE_MAX = 0xf
}
 IPv6 address scopes. More...
enum  ipv6_miniroute_flags { IPV6_HAS_ADDRESS = 0x0001, IPV6_HAS_ROUTER = 0x0002 }
 IPv6 address/routing table entry flags. More...
enum  ipv6_settings_order { IPV6_ORDER_PREFIX_ONLY = -4, IPV6_ORDER_LINK_LOCAL = -3, IPV6_ORDER_SLAAC = -2, IPV6_ORDER_DHCPV6 = -1 }
 IPv6 settings sibling order. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int ipv6_eui64 (struct in6_addr *addr, struct net_device *netdev)
 Construct local IPv6 address via EUI-64.
static int ipv6_link_local (struct in6_addr *addr, struct net_device *netdev)
 Construct link-local address via EUI-64.
static void ipv6_solicited_node (struct in6_addr *addr, const struct in6_addr *unicast)
 Construct solicited-node multicast address.
static void ipv6_all_routers (struct in6_addr *addr)
 Construct all-routers multicast address.
static unsigned int ipv6_multicast_scope (const struct in6_addr *addr)
 Get multicast address scope.
int ipv6_has_addr (struct net_device *netdev, struct in6_addr *addr)
 Check if network device has a specific IPv6 address.
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.
void ipv6_del_miniroute (struct ipv6_miniroute *miniroute)
 Delete IPv6 minirouting table entry.
struct ipv6_minirouteipv6_route (unsigned int scope_id, struct in6_addr **dest)
 Perform IPv6 routing.
int parse_ipv6_setting (const struct setting_type *type, const char *value, void *buf, size_t len)
int format_ipv6_setting (const struct setting_type *type, const void *raw, size_t raw_len, char *buf, size_t len)

Variables

struct list_head ipv6_miniroutes
 List of IPv6 miniroutes.
struct net_protocol ipv6_protocol __net_protocol
 AoE protocol.

Detailed Description

IPv6 protocol.

Definition in file ipv6.h.


Define Documentation

#define IPV6_VER   0x60000000UL

IPv6 version.

Definition at line 20 of file ipv6.h.

Referenced by ipv6_rx(), and ipv6_tx().

#define IPV6_MASK_VER   0xf0000000UL

IPv6 version mask.

Definition at line 23 of file ipv6.h.

Referenced by ipv6_rx().

#define IPV6_HOP_LIMIT   0xff

IPv6 maximum hop limit.

Definition at line 26 of file ipv6.h.

Referenced by ipv6_tx().

#define IPV6_DEFAULT_PREFIX_LEN   64

IPv6 default prefix length.

Definition at line 29 of file ipv6.h.

Referenced by ipv6_add_miniroute().

#define IPV6_MAX_PREFIX_LEN   128

IPv6 maximum prefix length.

Definition at line 32 of file ipv6.h.

Referenced by ipv6_add_miniroute(), and ipv6_create_routes().

#define IPV6_CAN_IGNORE_OPT (   type)    ( ( (type) & 0xc0 ) == 0x00 )

Test if IPv6 option can be safely ignored.

Definition at line 77 of file ipv6.h.

Referenced by ipv6_check_options().

#define IPV6_MASK_OFFSET   0xfff8

Fragment offset mask.

Definition at line 110 of file ipv6.h.

Referenced by ipv6_fragment_offset().

#define IPV6_MASK_MOREFRAGS   0x0001

More fragments.

Definition at line 113 of file ipv6.h.

Referenced by ipv6_more_fragments().

#define IPV6_SETTINGS_NAME   "link"

IPv6 link-local address settings block name.

Definition at line 292 of file ipv6.h.

Referenced by ipv6_register_settings().


Enumeration Type Documentation

IPv6 option types.

Enumerator:
IPV6_OPT_PAD1 

Pad1.

IPV6_OPT_PADN 

PadN.

Definition at line 69 of file ipv6.h.

                      {
        /** Pad1 */
        IPV6_OPT_PAD1 = 0x00,
        /** PadN */
        IPV6_OPT_PADN = 0x01,
};

IPv6 header types.

Enumerator:
IPV6_HOPBYHOP 

IPv6 hop-by-hop options header type.

IPV6_ROUTING 

IPv6 routing header type.

IPV6_FRAGMENT 

IPv6 fragment header type.

IPV6_NO_HEADER 

IPv6 no next header type.

IPV6_DESTINATION 

IPv6 destination options header type.

Definition at line 134 of file ipv6.h.

                      {
        /** IPv6 hop-by-hop options header type */
        IPV6_HOPBYHOP = 0,
        /** IPv6 routing header type */
        IPV6_ROUTING = 43,
        /** IPv6 fragment header type */
        IPV6_FRAGMENT = 44,
        /** IPv6 no next header type */
        IPV6_NO_HEADER = 59,
        /** IPv6 destination options header type */
        IPV6_DESTINATION = 60,
};

IPv6 address scopes.

Enumerator:
IPV6_SCOPE_INTERFACE_LOCAL 

Interface-local address scope.

IPV6_SCOPE_LINK_LOCAL 

Link-local address scope.

INV6_SCOPE_ADMIN_LOCAL 

Admin-local address scope.

IPV6_SCOPE_SITE_LOCAL 

Site-local address scope.

IPV6_SCOPE_ORGANISATION_LOCAL 

Organisation-local address scope.

IPV6_SCOPE_GLOBAL 

Global address scope.

IPV6_SCOPE_MAX 

Maximum scope.

Definition at line 162 of file ipv6.h.

                        {
        /** Interface-local address scope */
        IPV6_SCOPE_INTERFACE_LOCAL = 0x1,
        /** Link-local address scope */
        IPV6_SCOPE_LINK_LOCAL = 0x2,
        /** Admin-local address scope */
        INV6_SCOPE_ADMIN_LOCAL = 0x4,
        /** Site-local address scope */
        IPV6_SCOPE_SITE_LOCAL = 0x5,
        /** Organisation-local address scope */
        IPV6_SCOPE_ORGANISATION_LOCAL = 0x8,
        /** Global address scope */
        IPV6_SCOPE_GLOBAL = 0xe,
        /** Maximum scope */
        IPV6_SCOPE_MAX = 0xf,
};

IPv6 address/routing table entry flags.

Enumerator:
IPV6_HAS_ADDRESS 

Routing table entry address is valid.

IPV6_HAS_ROUTER 

Routing table entry router address is valid.

Definition at line 202 of file ipv6.h.

                          {
        /** Routing table entry address is valid */
        IPV6_HAS_ADDRESS = 0x0001,
        /** Routing table entry router address is valid */
        IPV6_HAS_ROUTER = 0x0002,
};

IPv6 settings sibling order.

Enumerator:
IPV6_ORDER_PREFIX_ONLY 

No address.

IPV6_ORDER_LINK_LOCAL 

Link-local address.

IPV6_ORDER_SLAAC 

Address assigned via SLAAC.

IPV6_ORDER_DHCPV6 

Address assigned via DHCPv6.

Definition at line 280 of file ipv6.h.

                         {
        /** No address */
        IPV6_ORDER_PREFIX_ONLY = -4,
        /** Link-local address */
        IPV6_ORDER_LINK_LOCAL = -3,
        /** Address assigned via SLAAC */
        IPV6_ORDER_SLAAC = -2,
        /** Address assigned via DHCPv6 */
        IPV6_ORDER_DHCPV6 = -1,
};

Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static int ipv6_eui64 ( struct in6_addr addr,
struct net_device netdev 
) [inline, static]

Construct local IPv6 address via EUI-64.

Parameters:
addrPrefix to be completed
netdevNetwork device
Return values:
prefix_lenPrefix length, or negative error

Definition at line 216 of file ipv6.h.

References ll_protocol::eui64, net_device::ll_addr, net_device::ll_protocol, and rc.

Referenced by ipv6_link_local(), and ndp_prefix_fetch_ip6().

                                                           {
        struct ll_protocol *ll_protocol = netdev->ll_protocol;
        const void *ll_addr = netdev->ll_addr;
        int rc;

        if ( ( rc = ll_protocol->eui64 ( ll_addr, &addr->s6_addr[8] ) ) != 0 )
                return rc;
        addr->s6_addr[8] ^= 0x02;
        return 64;
}
static int ipv6_link_local ( struct in6_addr addr,
struct net_device netdev 
) [inline, static]

Construct link-local address via EUI-64.

Parameters:
addrZeroed address to construct
netdevNetwork device
Return values:
prefix_lenPrefix length, or negative error

Definition at line 235 of file ipv6.h.

References htons, and ipv6_eui64().

Referenced by ipv6_fetch().

                                                                {

        addr->s6_addr16[0] = htons ( 0xfe80 );
        return ipv6_eui64 ( addr, netdev );
}
static void ipv6_solicited_node ( struct in6_addr addr,
const struct in6_addr unicast 
) [inline, static]

Construct solicited-node multicast address.

Parameters:
addrZeroed address to construct
unicastUnicast address

Definition at line 248 of file ipv6.h.

References htons, and memcpy().

Referenced by ndp_tx_request().

                                                                          {

        addr->s6_addr16[0] = htons ( 0xff02 );
        addr->s6_addr[11] = 1;
        addr->s6_addr[12] = 0xff;
        memcpy ( &addr->s6_addr[13], &unicast->s6_addr[13], 3 );
}
static void ipv6_all_routers ( struct in6_addr addr) [inline, static]

Construct all-routers multicast address.

Parameters:
addrZeroed address to construct

Definition at line 262 of file ipv6.h.

References htons.

Referenced by ndp_tx_router_solicitation().

                                                              {
        addr->s6_addr16[0] = htons ( 0xff02 );
        addr->s6_addr[15] = 2;
}
static unsigned int ipv6_multicast_scope ( const struct in6_addr addr) [inline, static]

Get multicast address scope.

Parameters:
addrMulticast address
Return values:
scopeAddress scope

Definition at line 274 of file ipv6.h.

Referenced by ipv6_scope().

                                                     {

        return ( addr->s6_addr[1] & 0x0f );
}
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.

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

Referenced by ipv6_rx(), and ndp_rx_neighbour_solicitation_ll_source().

                                                                       {
        struct ipv6_miniroute *miniroute;

        list_for_each_entry ( miniroute, &ipv6_miniroutes, list ) {
                if ( ( miniroute->netdev == netdev ) &&
                     ( miniroute->flags & IPV6_HAS_ADDRESS ) &&
                     ( memcmp ( &miniroute->address, addr,
                                sizeof ( miniroute->address ) ) == 0 ) ) {
                        /* Found matching address */
                        return 1;
                }
        }
        return 0;
}
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.

References 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_scope(), ipv6_miniroute::list, list_add, list_del, memcpy(), 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().

                                                                            {
        struct ipv6_miniroute *miniroute;
        uint8_t *prefix_mask;
        unsigned int remaining;
        unsigned int i;

        /* Find or create routing table entry */
        miniroute = ipv6_miniroute ( netdev, address );
        if ( miniroute ) {

                /* Remove from existing position in routing table */
                list_del ( &miniroute->list );

        } else {

                /* Create new routing table entry */
                miniroute = zalloc ( sizeof ( *miniroute ) );
                if ( ! miniroute )
                        return -ENOMEM;
                miniroute->netdev = netdev_get ( netdev );
                memcpy ( &miniroute->address, address,
                         sizeof ( miniroute->address ) );

                /* Default to prefix length of 64 if none specified */
                if ( ! prefix_len )
                        prefix_len = IPV6_DEFAULT_PREFIX_LEN;
                miniroute->prefix_len = prefix_len;
                assert ( prefix_len <= IPV6_MAX_PREFIX_LEN );

                /* Construct prefix mask */
                remaining = prefix_len;
                for ( prefix_mask = miniroute->prefix_mask.s6_addr ;
                      remaining >= 8 ; prefix_mask++, remaining -= 8 ) {
                        *prefix_mask = 0xff;
                }
                if ( remaining )
                        *prefix_mask <<= ( 8 - remaining );
        }

        /* Add to start of routing table */
        list_add ( &miniroute->list, &ipv6_miniroutes );

        /* Set or update address, if applicable */
        for ( i = 0 ; i < ( sizeof ( address->s6_addr32 ) /
                            sizeof ( address->s6_addr32[0] ) ) ; i++ ) {
                if ( ( address->s6_addr32[i] &
                       ~miniroute->prefix_mask.s6_addr32[i] ) != 0 ) {
                        memcpy ( &miniroute->address, address,
                                 sizeof ( miniroute->address ) );
                        miniroute->flags |= IPV6_HAS_ADDRESS;
                }
        }
        if ( miniroute->prefix_len == IPV6_MAX_PREFIX_LEN )
                miniroute->flags |= IPV6_HAS_ADDRESS;

        /* Update scope */
        miniroute->scope = ipv6_scope ( &miniroute->address );

        /* Set or update router, if applicable */
        if ( router ) {
                memcpy ( &miniroute->router, router,
                         sizeof ( miniroute->router ) );
                miniroute->flags |= IPV6_HAS_ROUTER;
        }

        ipv6_dump_miniroute ( miniroute );
        return 0;
}
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.

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

Referenced by ipv6_create_all_routes(), and ipv6_table_del().

                                                             {

        netdev_put ( miniroute->netdev );
        list_del ( &miniroute->list );
        free ( miniroute );
}
struct ipv6_miniroute* ipv6_route ( unsigned int  scope_id,
struct in6_addr **  dest 
) [read]

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.

References ipv6_miniroute::flags, IN6_IS_ADDR_MULTICAST, net_device::index, IPV6_HAS_ADDRESS, IPV6_HAS_ROUTER, ipv6_match_len(), 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, ipv6_miniroute::scope, and scope.

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

                                                              {
        struct ipv6_miniroute *miniroute;
        struct ipv6_miniroute *chosen = NULL;
        unsigned int best = 0;
        unsigned int match_len;
        unsigned int score;
        unsigned int scope;

        /* Calculate destination address scope */
        scope = ipv6_scope ( *dest );

        /* Find first usable route in routing table */
        list_for_each_entry ( miniroute, &ipv6_miniroutes, list ) {

                /* Skip closed network devices */
                if ( ! netdev_is_open ( miniroute->netdev ) )
                        continue;

                /* Skip entries with no usable source address */
                if ( ! ( miniroute->flags & IPV6_HAS_ADDRESS ) )
                        continue;

                /* Skip entries with a non-matching scope ID, if
                 * destination specifies a scope ID.
                 */
                if ( scope_id && ( miniroute->netdev->index != scope_id ) )
                        continue;

                /* Skip entries that are out of scope */
                if ( miniroute->scope < scope )
                        continue;

                /* Calculate match length */
                match_len = ipv6_match_len ( miniroute, *dest );

                /* If destination is on-link, then use this route */
                if ( match_len >= miniroute->prefix_len )
                        return miniroute;

                /* If destination is unicast, then skip off-link
                 * entries with no router.
                 */
                if ( ! ( IN6_IS_ADDR_MULTICAST ( *dest ) ||
                         ( miniroute->flags & IPV6_HAS_ROUTER ) ) )
                        continue;

                /* Choose best route, defined as being the route with
                 * the smallest viable scope.  If two routes both have
                 * the same scope, then prefer the route with the
                 * longest match length.
                 */
                score = ( ( ( IPV6_SCOPE_MAX + 1 - miniroute->scope ) << 8 )
                          + match_len );
                if ( score > best ) {
                        chosen = miniroute;
                        best = score;
                }
        }

        /* Return chosen route, if any */
        if ( chosen ) {
                if ( ! IN6_IS_ADDR_MULTICAST ( *dest ) )
                        *dest = &chosen->router;
                return chosen;
        }

        return NULL;
}
int parse_ipv6_setting ( const struct setting_type type,
const char *  value,
void *  buf,
size_t  len 
)
int format_ipv6_setting ( const struct setting_type type,
const void *  raw,
size_t  raw_len,
char *  buf,
size_t  len 
)

Variable Documentation

List of IPv6 miniroutes.

Definition at line 60 of file ipv6.c.

Referenced by ipv6_route_okx(), ipv6_table_del(), ipv6_table_okx(), and route_ipv6_print().

struct net_protocol ipv6_protocol __net_protocol

AoE protocol.

AoE protocol.

FIP protocol.

Definition at line 55 of file aoe.c.