in6_proto.c revision 62587
1345153Sdim/*	$FreeBSD: head/sys/netinet6/in6_proto.c 62587 2000-07-04 16:35:15Z itojun $	*/
2345153Sdim/*	$KAME: in6_proto.c,v 1.64 2000/06/20 16:20:27 itojun Exp $	*/
3345153Sdim
4345153Sdim/*
5345153Sdim * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6345153Sdim * All rights reserved.
7345153Sdim *
8345153Sdim * Redistribution and use in source and binary forms, with or without
9345153Sdim * modification, are permitted provided that the following conditions
10345153Sdim * are met:
11345153Sdim * 1. Redistributions of source code must retain the above copyright
12345153Sdim *    notice, this list of conditions and the following disclaimer.
13345153Sdim * 2. Redistributions in binary form must reproduce the above copyright
14345153Sdim *    notice, this list of conditions and the following disclaimer in the
15345153Sdim *    documentation and/or other materials provided with the distribution.
16345153Sdim * 3. Neither the name of the project nor the names of its contributors
17345153Sdim *    may be used to endorse or promote products derived from this software
18345153Sdim *    without specific prior written permission.
19345153Sdim *
20345153Sdim * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21345153Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22345153Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23345153Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24345153Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25345153Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26345153Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27345153Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28345153Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29345153Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30345153Sdim * SUCH DAMAGE.
31345153Sdim */
32345153Sdim
33345153Sdim/*
34345153Sdim * Copyright (c) 1982, 1986, 1993
35345153Sdim *	The Regents of the University of California.  All rights reserved.
36345153Sdim *
37345153Sdim * Redistribution and use in source and binary forms, with or without
38345153Sdim * modification, are permitted provided that the following conditions
39345153Sdim * are met:
40345153Sdim * 1. Redistributions of source code must retain the above copyright
41345153Sdim *    notice, this list of conditions and the following disclaimer.
42345153Sdim * 2. Redistributions in binary form must reproduce the above copyright
43345153Sdim *    notice, this list of conditions and the following disclaimer in the
44345153Sdim *    documentation and/or other materials provided with the distribution.
45345153Sdim * 3. All advertising materials mentioning features or use of this software
46345153Sdim *    must display the following acknowledgement:
47345153Sdim *	This product includes software developed by the University of
48345153Sdim *	California, Berkeley and its contributors.
49345153Sdim * 4. Neither the name of the University nor the names of its contributors
50345153Sdim *    may be used to endorse or promote products derived from this software
51345153Sdim *    without specific prior written permission.
52345153Sdim *
53345153Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54345153Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55345153Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56345153Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57345153Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58345153Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59345153Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60345153Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61345153Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62345153Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63345153Sdim * SUCH DAMAGE.
64345153Sdim *
65345153Sdim *	@(#)in_proto.c	8.1 (Berkeley) 6/10/93
66345153Sdim */
67345153Sdim
68345153Sdim#include "opt_inet.h"
69345153Sdim#include "opt_inet6.h"
70345153Sdim#include "opt_ipsec.h"
71345153Sdim
72345153Sdim#include <sys/param.h>
73345153Sdim#include <sys/socket.h>
74345153Sdim#include <sys/socketvar.h>
75345153Sdim#include <sys/protosw.h>
76345153Sdim#include <sys/kernel.h>
77345153Sdim#include <sys/domain.h>
78345153Sdim#include <sys/mbuf.h>
79345153Sdim#include <sys/systm.h>
80345153Sdim#include <sys/sysctl.h>
81345153Sdim
82345153Sdim#include <net/if.h>
83345153Sdim#include <net/radix.h>
84345153Sdim#include <net/route.h>
85345153Sdim
86345153Sdim#include <netinet/in.h>
87345153Sdim#include <netinet/in_systm.h>
88345153Sdim#include <netinet/in_var.h>
89345153Sdim#include <netinet/ip_encap.h>
90345153Sdim#include <netinet/ip.h>
91345153Sdim#include <netinet/ip_var.h>
92345153Sdim#include <netinet/ip6.h>
93345153Sdim#include <netinet6/ip6_var.h>
94345153Sdim#include <netinet/icmp6.h>
95345153Sdim
96345153Sdim#include <netinet/tcp.h>
97345153Sdim#include <netinet/tcp_timer.h>
98345153Sdim#include <netinet/tcp_var.h>
99345153Sdim#include <netinet/udp.h>
100345153Sdim#include <netinet/udp_var.h>
101345153Sdim#include <netinet6/tcp6_var.h>
102345153Sdim
103345153Sdim#include <netinet6/udp6_var.h>
104345153Sdim
105345153Sdim#include <netinet6/pim6_var.h>
106345153Sdim
107345153Sdim#include <netinet6/nd6.h>
108345153Sdim#include <netinet6/in6_prefix.h>
109345153Sdim
110345153Sdim#ifdef IPSEC
111345153Sdim#include <netinet6/ipsec.h>
112345153Sdim#include <netinet6/ipsec6.h>
113345153Sdim#include <netinet6/ah.h>
114345153Sdim#include <netinet6/ah6.h>
115345153Sdim#ifdef IPSEC_ESP
116345153Sdim#include <netinet6/esp.h>
117345153Sdim#include <netinet6/esp6.h>
118345153Sdim#endif
119345153Sdim#include <netinet6/ipcomp.h>
120345153Sdim#include <netinet6/ipcomp6.h>
121345153Sdim#endif /*IPSEC*/
122345153Sdim
123345153Sdim#include <netinet6/ip6protosw.h>
124345153Sdim
125345153Sdim#include "gif.h"
126345153Sdim#if NGIF > 0
127345153Sdim#include <netinet6/in6_gif.h>
128345153Sdim#endif
129345153Sdim
130345153Sdim#include <net/net_osdep.h>
131345153Sdim
132345153Sdim#define	offsetof(type, member)	((size_t)(&((type *)0)->member))
133345153Sdim
134345153Sdim/*
135345153Sdim * TCP/IP protocol family: IP6, ICMP6, UDP, TCP.
136345153Sdim */
137345153Sdim
138345153Sdimextern	struct domain inet6domain;
139345153Sdimstatic struct pr_usrreqs nousrreqs;
140345153Sdim
141345153Sdimstruct ip6protosw inet6sw[] = {
142345153Sdim{ 0,		&inet6domain,	IPPROTO_IPV6,	0,
143345153Sdim  0,		0,		0,		0,
144345153Sdim  0,
145345153Sdim  ip6_init,	0,		frag6_slowtimo,	frag6_drain,
146345153Sdim  &nousrreqs,
147345153Sdim},
148345153Sdim{ SOCK_DGRAM,	&inet6domain,	IPPROTO_UDP,	PR_ATOMIC | PR_ADDR,
149345153Sdim  udp6_input,	0,		udp6_ctlinput,	ip6_ctloutput,
150345153Sdim  0,
151345153Sdim  0,		0,		0,		0,
152345153Sdim  &udp6_usrreqs,
153345153Sdim},
154345153Sdim{ SOCK_STREAM,	&inet6domain,	IPPROTO_TCP,	PR_CONNREQUIRED | PR_WANTRCVD,
155345153Sdim  tcp6_input,	0,		tcp6_ctlinput,	tcp_ctloutput,
156345153Sdim  0,
157345153Sdim#ifdef INET	/* don't call timeout routines twice */
158345153Sdim  tcp_init,	0,		0,		tcp_drain,
159345153Sdim#else
160345153Sdim  tcp_init,	tcp_fasttimo,	tcp_slowtimo,	tcp_drain,
161345153Sdim#endif
162345153Sdim  &tcp6_usrreqs,
163345153Sdim},
164345153Sdim{ SOCK_RAW,	&inet6domain,	IPPROTO_RAW,	PR_ATOMIC | PR_ADDR,
165345153Sdim  rip6_input,	rip6_output,	rip6_ctlinput,	rip6_ctloutput,
166345153Sdim  0,
167345153Sdim  0,		0,		0,		0,
168345153Sdim  &rip6_usrreqs
169345153Sdim},
170345153Sdim{ SOCK_RAW,	&inet6domain,	IPPROTO_ICMPV6,	PR_ATOMIC | PR_ADDR,
171345153Sdim  icmp6_input,	rip6_output,	0,		rip6_ctloutput,
172345153Sdim  0,
173345153Sdim  icmp6_init,	icmp6_fasttimo,	0,		0,
174345153Sdim  &rip6_usrreqs
175345153Sdim},
176345153Sdim{ SOCK_RAW,	&inet6domain,	IPPROTO_DSTOPTS,PR_ATOMIC|PR_ADDR,
177345153Sdim  dest6_input,	0,	 	0,		0,
178345153Sdim  0,
179345153Sdim  0,		0,		0,		0,
180345153Sdim  &nousrreqs
181345153Sdim},
182345153Sdim{ SOCK_RAW,	&inet6domain,	IPPROTO_ROUTING,PR_ATOMIC|PR_ADDR,
183345153Sdim  route6_input,	0,	 	0,		0,
184345153Sdim  0,
185345153Sdim  0,		0,		0,		0,
186345153Sdim  &nousrreqs
187345153Sdim},
188345153Sdim{ SOCK_RAW,	&inet6domain,	IPPROTO_FRAGMENT,PR_ATOMIC|PR_ADDR,
189345153Sdim  frag6_input,	0,	 	0,		0,
190345153Sdim  0,
191345153Sdim  0,		0,		0,		0,
192345153Sdim  &nousrreqs
193345153Sdim},
194345153Sdim#ifdef IPSEC
195345153Sdim{ SOCK_RAW,	&inet6domain,	IPPROTO_AH,	PR_ATOMIC|PR_ADDR,
196345153Sdim  ah6_input,	0,	 	0,		0,
197345153Sdim  0,
198345153Sdim  0,		0,		0,		0,
199345153Sdim  &nousrreqs,
200345153Sdim},
201345153Sdim#ifdef IPSEC_ESP
202345153Sdim{ SOCK_RAW,	&inet6domain,	IPPROTO_ESP,	PR_ATOMIC|PR_ADDR,
203345153Sdim  esp6_input,	0,	 	0,		0,
204345153Sdim  0,
205345153Sdim  0,		0,		0,		0,
206345153Sdim  &nousrreqs,
207345153Sdim},
208345153Sdim#endif
209345153Sdim{ SOCK_RAW,	&inet6domain,	IPPROTO_IPCOMP,	PR_ATOMIC|PR_ADDR,
210345153Sdim  ipcomp6_input, 0,	 	0,		0,
211345153Sdim  0,
212345153Sdim  0,		0,		0,		0,
213345153Sdim  &nousrreqs,
214345153Sdim},
215345153Sdim#endif /* IPSEC */
216345153Sdim#ifdef INET
217345153Sdim{ SOCK_RAW,	&inet6domain,	IPPROTO_IPV4,	PR_ATOMIC|PR_ADDR,
218345153Sdim  encap6_input,	rip6_output, 	0,		rip6_ctloutput,
219345153Sdim  0,
220345153Sdim  0,		0,		0,		0,
221345153Sdim  &rip6_usrreqs
222345153Sdim},
223345153Sdim#endif /*INET*/
224345153Sdim{ SOCK_RAW,	&inet6domain,	IPPROTO_IPV6,	PR_ATOMIC|PR_ADDR,
225345153Sdim  encap6_input, rip6_output,	 0,	rip6_ctloutput,
226345153Sdim  0,
227345153Sdim#ifndef INET
228345153Sdim  encap_init,	0,		0,		0,
229345153Sdim#else
230345153Sdim  0,		0,		0,		0,
231345153Sdim#endif
232345153Sdim  &rip6_usrreqs
233345153Sdim},
234345153Sdim{ SOCK_RAW,     &inet6domain,	IPPROTO_PIM,	PR_ATOMIC|PR_ADDR,
235345153Sdim  pim6_input,    rip6_output,	0,              rip6_ctloutput,
236345153Sdim  0,
237345153Sdim  0,            0,              0,              0,
238345153Sdim  &rip6_usrreqs
239345153Sdim},
240345153Sdim/* raw wildcard */
241345153Sdim{ SOCK_RAW,	&inet6domain,	0,		PR_ATOMIC | PR_ADDR,
242345153Sdim  rip6_input,	rip6_output,	0,		rip6_ctloutput,
243345153Sdim  0, 0,
244345153Sdim  0,		0,		0,
245345153Sdim  &rip6_usrreqs
246345153Sdim},
247345153Sdim};
248345153Sdim
249345153Sdim#if NGIF > 0
250345153Sdimstruct ip6protosw in6_gif_protosw =
251345153Sdim{ SOCK_RAW,	&inet6domain,	0/*IPPROTO_IPV[46]*/,	PR_ATOMIC|PR_ADDR,
252345153Sdim  in6_gif_input, rip6_output,	0,		rip6_ctloutput,
253345153Sdim  0,
254345153Sdim  0,            0,              0,              0,
255345153Sdim  &rip6_usrreqs
256345153Sdim};
257345153Sdim#endif /*NGIF*/
258345153Sdim
259345153Sdimextern int in6_inithead __P((void **, int));
260345153Sdim
261345153Sdimstruct domain inet6domain =
262345153Sdim    { AF_INET6, "internet6", 0, 0, 0,
263345153Sdim      (struct protosw *)inet6sw,
264345153Sdim      (struct protosw *)&inet6sw[sizeof(inet6sw)/sizeof(inet6sw[0])], 0,
265345153Sdim      in6_inithead,
266345153Sdim      offsetof(struct sockaddr_in6, sin6_addr) << 3,
267345153Sdim      sizeof(struct sockaddr_in6) };
268345153Sdim
269345153SdimDOMAIN_SET(inet6);
270345153Sdim
271345153Sdim/*
272345153Sdim * Internet configuration info
273345153Sdim */
274345153Sdim#ifndef	IPV6FORWARDING
275345153Sdim#ifdef GATEWAY6
276345153Sdim#define	IPV6FORWARDING	1	/* forward IP6 packets not for us */
277345153Sdim#else
278345153Sdim#define	IPV6FORWARDING	0	/* don't forward IP6 packets not for us */
279345153Sdim#endif /* GATEWAY6 */
280345153Sdim#endif /* !IPV6FORWARDING */
281345153Sdim
282345153Sdim#ifndef	IPV6_SENDREDIRECTS
283345153Sdim#define	IPV6_SENDREDIRECTS	1
284345153Sdim#endif
285345153Sdim
286345153Sdimint	ip6_forwarding = IPV6FORWARDING;	/* act as router? */
287345153Sdimint	ip6_sendredirects = IPV6_SENDREDIRECTS;
288345153Sdimint	ip6_defhlim = IPV6_DEFHLIM;
289345153Sdimint	ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS;
290345153Sdimint	ip6_accept_rtadv = 0;	/* "IPV6FORWARDING ? 0 : 1" is dangerous */
291345153Sdimint	ip6_maxfragpackets = 200;
292345153Sdimint	ip6_log_interval = 5;
293345153Sdimint	ip6_hdrnestlimit = 50;	/* appropriate? */
294345153Sdimint	ip6_dad_count = 1;	/* DupAddrDetectionTransmits */
295345153Sdimu_int32_t ip6_flow_seq;
296345153Sdimint	ip6_auto_flowlabel = 1;
297345153Sdim#if NGIF > 0
298345153Sdimint	ip6_gif_hlim = GIF_HLIM;
299345153Sdim#else
300345153Sdimint	ip6_gif_hlim = 0;
301345153Sdim#endif
302345153Sdimint	ip6_use_deprecated = 1;	/* allow deprecated addr (RFC2462 5.5.4) */
303345153Sdimint	ip6_rr_prune = 5;	/* router renumbering prefix
304345153Sdim				 * walk list every 5 sec.    */
305345153Sdimint	ip6_mapped_addr_on = 1;
306345153Sdim
307345153Sdimu_int32_t ip6_id = 0UL;
308345153Sdimint	ip6_keepfaith = 0;
309345153Sdimtime_t	ip6_log_time = (time_t)0L;
310345153Sdim
311345153Sdim/* icmp6 */
312345153Sdim/*
313345153Sdim * BSDI4 defines these variables in in_proto.c...
314345153Sdim * XXX: what if we don't define INET? Should we define pmtu6_expire
315345153Sdim * or so? (jinmei@kame.net 19990310)
316345153Sdim */
317345153Sdimint pmtu_expire = 60*10;
318345153Sdimint pmtu_probe = 60*2;
319345153Sdim
320345153Sdim/* raw IP6 parameters */
321345153Sdim/*
322345153Sdim * Nominal space allocated to a raw ip socket.
323345153Sdim */
324345153Sdim#define	RIPV6SNDQ	8192
325345153Sdim#define	RIPV6RCVQ	8192
326345153Sdim
327345153Sdimu_long	rip6_sendspace = RIPV6SNDQ;
328345153Sdimu_long	rip6_recvspace = RIPV6RCVQ;
329345153Sdim
330345153Sdim/* ICMPV6 parameters */
331345153Sdimint	icmp6_rediraccept = 1;		/* accept and process redirects */
332345153Sdimint	icmp6_redirtimeout = 10 * 60;	/* 10 minutes */
333345153Sdimstruct timeval icmp6errratelim = { 0, 0 };	/* no ratelimit */
334345153Sdimint	icmp6errppslim = 100;		/* 100pps */
335345153Sdimint	icmp6_nodeinfo = 1;		/* enable/disable NI response */
336345153Sdim
337345153Sdim#ifdef TCP6
338345153Sdim/* TCP on IP6 parameters */
339345153Sdimint	tcp6_sendspace = 1024 * 8;
340345153Sdimint	tcp6_recvspace = 1024 * 8;
341345153Sdimint 	tcp6_mssdflt = TCP6_MSS;
342345153Sdimint 	tcp6_rttdflt = TCP6TV_SRTTDFLT / PR_SLOWHZ;
343345153Sdimint	tcp6_do_rfc1323 = 1;
344345153Sdimint	tcp6_conntimeo = TCP6TV_KEEP_INIT;	/* initial connection timeout */
345345153Sdimint	tcp6_43maxseg = 0;
346345153Sdimint	tcp6_pmtu = 0;
347345153Sdim
348345153Sdim/*
349345153Sdim * Parameters for keepalive option.
350345153Sdim * Connections for which SO_KEEPALIVE is set will be probed
351345153Sdim * after being idle for a time of tcp6_keepidle (in units of PR_SLOWHZ).
352345153Sdim * Starting at that time, the connection is probed at intervals
353345153Sdim * of tcp6_keepintvl (same units) until a response is received
354345153Sdim * or until tcp6_keepcnt probes have been made, at which time
355345153Sdim * the connection is dropped.  Note that a tcp6_keepidle value
356345153Sdim * under 2 hours is nonconformant with RFC-1122, Internet Host Requirements.
357345153Sdim */
358345153Sdimint	tcp6_keepidle = TCP6TV_KEEP_IDLE;	/* time before probing idle */
359345153Sdimint	tcp6_keepintvl = TCP6TV_KEEPINTVL;	/* interval betwn idle probes */
360345153Sdimint	tcp6_keepcnt = TCP6TV_KEEPCNT;		/* max idle probes */
361345153Sdimint	tcp6_maxpersistidle = TCP6TV_KEEP_IDLE;	/* max idle time in persist */
362345153Sdim
363345153Sdim#ifndef INET_SERVER
364345153Sdim#define	TCP6_LISTEN_HASH_SIZE	17
365345153Sdim#define	TCP6_CONN_HASH_SIZE	97
366345153Sdim#define	TCP6_SYN_HASH_SIZE	293
367345153Sdim#define	TCP6_SYN_BUCKET_SIZE	35
368345153Sdim#else
369345153Sdim#define	TCP6_LISTEN_HASH_SIZE	97
370345153Sdim#define	TCP6_CONN_HASH_SIZE	9973
371345153Sdim#define	TCP6_SYN_HASH_SIZE	997
372345153Sdim#define	TCP6_SYN_BUCKET_SIZE	35
373345153Sdim#endif
374345153Sdimint	tcp6_listen_hash_size = TCP6_LISTEN_HASH_SIZE;
375345153Sdimint	tcp6_conn_hash_size = TCP6_CONN_HASH_SIZE;
376345153Sdimstruct	tcp6_hash_list tcp6_listen_hash[TCP6_LISTEN_HASH_SIZE],
377345153Sdim	tcp6_conn_hash[TCP6_CONN_HASH_SIZE];
378345153Sdim
379345153Sdimint	tcp6_syn_cache_size = TCP6_SYN_HASH_SIZE;
380345153Sdimint	tcp6_syn_cache_limit = TCP6_SYN_HASH_SIZE*TCP6_SYN_BUCKET_SIZE;
381345153Sdimint	tcp6_syn_bucket_limit = 3*TCP6_SYN_BUCKET_SIZE;
382345153Sdimstruct	syn_cache_head6 tcp6_syn_cache[TCP6_SYN_HASH_SIZE];
383345153Sdimstruct	syn_cache_head6 *tcp6_syn_cache_first;
384345153Sdimint	tcp6_syn_cache_interval = 8;	/* runs timer every 4 seconds */
385345153Sdimint	tcp6_syn_cache_timeo = TCP6TV_KEEP_INIT;
386345153Sdim
387345153Sdim/*
388345153Sdim * Parameters for computing a desirable data segment size
389345153Sdim * given an upper bound (either interface MTU, or peer's MSS option)_.
390345153Sdim * As applications tend to use a buffer size that is a multiple
391345153Sdim * of kilobytes, try for something that divides evenly. However,
392345153Sdim * do not round down too much.
393345153Sdim *
394345153Sdim * Round segment size down to a multiple of TCP6_ROUNDSIZE if this
395345153Sdim * does not result in lowering by more than (size/TCP6_ROUNDFRAC).
396345153Sdim * For example, round 536 to 512.  Older versions of the system
397345153Sdim * effectively used MCLBYTES (1K or 2K) as TCP6_ROUNDSIZE, with
398345153Sdim * a value of 1 for TCP6_ROUNDFRAC (eliminating its effect).
399345153Sdim * We round to a multiple of 256 for SLIP.
400345153Sdim */
401345153Sdim#ifndef	TCP6_ROUNDSIZE
402345153Sdim#define	TCP6_ROUNDSIZE	256	/* round to multiple of 256 */
403345153Sdim#endif
404345153Sdim#ifndef	TCP6_ROUNDFRAC
405345153Sdim#define	TCP6_ROUNDFRAC	10	/* round down at most N/10, or 10% */
406345153Sdim#endif
407345153Sdim
408345153Sdimint	tcp6_roundsize = TCP6_ROUNDSIZE;
409345153Sdimint	tcp6_roundfrac = TCP6_ROUNDFRAC;
410345153Sdim#endif /*TCP6*/
411345153Sdim
412345153Sdim/* UDP on IP6 parameters */
413345153Sdimint	udp6_sendspace = 9216;		/* really max datagram size */
414345153Sdimint	udp6_recvspace = 40 * (1024 + sizeof(struct sockaddr_in6));
415345153Sdim					/* 40 1K datagrams */
416345153Sdim
417345153Sdim/*
418345153Sdim * sysctl related items.
419345153Sdim */
420345153SdimSYSCTL_NODE(_net,	PF_INET6,	inet6,	CTLFLAG_RW,	0,
421345153Sdim	"Internet6 Family");
422345153Sdim
423345153Sdim/* net.inet6 */
424345153SdimSYSCTL_NODE(_net_inet6,	IPPROTO_IPV6,	ip6,	CTLFLAG_RW, 0,	"IP6");
425345153SdimSYSCTL_NODE(_net_inet6,	IPPROTO_ICMPV6,	icmp6,	CTLFLAG_RW, 0,	"ICMP6");
426345153SdimSYSCTL_NODE(_net_inet6,	IPPROTO_UDP,	udp6,	CTLFLAG_RW, 0,	"UDP6");
427345153SdimSYSCTL_NODE(_net_inet6,	IPPROTO_TCP,	tcp6,	CTLFLAG_RW, 0,	"TCP6");
428345153Sdim#ifdef IPSEC
429345153SdimSYSCTL_NODE(_net_inet6,	IPPROTO_ESP,	ipsec6,	CTLFLAG_RW, 0,	"IPSEC6");
430345153Sdim#endif /* IPSEC */
431345153Sdim
432345153Sdim/* net.inet6.ip6 */
433345153Sdimstatic int
434345153Sdimsysctl_ip6_forwarding(SYSCTL_HANDLER_ARGS)
435345153Sdim{
436345153Sdim	int error = 0;
437345153Sdim	int old_ip6_forwarding;
438345153Sdim	int changed;
439345153Sdim
440345153Sdim	error = SYSCTL_OUT(req, arg1, sizeof(int));
441345153Sdim	if (error || !req->newptr)
442345153Sdim		return (error);
443345153Sdim	old_ip6_forwarding = ip6_forwarding;
444345153Sdim	error = SYSCTL_IN(req, arg1, sizeof(int));
445345153Sdim	if (error != 0)
446345153Sdim		return (error);
447345153Sdim	changed = (ip6_forwarding ? 1 : 0) ^ (old_ip6_forwarding ? 1 : 0);
448345153Sdim	if (changed == 0)
449345153Sdim		return (error);
450345153Sdim	/*
451345153Sdim	 * XXX while host->router removes prefix got from RA,
452345153Sdim	 * router->host case nukes all the prefixes managed by in6_prefix.c
453345153Sdim	 * (both RR and static).  therefore, switching from host->router->host
454345153Sdim	 * will remove statically configured addresses/prefixes.
455345153Sdim	 * not sure if it is intended behavior or not.
456345153Sdim	 */
457345153Sdim	if (ip6_forwarding != 0) {	/* host becomes router */
458345153Sdim		int s = splnet();
459345153Sdim		struct nd_prefix *pr, *next;
460345153Sdim
461345153Sdim		for (pr = nd_prefix.lh_first; pr; pr = next) {
462345153Sdim			next = pr->ndpr_next;
463345153Sdim			if (!IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr))
464345153Sdim				in6_ifdel(pr->ndpr_ifp, &pr->ndpr_addr);
465345153Sdim			prelist_remove(pr);
466345153Sdim		}
467345153Sdim		splx(s);
468345153Sdim	} else {			/* router becomes host */
469345153Sdim		while(!LIST_EMPTY(&rr_prefix))
470345153Sdim			delete_each_prefix(LIST_FIRST(&rr_prefix),
471345153Sdim					   PR_ORIG_KERNEL);
472345153Sdim	}
473345153Sdim
474345153Sdim	return (error);
475345153Sdim}
476345153Sdim
477345153Sdimstatic int
478345153Sdimsysctl_icmp6_ratelimit (SYSCTL_HANDLER_ARGS)
479345153Sdim{
480345153Sdim	int rate_usec, error, s;
481345153Sdim
482345153Sdim	/*
483345153Sdim	 * The sysctl specifies the rate in usec-between-icmp,
484345153Sdim	 * so we must convert from/to a timeval.
485345153Sdim	 */
486345153Sdim	rate_usec = (icmp6errratelim.tv_sec * 1000000) +
487345153Sdim	    icmp6errratelim.tv_usec;
488345153Sdim	error = sysctl_handle_int(oidp, &rate_usec, 0, req);
489345153Sdim	if (error)
490345153Sdim		return (error);
491345153Sdim	if (rate_usec < 0)
492345153Sdim		return (EINVAL);
493345153Sdim	s = splnet();
494345153Sdim	icmp6errratelim.tv_sec = rate_usec / 1000000;
495345153Sdim	icmp6errratelim.tv_usec = rate_usec % 1000000;
496345153Sdim	splx(s);
497345153Sdim
498345153Sdim	return (0);
499345153Sdim}
500345153Sdim
501345153SdimSYSCTL_OID(_net_inet6_ip6, IPV6CTL_FORWARDING, forwarding,
502345153Sdim	   CTLTYPE_INT|CTLFLAG_RW, &ip6_forwarding, 0, sysctl_ip6_forwarding,
503345153Sdim	   "I", "");
504345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_SENDREDIRECTS,
505345153Sdim	redirect, CTLFLAG_RW,		&ip6_sendredirects,	0, "");
506345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFHLIM,
507345153Sdim	hlim, CTLFLAG_RW,		&ip6_defhlim,	0, "");
508345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGPACKETS,
509345153Sdim	maxfragpackets, CTLFLAG_RW,	&ip6_maxfragpackets,	0, "");
510345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_ACCEPT_RTADV,
511345153Sdim	accept_rtadv, CTLFLAG_RW,	&ip6_accept_rtadv,	0, "");
512345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_KEEPFAITH,
513345153Sdim	keepfaith, CTLFLAG_RW,		&ip6_keepfaith,	0, "");
514345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_LOG_INTERVAL,
515345153Sdim	log_interval, CTLFLAG_RW,	&ip6_log_interval,	0, "");
516345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_HDRNESTLIMIT,
517345153Sdim	hdrnestlimit, CTLFLAG_RW,	&ip6_hdrnestlimit,	0, "");
518345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_DAD_COUNT,
519345153Sdim	dad_count, CTLFLAG_RW,	&ip6_dad_count,	0, "");
520345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_AUTO_FLOWLABEL,
521345153Sdim	auto_flowlabel, CTLFLAG_RW,	&ip6_auto_flowlabel,	0, "");
522345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFMCASTHLIM,
523345153Sdim	defmcasthlim, CTLFLAG_RW,	&ip6_defmcasthlim,	0, "");
524345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM,
525345153Sdim	gifhlim, CTLFLAG_RW,	&ip6_gif_hlim,			0, "");
526345153SdimSYSCTL_STRING(_net_inet6_ip6, IPV6CTL_KAME_VERSION,
527345153Sdim	kame_version, CTLFLAG_RD,	__KAME_VERSION,		0, "");
528345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_USE_DEPRECATED,
529345153Sdim	use_deprecated, CTLFLAG_RW,	&ip6_use_deprecated,	0, "");
530345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_RR_PRUNE,
531345153Sdim	rr_prune, CTLFLAG_RW,	&ip6_rr_prune,			0, "");
532345153SdimSYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAPPED_ADDR,
533345153Sdim	mapped_addr, CTLFLAG_RW,	&ip6_mapped_addr_on,	0, "");
534345153Sdim
535345153Sdim/* net.inet6.icmp6 */
536345153SdimSYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRACCEPT,
537345153Sdim	rediraccept, CTLFLAG_RW,	&icmp6_rediraccept,	0, "");
538345153SdimSYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRTIMEOUT,
539345153Sdim	redirtimeout, CTLFLAG_RW,	&icmp6_redirtimeout,	0, "");
540345153SdimSYSCTL_STRUCT(_net_inet6_icmp6, ICMPV6CTL_STATS, stats, CTLFLAG_RD,
541345153Sdim	&icmp6stat, icmp6stat, "");
542345153SdimSYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ERRRATELIMIT,
543345153Sdim	errratelimit, CTLTYPE_INT|CTLFLAG_RW,
544345153Sdim	0, sizeof(int), sysctl_icmp6_ratelimit, "I", "");
545345153SdimSYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_PRUNE,
546345153Sdim	nd6_prune, CTLFLAG_RW,		&nd6_prune,	0, "");
547345153SdimSYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_DELAY,
548345153Sdim	nd6_delay, CTLFLAG_RW,		&nd6_delay,	0, "");
549345153SdimSYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_UMAXTRIES,
550345153Sdim	nd6_umaxtries, CTLFLAG_RW,	&nd6_umaxtries,	0, "");
551345153SdimSYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MMAXTRIES,
552345153Sdim	nd6_mmaxtries, CTLFLAG_RW,	&nd6_mmaxtries,	0, "");
553345153SdimSYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_USELOOPBACK,
554345153Sdim	nd6_useloopback, CTLFLAG_RW,	&nd6_useloopback, 0, "");
555345153SdimSYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_NODEINFO,
556345153Sdim	nodeinfo, CTLFLAG_RW,	&icmp6_nodeinfo,	0, "");
557345153SdimSYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ERRPPSLIMIT,
558345153Sdim	errppslimit, CTLFLAG_RW,	&icmp6errppslim,	0, "");
559345153SdimSYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXNUDHINT,
560345153Sdim	nd6_maxnudhint, CTLFLAG_RW,	&nd6_maxnudhint, 0, "");
561345153Sdim