123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- #ifndef _IPXE_IPV6_H
- #define _IPXE_IPV6_H
-
- /** @file
- *
- * IPv6 protocol
- *
- */
-
- FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
- #include <stdint.h>
- #include <string.h>
- #include <byteswap.h>
- #include <ipxe/in.h>
- #include <ipxe/list.h>
- #include <ipxe/netdevice.h>
-
- /** IPv6 version */
- #define IPV6_VER 0x60000000UL
-
- /** IPv6 version mask */
- #define IPV6_MASK_VER 0xf0000000UL
-
- /** IPv6 maximum hop limit */
- #define IPV6_HOP_LIMIT 0xff
-
- /** IPv6 default prefix length */
- #define IPV6_DEFAULT_PREFIX_LEN 64
-
- /** IPv6 maximum prefix length */
- #define IPV6_MAX_PREFIX_LEN 128
-
- /** IPv6 header */
- struct ipv6_header {
- /** Version (4 bits), Traffic class (8 bits), Flow label (20 bits) */
- uint32_t ver_tc_label;
- /** Payload length, including any extension headers */
- uint16_t len;
- /** Next header type */
- uint8_t next_header;
- /** Hop limit */
- uint8_t hop_limit;
- /** Source address */
- struct in6_addr src;
- /** Destination address */
- struct in6_addr dest;
- } __attribute__ (( packed ));
-
- /** IPv6 extension header common fields */
- struct ipv6_extension_header_common {
- /** Next header type */
- uint8_t next_header;
- /** Header extension length (excluding first 8 bytes) */
- uint8_t len;
- } __attribute__ (( packed ));
-
- /** IPv6 type-length-value options */
- struct ipv6_option {
- /** Type */
- uint8_t type;
- /** Length */
- uint8_t len;
- /** Value */
- uint8_t value[0];
- } __attribute__ (( packed ));
-
- /** IPv6 option types */
- enum ipv6_option_type {
- /** Pad1 */
- IPV6_OPT_PAD1 = 0x00,
- /** PadN */
- IPV6_OPT_PADN = 0x01,
- };
-
- /** Test if IPv6 option can be safely ignored */
- #define IPV6_CAN_IGNORE_OPT( type ) ( ( (type) & 0xc0 ) == 0x00 )
-
- /** IPv6 option-based extension header */
- struct ipv6_options_header {
- /** Extension header common fields */
- struct ipv6_extension_header_common common;
- /** Options */
- struct ipv6_option options[0];
- } __attribute__ (( packed ));
-
- /** IPv6 routing header */
- struct ipv6_routing_header {
- /** Extension header common fields */
- struct ipv6_extension_header_common common;
- /** Routing type */
- uint8_t type;
- /** Segments left */
- uint8_t remaining;
- /** Type-specific data */
- uint8_t data[0];
- } __attribute__ (( packed ));
-
- /** IPv6 fragment header */
- struct ipv6_fragment_header {
- /** Extension header common fields */
- struct ipv6_extension_header_common common;
- /** Fragment offset (13 bits), reserved, more fragments (1 bit) */
- uint16_t offset_more;
- /** Identification */
- uint32_t ident;
- } __attribute__ (( packed ));
-
- /** Fragment offset mask */
- #define IPV6_MASK_OFFSET 0xfff8
-
- /** More fragments */
- #define IPV6_MASK_MOREFRAGS 0x0001
-
- /** IPv6 extension header */
- union ipv6_extension_header {
- /** Extension header common fields */
- struct ipv6_extension_header_common common;
- /** Minimum size padding */
- uint8_t pad[8];
- /** Generic options header */
- struct ipv6_options_header options;
- /** Hop-by-hop options header */
- struct ipv6_options_header hopbyhop;
- /** Routing header */
- struct ipv6_routing_header routing;
- /** Fragment header */
- struct ipv6_fragment_header fragment;
- /** Destination options header */
- struct ipv6_options_header destination;
- };
-
- /** IPv6 header types */
- enum ipv6_header_type {
- /** 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 pseudo-header */
- struct ipv6_pseudo_header {
- /** Source address */
- struct in6_addr src;
- /** Destination address */
- struct in6_addr dest;
- /** Upper-layer packet length */
- uint32_t len;
- /** Zero padding */
- uint8_t zero[3];
- /** Next header */
- uint8_t next_header;
- } __attribute__ (( packed ));
-
- /** IPv6 address scopes */
- enum ipv6_address_scope {
- /** 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,
- };
-
- /** An IPv6 address/routing table entry */
- struct ipv6_miniroute {
- /** List of miniroutes */
- struct list_head list;
-
- /** Network device */
- struct net_device *netdev;
-
- /** IPv6 address (or prefix if no address is defined) */
- struct in6_addr address;
- /** Prefix length */
- unsigned int prefix_len;
- /** IPv6 prefix mask (derived from prefix length) */
- struct in6_addr prefix_mask;
- /** Router address */
- struct in6_addr router;
- /** Scope */
- unsigned int scope;
- /** Flags */
- unsigned int flags;
- };
-
- /** IPv6 address/routing table entry flags */
- enum ipv6_miniroute_flags {
- /** Routing table entry address is valid */
- IPV6_HAS_ADDRESS = 0x0001,
- /** Routing table entry router address is valid */
- IPV6_HAS_ROUTER = 0x0002,
- };
-
- /**
- * Construct local IPv6 address via EUI-64
- *
- * @v addr Prefix to be completed
- * @v netdev Network device
- * @ret prefix_len Prefix length, or negative error
- */
- static inline int ipv6_eui64 ( struct in6_addr *addr,
- struct net_device *netdev ) {
- 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;
- }
-
- /**
- * Construct link-local address via EUI-64
- *
- * @v addr Zeroed address to construct
- * @v netdev Network device
- * @ret prefix_len Prefix length, or negative error
- */
- static inline int ipv6_link_local ( struct in6_addr *addr,
- struct net_device *netdev ) {
-
- addr->s6_addr16[0] = htons ( 0xfe80 );
- return ipv6_eui64 ( addr, netdev );
- }
-
- /**
- * Construct solicited-node multicast address
- *
- * @v addr Zeroed address to construct
- * @v unicast Unicast address
- */
- static inline void ipv6_solicited_node ( struct in6_addr *addr,
- const struct in6_addr *unicast ) {
-
- 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 );
- }
-
- /**
- * Construct all-routers multicast address
- *
- * @v addr Zeroed address to construct
- */
- static inline void ipv6_all_routers ( struct in6_addr *addr ) {
- addr->s6_addr16[0] = htons ( 0xff02 );
- addr->s6_addr[15] = 2;
- }
-
- /**
- * Get multicast address scope
- *
- * @v addr Multicast address
- * @ret scope Address scope
- */
- static inline unsigned int
- ipv6_multicast_scope ( const struct in6_addr *addr ) {
-
- return ( addr->s6_addr[1] & 0x0f );
- }
-
- /** IPv6 settings sibling order */
- enum ipv6_settings_order {
- /** 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,
- };
-
- /** IPv6 link-local address settings block name */
- #define IPV6_SETTINGS_NAME "link"
-
- extern struct list_head ipv6_miniroutes;
-
- extern struct net_protocol ipv6_protocol __net_protocol;
-
- extern int ipv6_has_addr ( struct net_device *netdev, struct in6_addr *addr );
- extern int ipv6_add_miniroute ( struct net_device *netdev,
- struct in6_addr *address,
- unsigned int prefix_len,
- struct in6_addr *router );
- extern void ipv6_del_miniroute ( struct ipv6_miniroute *miniroute );
- extern struct ipv6_miniroute * ipv6_route ( unsigned int scope_id,
- struct in6_addr **dest );
- extern int parse_ipv6_setting ( const struct setting_type *type,
- const char *value, void *buf, size_t len );
- extern int format_ipv6_setting ( const struct setting_type *type,
- const void *raw, size_t raw_len, char *buf,
- size_t len );
-
- #endif /* _IPXE_IPV6_H */
|