xref: /netbsd-src/sys/netinet6/ip6_input.c (revision df0caa2637da0538ecdf6b878c4d08e684b43d8f)
1 /*	$NetBSD: ip6_input.c,v 1.78 2005/05/29 21:43:51 christos Exp $	*/
2 /*	$KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $	*/
3 
4 /*
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1982, 1986, 1988, 1993
35  *	The Regents of the University of California.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. Neither the name of the University nor the names of its contributors
46  *    may be used to endorse or promote products derived from this software
47  *    without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  *
61  *	@(#)ip_input.c	8.2 (Berkeley) 1/4/94
62  */
63 
64 #include <sys/cdefs.h>
65 __KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.78 2005/05/29 21:43:51 christos Exp $");
66 
67 #include "opt_inet.h"
68 #include "opt_ipsec.h"
69 #include "opt_pfil_hooks.h"
70 
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/malloc.h>
74 #include <sys/mbuf.h>
75 #include <sys/domain.h>
76 #include <sys/protosw.h>
77 #include <sys/socket.h>
78 #include <sys/socketvar.h>
79 #include <sys/errno.h>
80 #include <sys/time.h>
81 #include <sys/kernel.h>
82 #include <sys/syslog.h>
83 #include <sys/proc.h>
84 #include <sys/sysctl.h>
85 
86 #include <net/if.h>
87 #include <net/if_types.h>
88 #include <net/if_dl.h>
89 #include <net/route.h>
90 #include <net/netisr.h>
91 #ifdef PFIL_HOOKS
92 #include <net/pfil.h>
93 #endif
94 
95 #include <netinet/in.h>
96 #include <netinet/in_systm.h>
97 #ifdef INET
98 #include <netinet/ip.h>
99 #include <netinet/ip_icmp.h>
100 #endif /* INET */
101 #include <netinet/ip6.h>
102 #include <netinet6/in6_var.h>
103 #include <netinet6/ip6_var.h>
104 #include <netinet6/in6_pcb.h>
105 #include <netinet/icmp6.h>
106 #include <netinet6/in6_ifattach.h>
107 #include <netinet6/nd6.h>
108 
109 #ifdef IPSEC
110 #include <netinet6/ipsec.h>
111 #endif
112 
113 #include <netinet6/ip6protosw.h>
114 
115 #include "faith.h"
116 #include "gif.h"
117 
118 #if NGIF > 0
119 #include <netinet6/in6_gif.h>
120 #endif
121 
122 #include <net/net_osdep.h>
123 
124 extern struct domain inet6domain;
125 
126 u_char ip6_protox[IPPROTO_MAX];
127 static int ip6qmaxlen = IFQ_MAXLEN;
128 struct in6_ifaddr *in6_ifaddr;
129 struct ifqueue ip6intrq;
130 
131 int ip6_forward_srcrt;			/* XXX */
132 int ip6_sourcecheck;			/* XXX */
133 int ip6_sourcecheck_interval;		/* XXX */
134 
135 #ifdef PFIL_HOOKS
136 struct pfil_head inet6_pfil_hook;
137 #endif
138 
139 struct ip6stat ip6stat;
140 
141 static void ip6_init2 __P((void *));
142 
143 static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *));
144 static struct mbuf *ip6_pullexthdr __P((struct mbuf *, size_t, int));
145 
146 /*
147  * IP6 initialization: fill in IP6 protocol switch table.
148  * All protocols not implemented in kernel go to raw IP6 protocol handler.
149  */
150 void
151 ip6_init()
152 {
153 	const struct ip6protosw *pr;
154 	int i;
155 
156 	pr = (const struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
157 	if (pr == 0)
158 		panic("ip6_init");
159 	for (i = 0; i < IPPROTO_MAX; i++)
160 		ip6_protox[i] = pr - inet6sw;
161 	for (pr = (const struct ip6protosw *)inet6domain.dom_protosw;
162 	    pr < (const struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++)
163 		if (pr->pr_domain->dom_family == PF_INET6 &&
164 		    pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
165 			ip6_protox[pr->pr_protocol] = pr - inet6sw;
166 	ip6intrq.ifq_maxlen = ip6qmaxlen;
167 	nd6_init();
168 	frag6_init();
169 
170 	ip6_init2((void *)0);
171 
172 #ifdef PFIL_HOOKS
173 	/* Register our Packet Filter hook. */
174 	inet6_pfil_hook.ph_type = PFIL_TYPE_AF;
175 	inet6_pfil_hook.ph_af   = AF_INET6;
176 	i = pfil_head_register(&inet6_pfil_hook);
177 	if (i != 0)
178 		printf("ip6_init: WARNING: unable to register pfil hook, "
179 		    "error %d\n", i);
180 #endif /* PFIL_HOOKS */
181 }
182 
183 static void
184 ip6_init2(dummy)
185 	void *dummy;
186 {
187 
188 	/* nd6_timer_init */
189 	callout_init(&nd6_timer_ch);
190 	callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL);
191 }
192 
193 /*
194  * IP6 input interrupt handling. Just pass the packet to ip6_input.
195  */
196 void
197 ip6intr()
198 {
199 	int s;
200 	struct mbuf *m;
201 
202 	for (;;) {
203 		s = splnet();
204 		IF_DEQUEUE(&ip6intrq, m);
205 		splx(s);
206 		if (m == 0)
207 			return;
208 		ip6_input(m);
209 	}
210 }
211 
212 extern struct	route_in6 ip6_forward_rt;
213 
214 void
215 ip6_input(m)
216 	struct mbuf *m;
217 {
218 	struct ip6_hdr *ip6;
219 	int off = sizeof(struct ip6_hdr), nest;
220 	u_int32_t plen;
221 	u_int32_t rtalert = ~0;
222 	int nxt, ours = 0;
223 	struct ifnet *deliverifp = NULL;
224 	int srcrt = 0;
225 
226 #ifdef IPSEC
227 	/*
228 	 * should the inner packet be considered authentic?
229 	 * see comment in ah4_input().
230 	 */
231 	m->m_flags &= ~M_AUTHIPHDR;
232 	m->m_flags &= ~M_AUTHIPDGM;
233 #endif
234 
235 	/*
236 	 * mbuf statistics
237 	 */
238 	if (m->m_flags & M_EXT) {
239 		if (m->m_next)
240 			ip6stat.ip6s_mext2m++;
241 		else
242 			ip6stat.ip6s_mext1++;
243 	} else {
244 #define M2MMAX	(sizeof(ip6stat.ip6s_m2m)/sizeof(ip6stat.ip6s_m2m[0]))
245 		if (m->m_next) {
246 			if (m->m_flags & M_LOOP) {
247 				ip6stat.ip6s_m2m[lo0ifp->if_index]++; /* XXX */
248 			} else if (m->m_pkthdr.rcvif->if_index < M2MMAX)
249 				ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++;
250 			else
251 				ip6stat.ip6s_m2m[0]++;
252 		} else
253 			ip6stat.ip6s_m1++;
254 #undef M2MMAX
255 	}
256 
257 	in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive);
258 	ip6stat.ip6s_total++;
259 
260 	/*
261 	 * If the IPv6 header is not aligned, slurp it up into a new
262 	 * mbuf with space for link headers, in the event we forward
263 	 * it.  OTherwise, if it is aligned, make sure the entire base
264 	 * IPv6 header is in the first mbuf of the chain.
265 	 */
266 	if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
267 		struct ifnet *inifp = m->m_pkthdr.rcvif;
268 		if ((m = m_copyup(m, sizeof(struct ip6_hdr),
269 				  (max_linkhdr + 3) & ~3)) == NULL) {
270 			/* XXXJRT new stat, please */
271 			ip6stat.ip6s_toosmall++;
272 			in6_ifstat_inc(inifp, ifs6_in_hdrerr);
273 			return;
274 		}
275 	} else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
276 		struct ifnet *inifp = m->m_pkthdr.rcvif;
277 		if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
278 			ip6stat.ip6s_toosmall++;
279 			in6_ifstat_inc(inifp, ifs6_in_hdrerr);
280 			return;
281 		}
282 	}
283 
284 	ip6 = mtod(m, struct ip6_hdr *);
285 
286 	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
287 		ip6stat.ip6s_badvers++;
288 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
289 		goto bad;
290 	}
291 
292 #ifdef PFIL_HOOKS
293 	/*
294 	 * Run through list of hooks for input packets.  If there are any
295 	 * filters which require that additional packets in the flow are
296 	 * not fast-forwarded, they must clear the M_CANFASTFWD flag.
297 	 * Note that filters must _never_ set this flag, as another filter
298 	 * in the list may have previously cleared it.
299 	 */
300 	/*
301 	 * let ipfilter look at packet on the wire,
302 	 * not the decapsulated packet.
303 	 */
304 #ifdef IPSEC
305 	if (!ipsec_getnhist(m))
306 #else
307 	if (1)
308 #endif
309 	{
310 		struct in6_addr odst;
311 
312 		odst = ip6->ip6_dst;
313 		if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif,
314 				   PFIL_IN) != 0)
315 			return;
316 		if (m == NULL)
317 			return;
318 		ip6 = mtod(m, struct ip6_hdr *);
319 		srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);
320 	}
321 #endif /* PFIL_HOOKS */
322 
323 	ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
324 
325 #ifdef ALTQ
326 	if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) {
327 		/* packet is dropped by traffic conditioner */
328 		return;
329 	}
330 #endif
331 
332 	/*
333 	 * Check against address spoofing/corruption.
334 	 */
335 	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||
336 	    IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {
337 		/*
338 		 * XXX: "badscope" is not very suitable for a multicast source.
339 		 */
340 		ip6stat.ip6s_badscope++;
341 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
342 		goto bad;
343 	}
344 	/*
345 	 * The following check is not documented in specs.  A malicious
346 	 * party may be able to use IPv4 mapped addr to confuse tcp/udp stack
347 	 * and bypass security checks (act as if it was from 127.0.0.1 by using
348 	 * IPv6 src ::ffff:127.0.0.1).  Be cautious.
349 	 *
350 	 * This check chokes if we are in an SIIT cloud.  As none of BSDs
351 	 * support IPv4-less kernel compilation, we cannot support SIIT
352 	 * environment at all.  So, it makes more sense for us to reject any
353 	 * malicious packets for non-SIIT environment, than try to do a
354 	 * partial support for SIIT environment.
355 	 */
356 	if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
357 	    IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
358 		ip6stat.ip6s_badscope++;
359 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
360 		goto bad;
361 	}
362 #if 0
363 	/*
364 	 * Reject packets with IPv4 compatible addresses (auto tunnel).
365 	 *
366 	 * The code forbids auto tunnel relay case in RFC1933 (the check is
367 	 * stronger than RFC1933).  We may want to re-enable it if mech-xx
368 	 * is revised to forbid relaying case.
369 	 */
370 	if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) ||
371 	    IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {
372 		ip6stat.ip6s_badscope++;
373 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
374 		goto bad;
375 	}
376 #endif
377 
378 	if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
379 	    IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) {
380 		if (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) {
381 			ours = 1;
382 			deliverifp = m->m_pkthdr.rcvif;
383 			goto hbhcheck;
384 		} else {
385 			ip6stat.ip6s_badscope++;
386 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
387 			goto bad;
388 		}
389 	}
390 
391 	/* drop packets if interface ID portion is already filled */
392 	if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
393 		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src) &&
394 		    ip6->ip6_src.s6_addr16[1]) {
395 			ip6stat.ip6s_badscope++;
396 			goto bad;
397 		}
398 		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst) &&
399 		    ip6->ip6_dst.s6_addr16[1]) {
400 			ip6stat.ip6s_badscope++;
401 			goto bad;
402 		}
403 	}
404 
405 	if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
406 		ip6->ip6_src.s6_addr16[1]
407 			= htons(m->m_pkthdr.rcvif->if_index);
408 	if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
409 		ip6->ip6_dst.s6_addr16[1]
410 			= htons(m->m_pkthdr.rcvif->if_index);
411 
412 	/*
413 	 * We use rt->rt_ifp to determine if the address is ours or not.
414 	 * If rt_ifp is lo0, the address is ours.
415 	 * The problem here is, rt->rt_ifp for fe80::%lo0/64 is set to lo0,
416 	 * so any address under fe80::%lo0/64 will be mistakenly considered
417 	 * local.  The special case is supplied to handle the case properly
418 	 * by actually looking at interface addresses
419 	 * (using in6ifa_ifpwithaddr).
420 	 */
421 	if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) != 0 &&
422 	    IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst)) {
423 		if (!in6ifa_ifpwithaddr(m->m_pkthdr.rcvif, &ip6->ip6_dst)) {
424 			icmp6_error(m, ICMP6_DST_UNREACH,
425 			    ICMP6_DST_UNREACH_ADDR, 0);
426 			/* m is already freed */
427 			return;
428 		}
429 
430 		ours = 1;
431 		deliverifp = m->m_pkthdr.rcvif;
432 		goto hbhcheck;
433 	}
434 
435 	/*
436 	 * Multicast check
437 	 */
438 	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
439 	  	struct	in6_multi *in6m = 0;
440 
441 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast);
442 		/*
443 		 * See if we belong to the destination multicast group on the
444 		 * arrival interface.
445 		 */
446 		IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m);
447 		if (in6m)
448 			ours = 1;
449 		else if (!ip6_mrouter) {
450 			ip6stat.ip6s_notmember++;
451 			ip6stat.ip6s_cantforward++;
452 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
453 			goto bad;
454 		}
455 		deliverifp = m->m_pkthdr.rcvif;
456 		goto hbhcheck;
457 	}
458 
459 	/*
460 	 *  Unicast check
461 	 */
462 	if (ip6_forward_rt.ro_rt != NULL &&
463 	    (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) != 0 &&
464 	    IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
465 	    &((struct sockaddr_in6 *)(&ip6_forward_rt.ro_dst))->sin6_addr))
466 		ip6stat.ip6s_forward_cachehit++;
467 	else {
468 		struct sockaddr_in6 *dst6;
469 
470 		if (ip6_forward_rt.ro_rt) {
471 			/* route is down or destination is different */
472 			ip6stat.ip6s_forward_cachemiss++;
473 			RTFREE(ip6_forward_rt.ro_rt);
474 			ip6_forward_rt.ro_rt = 0;
475 		}
476 
477 		bzero(&ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6));
478 		dst6 = (struct sockaddr_in6 *)&ip6_forward_rt.ro_dst;
479 		dst6->sin6_len = sizeof(struct sockaddr_in6);
480 		dst6->sin6_family = AF_INET6;
481 		dst6->sin6_addr = ip6->ip6_dst;
482 
483 		rtalloc((struct route *)&ip6_forward_rt);
484 	}
485 
486 #define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key))
487 
488 	/*
489 	 * Accept the packet if the forwarding interface to the destination
490 	 * according to the routing table is the loopback interface,
491 	 * unless the associated route has a gateway.
492 	 * Note that this approach causes to accept a packet if there is a
493 	 * route to the loopback interface for the destination of the packet.
494 	 * But we think it's even useful in some situations, e.g. when using
495 	 * a special daemon which wants to intercept the packet.
496 	 */
497 	if (ip6_forward_rt.ro_rt &&
498 	    (ip6_forward_rt.ro_rt->rt_flags &
499 	     (RTF_HOST|RTF_GATEWAY)) == RTF_HOST &&
500 	    !(ip6_forward_rt.ro_rt->rt_flags & RTF_CLONED) &&
501 #if 0
502 	    /*
503 	     * The check below is redundant since the comparison of
504 	     * the destination and the key of the rtentry has
505 	     * already done through looking up the routing table.
506 	     */
507 	    IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
508 	    &rt6_key(ip6_forward_rt.ro_rt)->sin6_addr) &&
509 #endif
510 	    ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) {
511 		struct in6_ifaddr *ia6 =
512 			(struct in6_ifaddr *)ip6_forward_rt.ro_rt->rt_ifa;
513 		if (ia6->ia6_flags & IN6_IFF_ANYCAST)
514 			m->m_flags |= M_ANYCAST6;
515 		/*
516 		 * packets to a tentative, duplicated, or somehow invalid
517 		 * address must not be accepted.
518 		 */
519 		if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) {
520 			/* this address is ready */
521 			ours = 1;
522 			deliverifp = ia6->ia_ifp;	/* correct? */
523 			goto hbhcheck;
524 		} else {
525 			/* address is not ready, so discard the packet. */
526 			nd6log((LOG_INFO,
527 			    "ip6_input: packet to an unready address %s->%s\n",
528 			    ip6_sprintf(&ip6->ip6_src),
529 			    ip6_sprintf(&ip6->ip6_dst)));
530 
531 			goto bad;
532 		}
533 	}
534 
535 	/*
536 	 * FAITH (Firewall Aided Internet Translator)
537 	 */
538 #if defined(NFAITH) && 0 < NFAITH
539 	if (ip6_keepfaith) {
540 		if (ip6_forward_rt.ro_rt && ip6_forward_rt.ro_rt->rt_ifp &&
541 		    ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_FAITH) {
542 			/* XXX do we need more sanity checks? */
543 			ours = 1;
544 			deliverifp = ip6_forward_rt.ro_rt->rt_ifp; /* faith */
545 			goto hbhcheck;
546 		}
547 	}
548 #endif
549 
550 #if 0
551     {
552 	/*
553 	 * Last resort: check in6_ifaddr for incoming interface.
554 	 * The code is here until I update the "goto ours hack" code above
555 	 * working right.
556 	 */
557 	struct ifaddr *ifa;
558 	for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first;
559 	     ifa;
560 	     ifa = ifa->ifa_list.tqe_next) {
561 		if (ifa->ifa_addr == NULL)
562 			continue;	/* just for safety */
563 		if (ifa->ifa_addr->sa_family != AF_INET6)
564 			continue;
565 		if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ip6->ip6_dst)) {
566 			ours = 1;
567 			deliverifp = ifa->ifa_ifp;
568 			goto hbhcheck;
569 		}
570 	}
571     }
572 #endif
573 
574 	/*
575 	 * Now there is no reason to process the packet if it's not our own
576 	 * and we're not a router.
577 	 */
578 	if (!ip6_forwarding) {
579 		ip6stat.ip6s_cantforward++;
580 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
581 		goto bad;
582 	}
583 
584   hbhcheck:
585 	/*
586 	 * Process Hop-by-Hop options header if it's contained.
587 	 * m may be modified in ip6_hopopts_input().
588 	 * If a JumboPayload option is included, plen will also be modified.
589 	 */
590 	plen = (u_int32_t)ntohs(ip6->ip6_plen);
591 	if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
592 		struct ip6_hbh *hbh;
593 
594 		if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) {
595 #if 0	/*touches NULL pointer*/
596 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
597 #endif
598 			return;	/* m have already been freed */
599 		}
600 
601 		/* adjust pointer */
602 		ip6 = mtod(m, struct ip6_hdr *);
603 
604 		/*
605 		 * if the payload length field is 0 and the next header field
606 		 * indicates Hop-by-Hop Options header, then a Jumbo Payload
607 		 * option MUST be included.
608 		 */
609 		if (ip6->ip6_plen == 0 && plen == 0) {
610 			/*
611 			 * Note that if a valid jumbo payload option is
612 			 * contained, ip6_hoptops_input() must set a valid
613 			 * (non-zero) payload length to the variable plen.
614 			 */
615 			ip6stat.ip6s_badoptions++;
616 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
617 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
618 			icmp6_error(m, ICMP6_PARAM_PROB,
619 				    ICMP6_PARAMPROB_HEADER,
620 				    (caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
621 			return;
622 		}
623 		IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
624 			sizeof(struct ip6_hbh));
625 		if (hbh == NULL) {
626 			ip6stat.ip6s_tooshort++;
627 			return;
628 		}
629 		KASSERT(IP6_HDR_ALIGNED_P(hbh));
630 		nxt = hbh->ip6h_nxt;
631 
632 		/*
633 		 * accept the packet if a router alert option is included
634 		 * and we act as an IPv6 router.
635 		 */
636 		if (rtalert != ~0 && ip6_forwarding)
637 			ours = 1;
638 	} else
639 		nxt = ip6->ip6_nxt;
640 
641 	/*
642 	 * Check that the amount of data in the buffers
643 	 * is as at least much as the IPv6 header would have us expect.
644 	 * Trim mbufs if longer than we expect.
645 	 * Drop packet if shorter than we expect.
646 	 */
647 	if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
648 		ip6stat.ip6s_tooshort++;
649 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
650 		goto bad;
651 	}
652 	if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
653 		if (m->m_len == m->m_pkthdr.len) {
654 			m->m_len = sizeof(struct ip6_hdr) + plen;
655 			m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen;
656 		} else
657 			m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len);
658 	}
659 
660 	/*
661 	 * Forward if desirable.
662 	 */
663 	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
664 		/*
665 		 * If we are acting as a multicast router, all
666 		 * incoming multicast packets are passed to the
667 		 * kernel-level multicast forwarding function.
668 		 * The packet is returned (relatively) intact; if
669 		 * ip6_mforward() returns a non-zero value, the packet
670 		 * must be discarded, else it may be accepted below.
671 		 */
672 		if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) {
673 			ip6stat.ip6s_cantforward++;
674 			m_freem(m);
675 			return;
676 		}
677 		if (!ours) {
678 			m_freem(m);
679 			return;
680 		}
681 	} else if (!ours) {
682 		ip6_forward(m, srcrt);
683 		return;
684 	}
685 
686 	ip6 = mtod(m, struct ip6_hdr *);
687 
688 	/*
689 	 * Malicious party may be able to use IPv4 mapped addr to confuse
690 	 * tcp/udp stack and bypass security checks (act as if it was from
691 	 * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1).  Be cautious.
692 	 *
693 	 * For SIIT end node behavior, you may want to disable the check.
694 	 * However, you will  become vulnerable to attacks using IPv4 mapped
695 	 * source.
696 	 */
697 	if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
698 	    IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
699 		ip6stat.ip6s_badscope++;
700 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
701 		goto bad;
702 	}
703 
704 	/*
705 	 * Tell launch routine the next header
706 	 */
707 #ifdef IFA_STATS
708 	if (deliverifp != NULL) {
709 		struct in6_ifaddr *ia6;
710 		ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
711 		if (ia6)
712 			ia6->ia_ifa.ifa_data.ifad_inbytes += m->m_pkthdr.len;
713 	}
714 #endif
715 	ip6stat.ip6s_delivered++;
716 	in6_ifstat_inc(deliverifp, ifs6_in_deliver);
717 	nest = 0;
718 
719 	while (nxt != IPPROTO_DONE) {
720 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
721 			ip6stat.ip6s_toomanyhdr++;
722 			goto bad;
723 		}
724 
725 		/*
726 		 * protection against faulty packet - there should be
727 		 * more sanity checks in header chain processing.
728 		 */
729 		if (m->m_pkthdr.len < off) {
730 			ip6stat.ip6s_tooshort++;
731 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
732 			goto bad;
733 		}
734 
735 #ifdef IPSEC
736 		/*
737 		 * enforce IPsec policy checking if we are seeing last header.
738 		 * note that we do not visit this with protocols with pcb layer
739 		 * code - like udp/tcp/raw ip.
740 		 */
741 		if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
742 		    ipsec6_in_reject(m, NULL)) {
743 			ipsec6stat.in_polvio++;
744 			goto bad;
745 		}
746 #endif
747 
748 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
749 	}
750 	return;
751  bad:
752 	m_freem(m);
753 }
754 
755 /*
756  * Hop-by-Hop options header processing. If a valid jumbo payload option is
757  * included, the real payload length will be stored in plenp.
758  */
759 static int
760 ip6_hopopts_input(plenp, rtalertp, mp, offp)
761 	u_int32_t *plenp;
762 	u_int32_t *rtalertp;	/* XXX: should be stored more smart way */
763 	struct mbuf **mp;
764 	int *offp;
765 {
766 	struct mbuf *m = *mp;
767 	int off = *offp, hbhlen;
768 	struct ip6_hbh *hbh;
769 
770 	/* validation of the length of the header */
771 	IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m,
772 		sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
773 	if (hbh == NULL) {
774 		ip6stat.ip6s_tooshort++;
775 		return -1;
776 	}
777 	hbhlen = (hbh->ip6h_len + 1) << 3;
778 	IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
779 		hbhlen);
780 	if (hbh == NULL) {
781 		ip6stat.ip6s_tooshort++;
782 		return -1;
783 	}
784 	KASSERT(IP6_HDR_ALIGNED_P(hbh));
785 	off += hbhlen;
786 	hbhlen -= sizeof(struct ip6_hbh);
787 
788 	if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
789 				hbhlen, rtalertp, plenp) < 0)
790 		return (-1);
791 
792 	*offp = off;
793 	*mp = m;
794 	return (0);
795 }
796 
797 /*
798  * Search header for all Hop-by-hop options and process each option.
799  * This function is separate from ip6_hopopts_input() in order to
800  * handle a case where the sending node itself process its hop-by-hop
801  * options header. In such a case, the function is called from ip6_output().
802  *
803  * The function assumes that hbh header is located right after the IPv6 header
804  * (RFC2460 p7), opthead is pointer into data content in m, and opthead to
805  * opthead + hbhlen is located in continuous memory region.
806  */
807 int
808 ip6_process_hopopts(m, opthead, hbhlen, rtalertp, plenp)
809 	struct mbuf *m;
810 	u_int8_t *opthead;
811 	int hbhlen;
812 	u_int32_t *rtalertp;
813 	u_int32_t *plenp;
814 {
815 	struct ip6_hdr *ip6;
816 	int optlen = 0;
817 	u_int8_t *opt = opthead;
818 	u_int16_t rtalert_val;
819 	u_int32_t jumboplen;
820 	const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh);
821 
822 	for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) {
823 		switch (*opt) {
824 		case IP6OPT_PAD1:
825 			optlen = 1;
826 			break;
827 		case IP6OPT_PADN:
828 			if (hbhlen < IP6OPT_MINLEN) {
829 				ip6stat.ip6s_toosmall++;
830 				goto bad;
831 			}
832 			optlen = *(opt + 1) + 2;
833 			break;
834 		case IP6OPT_RTALERT:
835 			/* XXX may need check for alignment */
836 			if (hbhlen < IP6OPT_RTALERT_LEN) {
837 				ip6stat.ip6s_toosmall++;
838 				goto bad;
839 			}
840 			if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) {
841 				/* XXX stat */
842 				icmp6_error(m, ICMP6_PARAM_PROB,
843 				    ICMP6_PARAMPROB_HEADER,
844 				    erroff + opt + 1 - opthead);
845 				return (-1);
846 			}
847 			optlen = IP6OPT_RTALERT_LEN;
848 			bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2);
849 			*rtalertp = ntohs(rtalert_val);
850 			break;
851 		case IP6OPT_JUMBO:
852 			/* XXX may need check for alignment */
853 			if (hbhlen < IP6OPT_JUMBO_LEN) {
854 				ip6stat.ip6s_toosmall++;
855 				goto bad;
856 			}
857 			if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) {
858 				/* XXX stat */
859 				icmp6_error(m, ICMP6_PARAM_PROB,
860 				    ICMP6_PARAMPROB_HEADER,
861 				    erroff + opt + 1 - opthead);
862 				return (-1);
863 			}
864 			optlen = IP6OPT_JUMBO_LEN;
865 
866 			/*
867 			 * IPv6 packets that have non 0 payload length
868 			 * must not contain a jumbo payload option.
869 			 */
870 			ip6 = mtod(m, struct ip6_hdr *);
871 			if (ip6->ip6_plen) {
872 				ip6stat.ip6s_badoptions++;
873 				icmp6_error(m, ICMP6_PARAM_PROB,
874 				    ICMP6_PARAMPROB_HEADER,
875 				    erroff + opt - opthead);
876 				return (-1);
877 			}
878 
879 			/*
880 			 * We may see jumbolen in unaligned location, so
881 			 * we'd need to perform bcopy().
882 			 */
883 			bcopy(opt + 2, &jumboplen, sizeof(jumboplen));
884 			jumboplen = (u_int32_t)htonl(jumboplen);
885 
886 #if 1
887 			/*
888 			 * if there are multiple jumbo payload options,
889 			 * *plenp will be non-zero and the packet will be
890 			 * rejected.
891 			 * the behavior may need some debate in ipngwg -
892 			 * multiple options does not make sense, however,
893 			 * there's no explicit mention in specification.
894 			 */
895 			if (*plenp != 0) {
896 				ip6stat.ip6s_badoptions++;
897 				icmp6_error(m, ICMP6_PARAM_PROB,
898 				    ICMP6_PARAMPROB_HEADER,
899 				    erroff + opt + 2 - opthead);
900 				return (-1);
901 			}
902 #endif
903 
904 			/*
905 			 * jumbo payload length must be larger than 65535.
906 			 */
907 			if (jumboplen <= IPV6_MAXPACKET) {
908 				ip6stat.ip6s_badoptions++;
909 				icmp6_error(m, ICMP6_PARAM_PROB,
910 				    ICMP6_PARAMPROB_HEADER,
911 				    erroff + opt + 2 - opthead);
912 				return (-1);
913 			}
914 			*plenp = jumboplen;
915 
916 			break;
917 		default:		/* unknown option */
918 			if (hbhlen < IP6OPT_MINLEN) {
919 				ip6stat.ip6s_toosmall++;
920 				goto bad;
921 			}
922 			optlen = ip6_unknown_opt(opt, m,
923 			    erroff + opt - opthead);
924 			if (optlen == -1)
925 				return (-1);
926 			optlen += 2;
927 			break;
928 		}
929 	}
930 
931 	return (0);
932 
933   bad:
934 	m_freem(m);
935 	return (-1);
936 }
937 
938 /*
939  * Unknown option processing.
940  * The third argument `off' is the offset from the IPv6 header to the option,
941  * which is necessary if the IPv6 header the and option header and IPv6 header
942  * is not continuous in order to return an ICMPv6 error.
943  */
944 int
945 ip6_unknown_opt(optp, m, off)
946 	u_int8_t *optp;
947 	struct mbuf *m;
948 	int off;
949 {
950 	struct ip6_hdr *ip6;
951 
952 	switch (IP6OPT_TYPE(*optp)) {
953 	case IP6OPT_TYPE_SKIP: /* ignore the option */
954 		return ((int)*(optp + 1));
955 	case IP6OPT_TYPE_DISCARD:	/* silently discard */
956 		m_freem(m);
957 		return (-1);
958 	case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */
959 		ip6stat.ip6s_badoptions++;
960 		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off);
961 		return (-1);
962 	case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */
963 		ip6stat.ip6s_badoptions++;
964 		ip6 = mtod(m, struct ip6_hdr *);
965 		if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
966 		    (m->m_flags & (M_BCAST|M_MCAST)))
967 			m_freem(m);
968 		else
969 			icmp6_error(m, ICMP6_PARAM_PROB,
970 				    ICMP6_PARAMPROB_OPTION, off);
971 		return (-1);
972 	}
973 
974 	m_freem(m);		/* XXX: NOTREACHED */
975 	return (-1);
976 }
977 
978 /*
979  * Create the "control" list for this pcb.
980  *
981  * The routine will be called from upper layer handlers like tcp6_input().
982  * Thus the routine assumes that the caller (tcp6_input) have already
983  * called IP6_EXTHDR_CHECK() and all the extension headers are located in the
984  * very first mbuf on the mbuf chain.
985  * We may want to add some infinite loop prevention or sanity checks for safety.
986  * (This applies only when you are using KAME mbuf chain restriction, i.e.
987  * you are using IP6_EXTHDR_CHECK() not m_pulldown())
988  */
989 void
990 ip6_savecontrol(in6p, mp, ip6, m)
991 	struct in6pcb *in6p;
992 	struct mbuf **mp;
993 	struct ip6_hdr *ip6;
994 	struct mbuf *m;
995 {
996 
997 #ifdef SO_TIMESTAMP
998 	if (in6p->in6p_socket->so_options & SO_TIMESTAMP) {
999 		struct timeval tv;
1000 
1001 		microtime(&tv);
1002 		*mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
1003 		    SCM_TIMESTAMP, SOL_SOCKET);
1004 		if (*mp)
1005 			mp = &(*mp)->m_next;
1006 	}
1007 #endif
1008 	if (in6p->in6p_flags & IN6P_RECVDSTADDR) {
1009 		*mp = sbcreatecontrol((caddr_t) &ip6->ip6_dst,
1010 		    sizeof(struct in6_addr), IPV6_RECVDSTADDR, IPPROTO_IPV6);
1011 		if (*mp)
1012 			mp = &(*mp)->m_next;
1013 	}
1014 
1015 #ifdef noyet
1016 	/* options were tossed above */
1017 	if (in6p->in6p_flags & IN6P_RECVOPTS)
1018 		/* broken */
1019 	/* ip6_srcroute doesn't do what we want here, need to fix */
1020 	if (in6p->in6p_flags & IPV6P_RECVRETOPTS)
1021 		/* broken */
1022 #endif
1023 
1024 	/* RFC 2292 sec. 5 */
1025 	if ((in6p->in6p_flags & IN6P_PKTINFO) != 0) {
1026 		struct in6_pktinfo pi6;
1027 		bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr));
1028 		if (IN6_IS_SCOPE_LINKLOCAL(&pi6.ipi6_addr))
1029 			pi6.ipi6_addr.s6_addr16[1] = 0;
1030 		pi6.ipi6_ifindex = (m && m->m_pkthdr.rcvif)
1031 					? m->m_pkthdr.rcvif->if_index
1032 					: 0;
1033 		*mp = sbcreatecontrol((caddr_t) &pi6,
1034 		    sizeof(struct in6_pktinfo), IPV6_PKTINFO, IPPROTO_IPV6);
1035 		if (*mp)
1036 			mp = &(*mp)->m_next;
1037 	}
1038 	if (in6p->in6p_flags & IN6P_HOPLIMIT) {
1039 		int hlim = ip6->ip6_hlim & 0xff;
1040 		*mp = sbcreatecontrol((caddr_t) &hlim, sizeof(int),
1041 		    IPV6_HOPLIMIT, IPPROTO_IPV6);
1042 		if (*mp)
1043 			mp = &(*mp)->m_next;
1044 	}
1045 	/* IN6P_NEXTHOP - for outgoing packet only */
1046 
1047 	/*
1048 	 * IPV6_HOPOPTS socket option.  Recall that we required super-user
1049 	 * privilege for the option (see ip6_ctloutput), but it might be too
1050 	 * strict, since there might be some hop-by-hop options which can be
1051 	 * returned to normal user.
1052 	 * See also RFC 2292 section 6.
1053 	 */
1054 	if ((in6p->in6p_flags & IN6P_HOPOPTS) != 0) {
1055 		/*
1056 		 * Check if a hop-by-hop options header is contatined in the
1057 		 * received packet, and if so, store the options as ancillary
1058 		 * data. Note that a hop-by-hop options header must be
1059 		 * just after the IPv6 header, which fact is assured through
1060 		 * the IPv6 input processing.
1061 		 */
1062 		struct ip6_hdr *xip6 = mtod(m, struct ip6_hdr *);
1063 		if (xip6->ip6_nxt == IPPROTO_HOPOPTS) {
1064 			struct ip6_hbh *hbh;
1065 			int hbhlen;
1066 			struct mbuf *ext;
1067 
1068 			ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr),
1069 			    xip6->ip6_nxt);
1070 			if (ext == NULL) {
1071 				ip6stat.ip6s_tooshort++;
1072 				return;
1073 			}
1074 			hbh = mtod(ext, struct ip6_hbh *);
1075 			hbhlen = (hbh->ip6h_len + 1) << 3;
1076 			if (hbhlen != ext->m_len) {
1077 				m_freem(ext);
1078 				ip6stat.ip6s_tooshort++;
1079 				return;
1080 			}
1081 
1082 			/*
1083 			 * XXX: We copy whole the header even if a jumbo
1084 			 * payload option is included, which option is to
1085 			 * be removed before returning in the RFC 2292.
1086 			 * But it's too painful operation...
1087 			 */
1088 			*mp = sbcreatecontrol((caddr_t)hbh, hbhlen,
1089 			    IPV6_HOPOPTS, IPPROTO_IPV6);
1090 			if (*mp)
1091 				mp = &(*mp)->m_next;
1092 			m_freem(ext);
1093 		}
1094 	}
1095 
1096 	/* IPV6_DSTOPTS and IPV6_RTHDR socket options */
1097 	if (in6p->in6p_flags & (IN6P_DSTOPTS | IN6P_RTHDR)) {
1098 		struct ip6_hdr *xip6 = mtod(m, struct ip6_hdr *);
1099 		int nxt = xip6->ip6_nxt, off = sizeof(struct ip6_hdr);
1100 
1101 		/*
1102 		 * Search for destination options headers or routing
1103 		 * header(s) through the header chain, and stores each
1104 		 * header as ancillary data.
1105 		 * Note that the order of the headers remains in
1106 		 * the chain of ancillary data.
1107 		 */
1108 		while (1) {	/* is explicit loop prevention necessary? */
1109 			struct ip6_ext *ip6e = NULL;
1110 			int elen;
1111 			struct mbuf *ext = NULL;
1112 
1113 			/*
1114 			 * if it is not an extension header, don't try to
1115 			 * pull it from the chain.
1116 			 */
1117 			switch (nxt) {
1118 			case IPPROTO_DSTOPTS:
1119 			case IPPROTO_ROUTING:
1120 			case IPPROTO_HOPOPTS:
1121 			case IPPROTO_AH: /* is it possible? */
1122 				break;
1123 			default:
1124 				goto loopend;
1125 			}
1126 
1127 			ext = ip6_pullexthdr(m, off, nxt);
1128 			if (ext == NULL) {
1129 				ip6stat.ip6s_tooshort++;
1130 				return;
1131 			}
1132 			ip6e = mtod(ext, struct ip6_ext *);
1133 			if (nxt == IPPROTO_AH)
1134 				elen = (ip6e->ip6e_len + 2) << 2;
1135 			else
1136 				elen = (ip6e->ip6e_len + 1) << 3;
1137 			if (elen != ext->m_len) {
1138 				m_freem(ext);
1139 				ip6stat.ip6s_tooshort++;
1140 				return;
1141 			}
1142 			KASSERT(IP6_HDR_ALIGNED_P(ip6e));
1143 
1144 			switch (nxt) {
1145 			case IPPROTO_DSTOPTS:
1146 				if (!in6p->in6p_flags & IN6P_DSTOPTS)
1147 					break;
1148 
1149 				*mp = sbcreatecontrol((caddr_t)ip6e, elen,
1150 				    IPV6_DSTOPTS, IPPROTO_IPV6);
1151 				if (*mp)
1152 					mp = &(*mp)->m_next;
1153 				break;
1154 
1155 			case IPPROTO_ROUTING:
1156 				if (!in6p->in6p_flags & IN6P_RTHDR)
1157 					break;
1158 
1159 				*mp = sbcreatecontrol((caddr_t)ip6e, elen,
1160 				    IPV6_RTHDR, IPPROTO_IPV6);
1161 				if (*mp)
1162 					mp = &(*mp)->m_next;
1163 				break;
1164 
1165 			case IPPROTO_HOPOPTS:
1166 			case IPPROTO_AH: /* is it possible? */
1167 				break;
1168 
1169 			default:
1170 				/*
1171 			 	 * other cases have been filtered in the above.
1172 				 * none will visit this case.  here we supply
1173 				 * the code just in case (nxt overwritten or
1174 				 * other cases).
1175 				 */
1176 				m_freem(ext);
1177 				goto loopend;
1178 
1179 			}
1180 
1181 			/* proceed with the next header. */
1182 			off += elen;
1183 			nxt = ip6e->ip6e_nxt;
1184 			ip6e = NULL;
1185 			m_freem(ext);
1186 			ext = NULL;
1187 		}
1188 	  loopend:
1189 	  	;
1190 	}
1191 }
1192 
1193 /*
1194  * pull single extension header from mbuf chain.  returns single mbuf that
1195  * contains the result, or NULL on error.
1196  */
1197 static struct mbuf *
1198 ip6_pullexthdr(m, off, nxt)
1199 	struct mbuf *m;
1200 	size_t off;
1201 	int nxt;
1202 {
1203 	struct ip6_ext ip6e;
1204 	size_t elen;
1205 	struct mbuf *n;
1206 
1207 #ifdef DIAGNOSTIC
1208 	switch (nxt) {
1209 	case IPPROTO_DSTOPTS:
1210 	case IPPROTO_ROUTING:
1211 	case IPPROTO_HOPOPTS:
1212 	case IPPROTO_AH: /* is it possible? */
1213 		break;
1214 	default:
1215 		printf("ip6_pullexthdr: invalid nxt=%d\n", nxt);
1216 	}
1217 #endif
1218 
1219 	m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1220 	if (nxt == IPPROTO_AH)
1221 		elen = (ip6e.ip6e_len + 2) << 2;
1222 	else
1223 		elen = (ip6e.ip6e_len + 1) << 3;
1224 
1225 	MGET(n, M_DONTWAIT, MT_DATA);
1226 	if (n && elen >= MLEN) {
1227 		MCLGET(n, M_DONTWAIT);
1228 		if ((n->m_flags & M_EXT) == 0) {
1229 			m_free(n);
1230 			n = NULL;
1231 		}
1232 	}
1233 	if (!n)
1234 		return NULL;
1235 
1236 	n->m_len = 0;
1237 	if (elen >= M_TRAILINGSPACE(n)) {
1238 		m_free(n);
1239 		return NULL;
1240 	}
1241 
1242 	m_copydata(m, off, elen, mtod(n, caddr_t));
1243 	n->m_len = elen;
1244 	return n;
1245 }
1246 
1247 /*
1248  * Get pointer to the previous header followed by the header
1249  * currently processed.
1250  * XXX: This function supposes that
1251  *	M includes all headers,
1252  *	the next header field and the header length field of each header
1253  *	are valid, and
1254  *	the sum of each header length equals to OFF.
1255  * Because of these assumptions, this function must be called very
1256  * carefully. Moreover, it will not be used in the near future when
1257  * we develop `neater' mechanism to process extension headers.
1258  */
1259 u_int8_t *
1260 ip6_get_prevhdr(m, off)
1261 	struct mbuf *m;
1262 	int off;
1263 {
1264 	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1265 
1266 	if (off == sizeof(struct ip6_hdr))
1267 		return (&ip6->ip6_nxt);
1268 	else {
1269 		int len, nxt;
1270 		struct ip6_ext *ip6e = NULL;
1271 
1272 		nxt = ip6->ip6_nxt;
1273 		len = sizeof(struct ip6_hdr);
1274 		while (len < off) {
1275 			ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + len);
1276 
1277 			switch (nxt) {
1278 			case IPPROTO_FRAGMENT:
1279 				len += sizeof(struct ip6_frag);
1280 				break;
1281 			case IPPROTO_AH:
1282 				len += (ip6e->ip6e_len + 2) << 2;
1283 				break;
1284 			default:
1285 				len += (ip6e->ip6e_len + 1) << 3;
1286 				break;
1287 			}
1288 			nxt = ip6e->ip6e_nxt;
1289 		}
1290 		if (ip6e)
1291 			return (&ip6e->ip6e_nxt);
1292 		else
1293 			return NULL;
1294 	}
1295 }
1296 
1297 /*
1298  * get next header offset.  m will be retained.
1299  */
1300 int
1301 ip6_nexthdr(m, off, proto, nxtp)
1302 	struct mbuf *m;
1303 	int off;
1304 	int proto;
1305 	int *nxtp;
1306 {
1307 	struct ip6_hdr ip6;
1308 	struct ip6_ext ip6e;
1309 	struct ip6_frag fh;
1310 
1311 	/* just in case */
1312 	if (m == NULL)
1313 		panic("ip6_nexthdr: m == NULL");
1314 	if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len < off)
1315 		return -1;
1316 
1317 	switch (proto) {
1318 	case IPPROTO_IPV6:
1319 		if (m->m_pkthdr.len < off + sizeof(ip6))
1320 			return -1;
1321 		m_copydata(m, off, sizeof(ip6), (caddr_t)&ip6);
1322 		if (nxtp)
1323 			*nxtp = ip6.ip6_nxt;
1324 		off += sizeof(ip6);
1325 		return off;
1326 
1327 	case IPPROTO_FRAGMENT:
1328 		/*
1329 		 * terminate parsing if it is not the first fragment,
1330 		 * it does not make sense to parse through it.
1331 		 */
1332 		if (m->m_pkthdr.len < off + sizeof(fh))
1333 			return -1;
1334 		m_copydata(m, off, sizeof(fh), (caddr_t)&fh);
1335 		if ((fh.ip6f_offlg & IP6F_OFF_MASK) != 0)
1336 			return -1;
1337 		if (nxtp)
1338 			*nxtp = fh.ip6f_nxt;
1339 		off += sizeof(struct ip6_frag);
1340 		return off;
1341 
1342 	case IPPROTO_AH:
1343 		if (m->m_pkthdr.len < off + sizeof(ip6e))
1344 			return -1;
1345 		m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1346 		if (nxtp)
1347 			*nxtp = ip6e.ip6e_nxt;
1348 		off += (ip6e.ip6e_len + 2) << 2;
1349 		if (m->m_pkthdr.len < off)
1350 			return -1;
1351 		return off;
1352 
1353 	case IPPROTO_HOPOPTS:
1354 	case IPPROTO_ROUTING:
1355 	case IPPROTO_DSTOPTS:
1356 		if (m->m_pkthdr.len < off + sizeof(ip6e))
1357 			return -1;
1358 		m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1359 		if (nxtp)
1360 			*nxtp = ip6e.ip6e_nxt;
1361 		off += (ip6e.ip6e_len + 1) << 3;
1362 		if (m->m_pkthdr.len < off)
1363 			return -1;
1364 		return off;
1365 
1366 	case IPPROTO_NONE:
1367 	case IPPROTO_ESP:
1368 	case IPPROTO_IPCOMP:
1369 		/* give up */
1370 		return -1;
1371 
1372 	default:
1373 		return -1;
1374 	}
1375 }
1376 
1377 /*
1378  * get offset for the last header in the chain.  m will be kept untainted.
1379  */
1380 int
1381 ip6_lasthdr(m, off, proto, nxtp)
1382 	struct mbuf *m;
1383 	int off;
1384 	int proto;
1385 	int *nxtp;
1386 {
1387 	int newoff;
1388 	int nxt;
1389 
1390 	if (!nxtp) {
1391 		nxt = -1;
1392 		nxtp = &nxt;
1393 	}
1394 	while (1) {
1395 		newoff = ip6_nexthdr(m, off, proto, nxtp);
1396 		if (newoff < 0)
1397 			return off;
1398 		else if (newoff < off)
1399 			return -1;	/* invalid */
1400 		else if (newoff == off)
1401 			return newoff;
1402 
1403 		off = newoff;
1404 		proto = *nxtp;
1405 	}
1406 }
1407 
1408 /*
1409  * System control for IP6
1410  */
1411 
1412 u_char	inet6ctlerrmap[PRC_NCMDS] = {
1413 	0,		0,		0,		0,
1414 	0,		EMSGSIZE,	EHOSTDOWN,	EHOSTUNREACH,
1415 	EHOSTUNREACH,	EHOSTUNREACH,	ECONNREFUSED,	ECONNREFUSED,
1416 	EMSGSIZE,	EHOSTUNREACH,	0,		0,
1417 	0,		0,		0,		0,
1418 	ENOPROTOOPT
1419 };
1420 
1421 SYSCTL_SETUP(sysctl_net_inet6_ip6_setup, "sysctl net.inet6.ip6 subtree setup")
1422 {
1423 
1424 	sysctl_createv(clog, 0, NULL, NULL,
1425 		       CTLFLAG_PERMANENT,
1426 		       CTLTYPE_NODE, "net", NULL,
1427 		       NULL, 0, NULL, 0,
1428 		       CTL_NET, CTL_EOL);
1429 	sysctl_createv(clog, 0, NULL, NULL,
1430 		       CTLFLAG_PERMANENT,
1431 		       CTLTYPE_NODE, "inet6",
1432 		       SYSCTL_DESCR("PF_INET6 related settings"),
1433 		       NULL, 0, NULL, 0,
1434 		       CTL_NET, PF_INET6, CTL_EOL);
1435 	sysctl_createv(clog, 0, NULL, NULL,
1436 		       CTLFLAG_PERMANENT,
1437 		       CTLTYPE_NODE, "ip6",
1438 		       SYSCTL_DESCR("IPv6 related settings"),
1439 		       NULL, 0, NULL, 0,
1440 		       CTL_NET, PF_INET6, IPPROTO_IPV6, CTL_EOL);
1441 
1442 	sysctl_createv(clog, 0, NULL, NULL,
1443 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1444 		       CTLTYPE_INT, "forwarding",
1445 		       SYSCTL_DESCR("Enable forwarding of INET6 datagrams"),
1446 		       NULL, 0, &ip6_forwarding, 0,
1447 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1448 		       IPV6CTL_FORWARDING, CTL_EOL);
1449 	sysctl_createv(clog, 0, NULL, NULL,
1450 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1451 		       CTLTYPE_INT, "redirect",
1452 		       SYSCTL_DESCR("Enable sending of ICMPv6 redirect messages"),
1453 		       NULL, 0, &ip6_sendredirects, 0,
1454 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1455 		       IPV6CTL_SENDREDIRECTS, CTL_EOL);
1456 	sysctl_createv(clog, 0, NULL, NULL,
1457 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1458 		       CTLTYPE_INT, "hlim",
1459 		       SYSCTL_DESCR("Hop limit for an INET6 datagram"),
1460 		       NULL, 0, &ip6_defhlim, 0,
1461 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1462 		       IPV6CTL_DEFHLIM, CTL_EOL);
1463 #ifdef notyet
1464 	sysctl_createv(clog, 0, NULL, NULL,
1465 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1466 		       CTLTYPE_INT, "mtu", NULL,
1467 		       NULL, 0, &, 0,
1468 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1469 		       IPV6CTL_DEFMTU, CTL_EOL);
1470 #endif
1471 #ifdef __no_idea__
1472 	sysctl_createv(clog, 0, NULL, NULL,
1473 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1474 		       CTLTYPE_INT, "forwsrcrt", NULL,
1475 		       NULL, 0, &?, 0,
1476 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1477 		       IPV6CTL_FORWSRCRT, CTL_EOL);
1478 	sysctl_createv(clog, 0, NULL, NULL,
1479 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1480 		       CTLTYPE_STRUCT, "stats", NULL,
1481 		       NULL, 0, &?, sizeof(?),
1482 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1483 		       IPV6CTL_STATS, CTL_EOL);
1484 	sysctl_createv(clog, 0, NULL, NULL,
1485 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1486 		       CTLTYPE_STRUCT, "mrtstats", NULL,
1487 		       NULL, 0, &?, sizeof(?),
1488 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1489 		       IPV6CTL_MRTSTATS, CTL_EOL);
1490 	sysctl_createv(clog, 0, NULL, NULL,
1491 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1492 		       CTLTYPE_?, "mrtproto", NULL,
1493 		       NULL, 0, &?, sizeof(?),
1494 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1495 		       IPV6CTL_MRTPROTO, CTL_EOL);
1496 #endif
1497 	sysctl_createv(clog, 0, NULL, NULL,
1498 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1499 		       CTLTYPE_INT, "maxfragpackets",
1500 		       SYSCTL_DESCR("Maximum number of fragments to buffer "
1501 				    "for reassembly"),
1502 		       NULL, 0, &ip6_maxfragpackets, 0,
1503 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1504 		       IPV6CTL_MAXFRAGPACKETS, CTL_EOL);
1505 #ifdef __no_idea__
1506 	sysctl_createv(clog, 0, NULL, NULL,
1507 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1508 		       CTLTYPE_INT, "sourcecheck", NULL,
1509 		       NULL, 0, &?, 0,
1510 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1511 		       IPV6CTL_SOURCECHECK, CTL_EOL);
1512 	sysctl_createv(clog, 0, NULL, NULL,
1513 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1514 		       CTLTYPE_INT, "sourcecheck_logint", NULL,
1515 		       NULL, 0, &?, 0,
1516 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1517 		       IPV6CTL_SOURCECHECK_LOGINT, CTL_EOL);
1518 #endif
1519 	sysctl_createv(clog, 0, NULL, NULL,
1520 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1521 		       CTLTYPE_INT, "accept_rtadv",
1522 		       SYSCTL_DESCR("Accept router advertisements"),
1523 		       NULL, 0, &ip6_accept_rtadv, 0,
1524 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1525 		       IPV6CTL_ACCEPT_RTADV, CTL_EOL);
1526 	sysctl_createv(clog, 0, NULL, NULL,
1527 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1528 		       CTLTYPE_INT, "keepfaith",
1529 		       SYSCTL_DESCR("Activate faith interface"),
1530 		       NULL, 0, &ip6_keepfaith, 0,
1531 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1532 		       IPV6CTL_KEEPFAITH, CTL_EOL);
1533 	sysctl_createv(clog, 0, NULL, NULL,
1534 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1535 		       CTLTYPE_INT, "log_interval",
1536 		       SYSCTL_DESCR("Minumum interval between logging "
1537 				    "unroutable packets"),
1538 		       NULL, 0, &ip6_log_interval, 0,
1539 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1540 		       IPV6CTL_LOG_INTERVAL, CTL_EOL);
1541 	sysctl_createv(clog, 0, NULL, NULL,
1542 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1543 		       CTLTYPE_INT, "hdrnestlimit",
1544 		       SYSCTL_DESCR("Maximum number of nested IPv6 headers"),
1545 		       NULL, 0, &ip6_hdrnestlimit, 0,
1546 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1547 		       IPV6CTL_HDRNESTLIMIT, CTL_EOL);
1548 	sysctl_createv(clog, 0, NULL, NULL,
1549 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1550 		       CTLTYPE_INT, "dad_count",
1551 		       SYSCTL_DESCR("Number of Duplicate Address Detection "
1552 				    "probes to send"),
1553 		       NULL, 0, &ip6_dad_count, 0,
1554 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1555 		       IPV6CTL_DAD_COUNT, CTL_EOL);
1556 	sysctl_createv(clog, 0, NULL, NULL,
1557 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1558 		       CTLTYPE_INT, "auto_flowlabel",
1559 		       SYSCTL_DESCR("Assign random IPv6 flow labels"),
1560 		       NULL, 0, &ip6_auto_flowlabel, 0,
1561 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1562 		       IPV6CTL_AUTO_FLOWLABEL, CTL_EOL);
1563 	sysctl_createv(clog, 0, NULL, NULL,
1564 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1565 		       CTLTYPE_INT, "defmcasthlim",
1566 		       SYSCTL_DESCR("Default multicast hop limit"),
1567 		       NULL, 0, &ip6_defmcasthlim, 0,
1568 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1569 		       IPV6CTL_DEFMCASTHLIM, CTL_EOL);
1570 #if NGIF > 0
1571 	sysctl_createv(clog, 0, NULL, NULL,
1572 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1573 		       CTLTYPE_INT, "gifhlim",
1574 		       SYSCTL_DESCR("Default hop limit for a gif tunnel datagram"),
1575 		       NULL, 0, &ip6_gif_hlim, 0,
1576 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1577 		       IPV6CTL_GIF_HLIM, CTL_EOL);
1578 #endif /* NGIF */
1579 	sysctl_createv(clog, 0, NULL, NULL,
1580 		       CTLFLAG_PERMANENT,
1581 		       CTLTYPE_STRING, "kame_version",
1582 		       SYSCTL_DESCR("KAME Version"),
1583 		       NULL, 0, __UNCONST(__KAME_VERSION), 0,
1584 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1585 		       IPV6CTL_KAME_VERSION, CTL_EOL);
1586 	sysctl_createv(clog, 0, NULL, NULL,
1587 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1588 		       CTLTYPE_INT, "use_deprecated",
1589 		       SYSCTL_DESCR("Allow use of deprecated addresses as "
1590 				    "source addresses"),
1591 		       NULL, 0, &ip6_use_deprecated, 0,
1592 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1593 		       IPV6CTL_USE_DEPRECATED, CTL_EOL);
1594 	sysctl_createv(clog, 0, NULL, NULL,
1595 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1596 		       CTLTYPE_INT, "rr_prune", NULL,
1597 		       NULL, 0, &ip6_rr_prune, 0,
1598 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1599 		       IPV6CTL_RR_PRUNE, CTL_EOL);
1600 	sysctl_createv(clog, 0, NULL, NULL,
1601 		       CTLFLAG_PERMANENT
1602 #ifndef INET6_BINDV6ONLY
1603 		       |CTLFLAG_READWRITE,
1604 #endif
1605 		       CTLTYPE_INT, "v6only",
1606 		       SYSCTL_DESCR("Disallow PF_INET6 sockets from connecting "
1607 				    "to PF_INET sockets"),
1608 		       NULL, 0, &ip6_v6only, 0,
1609 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1610 		       IPV6CTL_V6ONLY, CTL_EOL);
1611 	sysctl_createv(clog, 0, NULL, NULL,
1612 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1613 		       CTLTYPE_INT, "anonportmin",
1614 		       SYSCTL_DESCR("Lowest ephemeral port number to assign"),
1615 		       sysctl_net_inet_ip_ports, 0, &ip6_anonportmin, 0,
1616 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1617 		       IPV6CTL_ANONPORTMIN, CTL_EOL);
1618 	sysctl_createv(clog, 0, NULL, NULL,
1619 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1620 		       CTLTYPE_INT, "anonportmax",
1621 		       SYSCTL_DESCR("Highest ephemeral port number to assign"),
1622 		       sysctl_net_inet_ip_ports, 0, &ip6_anonportmax, 0,
1623 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1624 		       IPV6CTL_ANONPORTMAX, CTL_EOL);
1625 #ifndef IPNOPRIVPORTS
1626 	sysctl_createv(clog, 0, NULL, NULL,
1627 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1628 		       CTLTYPE_INT, "lowportmin",
1629 		       SYSCTL_DESCR("Lowest privileged ephemeral port number "
1630 				    "to assign"),
1631 		       sysctl_net_inet_ip_ports, 0, &ip6_lowportmin, 0,
1632 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1633 		       IPV6CTL_LOWPORTMIN, CTL_EOL);
1634 	sysctl_createv(clog, 0, NULL, NULL,
1635 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1636 		       CTLTYPE_INT, "lowportmax",
1637 		       SYSCTL_DESCR("Highest privileged ephemeral port number "
1638 				    "to assign"),
1639 		       sysctl_net_inet_ip_ports, 0, &ip6_lowportmax, 0,
1640 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1641 		       IPV6CTL_LOWPORTMAX, CTL_EOL);
1642 #endif /* IPNOPRIVPORTS */
1643 	sysctl_createv(clog, 0, NULL, NULL,
1644 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1645 		       CTLTYPE_INT, "maxfrags",
1646 		       SYSCTL_DESCR("Maximum fragments in reassembly queue"),
1647 		       NULL, 0, &ip6_maxfrags, 0,
1648 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
1649 		       IPV6CTL_MAXFRAGS, CTL_EOL);
1650 }
1651