1/*
2 *	Linux INET6 implementation
3 *
4 *	Authors:
5 *	Pedro Roque		<roque@di.fc.ul.pt>
6 *
7 *	$Id: ipv6.h,v 1.1.1.1 2008/10/15 03:29:28 james26_jang Exp $
8 *
9 *	This program is free software; you can redistribute it and/or
10 *      modify it under the terms of the GNU General Public License
11 *      as published by the Free Software Foundation; either version
12 *      2 of the License, or (at your option) any later version.
13 */
14
15#ifndef _NET_IPV6_H
16#define _NET_IPV6_H
17
18#include <linux/ipv6.h>
19#include <asm/hardirq.h>
20#include <net/ndisc.h>
21#include <net/flow.h>
22
23#define SIN6_LEN_RFC2133	24
24
25/*
26 *	NextHeader field of IPv6 header
27 */
28
29#define NEXTHDR_HOP		0	/* Hop-by-hop option header. */
30#define NEXTHDR_TCP		6	/* TCP segment. */
31#define NEXTHDR_UDP		17	/* UDP message. */
32#define NEXTHDR_IPV6		41	/* IPv6 in IPv6 */
33#define NEXTHDR_ROUTING		43	/* Routing header. */
34#define NEXTHDR_FRAGMENT	44	/* Fragmentation/reassembly header. */
35#define NEXTHDR_ESP		50	/* Encapsulating security payload. */
36#define NEXTHDR_AUTH		51	/* Authentication header. */
37#define NEXTHDR_ICMP		58	/* ICMP for IPv6. */
38#define NEXTHDR_NONE		59	/* No next header */
39#define NEXTHDR_DEST		60	/* Destination options header. */
40
41#define NEXTHDR_MAX		255
42
43
44
45#define IPV6_DEFAULT_HOPLIMIT   64
46#define IPV6_DEFAULT_MCASTHOPS	1
47
48/*
49 *	Addr type
50 *
51 *	type	-	unicast | multicast | anycast
52 *	scope	-	local	| site	    | global
53 *	v4	-	compat
54 *	v4mapped
55 *	any
56 *	loopback
57 */
58
59#define IPV6_ADDR_ANY		0x0000U
60
61#define IPV6_ADDR_UNICAST      	0x0001U
62#define IPV6_ADDR_MULTICAST    	0x0002U
63#define IPV6_ADDR_ANYCAST	0x0004U
64
65#define IPV6_ADDR_LOOPBACK	0x0010U
66#define IPV6_ADDR_LINKLOCAL	0x0020U
67#define IPV6_ADDR_SITELOCAL	0x0040U
68
69#define IPV6_ADDR_COMPATv4	0x0080U
70
71#define IPV6_ADDR_SCOPE_MASK	0x00f0U
72
73#define IPV6_ADDR_MAPPED	0x1000U
74#define IPV6_ADDR_RESERVED	0x2000U	/* reserved address space */
75
76/*
77 *	fragmentation header
78 */
79
80struct frag_hdr {
81	unsigned char	nexthdr;
82	unsigned char	reserved;
83	unsigned short	frag_off;
84	__u32		identification;
85};
86
87#ifdef __KERNEL__
88
89#include <net/sock.h>
90
91extern struct ipv6_mib		ipv6_statistics[NR_CPUS*2];
92#define IP6_INC_STATS(field)		SNMP_INC_STATS(ipv6_statistics, field)
93#define IP6_INC_STATS_BH(field)		SNMP_INC_STATS_BH(ipv6_statistics, field)
94#define IP6_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(ipv6_statistics, field)
95extern struct icmpv6_mib	icmpv6_statistics[NR_CPUS*2];
96#define ICMP6_INC_STATS(field)		SNMP_INC_STATS(icmpv6_statistics, field)
97#define ICMP6_INC_STATS_BH(field)	SNMP_INC_STATS_BH(icmpv6_statistics, field)
98#define ICMP6_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(icmpv6_statistics, field)
99extern struct udp_mib		udp_stats_in6[NR_CPUS*2];
100#define UDP6_INC_STATS(field)		SNMP_INC_STATS(udp_stats_in6, field)
101#define UDP6_INC_STATS_BH(field)	SNMP_INC_STATS_BH(udp_stats_in6, field)
102#define UDP6_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(udp_stats_in6, field)
103extern atomic_t			inet6_sock_nr;
104
105struct ip6_ra_chain
106{
107	struct ip6_ra_chain	*next;
108	struct sock		*sk;
109	int			sel;
110	void			(*destructor)(struct sock *);
111};
112
113extern struct ip6_ra_chain	*ip6_ra_chain;
114extern rwlock_t ip6_ra_lock;
115
116/*
117   This structure is prepared by protocol, when parsing
118   ancillary data and passed to IPv6.
119 */
120
121struct ipv6_txoptions
122{
123	/* Length of this structure */
124	int			tot_len;
125
126	/* length of extension headers   */
127
128	__u16			opt_flen;	/* after fragment hdr */
129	__u16			opt_nflen;	/* before fragment hdr */
130
131	struct ipv6_opt_hdr	*hopopt;
132	struct ipv6_opt_hdr	*dst0opt;
133	struct ipv6_rt_hdr	*srcrt;	/* Routing Header */
134	struct ipv6_opt_hdr	*auth;
135	struct ipv6_opt_hdr	*dst1opt;
136
137	/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
138};
139
140struct ip6_flowlabel
141{
142	struct ip6_flowlabel	*next;
143	u32			label;
144	struct in6_addr		dst;
145	struct ipv6_txoptions	*opt;
146	atomic_t		users;
147	u32			linger;
148	u8			share;
149	u32			owner;
150	unsigned long		lastuse;
151	unsigned long		expires;
152};
153
154#define IPV6_FLOWINFO_MASK	__constant_htonl(0x0FFFFFFF)
155#define IPV6_FLOWLABEL_MASK	__constant_htonl(0x000FFFFF)
156
157struct ipv6_fl_socklist
158{
159	struct ipv6_fl_socklist	*next;
160	struct ip6_flowlabel	*fl;
161};
162
163extern struct ip6_flowlabel	*fl6_sock_lookup(struct sock *sk, u32 label);
164extern struct ipv6_txoptions	*fl6_merge_options(struct ipv6_txoptions * opt_space,
165						   struct ip6_flowlabel * fl,
166						   struct ipv6_txoptions * fopt);
167extern void			fl6_free_socklist(struct sock *sk);
168extern int			ipv6_flowlabel_opt(struct sock *sk, char *optval, int optlen);
169extern void			ip6_flowlabel_init(void);
170extern void			ip6_flowlabel_cleanup(void);
171
172static inline void fl6_sock_release(struct ip6_flowlabel *fl)
173{
174	if (fl)
175		atomic_dec(&fl->users);
176}
177
178extern int 			ip6_ra_control(struct sock *sk, int sel,
179					       void (*destructor)(struct sock *));
180
181
182extern int			ip6_call_ra_chain(struct sk_buff *skb, int sel);
183
184extern int			ipv6_reassembly(struct sk_buff **skb, int);
185
186extern int			ipv6_parse_hopopts(struct sk_buff *skb, int);
187
188extern int			ipv6_parse_exthdrs(struct sk_buff **skb, int);
189
190extern struct ipv6_txoptions *  ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
191
192extern int ip6_frag_nqueues;
193extern atomic_t ip6_frag_mem;
194
195#define IPV6_FRAG_TIMEOUT	(60*HZ)		/* 60 seconds */
196
197/*
198 *	Function prototype for build_xmit
199 */
200
201typedef int		(*inet_getfrag_t) (const void *data,
202					   struct in6_addr *addr,
203					   char *,
204					   unsigned int, unsigned int);
205
206
207extern int		ipv6_addr_type(struct in6_addr *addr);
208
209static inline int ipv6_addr_scope(struct in6_addr *addr)
210{
211	return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
212}
213
214static inline int ipv6_addr_cmp(struct in6_addr *a1, struct in6_addr *a2)
215{
216	return memcmp((void *) a1, (void *) a2, sizeof(struct in6_addr));
217}
218
219static inline void ipv6_addr_copy(struct in6_addr *a1, struct in6_addr *a2)
220{
221	memcpy((void *) a1, (void *) a2, sizeof(struct in6_addr));
222}
223
224#ifndef __HAVE_ARCH_ADDR_SET
225static inline void ipv6_addr_set(struct in6_addr *addr,
226				     __u32 w1, __u32 w2,
227				     __u32 w3, __u32 w4)
228{
229	addr->s6_addr32[0] = w1;
230	addr->s6_addr32[1] = w2;
231	addr->s6_addr32[2] = w3;
232	addr->s6_addr32[3] = w4;
233}
234#endif
235
236static inline int ipv6_addr_any(struct in6_addr *a)
237{
238	return ((a->s6_addr32[0] | a->s6_addr32[1] |
239		 a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
240}
241
242/*
243 *	Prototypes exported by ipv6
244 */
245
246/*
247 *	rcv function (called from netdevice level)
248 */
249
250extern int			ipv6_rcv(struct sk_buff *skb,
251					 struct net_device *dev,
252					 struct packet_type *pt);
253
254/*
255 *	upper-layer output functions
256 */
257extern int			ip6_xmit(struct sock *sk,
258					 struct sk_buff *skb,
259					 struct flowi *fl,
260					 struct ipv6_txoptions *opt);
261
262extern int			ip6_nd_hdr(struct sock *sk,
263					   struct sk_buff *skb,
264					   struct net_device *dev,
265					   struct in6_addr *saddr,
266					   struct in6_addr *daddr,
267					   int proto, int len);
268
269extern int			ip6_build_xmit(struct sock *sk,
270					       inet_getfrag_t getfrag,
271					       const void *data,
272					       struct flowi *fl,
273					       unsigned length,
274					       struct ipv6_txoptions *opt,
275					       int hlimit, int flags);
276
277/*
278 *	skb processing functions
279 */
280
281extern int			ip6_output(struct sk_buff *skb);
282extern int			ip6_forward(struct sk_buff *skb);
283extern int			ip6_input(struct sk_buff *skb);
284extern int			ip6_mc_input(struct sk_buff *skb);
285
286/*
287 *	Extension header (options) processing
288 */
289
290extern u8 *			ipv6_build_nfrag_opts(struct sk_buff *skb,
291						      u8 *prev_hdr,
292						      struct ipv6_txoptions *opt,
293						      struct in6_addr *daddr,
294						      u32 jumbolen);
295extern u8 *			ipv6_build_frag_opts(struct sk_buff *skb,
296						     u8 *prev_hdr,
297						     struct ipv6_txoptions *opt);
298extern void 			ipv6_push_nfrag_opts(struct sk_buff *skb,
299						     struct ipv6_txoptions *opt,
300						     u8 *proto,
301						     struct in6_addr **daddr_p);
302extern void			ipv6_push_frag_opts(struct sk_buff *skb,
303						    struct ipv6_txoptions *opt,
304						    u8 *proto);
305
306extern int			ipv6_skip_exthdr(struct sk_buff *, int start,
307					         u8 *nexthdrp, int len);
308
309extern int 			ipv6_ext_hdr(u8 nexthdr);
310
311extern struct ipv6_txoptions *	ipv6_invert_rthdr(struct sock *sk,
312						  struct ipv6_rt_hdr *hdr);
313
314
315/*
316 *	socket options (ipv6_sockglue.c)
317 */
318
319extern int			ipv6_setsockopt(struct sock *sk, int level,
320						int optname, char *optval,
321						int optlen);
322extern int			ipv6_getsockopt(struct sock *sk, int level,
323						int optname, char *optval,
324						int *optlen);
325
326extern void			ipv6_packet_init(void);
327
328extern void			ipv6_netdev_notif_init(void);
329
330extern void			ipv6_packet_cleanup(void);
331
332extern void			ipv6_netdev_notif_cleanup(void);
333
334extern int 			ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
335extern void			ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, u16 port,
336						u32 info, u8 *payload);
337extern void			ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info);
338
339#endif /* __KERNEL__ */
340#endif /* _NET_IPV6_H */
341
342
343
344