1 | /* $NetBSD: ip6_input.c,v 1.170 2016/11/01 10:32:57 ozaki-r 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.170 2016/11/01 10:32:57 ozaki-r Exp $" ); |
66 | |
67 | #ifdef _KERNEL_OPT |
68 | #include "opt_gateway.h" |
69 | #include "opt_inet.h" |
70 | #include "opt_inet6.h" |
71 | #include "opt_ipsec.h" |
72 | #include "opt_compat_netbsd.h" |
73 | #include "opt_net_mpsafe.h" |
74 | #endif |
75 | |
76 | #include <sys/param.h> |
77 | #include <sys/systm.h> |
78 | #include <sys/malloc.h> |
79 | #include <sys/mbuf.h> |
80 | #include <sys/domain.h> |
81 | #include <sys/protosw.h> |
82 | #include <sys/socket.h> |
83 | #include <sys/socketvar.h> |
84 | #include <sys/errno.h> |
85 | #include <sys/time.h> |
86 | #include <sys/kernel.h> |
87 | #include <sys/syslog.h> |
88 | #include <sys/proc.h> |
89 | #include <sys/sysctl.h> |
90 | #include <sys/cprng.h> |
91 | #include <sys/percpu.h> |
92 | |
93 | #include <net/if.h> |
94 | #include <net/if_types.h> |
95 | #include <net/if_dl.h> |
96 | #include <net/route.h> |
97 | #include <net/pktqueue.h> |
98 | #include <net/pfil.h> |
99 | |
100 | #include <netinet/in.h> |
101 | #include <netinet/in_systm.h> |
102 | #ifdef INET |
103 | #include <netinet/ip.h> |
104 | #include <netinet/ip_var.h> |
105 | #include <netinet/ip_icmp.h> |
106 | #endif /* INET */ |
107 | #include <netinet/ip6.h> |
108 | #include <netinet/portalgo.h> |
109 | #include <netinet6/in6_var.h> |
110 | #include <netinet6/ip6_var.h> |
111 | #include <netinet6/ip6_private.h> |
112 | #include <netinet6/in6_pcb.h> |
113 | #include <netinet/icmp6.h> |
114 | #include <netinet6/scope6_var.h> |
115 | #include <netinet6/in6_ifattach.h> |
116 | #include <netinet6/nd6.h> |
117 | |
118 | #ifdef IPSEC |
119 | #include <netipsec/ipsec.h> |
120 | #include <netipsec/ipsec6.h> |
121 | #include <netipsec/key.h> |
122 | #endif /* IPSEC */ |
123 | |
124 | #ifdef COMPAT_50 |
125 | #include <compat/sys/time.h> |
126 | #include <compat/sys/socket.h> |
127 | #endif |
128 | |
129 | #include <netinet6/ip6protosw.h> |
130 | |
131 | #include "faith.h" |
132 | |
133 | #include <net/net_osdep.h> |
134 | |
135 | extern struct domain inet6domain; |
136 | |
137 | u_char ip6_protox[IPPROTO_MAX]; |
138 | pktqueue_t *ip6_pktq __read_mostly; |
139 | |
140 | int ip6_forward_srcrt; /* XXX */ |
141 | int ip6_sourcecheck; /* XXX */ |
142 | int ip6_sourcecheck_interval; /* XXX */ |
143 | |
144 | pfil_head_t *inet6_pfil_hook; |
145 | |
146 | percpu_t *ip6stat_percpu; |
147 | |
148 | percpu_t *ip6_forward_rt_percpu __cacheline_aligned; |
149 | |
150 | static void ip6_init2(void); |
151 | static void ip6intr(void *); |
152 | static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *); |
153 | |
154 | static int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *, |
155 | u_int32_t *); |
156 | static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); |
157 | static void sysctl_net_inet6_ip6_setup(struct sysctllog **); |
158 | |
159 | #ifdef NET_MPSAFE |
160 | #define SOFTNET_LOCK() mutex_enter(softnet_lock) |
161 | #define SOFTNET_UNLOCK() mutex_exit(softnet_lock) |
162 | #else |
163 | #define SOFTNET_LOCK() KASSERT(mutex_owned(softnet_lock)) |
164 | #define SOFTNET_UNLOCK() KASSERT(mutex_owned(softnet_lock)) |
165 | #endif |
166 | |
167 | /* |
168 | * IP6 initialization: fill in IP6 protocol switch table. |
169 | * All protocols not implemented in kernel go to raw IP6 protocol handler. |
170 | */ |
171 | void |
172 | ip6_init(void) |
173 | { |
174 | const struct ip6protosw *pr; |
175 | int i; |
176 | |
177 | in6_init(); |
178 | |
179 | sysctl_net_inet6_ip6_setup(NULL); |
180 | pr = (const struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); |
181 | if (pr == 0) |
182 | panic("ip6_init" ); |
183 | for (i = 0; i < IPPROTO_MAX; i++) |
184 | ip6_protox[i] = pr - inet6sw; |
185 | for (pr = (const struct ip6protosw *)inet6domain.dom_protosw; |
186 | pr < (const struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++) |
187 | if (pr->pr_domain->dom_family == PF_INET6 && |
188 | pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) |
189 | ip6_protox[pr->pr_protocol] = pr - inet6sw; |
190 | |
191 | ip6_pktq = pktq_create(IFQ_MAXLEN, ip6intr, NULL); |
192 | KASSERT(ip6_pktq != NULL); |
193 | |
194 | scope6_init(); |
195 | addrsel_policy_init(); |
196 | nd6_init(); |
197 | frag6_init(); |
198 | ip6_desync_factor = cprng_fast32() % MAX_TEMP_DESYNC_FACTOR; |
199 | |
200 | ip6_init2(); |
201 | #ifdef GATEWAY |
202 | ip6flow_init(ip6_hashsize); |
203 | #endif |
204 | /* Register our Packet Filter hook. */ |
205 | inet6_pfil_hook = pfil_head_create(PFIL_TYPE_AF, (void *)AF_INET6); |
206 | KASSERT(inet6_pfil_hook != NULL); |
207 | |
208 | ip6stat_percpu = percpu_alloc(sizeof(uint64_t) * IP6_NSTATS); |
209 | |
210 | ip6_forward_rt_percpu = percpu_alloc(sizeof(struct route)); |
211 | if (ip6_forward_rt_percpu == NULL) |
212 | panic("failed to alllocate ip6_forward_rt_percpu" ); |
213 | } |
214 | |
215 | static void |
216 | ip6_init2(void) |
217 | { |
218 | |
219 | /* timer for regeneranation of temporary addresses randomize ID */ |
220 | callout_init(&in6_tmpaddrtimer_ch, CALLOUT_MPSAFE); |
221 | callout_reset(&in6_tmpaddrtimer_ch, |
222 | (ip6_temp_preferred_lifetime - ip6_desync_factor - |
223 | ip6_temp_regen_advance) * hz, |
224 | in6_tmpaddrtimer, NULL); |
225 | } |
226 | |
227 | /* |
228 | * IP6 input interrupt handling. Just pass the packet to ip6_input. |
229 | */ |
230 | static void |
231 | ip6intr(void *arg __unused) |
232 | { |
233 | struct mbuf *m; |
234 | |
235 | #ifndef NET_MPSAFE |
236 | mutex_enter(softnet_lock); |
237 | #endif |
238 | while ((m = pktq_dequeue(ip6_pktq)) != NULL) { |
239 | struct psref psref; |
240 | struct ifnet *rcvif = m_get_rcvif_psref(m, &psref); |
241 | |
242 | if (rcvif == NULL) { |
243 | m_freem(m); |
244 | continue; |
245 | } |
246 | /* |
247 | * Drop the packet if IPv6 is disabled on the interface. |
248 | */ |
249 | if ((ND_IFINFO(rcvif)->flags & ND6_IFF_IFDISABLED)) { |
250 | m_put_rcvif_psref(rcvif, &psref); |
251 | m_freem(m); |
252 | continue; |
253 | } |
254 | ip6_input(m, rcvif); |
255 | m_put_rcvif_psref(rcvif, &psref); |
256 | } |
257 | #ifndef NET_MPSAFE |
258 | mutex_exit(softnet_lock); |
259 | #endif |
260 | } |
261 | |
262 | void |
263 | ip6_input(struct mbuf *m, struct ifnet *rcvif) |
264 | { |
265 | struct ip6_hdr *ip6; |
266 | int hit, off = sizeof(struct ip6_hdr), nest; |
267 | u_int32_t plen; |
268 | u_int32_t rtalert = ~0; |
269 | int nxt, ours = 0, rh_present = 0; |
270 | struct ifnet *deliverifp = NULL; |
271 | int srcrt = 0; |
272 | const struct rtentry *rt; |
273 | union { |
274 | struct sockaddr dst; |
275 | struct sockaddr_in6 dst6; |
276 | } u; |
277 | struct route *ro; |
278 | |
279 | /* |
280 | * make sure we don't have onion peering information into m_tag. |
281 | */ |
282 | ip6_delaux(m); |
283 | |
284 | /* |
285 | * mbuf statistics |
286 | */ |
287 | if (m->m_flags & M_EXT) { |
288 | if (m->m_next) |
289 | IP6_STATINC(IP6_STAT_MEXT2M); |
290 | else |
291 | IP6_STATINC(IP6_STAT_MEXT1); |
292 | } else { |
293 | #define M2MMAX 32 |
294 | if (m->m_next) { |
295 | if (m->m_flags & M_LOOP) |
296 | /*XXX*/ IP6_STATINC(IP6_STAT_M2M + lo0ifp->if_index); |
297 | else if (rcvif->if_index < M2MMAX) |
298 | IP6_STATINC(IP6_STAT_M2M + rcvif->if_index); |
299 | else |
300 | IP6_STATINC(IP6_STAT_M2M); |
301 | } else |
302 | IP6_STATINC(IP6_STAT_M1); |
303 | #undef M2MMAX |
304 | } |
305 | |
306 | in6_ifstat_inc(rcvif, ifs6_in_receive); |
307 | IP6_STATINC(IP6_STAT_TOTAL); |
308 | |
309 | /* |
310 | * If the IPv6 header is not aligned, slurp it up into a new |
311 | * mbuf with space for link headers, in the event we forward |
312 | * it. Otherwise, if it is aligned, make sure the entire base |
313 | * IPv6 header is in the first mbuf of the chain. |
314 | */ |
315 | if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) { |
316 | if ((m = m_copyup(m, sizeof(struct ip6_hdr), |
317 | (max_linkhdr + 3) & ~3)) == NULL) { |
318 | /* XXXJRT new stat, please */ |
319 | IP6_STATINC(IP6_STAT_TOOSMALL); |
320 | in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
321 | return; |
322 | } |
323 | } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { |
324 | if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { |
325 | IP6_STATINC(IP6_STAT_TOOSMALL); |
326 | in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
327 | return; |
328 | } |
329 | } |
330 | |
331 | ip6 = mtod(m, struct ip6_hdr *); |
332 | |
333 | if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { |
334 | IP6_STATINC(IP6_STAT_BADVERS); |
335 | in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
336 | goto bad; |
337 | } |
338 | |
339 | /* |
340 | * Assume that we can create a fast-forward IP flow entry |
341 | * based on this packet. |
342 | */ |
343 | m->m_flags |= M_CANFASTFWD; |
344 | |
345 | /* |
346 | * Run through list of hooks for input packets. If there are any |
347 | * filters which require that additional packets in the flow are |
348 | * not fast-forwarded, they must clear the M_CANFASTFWD flag. |
349 | * Note that filters must _never_ set this flag, as another filter |
350 | * in the list may have previously cleared it. |
351 | */ |
352 | /* |
353 | * let ipfilter look at packet on the wire, |
354 | * not the decapsulated packet. |
355 | */ |
356 | #if defined(IPSEC) |
357 | if (!ipsec_used || !ipsec_indone(m)) |
358 | #else |
359 | if (1) |
360 | #endif |
361 | { |
362 | struct in6_addr odst; |
363 | |
364 | odst = ip6->ip6_dst; |
365 | if (pfil_run_hooks(inet6_pfil_hook, &m, rcvif, PFIL_IN) != 0) |
366 | return; |
367 | if (m == NULL) |
368 | return; |
369 | ip6 = mtod(m, struct ip6_hdr *); |
370 | srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); |
371 | } |
372 | |
373 | IP6_STATINC(IP6_STAT_NXTHIST + ip6->ip6_nxt); |
374 | |
375 | #ifdef ALTQ |
376 | if (altq_input != NULL) { |
377 | SOFTNET_LOCK(); |
378 | if ((*altq_input)(m, AF_INET6) == 0) { |
379 | SOFTNET_UNLOCK(); |
380 | /* packet is dropped by traffic conditioner */ |
381 | return; |
382 | } |
383 | SOFTNET_UNLOCK(); |
384 | } |
385 | #endif |
386 | |
387 | /* |
388 | * Check against address spoofing/corruption. |
389 | */ |
390 | if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) || |
391 | IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) { |
392 | /* |
393 | * XXX: "badscope" is not very suitable for a multicast source. |
394 | */ |
395 | IP6_STATINC(IP6_STAT_BADSCOPE); |
396 | in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
397 | goto bad; |
398 | } |
399 | /* |
400 | * The following check is not documented in specs. A malicious |
401 | * party may be able to use IPv4 mapped addr to confuse tcp/udp stack |
402 | * and bypass security checks (act as if it was from 127.0.0.1 by using |
403 | * IPv6 src ::ffff:127.0.0.1). Be cautious. |
404 | * |
405 | * This check chokes if we are in an SIIT cloud. As none of BSDs |
406 | * support IPv4-less kernel compilation, we cannot support SIIT |
407 | * environment at all. So, it makes more sense for us to reject any |
408 | * malicious packets for non-SIIT environment, than try to do a |
409 | * partial support for SIIT environment. |
410 | */ |
411 | if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || |
412 | IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { |
413 | IP6_STATINC(IP6_STAT_BADSCOPE); |
414 | in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
415 | goto bad; |
416 | } |
417 | #if 0 |
418 | /* |
419 | * Reject packets with IPv4 compatible addresses (auto tunnel). |
420 | * |
421 | * The code forbids auto tunnel relay case in RFC1933 (the check is |
422 | * stronger than RFC1933). We may want to re-enable it if mech-xx |
423 | * is revised to forbid relaying case. |
424 | */ |
425 | if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || |
426 | IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { |
427 | IP6_STATINC(IP6_STAT_BADSCOPE); |
428 | in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
429 | goto bad; |
430 | } |
431 | #endif |
432 | |
433 | /* |
434 | * Disambiguate address scope zones (if there is ambiguity). |
435 | * We first make sure that the original source or destination address |
436 | * is not in our internal form for scoped addresses. Such addresses |
437 | * are not necessarily invalid spec-wise, but we cannot accept them due |
438 | * to the usage conflict. |
439 | * in6_setscope() then also checks and rejects the cases where src or |
440 | * dst are the loopback address and the receiving interface |
441 | * is not loopback. |
442 | */ |
443 | if (__predict_false( |
444 | m_makewritable(&m, 0, sizeof(struct ip6_hdr), M_DONTWAIT))) |
445 | goto bad; |
446 | ip6 = mtod(m, struct ip6_hdr *); |
447 | if (in6_clearscope(&ip6->ip6_src) || in6_clearscope(&ip6->ip6_dst)) { |
448 | IP6_STATINC(IP6_STAT_BADSCOPE); /* XXX */ |
449 | goto bad; |
450 | } |
451 | if (in6_setscope(&ip6->ip6_src, rcvif, NULL) || |
452 | in6_setscope(&ip6->ip6_dst, rcvif, NULL)) { |
453 | IP6_STATINC(IP6_STAT_BADSCOPE); |
454 | goto bad; |
455 | } |
456 | |
457 | /* |
458 | * Multicast check |
459 | */ |
460 | if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
461 | struct in6_multi *in6m = 0; |
462 | |
463 | in6_ifstat_inc(rcvif, ifs6_in_mcast); |
464 | /* |
465 | * See if we belong to the destination multicast group on the |
466 | * arrival interface. |
467 | */ |
468 | IN6_LOOKUP_MULTI(ip6->ip6_dst, rcvif, in6m); |
469 | if (in6m) |
470 | ours = 1; |
471 | else if (!ip6_mrouter) { |
472 | uint64_t *ip6s = IP6_STAT_GETREF(); |
473 | ip6s[IP6_STAT_NOTMEMBER]++; |
474 | ip6s[IP6_STAT_CANTFORWARD]++; |
475 | IP6_STAT_PUTREF(); |
476 | in6_ifstat_inc(rcvif, ifs6_in_discard); |
477 | goto bad; |
478 | } |
479 | deliverifp = rcvif; |
480 | goto hbhcheck; |
481 | } |
482 | |
483 | sockaddr_in6_init(&u.dst6, &ip6->ip6_dst, 0, 0, 0); |
484 | |
485 | /* |
486 | * Unicast check |
487 | */ |
488 | ro = percpu_getref(ip6_forward_rt_percpu); |
489 | rt = rtcache_lookup2(ro, &u.dst, 1, &hit); |
490 | percpu_putref(ip6_forward_rt_percpu); |
491 | if (hit) |
492 | IP6_STATINC(IP6_STAT_FORWARD_CACHEHIT); |
493 | else |
494 | IP6_STATINC(IP6_STAT_FORWARD_CACHEMISS); |
495 | |
496 | #define rt6_getkey(__rt) satocsin6(rt_getkey(__rt)) |
497 | |
498 | /* |
499 | * Accept the packet if the forwarding interface to the destination |
500 | * according to the routing table is the loopback interface, |
501 | * unless the associated route has a gateway. |
502 | * Note that this approach causes to accept a packet if there is a |
503 | * route to the loopback interface for the destination of the packet. |
504 | * But we think it's even useful in some situations, e.g. when using |
505 | * a special daemon which wants to intercept the packet. |
506 | */ |
507 | if (rt != NULL && |
508 | (rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST && |
509 | #if 0 |
510 | /* |
511 | * The check below is redundant since the comparison of |
512 | * the destination and the key of the rtentry has |
513 | * already done through looking up the routing table. |
514 | */ |
515 | IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &rt6_getkey(rt)->sin6_addr) && |
516 | #endif |
517 | rt->rt_ifp->if_type == IFT_LOOP) { |
518 | struct in6_ifaddr *ia6 = (struct in6_ifaddr *)rt->rt_ifa; |
519 | if (ia6->ia6_flags & IN6_IFF_ANYCAST) |
520 | m->m_flags |= M_ANYCAST6; |
521 | /* |
522 | * packets to a tentative, duplicated, or somehow invalid |
523 | * address must not be accepted. |
524 | */ |
525 | if (!(ia6->ia6_flags & (IN6_IFF_NOTREADY | IN6_IFF_DETACHED))) { |
526 | /* this address is ready */ |
527 | ours = 1; |
528 | deliverifp = ia6->ia_ifp; /* correct? */ |
529 | goto hbhcheck; |
530 | } else { |
531 | /* address is not ready, so discard the packet. */ |
532 | nd6log(LOG_INFO, "packet to an unready address %s->%s\n" , |
533 | ip6_sprintf(&ip6->ip6_src), |
534 | ip6_sprintf(&ip6->ip6_dst)); |
535 | |
536 | goto bad; |
537 | } |
538 | } |
539 | |
540 | /* |
541 | * FAITH (Firewall Aided Internet Translator) |
542 | */ |
543 | #if defined(NFAITH) && 0 < NFAITH |
544 | if (ip6_keepfaith) { |
545 | if (rt != NULL && rt->rt_ifp != NULL && |
546 | rt->rt_ifp->if_type == IFT_FAITH) { |
547 | /* XXX do we need more sanity checks? */ |
548 | ours = 1; |
549 | deliverifp = rt->rt_ifp; /* faith */ |
550 | goto hbhcheck; |
551 | } |
552 | } |
553 | #endif |
554 | |
555 | #if 0 |
556 | { |
557 | /* |
558 | * Last resort: check in6_ifaddr for incoming interface. |
559 | * The code is here until I update the "goto ours hack" code above |
560 | * working right. |
561 | */ |
562 | struct ifaddr *ifa; |
563 | IFADDR_READER_FOREACH(ifa, rcvif) { |
564 | if (ifa->ifa_addr->sa_family != AF_INET6) |
565 | continue; |
566 | if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ip6->ip6_dst)) { |
567 | ours = 1; |
568 | deliverifp = ifa->ifa_ifp; |
569 | goto hbhcheck; |
570 | } |
571 | } |
572 | } |
573 | #endif |
574 | |
575 | /* |
576 | * Now there is no reason to process the packet if it's not our own |
577 | * and we're not a router. |
578 | */ |
579 | if (!ip6_forwarding) { |
580 | IP6_STATINC(IP6_STAT_CANTFORWARD); |
581 | in6_ifstat_inc(rcvif, ifs6_in_discard); |
582 | goto bad; |
583 | } |
584 | |
585 | hbhcheck: |
586 | /* |
587 | * record address information into m_tag, if we don't have one yet. |
588 | * note that we are unable to record it, if the address is not listed |
589 | * as our interface address (e.g. multicast addresses, addresses |
590 | * within FAITH prefixes and such). |
591 | */ |
592 | if (deliverifp && ip6_getdstifaddr(m) == NULL) { |
593 | struct in6_ifaddr *ia6; |
594 | int s = pserialize_read_enter(); |
595 | |
596 | ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst); |
597 | /* Depends on ip6_setdstifaddr never sleep */ |
598 | if (ia6 != NULL && ip6_setdstifaddr(m, ia6) == NULL) { |
599 | /* |
600 | * XXX maybe we should drop the packet here, |
601 | * as we could not provide enough information |
602 | * to the upper layers. |
603 | */ |
604 | } |
605 | pserialize_read_exit(s); |
606 | } |
607 | |
608 | /* |
609 | * Process Hop-by-Hop options header if it's contained. |
610 | * m may be modified in ip6_hopopts_input(). |
611 | * If a JumboPayload option is included, plen will also be modified. |
612 | */ |
613 | plen = (u_int32_t)ntohs(ip6->ip6_plen); |
614 | if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { |
615 | struct ip6_hbh *hbh; |
616 | |
617 | if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) { |
618 | #if 0 /*touches NULL pointer*/ |
619 | in6_ifstat_inc(rcvif, ifs6_in_discard); |
620 | #endif |
621 | return; /* m have already been freed */ |
622 | } |
623 | |
624 | /* adjust pointer */ |
625 | ip6 = mtod(m, struct ip6_hdr *); |
626 | |
627 | /* |
628 | * if the payload length field is 0 and the next header field |
629 | * indicates Hop-by-Hop Options header, then a Jumbo Payload |
630 | * option MUST be included. |
631 | */ |
632 | if (ip6->ip6_plen == 0 && plen == 0) { |
633 | /* |
634 | * Note that if a valid jumbo payload option is |
635 | * contained, ip6_hopopts_input() must set a valid |
636 | * (non-zero) payload length to the variable plen. |
637 | */ |
638 | IP6_STATINC(IP6_STAT_BADOPTIONS); |
639 | in6_ifstat_inc(rcvif, ifs6_in_discard); |
640 | in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
641 | icmp6_error(m, ICMP6_PARAM_PROB, |
642 | ICMP6_PARAMPROB_HEADER, |
643 | (char *)&ip6->ip6_plen - (char *)ip6); |
644 | return; |
645 | } |
646 | IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), |
647 | sizeof(struct ip6_hbh)); |
648 | if (hbh == NULL) { |
649 | IP6_STATINC(IP6_STAT_TOOSHORT); |
650 | return; |
651 | } |
652 | KASSERT(IP6_HDR_ALIGNED_P(hbh)); |
653 | nxt = hbh->ip6h_nxt; |
654 | |
655 | /* |
656 | * accept the packet if a router alert option is included |
657 | * and we act as an IPv6 router. |
658 | */ |
659 | if (rtalert != ~0 && ip6_forwarding) |
660 | ours = 1; |
661 | } else |
662 | nxt = ip6->ip6_nxt; |
663 | |
664 | /* |
665 | * Check that the amount of data in the buffers |
666 | * is as at least much as the IPv6 header would have us expect. |
667 | * Trim mbufs if longer than we expect. |
668 | * Drop packet if shorter than we expect. |
669 | */ |
670 | if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) { |
671 | IP6_STATINC(IP6_STAT_TOOSHORT); |
672 | in6_ifstat_inc(rcvif, ifs6_in_truncated); |
673 | goto bad; |
674 | } |
675 | if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { |
676 | if (m->m_len == m->m_pkthdr.len) { |
677 | m->m_len = sizeof(struct ip6_hdr) + plen; |
678 | m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen; |
679 | } else |
680 | m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len); |
681 | } |
682 | |
683 | /* |
684 | * Forward if desirable. |
685 | */ |
686 | if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
687 | /* |
688 | * If we are acting as a multicast router, all |
689 | * incoming multicast packets are passed to the |
690 | * kernel-level multicast forwarding function. |
691 | * The packet is returned (relatively) intact; if |
692 | * ip6_mforward() returns a non-zero value, the packet |
693 | * must be discarded, else it may be accepted below. |
694 | */ |
695 | if (ip6_mrouter != NULL) { |
696 | int error; |
697 | |
698 | SOFTNET_LOCK(); |
699 | error = ip6_mforward(ip6, rcvif, m); |
700 | SOFTNET_UNLOCK(); |
701 | |
702 | if (error != 0) { |
703 | IP6_STATINC(IP6_STAT_CANTFORWARD); |
704 | goto bad; |
705 | } |
706 | } |
707 | if (!ours) |
708 | goto bad; |
709 | } else if (!ours) { |
710 | ip6_forward(m, srcrt); |
711 | return; |
712 | } |
713 | |
714 | ip6 = mtod(m, struct ip6_hdr *); |
715 | |
716 | /* |
717 | * Malicious party may be able to use IPv4 mapped addr to confuse |
718 | * tcp/udp stack and bypass security checks (act as if it was from |
719 | * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1). Be cautious. |
720 | * |
721 | * For SIIT end node behavior, you may want to disable the check. |
722 | * However, you will become vulnerable to attacks using IPv4 mapped |
723 | * source. |
724 | */ |
725 | if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || |
726 | IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { |
727 | IP6_STATINC(IP6_STAT_BADSCOPE); |
728 | in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
729 | goto bad; |
730 | } |
731 | |
732 | /* |
733 | * Tell launch routine the next header |
734 | */ |
735 | #ifdef IFA_STATS |
736 | if (deliverifp != NULL) { |
737 | struct in6_ifaddr *ia6; |
738 | int s = pserialize_read_enter(); |
739 | ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst); |
740 | if (ia6) |
741 | ia6->ia_ifa.ifa_data.ifad_inbytes += m->m_pkthdr.len; |
742 | pserialize_read_exit(s); |
743 | } |
744 | #endif |
745 | IP6_STATINC(IP6_STAT_DELIVERED); |
746 | in6_ifstat_inc(deliverifp, ifs6_in_deliver); |
747 | nest = 0; |
748 | |
749 | rh_present = 0; |
750 | while (nxt != IPPROTO_DONE) { |
751 | if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { |
752 | IP6_STATINC(IP6_STAT_TOOMANYHDR); |
753 | in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
754 | goto bad; |
755 | } |
756 | |
757 | /* |
758 | * protection against faulty packet - there should be |
759 | * more sanity checks in header chain processing. |
760 | */ |
761 | if (m->m_pkthdr.len < off) { |
762 | IP6_STATINC(IP6_STAT_TOOSHORT); |
763 | in6_ifstat_inc(rcvif, ifs6_in_truncated); |
764 | goto bad; |
765 | } |
766 | |
767 | if (nxt == IPPROTO_ROUTING) { |
768 | if (rh_present++) { |
769 | in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
770 | IP6_STATINC(IP6_STAT_BADOPTIONS); |
771 | goto bad; |
772 | } |
773 | } |
774 | |
775 | #ifdef IPSEC |
776 | if (ipsec_used) { |
777 | /* |
778 | * enforce IPsec policy checking if we are seeing last |
779 | * header. note that we do not visit this with |
780 | * protocols with pcb layer code - like udp/tcp/raw ip. |
781 | */ |
782 | if ((inet6sw[ip_protox[nxt]].pr_flags |
783 | & PR_LASTHDR) != 0) { |
784 | int error; |
785 | |
786 | SOFTNET_LOCK(); |
787 | error = ipsec6_input(m); |
788 | SOFTNET_UNLOCK(); |
789 | if (error) |
790 | goto bad; |
791 | } |
792 | } |
793 | #endif /* IPSEC */ |
794 | |
795 | SOFTNET_LOCK(); |
796 | nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); |
797 | SOFTNET_UNLOCK(); |
798 | } |
799 | return; |
800 | bad: |
801 | m_freem(m); |
802 | } |
803 | |
804 | /* |
805 | * set/grab in6_ifaddr correspond to IPv6 destination address. |
806 | */ |
807 | static struct m_tag * |
808 | ip6_setdstifaddr(struct mbuf *m, const struct in6_ifaddr *ia) |
809 | { |
810 | struct m_tag *mtag; |
811 | struct ip6aux *ip6a; |
812 | |
813 | mtag = ip6_addaux(m); |
814 | if (mtag == NULL) |
815 | return NULL; |
816 | |
817 | ip6a = (struct ip6aux *)(mtag + 1); |
818 | if (in6_setscope(&ip6a->ip6a_src, ia->ia_ifp, &ip6a->ip6a_scope_id)) { |
819 | IP6_STATINC(IP6_STAT_BADSCOPE); |
820 | return NULL; |
821 | } |
822 | |
823 | ip6a->ip6a_src = ia->ia_addr.sin6_addr; |
824 | ip6a->ip6a_flags = ia->ia6_flags; |
825 | return mtag; |
826 | } |
827 | |
828 | const struct ip6aux * |
829 | ip6_getdstifaddr(struct mbuf *m) |
830 | { |
831 | struct m_tag *mtag; |
832 | |
833 | mtag = ip6_findaux(m); |
834 | if (mtag != NULL) |
835 | return (struct ip6aux *)(mtag + 1); |
836 | else |
837 | return NULL; |
838 | } |
839 | |
840 | /* |
841 | * Hop-by-Hop options header processing. If a valid jumbo payload option is |
842 | * included, the real payload length will be stored in plenp. |
843 | * |
844 | * rtalertp - XXX: should be stored more smart way |
845 | */ |
846 | int |
847 | ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, |
848 | struct mbuf **mp, int *offp) |
849 | { |
850 | struct mbuf *m = *mp; |
851 | int off = *offp, hbhlen; |
852 | struct ip6_hbh *hbh; |
853 | |
854 | /* validation of the length of the header */ |
855 | IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, |
856 | sizeof(struct ip6_hdr), sizeof(struct ip6_hbh)); |
857 | if (hbh == NULL) { |
858 | IP6_STATINC(IP6_STAT_TOOSHORT); |
859 | return -1; |
860 | } |
861 | hbhlen = (hbh->ip6h_len + 1) << 3; |
862 | IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), |
863 | hbhlen); |
864 | if (hbh == NULL) { |
865 | IP6_STATINC(IP6_STAT_TOOSHORT); |
866 | return -1; |
867 | } |
868 | KASSERT(IP6_HDR_ALIGNED_P(hbh)); |
869 | off += hbhlen; |
870 | hbhlen -= sizeof(struct ip6_hbh); |
871 | |
872 | if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), |
873 | hbhlen, rtalertp, plenp) < 0) |
874 | return (-1); |
875 | |
876 | *offp = off; |
877 | *mp = m; |
878 | return (0); |
879 | } |
880 | |
881 | /* |
882 | * Search header for all Hop-by-hop options and process each option. |
883 | * This function is separate from ip6_hopopts_input() in order to |
884 | * handle a case where the sending node itself process its hop-by-hop |
885 | * options header. In such a case, the function is called from ip6_output(). |
886 | * |
887 | * The function assumes that hbh header is located right after the IPv6 header |
888 | * (RFC2460 p7), opthead is pointer into data content in m, and opthead to |
889 | * opthead + hbhlen is located in continuous memory region. |
890 | */ |
891 | static int |
892 | ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, |
893 | u_int32_t *rtalertp, u_int32_t *plenp) |
894 | { |
895 | struct ip6_hdr *ip6; |
896 | int optlen = 0; |
897 | u_int8_t *opt = opthead; |
898 | u_int16_t rtalert_val; |
899 | u_int32_t jumboplen; |
900 | const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh); |
901 | |
902 | for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) { |
903 | switch (*opt) { |
904 | case IP6OPT_PAD1: |
905 | optlen = 1; |
906 | break; |
907 | case IP6OPT_PADN: |
908 | if (hbhlen < IP6OPT_MINLEN) { |
909 | IP6_STATINC(IP6_STAT_TOOSMALL); |
910 | goto bad; |
911 | } |
912 | optlen = *(opt + 1) + 2; |
913 | break; |
914 | case IP6OPT_RTALERT: |
915 | /* XXX may need check for alignment */ |
916 | if (hbhlen < IP6OPT_RTALERT_LEN) { |
917 | IP6_STATINC(IP6_STAT_TOOSMALL); |
918 | goto bad; |
919 | } |
920 | if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) { |
921 | /* XXX stat */ |
922 | icmp6_error(m, ICMP6_PARAM_PROB, |
923 | ICMP6_PARAMPROB_HEADER, |
924 | erroff + opt + 1 - opthead); |
925 | return (-1); |
926 | } |
927 | optlen = IP6OPT_RTALERT_LEN; |
928 | memcpy((void *)&rtalert_val, (void *)(opt + 2), 2); |
929 | *rtalertp = ntohs(rtalert_val); |
930 | break; |
931 | case IP6OPT_JUMBO: |
932 | /* XXX may need check for alignment */ |
933 | if (hbhlen < IP6OPT_JUMBO_LEN) { |
934 | IP6_STATINC(IP6_STAT_TOOSMALL); |
935 | goto bad; |
936 | } |
937 | if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) { |
938 | /* XXX stat */ |
939 | icmp6_error(m, ICMP6_PARAM_PROB, |
940 | ICMP6_PARAMPROB_HEADER, |
941 | erroff + opt + 1 - opthead); |
942 | return (-1); |
943 | } |
944 | optlen = IP6OPT_JUMBO_LEN; |
945 | |
946 | /* |
947 | * IPv6 packets that have non 0 payload length |
948 | * must not contain a jumbo payload option. |
949 | */ |
950 | ip6 = mtod(m, struct ip6_hdr *); |
951 | if (ip6->ip6_plen) { |
952 | IP6_STATINC(IP6_STAT_BADOPTIONS); |
953 | icmp6_error(m, ICMP6_PARAM_PROB, |
954 | ICMP6_PARAMPROB_HEADER, |
955 | erroff + opt - opthead); |
956 | return (-1); |
957 | } |
958 | |
959 | /* |
960 | * We may see jumbolen in unaligned location, so |
961 | * we'd need to perform bcopy(). |
962 | */ |
963 | memcpy(&jumboplen, opt + 2, sizeof(jumboplen)); |
964 | jumboplen = (u_int32_t)htonl(jumboplen); |
965 | |
966 | #if 1 |
967 | /* |
968 | * if there are multiple jumbo payload options, |
969 | * *plenp will be non-zero and the packet will be |
970 | * rejected. |
971 | * the behavior may need some debate in ipngwg - |
972 | * multiple options does not make sense, however, |
973 | * there's no explicit mention in specification. |
974 | */ |
975 | if (*plenp != 0) { |
976 | IP6_STATINC(IP6_STAT_BADOPTIONS); |
977 | icmp6_error(m, ICMP6_PARAM_PROB, |
978 | ICMP6_PARAMPROB_HEADER, |
979 | erroff + opt + 2 - opthead); |
980 | return (-1); |
981 | } |
982 | #endif |
983 | |
984 | /* |
985 | * jumbo payload length must be larger than 65535. |
986 | */ |
987 | if (jumboplen <= IPV6_MAXPACKET) { |
988 | IP6_STATINC(IP6_STAT_BADOPTIONS); |
989 | icmp6_error(m, ICMP6_PARAM_PROB, |
990 | ICMP6_PARAMPROB_HEADER, |
991 | erroff + opt + 2 - opthead); |
992 | return (-1); |
993 | } |
994 | *plenp = jumboplen; |
995 | |
996 | break; |
997 | default: /* unknown option */ |
998 | if (hbhlen < IP6OPT_MINLEN) { |
999 | IP6_STATINC(IP6_STAT_TOOSMALL); |
1000 | goto bad; |
1001 | } |
1002 | optlen = ip6_unknown_opt(opt, m, |
1003 | erroff + opt - opthead); |
1004 | if (optlen == -1) |
1005 | return (-1); |
1006 | optlen += 2; |
1007 | break; |
1008 | } |
1009 | } |
1010 | |
1011 | return (0); |
1012 | |
1013 | bad: |
1014 | m_freem(m); |
1015 | return (-1); |
1016 | } |
1017 | |
1018 | /* |
1019 | * Unknown option processing. |
1020 | * The third argument `off' is the offset from the IPv6 header to the option, |
1021 | * which is necessary if the IPv6 header the and option header and IPv6 header |
1022 | * is not continuous in order to return an ICMPv6 error. |
1023 | */ |
1024 | int |
1025 | ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off) |
1026 | { |
1027 | struct ip6_hdr *ip6; |
1028 | |
1029 | switch (IP6OPT_TYPE(*optp)) { |
1030 | case IP6OPT_TYPE_SKIP: /* ignore the option */ |
1031 | return ((int)*(optp + 1)); |
1032 | case IP6OPT_TYPE_DISCARD: /* silently discard */ |
1033 | m_freem(m); |
1034 | return (-1); |
1035 | case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */ |
1036 | IP6_STATINC(IP6_STAT_BADOPTIONS); |
1037 | icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); |
1038 | return (-1); |
1039 | case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */ |
1040 | IP6_STATINC(IP6_STAT_BADOPTIONS); |
1041 | ip6 = mtod(m, struct ip6_hdr *); |
1042 | if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || |
1043 | (m->m_flags & (M_BCAST|M_MCAST))) |
1044 | m_freem(m); |
1045 | else |
1046 | icmp6_error(m, ICMP6_PARAM_PROB, |
1047 | ICMP6_PARAMPROB_OPTION, off); |
1048 | return (-1); |
1049 | } |
1050 | |
1051 | m_freem(m); /* XXX: NOTREACHED */ |
1052 | return (-1); |
1053 | } |
1054 | |
1055 | /* |
1056 | * Create the "control" list for this pcb. |
1057 | * |
1058 | * The routine will be called from upper layer handlers like tcp6_input(). |
1059 | * Thus the routine assumes that the caller (tcp6_input) have already |
1060 | * called IP6_EXTHDR_CHECK() and all the extension headers are located in the |
1061 | * very first mbuf on the mbuf chain. |
1062 | * We may want to add some infinite loop prevention or sanity checks for safety. |
1063 | * (This applies only when you are using KAME mbuf chain restriction, i.e. |
1064 | * you are using IP6_EXTHDR_CHECK() not m_pulldown()) |
1065 | */ |
1066 | void |
1067 | ip6_savecontrol(struct in6pcb *in6p, struct mbuf **mp, |
1068 | struct ip6_hdr *ip6, struct mbuf *m) |
1069 | { |
1070 | #ifdef RFC2292 |
1071 | #define IS2292(x, y) ((in6p->in6p_flags & IN6P_RFC2292) ? (x) : (y)) |
1072 | #else |
1073 | #define IS2292(x, y) (y) |
1074 | #endif |
1075 | |
1076 | if (in6p->in6p_socket->so_options & SO_TIMESTAMP |
1077 | #ifdef SO_OTIMESTAMP |
1078 | || in6p->in6p_socket->so_options & SO_OTIMESTAMP |
1079 | #endif |
1080 | ) { |
1081 | struct timeval tv; |
1082 | |
1083 | microtime(&tv); |
1084 | #ifdef SO_OTIMESTAMP |
1085 | if (in6p->in6p_socket->so_options & SO_OTIMESTAMP) { |
1086 | struct timeval50 tv50; |
1087 | timeval_to_timeval50(&tv, &tv50); |
1088 | *mp = sbcreatecontrol((void *) &tv50, sizeof(tv50), |
1089 | SCM_OTIMESTAMP, SOL_SOCKET); |
1090 | } else |
1091 | #endif |
1092 | *mp = sbcreatecontrol((void *) &tv, sizeof(tv), |
1093 | SCM_TIMESTAMP, SOL_SOCKET); |
1094 | if (*mp) |
1095 | mp = &(*mp)->m_next; |
1096 | } |
1097 | |
1098 | /* some OSes call this logic with IPv4 packet, for SO_TIMESTAMP */ |
1099 | if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) |
1100 | return; |
1101 | |
1102 | /* RFC 2292 sec. 5 */ |
1103 | if ((in6p->in6p_flags & IN6P_PKTINFO) != 0) { |
1104 | struct in6_pktinfo pi6; |
1105 | |
1106 | memcpy(&pi6.ipi6_addr, &ip6->ip6_dst, sizeof(struct in6_addr)); |
1107 | in6_clearscope(&pi6.ipi6_addr); /* XXX */ |
1108 | pi6.ipi6_ifindex = m->m_pkthdr.rcvif_index; |
1109 | *mp = sbcreatecontrol((void *) &pi6, |
1110 | sizeof(struct in6_pktinfo), |
1111 | IS2292(IPV6_2292PKTINFO, IPV6_PKTINFO), IPPROTO_IPV6); |
1112 | if (*mp) |
1113 | mp = &(*mp)->m_next; |
1114 | } |
1115 | |
1116 | if (in6p->in6p_flags & IN6P_HOPLIMIT) { |
1117 | int hlim = ip6->ip6_hlim & 0xff; |
1118 | |
1119 | *mp = sbcreatecontrol((void *) &hlim, sizeof(int), |
1120 | IS2292(IPV6_2292HOPLIMIT, IPV6_HOPLIMIT), IPPROTO_IPV6); |
1121 | if (*mp) |
1122 | mp = &(*mp)->m_next; |
1123 | } |
1124 | |
1125 | if ((in6p->in6p_flags & IN6P_TCLASS) != 0) { |
1126 | u_int32_t flowinfo; |
1127 | int tclass; |
1128 | |
1129 | flowinfo = (u_int32_t)ntohl(ip6->ip6_flow & IPV6_FLOWINFO_MASK); |
1130 | flowinfo >>= 20; |
1131 | |
1132 | tclass = flowinfo & 0xff; |
1133 | *mp = sbcreatecontrol((void *)&tclass, sizeof(tclass), |
1134 | IPV6_TCLASS, IPPROTO_IPV6); |
1135 | |
1136 | if (*mp) |
1137 | mp = &(*mp)->m_next; |
1138 | } |
1139 | |
1140 | /* |
1141 | * IPV6_HOPOPTS socket option. Recall that we required super-user |
1142 | * privilege for the option (see ip6_ctloutput), but it might be too |
1143 | * strict, since there might be some hop-by-hop options which can be |
1144 | * returned to normal user. |
1145 | * See also RFC3542 section 8 (or RFC2292 section 6). |
1146 | */ |
1147 | if ((in6p->in6p_flags & IN6P_HOPOPTS) != 0) { |
1148 | /* |
1149 | * Check if a hop-by-hop options header is contatined in the |
1150 | * received packet, and if so, store the options as ancillary |
1151 | * data. Note that a hop-by-hop options header must be |
1152 | * just after the IPv6 header, which fact is assured through |
1153 | * the IPv6 input processing. |
1154 | */ |
1155 | struct ip6_hdr *xip6 = mtod(m, struct ip6_hdr *); |
1156 | if (xip6->ip6_nxt == IPPROTO_HOPOPTS) { |
1157 | struct ip6_hbh *hbh; |
1158 | int hbhlen; |
1159 | struct mbuf *ext; |
1160 | |
1161 | ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr), |
1162 | xip6->ip6_nxt); |
1163 | if (ext == NULL) { |
1164 | IP6_STATINC(IP6_STAT_TOOSHORT); |
1165 | return; |
1166 | } |
1167 | hbh = mtod(ext, struct ip6_hbh *); |
1168 | hbhlen = (hbh->ip6h_len + 1) << 3; |
1169 | if (hbhlen != ext->m_len) { |
1170 | m_freem(ext); |
1171 | IP6_STATINC(IP6_STAT_TOOSHORT); |
1172 | return; |
1173 | } |
1174 | |
1175 | /* |
1176 | * XXX: We copy whole the header even if a jumbo |
1177 | * payload option is included, which option is to |
1178 | * be removed before returning in the RFC 2292. |
1179 | * Note: this constraint is removed in RFC3542. |
1180 | */ |
1181 | *mp = sbcreatecontrol((void *)hbh, hbhlen, |
1182 | IS2292(IPV6_2292HOPOPTS, IPV6_HOPOPTS), |
1183 | IPPROTO_IPV6); |
1184 | if (*mp) |
1185 | mp = &(*mp)->m_next; |
1186 | m_freem(ext); |
1187 | } |
1188 | } |
1189 | |
1190 | /* IPV6_DSTOPTS and IPV6_RTHDR socket options */ |
1191 | if (in6p->in6p_flags & (IN6P_DSTOPTS | IN6P_RTHDR)) { |
1192 | struct ip6_hdr *xip6 = mtod(m, struct ip6_hdr *); |
1193 | int nxt = xip6->ip6_nxt, off = sizeof(struct ip6_hdr); |
1194 | |
1195 | /* |
1196 | * Search for destination options headers or routing |
1197 | * header(s) through the header chain, and stores each |
1198 | * header as ancillary data. |
1199 | * Note that the order of the headers remains in |
1200 | * the chain of ancillary data. |
1201 | */ |
1202 | for (;;) { /* is explicit loop prevention necessary? */ |
1203 | struct ip6_ext *ip6e = NULL; |
1204 | int elen; |
1205 | struct mbuf *ext = NULL; |
1206 | |
1207 | /* |
1208 | * if it is not an extension header, don't try to |
1209 | * pull it from the chain. |
1210 | */ |
1211 | switch (nxt) { |
1212 | case IPPROTO_DSTOPTS: |
1213 | case IPPROTO_ROUTING: |
1214 | case IPPROTO_HOPOPTS: |
1215 | case IPPROTO_AH: /* is it possible? */ |
1216 | break; |
1217 | default: |
1218 | goto loopend; |
1219 | } |
1220 | |
1221 | ext = ip6_pullexthdr(m, off, nxt); |
1222 | if (ext == NULL) { |
1223 | IP6_STATINC(IP6_STAT_TOOSHORT); |
1224 | return; |
1225 | } |
1226 | ip6e = mtod(ext, struct ip6_ext *); |
1227 | if (nxt == IPPROTO_AH) |
1228 | elen = (ip6e->ip6e_len + 2) << 2; |
1229 | else |
1230 | elen = (ip6e->ip6e_len + 1) << 3; |
1231 | if (elen != ext->m_len) { |
1232 | m_freem(ext); |
1233 | IP6_STATINC(IP6_STAT_TOOSHORT); |
1234 | return; |
1235 | } |
1236 | KASSERT(IP6_HDR_ALIGNED_P(ip6e)); |
1237 | |
1238 | switch (nxt) { |
1239 | case IPPROTO_DSTOPTS: |
1240 | if (!(in6p->in6p_flags & IN6P_DSTOPTS)) |
1241 | break; |
1242 | |
1243 | *mp = sbcreatecontrol((void *)ip6e, elen, |
1244 | IS2292(IPV6_2292DSTOPTS, IPV6_DSTOPTS), |
1245 | IPPROTO_IPV6); |
1246 | if (*mp) |
1247 | mp = &(*mp)->m_next; |
1248 | break; |
1249 | |
1250 | case IPPROTO_ROUTING: |
1251 | if (!(in6p->in6p_flags & IN6P_RTHDR)) |
1252 | break; |
1253 | |
1254 | *mp = sbcreatecontrol((void *)ip6e, elen, |
1255 | IS2292(IPV6_2292RTHDR, IPV6_RTHDR), |
1256 | IPPROTO_IPV6); |
1257 | if (*mp) |
1258 | mp = &(*mp)->m_next; |
1259 | break; |
1260 | |
1261 | case IPPROTO_HOPOPTS: |
1262 | case IPPROTO_AH: /* is it possible? */ |
1263 | break; |
1264 | |
1265 | default: |
1266 | /* |
1267 | * other cases have been filtered in the above. |
1268 | * none will visit this case. here we supply |
1269 | * the code just in case (nxt overwritten or |
1270 | * other cases). |
1271 | */ |
1272 | m_freem(ext); |
1273 | goto loopend; |
1274 | |
1275 | } |
1276 | |
1277 | /* proceed with the next header. */ |
1278 | off += elen; |
1279 | nxt = ip6e->ip6e_nxt; |
1280 | ip6e = NULL; |
1281 | m_freem(ext); |
1282 | ext = NULL; |
1283 | } |
1284 | loopend: |
1285 | ; |
1286 | } |
1287 | } |
1288 | #undef IS2292 |
1289 | |
1290 | |
1291 | void |
1292 | ip6_notify_pmtu(struct in6pcb *in6p, const struct sockaddr_in6 *dst, |
1293 | uint32_t *mtu) |
1294 | { |
1295 | struct socket *so; |
1296 | struct mbuf *m_mtu; |
1297 | struct ip6_mtuinfo mtuctl; |
1298 | |
1299 | so = in6p->in6p_socket; |
1300 | |
1301 | if (mtu == NULL) |
1302 | return; |
1303 | |
1304 | #ifdef DIAGNOSTIC |
1305 | if (so == NULL) /* I believe this is impossible */ |
1306 | panic("ip6_notify_pmtu: socket is NULL" ); |
1307 | #endif |
1308 | |
1309 | memset(&mtuctl, 0, sizeof(mtuctl)); /* zero-clear for safety */ |
1310 | mtuctl.ip6m_mtu = *mtu; |
1311 | mtuctl.ip6m_addr = *dst; |
1312 | if (sa6_recoverscope(&mtuctl.ip6m_addr)) |
1313 | return; |
1314 | |
1315 | if ((m_mtu = sbcreatecontrol((void *)&mtuctl, sizeof(mtuctl), |
1316 | IPV6_PATHMTU, IPPROTO_IPV6)) == NULL) |
1317 | return; |
1318 | |
1319 | if (sbappendaddr(&so->so_rcv, (const struct sockaddr *)dst, NULL, m_mtu) |
1320 | == 0) { |
1321 | m_freem(m_mtu); |
1322 | /* XXX: should count statistics */ |
1323 | } else |
1324 | sorwakeup(so); |
1325 | |
1326 | return; |
1327 | } |
1328 | |
1329 | /* |
1330 | * pull single extension header from mbuf chain. returns single mbuf that |
1331 | * contains the result, or NULL on error. |
1332 | */ |
1333 | static struct mbuf * |
1334 | ip6_pullexthdr(struct mbuf *m, size_t off, int nxt) |
1335 | { |
1336 | struct ip6_ext ip6e; |
1337 | size_t elen; |
1338 | struct mbuf *n; |
1339 | |
1340 | #ifdef DIAGNOSTIC |
1341 | switch (nxt) { |
1342 | case IPPROTO_DSTOPTS: |
1343 | case IPPROTO_ROUTING: |
1344 | case IPPROTO_HOPOPTS: |
1345 | case IPPROTO_AH: /* is it possible? */ |
1346 | break; |
1347 | default: |
1348 | printf("ip6_pullexthdr: invalid nxt=%d\n" , nxt); |
1349 | } |
1350 | #endif |
1351 | |
1352 | m_copydata(m, off, sizeof(ip6e), (void *)&ip6e); |
1353 | if (nxt == IPPROTO_AH) |
1354 | elen = (ip6e.ip6e_len + 2) << 2; |
1355 | else |
1356 | elen = (ip6e.ip6e_len + 1) << 3; |
1357 | |
1358 | MGET(n, M_DONTWAIT, MT_DATA); |
1359 | if (n && elen >= MLEN) { |
1360 | MCLGET(n, M_DONTWAIT); |
1361 | if ((n->m_flags & M_EXT) == 0) { |
1362 | m_free(n); |
1363 | n = NULL; |
1364 | } |
1365 | } |
1366 | if (!n) |
1367 | return NULL; |
1368 | |
1369 | n->m_len = 0; |
1370 | if (elen >= M_TRAILINGSPACE(n)) { |
1371 | m_free(n); |
1372 | return NULL; |
1373 | } |
1374 | |
1375 | m_copydata(m, off, elen, mtod(n, void *)); |
1376 | n->m_len = elen; |
1377 | return n; |
1378 | } |
1379 | |
1380 | /* |
1381 | * Get pointer to the previous header followed by the header |
1382 | * currently processed. |
1383 | * XXX: This function supposes that |
1384 | * M includes all headers, |
1385 | * the next header field and the header length field of each header |
1386 | * are valid, and |
1387 | * the sum of each header length equals to OFF. |
1388 | * Because of these assumptions, this function must be called very |
1389 | * carefully. Moreover, it will not be used in the near future when |
1390 | * we develop `neater' mechanism to process extension headers. |
1391 | */ |
1392 | u_int8_t * |
1393 | ip6_get_prevhdr(struct mbuf *m, int off) |
1394 | { |
1395 | struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); |
1396 | |
1397 | if (off == sizeof(struct ip6_hdr)) |
1398 | return (&ip6->ip6_nxt); |
1399 | else { |
1400 | int len, nxt; |
1401 | struct ip6_ext *ip6e = NULL; |
1402 | |
1403 | nxt = ip6->ip6_nxt; |
1404 | len = sizeof(struct ip6_hdr); |
1405 | while (len < off) { |
1406 | ip6e = (struct ip6_ext *)(mtod(m, char *) + len); |
1407 | |
1408 | switch (nxt) { |
1409 | case IPPROTO_FRAGMENT: |
1410 | len += sizeof(struct ip6_frag); |
1411 | break; |
1412 | case IPPROTO_AH: |
1413 | len += (ip6e->ip6e_len + 2) << 2; |
1414 | break; |
1415 | default: |
1416 | len += (ip6e->ip6e_len + 1) << 3; |
1417 | break; |
1418 | } |
1419 | nxt = ip6e->ip6e_nxt; |
1420 | } |
1421 | if (ip6e) |
1422 | return (&ip6e->ip6e_nxt); |
1423 | else |
1424 | return NULL; |
1425 | } |
1426 | } |
1427 | |
1428 | /* |
1429 | * get next header offset. m will be retained. |
1430 | */ |
1431 | int |
1432 | ip6_nexthdr(struct mbuf *m, int off, int proto, int *nxtp) |
1433 | { |
1434 | struct ip6_hdr ip6; |
1435 | struct ip6_ext ip6e; |
1436 | struct ip6_frag fh; |
1437 | |
1438 | /* just in case */ |
1439 | if (m == NULL) |
1440 | panic("ip6_nexthdr: m == NULL" ); |
1441 | if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len < off) |
1442 | return -1; |
1443 | |
1444 | switch (proto) { |
1445 | case IPPROTO_IPV6: |
1446 | /* do not chase beyond intermediate IPv6 headers */ |
1447 | if (off != 0) |
1448 | return -1; |
1449 | if (m->m_pkthdr.len < off + sizeof(ip6)) |
1450 | return -1; |
1451 | m_copydata(m, off, sizeof(ip6), (void *)&ip6); |
1452 | if (nxtp) |
1453 | *nxtp = ip6.ip6_nxt; |
1454 | off += sizeof(ip6); |
1455 | return off; |
1456 | |
1457 | case IPPROTO_FRAGMENT: |
1458 | /* |
1459 | * terminate parsing if it is not the first fragment, |
1460 | * it does not make sense to parse through it. |
1461 | */ |
1462 | if (m->m_pkthdr.len < off + sizeof(fh)) |
1463 | return -1; |
1464 | m_copydata(m, off, sizeof(fh), (void *)&fh); |
1465 | if ((fh.ip6f_offlg & IP6F_OFF_MASK) != 0) |
1466 | return -1; |
1467 | if (nxtp) |
1468 | *nxtp = fh.ip6f_nxt; |
1469 | off += sizeof(struct ip6_frag); |
1470 | return off; |
1471 | |
1472 | case IPPROTO_AH: |
1473 | if (m->m_pkthdr.len < off + sizeof(ip6e)) |
1474 | return -1; |
1475 | m_copydata(m, off, sizeof(ip6e), (void *)&ip6e); |
1476 | if (nxtp) |
1477 | *nxtp = ip6e.ip6e_nxt; |
1478 | off += (ip6e.ip6e_len + 2) << 2; |
1479 | if (m->m_pkthdr.len < off) |
1480 | return -1; |
1481 | return off; |
1482 | |
1483 | case IPPROTO_HOPOPTS: |
1484 | case IPPROTO_ROUTING: |
1485 | case IPPROTO_DSTOPTS: |
1486 | if (m->m_pkthdr.len < off + sizeof(ip6e)) |
1487 | return -1; |
1488 | m_copydata(m, off, sizeof(ip6e), (void *)&ip6e); |
1489 | if (nxtp) |
1490 | *nxtp = ip6e.ip6e_nxt; |
1491 | off += (ip6e.ip6e_len + 1) << 3; |
1492 | if (m->m_pkthdr.len < off) |
1493 | return -1; |
1494 | return off; |
1495 | |
1496 | case IPPROTO_NONE: |
1497 | case IPPROTO_ESP: |
1498 | case IPPROTO_IPCOMP: |
1499 | /* give up */ |
1500 | return -1; |
1501 | |
1502 | default: |
1503 | return -1; |
1504 | } |
1505 | } |
1506 | |
1507 | /* |
1508 | * get offset for the last header in the chain. m will be kept untainted. |
1509 | */ |
1510 | int |
1511 | ip6_lasthdr(struct mbuf *m, int off, int proto, int *nxtp) |
1512 | { |
1513 | int newoff; |
1514 | int nxt; |
1515 | |
1516 | if (!nxtp) { |
1517 | nxt = -1; |
1518 | nxtp = &nxt; |
1519 | } |
1520 | for (;;) { |
1521 | newoff = ip6_nexthdr(m, off, proto, nxtp); |
1522 | if (newoff < 0) |
1523 | return off; |
1524 | else if (newoff < off) |
1525 | return -1; /* invalid */ |
1526 | else if (newoff == off) |
1527 | return newoff; |
1528 | |
1529 | off = newoff; |
1530 | proto = *nxtp; |
1531 | } |
1532 | } |
1533 | |
1534 | struct m_tag * |
1535 | ip6_addaux(struct mbuf *m) |
1536 | { |
1537 | struct m_tag *mtag; |
1538 | |
1539 | mtag = m_tag_find(m, PACKET_TAG_INET6, NULL); |
1540 | if (!mtag) { |
1541 | mtag = m_tag_get(PACKET_TAG_INET6, sizeof(struct ip6aux), |
1542 | M_NOWAIT); |
1543 | if (mtag) { |
1544 | m_tag_prepend(m, mtag); |
1545 | memset(mtag + 1, 0, sizeof(struct ip6aux)); |
1546 | } |
1547 | } |
1548 | return mtag; |
1549 | } |
1550 | |
1551 | struct m_tag * |
1552 | ip6_findaux(struct mbuf *m) |
1553 | { |
1554 | struct m_tag *mtag; |
1555 | |
1556 | mtag = m_tag_find(m, PACKET_TAG_INET6, NULL); |
1557 | return mtag; |
1558 | } |
1559 | |
1560 | void |
1561 | ip6_delaux(struct mbuf *m) |
1562 | { |
1563 | struct m_tag *mtag; |
1564 | |
1565 | mtag = m_tag_find(m, PACKET_TAG_INET6, NULL); |
1566 | if (mtag) |
1567 | m_tag_delete(m, mtag); |
1568 | } |
1569 | |
1570 | /* |
1571 | * System control for IP6 |
1572 | */ |
1573 | |
1574 | const u_char inet6ctlerrmap[PRC_NCMDS] = { |
1575 | 0, 0, 0, 0, |
1576 | 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH, |
1577 | EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED, |
1578 | EMSGSIZE, EHOSTUNREACH, 0, 0, |
1579 | 0, 0, 0, 0, |
1580 | ENOPROTOOPT |
1581 | }; |
1582 | |
1583 | extern int sysctl_net_inet6_addrctlpolicy(SYSCTLFN_ARGS); |
1584 | |
1585 | static int |
1586 | sysctl_net_inet6_ip6_stats(SYSCTLFN_ARGS) |
1587 | { |
1588 | |
1589 | return (NETSTAT_SYSCTL(ip6stat_percpu, IP6_NSTATS)); |
1590 | } |
1591 | |
1592 | static void |
1593 | sysctl_net_inet6_ip6_setup(struct sysctllog **clog) |
1594 | { |
1595 | #ifdef RFC2292 |
1596 | #define IS2292(x, y) ((in6p->in6p_flags & IN6P_RFC2292) ? (x) : (y)) |
1597 | #else |
1598 | #define IS2292(x, y) (y) |
1599 | #endif |
1600 | |
1601 | sysctl_createv(clog, 0, NULL, NULL, |
1602 | CTLFLAG_PERMANENT, |
1603 | CTLTYPE_NODE, "inet6" , |
1604 | SYSCTL_DESCR("PF_INET6 related settings" ), |
1605 | NULL, 0, NULL, 0, |
1606 | CTL_NET, PF_INET6, CTL_EOL); |
1607 | sysctl_createv(clog, 0, NULL, NULL, |
1608 | CTLFLAG_PERMANENT, |
1609 | CTLTYPE_NODE, "ip6" , |
1610 | SYSCTL_DESCR("IPv6 related settings" ), |
1611 | NULL, 0, NULL, 0, |
1612 | CTL_NET, PF_INET6, IPPROTO_IPV6, CTL_EOL); |
1613 | |
1614 | sysctl_createv(clog, 0, NULL, NULL, |
1615 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1616 | CTLTYPE_INT, "forwarding" , |
1617 | SYSCTL_DESCR("Enable forwarding of INET6 datagrams" ), |
1618 | NULL, 0, &ip6_forwarding, 0, |
1619 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1620 | IPV6CTL_FORWARDING, CTL_EOL); |
1621 | sysctl_createv(clog, 0, NULL, NULL, |
1622 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1623 | CTLTYPE_INT, "redirect" , |
1624 | SYSCTL_DESCR("Enable sending of ICMPv6 redirect messages" ), |
1625 | NULL, 0, &ip6_sendredirects, 0, |
1626 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1627 | IPV6CTL_SENDREDIRECTS, CTL_EOL); |
1628 | sysctl_createv(clog, 0, NULL, NULL, |
1629 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1630 | CTLTYPE_INT, "hlim" , |
1631 | SYSCTL_DESCR("Hop limit for an INET6 datagram" ), |
1632 | NULL, 0, &ip6_defhlim, 0, |
1633 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1634 | IPV6CTL_DEFHLIM, CTL_EOL); |
1635 | #ifdef notyet |
1636 | sysctl_createv(clog, 0, NULL, NULL, |
1637 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1638 | CTLTYPE_INT, "mtu" , NULL, |
1639 | NULL, 0, &, 0, |
1640 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1641 | IPV6CTL_DEFMTU, CTL_EOL); |
1642 | #endif |
1643 | #ifdef __no_idea__ |
1644 | sysctl_createv(clog, 0, NULL, NULL, |
1645 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1646 | CTLTYPE_INT, "forwsrcrt" , NULL, |
1647 | NULL, 0, &?, 0, |
1648 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1649 | IPV6CTL_FORWSRCRT, CTL_EOL); |
1650 | sysctl_createv(clog, 0, NULL, NULL, |
1651 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1652 | CTLTYPE_STRUCT, "mrtstats" , NULL, |
1653 | NULL, 0, &?, sizeof(?), |
1654 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1655 | IPV6CTL_MRTSTATS, CTL_EOL); |
1656 | sysctl_createv(clog, 0, NULL, NULL, |
1657 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1658 | CTLTYPE_?, "mrtproto" , NULL, |
1659 | NULL, 0, &?, sizeof(?), |
1660 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1661 | IPV6CTL_MRTPROTO, CTL_EOL); |
1662 | #endif |
1663 | sysctl_createv(clog, 0, NULL, NULL, |
1664 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1665 | CTLTYPE_INT, "maxfragpackets" , |
1666 | SYSCTL_DESCR("Maximum number of fragments to buffer " |
1667 | "for reassembly" ), |
1668 | NULL, 0, &ip6_maxfragpackets, 0, |
1669 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1670 | IPV6CTL_MAXFRAGPACKETS, CTL_EOL); |
1671 | #ifdef __no_idea__ |
1672 | sysctl_createv(clog, 0, NULL, NULL, |
1673 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1674 | CTLTYPE_INT, "sourcecheck" , NULL, |
1675 | NULL, 0, &?, 0, |
1676 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1677 | IPV6CTL_SOURCECHECK, CTL_EOL); |
1678 | sysctl_createv(clog, 0, NULL, NULL, |
1679 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1680 | CTLTYPE_INT, "sourcecheck_logint" , NULL, |
1681 | NULL, 0, &?, 0, |
1682 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1683 | IPV6CTL_SOURCECHECK_LOGINT, CTL_EOL); |
1684 | #endif |
1685 | sysctl_createv(clog, 0, NULL, NULL, |
1686 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1687 | CTLTYPE_INT, "accept_rtadv" , |
1688 | SYSCTL_DESCR("Accept router advertisements" ), |
1689 | NULL, 0, &ip6_accept_rtadv, 0, |
1690 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1691 | IPV6CTL_ACCEPT_RTADV, CTL_EOL); |
1692 | sysctl_createv(clog, 0, NULL, NULL, |
1693 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1694 | CTLTYPE_INT, "rtadv_maxroutes" , |
1695 | SYSCTL_DESCR("Maximum number of routes accepted via router advertisements" ), |
1696 | NULL, 0, &ip6_rtadv_maxroutes, 0, |
1697 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1698 | IPV6CTL_RTADV_MAXROUTES, CTL_EOL); |
1699 | sysctl_createv(clog, 0, NULL, NULL, |
1700 | CTLFLAG_PERMANENT, |
1701 | CTLTYPE_INT, "rtadv_numroutes" , |
1702 | SYSCTL_DESCR("Current number of routes accepted via router advertisements" ), |
1703 | NULL, 0, &nd6_numroutes, 0, |
1704 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1705 | IPV6CTL_RTADV_NUMROUTES, CTL_EOL); |
1706 | sysctl_createv(clog, 0, NULL, NULL, |
1707 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1708 | CTLTYPE_INT, "keepfaith" , |
1709 | SYSCTL_DESCR("Activate faith interface" ), |
1710 | NULL, 0, &ip6_keepfaith, 0, |
1711 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1712 | IPV6CTL_KEEPFAITH, CTL_EOL); |
1713 | sysctl_createv(clog, 0, NULL, NULL, |
1714 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1715 | CTLTYPE_INT, "log_interval" , |
1716 | SYSCTL_DESCR("Minumum interval between logging " |
1717 | "unroutable packets" ), |
1718 | NULL, 0, &ip6_log_interval, 0, |
1719 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1720 | IPV6CTL_LOG_INTERVAL, CTL_EOL); |
1721 | sysctl_createv(clog, 0, NULL, NULL, |
1722 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1723 | CTLTYPE_INT, "hdrnestlimit" , |
1724 | SYSCTL_DESCR("Maximum number of nested IPv6 headers" ), |
1725 | NULL, 0, &ip6_hdrnestlimit, 0, |
1726 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1727 | IPV6CTL_HDRNESTLIMIT, CTL_EOL); |
1728 | sysctl_createv(clog, 0, NULL, NULL, |
1729 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1730 | CTLTYPE_INT, "dad_count" , |
1731 | SYSCTL_DESCR("Number of Duplicate Address Detection " |
1732 | "probes to send" ), |
1733 | NULL, 0, &ip6_dad_count, 0, |
1734 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1735 | IPV6CTL_DAD_COUNT, CTL_EOL); |
1736 | sysctl_createv(clog, 0, NULL, NULL, |
1737 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1738 | CTLTYPE_INT, "auto_flowlabel" , |
1739 | SYSCTL_DESCR("Assign random IPv6 flow labels" ), |
1740 | NULL, 0, &ip6_auto_flowlabel, 0, |
1741 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1742 | IPV6CTL_AUTO_FLOWLABEL, CTL_EOL); |
1743 | sysctl_createv(clog, 0, NULL, NULL, |
1744 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1745 | CTLTYPE_INT, "defmcasthlim" , |
1746 | SYSCTL_DESCR("Default multicast hop limit" ), |
1747 | NULL, 0, &ip6_defmcasthlim, 0, |
1748 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1749 | IPV6CTL_DEFMCASTHLIM, CTL_EOL); |
1750 | sysctl_createv(clog, 0, NULL, NULL, |
1751 | CTLFLAG_PERMANENT, |
1752 | CTLTYPE_STRING, "kame_version" , |
1753 | SYSCTL_DESCR("KAME Version" ), |
1754 | NULL, 0, __UNCONST(__KAME_VERSION), 0, |
1755 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1756 | IPV6CTL_KAME_VERSION, CTL_EOL); |
1757 | sysctl_createv(clog, 0, NULL, NULL, |
1758 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1759 | CTLTYPE_INT, "use_deprecated" , |
1760 | SYSCTL_DESCR("Allow use of deprecated addresses as " |
1761 | "source addresses" ), |
1762 | NULL, 0, &ip6_use_deprecated, 0, |
1763 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1764 | IPV6CTL_USE_DEPRECATED, CTL_EOL); |
1765 | sysctl_createv(clog, 0, NULL, NULL, |
1766 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1767 | CTLTYPE_INT, "rr_prune" , NULL, |
1768 | NULL, 0, &ip6_rr_prune, 0, |
1769 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1770 | IPV6CTL_RR_PRUNE, CTL_EOL); |
1771 | sysctl_createv(clog, 0, NULL, NULL, |
1772 | CTLFLAG_PERMANENT |
1773 | #ifndef INET6_BINDV6ONLY |
1774 | |CTLFLAG_READWRITE, |
1775 | #endif |
1776 | CTLTYPE_INT, "v6only" , |
1777 | SYSCTL_DESCR("Disallow PF_INET6 sockets from connecting " |
1778 | "to PF_INET sockets" ), |
1779 | NULL, 0, &ip6_v6only, 0, |
1780 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1781 | IPV6CTL_V6ONLY, CTL_EOL); |
1782 | sysctl_createv(clog, 0, NULL, NULL, |
1783 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1784 | CTLTYPE_INT, "anonportmin" , |
1785 | SYSCTL_DESCR("Lowest ephemeral port number to assign" ), |
1786 | sysctl_net_inet_ip_ports, 0, &ip6_anonportmin, 0, |
1787 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1788 | IPV6CTL_ANONPORTMIN, CTL_EOL); |
1789 | sysctl_createv(clog, 0, NULL, NULL, |
1790 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1791 | CTLTYPE_INT, "anonportmax" , |
1792 | SYSCTL_DESCR("Highest ephemeral port number to assign" ), |
1793 | sysctl_net_inet_ip_ports, 0, &ip6_anonportmax, 0, |
1794 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1795 | IPV6CTL_ANONPORTMAX, CTL_EOL); |
1796 | #ifndef IPNOPRIVPORTS |
1797 | sysctl_createv(clog, 0, NULL, NULL, |
1798 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1799 | CTLTYPE_INT, "lowportmin" , |
1800 | SYSCTL_DESCR("Lowest privileged ephemeral port number " |
1801 | "to assign" ), |
1802 | sysctl_net_inet_ip_ports, 0, &ip6_lowportmin, 0, |
1803 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1804 | IPV6CTL_LOWPORTMIN, CTL_EOL); |
1805 | sysctl_createv(clog, 0, NULL, NULL, |
1806 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1807 | CTLTYPE_INT, "lowportmax" , |
1808 | SYSCTL_DESCR("Highest privileged ephemeral port number " |
1809 | "to assign" ), |
1810 | sysctl_net_inet_ip_ports, 0, &ip6_lowportmax, 0, |
1811 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1812 | IPV6CTL_LOWPORTMAX, CTL_EOL); |
1813 | #endif /* IPNOPRIVPORTS */ |
1814 | sysctl_createv(clog, 0, NULL, NULL, |
1815 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1816 | CTLTYPE_INT, "auto_linklocal" , |
1817 | SYSCTL_DESCR("Default value of per-interface flag for " |
1818 | "adding an IPv6 link-local address to " |
1819 | "interfaces when attached" ), |
1820 | NULL, 0, &ip6_auto_linklocal, 0, |
1821 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1822 | IPV6CTL_AUTO_LINKLOCAL, CTL_EOL); |
1823 | sysctl_createv(clog, 0, NULL, NULL, |
1824 | CTLFLAG_PERMANENT|CTLFLAG_READONLY, |
1825 | CTLTYPE_STRUCT, "addctlpolicy" , |
1826 | SYSCTL_DESCR("Return the current address control" |
1827 | " policy" ), |
1828 | sysctl_net_inet6_addrctlpolicy, 0, NULL, 0, |
1829 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1830 | IPV6CTL_ADDRCTLPOLICY, CTL_EOL); |
1831 | sysctl_createv(clog, 0, NULL, NULL, |
1832 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1833 | CTLTYPE_INT, "use_tempaddr" , |
1834 | SYSCTL_DESCR("Use temporary address" ), |
1835 | NULL, 0, &ip6_use_tempaddr, 0, |
1836 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1837 | CTL_CREATE, CTL_EOL); |
1838 | sysctl_createv(clog, 0, NULL, NULL, |
1839 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1840 | CTLTYPE_INT, "prefer_tempaddr" , |
1841 | SYSCTL_DESCR("Prefer temporary address as source " |
1842 | "address" ), |
1843 | NULL, 0, &ip6_prefer_tempaddr, 0, |
1844 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1845 | CTL_CREATE, CTL_EOL); |
1846 | sysctl_createv(clog, 0, NULL, NULL, |
1847 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1848 | CTLTYPE_INT, "temppltime" , |
1849 | SYSCTL_DESCR("preferred lifetime of a temporary address" ), |
1850 | NULL, 0, &ip6_temp_preferred_lifetime, 0, |
1851 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1852 | CTL_CREATE, CTL_EOL); |
1853 | sysctl_createv(clog, 0, NULL, NULL, |
1854 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1855 | CTLTYPE_INT, "tempvltime" , |
1856 | SYSCTL_DESCR("valid lifetime of a temporary address" ), |
1857 | NULL, 0, &ip6_temp_valid_lifetime, 0, |
1858 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1859 | CTL_CREATE, CTL_EOL); |
1860 | sysctl_createv(clog, 0, NULL, NULL, |
1861 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1862 | CTLTYPE_INT, "maxfrags" , |
1863 | SYSCTL_DESCR("Maximum fragments in reassembly queue" ), |
1864 | NULL, 0, &ip6_maxfrags, 0, |
1865 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1866 | IPV6CTL_MAXFRAGS, CTL_EOL); |
1867 | sysctl_createv(clog, 0, NULL, NULL, |
1868 | CTLFLAG_PERMANENT, |
1869 | CTLTYPE_STRUCT, "stats" , |
1870 | SYSCTL_DESCR("IPv6 statistics" ), |
1871 | sysctl_net_inet6_ip6_stats, 0, NULL, 0, |
1872 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1873 | IPV6CTL_STATS, CTL_EOL); |
1874 | sysctl_createv(clog, 0, NULL, NULL, |
1875 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1876 | CTLTYPE_INT, "use_defaultzone" , |
1877 | SYSCTL_DESCR("Whether to use the default scope zones" ), |
1878 | NULL, 0, &ip6_use_defzone, 0, |
1879 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1880 | IPV6CTL_USE_DEFAULTZONE, CTL_EOL); |
1881 | sysctl_createv(clog, 0, NULL, NULL, |
1882 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1883 | CTLTYPE_INT, "mcast_pmtu" , |
1884 | SYSCTL_DESCR("Enable pMTU discovery for multicast packet" ), |
1885 | NULL, 0, &ip6_mcast_pmtu, 0, |
1886 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1887 | CTL_CREATE, CTL_EOL); |
1888 | /* anonportalgo RFC6056 subtree */ |
1889 | const struct sysctlnode *portalgo_node; |
1890 | sysctl_createv(clog, 0, NULL, &portalgo_node, |
1891 | CTLFLAG_PERMANENT, |
1892 | CTLTYPE_NODE, "anonportalgo" , |
1893 | SYSCTL_DESCR("Anonymous port algorithm selection (RFC 6056)" ), |
1894 | NULL, 0, NULL, 0, |
1895 | CTL_NET, PF_INET6, IPPROTO_IPV6, CTL_CREATE, CTL_EOL); |
1896 | sysctl_createv(clog, 0, &portalgo_node, NULL, |
1897 | CTLFLAG_PERMANENT, |
1898 | CTLTYPE_STRING, "available" , |
1899 | SYSCTL_DESCR("available algorithms" ), |
1900 | sysctl_portalgo_available, 0, NULL, PORTALGO_MAXLEN, |
1901 | CTL_CREATE, CTL_EOL); |
1902 | sysctl_createv(clog, 0, &portalgo_node, NULL, |
1903 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1904 | CTLTYPE_STRING, "selected" , |
1905 | SYSCTL_DESCR("selected algorithm" ), |
1906 | sysctl_portalgo_selected6, 0, NULL, PORTALGO_MAXLEN, |
1907 | CTL_CREATE, CTL_EOL); |
1908 | sysctl_createv(clog, 0, &portalgo_node, NULL, |
1909 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1910 | CTLTYPE_STRUCT, "reserve" , |
1911 | SYSCTL_DESCR("bitmap of reserved ports" ), |
1912 | sysctl_portalgo_reserve6, 0, NULL, 0, |
1913 | CTL_CREATE, CTL_EOL); |
1914 | sysctl_createv(clog, 0, NULL, NULL, |
1915 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1916 | CTLTYPE_INT, "neighborgcthresh" , |
1917 | SYSCTL_DESCR("Maximum number of entries in neighbor" |
1918 | " cache" ), |
1919 | NULL, 1, &ip6_neighborgcthresh, 0, |
1920 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1921 | CTL_CREATE, CTL_EOL); |
1922 | sysctl_createv(clog, 0, NULL, NULL, |
1923 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1924 | CTLTYPE_INT, "maxifprefixes" , |
1925 | SYSCTL_DESCR("Maximum number of prefixes created by" |
1926 | " route advertisement per interface" ), |
1927 | NULL, 1, &ip6_maxifprefixes, 0, |
1928 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1929 | CTL_CREATE, CTL_EOL); |
1930 | sysctl_createv(clog, 0, NULL, NULL, |
1931 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1932 | CTLTYPE_INT, "maxifdefrouters" , |
1933 | SYSCTL_DESCR("Maximum number of default routers created" |
1934 | " by route advertisement per interface" ), |
1935 | NULL, 1, &ip6_maxifdefrouters, 0, |
1936 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1937 | CTL_CREATE, CTL_EOL); |
1938 | sysctl_createv(clog, 0, NULL, NULL, |
1939 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1940 | CTLTYPE_INT, "maxdynroutes" , |
1941 | SYSCTL_DESCR("Maximum number of routes created via" |
1942 | " redirect" ), |
1943 | NULL, 1, &ip6_maxdynroutes, 0, |
1944 | CTL_NET, PF_INET6, IPPROTO_IPV6, |
1945 | CTL_CREATE, CTL_EOL); |
1946 | } |
1947 | |
1948 | void |
1949 | ip6_statinc(u_int stat) |
1950 | { |
1951 | |
1952 | KASSERT(stat < IP6_NSTATS); |
1953 | IP6_STATINC(stat); |
1954 | } |
1955 | |