You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ipv6.h 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. #ifndef _IPXE_IPV6_H
  2. #define _IPXE_IPV6_H
  3. /** @file
  4. *
  5. * IPv6 protocol
  6. *
  7. */
  8. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  9. #include <stdint.h>
  10. #include <string.h>
  11. #include <byteswap.h>
  12. #include <ipxe/in.h>
  13. #include <ipxe/list.h>
  14. #include <ipxe/netdevice.h>
  15. /** IPv6 version */
  16. #define IPV6_VER 0x60000000UL
  17. /** IPv6 version mask */
  18. #define IPV6_MASK_VER 0xf0000000UL
  19. /** IPv6 maximum hop limit */
  20. #define IPV6_HOP_LIMIT 0xff
  21. /** IPv6 default prefix length */
  22. #define IPV6_DEFAULT_PREFIX_LEN 64
  23. /** IPv6 maximum prefix length */
  24. #define IPV6_MAX_PREFIX_LEN 128
  25. /** IPv6 header */
  26. struct ipv6_header {
  27. /** Version (4 bits), Traffic class (8 bits), Flow label (20 bits) */
  28. uint32_t ver_tc_label;
  29. /** Payload length, including any extension headers */
  30. uint16_t len;
  31. /** Next header type */
  32. uint8_t next_header;
  33. /** Hop limit */
  34. uint8_t hop_limit;
  35. /** Source address */
  36. struct in6_addr src;
  37. /** Destination address */
  38. struct in6_addr dest;
  39. } __attribute__ (( packed ));
  40. /** IPv6 extension header common fields */
  41. struct ipv6_extension_header_common {
  42. /** Next header type */
  43. uint8_t next_header;
  44. /** Header extension length (excluding first 8 bytes) */
  45. uint8_t len;
  46. } __attribute__ (( packed ));
  47. /** IPv6 type-length-value options */
  48. struct ipv6_option {
  49. /** Type */
  50. uint8_t type;
  51. /** Length */
  52. uint8_t len;
  53. /** Value */
  54. uint8_t value[0];
  55. } __attribute__ (( packed ));
  56. /** IPv6 option types */
  57. enum ipv6_option_type {
  58. /** Pad1 */
  59. IPV6_OPT_PAD1 = 0x00,
  60. /** PadN */
  61. IPV6_OPT_PADN = 0x01,
  62. };
  63. /** Test if IPv6 option can be safely ignored */
  64. #define IPV6_CAN_IGNORE_OPT( type ) ( ( (type) & 0xc0 ) == 0x00 )
  65. /** IPv6 option-based extension header */
  66. struct ipv6_options_header {
  67. /** Extension header common fields */
  68. struct ipv6_extension_header_common common;
  69. /** Options */
  70. struct ipv6_option options[0];
  71. } __attribute__ (( packed ));
  72. /** IPv6 routing header */
  73. struct ipv6_routing_header {
  74. /** Extension header common fields */
  75. struct ipv6_extension_header_common common;
  76. /** Routing type */
  77. uint8_t type;
  78. /** Segments left */
  79. uint8_t remaining;
  80. /** Type-specific data */
  81. uint8_t data[0];
  82. } __attribute__ (( packed ));
  83. /** IPv6 fragment header */
  84. struct ipv6_fragment_header {
  85. /** Extension header common fields */
  86. struct ipv6_extension_header_common common;
  87. /** Fragment offset (13 bits), reserved, more fragments (1 bit) */
  88. uint16_t offset_more;
  89. /** Identification */
  90. uint32_t ident;
  91. } __attribute__ (( packed ));
  92. /** Fragment offset mask */
  93. #define IPV6_MASK_OFFSET 0xfff8
  94. /** More fragments */
  95. #define IPV6_MASK_MOREFRAGS 0x0001
  96. /** IPv6 extension header */
  97. union ipv6_extension_header {
  98. /** Extension header common fields */
  99. struct ipv6_extension_header_common common;
  100. /** Minimum size padding */
  101. uint8_t pad[8];
  102. /** Generic options header */
  103. struct ipv6_options_header options;
  104. /** Hop-by-hop options header */
  105. struct ipv6_options_header hopbyhop;
  106. /** Routing header */
  107. struct ipv6_routing_header routing;
  108. /** Fragment header */
  109. struct ipv6_fragment_header fragment;
  110. /** Destination options header */
  111. struct ipv6_options_header destination;
  112. };
  113. /** IPv6 header types */
  114. enum ipv6_header_type {
  115. /** IPv6 hop-by-hop options header type */
  116. IPV6_HOPBYHOP = 0,
  117. /** IPv6 routing header type */
  118. IPV6_ROUTING = 43,
  119. /** IPv6 fragment header type */
  120. IPV6_FRAGMENT = 44,
  121. /** IPv6 no next header type */
  122. IPV6_NO_HEADER = 59,
  123. /** IPv6 destination options header type */
  124. IPV6_DESTINATION = 60,
  125. };
  126. /** IPv6 pseudo-header */
  127. struct ipv6_pseudo_header {
  128. /** Source address */
  129. struct in6_addr src;
  130. /** Destination address */
  131. struct in6_addr dest;
  132. /** Upper-layer packet length */
  133. uint32_t len;
  134. /** Zero padding */
  135. uint8_t zero[3];
  136. /** Next header */
  137. uint8_t next_header;
  138. } __attribute__ (( packed ));
  139. /** IPv6 address scopes */
  140. enum ipv6_address_scope {
  141. /** Interface-local address scope */
  142. IPV6_SCOPE_INTERFACE_LOCAL = 0x1,
  143. /** Link-local address scope */
  144. IPV6_SCOPE_LINK_LOCAL = 0x2,
  145. /** Admin-local address scope */
  146. INV6_SCOPE_ADMIN_LOCAL = 0x4,
  147. /** Site-local address scope */
  148. IPV6_SCOPE_SITE_LOCAL = 0x5,
  149. /** Organisation-local address scope */
  150. IPV6_SCOPE_ORGANISATION_LOCAL = 0x8,
  151. /** Global address scope */
  152. IPV6_SCOPE_GLOBAL = 0xe,
  153. /** Maximum scope */
  154. IPV6_SCOPE_MAX = 0xf,
  155. };
  156. /** An IPv6 address/routing table entry */
  157. struct ipv6_miniroute {
  158. /** List of miniroutes */
  159. struct list_head list;
  160. /** Network device */
  161. struct net_device *netdev;
  162. /** IPv6 address (or prefix if no address is defined) */
  163. struct in6_addr address;
  164. /** Prefix length */
  165. unsigned int prefix_len;
  166. /** IPv6 prefix mask (derived from prefix length) */
  167. struct in6_addr prefix_mask;
  168. /** Router address */
  169. struct in6_addr router;
  170. /** Scope */
  171. unsigned int scope;
  172. /** Flags */
  173. unsigned int flags;
  174. };
  175. /** IPv6 address/routing table entry flags */
  176. enum ipv6_miniroute_flags {
  177. /** Routing table entry address is valid */
  178. IPV6_HAS_ADDRESS = 0x0001,
  179. /** Routing table entry router address is valid */
  180. IPV6_HAS_ROUTER = 0x0002,
  181. };
  182. /**
  183. * Construct local IPv6 address via EUI-64
  184. *
  185. * @v addr Prefix to be completed
  186. * @v netdev Network device
  187. * @ret prefix_len Prefix length, or negative error
  188. */
  189. static inline int ipv6_eui64 ( struct in6_addr *addr,
  190. struct net_device *netdev ) {
  191. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  192. const void *ll_addr = netdev->ll_addr;
  193. int rc;
  194. if ( ( rc = ll_protocol->eui64 ( ll_addr, &addr->s6_addr[8] ) ) != 0 )
  195. return rc;
  196. addr->s6_addr[8] ^= 0x02;
  197. return 64;
  198. }
  199. /**
  200. * Construct link-local address via EUI-64
  201. *
  202. * @v addr Zeroed address to construct
  203. * @v netdev Network device
  204. * @ret prefix_len Prefix length, or negative error
  205. */
  206. static inline int ipv6_link_local ( struct in6_addr *addr,
  207. struct net_device *netdev ) {
  208. addr->s6_addr16[0] = htons ( 0xfe80 );
  209. return ipv6_eui64 ( addr, netdev );
  210. }
  211. /**
  212. * Construct solicited-node multicast address
  213. *
  214. * @v addr Zeroed address to construct
  215. * @v unicast Unicast address
  216. */
  217. static inline void ipv6_solicited_node ( struct in6_addr *addr,
  218. const struct in6_addr *unicast ) {
  219. addr->s6_addr16[0] = htons ( 0xff02 );
  220. addr->s6_addr[11] = 1;
  221. addr->s6_addr[12] = 0xff;
  222. memcpy ( &addr->s6_addr[13], &unicast->s6_addr[13], 3 );
  223. }
  224. /**
  225. * Construct all-routers multicast address
  226. *
  227. * @v addr Zeroed address to construct
  228. */
  229. static inline void ipv6_all_routers ( struct in6_addr *addr ) {
  230. addr->s6_addr16[0] = htons ( 0xff02 );
  231. addr->s6_addr[15] = 2;
  232. }
  233. /**
  234. * Get multicast address scope
  235. *
  236. * @v addr Multicast address
  237. * @ret scope Address scope
  238. */
  239. static inline unsigned int
  240. ipv6_multicast_scope ( const struct in6_addr *addr ) {
  241. return ( addr->s6_addr[1] & 0x0f );
  242. }
  243. /** IPv6 settings sibling order */
  244. enum ipv6_settings_order {
  245. /** No address */
  246. IPV6_ORDER_PREFIX_ONLY = -4,
  247. /** Link-local address */
  248. IPV6_ORDER_LINK_LOCAL = -3,
  249. /** Address assigned via SLAAC */
  250. IPV6_ORDER_SLAAC = -2,
  251. /** Address assigned via DHCPv6 */
  252. IPV6_ORDER_DHCPV6 = -1,
  253. };
  254. /** IPv6 link-local address settings block name */
  255. #define IPV6_SETTINGS_NAME "link"
  256. extern struct list_head ipv6_miniroutes;
  257. extern struct net_protocol ipv6_protocol __net_protocol;
  258. extern int ipv6_has_addr ( struct net_device *netdev, struct in6_addr *addr );
  259. extern int ipv6_add_miniroute ( struct net_device *netdev,
  260. struct in6_addr *address,
  261. unsigned int prefix_len,
  262. struct in6_addr *router );
  263. extern void ipv6_del_miniroute ( struct ipv6_miniroute *miniroute );
  264. extern struct ipv6_miniroute * ipv6_route ( unsigned int scope_id,
  265. struct in6_addr **dest );
  266. extern int parse_ipv6_setting ( const struct setting_type *type,
  267. const char *value, void *buf, size_t len );
  268. extern int format_ipv6_setting ( const struct setting_type *type,
  269. const void *raw, size_t raw_len, char *buf,
  270. size_t len );
  271. #endif /* _IPXE_IPV6_H */