xref: /freebsd/sys/netinet6/in6_proto.c (revision 23f282aa31e9b6fceacd449020e936e98d6f2298)
1 /*
2  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the project nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 
32 /*
33  * Copyright (c) 1982, 1986, 1993
34  *	The Regents of the University of California.  All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  * 3. All advertising materials mentioning features or use of this software
45  *    must display the following acknowledgement:
46  *	This product includes software developed by the University of
47  *	California, Berkeley and its contributors.
48  * 4. Neither the name of the University nor the names of its contributors
49  *    may be used to endorse or promote products derived from this software
50  *    without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62  * SUCH DAMAGE.
63  *
64  *	@(#)in_proto.c	8.1 (Berkeley) 6/10/93
65  */
66 
67 #include "opt_inet.h"
68 #include "opt_ipsec.h"
69 
70 #include <sys/param.h>
71 #include <sys/socket.h>
72 #include <sys/socketvar.h>
73 #include <sys/protosw.h>
74 #include <sys/kernel.h>
75 #include <sys/domain.h>
76 #include <sys/mbuf.h>
77 #include <sys/systm.h>
78 #include <sys/sysctl.h>
79 
80 #include <net/if.h>
81 #include <net/radix.h>
82 #include <net/route.h>
83 
84 #include <netinet/in.h>
85 #include <netinet/in_systm.h>
86 #include <netinet/in_var.h>
87 #include <netinet/ip.h>
88 #include <netinet/ip_var.h>
89 #include <netinet6/ip6.h>
90 #include <netinet6/ip6_var.h>
91 #include <netinet6/icmp6.h>
92 
93 #include <netinet/tcp.h>
94 #include <netinet/tcp_timer.h>
95 #include <netinet/tcp_var.h>
96 #include <netinet/udp.h>
97 #include <netinet/udp_var.h>
98 #include <netinet6/tcp6_var.h>
99 #include <netinet6/udp6_var.h>
100 
101 #include <netinet6/pim6_var.h>
102 
103 #include <netinet6/nd6.h>
104 #include <netinet6/in6_prefix.h>
105 
106 #ifdef IPSEC
107 #include <netinet6/ipsec.h>
108 #include <netinet6/ah.h>
109 #include <netinet6/ipsec6.h>
110 #include <netinet6/ah6.h>
111 #ifdef IPSEC_ESP
112 #include <netinet6/esp.h>
113 #include <netinet6/esp6.h>
114 #endif
115 #endif /*IPSEC*/
116 
117 #include <netinet6/ip6protosw.h>
118 
119 #include "gif.h"
120 #if NGIF > 0
121 #include <netinet6/in6_gif.h>
122 #endif
123 
124 #include <net/net_osdep.h>
125 
126 #define	offsetof(type, member)	((size_t)(&((type *)0)->member))
127 
128 /*
129  * TCP/IP protocol family: IP6, ICMP6, UDP, TCP.
130  */
131 
132 extern struct	domain inet6domain;
133 static struct	pr_usrreqs nousrreqs;
134 
135 struct ip6protosw inet6sw[] = {
136 { 0,		&inet6domain,	IPPROTO_IPV6,	0,
137   0,		0,		0,		0,
138   0,
139   ip6_init,	0,		frag6_slowtimo,	frag6_drain,
140   &nousrreqs,
141 },
142 { SOCK_DGRAM,	&inet6domain,	IPPROTO_UDP,	PR_ATOMIC | PR_ADDR,
143   udp6_input,	0,		udp6_ctlinput,	ip6_ctloutput,
144   0,
145   0,		0,		0,		0,
146   &udp6_usrreqs,
147 },
148 { SOCK_STREAM,	&inet6domain,	IPPROTO_TCP,	PR_CONNREQUIRED | PR_WANTRCVD,
149   tcp6_input,	0,		tcp6_ctlinput,	tcp_ctloutput,
150   0,
151 #ifdef INET	/* don't call timeout routines twice */
152   tcp_init,	0,		0,		tcp_drain,
153 #else
154   tcp_init,	0,		tcp_slowtimo,	tcp_drain,
155 #endif
156   &tcp6_usrreqs,
157 },
158 { SOCK_RAW,	&inet6domain,	IPPROTO_RAW,	PR_ATOMIC | PR_ADDR,
159   rip6_input,	rip6_output,	0,		rip6_ctloutput,
160   0,
161   0,		0,		0,		0,
162   &rip6_usrreqs
163 },
164 { SOCK_RAW,	&inet6domain,	IPPROTO_ICMPV6,	PR_ATOMIC | PR_ADDR,
165   icmp6_input,	rip6_output,	0,		rip6_ctloutput,
166   0,
167   icmp6_init,	icmp6_fasttimo,	0,		0,
168   &rip6_usrreqs
169 },
170 { SOCK_RAW,	&inet6domain,	IPPROTO_DSTOPTS,PR_ATOMIC|PR_ADDR,
171   dest6_input,	0,	 	0,		0,
172   0,
173   0,		0,		0,		0,
174   &nousrreqs
175 },
176 { SOCK_RAW,	&inet6domain,	IPPROTO_ROUTING,PR_ATOMIC|PR_ADDR,
177   route6_input,	0,	 	0,		0,
178   0,
179   0,		0,		0,		0,
180   &nousrreqs
181 },
182 { SOCK_RAW,	&inet6domain,	IPPROTO_FRAGMENT,PR_ATOMIC|PR_ADDR,
183   frag6_input,	0,	 	0,		0,
184   0,
185   0,		0,		0,		0,
186   &nousrreqs
187 },
188 #ifdef IPSEC
189 { SOCK_RAW,	&inet6domain,	IPPROTO_AH,	PR_ATOMIC|PR_ADDR,
190   ah6_input,	0,	 	0,		0,
191   0,
192   0,		0,		0,		0,
193   &nousrreqs,
194 },
195 #ifdef IPSEC_ESP
196 { SOCK_RAW,	&inet6domain,	IPPROTO_ESP,	PR_ATOMIC|PR_ADDR,
197   esp6_input,	0,	 	0,		0,
198   0,
199   0,		0,		0,		0,
200   &nousrreqs,
201 },
202 #endif
203 #endif /* IPSEC */
204 #if NGIF > 0
205 { SOCK_RAW,	&inet6domain,	IPPROTO_IPV4,	PR_ATOMIC|PR_ADDR,
206   in6_gif_input,0,	 	0,		0,
207   0,
208   0,		0,		0,		0,
209   &nousrreqs
210 },
211 { SOCK_RAW,	&inet6domain,	IPPROTO_IPV6,	PR_ATOMIC|PR_ADDR,
212   in6_gif_input,0,	 	0,		0,
213   0,
214   0,		0,		0,		0,
215   &nousrreqs
216 },
217 #endif /* GIF */
218 { SOCK_RAW,     &inet6domain,	IPPROTO_PIM,	PR_ATOMIC|PR_ADDR,
219   pim6_input,    rip6_output,	0,              rip6_ctloutput,
220   0,
221   0,		0,		0,		0,
222   &rip6_usrreqs
223 },
224 /* raw wildcard */
225 { SOCK_RAW,	&inet6domain,	0,		PR_ATOMIC | PR_ADDR,
226   rip6_input,	rip6_output,	0,		rip6_ctloutput,
227   0,
228   0,		0,		0,		0,
229   &rip6_usrreqs
230 },
231 };
232 
233 extern int	in6_inithead __P((void **, int));
234 
235 struct domain inet6domain =
236     { AF_INET6, "internet6", 0, 0, 0,
237       (struct protosw *)inet6sw,
238       (struct protosw *)&inet6sw[sizeof(inet6sw)/sizeof(inet6sw[0])], 0,
239       in6_inithead,
240       offsetof(struct sockaddr_in6, sin6_addr) << 3,
241       sizeof(struct sockaddr_in6) };
242 
243 DOMAIN_SET(inet6);
244 
245 /*
246  * Internet configuration info
247  */
248 #ifndef	IPV6FORWARDING
249 #ifdef GATEWAY6
250 #define	IPV6FORWARDING	1	/* forward IP6 packets not for us */
251 #else
252 #define	IPV6FORWARDING	0	/* don't forward IP6 packets not for us */
253 #endif /* GATEWAY6 */
254 #endif /* !IPV6FORWARDING */
255 
256 #ifndef	IPV6_SENDREDIRECTS
257 #define	IPV6_SENDREDIRECTS	1
258 #endif
259 
260 int	ip6_forwarding = IPV6FORWARDING;	/* act as router? */
261 int	ip6_sendredirects = IPV6_SENDREDIRECTS;
262 int	ip6_defhlim = IPV6_DEFHLIM;
263 int	ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS;
264 int	ip6_accept_rtadv = 0;	/* "IPV6FORWARDING ? 0 : 1" is dangerous */
265 int	ip6_maxfragpackets = 200;
266 int	ip6_log_interval = 5;
267 int	ip6_hdrnestlimit = 50;	/* appropriate? */
268 int	ip6_dad_count = 1;	/* DupAddrDetectionTransmits */
269 u_int32_t	ip6_flow_seq;
270 int	ip6_auto_flowlabel = 1;
271 #if NGIF > 0
272 int	ip6_gif_hlim = GIF_HLIM;
273 #else
274 int	ip6_gif_hlim = 0;
275 #endif
276 int	ip6_use_deprecated = 1;	/* allow deprecated addr (RFC2462 5.5.4) */
277 int	ip6_rr_prune = 5;	/* router renumbering prefix
278 				 * walk list every 5 sec.    */
279 int	ip6_mapped_addr_on = 1;
280 
281 u_int32_t ip6_id = 0UL;
282 int	ip6_keepfaith = 0;
283 time_t	ip6_log_time = (time_t)0L;
284 
285 /* icmp6 */
286 /*
287  * BSDI4 defines these variables in in_proto.c...
288  * XXX: what if we don't define INET? Should we define pmtu6_expire
289  * or so? (jinmei@kame.net 19990310)
290  */
291 int	pmtu_expire = 60*10;
292 int	pmtu_probe = 60*2;
293 
294 /* raw IP6 parameters */
295 /*
296  * Nominal space allocated to a raw ip socket.
297  */
298 #define	RIPV6SNDQ	8192
299 #define	RIPV6RCVQ	8192
300 
301 u_long	rip6_sendspace = RIPV6SNDQ;
302 u_long	rip6_recvspace = RIPV6RCVQ;
303 
304 /* ICMPV6 parameters */
305 int	icmp6_rediraccept = 1;		/* accept and process redirects */
306 int	icmp6_redirtimeout = 10 * 60;	/* 10 minutes */
307 u_int	icmp6errratelim = 1000;		/* 1000usec = 1msec */
308 
309 /* UDP on IP6 parameters */
310 int	udp6_sendspace = 9216;		/* really max datagram size */
311 int	udp6_recvspace = 40 * (1024 + sizeof(struct sockaddr_in6));
312 					/* 40 1K datagrams */
313 
314 /*
315  * sysctl related items.
316  */
317 SYSCTL_NODE(_net,	PF_INET6,	inet6,	CTLFLAG_RW,	0,
318 	"Internet6 Family");
319 
320 /* net.inet6 */
321 SYSCTL_NODE(_net_inet6,	IPPROTO_IPV6,	ip6,	CTLFLAG_RW, 0,	"IP6");
322 SYSCTL_NODE(_net_inet6,	IPPROTO_ICMPV6,	icmp6,	CTLFLAG_RW, 0,	"ICMP6");
323 SYSCTL_NODE(_net_inet6,	IPPROTO_UDP,	udp6,	CTLFLAG_RW, 0,	"UDP6");
324 SYSCTL_NODE(_net_inet6,	IPPROTO_TCP,	tcp6,	CTLFLAG_RW, 0,	"TCP6");
325 #ifdef IPSEC
326 SYSCTL_NODE(_net_inet6,	IPPROTO_ESP,	ipsec6,	CTLFLAG_RW, 0,	"IPSEC6");
327 #endif /* IPSEC */
328 
329 /* net.inet6.ip6 */
330 static int
331 sysctl_ip6_forwarding SYSCTL_HANDLER_ARGS
332 {
333 	int error = 0;
334 	int old_ip6_forwarding;
335 	int changed;
336 
337 	error = SYSCTL_OUT(req, arg1, sizeof(int));
338 	if (error || !req->newptr)
339 		return (error);
340 	old_ip6_forwarding = ip6_forwarding;
341 	error = SYSCTL_IN(req, arg1, sizeof(int));
342 	if (error != 0)
343 		return (error);
344 	changed = (ip6_forwarding ? 1 : 0) ^ (old_ip6_forwarding ? 1 : 0);
345 	if (changed == 0)
346 		return (error);
347 	if (ip6_forwarding != 0) {	/* host becomes router */
348 		int s = splnet();
349 		struct nd_prefix *pr, *next;
350 
351 		for (pr = LIST_FIRST(&nd_prefix); pr; pr = next) {
352 			next = LIST_NEXT(pr, ndpr_entry);
353 			if (!IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr))
354 				in6_ifdel(pr->ndpr_ifp, &pr->ndpr_addr);
355 			prelist_remove(pr);
356 		}
357 		splx(s);
358 	} else {			/* router becomes host */
359 		struct socket so;
360 
361 		/* XXX: init dummy so */
362 		bzero(&so, sizeof(so));
363 		while(!LIST_EMPTY(&rr_prefix))
364 			delete_each_prefix(&so, LIST_FIRST(&rr_prefix),
365 					   PR_ORIG_KERNEL);
366 	}
367 
368 	return (error);
369 }
370 
371 SYSCTL_OID(_net_inet6_ip6, IPV6CTL_FORWARDING, forwarding,
372 	   CTLTYPE_INT|CTLFLAG_RW, &ip6_forwarding, 0, sysctl_ip6_forwarding,
373 	   "I", "");
374 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_SENDREDIRECTS,
375 	redirect, CTLFLAG_RW,		&ip6_sendredirects,	0, "");
376 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFHLIM,
377 	hlim, CTLFLAG_RW,		&ip6_defhlim,	0, "");
378 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGPACKETS,
379 	maxfragpackets, CTLFLAG_RW,	&ip6_maxfragpackets,	0, "");
380 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_ACCEPT_RTADV,
381 	accept_rtadv, CTLFLAG_RW,	&ip6_accept_rtadv,	0, "");
382 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_KEEPFAITH,
383 	keepfaith, CTLFLAG_RW,		&ip6_keepfaith,	0, "");
384 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_LOG_INTERVAL,
385 	log_interval, CTLFLAG_RW,	&ip6_log_interval,	0, "");
386 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_HDRNESTLIMIT,
387 	hdrnestlimit, CTLFLAG_RW,	&ip6_hdrnestlimit,	0, "");
388 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DAD_COUNT,
389 	dad_count, CTLFLAG_RW,	&ip6_dad_count,	0, "");
390 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_AUTO_FLOWLABEL,
391 	auto_flowlabel, CTLFLAG_RW,	&ip6_auto_flowlabel,	0, "");
392 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFMCASTHLIM,
393 	defmcasthlim, CTLFLAG_RW,	&ip6_defmcasthlim,	0, "");
394 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM,
395 	gifhlim, CTLFLAG_RW,	&ip6_gif_hlim,			0, "");
396 SYSCTL_STRING(_net_inet6_ip6, IPV6CTL_KAME_VERSION,
397 	kame_version, CTLFLAG_RD,	__KAME_VERSION,		0, "");
398 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_USE_DEPRECATED,
399 	use_deprecated, CTLFLAG_RW,	&ip6_use_deprecated,	0, "");
400 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_RR_PRUNE,
401 	rr_prune, CTLFLAG_RW,	&ip6_rr_prune,			0, "");
402 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAPPED_ADDR,
403 	mapped_addr, CTLFLAG_RW,	&ip6_mapped_addr_on,	0, "");
404 
405 /* net.inet6.icmp6 */
406 SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRACCEPT,
407 	rediraccept, CTLFLAG_RW,	&icmp6_rediraccept,	0, "");
408 SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRTIMEOUT,
409 	redirtimeout, CTLFLAG_RW,	&icmp6_redirtimeout,	0, "");
410 SYSCTL_STRUCT(_net_inet6_icmp6, ICMPV6CTL_STATS, stats, CTLFLAG_RD,
411 	&icmp6stat, icmp6stat, "");
412 SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ERRRATELIMIT,
413 	errratelimit, CTLFLAG_RW,	&icmp6errratelim,	0, "");
414 SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_PRUNE,
415 	nd6_prune, CTLFLAG_RW,		&nd6_prune,	0, "");
416 SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_DELAY,
417 	nd6_delay, CTLFLAG_RW,		&nd6_delay,	0, "");
418 SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_UMAXTRIES,
419 	nd6_umaxtries, CTLFLAG_RW,	&nd6_umaxtries,	0, "");
420 SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MMAXTRIES,
421 	nd6_mmaxtries, CTLFLAG_RW,	&nd6_mmaxtries,	0, "");
422 SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_USELOOPBACK,
423 	nd6_useloopback, CTLFLAG_RW,	&nd6_useloopback, 0, "");
424 SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_PROXYALL,
425 	nd6_proxyall, CTLFLAG_RW,	&nd6_proxyall, 0, "");
426