1 | /* $NetBSD: nd6.c,v 1.211 2016/11/14 02:34:19 ozaki-r Exp $ */ |
2 | /* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 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 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.211 2016/11/14 02:34:19 ozaki-r Exp $" ); |
35 | |
36 | #ifdef _KERNEL_OPT |
37 | #include "opt_net_mpsafe.h" |
38 | #endif |
39 | |
40 | #include "bridge.h" |
41 | #include "carp.h" |
42 | |
43 | #include <sys/param.h> |
44 | #include <sys/systm.h> |
45 | #include <sys/callout.h> |
46 | #include <sys/malloc.h> |
47 | #include <sys/mbuf.h> |
48 | #include <sys/socket.h> |
49 | #include <sys/socketvar.h> |
50 | #include <sys/sockio.h> |
51 | #include <sys/time.h> |
52 | #include <sys/kernel.h> |
53 | #include <sys/protosw.h> |
54 | #include <sys/errno.h> |
55 | #include <sys/ioctl.h> |
56 | #include <sys/syslog.h> |
57 | #include <sys/queue.h> |
58 | #include <sys/cprng.h> |
59 | #include <sys/workqueue.h> |
60 | |
61 | #include <net/if.h> |
62 | #include <net/if_dl.h> |
63 | #include <net/if_llatbl.h> |
64 | #include <net/if_types.h> |
65 | #include <net/route.h> |
66 | #include <net/if_ether.h> |
67 | #include <net/if_fddi.h> |
68 | #include <net/if_arc.h> |
69 | |
70 | #include <netinet/in.h> |
71 | #include <netinet6/in6_var.h> |
72 | #include <netinet/ip6.h> |
73 | #include <netinet6/ip6_var.h> |
74 | #include <netinet6/scope6_var.h> |
75 | #include <netinet6/nd6.h> |
76 | #include <netinet6/in6_ifattach.h> |
77 | #include <netinet/icmp6.h> |
78 | #include <netinet6/icmp6_private.h> |
79 | |
80 | #include <net/net_osdep.h> |
81 | |
82 | #define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */ |
83 | #define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */ |
84 | |
85 | /* timer values */ |
86 | int nd6_prune = 1; /* walk list every 1 seconds */ |
87 | int nd6_delay = 5; /* delay first probe time 5 second */ |
88 | int nd6_umaxtries = 3; /* maximum unicast query */ |
89 | int nd6_mmaxtries = 3; /* maximum multicast query */ |
90 | int nd6_useloopback = 1; /* use loopback interface for local traffic */ |
91 | int nd6_gctimer = (60 * 60 * 24); /* 1 day: garbage collection timer */ |
92 | |
93 | /* preventing too many loops in ND option parsing */ |
94 | int nd6_maxndopt = 10; /* max # of ND options allowed */ |
95 | |
96 | int nd6_maxnudhint = 0; /* max # of subsequent upper layer hints */ |
97 | |
98 | int nd6_maxqueuelen = 1; /* max # of packets cached in unresolved ND entries */ |
99 | |
100 | #ifdef ND6_DEBUG |
101 | int nd6_debug = 1; |
102 | #else |
103 | int nd6_debug = 0; |
104 | #endif |
105 | |
106 | struct nd_drhead nd_defrouter; |
107 | struct nd_prhead nd_prefix = { 0 }; |
108 | |
109 | int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL; |
110 | |
111 | static void nd6_setmtu0(struct ifnet *, struct nd_ifinfo *); |
112 | static void nd6_slowtimo(void *); |
113 | static int regen_tmpaddr(const struct in6_ifaddr *); |
114 | static void nd6_free(struct llentry *, int); |
115 | static void nd6_llinfo_timer(void *); |
116 | static void nd6_timer(void *); |
117 | static void nd6_timer_work(struct work *, void *); |
118 | static void clear_llinfo_pqueue(struct llentry *); |
119 | |
120 | static callout_t nd6_slowtimo_ch; |
121 | static callout_t nd6_timer_ch; |
122 | static struct workqueue *nd6_timer_wq; |
123 | static struct work nd6_timer_wk; |
124 | |
125 | static int fill_drlist(void *, size_t *, size_t); |
126 | static int fill_prlist(void *, size_t *, size_t); |
127 | |
128 | MALLOC_DEFINE(M_IP6NDP, "NDP" , "IPv6 Neighbour Discovery" ); |
129 | |
130 | void |
131 | nd6_init(void) |
132 | { |
133 | int error; |
134 | |
135 | /* initialization of the default router list */ |
136 | TAILQ_INIT(&nd_defrouter); |
137 | |
138 | callout_init(&nd6_slowtimo_ch, CALLOUT_MPSAFE); |
139 | callout_init(&nd6_timer_ch, CALLOUT_MPSAFE); |
140 | |
141 | error = workqueue_create(&nd6_timer_wq, "nd6_timer" , |
142 | nd6_timer_work, NULL, PRI_SOFTNET, IPL_SOFTNET, WQ_MPSAFE); |
143 | if (error) |
144 | panic("%s: workqueue_create failed (%d)\n" , __func__, error); |
145 | |
146 | /* start timer */ |
147 | callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, |
148 | nd6_slowtimo, NULL); |
149 | callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL); |
150 | } |
151 | |
152 | struct nd_ifinfo * |
153 | nd6_ifattach(struct ifnet *ifp) |
154 | { |
155 | struct nd_ifinfo *nd; |
156 | |
157 | nd = (struct nd_ifinfo *)malloc(sizeof(*nd), M_IP6NDP, M_WAITOK|M_ZERO); |
158 | |
159 | nd->initialized = 1; |
160 | |
161 | nd->chlim = IPV6_DEFHLIM; |
162 | nd->basereachable = REACHABLE_TIME; |
163 | nd->reachable = ND_COMPUTE_RTIME(nd->basereachable); |
164 | nd->retrans = RETRANS_TIMER; |
165 | |
166 | nd->flags = ND6_IFF_PERFORMNUD | ND6_IFF_ACCEPT_RTADV; |
167 | |
168 | /* A loopback interface always has ND6_IFF_AUTO_LINKLOCAL. |
169 | * A bridge interface should not have ND6_IFF_AUTO_LINKLOCAL |
170 | * because one of its members should. */ |
171 | if ((ip6_auto_linklocal && ifp->if_type != IFT_BRIDGE) || |
172 | (ifp->if_flags & IFF_LOOPBACK)) |
173 | nd->flags |= ND6_IFF_AUTO_LINKLOCAL; |
174 | |
175 | /* A loopback interface does not need to accept RTADV. |
176 | * A bridge interface should not accept RTADV |
177 | * because one of its members should. */ |
178 | if (ip6_accept_rtadv && |
179 | !(ifp->if_flags & IFF_LOOPBACK) && |
180 | !(ifp->if_type != IFT_BRIDGE)) |
181 | nd->flags |= ND6_IFF_ACCEPT_RTADV; |
182 | |
183 | /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */ |
184 | nd6_setmtu0(ifp, nd); |
185 | |
186 | return nd; |
187 | } |
188 | |
189 | void |
190 | nd6_ifdetach(struct ifnet *ifp, struct in6_ifextra *ext) |
191 | { |
192 | |
193 | nd6_purge(ifp, ext); |
194 | free(ext->nd_ifinfo, M_IP6NDP); |
195 | } |
196 | |
197 | void |
198 | nd6_setmtu(struct ifnet *ifp) |
199 | { |
200 | nd6_setmtu0(ifp, ND_IFINFO(ifp)); |
201 | } |
202 | |
203 | void |
204 | nd6_setmtu0(struct ifnet *ifp, struct nd_ifinfo *ndi) |
205 | { |
206 | u_int32_t omaxmtu; |
207 | |
208 | omaxmtu = ndi->maxmtu; |
209 | |
210 | switch (ifp->if_type) { |
211 | case IFT_ARCNET: |
212 | ndi->maxmtu = MIN(ARC_PHDS_MAXMTU, ifp->if_mtu); /* RFC2497 */ |
213 | break; |
214 | case IFT_FDDI: |
215 | ndi->maxmtu = MIN(FDDIIPMTU, ifp->if_mtu); |
216 | break; |
217 | default: |
218 | ndi->maxmtu = ifp->if_mtu; |
219 | break; |
220 | } |
221 | |
222 | /* |
223 | * Decreasing the interface MTU under IPV6 minimum MTU may cause |
224 | * undesirable situation. We thus notify the operator of the change |
225 | * explicitly. The check for omaxmtu is necessary to restrict the |
226 | * log to the case of changing the MTU, not initializing it. |
227 | */ |
228 | if (omaxmtu >= IPV6_MMTU && ndi->maxmtu < IPV6_MMTU) { |
229 | log(LOG_NOTICE, "nd6_setmtu0: new link MTU on %s (%lu) is too" |
230 | " small for IPv6 which needs %lu\n" , |
231 | if_name(ifp), (unsigned long)ndi->maxmtu, (unsigned long) |
232 | IPV6_MMTU); |
233 | } |
234 | |
235 | if (ndi->maxmtu > in6_maxmtu) |
236 | in6_setmaxmtu(); /* check all interfaces just in case */ |
237 | } |
238 | |
239 | void |
240 | nd6_option_init(void *opt, int icmp6len, union nd_opts *ndopts) |
241 | { |
242 | |
243 | memset(ndopts, 0, sizeof(*ndopts)); |
244 | ndopts->nd_opts_search = (struct nd_opt_hdr *)opt; |
245 | ndopts->nd_opts_last |
246 | = (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len); |
247 | |
248 | if (icmp6len == 0) { |
249 | ndopts->nd_opts_done = 1; |
250 | ndopts->nd_opts_search = NULL; |
251 | } |
252 | } |
253 | |
254 | /* |
255 | * Take one ND option. |
256 | */ |
257 | struct nd_opt_hdr * |
258 | nd6_option(union nd_opts *ndopts) |
259 | { |
260 | struct nd_opt_hdr *nd_opt; |
261 | int olen; |
262 | |
263 | KASSERT(ndopts != NULL); |
264 | KASSERT(ndopts->nd_opts_last != NULL); |
265 | |
266 | if (ndopts->nd_opts_search == NULL) |
267 | return NULL; |
268 | if (ndopts->nd_opts_done) |
269 | return NULL; |
270 | |
271 | nd_opt = ndopts->nd_opts_search; |
272 | |
273 | /* make sure nd_opt_len is inside the buffer */ |
274 | if ((void *)&nd_opt->nd_opt_len >= (void *)ndopts->nd_opts_last) { |
275 | memset(ndopts, 0, sizeof(*ndopts)); |
276 | return NULL; |
277 | } |
278 | |
279 | olen = nd_opt->nd_opt_len << 3; |
280 | if (olen == 0) { |
281 | /* |
282 | * Message validation requires that all included |
283 | * options have a length that is greater than zero. |
284 | */ |
285 | memset(ndopts, 0, sizeof(*ndopts)); |
286 | return NULL; |
287 | } |
288 | |
289 | ndopts->nd_opts_search = (struct nd_opt_hdr *)((char *)nd_opt + olen); |
290 | if (ndopts->nd_opts_search > ndopts->nd_opts_last) { |
291 | /* option overruns the end of buffer, invalid */ |
292 | memset(ndopts, 0, sizeof(*ndopts)); |
293 | return NULL; |
294 | } else if (ndopts->nd_opts_search == ndopts->nd_opts_last) { |
295 | /* reached the end of options chain */ |
296 | ndopts->nd_opts_done = 1; |
297 | ndopts->nd_opts_search = NULL; |
298 | } |
299 | return nd_opt; |
300 | } |
301 | |
302 | /* |
303 | * Parse multiple ND options. |
304 | * This function is much easier to use, for ND routines that do not need |
305 | * multiple options of the same type. |
306 | */ |
307 | int |
308 | nd6_options(union nd_opts *ndopts) |
309 | { |
310 | struct nd_opt_hdr *nd_opt; |
311 | int i = 0; |
312 | |
313 | KASSERT(ndopts != NULL); |
314 | KASSERT(ndopts->nd_opts_last != NULL); |
315 | |
316 | if (ndopts->nd_opts_search == NULL) |
317 | return 0; |
318 | |
319 | while (1) { |
320 | nd_opt = nd6_option(ndopts); |
321 | if (nd_opt == NULL && ndopts->nd_opts_last == NULL) { |
322 | /* |
323 | * Message validation requires that all included |
324 | * options have a length that is greater than zero. |
325 | */ |
326 | ICMP6_STATINC(ICMP6_STAT_ND_BADOPT); |
327 | memset(ndopts, 0, sizeof(*ndopts)); |
328 | return -1; |
329 | } |
330 | |
331 | if (nd_opt == NULL) |
332 | goto skip1; |
333 | |
334 | switch (nd_opt->nd_opt_type) { |
335 | case ND_OPT_SOURCE_LINKADDR: |
336 | case ND_OPT_TARGET_LINKADDR: |
337 | case ND_OPT_MTU: |
338 | case ND_OPT_REDIRECTED_HEADER: |
339 | if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) { |
340 | nd6log(LOG_INFO, |
341 | "duplicated ND6 option found (type=%d)\n" , |
342 | nd_opt->nd_opt_type); |
343 | /* XXX bark? */ |
344 | } else { |
345 | ndopts->nd_opt_array[nd_opt->nd_opt_type] |
346 | = nd_opt; |
347 | } |
348 | break; |
349 | case ND_OPT_PREFIX_INFORMATION: |
350 | if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) { |
351 | ndopts->nd_opt_array[nd_opt->nd_opt_type] |
352 | = nd_opt; |
353 | } |
354 | ndopts->nd_opts_pi_end = |
355 | (struct nd_opt_prefix_info *)nd_opt; |
356 | break; |
357 | default: |
358 | /* |
359 | * Unknown options must be silently ignored, |
360 | * to accommodate future extension to the protocol. |
361 | */ |
362 | nd6log(LOG_DEBUG, |
363 | "nd6_options: unsupported option %d - " |
364 | "option ignored\n" , nd_opt->nd_opt_type); |
365 | } |
366 | |
367 | skip1: |
368 | i++; |
369 | if (i > nd6_maxndopt) { |
370 | ICMP6_STATINC(ICMP6_STAT_ND_TOOMANYOPT); |
371 | nd6log(LOG_INFO, "too many loop in nd opt\n" ); |
372 | break; |
373 | } |
374 | |
375 | if (ndopts->nd_opts_done) |
376 | break; |
377 | } |
378 | |
379 | return 0; |
380 | } |
381 | |
382 | /* |
383 | * ND6 timer routine to handle ND6 entries |
384 | */ |
385 | void |
386 | nd6_llinfo_settimer(struct llentry *ln, time_t xtick) |
387 | { |
388 | |
389 | CTASSERT(sizeof(time_t) > sizeof(int)); |
390 | LLE_WLOCK_ASSERT(ln); |
391 | |
392 | if (xtick < 0) { |
393 | ln->ln_expire = 0; |
394 | ln->ln_ntick = 0; |
395 | callout_halt(&ln->ln_timer_ch, &ln->lle_lock); |
396 | } else { |
397 | ln->ln_expire = time_uptime + xtick / hz; |
398 | LLE_ADDREF(ln); |
399 | if (xtick > INT_MAX) { |
400 | ln->ln_ntick = xtick - INT_MAX; |
401 | callout_reset(&ln->ln_timer_ch, INT_MAX, |
402 | nd6_llinfo_timer, ln); |
403 | } else { |
404 | ln->ln_ntick = 0; |
405 | callout_reset(&ln->ln_timer_ch, xtick, |
406 | nd6_llinfo_timer, ln); |
407 | } |
408 | } |
409 | } |
410 | |
411 | /* |
412 | * Gets source address of the first packet in hold queue |
413 | * and stores it in @src. |
414 | * Returns pointer to @src (if hold queue is not empty) or NULL. |
415 | */ |
416 | static struct in6_addr * |
417 | nd6_llinfo_get_holdsrc(struct llentry *ln, struct in6_addr *src) |
418 | { |
419 | struct ip6_hdr *hip6; |
420 | |
421 | if (ln == NULL || ln->ln_hold == NULL) |
422 | return NULL; |
423 | |
424 | /* |
425 | * assuming every packet in ln_hold has the same IP header |
426 | */ |
427 | hip6 = mtod(ln->ln_hold, struct ip6_hdr *); |
428 | /* XXX pullup? */ |
429 | if (sizeof(*hip6) < ln->ln_hold->m_len) |
430 | *src = hip6->ip6_src; |
431 | else |
432 | src = NULL; |
433 | |
434 | return src; |
435 | } |
436 | |
437 | static void |
438 | nd6_llinfo_timer(void *arg) |
439 | { |
440 | struct llentry *ln = arg; |
441 | struct ifnet *ifp; |
442 | struct nd_ifinfo *ndi = NULL; |
443 | bool send_ns = false; |
444 | const struct in6_addr *daddr6 = NULL; |
445 | |
446 | #ifndef NET_MPSAFE |
447 | mutex_enter(softnet_lock); |
448 | KERNEL_LOCK(1, NULL); |
449 | #endif |
450 | |
451 | LLE_WLOCK(ln); |
452 | if (ln->ln_ntick > 0) { |
453 | nd6_llinfo_settimer(ln, ln->ln_ntick); |
454 | goto out; |
455 | } |
456 | |
457 | if (callout_pending(&ln->la_timer)) { |
458 | /* |
459 | * Here we are a bit odd here in the treatment of |
460 | * active/pending. If the pending bit is set, it got |
461 | * rescheduled before I ran. The active |
462 | * bit we ignore, since if it was stopped |
463 | * in ll_tablefree() and was currently running |
464 | * it would have return 0 so the code would |
465 | * not have deleted it since the callout could |
466 | * not be stopped so we want to go through |
467 | * with the delete here now. If the callout |
468 | * was restarted, the pending bit will be back on and |
469 | * we just want to bail since the callout_reset would |
470 | * return 1 and our reference would have been removed |
471 | * by nd6_llinfo_settimer above since canceled |
472 | * would have been 1. |
473 | */ |
474 | goto out; |
475 | } |
476 | |
477 | ifp = ln->lle_tbl->llt_ifp; |
478 | |
479 | KASSERT(ifp != NULL); |
480 | |
481 | ndi = ND_IFINFO(ifp); |
482 | |
483 | switch (ln->ln_state) { |
484 | case ND6_LLINFO_INCOMPLETE: |
485 | if (ln->ln_asked < nd6_mmaxtries) { |
486 | ln->ln_asked++; |
487 | send_ns = true; |
488 | } else { |
489 | struct mbuf *m = ln->ln_hold; |
490 | if (m) { |
491 | struct mbuf *m0; |
492 | |
493 | /* |
494 | * assuming every packet in ln_hold has |
495 | * the same IP header |
496 | */ |
497 | m0 = m->m_nextpkt; |
498 | m->m_nextpkt = NULL; |
499 | ln->ln_hold = m0; |
500 | clear_llinfo_pqueue(ln); |
501 | } |
502 | nd6_free(ln, 0); |
503 | ln = NULL; |
504 | if (m != NULL) |
505 | icmp6_error2(m, ICMP6_DST_UNREACH, |
506 | ICMP6_DST_UNREACH_ADDR, 0, ifp); |
507 | } |
508 | break; |
509 | case ND6_LLINFO_REACHABLE: |
510 | if (!ND6_LLINFO_PERMANENT(ln)) { |
511 | ln->ln_state = ND6_LLINFO_STALE; |
512 | nd6_llinfo_settimer(ln, nd6_gctimer * hz); |
513 | } |
514 | break; |
515 | |
516 | case ND6_LLINFO_PURGE: |
517 | case ND6_LLINFO_STALE: |
518 | /* Garbage Collection(RFC 2461 5.3) */ |
519 | if (!ND6_LLINFO_PERMANENT(ln)) { |
520 | nd6_free(ln, 1); |
521 | ln = NULL; |
522 | } |
523 | break; |
524 | |
525 | case ND6_LLINFO_DELAY: |
526 | if (ndi && (ndi->flags & ND6_IFF_PERFORMNUD) != 0) { |
527 | /* We need NUD */ |
528 | ln->ln_asked = 1; |
529 | ln->ln_state = ND6_LLINFO_PROBE; |
530 | daddr6 = &ln->r_l3addr.addr6; |
531 | send_ns = true; |
532 | } else { |
533 | ln->ln_state = ND6_LLINFO_STALE; /* XXX */ |
534 | nd6_llinfo_settimer(ln, nd6_gctimer * hz); |
535 | } |
536 | break; |
537 | case ND6_LLINFO_PROBE: |
538 | if (ln->ln_asked < nd6_umaxtries) { |
539 | ln->ln_asked++; |
540 | daddr6 = &ln->r_l3addr.addr6; |
541 | send_ns = true; |
542 | } else { |
543 | nd6_free(ln, 0); |
544 | ln = NULL; |
545 | } |
546 | break; |
547 | } |
548 | |
549 | if (send_ns) { |
550 | struct in6_addr src, *psrc; |
551 | const struct in6_addr *taddr6 = &ln->r_l3addr.addr6; |
552 | |
553 | nd6_llinfo_settimer(ln, ndi->retrans * hz / 1000); |
554 | psrc = nd6_llinfo_get_holdsrc(ln, &src); |
555 | LLE_FREE_LOCKED(ln); |
556 | ln = NULL; |
557 | nd6_ns_output(ifp, daddr6, taddr6, psrc, 0); |
558 | } |
559 | |
560 | out: |
561 | if (ln != NULL) |
562 | LLE_FREE_LOCKED(ln); |
563 | #ifndef NET_MPSAFE |
564 | KERNEL_UNLOCK_ONE(NULL); |
565 | mutex_exit(softnet_lock); |
566 | #endif |
567 | } |
568 | |
569 | /* |
570 | * ND6 timer routine to expire default route list and prefix list |
571 | */ |
572 | static void |
573 | nd6_timer_work(struct work *wk, void *arg) |
574 | { |
575 | struct nd_defrouter *next_dr, *dr; |
576 | struct nd_prefix *next_pr, *pr; |
577 | struct in6_ifaddr *ia6, *nia6; |
578 | int s, bound; |
579 | struct psref psref; |
580 | |
581 | callout_reset(&nd6_timer_ch, nd6_prune * hz, |
582 | nd6_timer, NULL); |
583 | |
584 | #ifndef NET_MPSAFE |
585 | mutex_enter(softnet_lock); |
586 | KERNEL_LOCK(1, NULL); |
587 | #endif |
588 | |
589 | /* expire default router list */ |
590 | |
591 | TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, next_dr) { |
592 | if (dr->expire && dr->expire < time_uptime) { |
593 | defrtrlist_del(dr, NULL); |
594 | } |
595 | } |
596 | |
597 | /* |
598 | * expire interface addresses. |
599 | * in the past the loop was inside prefix expiry processing. |
600 | * However, from a stricter speci-confrmance standpoint, we should |
601 | * rather separate address lifetimes and prefix lifetimes. |
602 | */ |
603 | bound = curlwp_bind(); |
604 | addrloop: |
605 | s = pserialize_read_enter(); |
606 | for (ia6 = IN6_ADDRLIST_READER_FIRST(); ia6; ia6 = nia6) { |
607 | nia6 = IN6_ADDRLIST_READER_NEXT(ia6); |
608 | |
609 | ia6_acquire(ia6, &psref); |
610 | pserialize_read_exit(s); |
611 | |
612 | /* check address lifetime */ |
613 | if (IFA6_IS_INVALID(ia6)) { |
614 | int regen = 0; |
615 | |
616 | /* |
617 | * If the expiring address is temporary, try |
618 | * regenerating a new one. This would be useful when |
619 | * we suspended a laptop PC, then turned it on after a |
620 | * period that could invalidate all temporary |
621 | * addresses. Although we may have to restart the |
622 | * loop (see below), it must be after purging the |
623 | * address. Otherwise, we'd see an infinite loop of |
624 | * regeneration. |
625 | */ |
626 | if (ip6_use_tempaddr && |
627 | (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0) { |
628 | if (regen_tmpaddr(ia6) == 0) |
629 | regen = 1; |
630 | } |
631 | |
632 | ia6_release(ia6, &psref); |
633 | in6_purgeaddr(&ia6->ia_ifa); |
634 | ia6 = NULL; |
635 | |
636 | if (regen) |
637 | goto addrloop; /* XXX: see below */ |
638 | } else if (IFA6_IS_DEPRECATED(ia6)) { |
639 | int oldflags = ia6->ia6_flags; |
640 | |
641 | if ((oldflags & IN6_IFF_DEPRECATED) == 0) { |
642 | ia6->ia6_flags |= IN6_IFF_DEPRECATED; |
643 | rt_newaddrmsg(RTM_NEWADDR, |
644 | (struct ifaddr *)ia6, 0, NULL); |
645 | } |
646 | |
647 | /* |
648 | * If a temporary address has just become deprecated, |
649 | * regenerate a new one if possible. |
650 | */ |
651 | if (ip6_use_tempaddr && |
652 | (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && |
653 | (oldflags & IN6_IFF_DEPRECATED) == 0) { |
654 | |
655 | if (regen_tmpaddr(ia6) == 0) { |
656 | /* |
657 | * A new temporary address is |
658 | * generated. |
659 | * XXX: this means the address chain |
660 | * has changed while we are still in |
661 | * the loop. Although the change |
662 | * would not cause disaster (because |
663 | * it's not a deletion, but an |
664 | * addition,) we'd rather restart the |
665 | * loop just for safety. Or does this |
666 | * significantly reduce performance?? |
667 | */ |
668 | ia6_release(ia6, &psref); |
669 | goto addrloop; |
670 | } |
671 | } |
672 | } else { |
673 | /* |
674 | * A new RA might have made a deprecated address |
675 | * preferred. |
676 | */ |
677 | if (ia6->ia6_flags & IN6_IFF_DEPRECATED) { |
678 | ia6->ia6_flags &= ~IN6_IFF_DEPRECATED; |
679 | rt_newaddrmsg(RTM_NEWADDR, |
680 | (struct ifaddr *)ia6, 0, NULL); |
681 | } |
682 | } |
683 | s = pserialize_read_enter(); |
684 | ia6_release(ia6, &psref); |
685 | } |
686 | pserialize_read_exit(s); |
687 | curlwp_bindx(bound); |
688 | |
689 | /* expire prefix list */ |
690 | LIST_FOREACH_SAFE(pr, &nd_prefix, ndpr_entry, next_pr) { |
691 | /* |
692 | * check prefix lifetime. |
693 | * since pltime is just for autoconf, pltime processing for |
694 | * prefix is not necessary. |
695 | */ |
696 | if (pr->ndpr_vltime != ND6_INFINITE_LIFETIME && |
697 | time_uptime - pr->ndpr_lastupdate > pr->ndpr_vltime) { |
698 | |
699 | /* |
700 | * address expiration and prefix expiration are |
701 | * separate. NEVER perform in6_purgeaddr here. |
702 | */ |
703 | |
704 | prelist_remove(pr); |
705 | } |
706 | } |
707 | |
708 | #ifndef NET_MPSAFE |
709 | KERNEL_UNLOCK_ONE(NULL); |
710 | mutex_exit(softnet_lock); |
711 | #endif |
712 | } |
713 | |
714 | static void |
715 | nd6_timer(void *ignored_arg) |
716 | { |
717 | |
718 | workqueue_enqueue(nd6_timer_wq, &nd6_timer_wk, NULL); |
719 | } |
720 | |
721 | /* ia6: deprecated/invalidated temporary address */ |
722 | static int |
723 | regen_tmpaddr(const struct in6_ifaddr *ia6) |
724 | { |
725 | struct ifaddr *ifa; |
726 | struct ifnet *ifp; |
727 | struct in6_ifaddr *public_ifa6 = NULL; |
728 | int s; |
729 | |
730 | ifp = ia6->ia_ifa.ifa_ifp; |
731 | s = pserialize_read_enter(); |
732 | IFADDR_READER_FOREACH(ifa, ifp) { |
733 | struct in6_ifaddr *it6; |
734 | |
735 | if (ifa->ifa_addr->sa_family != AF_INET6) |
736 | continue; |
737 | |
738 | it6 = (struct in6_ifaddr *)ifa; |
739 | |
740 | /* ignore no autoconf addresses. */ |
741 | if ((it6->ia6_flags & IN6_IFF_AUTOCONF) == 0) |
742 | continue; |
743 | |
744 | /* ignore autoconf addresses with different prefixes. */ |
745 | if (it6->ia6_ndpr == NULL || it6->ia6_ndpr != ia6->ia6_ndpr) |
746 | continue; |
747 | |
748 | /* |
749 | * Now we are looking at an autoconf address with the same |
750 | * prefix as ours. If the address is temporary and is still |
751 | * preferred, do not create another one. It would be rare, but |
752 | * could happen, for example, when we resume a laptop PC after |
753 | * a long period. |
754 | */ |
755 | if ((it6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && |
756 | !IFA6_IS_DEPRECATED(it6)) { |
757 | public_ifa6 = NULL; |
758 | break; |
759 | } |
760 | |
761 | /* |
762 | * This is a public autoconf address that has the same prefix |
763 | * as ours. If it is preferred, keep it. We can't break the |
764 | * loop here, because there may be a still-preferred temporary |
765 | * address with the prefix. |
766 | */ |
767 | if (!IFA6_IS_DEPRECATED(it6)) |
768 | public_ifa6 = it6; |
769 | } |
770 | |
771 | if (public_ifa6 != NULL) { |
772 | int e; |
773 | struct psref psref; |
774 | |
775 | ia6_acquire(public_ifa6, &psref); |
776 | pserialize_read_exit(s); |
777 | /* |
778 | * Random factor is introduced in the preferred lifetime, so |
779 | * we do not need additional delay (3rd arg to in6_tmpifadd). |
780 | */ |
781 | if ((e = in6_tmpifadd(public_ifa6, 0, 0)) != 0) { |
782 | ia6_release(public_ifa6, &psref); |
783 | log(LOG_NOTICE, "regen_tmpaddr: failed to create a new" |
784 | " tmp addr, errno=%d\n" , e); |
785 | return -1; |
786 | } |
787 | ia6_release(public_ifa6, &psref); |
788 | return 0; |
789 | } |
790 | pserialize_read_exit(s); |
791 | |
792 | return -1; |
793 | } |
794 | |
795 | bool |
796 | nd6_accepts_rtadv(const struct nd_ifinfo *ndi) |
797 | { |
798 | switch (ndi->flags & (ND6_IFF_ACCEPT_RTADV|ND6_IFF_OVERRIDE_RTADV)) { |
799 | case ND6_IFF_OVERRIDE_RTADV|ND6_IFF_ACCEPT_RTADV: |
800 | return true; |
801 | case ND6_IFF_ACCEPT_RTADV: |
802 | return ip6_accept_rtadv != 0; |
803 | case ND6_IFF_OVERRIDE_RTADV: |
804 | case 0: |
805 | default: |
806 | return false; |
807 | } |
808 | } |
809 | |
810 | /* |
811 | * Nuke neighbor cache/prefix/default router management table, right before |
812 | * ifp goes away. |
813 | */ |
814 | void |
815 | nd6_purge(struct ifnet *ifp, struct in6_ifextra *ext) |
816 | { |
817 | struct nd_defrouter *dr, *ndr; |
818 | struct nd_prefix *pr, *npr; |
819 | |
820 | /* |
821 | * During detach, the ND info might be already removed, but |
822 | * then is explitly passed as argument. |
823 | * Otherwise get it from ifp->if_afdata. |
824 | */ |
825 | if (ext == NULL) |
826 | ext = ifp->if_afdata[AF_INET6]; |
827 | if (ext == NULL) |
828 | return; |
829 | |
830 | /* |
831 | * Nuke default router list entries toward ifp. |
832 | * We defer removal of default router list entries that is installed |
833 | * in the routing table, in order to keep additional side effects as |
834 | * small as possible. |
835 | */ |
836 | TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, ndr) { |
837 | if (dr->installed) |
838 | continue; |
839 | |
840 | if (dr->ifp == ifp) { |
841 | KASSERT(ext != NULL); |
842 | defrtrlist_del(dr, ext); |
843 | } |
844 | } |
845 | |
846 | TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, ndr) { |
847 | if (!dr->installed) |
848 | continue; |
849 | |
850 | if (dr->ifp == ifp) { |
851 | KASSERT(ext != NULL); |
852 | defrtrlist_del(dr, ext); |
853 | } |
854 | } |
855 | |
856 | /* Nuke prefix list entries toward ifp */ |
857 | LIST_FOREACH_SAFE(pr, &nd_prefix, ndpr_entry, npr) { |
858 | if (pr->ndpr_ifp == ifp) { |
859 | /* |
860 | * Because if_detach() does *not* release prefixes |
861 | * while purging addresses the reference count will |
862 | * still be above zero. We therefore reset it to |
863 | * make sure that the prefix really gets purged. |
864 | */ |
865 | pr->ndpr_refcnt = 0; |
866 | /* |
867 | * Previously, pr->ndpr_addr is removed as well, |
868 | * but I strongly believe we don't have to do it. |
869 | * nd6_purge() is only called from in6_ifdetach(), |
870 | * which removes all the associated interface addresses |
871 | * by itself. |
872 | * (jinmei@kame.net 20010129) |
873 | */ |
874 | prelist_remove(pr); |
875 | } |
876 | } |
877 | |
878 | /* cancel default outgoing interface setting */ |
879 | if (nd6_defifindex == ifp->if_index) |
880 | nd6_setdefaultiface(0); |
881 | |
882 | /* XXX: too restrictive? */ |
883 | if (!ip6_forwarding && ifp->if_afdata[AF_INET6]) { |
884 | struct nd_ifinfo *ndi = ND_IFINFO(ifp); |
885 | if (ndi && nd6_accepts_rtadv(ndi)) { |
886 | /* refresh default router list */ |
887 | defrouter_select(); |
888 | } |
889 | } |
890 | |
891 | /* |
892 | * We may not need to nuke the neighbor cache entries here |
893 | * because the neighbor cache is kept in if_afdata[AF_INET6]. |
894 | * nd6_purge() is invoked by in6_ifdetach() which is called |
895 | * from if_detach() where everything gets purged. However |
896 | * in6_ifdetach is directly called from vlan(4), so we still |
897 | * need to purge entries here. |
898 | */ |
899 | if (ext->lltable != NULL) |
900 | lltable_purge_entries(ext->lltable); |
901 | } |
902 | |
903 | struct llentry * |
904 | nd6_lookup(const struct in6_addr *addr6, const struct ifnet *ifp, bool wlock) |
905 | { |
906 | struct sockaddr_in6 sin6; |
907 | struct llentry *ln; |
908 | |
909 | sockaddr_in6_init(&sin6, addr6, 0, 0, 0); |
910 | |
911 | IF_AFDATA_RLOCK(ifp); |
912 | ln = lla_lookup(LLTABLE6(ifp), wlock ? LLE_EXCLUSIVE : 0, |
913 | sin6tosa(&sin6)); |
914 | IF_AFDATA_RUNLOCK(ifp); |
915 | |
916 | return ln; |
917 | } |
918 | |
919 | struct llentry * |
920 | nd6_create(const struct in6_addr *addr6, const struct ifnet *ifp) |
921 | { |
922 | struct sockaddr_in6 sin6; |
923 | struct llentry *ln; |
924 | |
925 | sockaddr_in6_init(&sin6, addr6, 0, 0, 0); |
926 | |
927 | IF_AFDATA_WLOCK(ifp); |
928 | ln = lla_create(LLTABLE6(ifp), LLE_EXCLUSIVE, |
929 | sin6tosa(&sin6)); |
930 | IF_AFDATA_WUNLOCK(ifp); |
931 | |
932 | if (ln != NULL) |
933 | ln->ln_state = ND6_LLINFO_NOSTATE; |
934 | |
935 | return ln; |
936 | } |
937 | |
938 | /* |
939 | * Test whether a given IPv6 address is a neighbor or not, ignoring |
940 | * the actual neighbor cache. The neighbor cache is ignored in order |
941 | * to not reenter the routing code from within itself. |
942 | */ |
943 | static int |
944 | nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp) |
945 | { |
946 | struct nd_prefix *pr; |
947 | struct ifaddr *dstaddr; |
948 | int s; |
949 | |
950 | /* |
951 | * A link-local address is always a neighbor. |
952 | * XXX: a link does not necessarily specify a single interface. |
953 | */ |
954 | if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) { |
955 | struct sockaddr_in6 sin6_copy; |
956 | u_int32_t zone; |
957 | |
958 | /* |
959 | * We need sin6_copy since sa6_recoverscope() may modify the |
960 | * content (XXX). |
961 | */ |
962 | sin6_copy = *addr; |
963 | if (sa6_recoverscope(&sin6_copy)) |
964 | return 0; /* XXX: should be impossible */ |
965 | if (in6_setscope(&sin6_copy.sin6_addr, ifp, &zone)) |
966 | return 0; |
967 | if (sin6_copy.sin6_scope_id == zone) |
968 | return 1; |
969 | else |
970 | return 0; |
971 | } |
972 | |
973 | /* |
974 | * If the address matches one of our addresses, |
975 | * it should be a neighbor. |
976 | * If the address matches one of our on-link prefixes, it should be a |
977 | * neighbor. |
978 | */ |
979 | LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { |
980 | if (pr->ndpr_ifp != ifp) |
981 | continue; |
982 | |
983 | if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) { |
984 | struct rtentry *rt; |
985 | |
986 | rt = rtalloc1(sin6tosa(&pr->ndpr_prefix), 0); |
987 | if (rt == NULL) |
988 | continue; |
989 | /* |
990 | * This is the case where multiple interfaces |
991 | * have the same prefix, but only one is installed |
992 | * into the routing table and that prefix entry |
993 | * is not the one being examined here. In the case |
994 | * where RADIX_MPATH is enabled, multiple route |
995 | * entries (of the same rt_key value) will be |
996 | * installed because the interface addresses all |
997 | * differ. |
998 | */ |
999 | if (!IN6_ARE_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr, |
1000 | &satocsin6(rt_getkey(rt))->sin6_addr)) { |
1001 | rtfree(rt); |
1002 | continue; |
1003 | } |
1004 | rtfree(rt); |
1005 | } |
1006 | |
1007 | if (IN6_ARE_MASKED_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr, |
1008 | &addr->sin6_addr, &pr->ndpr_mask)) |
1009 | return 1; |
1010 | } |
1011 | |
1012 | /* |
1013 | * If the address is assigned on the node of the other side of |
1014 | * a p2p interface, the address should be a neighbor. |
1015 | */ |
1016 | s = pserialize_read_enter(); |
1017 | dstaddr = ifa_ifwithdstaddr(sin6tocsa(addr)); |
1018 | if (dstaddr != NULL) { |
1019 | if (dstaddr->ifa_ifp == ifp) { |
1020 | pserialize_read_exit(s); |
1021 | return 1; |
1022 | } |
1023 | } |
1024 | pserialize_read_exit(s); |
1025 | |
1026 | /* |
1027 | * If the default router list is empty, all addresses are regarded |
1028 | * as on-link, and thus, as a neighbor. |
1029 | */ |
1030 | if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && |
1031 | TAILQ_EMPTY(&nd_defrouter) && |
1032 | nd6_defifindex == ifp->if_index) { |
1033 | return 1; |
1034 | } |
1035 | |
1036 | return 0; |
1037 | } |
1038 | |
1039 | /* |
1040 | * Detect if a given IPv6 address identifies a neighbor on a given link. |
1041 | * XXX: should take care of the destination of a p2p link? |
1042 | */ |
1043 | int |
1044 | nd6_is_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp) |
1045 | { |
1046 | struct nd_prefix *pr; |
1047 | struct llentry *ln; |
1048 | struct rtentry *rt; |
1049 | |
1050 | /* |
1051 | * A link-local address is always a neighbor. |
1052 | * XXX: a link does not necessarily specify a single interface. |
1053 | */ |
1054 | if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) { |
1055 | struct sockaddr_in6 sin6_copy; |
1056 | u_int32_t zone; |
1057 | |
1058 | /* |
1059 | * We need sin6_copy since sa6_recoverscope() may modify the |
1060 | * content (XXX). |
1061 | */ |
1062 | sin6_copy = *addr; |
1063 | if (sa6_recoverscope(&sin6_copy)) |
1064 | return 0; /* XXX: should be impossible */ |
1065 | if (in6_setscope(&sin6_copy.sin6_addr, ifp, &zone)) |
1066 | return 0; |
1067 | if (sin6_copy.sin6_scope_id == zone) |
1068 | return 1; |
1069 | else |
1070 | return 0; |
1071 | } |
1072 | |
1073 | /* |
1074 | * If the address matches one of our on-link prefixes, it should be a |
1075 | * neighbor. |
1076 | */ |
1077 | LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { |
1078 | if (pr->ndpr_ifp != ifp) |
1079 | continue; |
1080 | |
1081 | if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) |
1082 | continue; |
1083 | |
1084 | if (IN6_ARE_MASKED_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr, |
1085 | &addr->sin6_addr, &pr->ndpr_mask)) |
1086 | return 1; |
1087 | } |
1088 | |
1089 | /* |
1090 | * If the default router list is empty, all addresses are regarded |
1091 | * as on-link, and thus, as a neighbor. |
1092 | * XXX: we restrict the condition to hosts, because routers usually do |
1093 | * not have the "default router list". |
1094 | */ |
1095 | if (!ip6_forwarding && TAILQ_FIRST(&nd_defrouter) == NULL && |
1096 | nd6_defifindex == ifp->if_index) { |
1097 | return 1; |
1098 | } |
1099 | |
1100 | IF_AFDATA_UNLOCK_ASSERT(ifp); |
1101 | if (nd6_is_new_addr_neighbor(addr, ifp)) |
1102 | return 1; |
1103 | |
1104 | /* |
1105 | * Even if the address matches none of our addresses, it might be |
1106 | * in the neighbor cache or a connected route. |
1107 | */ |
1108 | ln = nd6_lookup(&addr->sin6_addr, ifp, false); |
1109 | if (ln != NULL) { |
1110 | LLE_RUNLOCK(ln); |
1111 | return 1; |
1112 | } |
1113 | |
1114 | rt = rtalloc1(sin6tocsa(addr), 0); |
1115 | if (rt == NULL) |
1116 | return 0; |
1117 | |
1118 | if ((rt->rt_flags & RTF_CONNECTED) && (rt->rt_ifp == ifp |
1119 | #if NBRIDGE > 0 |
1120 | || rt->rt_ifp->if_bridge == ifp->if_bridge |
1121 | #endif |
1122 | #if NCARP > 0 |
1123 | || (ifp->if_type == IFT_CARP && rt->rt_ifp == ifp->if_carpdev) || |
1124 | (rt->rt_ifp->if_type == IFT_CARP && rt->rt_ifp->if_carpdev == ifp)|| |
1125 | (ifp->if_type == IFT_CARP && rt->rt_ifp->if_type == IFT_CARP && |
1126 | rt->rt_ifp->if_carpdev == ifp->if_carpdev) |
1127 | #endif |
1128 | )) { |
1129 | rtfree(rt); |
1130 | return 1; |
1131 | } |
1132 | rtfree(rt); |
1133 | |
1134 | return 0; |
1135 | } |
1136 | |
1137 | /* |
1138 | * Free an nd6 llinfo entry. |
1139 | * Since the function would cause significant changes in the kernel, DO NOT |
1140 | * make it global, unless you have a strong reason for the change, and are sure |
1141 | * that the change is safe. |
1142 | */ |
1143 | static void |
1144 | nd6_free(struct llentry *ln, int gc) |
1145 | { |
1146 | struct nd_defrouter *dr; |
1147 | struct ifnet *ifp; |
1148 | struct in6_addr *in6; |
1149 | |
1150 | KASSERT(ln != NULL); |
1151 | LLE_WLOCK_ASSERT(ln); |
1152 | |
1153 | ifp = ln->lle_tbl->llt_ifp; |
1154 | in6 = &ln->r_l3addr.addr6; |
1155 | /* |
1156 | * we used to have pfctlinput(PRC_HOSTDEAD) here. |
1157 | * even though it is not harmful, it was not really necessary. |
1158 | */ |
1159 | |
1160 | /* cancel timer */ |
1161 | nd6_llinfo_settimer(ln, -1); |
1162 | |
1163 | if (!ip6_forwarding) { |
1164 | int s; |
1165 | s = splsoftnet(); |
1166 | dr = defrouter_lookup(in6, ifp); |
1167 | |
1168 | if (dr != NULL && dr->expire && |
1169 | ln->ln_state == ND6_LLINFO_STALE && gc) { |
1170 | /* |
1171 | * If the reason for the deletion is just garbage |
1172 | * collection, and the neighbor is an active default |
1173 | * router, do not delete it. Instead, reset the GC |
1174 | * timer using the router's lifetime. |
1175 | * Simply deleting the entry would affect default |
1176 | * router selection, which is not necessarily a good |
1177 | * thing, especially when we're using router preference |
1178 | * values. |
1179 | * XXX: the check for ln_state would be redundant, |
1180 | * but we intentionally keep it just in case. |
1181 | */ |
1182 | if (dr->expire > time_uptime) |
1183 | nd6_llinfo_settimer(ln, |
1184 | (dr->expire - time_uptime) * hz); |
1185 | else |
1186 | nd6_llinfo_settimer(ln, nd6_gctimer * hz); |
1187 | splx(s); |
1188 | LLE_WUNLOCK(ln); |
1189 | return; |
1190 | } |
1191 | |
1192 | if (ln->ln_router || dr) { |
1193 | /* |
1194 | * We need to unlock to avoid a LOR with rt6_flush() |
1195 | * with the rnh and for the calls to |
1196 | * pfxlist_onlink_check() and defrouter_select() in the |
1197 | * block further down for calls into nd6_lookup(). |
1198 | * We still hold a ref. |
1199 | */ |
1200 | LLE_WUNLOCK(ln); |
1201 | |
1202 | /* |
1203 | * rt6_flush must be called whether or not the neighbor |
1204 | * is in the Default Router List. |
1205 | * See a corresponding comment in nd6_na_input(). |
1206 | */ |
1207 | rt6_flush(in6, ifp); |
1208 | } |
1209 | |
1210 | if (dr) { |
1211 | /* |
1212 | * Unreachablity of a router might affect the default |
1213 | * router selection and on-link detection of advertised |
1214 | * prefixes. |
1215 | */ |
1216 | |
1217 | /* |
1218 | * Temporarily fake the state to choose a new default |
1219 | * router and to perform on-link determination of |
1220 | * prefixes correctly. |
1221 | * Below the state will be set correctly, |
1222 | * or the entry itself will be deleted. |
1223 | */ |
1224 | ln->ln_state = ND6_LLINFO_INCOMPLETE; |
1225 | |
1226 | /* |
1227 | * Since defrouter_select() does not affect the |
1228 | * on-link determination and MIP6 needs the check |
1229 | * before the default router selection, we perform |
1230 | * the check now. |
1231 | */ |
1232 | pfxlist_onlink_check(); |
1233 | |
1234 | /* |
1235 | * refresh default router list |
1236 | */ |
1237 | defrouter_select(); |
1238 | } |
1239 | |
1240 | #ifdef __FreeBSD__ |
1241 | /* |
1242 | * If this entry was added by an on-link redirect, remove the |
1243 | * corresponding host route. |
1244 | */ |
1245 | if (ln->la_flags & LLE_REDIRECT) |
1246 | nd6_free_redirect(ln); |
1247 | #endif |
1248 | |
1249 | if (ln->ln_router || dr) |
1250 | LLE_WLOCK(ln); |
1251 | |
1252 | splx(s); |
1253 | } |
1254 | |
1255 | /* |
1256 | * Save to unlock. We still hold an extra reference and will not |
1257 | * free(9) in llentry_free() if someone else holds one as well. |
1258 | */ |
1259 | LLE_WUNLOCK(ln); |
1260 | IF_AFDATA_LOCK(ifp); |
1261 | LLE_WLOCK(ln); |
1262 | |
1263 | /* Guard against race with other llentry_free(). */ |
1264 | if (ln->la_flags & LLE_LINKED) { |
1265 | LLE_REMREF(ln); |
1266 | llentry_free(ln); |
1267 | } else |
1268 | LLE_FREE_LOCKED(ln); |
1269 | |
1270 | IF_AFDATA_UNLOCK(ifp); |
1271 | } |
1272 | |
1273 | /* |
1274 | * Upper-layer reachability hint for Neighbor Unreachability Detection. |
1275 | * |
1276 | * XXX cost-effective methods? |
1277 | */ |
1278 | void |
1279 | nd6_nud_hint(struct rtentry *rt) |
1280 | { |
1281 | struct llentry *ln; |
1282 | struct ifnet *ifp; |
1283 | |
1284 | if (rt == NULL) |
1285 | return; |
1286 | |
1287 | ifp = rt->rt_ifp; |
1288 | ln = nd6_lookup(&(satocsin6(rt_getkey(rt)))->sin6_addr, ifp, true); |
1289 | if (ln == NULL) |
1290 | return; |
1291 | |
1292 | if (ln->ln_state < ND6_LLINFO_REACHABLE) |
1293 | goto done; |
1294 | |
1295 | /* |
1296 | * if we get upper-layer reachability confirmation many times, |
1297 | * it is possible we have false information. |
1298 | */ |
1299 | ln->ln_byhint++; |
1300 | if (ln->ln_byhint > nd6_maxnudhint) |
1301 | goto done; |
1302 | |
1303 | ln->ln_state = ND6_LLINFO_REACHABLE; |
1304 | if (!ND6_LLINFO_PERMANENT(ln)) |
1305 | nd6_llinfo_settimer(ln, ND_IFINFO(rt->rt_ifp)->reachable * hz); |
1306 | |
1307 | done: |
1308 | LLE_WUNLOCK(ln); |
1309 | |
1310 | return; |
1311 | } |
1312 | |
1313 | struct gc_args { |
1314 | int gc_entries; |
1315 | const struct in6_addr *skip_in6; |
1316 | }; |
1317 | |
1318 | static int |
1319 | nd6_purge_entry(struct lltable *llt, struct llentry *ln, void *farg) |
1320 | { |
1321 | struct gc_args *args = farg; |
1322 | int *n = &args->gc_entries; |
1323 | const struct in6_addr *skip_in6 = args->skip_in6; |
1324 | |
1325 | if (*n <= 0) |
1326 | return 0; |
1327 | |
1328 | if (ND6_LLINFO_PERMANENT(ln)) |
1329 | return 0; |
1330 | |
1331 | if (IN6_ARE_ADDR_EQUAL(&ln->r_l3addr.addr6, skip_in6)) |
1332 | return 0; |
1333 | |
1334 | LLE_WLOCK(ln); |
1335 | if (ln->ln_state > ND6_LLINFO_INCOMPLETE) |
1336 | ln->ln_state = ND6_LLINFO_STALE; |
1337 | else |
1338 | ln->ln_state = ND6_LLINFO_PURGE; |
1339 | nd6_llinfo_settimer(ln, 0); |
1340 | LLE_WUNLOCK(ln); |
1341 | |
1342 | (*n)--; |
1343 | return 0; |
1344 | } |
1345 | |
1346 | static void |
1347 | nd6_gc_neighbors(struct lltable *llt, const struct in6_addr *in6) |
1348 | { |
1349 | |
1350 | if (ip6_neighborgcthresh >= 0 && |
1351 | lltable_get_entry_count(llt) >= ip6_neighborgcthresh) { |
1352 | struct gc_args gc_args = {10, in6}; |
1353 | /* |
1354 | * XXX entries that are "less recently used" should be |
1355 | * freed first. |
1356 | */ |
1357 | lltable_foreach_lle(llt, nd6_purge_entry, &gc_args); |
1358 | } |
1359 | } |
1360 | |
1361 | void |
1362 | nd6_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info) |
1363 | { |
1364 | struct sockaddr *gate = rt->rt_gateway; |
1365 | struct ifnet *ifp = rt->rt_ifp; |
1366 | uint8_t namelen = strlen(ifp->if_xname), addrlen = ifp->if_addrlen; |
1367 | struct ifaddr *ifa; |
1368 | |
1369 | RT_DPRINTF("rt_getkey(rt) = %p\n" , rt_getkey(rt)); |
1370 | |
1371 | if (req == RTM_LLINFO_UPD) { |
1372 | int rc; |
1373 | struct in6_addr *in6; |
1374 | struct in6_addr in6_all; |
1375 | int anycast; |
1376 | |
1377 | if ((ifa = info->rti_ifa) == NULL) |
1378 | return; |
1379 | |
1380 | in6 = &ifatoia6(ifa)->ia_addr.sin6_addr; |
1381 | anycast = ifatoia6(ifa)->ia6_flags & IN6_IFF_ANYCAST; |
1382 | |
1383 | in6_all = in6addr_linklocal_allnodes; |
1384 | if ((rc = in6_setscope(&in6_all, ifa->ifa_ifp, NULL)) != 0) { |
1385 | log(LOG_ERR, "%s: failed to set scope %s " |
1386 | "(errno=%d)\n" , __func__, if_name(ifp), rc); |
1387 | return; |
1388 | } |
1389 | |
1390 | /* XXX don't set Override for proxy addresses */ |
1391 | nd6_na_output(ifa->ifa_ifp, &in6_all, in6, |
1392 | (anycast ? 0 : ND_NA_FLAG_OVERRIDE) |
1393 | #if 0 |
1394 | | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0) |
1395 | #endif |
1396 | , 1, NULL); |
1397 | return; |
1398 | } |
1399 | |
1400 | if ((rt->rt_flags & RTF_GATEWAY) != 0) |
1401 | return; |
1402 | |
1403 | if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) { |
1404 | RT_DPRINTF("rt_getkey(rt) = %p\n" , rt_getkey(rt)); |
1405 | /* |
1406 | * This is probably an interface direct route for a link |
1407 | * which does not need neighbor caches (e.g. fe80::%lo0/64). |
1408 | * We do not need special treatment below for such a route. |
1409 | * Moreover, the RTF_LLINFO flag which would be set below |
1410 | * would annoy the ndp(8) command. |
1411 | */ |
1412 | return; |
1413 | } |
1414 | |
1415 | switch (req) { |
1416 | case RTM_ADD: { |
1417 | int s; |
1418 | |
1419 | RT_DPRINTF("rt_getkey(rt) = %p\n" , rt_getkey(rt)); |
1420 | /* |
1421 | * There is no backward compatibility :) |
1422 | * |
1423 | * if ((rt->rt_flags & RTF_HOST) == 0 && |
1424 | * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff) |
1425 | * rt->rt_flags |= RTF_CLONING; |
1426 | */ |
1427 | /* XXX should move to route.c? */ |
1428 | if (rt->rt_flags & (RTF_CONNECTED | RTF_LOCAL)) { |
1429 | union { |
1430 | struct sockaddr sa; |
1431 | struct sockaddr_dl sdl; |
1432 | struct sockaddr_storage ss; |
1433 | } u; |
1434 | /* |
1435 | * Case 1: This route should come from a route to |
1436 | * interface (RTF_CLONING case) or the route should be |
1437 | * treated as on-link but is currently not |
1438 | * (RTF_LLINFO && ln == NULL case). |
1439 | */ |
1440 | if (sockaddr_dl_init(&u.sdl, sizeof(u.ss), |
1441 | ifp->if_index, ifp->if_type, |
1442 | NULL, namelen, NULL, addrlen) == NULL) { |
1443 | printf("%s.%d: sockaddr_dl_init(, %zu, ) " |
1444 | "failed on %s\n" , __func__, __LINE__, |
1445 | sizeof(u.ss), if_name(ifp)); |
1446 | } |
1447 | rt_setgate(rt, &u.sa); |
1448 | gate = rt->rt_gateway; |
1449 | RT_DPRINTF("rt_getkey(rt) = %p\n" , rt_getkey(rt)); |
1450 | if (gate == NULL) { |
1451 | log(LOG_ERR, |
1452 | "%s: rt_setgate failed on %s\n" , __func__, |
1453 | if_name(ifp)); |
1454 | break; |
1455 | } |
1456 | |
1457 | RT_DPRINTF("rt_getkey(rt) = %p\n" , rt_getkey(rt)); |
1458 | if ((rt->rt_flags & RTF_CONNECTED) != 0) |
1459 | break; |
1460 | } |
1461 | RT_DPRINTF("rt_getkey(rt) = %p\n" , rt_getkey(rt)); |
1462 | /* |
1463 | * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here. |
1464 | * We don't do that here since llinfo is not ready yet. |
1465 | * |
1466 | * There are also couple of other things to be discussed: |
1467 | * - unsolicited NA code needs improvement beforehand |
1468 | * - RFC2461 says we MAY send multicast unsolicited NA |
1469 | * (7.2.6 paragraph 4), however, it also says that we |
1470 | * SHOULD provide a mechanism to prevent multicast NA storm. |
1471 | * we don't have anything like it right now. |
1472 | * note that the mechanism needs a mutual agreement |
1473 | * between proxies, which means that we need to implement |
1474 | * a new protocol, or a new kludge. |
1475 | * - from RFC2461 6.2.4, host MUST NOT send an unsolicited NA. |
1476 | * we need to check ip6forwarding before sending it. |
1477 | * (or should we allow proxy ND configuration only for |
1478 | * routers? there's no mention about proxy ND from hosts) |
1479 | */ |
1480 | #if 0 |
1481 | /* XXX it does not work */ |
1482 | if (rt->rt_flags & RTF_ANNOUNCE) |
1483 | nd6_na_output(ifp, |
1484 | &satocsin6(rt_getkey(rt))->sin6_addr, |
1485 | &satocsin6(rt_getkey(rt))->sin6_addr, |
1486 | ip6_forwarding ? ND_NA_FLAG_ROUTER : 0, |
1487 | 1, NULL); |
1488 | #endif |
1489 | |
1490 | if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) { |
1491 | RT_DPRINTF("rt_getkey(rt) = %p\n" , rt_getkey(rt)); |
1492 | /* |
1493 | * Address resolution isn't necessary for a point to |
1494 | * point link, so we can skip this test for a p2p link. |
1495 | */ |
1496 | if (gate->sa_family != AF_LINK || |
1497 | gate->sa_len < |
1498 | sockaddr_dl_measure(namelen, addrlen)) { |
1499 | log(LOG_DEBUG, |
1500 | "nd6_rtrequest: bad gateway value: %s\n" , |
1501 | if_name(ifp)); |
1502 | break; |
1503 | } |
1504 | satosdl(gate)->sdl_type = ifp->if_type; |
1505 | satosdl(gate)->sdl_index = ifp->if_index; |
1506 | RT_DPRINTF("rt_getkey(rt) = %p\n" , rt_getkey(rt)); |
1507 | } |
1508 | RT_DPRINTF("rt_getkey(rt) = %p\n" , rt_getkey(rt)); |
1509 | |
1510 | /* |
1511 | * When called from rt_ifa_addlocal, we cannot depend on that |
1512 | * the address (rt_getkey(rt)) exits in the address list of the |
1513 | * interface. So check RTF_LOCAL instead. |
1514 | */ |
1515 | if (rt->rt_flags & RTF_LOCAL) { |
1516 | if (nd6_useloopback) |
1517 | rt->rt_ifp = lo0ifp; /* XXX */ |
1518 | break; |
1519 | } |
1520 | |
1521 | /* |
1522 | * check if rt_getkey(rt) is an address assigned |
1523 | * to the interface. |
1524 | */ |
1525 | s = pserialize_read_enter(); |
1526 | ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, |
1527 | &satocsin6(rt_getkey(rt))->sin6_addr); |
1528 | if (ifa != NULL) { |
1529 | if (nd6_useloopback) { |
1530 | rt->rt_ifp = lo0ifp; /* XXX */ |
1531 | /* |
1532 | * Make sure rt_ifa be equal to the ifaddr |
1533 | * corresponding to the address. |
1534 | * We need this because when we refer |
1535 | * rt_ifa->ia6_flags in ip6_input, we assume |
1536 | * that the rt_ifa points to the address instead |
1537 | * of the loopback address. |
1538 | */ |
1539 | if (ifa != rt->rt_ifa) |
1540 | rt_replace_ifa(rt, ifa); |
1541 | } |
1542 | } else if (rt->rt_flags & RTF_ANNOUNCE) { |
1543 | /* join solicited node multicast for proxy ND */ |
1544 | if (ifp->if_flags & IFF_MULTICAST) { |
1545 | struct in6_addr llsol; |
1546 | int error; |
1547 | |
1548 | llsol = satocsin6(rt_getkey(rt))->sin6_addr; |
1549 | llsol.s6_addr32[0] = htonl(0xff020000); |
1550 | llsol.s6_addr32[1] = 0; |
1551 | llsol.s6_addr32[2] = htonl(1); |
1552 | llsol.s6_addr8[12] = 0xff; |
1553 | if (in6_setscope(&llsol, ifp, NULL)) |
1554 | goto out; |
1555 | if (!in6_addmulti(&llsol, ifp, &error, 0)) { |
1556 | nd6log(LOG_ERR, "%s: failed to join " |
1557 | "%s (errno=%d)\n" , if_name(ifp), |
1558 | ip6_sprintf(&llsol), error); |
1559 | } |
1560 | } |
1561 | } |
1562 | out: |
1563 | pserialize_read_exit(s); |
1564 | /* |
1565 | * If we have too many cache entries, initiate immediate |
1566 | * purging for some entries. |
1567 | */ |
1568 | if (rt->rt_ifp != NULL) |
1569 | nd6_gc_neighbors(LLTABLE6(rt->rt_ifp), NULL); |
1570 | break; |
1571 | } |
1572 | |
1573 | case RTM_DELETE: |
1574 | /* leave from solicited node multicast for proxy ND */ |
1575 | if ((rt->rt_flags & RTF_ANNOUNCE) != 0 && |
1576 | (ifp->if_flags & IFF_MULTICAST) != 0) { |
1577 | struct in6_addr llsol; |
1578 | struct in6_multi *in6m; |
1579 | |
1580 | llsol = satocsin6(rt_getkey(rt))->sin6_addr; |
1581 | llsol.s6_addr32[0] = htonl(0xff020000); |
1582 | llsol.s6_addr32[1] = 0; |
1583 | llsol.s6_addr32[2] = htonl(1); |
1584 | llsol.s6_addr8[12] = 0xff; |
1585 | if (in6_setscope(&llsol, ifp, NULL) == 0) { |
1586 | IN6_LOOKUP_MULTI(llsol, ifp, in6m); |
1587 | if (in6m) |
1588 | in6_delmulti(in6m); |
1589 | } |
1590 | } |
1591 | break; |
1592 | } |
1593 | } |
1594 | |
1595 | int |
1596 | nd6_ioctl(u_long cmd, void *data, struct ifnet *ifp) |
1597 | { |
1598 | struct in6_drlist *drl = (struct in6_drlist *)data; |
1599 | struct in6_oprlist *oprl = (struct in6_oprlist *)data; |
1600 | struct in6_ndireq *ndi = (struct in6_ndireq *)data; |
1601 | struct in6_nbrinfo *nbi = (struct in6_nbrinfo *)data; |
1602 | struct in6_ndifreq *ndif = (struct in6_ndifreq *)data; |
1603 | struct nd_defrouter *dr; |
1604 | struct nd_prefix *pr; |
1605 | int i = 0, error = 0; |
1606 | int s; |
1607 | |
1608 | switch (cmd) { |
1609 | case SIOCGDRLST_IN6: |
1610 | /* |
1611 | * obsolete API, use sysctl under net.inet6.icmp6 |
1612 | */ |
1613 | memset(drl, 0, sizeof(*drl)); |
1614 | s = splsoftnet(); |
1615 | TAILQ_FOREACH(dr, &nd_defrouter, dr_entry) { |
1616 | if (i >= DRLSTSIZ) |
1617 | break; |
1618 | drl->defrouter[i].rtaddr = dr->rtaddr; |
1619 | in6_clearscope(&drl->defrouter[i].rtaddr); |
1620 | |
1621 | drl->defrouter[i].flags = dr->flags; |
1622 | drl->defrouter[i].rtlifetime = dr->rtlifetime; |
1623 | drl->defrouter[i].expire = dr->expire ? |
1624 | time_mono_to_wall(dr->expire) : 0; |
1625 | drl->defrouter[i].if_index = dr->ifp->if_index; |
1626 | i++; |
1627 | } |
1628 | splx(s); |
1629 | break; |
1630 | case SIOCGPRLST_IN6: |
1631 | /* |
1632 | * obsolete API, use sysctl under net.inet6.icmp6 |
1633 | * |
1634 | * XXX the structure in6_prlist was changed in backward- |
1635 | * incompatible manner. in6_oprlist is used for SIOCGPRLST_IN6, |
1636 | * in6_prlist is used for nd6_sysctl() - fill_prlist(). |
1637 | */ |
1638 | /* |
1639 | * XXX meaning of fields, especialy "raflags", is very |
1640 | * differnet between RA prefix list and RR/static prefix list. |
1641 | * how about separating ioctls into two? |
1642 | */ |
1643 | memset(oprl, 0, sizeof(*oprl)); |
1644 | s = splsoftnet(); |
1645 | LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { |
1646 | struct nd_pfxrouter *pfr; |
1647 | int j; |
1648 | |
1649 | if (i >= PRLSTSIZ) |
1650 | break; |
1651 | oprl->prefix[i].prefix = pr->ndpr_prefix.sin6_addr; |
1652 | oprl->prefix[i].raflags = pr->ndpr_raf; |
1653 | oprl->prefix[i].prefixlen = pr->ndpr_plen; |
1654 | oprl->prefix[i].vltime = pr->ndpr_vltime; |
1655 | oprl->prefix[i].pltime = pr->ndpr_pltime; |
1656 | oprl->prefix[i].if_index = pr->ndpr_ifp->if_index; |
1657 | if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME) |
1658 | oprl->prefix[i].expire = 0; |
1659 | else { |
1660 | time_t maxexpire; |
1661 | |
1662 | /* XXX: we assume time_t is signed. */ |
1663 | maxexpire = (-1) & |
1664 | ~((time_t)1 << |
1665 | ((sizeof(maxexpire) * 8) - 1)); |
1666 | if (pr->ndpr_vltime < |
1667 | maxexpire - pr->ndpr_lastupdate) { |
1668 | time_t expire; |
1669 | expire = pr->ndpr_lastupdate + |
1670 | pr->ndpr_vltime; |
1671 | oprl->prefix[i].expire = expire ? |
1672 | time_mono_to_wall(expire) : 0; |
1673 | } else |
1674 | oprl->prefix[i].expire = maxexpire; |
1675 | } |
1676 | |
1677 | j = 0; |
1678 | LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) { |
1679 | if (j < DRLSTSIZ) { |
1680 | #define RTRADDR oprl->prefix[i].advrtr[j] |
1681 | RTRADDR = pfr->router->rtaddr; |
1682 | in6_clearscope(&RTRADDR); |
1683 | #undef RTRADDR |
1684 | } |
1685 | j++; |
1686 | } |
1687 | oprl->prefix[i].advrtrs = j; |
1688 | oprl->prefix[i].origin = PR_ORIG_RA; |
1689 | |
1690 | i++; |
1691 | } |
1692 | splx(s); |
1693 | |
1694 | break; |
1695 | case OSIOCGIFINFO_IN6: |
1696 | #define ND ndi->ndi |
1697 | /* XXX: old ndp(8) assumes a positive value for linkmtu. */ |
1698 | memset(&ND, 0, sizeof(ND)); |
1699 | ND.linkmtu = IN6_LINKMTU(ifp); |
1700 | ND.maxmtu = ND_IFINFO(ifp)->maxmtu; |
1701 | ND.basereachable = ND_IFINFO(ifp)->basereachable; |
1702 | ND.reachable = ND_IFINFO(ifp)->reachable; |
1703 | ND.retrans = ND_IFINFO(ifp)->retrans; |
1704 | ND.flags = ND_IFINFO(ifp)->flags; |
1705 | ND.recalctm = ND_IFINFO(ifp)->recalctm; |
1706 | ND.chlim = ND_IFINFO(ifp)->chlim; |
1707 | break; |
1708 | case SIOCGIFINFO_IN6: |
1709 | ND = *ND_IFINFO(ifp); |
1710 | break; |
1711 | case SIOCSIFINFO_IN6: |
1712 | /* |
1713 | * used to change host variables from userland. |
1714 | * intented for a use on router to reflect RA configurations. |
1715 | */ |
1716 | /* 0 means 'unspecified' */ |
1717 | if (ND.linkmtu != 0) { |
1718 | if (ND.linkmtu < IPV6_MMTU || |
1719 | ND.linkmtu > IN6_LINKMTU(ifp)) { |
1720 | error = EINVAL; |
1721 | break; |
1722 | } |
1723 | ND_IFINFO(ifp)->linkmtu = ND.linkmtu; |
1724 | } |
1725 | |
1726 | if (ND.basereachable != 0) { |
1727 | int obasereachable = ND_IFINFO(ifp)->basereachable; |
1728 | |
1729 | ND_IFINFO(ifp)->basereachable = ND.basereachable; |
1730 | if (ND.basereachable != obasereachable) |
1731 | ND_IFINFO(ifp)->reachable = |
1732 | ND_COMPUTE_RTIME(ND.basereachable); |
1733 | } |
1734 | if (ND.retrans != 0) |
1735 | ND_IFINFO(ifp)->retrans = ND.retrans; |
1736 | if (ND.chlim != 0) |
1737 | ND_IFINFO(ifp)->chlim = ND.chlim; |
1738 | /* FALLTHROUGH */ |
1739 | case SIOCSIFINFO_FLAGS: |
1740 | { |
1741 | struct ifaddr *ifa; |
1742 | struct in6_ifaddr *ia; |
1743 | |
1744 | if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) && |
1745 | !(ND.flags & ND6_IFF_IFDISABLED)) |
1746 | { |
1747 | /* |
1748 | * If the interface is marked as ND6_IFF_IFDISABLED and |
1749 | * has a link-local address with IN6_IFF_DUPLICATED, |
1750 | * do not clear ND6_IFF_IFDISABLED. |
1751 | * See RFC 4862, section 5.4.5. |
1752 | */ |
1753 | int duplicated_linklocal = 0; |
1754 | |
1755 | s = pserialize_read_enter(); |
1756 | IFADDR_READER_FOREACH(ifa, ifp) { |
1757 | if (ifa->ifa_addr->sa_family != AF_INET6) |
1758 | continue; |
1759 | ia = (struct in6_ifaddr *)ifa; |
1760 | if ((ia->ia6_flags & IN6_IFF_DUPLICATED) && |
1761 | IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia))) |
1762 | { |
1763 | duplicated_linklocal = 1; |
1764 | break; |
1765 | } |
1766 | } |
1767 | pserialize_read_exit(s); |
1768 | |
1769 | if (duplicated_linklocal) { |
1770 | ND.flags |= ND6_IFF_IFDISABLED; |
1771 | log(LOG_ERR, "Cannot enable an interface" |
1772 | " with a link-local address marked" |
1773 | " duplicate.\n" ); |
1774 | } else { |
1775 | ND_IFINFO(ifp)->flags &= ~ND6_IFF_IFDISABLED; |
1776 | if (ifp->if_flags & IFF_UP) |
1777 | in6_if_up(ifp); |
1778 | } |
1779 | } else if (!(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) && |
1780 | (ND.flags & ND6_IFF_IFDISABLED)) { |
1781 | int bound = curlwp_bind(); |
1782 | /* Mark all IPv6 addresses as tentative. */ |
1783 | |
1784 | ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED; |
1785 | s = pserialize_read_enter(); |
1786 | IFADDR_READER_FOREACH(ifa, ifp) { |
1787 | struct psref psref; |
1788 | if (ifa->ifa_addr->sa_family != AF_INET6) |
1789 | continue; |
1790 | ifa_acquire(ifa, &psref); |
1791 | pserialize_read_exit(s); |
1792 | |
1793 | nd6_dad_stop(ifa); |
1794 | |
1795 | ia = (struct in6_ifaddr *)ifa; |
1796 | ia->ia6_flags |= IN6_IFF_TENTATIVE; |
1797 | |
1798 | s = pserialize_read_enter(); |
1799 | ifa_release(ifa, &psref); |
1800 | } |
1801 | pserialize_read_exit(s); |
1802 | curlwp_bindx(bound); |
1803 | } |
1804 | |
1805 | if (ND.flags & ND6_IFF_AUTO_LINKLOCAL) { |
1806 | if (!(ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL)) { |
1807 | /* auto_linklocal 0->1 transition */ |
1808 | |
1809 | ND_IFINFO(ifp)->flags |= ND6_IFF_AUTO_LINKLOCAL; |
1810 | in6_ifattach(ifp, NULL); |
1811 | } else if (!(ND.flags & ND6_IFF_IFDISABLED) && |
1812 | ifp->if_flags & IFF_UP) |
1813 | { |
1814 | /* |
1815 | * When the IF already has |
1816 | * ND6_IFF_AUTO_LINKLOCAL, no link-local |
1817 | * address is assigned, and IFF_UP, try to |
1818 | * assign one. |
1819 | */ |
1820 | int haslinklocal = 0; |
1821 | |
1822 | s = pserialize_read_enter(); |
1823 | IFADDR_READER_FOREACH(ifa, ifp) { |
1824 | if (ifa->ifa_addr->sa_family !=AF_INET6) |
1825 | continue; |
1826 | ia = (struct in6_ifaddr *)ifa; |
1827 | if (IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia))){ |
1828 | haslinklocal = 1; |
1829 | break; |
1830 | } |
1831 | } |
1832 | pserialize_read_exit(s); |
1833 | if (!haslinklocal) |
1834 | in6_ifattach(ifp, NULL); |
1835 | } |
1836 | } |
1837 | } |
1838 | ND_IFINFO(ifp)->flags = ND.flags; |
1839 | break; |
1840 | #undef ND |
1841 | case SIOCSNDFLUSH_IN6: /* XXX: the ioctl name is confusing... */ |
1842 | /* sync kernel routing table with the default router list */ |
1843 | defrouter_reset(); |
1844 | defrouter_select(); |
1845 | break; |
1846 | case SIOCSPFXFLUSH_IN6: |
1847 | { |
1848 | /* flush all the prefix advertised by routers */ |
1849 | struct nd_prefix *pfx, *next; |
1850 | |
1851 | s = splsoftnet(); |
1852 | LIST_FOREACH_SAFE(pfx, &nd_prefix, ndpr_entry, next) { |
1853 | struct in6_ifaddr *ia, *ia_next; |
1854 | int _s; |
1855 | |
1856 | if (IN6_IS_ADDR_LINKLOCAL(&pfx->ndpr_prefix.sin6_addr)) |
1857 | continue; /* XXX */ |
1858 | |
1859 | /* do we really have to remove addresses as well? */ |
1860 | restart: |
1861 | _s = pserialize_read_enter(); |
1862 | for (ia = IN6_ADDRLIST_READER_FIRST(); ia; |
1863 | ia = ia_next) { |
1864 | /* ia might be removed. keep the next ptr. */ |
1865 | ia_next = IN6_ADDRLIST_READER_NEXT(ia); |
1866 | |
1867 | if ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0) |
1868 | continue; |
1869 | |
1870 | if (ia->ia6_ndpr == pfx) { |
1871 | pserialize_read_exit(_s); |
1872 | /* XXX NOMPSAFE? */ |
1873 | in6_purgeaddr(&ia->ia_ifa); |
1874 | goto restart; |
1875 | } |
1876 | } |
1877 | pserialize_read_exit(_s); |
1878 | prelist_remove(pfx); |
1879 | } |
1880 | splx(s); |
1881 | break; |
1882 | } |
1883 | case SIOCSRTRFLUSH_IN6: |
1884 | { |
1885 | /* flush all the default routers */ |
1886 | struct nd_defrouter *drtr, *next; |
1887 | |
1888 | s = splsoftnet(); |
1889 | defrouter_reset(); |
1890 | TAILQ_FOREACH_SAFE(drtr, &nd_defrouter, dr_entry, next) { |
1891 | defrtrlist_del(drtr, NULL); |
1892 | } |
1893 | defrouter_select(); |
1894 | splx(s); |
1895 | break; |
1896 | } |
1897 | case SIOCGNBRINFO_IN6: |
1898 | { |
1899 | struct llentry *ln; |
1900 | struct in6_addr nb_addr = nbi->addr; /* make local for safety */ |
1901 | |
1902 | if ((error = in6_setscope(&nb_addr, ifp, NULL)) != 0) |
1903 | return error; |
1904 | |
1905 | ln = nd6_lookup(&nb_addr, ifp, false); |
1906 | if (ln == NULL) { |
1907 | error = EINVAL; |
1908 | break; |
1909 | } |
1910 | nbi->state = ln->ln_state; |
1911 | nbi->asked = ln->ln_asked; |
1912 | nbi->isrouter = ln->ln_router; |
1913 | nbi->expire = ln->ln_expire ? |
1914 | time_mono_to_wall(ln->ln_expire) : 0; |
1915 | LLE_RUNLOCK(ln); |
1916 | |
1917 | break; |
1918 | } |
1919 | case SIOCGDEFIFACE_IN6: /* XXX: should be implemented as a sysctl? */ |
1920 | ndif->ifindex = nd6_defifindex; |
1921 | break; |
1922 | case SIOCSDEFIFACE_IN6: /* XXX: should be implemented as a sysctl? */ |
1923 | return nd6_setdefaultiface(ndif->ifindex); |
1924 | } |
1925 | return error; |
1926 | } |
1927 | |
1928 | void |
1929 | nd6_llinfo_release_pkts(struct llentry *ln, struct ifnet *ifp) |
1930 | { |
1931 | struct mbuf *m_hold, *m_hold_next; |
1932 | struct sockaddr_in6 sin6; |
1933 | |
1934 | LLE_WLOCK_ASSERT(ln); |
1935 | |
1936 | sockaddr_in6_init(&sin6, &ln->r_l3addr.addr6, 0, 0, 0); |
1937 | |
1938 | m_hold = ln->la_hold, ln->la_hold = NULL, ln->la_numheld = 0; |
1939 | |
1940 | LLE_WUNLOCK(ln); |
1941 | for (; m_hold != NULL; m_hold = m_hold_next) { |
1942 | m_hold_next = m_hold->m_nextpkt; |
1943 | m_hold->m_nextpkt = NULL; |
1944 | |
1945 | /* |
1946 | * we assume ifp is not a p2p here, so |
1947 | * just set the 2nd argument as the |
1948 | * 1st one. |
1949 | */ |
1950 | nd6_output(ifp, ifp, m_hold, &sin6, NULL); |
1951 | } |
1952 | LLE_WLOCK(ln); |
1953 | } |
1954 | |
1955 | /* |
1956 | * Create neighbor cache entry and cache link-layer address, |
1957 | * on reception of inbound ND6 packets. (RS/RA/NS/redirect) |
1958 | */ |
1959 | void |
1960 | nd6_cache_lladdr( |
1961 | struct ifnet *ifp, |
1962 | struct in6_addr *from, |
1963 | char *lladdr, |
1964 | int lladdrlen, |
1965 | int type, /* ICMP6 type */ |
1966 | int code /* type dependent information */ |
1967 | ) |
1968 | { |
1969 | struct nd_ifinfo *ndi = ND_IFINFO(ifp); |
1970 | struct llentry *ln = NULL; |
1971 | int is_newentry; |
1972 | int do_update; |
1973 | int olladdr; |
1974 | int llchange; |
1975 | int newstate = 0; |
1976 | uint16_t router = 0; |
1977 | |
1978 | KASSERT(ifp != NULL); |
1979 | KASSERT(from != NULL); |
1980 | |
1981 | /* nothing must be updated for unspecified address */ |
1982 | if (IN6_IS_ADDR_UNSPECIFIED(from)) |
1983 | return; |
1984 | |
1985 | /* |
1986 | * Validation about ifp->if_addrlen and lladdrlen must be done in |
1987 | * the caller. |
1988 | * |
1989 | * XXX If the link does not have link-layer adderss, what should |
1990 | * we do? (ifp->if_addrlen == 0) |
1991 | * Spec says nothing in sections for RA, RS and NA. There's small |
1992 | * description on it in NS section (RFC 2461 7.2.3). |
1993 | */ |
1994 | |
1995 | ln = nd6_lookup(from, ifp, true); |
1996 | if (ln == NULL) { |
1997 | #if 0 |
1998 | /* nothing must be done if there's no lladdr */ |
1999 | if (!lladdr || !lladdrlen) |
2000 | return NULL; |
2001 | #endif |
2002 | |
2003 | ln = nd6_create(from, ifp); |
2004 | is_newentry = 1; |
2005 | } else { |
2006 | /* do nothing if static ndp is set */ |
2007 | if (ln->la_flags & LLE_STATIC) { |
2008 | LLE_WUNLOCK(ln); |
2009 | return; |
2010 | } |
2011 | is_newentry = 0; |
2012 | } |
2013 | |
2014 | if (ln == NULL) |
2015 | return; |
2016 | |
2017 | olladdr = (ln->la_flags & LLE_VALID) ? 1 : 0; |
2018 | if (olladdr && lladdr) { |
2019 | llchange = memcmp(lladdr, &ln->ll_addr, ifp->if_addrlen); |
2020 | } else |
2021 | llchange = 0; |
2022 | |
2023 | /* |
2024 | * newentry olladdr lladdr llchange (*=record) |
2025 | * 0 n n -- (1) |
2026 | * 0 y n -- (2) |
2027 | * 0 n y -- (3) * STALE |
2028 | * 0 y y n (4) * |
2029 | * 0 y y y (5) * STALE |
2030 | * 1 -- n -- (6) NOSTATE(= PASSIVE) |
2031 | * 1 -- y -- (7) * STALE |
2032 | */ |
2033 | |
2034 | if (lladdr) { /* (3-5) and (7) */ |
2035 | /* |
2036 | * Record source link-layer address |
2037 | * XXX is it dependent to ifp->if_type? |
2038 | */ |
2039 | memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen); |
2040 | ln->la_flags |= LLE_VALID; |
2041 | } |
2042 | |
2043 | if (!is_newentry) { |
2044 | if ((!olladdr && lladdr) || /* (3) */ |
2045 | (olladdr && lladdr && llchange)) { /* (5) */ |
2046 | do_update = 1; |
2047 | newstate = ND6_LLINFO_STALE; |
2048 | } else /* (1-2,4) */ |
2049 | do_update = 0; |
2050 | } else { |
2051 | do_update = 1; |
2052 | if (lladdr == NULL) /* (6) */ |
2053 | newstate = ND6_LLINFO_NOSTATE; |
2054 | else /* (7) */ |
2055 | newstate = ND6_LLINFO_STALE; |
2056 | } |
2057 | |
2058 | if (do_update) { |
2059 | /* |
2060 | * Update the state of the neighbor cache. |
2061 | */ |
2062 | ln->ln_state = newstate; |
2063 | |
2064 | if (ln->ln_state == ND6_LLINFO_STALE) { |
2065 | /* |
2066 | * XXX: since nd6_output() below will cause |
2067 | * state tansition to DELAY and reset the timer, |
2068 | * we must set the timer now, although it is actually |
2069 | * meaningless. |
2070 | */ |
2071 | nd6_llinfo_settimer(ln, nd6_gctimer * hz); |
2072 | |
2073 | nd6_llinfo_release_pkts(ln, ifp); |
2074 | } else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) { |
2075 | /* probe right away */ |
2076 | nd6_llinfo_settimer((void *)ln, 0); |
2077 | } |
2078 | } |
2079 | |
2080 | /* |
2081 | * ICMP6 type dependent behavior. |
2082 | * |
2083 | * NS: clear IsRouter if new entry |
2084 | * RS: clear IsRouter |
2085 | * RA: set IsRouter if there's lladdr |
2086 | * redir: clear IsRouter if new entry |
2087 | * |
2088 | * RA case, (1): |
2089 | * The spec says that we must set IsRouter in the following cases: |
2090 | * - If lladdr exist, set IsRouter. This means (1-5). |
2091 | * - If it is old entry (!newentry), set IsRouter. This means (7). |
2092 | * So, based on the spec, in (1-5) and (7) cases we must set IsRouter. |
2093 | * A quetion arises for (1) case. (1) case has no lladdr in the |
2094 | * neighbor cache, this is similar to (6). |
2095 | * This case is rare but we figured that we MUST NOT set IsRouter. |
2096 | * |
2097 | * newentry olladdr lladdr llchange NS RS RA redir |
2098 | * D R |
2099 | * 0 n n -- (1) c ? s |
2100 | * 0 y n -- (2) c s s |
2101 | * 0 n y -- (3) c s s |
2102 | * 0 y y n (4) c s s |
2103 | * 0 y y y (5) c s s |
2104 | * 1 -- n -- (6) c c c s |
2105 | * 1 -- y -- (7) c c s c s |
2106 | * |
2107 | * (c=clear s=set) |
2108 | */ |
2109 | switch (type & 0xff) { |
2110 | case ND_NEIGHBOR_SOLICIT: |
2111 | /* |
2112 | * New entry must have is_router flag cleared. |
2113 | */ |
2114 | if (is_newentry) /* (6-7) */ |
2115 | ln->ln_router = 0; |
2116 | break; |
2117 | case ND_REDIRECT: |
2118 | /* |
2119 | * If the icmp is a redirect to a better router, always set the |
2120 | * is_router flag. Otherwise, if the entry is newly created, |
2121 | * clear the flag. [RFC 2461, sec 8.3] |
2122 | */ |
2123 | if (code == ND_REDIRECT_ROUTER) |
2124 | ln->ln_router = 1; |
2125 | else if (is_newentry) /* (6-7) */ |
2126 | ln->ln_router = 0; |
2127 | break; |
2128 | case ND_ROUTER_SOLICIT: |
2129 | /* |
2130 | * is_router flag must always be cleared. |
2131 | */ |
2132 | ln->ln_router = 0; |
2133 | break; |
2134 | case ND_ROUTER_ADVERT: |
2135 | /* |
2136 | * Mark an entry with lladdr as a router. |
2137 | */ |
2138 | if ((!is_newentry && (olladdr || lladdr)) || /* (2-5) */ |
2139 | (is_newentry && lladdr)) { /* (7) */ |
2140 | ln->ln_router = 1; |
2141 | } |
2142 | break; |
2143 | } |
2144 | |
2145 | #if 0 |
2146 | /* XXX should we send rtmsg as it used to be? */ |
2147 | if (do_update) |
2148 | rt_newmsg(RTM_CHANGE, rt); /* tell user process */ |
2149 | #endif |
2150 | |
2151 | if (ln != NULL) { |
2152 | router = ln->ln_router; |
2153 | LLE_WUNLOCK(ln); |
2154 | } |
2155 | |
2156 | /* |
2157 | * If we have too many cache entries, initiate immediate |
2158 | * purging for some entries. |
2159 | */ |
2160 | if (is_newentry) |
2161 | nd6_gc_neighbors(LLTABLE6(ifp), &ln->r_l3addr.addr6); |
2162 | |
2163 | /* |
2164 | * When the link-layer address of a router changes, select the |
2165 | * best router again. In particular, when the neighbor entry is newly |
2166 | * created, it might affect the selection policy. |
2167 | * Question: can we restrict the first condition to the "is_newentry" |
2168 | * case? |
2169 | * XXX: when we hear an RA from a new router with the link-layer |
2170 | * address option, defrouter_select() is called twice, since |
2171 | * defrtrlist_update called the function as well. However, I believe |
2172 | * we can compromise the overhead, since it only happens the first |
2173 | * time. |
2174 | * XXX: although defrouter_select() should not have a bad effect |
2175 | * for those are not autoconfigured hosts, we explicitly avoid such |
2176 | * cases for safety. |
2177 | */ |
2178 | if (do_update && router && !ip6_forwarding && |
2179 | nd6_accepts_rtadv(ndi)) |
2180 | defrouter_select(); |
2181 | } |
2182 | |
2183 | static void |
2184 | nd6_slowtimo(void *ignored_arg) |
2185 | { |
2186 | struct nd_ifinfo *nd6if; |
2187 | struct ifnet *ifp; |
2188 | int s; |
2189 | |
2190 | #ifndef NET_MPSAFE |
2191 | mutex_enter(softnet_lock); |
2192 | KERNEL_LOCK(1, NULL); |
2193 | #endif |
2194 | callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, |
2195 | nd6_slowtimo, NULL); |
2196 | |
2197 | s = pserialize_read_enter(); |
2198 | IFNET_READER_FOREACH(ifp) { |
2199 | nd6if = ND_IFINFO(ifp); |
2200 | if (nd6if->basereachable && /* already initialized */ |
2201 | (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) { |
2202 | /* |
2203 | * Since reachable time rarely changes by router |
2204 | * advertisements, we SHOULD insure that a new random |
2205 | * value gets recomputed at least once every few hours. |
2206 | * (RFC 2461, 6.3.4) |
2207 | */ |
2208 | nd6if->recalctm = nd6_recalc_reachtm_interval; |
2209 | nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable); |
2210 | } |
2211 | } |
2212 | pserialize_read_exit(s); |
2213 | |
2214 | #ifndef NET_MPSAFE |
2215 | KERNEL_UNLOCK_ONE(NULL); |
2216 | mutex_exit(softnet_lock); |
2217 | #endif |
2218 | } |
2219 | |
2220 | int |
2221 | nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m, |
2222 | const struct sockaddr_in6 *dst, struct rtentry *rt) |
2223 | { |
2224 | #define senderr(e) { error = (e); goto bad;} |
2225 | struct llentry *ln = NULL; |
2226 | int error = 0; |
2227 | bool created = false; |
2228 | |
2229 | if (rt != NULL) { |
2230 | error = rt_check_reject_route(rt, ifp); |
2231 | if (error != 0) { |
2232 | m_freem(m); |
2233 | return error; |
2234 | } |
2235 | } |
2236 | |
2237 | if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr)) |
2238 | goto sendpkt; |
2239 | |
2240 | if (nd6_need_cache(ifp) == 0) |
2241 | goto sendpkt; |
2242 | |
2243 | if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) != 0) { |
2244 | struct sockaddr_in6 *gw6 = satosin6(rt->rt_gateway); |
2245 | int s; |
2246 | |
2247 | /* XXX remain the check to keep the original behavior. */ |
2248 | /* |
2249 | * We skip link-layer address resolution and NUD |
2250 | * if the gateway is not a neighbor from ND point |
2251 | * of view, regardless of the value of nd_ifinfo.flags. |
2252 | * The second condition is a bit tricky; we skip |
2253 | * if the gateway is our own address, which is |
2254 | * sometimes used to install a route to a p2p link. |
2255 | */ |
2256 | s = pserialize_read_enter(); |
2257 | if (!nd6_is_addr_neighbor(gw6, ifp) || |
2258 | in6ifa_ifpwithaddr(ifp, &gw6->sin6_addr)) { |
2259 | /* |
2260 | * We allow this kind of tricky route only |
2261 | * when the outgoing interface is p2p. |
2262 | * XXX: we may need a more generic rule here. |
2263 | */ |
2264 | if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { |
2265 | pserialize_read_exit(s); |
2266 | senderr(EHOSTUNREACH); |
2267 | } |
2268 | |
2269 | pserialize_read_exit(s); |
2270 | goto sendpkt; |
2271 | } |
2272 | pserialize_read_exit(s); |
2273 | } |
2274 | |
2275 | /* |
2276 | * Address resolution or Neighbor Unreachability Detection |
2277 | * for the next hop. |
2278 | * At this point, the destination of the packet must be a unicast |
2279 | * or an anycast address(i.e. not a multicast). |
2280 | */ |
2281 | |
2282 | /* Look up the neighbor cache for the nexthop */ |
2283 | ln = nd6_lookup(&dst->sin6_addr, ifp, true); |
2284 | if ((ln == NULL) && nd6_is_addr_neighbor(dst, ifp)) { |
2285 | /* |
2286 | * Since nd6_is_addr_neighbor() internally calls nd6_lookup(), |
2287 | * the condition below is not very efficient. But we believe |
2288 | * it is tolerable, because this should be a rare case. |
2289 | */ |
2290 | ln = nd6_create(&dst->sin6_addr, ifp); |
2291 | if (ln != NULL) |
2292 | created = true; |
2293 | } |
2294 | |
2295 | if (ln == NULL) { |
2296 | if ((ifp->if_flags & IFF_POINTOPOINT) == 0 && |
2297 | !(ND_IFINFO(ifp)->flags & ND6_IFF_PERFORMNUD)) { |
2298 | log(LOG_DEBUG, |
2299 | "nd6_output: can't allocate llinfo for %s " |
2300 | "(ln=%p, rt=%p)\n" , |
2301 | ip6_sprintf(&dst->sin6_addr), ln, rt); |
2302 | senderr(EIO); /* XXX: good error? */ |
2303 | } |
2304 | goto sendpkt; /* send anyway */ |
2305 | } |
2306 | |
2307 | LLE_WLOCK_ASSERT(ln); |
2308 | |
2309 | /* We don't have to do link-layer address resolution on a p2p link. */ |
2310 | if ((ifp->if_flags & IFF_POINTOPOINT) != 0 && |
2311 | ln->ln_state < ND6_LLINFO_REACHABLE) { |
2312 | ln->ln_state = ND6_LLINFO_STALE; |
2313 | nd6_llinfo_settimer(ln, nd6_gctimer * hz); |
2314 | } |
2315 | |
2316 | /* |
2317 | * The first time we send a packet to a neighbor whose entry is |
2318 | * STALE, we have to change the state to DELAY and a sets a timer to |
2319 | * expire in DELAY_FIRST_PROBE_TIME seconds to ensure do |
2320 | * neighbor unreachability detection on expiration. |
2321 | * (RFC 2461 7.3.3) |
2322 | */ |
2323 | if (ln->ln_state == ND6_LLINFO_STALE) { |
2324 | ln->ln_asked = 0; |
2325 | ln->ln_state = ND6_LLINFO_DELAY; |
2326 | nd6_llinfo_settimer(ln, nd6_delay * hz); |
2327 | } |
2328 | |
2329 | /* |
2330 | * If the neighbor cache entry has a state other than INCOMPLETE |
2331 | * (i.e. its link-layer address is already resolved), just |
2332 | * send the packet. |
2333 | */ |
2334 | if (ln->ln_state > ND6_LLINFO_INCOMPLETE) |
2335 | goto sendpkt; |
2336 | |
2337 | /* |
2338 | * There is a neighbor cache entry, but no ethernet address |
2339 | * response yet. Append this latest packet to the end of the |
2340 | * packet queue in the mbuf, unless the number of the packet |
2341 | * does not exceed nd6_maxqueuelen. When it exceeds nd6_maxqueuelen, |
2342 | * the oldest packet in the queue will be removed. |
2343 | */ |
2344 | if (ln->ln_state == ND6_LLINFO_NOSTATE) |
2345 | ln->ln_state = ND6_LLINFO_INCOMPLETE; |
2346 | if (ln->ln_hold) { |
2347 | struct mbuf *m_hold; |
2348 | int i; |
2349 | |
2350 | i = 0; |
2351 | for (m_hold = ln->ln_hold; m_hold; m_hold = m_hold->m_nextpkt) { |
2352 | i++; |
2353 | if (m_hold->m_nextpkt == NULL) { |
2354 | m_hold->m_nextpkt = m; |
2355 | break; |
2356 | } |
2357 | } |
2358 | while (i >= nd6_maxqueuelen) { |
2359 | m_hold = ln->ln_hold; |
2360 | ln->ln_hold = ln->ln_hold->m_nextpkt; |
2361 | m_freem(m_hold); |
2362 | i--; |
2363 | } |
2364 | } else { |
2365 | ln->ln_hold = m; |
2366 | } |
2367 | |
2368 | /* |
2369 | * If there has been no NS for the neighbor after entering the |
2370 | * INCOMPLETE state, send the first solicitation. |
2371 | */ |
2372 | if (!ND6_LLINFO_PERMANENT(ln) && ln->ln_asked == 0) { |
2373 | struct in6_addr src, *psrc; |
2374 | |
2375 | ln->ln_asked++; |
2376 | nd6_llinfo_settimer(ln, ND_IFINFO(ifp)->retrans * hz / 1000); |
2377 | psrc = nd6_llinfo_get_holdsrc(ln, &src); |
2378 | LLE_WUNLOCK(ln); |
2379 | ln = NULL; |
2380 | nd6_ns_output(ifp, NULL, &dst->sin6_addr, psrc, 0); |
2381 | } else { |
2382 | /* We did the lookup so we need to do the unlock here. */ |
2383 | LLE_WUNLOCK(ln); |
2384 | } |
2385 | |
2386 | error = 0; |
2387 | goto exit; |
2388 | |
2389 | sendpkt: |
2390 | /* discard the packet if IPv6 operation is disabled on the interface */ |
2391 | if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) { |
2392 | error = ENETDOWN; /* better error? */ |
2393 | goto bad; |
2394 | } |
2395 | |
2396 | if (ln != NULL) |
2397 | LLE_WUNLOCK(ln); |
2398 | |
2399 | if ((ifp->if_flags & IFF_LOOPBACK) != 0) |
2400 | error = if_output_lock(ifp, origifp, m, sin6tocsa(dst), rt); |
2401 | else |
2402 | error = if_output_lock(ifp, ifp, m, sin6tocsa(dst), rt); |
2403 | goto exit; |
2404 | |
2405 | bad: |
2406 | if (m != NULL) |
2407 | m_freem(m); |
2408 | exit: |
2409 | if (created) |
2410 | nd6_gc_neighbors(LLTABLE6(ifp), &dst->sin6_addr); |
2411 | |
2412 | return error; |
2413 | #undef senderr |
2414 | } |
2415 | |
2416 | int |
2417 | nd6_need_cache(struct ifnet *ifp) |
2418 | { |
2419 | /* |
2420 | * XXX: we currently do not make neighbor cache on any interface |
2421 | * other than ARCnet, Ethernet, FDDI and GIF. |
2422 | * |
2423 | * RFC2893 says: |
2424 | * - unidirectional tunnels needs no ND |
2425 | */ |
2426 | switch (ifp->if_type) { |
2427 | case IFT_ARCNET: |
2428 | case IFT_ETHER: |
2429 | case IFT_FDDI: |
2430 | case IFT_IEEE1394: |
2431 | case IFT_CARP: |
2432 | case IFT_GIF: /* XXX need more cases? */ |
2433 | case IFT_PPP: |
2434 | case IFT_TUNNEL: |
2435 | return 1; |
2436 | default: |
2437 | return 0; |
2438 | } |
2439 | } |
2440 | |
2441 | /* |
2442 | * Add pernament ND6 link-layer record for given |
2443 | * interface address. |
2444 | * |
2445 | * Very similar to IPv4 arp_ifinit(), but: |
2446 | * 1) IPv6 DAD is performed in different place |
2447 | * 2) It is called by IPv6 protocol stack in contrast to |
2448 | * arp_ifinit() which is typically called in SIOCSIFADDR |
2449 | * driver ioctl handler. |
2450 | * |
2451 | */ |
2452 | int |
2453 | nd6_add_ifa_lle(struct in6_ifaddr *ia) |
2454 | { |
2455 | struct ifnet *ifp; |
2456 | struct llentry *ln; |
2457 | |
2458 | ifp = ia->ia_ifa.ifa_ifp; |
2459 | if (nd6_need_cache(ifp) == 0) |
2460 | return 0; |
2461 | ia->ia_ifa.ifa_rtrequest = nd6_rtrequest; |
2462 | ia->ia_ifa.ifa_flags |= RTF_CONNECTED; |
2463 | |
2464 | IF_AFDATA_WLOCK(ifp); |
2465 | ln = lla_create(LLTABLE6(ifp), LLE_IFADDR | LLE_EXCLUSIVE, |
2466 | sin6tosa(&ia->ia_addr)); |
2467 | IF_AFDATA_WUNLOCK(ifp); |
2468 | if (ln == NULL) |
2469 | return ENOBUFS; |
2470 | |
2471 | ln->la_expire = 0; /* for IPv6 this means permanent */ |
2472 | ln->ln_state = ND6_LLINFO_REACHABLE; |
2473 | |
2474 | LLE_WUNLOCK(ln); |
2475 | return 0; |
2476 | } |
2477 | |
2478 | /* |
2479 | * Removes ALL lle records for interface address prefix. |
2480 | * XXXME: That's probably not we really want to do, we need |
2481 | * to remove address record only and keep other records |
2482 | * until we determine if given prefix is really going |
2483 | * to be removed. |
2484 | */ |
2485 | void |
2486 | nd6_rem_ifa_lle(struct in6_ifaddr *ia) |
2487 | { |
2488 | struct sockaddr_in6 mask, addr; |
2489 | |
2490 | memcpy(&addr, &ia->ia_addr, sizeof(ia->ia_addr)); |
2491 | memcpy(&mask, &ia->ia_prefixmask, sizeof(ia->ia_prefixmask)); |
2492 | lltable_prefix_free(AF_INET6, sin6tosa(&addr), sin6tosa(&mask), |
2493 | LLE_STATIC); |
2494 | } |
2495 | |
2496 | int |
2497 | nd6_storelladdr(const struct ifnet *ifp, const struct rtentry *rt, |
2498 | struct mbuf *m, const struct sockaddr *dst, uint8_t *lldst, |
2499 | size_t dstsize) |
2500 | { |
2501 | struct llentry *ln; |
2502 | |
2503 | if (m->m_flags & M_MCAST) { |
2504 | switch (ifp->if_type) { |
2505 | case IFT_ETHER: |
2506 | case IFT_FDDI: |
2507 | ETHER_MAP_IPV6_MULTICAST(&satocsin6(dst)->sin6_addr, |
2508 | lldst); |
2509 | return 1; |
2510 | case IFT_IEEE1394: |
2511 | memcpy(lldst, ifp->if_broadcastaddr, |
2512 | MIN(dstsize, ifp->if_addrlen)); |
2513 | return 1; |
2514 | case IFT_ARCNET: |
2515 | *lldst = 0; |
2516 | return 1; |
2517 | default: |
2518 | m_freem(m); |
2519 | return 0; |
2520 | } |
2521 | } |
2522 | |
2523 | /* |
2524 | * the entry should have been created in nd6_store_lladdr |
2525 | */ |
2526 | ln = nd6_lookup(&satocsin6(dst)->sin6_addr, ifp, false); |
2527 | if ((ln == NULL) || !(ln->la_flags & LLE_VALID)) { |
2528 | if (ln != NULL) |
2529 | LLE_RUNLOCK(ln); |
2530 | /* this could happen, if we could not allocate memory */ |
2531 | m_freem(m); |
2532 | return 0; |
2533 | } |
2534 | |
2535 | /* XXX llentry should have addrlen? */ |
2536 | #if 0 |
2537 | sdl = satocsdl(rt->rt_gateway); |
2538 | if (sdl->sdl_alen == 0 || sdl->sdl_alen > dstsize) { |
2539 | char sbuf[INET6_ADDRSTRLEN]; |
2540 | char dbuf[LINK_ADDRSTRLEN]; |
2541 | /* this should be impossible, but we bark here for debugging */ |
2542 | printf("%s: sdl_alen == %" PRIu8 ", if=%s, dst=%s, sdl=%s\n" , |
2543 | __func__, sdl->sdl_alen, if_name(ifp), |
2544 | IN6_PRINT(sbuf, &satocsin6(dst)->sin6_addr), |
2545 | DL_PRINT(dbuf, &sdl->sdl_addr)); |
2546 | m_freem(m); |
2547 | return 0; |
2548 | } |
2549 | #endif |
2550 | |
2551 | memcpy(lldst, &ln->ll_addr, MIN(dstsize, ifp->if_addrlen)); |
2552 | |
2553 | LLE_RUNLOCK(ln); |
2554 | |
2555 | return 1; |
2556 | } |
2557 | |
2558 | static void |
2559 | clear_llinfo_pqueue(struct llentry *ln) |
2560 | { |
2561 | struct mbuf *m_hold, *m_hold_next; |
2562 | |
2563 | for (m_hold = ln->ln_hold; m_hold; m_hold = m_hold_next) { |
2564 | m_hold_next = m_hold->m_nextpkt; |
2565 | m_hold->m_nextpkt = NULL; |
2566 | m_freem(m_hold); |
2567 | } |
2568 | |
2569 | ln->ln_hold = NULL; |
2570 | return; |
2571 | } |
2572 | |
2573 | int |
2574 | nd6_sysctl( |
2575 | int name, |
2576 | void *oldp, /* syscall arg, need copyout */ |
2577 | size_t *oldlenp, |
2578 | void *newp, /* syscall arg, need copyin */ |
2579 | size_t newlen |
2580 | ) |
2581 | { |
2582 | void *p; |
2583 | size_t ol; |
2584 | int error; |
2585 | |
2586 | error = 0; |
2587 | |
2588 | if (newp) |
2589 | return EPERM; |
2590 | if (oldp && !oldlenp) |
2591 | return EINVAL; |
2592 | ol = oldlenp ? *oldlenp : 0; |
2593 | |
2594 | if (oldp) { |
2595 | p = malloc(*oldlenp, M_TEMP, M_WAITOK); |
2596 | if (p == NULL) |
2597 | return ENOMEM; |
2598 | } else |
2599 | p = NULL; |
2600 | switch (name) { |
2601 | case ICMPV6CTL_ND6_DRLIST: |
2602 | error = fill_drlist(p, oldlenp, ol); |
2603 | if (!error && p != NULL && oldp != NULL) |
2604 | error = copyout(p, oldp, *oldlenp); |
2605 | break; |
2606 | |
2607 | case ICMPV6CTL_ND6_PRLIST: |
2608 | error = fill_prlist(p, oldlenp, ol); |
2609 | if (!error && p != NULL && oldp != NULL) |
2610 | error = copyout(p, oldp, *oldlenp); |
2611 | break; |
2612 | |
2613 | case ICMPV6CTL_ND6_MAXQLEN: |
2614 | break; |
2615 | |
2616 | default: |
2617 | error = ENOPROTOOPT; |
2618 | break; |
2619 | } |
2620 | if (p) |
2621 | free(p, M_TEMP); |
2622 | |
2623 | return error; |
2624 | } |
2625 | |
2626 | static int |
2627 | fill_drlist(void *oldp, size_t *oldlenp, size_t ol) |
2628 | { |
2629 | int error = 0, s; |
2630 | struct in6_defrouter *d = NULL, *de = NULL; |
2631 | struct nd_defrouter *dr; |
2632 | size_t l; |
2633 | |
2634 | s = splsoftnet(); |
2635 | |
2636 | if (oldp) { |
2637 | d = (struct in6_defrouter *)oldp; |
2638 | de = (struct in6_defrouter *)((char *)oldp + *oldlenp); |
2639 | } |
2640 | l = 0; |
2641 | |
2642 | TAILQ_FOREACH(dr, &nd_defrouter, dr_entry) { |
2643 | |
2644 | if (oldp && d + 1 <= de) { |
2645 | memset(d, 0, sizeof(*d)); |
2646 | sockaddr_in6_init(&d->rtaddr, &dr->rtaddr, 0, 0, 0); |
2647 | if (sa6_recoverscope(&d->rtaddr)) { |
2648 | log(LOG_ERR, |
2649 | "scope error in router list (%s)\n" , |
2650 | ip6_sprintf(&d->rtaddr.sin6_addr)); |
2651 | /* XXX: press on... */ |
2652 | } |
2653 | d->flags = dr->flags; |
2654 | d->rtlifetime = dr->rtlifetime; |
2655 | d->expire = dr->expire ? |
2656 | time_mono_to_wall(dr->expire) : 0; |
2657 | d->if_index = dr->ifp->if_index; |
2658 | } |
2659 | |
2660 | l += sizeof(*d); |
2661 | if (d) |
2662 | d++; |
2663 | } |
2664 | |
2665 | if (oldp) { |
2666 | if (l > ol) |
2667 | error = ENOMEM; |
2668 | } |
2669 | if (oldlenp) |
2670 | *oldlenp = l; /* (void *)d - (void *)oldp */ |
2671 | |
2672 | splx(s); |
2673 | |
2674 | return error; |
2675 | } |
2676 | |
2677 | static int |
2678 | fill_prlist(void *oldp, size_t *oldlenp, size_t ol) |
2679 | { |
2680 | int error = 0, s; |
2681 | struct nd_prefix *pr; |
2682 | uint8_t *p = NULL, *ps = NULL; |
2683 | uint8_t *pe = NULL; |
2684 | size_t l; |
2685 | |
2686 | s = splsoftnet(); |
2687 | |
2688 | if (oldp) { |
2689 | ps = p = (uint8_t*)oldp; |
2690 | pe = (uint8_t*)oldp + *oldlenp; |
2691 | } |
2692 | l = 0; |
2693 | |
2694 | LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { |
2695 | u_short advrtrs; |
2696 | struct sockaddr_in6 sin6; |
2697 | struct nd_pfxrouter *pfr; |
2698 | struct in6_prefix pfx; |
2699 | |
2700 | if (oldp && p + sizeof(struct in6_prefix) <= pe) |
2701 | { |
2702 | memset(&pfx, 0, sizeof(pfx)); |
2703 | ps = p; |
2704 | pfx.prefix = pr->ndpr_prefix; |
2705 | |
2706 | if (sa6_recoverscope(&pfx.prefix)) { |
2707 | log(LOG_ERR, |
2708 | "scope error in prefix list (%s)\n" , |
2709 | ip6_sprintf(&pfx.prefix.sin6_addr)); |
2710 | /* XXX: press on... */ |
2711 | } |
2712 | pfx.raflags = pr->ndpr_raf; |
2713 | pfx.prefixlen = pr->ndpr_plen; |
2714 | pfx.vltime = pr->ndpr_vltime; |
2715 | pfx.pltime = pr->ndpr_pltime; |
2716 | pfx.if_index = pr->ndpr_ifp->if_index; |
2717 | if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME) |
2718 | pfx.expire = 0; |
2719 | else { |
2720 | time_t maxexpire; |
2721 | |
2722 | /* XXX: we assume time_t is signed. */ |
2723 | maxexpire = (-1) & |
2724 | ~((time_t)1 << |
2725 | ((sizeof(maxexpire) * 8) - 1)); |
2726 | if (pr->ndpr_vltime < |
2727 | maxexpire - pr->ndpr_lastupdate) { |
2728 | pfx.expire = pr->ndpr_lastupdate + |
2729 | pr->ndpr_vltime; |
2730 | } else |
2731 | pfx.expire = maxexpire; |
2732 | } |
2733 | pfx.refcnt = pr->ndpr_refcnt; |
2734 | pfx.flags = pr->ndpr_stateflags; |
2735 | pfx.origin = PR_ORIG_RA; |
2736 | |
2737 | p += sizeof(pfx); l += sizeof(pfx); |
2738 | |
2739 | advrtrs = 0; |
2740 | LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) { |
2741 | if (p + sizeof(sin6) > pe) { |
2742 | advrtrs++; |
2743 | continue; |
2744 | } |
2745 | |
2746 | sockaddr_in6_init(&sin6, &pfr->router->rtaddr, |
2747 | 0, 0, 0); |
2748 | if (sa6_recoverscope(&sin6)) { |
2749 | log(LOG_ERR, |
2750 | "scope error in " |
2751 | "prefix list (%s)\n" , |
2752 | ip6_sprintf(&pfr->router->rtaddr)); |
2753 | } |
2754 | advrtrs++; |
2755 | memcpy(p, &sin6, sizeof(sin6)); |
2756 | p += sizeof(sin6); |
2757 | l += sizeof(sin6); |
2758 | } |
2759 | pfx.advrtrs = advrtrs; |
2760 | memcpy(ps, &pfx, sizeof(pfx)); |
2761 | } |
2762 | else { |
2763 | l += sizeof(pfx); |
2764 | advrtrs = 0; |
2765 | LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) { |
2766 | advrtrs++; |
2767 | l += sizeof(sin6); |
2768 | } |
2769 | } |
2770 | } |
2771 | |
2772 | if (oldp) { |
2773 | *oldlenp = l; /* (void *)d - (void *)oldp */ |
2774 | if (l > ol) |
2775 | error = ENOMEM; |
2776 | } else |
2777 | *oldlenp = l; |
2778 | |
2779 | splx(s); |
2780 | |
2781 | return error; |
2782 | } |
2783 | |