1#ifndef _IPV6_H
2#define _IPV6_H
3
4#include <linux/in6.h>
5#include <asm/byteorder.h>
6
7/* The latest drafts declared increase in minimal mtu up to 1280. */
8
9#define IPV6_MIN_MTU	1280
10
11/*
12 *	Advanced API
13 *	source interface/address selection, source routing, etc...
14 *	*under construction*
15 */
16
17
18struct in6_pktinfo {
19	struct in6_addr	ipi6_addr;
20	int		ipi6_ifindex;
21};
22
23
24struct in6_ifreq {
25	struct in6_addr	ifr6_addr;
26	__u32		ifr6_prefixlen;
27	int		ifr6_ifindex;
28};
29
30#define IPV6_SRCRT_STRICT	0x01	/* this hop must be a neighbor	*/
31#define IPV6_SRCRT_TYPE_0	0	/* IPv6 type 0 Routing Header	*/
32#define IPV6_SRCRT_TYPE_2	2	/* IPv6 type 2 Routing Header	*/
33
34/*
35 *	routing header
36 */
37struct ipv6_rt_hdr {
38	__u8		nexthdr;
39	__u8		hdrlen;
40	__u8		type;
41	__u8		segments_left;
42
43	/*
44	 *	type specific data
45	 *	variable length field
46	 */
47};
48
49
50struct ipv6_opt_hdr {
51	__u8 		nexthdr;
52	__u8 		hdrlen;
53	/*
54	 * TLV encoded option data follows.
55	 */
56};
57
58#define ipv6_destopt_hdr ipv6_opt_hdr
59#define ipv6_hopopt_hdr  ipv6_opt_hdr
60
61#ifdef __KERNEL__
62#define ipv6_optlen(p)  (((p)->hdrlen+1) << 3)
63#endif
64
65/*
66 *	routing header type 0 (used in cmsghdr struct)
67 */
68
69struct rt0_hdr {
70	struct ipv6_rt_hdr	rt_hdr;
71	__u32			reserved;
72	struct in6_addr		addr[0];
73
74#define rt0_type		rt_hdr.type
75};
76
77/*
78 *	routing header type 2
79 */
80
81struct rt2_hdr {
82	struct ipv6_rt_hdr	rt_hdr;
83	__u32			reserved;
84	struct in6_addr		addr;
85
86#define rt2_type		rt_hdr.type
87};
88
89/*
90 *	home address option in destination options header
91 */
92
93struct ipv6_destopt_hao {
94	__u8			type;
95	__u8			length;
96	struct in6_addr		addr;
97} __attribute__ ((__packed__));
98
99struct ipv6_auth_hdr {
100	__u8  nexthdr;
101	__u8  hdrlen;           /* This one is measured in 32 bit units! */
102	__be16 reserved;
103	__be32 spi;
104	__be32 seq_no;           /* Sequence number */
105	__u8  auth_data[0];     /* Length variable but >=4. Mind the 64 bit alignment! */
106};
107
108struct ipv6_esp_hdr {
109	__be32 spi;
110	__be32 seq_no;           /* Sequence number */
111	__u8  enc_data[0];      /* Length variable but >=8. Mind the 64 bit alignment! */
112};
113
114struct ipv6_comp_hdr {
115	__u8 nexthdr;
116	__u8 flags;
117	__be16 cpi;
118};
119
120/*
121 *	IPv6 fixed header
122 *
123 *	BEWARE, it is incorrect. The first 4 bits of flow_lbl
124 *	are glued to priority now, forming "class".
125 */
126
127struct ipv6hdr {
128#if defined(__LITTLE_ENDIAN_BITFIELD)
129	__u8			priority:4,
130				version:4;
131#elif defined(__BIG_ENDIAN_BITFIELD)
132	__u8			version:4,
133				priority:4;
134#else
135#error	"Please fix <asm/byteorder.h>"
136#endif
137	__u8			flow_lbl[3];
138
139	__be16			payload_len;
140	__u8			nexthdr;
141	__u8			hop_limit;
142
143	struct	in6_addr	saddr;
144	struct	in6_addr	daddr;
145};
146
147/*
148 * This structure contains configuration options per IPv6 link.
149 */
150struct ipv6_devconf {
151	__s32		forwarding;
152	__s32		hop_limit;
153	__s32		mtu6;
154	__s32		accept_ra;
155	__s32		accept_redirects;
156	__s32		autoconf;
157	__s32		dad_transmits;
158	__s32		rtr_solicits;
159	__s32		rtr_solicit_interval;
160	__s32		rtr_solicit_delay;
161	__s32		force_mld_version;
162#ifdef CONFIG_IPV6_PRIVACY
163	__s32		use_tempaddr;
164	__s32		temp_valid_lft;
165	__s32		temp_prefered_lft;
166	__s32		regen_max_retry;
167	__s32		max_desync_factor;
168#endif
169	__s32		max_addresses;
170	__s32		accept_ra_defrtr;
171	__s32		accept_ra_pinfo;
172#ifdef CONFIG_IPV6_ROUTER_PREF
173	__s32		accept_ra_rtr_pref;
174	__s32		rtr_probe_interval;
175#ifdef CONFIG_IPV6_ROUTE_INFO
176	__s32		accept_ra_rt_info_max_plen;
177#endif
178#endif
179	__s32		proxy_ndp;
180	__s32		accept_source_route;
181#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
182	__s32		optimistic_dad;
183#endif
184#ifdef CONFIG_IPV6_MROUTE
185	__s32		mc_forwarding;
186#endif
187	void		*sysctl;
188};
189
190/* index values for the variables in ipv6_devconf */
191enum {
192	DEVCONF_FORWARDING = 0,
193	DEVCONF_HOPLIMIT,
194	DEVCONF_MTU6,
195	DEVCONF_ACCEPT_RA,
196	DEVCONF_ACCEPT_REDIRECTS,
197	DEVCONF_AUTOCONF,
198	DEVCONF_DAD_TRANSMITS,
199	DEVCONF_RTR_SOLICITS,
200	DEVCONF_RTR_SOLICIT_INTERVAL,
201	DEVCONF_RTR_SOLICIT_DELAY,
202	DEVCONF_USE_TEMPADDR,
203	DEVCONF_TEMP_VALID_LFT,
204	DEVCONF_TEMP_PREFERED_LFT,
205	DEVCONF_REGEN_MAX_RETRY,
206	DEVCONF_MAX_DESYNC_FACTOR,
207	DEVCONF_MAX_ADDRESSES,
208	DEVCONF_FORCE_MLD_VERSION,
209	DEVCONF_ACCEPT_RA_DEFRTR,
210	DEVCONF_ACCEPT_RA_PINFO,
211	DEVCONF_ACCEPT_RA_RTR_PREF,
212	DEVCONF_RTR_PROBE_INTERVAL,
213	DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
214	DEVCONF_PROXY_NDP,
215	DEVCONF_OPTIMISTIC_DAD,
216	DEVCONF_ACCEPT_SOURCE_ROUTE,
217#ifdef CONFIG_IPV6_MROUTE
218	DEVCONF_MCFORWARDING,
219#endif
220	DEVCONF_MAX
221};
222
223#ifdef __KERNEL__
224#include <linux/icmpv6.h>
225#include <linux/tcp.h>
226#include <linux/udp.h>
227
228#include <net/if_inet6.h>       /* struct ipv6_mc_socklist */
229#include <net/inet_sock.h>
230
231static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb)
232{
233	return (struct ipv6hdr *)skb_network_header(skb);
234}
235
236static inline struct ipv6hdr *ipipv6_hdr(const struct sk_buff *skb)
237{
238	return (struct ipv6hdr *)skb_transport_header(skb);
239}
240
241/*
242   This structure contains results of exthdrs parsing
243   as offsets from skb->nh.
244 */
245
246struct inet6_skb_parm {
247	int			iif;
248	__u16			ra;
249	__u16			hop;
250	__u16			dst0;
251	__u16			srcrt;
252	__u16			dst1;
253	__u16			lastopt;
254	__u32			nhoff;
255	__u16			flags;
256#ifdef CONFIG_IPV6_MIP6
257	__u16			dsthao;
258#endif
259
260#define IP6SKB_XFRM_TRANSFORMED	1
261};
262
263#define IP6CB(skb)	((struct inet6_skb_parm*)((skb)->cb))
264
265static inline int inet6_iif(const struct sk_buff *skb)
266{
267	return IP6CB(skb)->iif;
268}
269
270struct inet6_request_sock {
271	struct in6_addr		loc_addr;
272	struct in6_addr		rmt_addr;
273	struct sk_buff		*pktopts;
274	int			iif;
275};
276
277struct tcp6_request_sock {
278	struct tcp_request_sock	  tcp6rsk_tcp;
279	struct inet6_request_sock tcp6rsk_inet6;
280};
281
282/**
283 * struct ipv6_pinfo - ipv6 private area
284 *
285 * In the struct sock hierarchy (tcp6_sock, upd6_sock, etc)
286 * this _must_ be the last member, so that inet6_sk_generic
287 * is able to calculate its offset from the base struct sock
288 * by using the struct proto->slab_obj_size member. -acme
289 */
290struct ipv6_pinfo {
291	struct in6_addr 	saddr;
292	struct in6_addr 	rcv_saddr;
293	struct in6_addr		daddr;
294	struct in6_addr		*daddr_cache;
295#ifdef CONFIG_IPV6_SUBTREES
296	struct in6_addr		*saddr_cache;
297#endif
298
299	__be32			flow_label;
300	__u32			frag_size;
301	__s16			hop_limit;
302	__s16			mcast_hops;
303	int			mcast_oif;
304
305	/* pktoption flags */
306	union {
307		struct {
308			__u16	srcrt:2,
309				osrcrt:2,
310			        rxinfo:1,
311			        rxoinfo:1,
312				rxhlim:1,
313				rxohlim:1,
314				hopopts:1,
315				ohopopts:1,
316				dstopts:1,
317				odstopts:1,
318                                rxflow:1,
319				rxtclass:1;
320		} bits;
321		__u16		all;
322	} rxopt;
323
324	/* sockopt flags */
325	__u8			mc_loop:1,
326	                        recverr:1,
327	                        sndflow:1,
328				pmtudisc:2,
329				ipv6only:1;
330	__u8			tclass;
331
332	__u32			dst_cookie;
333
334	struct ipv6_mc_socklist	*ipv6_mc_list;
335	struct ipv6_ac_socklist	*ipv6_ac_list;
336	struct ipv6_fl_socklist *ipv6_fl_list;
337
338	struct ipv6_txoptions	*opt;
339	struct sk_buff		*pktoptions;
340	struct {
341		struct ipv6_txoptions *opt;
342		struct rt6_info	*rt;
343		int hop_limit;
344		int tclass;
345	} cork;
346};
347
348/* WARNING: don't change the layout of the members in {raw,udp,tcp}6_sock! */
349struct raw6_sock {
350	/* inet_sock has to be the first member of raw6_sock */
351	struct inet_sock	inet;
352	__u32			checksum;	/* perform checksum */
353	__u32			offset;		/* checksum offset  */
354	struct icmp6_filter	filter;
355	/* ipv6_pinfo has to be the last member of raw6_sock, see inet6_sk_generic */
356	struct ipv6_pinfo	inet6;
357};
358
359struct udp6_sock {
360	struct udp_sock	  udp;
361	/* ipv6_pinfo has to be the last member of udp6_sock, see inet6_sk_generic */
362	struct ipv6_pinfo inet6;
363};
364
365struct tcp6_sock {
366	struct tcp_sock	  tcp;
367	/* ipv6_pinfo has to be the last member of tcp6_sock, see inet6_sk_generic */
368	struct ipv6_pinfo inet6;
369};
370
371extern int inet6_sk_rebuild_header(struct sock *sk);
372
373#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
374static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
375{
376	return inet_sk(__sk)->pinet6;
377}
378
379static inline struct inet6_request_sock *
380			inet6_rsk(const struct request_sock *rsk)
381{
382	return (struct inet6_request_sock *)(((u8 *)rsk) +
383					     inet_rsk(rsk)->inet6_rsk_offset);
384}
385
386static inline u32 inet6_rsk_offset(struct request_sock *rsk)
387{
388	return rsk->rsk_ops->obj_size - sizeof(struct inet6_request_sock);
389}
390
391static inline struct request_sock *inet6_reqsk_alloc(struct request_sock_ops *ops)
392{
393	struct request_sock *req = reqsk_alloc(ops);
394
395	if (req != NULL)
396		inet_rsk(req)->inet6_rsk_offset = inet6_rsk_offset(req);
397
398	return req;
399}
400
401static inline struct raw6_sock *raw6_sk(const struct sock *sk)
402{
403	return (struct raw6_sock *)sk;
404}
405
406static inline void inet_sk_copy_descendant(struct sock *sk_to,
407					   const struct sock *sk_from)
408{
409	int ancestor_size = sizeof(struct inet_sock);
410
411	if (sk_from->sk_family == PF_INET6)
412		ancestor_size += sizeof(struct ipv6_pinfo);
413
414	__inet_sk_copy_descendant(sk_to, sk_from, ancestor_size);
415}
416
417#define __ipv6_only_sock(sk)	(inet6_sk(sk)->ipv6only)
418#define ipv6_only_sock(sk)	((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk))
419
420struct inet6_timewait_sock {
421	struct in6_addr tw_v6_daddr;
422	struct in6_addr	tw_v6_rcv_saddr;
423};
424
425struct tcp6_timewait_sock {
426	struct tcp_timewait_sock   tcp6tw_tcp;
427	struct inet6_timewait_sock tcp6tw_inet6;
428};
429
430static inline u16 inet6_tw_offset(const struct proto *prot)
431{
432	return prot->twsk_prot->twsk_obj_size -
433			sizeof(struct inet6_timewait_sock);
434}
435
436static inline struct inet6_timewait_sock *inet6_twsk(const struct sock *sk)
437{
438	return (struct inet6_timewait_sock *)(((u8 *)sk) +
439					      inet_twsk(sk)->tw_ipv6_offset);
440}
441
442static inline struct in6_addr *__inet6_rcv_saddr(const struct sock *sk)
443{
444	return likely(sk->sk_state != TCP_TIME_WAIT) ?
445		&inet6_sk(sk)->rcv_saddr : &inet6_twsk(sk)->tw_v6_rcv_saddr;
446}
447
448static inline struct in6_addr *inet6_rcv_saddr(const struct sock *sk)
449{
450	return sk->sk_family == AF_INET6 ? __inet6_rcv_saddr(sk) : NULL;
451}
452
453static inline int inet_v6_ipv6only(const struct sock *sk)
454{
455	return likely(sk->sk_state != TCP_TIME_WAIT) ?
456		ipv6_only_sock(sk) : inet_twsk(sk)->tw_ipv6only;
457}
458#else
459#define __ipv6_only_sock(sk)	0
460#define ipv6_only_sock(sk)	0
461
462static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
463{
464	return NULL;
465}
466
467static inline struct inet6_request_sock *
468			inet6_rsk(const struct request_sock *rsk)
469{
470	return NULL;
471}
472
473static inline struct raw6_sock *raw6_sk(const struct sock *sk)
474{
475	return NULL;
476}
477
478#define __inet6_rcv_saddr(__sk)	NULL
479#define inet6_rcv_saddr(__sk)	NULL
480#define tcp_twsk_ipv6only(__sk)		0
481#define inet_v6_ipv6only(__sk)		0
482#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
483
484#define INET6_MATCH(__sk, __hash, __saddr, __daddr, __ports, __dif)\
485	(((__sk)->sk_hash == (__hash))				&& \
486	 ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))  	&& \
487	 ((__sk)->sk_family		== AF_INET6)		&& \
488	 ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr))	&& \
489	 ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr))	&& \
490	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
491
492#endif /* __KERNEL__ */
493
494#endif /* _IPV6_H */
495