Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / include / ipxe / ipv6.h
1 #ifndef _IPXE_IPV6_H
2 #define _IPXE_IPV6_H
3
4 /** @file
5  *
6  * IPv6 protocol
7  *
8  */
9
10 FILE_LICENCE ( GPL2_OR_LATER );
11
12 #include <stdint.h>
13 #include <string.h>
14 #include <byteswap.h>
15 #include <ipxe/in.h>
16 #include <ipxe/list.h>
17 #include <ipxe/netdevice.h>
18
19 /** IPv6 version */
20 #define IPV6_VER 0x60000000UL
21
22 /** IPv6 version mask */
23 #define IPV6_MASK_VER 0xf0000000UL
24
25 /** IPv6 maximum hop limit */
26 #define IPV6_HOP_LIMIT 0xff
27
28 /** IPv6 header */
29 struct ipv6_header {
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 */
33         uint16_t len;
34         /** Next header type */
35         uint8_t next_header;
36         /** Hop limit */
37         uint8_t hop_limit;
38         /** Source address */
39         struct in6_addr src;
40         /** Destination address */
41         struct in6_addr dest;
42 } __attribute__ (( packed ));
43
44 /** IPv6 extension header common fields */
45 struct ipv6_extension_header_common {
46         /** Next header type */
47         uint8_t next_header;
48         /** Header extension length (excluding first 8 bytes) */
49         uint8_t len;
50 } __attribute__ (( packed ));
51
52 /** IPv6 type-length-value options */
53 struct ipv6_option {
54         /** Type */
55         uint8_t type;
56         /** Length */
57         uint8_t len;
58         /** Value */
59         uint8_t value[0];
60 } __attribute__ (( packed ));
61
62 /** IPv6 option types */
63 enum ipv6_option_type {
64         /** Pad1 */
65         IPV6_OPT_PAD1 = 0x00,
66         /** PadN */
67         IPV6_OPT_PADN = 0x01,
68 };
69
70 /** Test if IPv6 option can be safely ignored */
71 #define IPV6_CAN_IGNORE_OPT( type ) ( ( (type) & 0xc0 ) == 0x00 )
72
73 /** IPv6 option-based extension header */
74 struct ipv6_options_header {
75         /** Extension header common fields */
76         struct ipv6_extension_header_common common;
77         /** Options */
78         struct ipv6_option options[0];
79 } __attribute__ (( packed ));
80
81 /** IPv6 routing header */
82 struct ipv6_routing_header {
83         /** Extension header common fields */
84         struct ipv6_extension_header_common common;
85         /** Routing type */
86         uint8_t type;
87         /** Segments left */
88         uint8_t remaining;
89         /** Type-specific data */
90         uint8_t data[0];
91 } __attribute__ (( packed ));
92
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) */
98         uint16_t offset_more;
99         /** Identification */
100         uint32_t ident;
101 } __attribute__ (( packed ));
102
103 /** Fragment offset mask */
104 #define IPV6_MASK_OFFSET 0xfff8
105
106 /** More fragments */
107 #define IPV6_MASK_MOREFRAGS 0x0001
108
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 */
114         uint8_t pad[8];
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;
125 };
126
127 /** IPv6 header types */
128 enum ipv6_header_type {
129         /** IPv6 hop-by-hop options header type */
130         IPV6_HOPBYHOP = 0,
131         /** IPv6 routing header type */
132         IPV6_ROUTING = 43,
133         /** IPv6 fragment header type */
134         IPV6_FRAGMENT = 44,
135         /** IPv6 no next header type */
136         IPV6_NO_HEADER = 59,
137         /** IPv6 destination options header type */
138         IPV6_DESTINATION = 60,
139 };
140
141 /** IPv6 pseudo-header */
142 struct ipv6_pseudo_header {
143         /** Source address */
144         struct in6_addr src;
145         /** Destination address */
146         struct in6_addr dest;
147         /** Upper-layer packet length */
148         uint32_t len;
149         /** Zero padding */
150         uint8_t zero[3];
151         /** Next header */
152         uint8_t next_header;
153 } __attribute__ (( packed ));
154
155 /** An IPv6 address/routing table entry */
156 struct ipv6_miniroute {
157         /** List of miniroutes */
158         struct list_head list;
159
160         /** Network device */
161         struct net_device *netdev;
162
163         /** IPv6 address (or prefix if no address is defined) */
164         struct in6_addr address;
165         /** Prefix length */
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;
171         /** Flags */
172         unsigned int flags;
173 };
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 /**
184  * Construct local IPv6 address via EUI-64
185  *
186  * @v addr              Prefix to be completed
187  * @v netdev            Network device
188  * @ret prefix_len      Prefix length, or negative error
189  */
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;
194         int rc;
195
196         if ( ( rc = ll_protocol->eui64 ( ll_addr, &addr->s6_addr[8] ) ) != 0 )
197                 return rc;
198         addr->s6_addr[8] ^= 0x02;
199         return 64;
200 }
201
202 /**
203  * Construct link-local address via EUI-64
204  *
205  * @v addr              Zeroed address to construct
206  * @v netdev            Network device
207  * @ret prefix_len      Prefix length, or negative error
208  */
209 static inline int ipv6_link_local ( struct in6_addr *addr,
210                                     struct net_device *netdev ) {
211
212         addr->s6_addr16[0] = htons ( 0xfe80 );
213         return ipv6_eui64 ( addr, netdev );
214 }
215
216 /**
217  * Construct solicited-node multicast address
218  *
219  * @v addr              Zeroed address to construct
220  * @v unicast           Unicast address
221  */
222 static inline void ipv6_solicited_node ( struct in6_addr *addr,
223                                          const struct in6_addr *unicast ) {
224
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 );
229 }
230
231 /**
232  * Construct all-routers multicast address
233  *
234  * @v addr              Zeroed address to construct
235  */
236 static inline void ipv6_all_routers ( struct in6_addr *addr ) {
237         addr->s6_addr16[0] = htons ( 0xff02 );
238         addr->s6_addr[15] = 2;
239 }
240
241 extern struct list_head ipv6_miniroutes;
242
243 extern struct net_protocol ipv6_protocol __net_protocol;
244
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,
254                                  size_t len );
255
256 #endif /* _IPXE_IPV6_H */