10 FILE_LICENCE ( GPL2_OR_LATER );
16 #include <ipxe/list.h>
17 #include <ipxe/netdevice.h>
20 #define IPV6_VER 0x60000000UL
22 /** IPv6 version mask */
23 #define IPV6_MASK_VER 0xf0000000UL
25 /** IPv6 maximum hop limit */
26 #define IPV6_HOP_LIMIT 0xff
30 /** Version (4 bits), Traffic class (8 bits), Flow label (20 bits) */
31 uint32_t ver_tc_label;
32 /** Payload length, including any extension headers */
34 /** Next header type */
40 /** Destination address */
42 } __attribute__ (( packed ));
44 /** IPv6 extension header common fields */
45 struct ipv6_extension_header_common {
46 /** Next header type */
48 /** Header extension length (excluding first 8 bytes) */
50 } __attribute__ (( packed ));
52 /** IPv6 type-length-value options */
60 } __attribute__ (( packed ));
62 /** IPv6 option types */
63 enum ipv6_option_type {
70 /** Test if IPv6 option can be safely ignored */
71 #define IPV6_CAN_IGNORE_OPT( type ) ( ( (type) & 0xc0 ) == 0x00 )
73 /** IPv6 option-based extension header */
74 struct ipv6_options_header {
75 /** Extension header common fields */
76 struct ipv6_extension_header_common common;
78 struct ipv6_option options[0];
79 } __attribute__ (( packed ));
81 /** IPv6 routing header */
82 struct ipv6_routing_header {
83 /** Extension header common fields */
84 struct ipv6_extension_header_common common;
89 /** Type-specific data */
91 } __attribute__ (( packed ));
93 /** IPv6 fragment header */
94 struct ipv6_fragment_header {
95 /** Extension header common fields */
96 struct ipv6_extension_header_common common;
97 /** Fragment offset (13 bits), reserved, more fragments (1 bit) */
101 } __attribute__ (( packed ));
103 /** Fragment offset mask */
104 #define IPV6_MASK_OFFSET 0xfff8
106 /** More fragments */
107 #define IPV6_MASK_MOREFRAGS 0x0001
109 /** IPv6 extension header */
110 union ipv6_extension_header {
111 /** Extension header common fields */
112 struct ipv6_extension_header_common common;
113 /** Minimum size padding */
115 /** Generic options header */
116 struct ipv6_options_header options;
117 /** Hop-by-hop options header */
118 struct ipv6_options_header hopbyhop;
119 /** Routing header */
120 struct ipv6_routing_header routing;
121 /** Fragment header */
122 struct ipv6_fragment_header fragment;
123 /** Destination options header */
124 struct ipv6_options_header destination;
127 /** IPv6 header types */
128 enum ipv6_header_type {
129 /** IPv6 hop-by-hop options header type */
131 /** IPv6 routing header type */
133 /** IPv6 fragment header type */
135 /** IPv6 no next header type */
137 /** IPv6 destination options header type */
138 IPV6_DESTINATION = 60,
141 /** IPv6 pseudo-header */
142 struct ipv6_pseudo_header {
143 /** Source address */
145 /** Destination address */
146 struct in6_addr dest;
147 /** Upper-layer packet length */
153 } __attribute__ (( packed ));
155 /** An IPv6 address/routing table entry */
156 struct ipv6_miniroute {
157 /** List of miniroutes */
158 struct list_head list;
160 /** Network device */
161 struct net_device *netdev;
163 /** IPv6 address (or prefix if no address is defined) */
164 struct in6_addr address;
166 unsigned int prefix_len;
167 /** IPv6 prefix mask (derived from prefix length) */
168 struct in6_addr prefix_mask;
169 /** Router address */
170 struct in6_addr router;
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,
184 * Construct local IPv6 address via EUI-64
186 * @v addr Prefix to be completed
187 * @v netdev Network device
188 * @ret prefix_len Prefix length, or negative error
190 static inline int ipv6_eui64 ( struct in6_addr *addr,
191 struct net_device *netdev ) {
192 struct ll_protocol *ll_protocol = netdev->ll_protocol;
193 const void *ll_addr = netdev->ll_addr;
196 if ( ( rc = ll_protocol->eui64 ( ll_addr, &addr->s6_addr[8] ) ) != 0 )
198 addr->s6_addr[8] ^= 0x02;
203 * Construct link-local address via EUI-64
205 * @v addr Zeroed address to construct
206 * @v netdev Network device
207 * @ret prefix_len Prefix length, or negative error
209 static inline int ipv6_link_local ( struct in6_addr *addr,
210 struct net_device *netdev ) {
212 addr->s6_addr16[0] = htons ( 0xfe80 );
213 return ipv6_eui64 ( addr, netdev );
217 * Construct solicited-node multicast address
219 * @v addr Zeroed address to construct
220 * @v unicast Unicast address
222 static inline void ipv6_solicited_node ( struct in6_addr *addr,
223 const struct in6_addr *unicast ) {
225 addr->s6_addr16[0] = htons ( 0xff02 );
226 addr->s6_addr[11] = 1;
227 addr->s6_addr[12] = 0xff;
228 memcpy ( &addr->s6_addr[13], &unicast->s6_addr[13], 3 );
232 * Construct all-routers multicast address
234 * @v addr Zeroed address to construct
236 static inline void ipv6_all_routers ( struct in6_addr *addr ) {
237 addr->s6_addr16[0] = htons ( 0xff02 );
238 addr->s6_addr[15] = 2;
241 extern struct list_head ipv6_miniroutes;
243 extern struct net_protocol ipv6_protocol __net_protocol;
245 extern int ipv6_has_addr ( struct net_device *netdev, struct in6_addr *addr );
246 extern int ipv6_set_prefix ( struct net_device *netdev, struct in6_addr *prefix,
247 unsigned int prefix_len, struct in6_addr *router );
248 extern int ipv6_set_address ( struct net_device *netdev,
249 struct in6_addr *address );
250 extern int parse_ipv6_setting ( const struct setting_type *type,
251 const char *value, void *buf, size_t len );
252 extern int format_ipv6_setting ( const struct setting_type *type,
253 const void *raw, size_t raw_len, char *buf,
256 #endif /* _IPXE_IPV6_H */