Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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 header */
  22. struct ipv6_header {
  23. /** Version (4 bits), Traffic class (8 bits), Flow label (20 bits) */
  24. uint32_t ver_tc_label;
  25. /** Payload length, including any extension headers */
  26. uint16_t len;
  27. /** Next header type */
  28. uint8_t next_header;
  29. /** Hop limit */
  30. uint8_t hop_limit;
  31. /** Source address */
  32. struct in6_addr src;
  33. /** Destination address */
  34. struct in6_addr dest;
  35. } __attribute__ (( packed ));
  36. /** IPv6 extension header common fields */
  37. struct ipv6_extension_header_common {
  38. /** Next header type */
  39. uint8_t next_header;
  40. /** Header extension length (excluding first 8 bytes) */
  41. uint8_t len;
  42. } __attribute__ (( packed ));
  43. /** IPv6 type-length-value options */
  44. struct ipv6_option {
  45. /** Type */
  46. uint8_t type;
  47. /** Length */
  48. uint8_t len;
  49. /** Value */
  50. uint8_t value[0];
  51. } __attribute__ (( packed ));
  52. /** IPv6 option types */
  53. enum ipv6_option_type {
  54. /** Pad1 */
  55. IPV6_OPT_PAD1 = 0x00,
  56. /** PadN */
  57. IPV6_OPT_PADN = 0x01,
  58. };
  59. /** Test if IPv6 option can be safely ignored */
  60. #define IPV6_CAN_IGNORE_OPT( type ) ( ( (type) & 0xc0 ) == 0x00 )
  61. /** IPv6 option-based extension header */
  62. struct ipv6_options_header {
  63. /** Extension header common fields */
  64. struct ipv6_extension_header_common common;
  65. /** Options */
  66. struct ipv6_option options[0];
  67. } __attribute__ (( packed ));
  68. /** IPv6 routing header */
  69. struct ipv6_routing_header {
  70. /** Extension header common fields */
  71. struct ipv6_extension_header_common common;
  72. /** Routing type */
  73. uint8_t type;
  74. /** Segments left */
  75. uint8_t remaining;
  76. /** Type-specific data */
  77. uint8_t data[0];
  78. } __attribute__ (( packed ));
  79. /** IPv6 fragment header */
  80. struct ipv6_fragment_header {
  81. /** Extension header common fields */
  82. struct ipv6_extension_header_common common;
  83. /** Fragment offset (13 bits), reserved, more fragments (1 bit) */
  84. uint16_t offset_more;
  85. /** Identification */
  86. uint32_t ident;
  87. } __attribute__ (( packed ));
  88. /** Fragment offset mask */
  89. #define IPV6_MASK_OFFSET 0xfff8
  90. /** More fragments */
  91. #define IPV6_MASK_MOREFRAGS 0x0001
  92. /** IPv6 extension header */
  93. union ipv6_extension_header {
  94. /** Extension header common fields */
  95. struct ipv6_extension_header_common common;
  96. /** Minimum size padding */
  97. uint8_t pad[8];
  98. /** Generic options header */
  99. struct ipv6_options_header options;
  100. /** Hop-by-hop options header */
  101. struct ipv6_options_header hopbyhop;
  102. /** Routing header */
  103. struct ipv6_routing_header routing;
  104. /** Fragment header */
  105. struct ipv6_fragment_header fragment;
  106. /** Destination options header */
  107. struct ipv6_options_header destination;
  108. };
  109. /** IPv6 header types */
  110. enum ipv6_header_type {
  111. /** IPv6 hop-by-hop options header type */
  112. IPV6_HOPBYHOP = 0,
  113. /** IPv6 routing header type */
  114. IPV6_ROUTING = 43,
  115. /** IPv6 fragment header type */
  116. IPV6_FRAGMENT = 44,
  117. /** IPv6 no next header type */
  118. IPV6_NO_HEADER = 59,
  119. /** IPv6 destination options header type */
  120. IPV6_DESTINATION = 60,
  121. };
  122. /** IPv6 pseudo-header */
  123. struct ipv6_pseudo_header {
  124. /** Source address */
  125. struct in6_addr src;
  126. /** Destination address */
  127. struct in6_addr dest;
  128. /** Upper-layer packet length */
  129. uint32_t len;
  130. /** Zero padding */
  131. uint8_t zero[3];
  132. /** Next header */
  133. uint8_t next_header;
  134. } __attribute__ (( packed ));
  135. /** An IPv6 address/routing table entry */
  136. struct ipv6_miniroute {
  137. /** List of miniroutes */
  138. struct list_head list;
  139. /** Network device */
  140. struct net_device *netdev;
  141. /** IPv6 address (or prefix if no address is defined) */
  142. struct in6_addr address;
  143. /** Prefix length */
  144. unsigned int prefix_len;
  145. /** IPv6 prefix mask (derived from prefix length) */
  146. struct in6_addr prefix_mask;
  147. /** Router address */
  148. struct in6_addr router;
  149. /** Flags */
  150. unsigned int flags;
  151. };
  152. /** IPv6 address/routing table entry flags */
  153. enum ipv6_miniroute_flags {
  154. /** Routing table entry address is valid */
  155. IPV6_HAS_ADDRESS = 0x0001,
  156. /** Routing table entry router address is valid */
  157. IPV6_HAS_ROUTER = 0x0002,
  158. };
  159. /**
  160. * Construct local IPv6 address via EUI-64
  161. *
  162. * @v addr Prefix to be completed
  163. * @v netdev Network device
  164. * @ret prefix_len Prefix length, or negative error
  165. */
  166. static inline int ipv6_eui64 ( struct in6_addr *addr,
  167. struct net_device *netdev ) {
  168. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  169. const void *ll_addr = netdev->ll_addr;
  170. int rc;
  171. if ( ( rc = ll_protocol->eui64 ( ll_addr, &addr->s6_addr[8] ) ) != 0 )
  172. return rc;
  173. addr->s6_addr[8] ^= 0x02;
  174. return 64;
  175. }
  176. /**
  177. * Construct link-local address via EUI-64
  178. *
  179. * @v addr Zeroed address to construct
  180. * @v netdev Network device
  181. * @ret prefix_len Prefix length, or negative error
  182. */
  183. static inline int ipv6_link_local ( struct in6_addr *addr,
  184. struct net_device *netdev ) {
  185. addr->s6_addr16[0] = htons ( 0xfe80 );
  186. return ipv6_eui64 ( addr, netdev );
  187. }
  188. /**
  189. * Construct solicited-node multicast address
  190. *
  191. * @v addr Zeroed address to construct
  192. * @v unicast Unicast address
  193. */
  194. static inline void ipv6_solicited_node ( struct in6_addr *addr,
  195. const struct in6_addr *unicast ) {
  196. addr->s6_addr16[0] = htons ( 0xff02 );
  197. addr->s6_addr[11] = 1;
  198. addr->s6_addr[12] = 0xff;
  199. memcpy ( &addr->s6_addr[13], &unicast->s6_addr[13], 3 );
  200. }
  201. /**
  202. * Construct all-routers multicast address
  203. *
  204. * @v addr Zeroed address to construct
  205. */
  206. static inline void ipv6_all_routers ( struct in6_addr *addr ) {
  207. addr->s6_addr16[0] = htons ( 0xff02 );
  208. addr->s6_addr[15] = 2;
  209. }
  210. extern struct list_head ipv6_miniroutes;
  211. extern struct net_protocol ipv6_protocol __net_protocol;
  212. extern int ipv6_has_addr ( struct net_device *netdev, struct in6_addr *addr );
  213. extern int ipv6_set_prefix ( struct net_device *netdev, struct in6_addr *prefix,
  214. unsigned int prefix_len, struct in6_addr *router );
  215. extern int ipv6_set_address ( struct net_device *netdev,
  216. struct in6_addr *address );
  217. extern int parse_ipv6_setting ( const struct setting_type *type,
  218. const char *value, void *buf, size_t len );
  219. extern int format_ipv6_setting ( const struct setting_type *type,
  220. const void *raw, size_t raw_len, char *buf,
  221. size_t len );
  222. #endif /* _IPXE_IPV6_H */