Line data Source code
1 : /* $OpenBSD: nd6.c,v 1.226 2018/08/03 09:11:56 florian Exp $ */
2 : /* $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 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/param.h>
34 : #include <sys/systm.h>
35 : #include <sys/timeout.h>
36 : #include <sys/malloc.h>
37 : #include <sys/mbuf.h>
38 : #include <sys/socket.h>
39 : #include <sys/sockio.h>
40 : #include <sys/time.h>
41 : #include <sys/kernel.h>
42 : #include <sys/pool.h>
43 : #include <sys/protosw.h>
44 : #include <sys/errno.h>
45 : #include <sys/ioctl.h>
46 : #include <sys/syslog.h>
47 : #include <sys/queue.h>
48 : #include <sys/stdint.h>
49 : #include <sys/task.h>
50 :
51 : #include <net/if.h>
52 : #include <net/if_dl.h>
53 : #include <net/if_types.h>
54 : #include <net/route.h>
55 :
56 : #include <netinet/in.h>
57 : #include <netinet/if_ether.h>
58 : #include <netinet/ip_ipsp.h>
59 :
60 : #include <netinet6/in6_var.h>
61 : #include <netinet/ip6.h>
62 : #include <netinet6/ip6_var.h>
63 : #include <netinet6/nd6.h>
64 : #include <netinet/icmp6.h>
65 :
66 : #define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */
67 : #define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */
68 :
69 : /* timer values */
70 : int nd6_timer_next = -1; /* at which time_uptime nd6_timer runs */
71 : time_t nd6_expire_next = -1; /* at which time_uptime nd6_expire runs */
72 : int nd6_delay = 5; /* delay first probe time 5 second */
73 : int nd6_umaxtries = 3; /* maximum unicast query */
74 : int nd6_mmaxtries = 3; /* maximum multicast query */
75 : int nd6_gctimer = (60 * 60 * 24); /* 1 day: garbage collection timer */
76 :
77 : /* preventing too many loops in ND option parsing */
78 : int nd6_maxndopt = 10; /* max # of ND options allowed */
79 :
80 : int nd6_maxnudhint = 0; /* max # of subsequent upper layer hints */
81 :
82 : #ifdef ND6_DEBUG
83 : int nd6_debug = 1;
84 : #else
85 : int nd6_debug = 0;
86 : #endif
87 :
88 : TAILQ_HEAD(llinfo_nd6_head, llinfo_nd6) nd6_list;
89 : struct pool nd6_pool; /* pool for llinfo_nd6 structures */
90 : int nd6_inuse, nd6_allocated;
91 :
92 : int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
93 :
94 : void nd6_timer(void *);
95 : void nd6_slowtimo(void *);
96 : void nd6_expire(void *);
97 : void nd6_expire_timer(void *);
98 : void nd6_invalidate(struct rtentry *);
99 : void nd6_free(struct rtentry *);
100 : int nd6_llinfo_timer(struct rtentry *);
101 :
102 : struct timeout nd6_timer_to;
103 : struct timeout nd6_slowtimo_ch;
104 : struct timeout nd6_expire_timeout;
105 : struct task nd6_expire_task;
106 :
107 : void
108 0 : nd6_init(void)
109 : {
110 : static int nd6_init_done = 0;
111 :
112 0 : if (nd6_init_done) {
113 0 : log(LOG_NOTICE, "%s called more than once\n", __func__);
114 0 : return;
115 : }
116 :
117 0 : TAILQ_INIT(&nd6_list);
118 0 : pool_init(&nd6_pool, sizeof(struct llinfo_nd6), 0,
119 : IPL_SOFTNET, 0, "nd6", NULL);
120 :
121 0 : task_set(&nd6_expire_task, nd6_expire, NULL);
122 :
123 0 : nd6_init_done = 1;
124 :
125 : /* start timer */
126 0 : timeout_set_proc(&nd6_timer_to, nd6_timer, &nd6_timer_to);
127 0 : timeout_set_proc(&nd6_slowtimo_ch, nd6_slowtimo, NULL);
128 0 : timeout_add_sec(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL);
129 0 : timeout_set(&nd6_expire_timeout, nd6_expire_timer, NULL);
130 0 : }
131 :
132 : struct nd_ifinfo *
133 0 : nd6_ifattach(struct ifnet *ifp)
134 : {
135 : struct nd_ifinfo *nd;
136 :
137 0 : nd = malloc(sizeof(*nd), M_IP6NDP, M_WAITOK | M_ZERO);
138 :
139 0 : nd->initialized = 1;
140 :
141 0 : nd->basereachable = REACHABLE_TIME;
142 0 : nd->reachable = ND_COMPUTE_RTIME(nd->basereachable);
143 0 : nd->retrans = RETRANS_TIMER;
144 : /* per-interface IFXF_AUTOCONF6 needs to be set too to accept RAs */
145 :
146 0 : return nd;
147 : }
148 :
149 : void
150 0 : nd6_ifdetach(struct nd_ifinfo *nd)
151 : {
152 :
153 0 : free(nd, M_IP6NDP, sizeof(*nd));
154 0 : }
155 :
156 : void
157 0 : nd6_option_init(void *opt, int icmp6len, union nd_opts *ndopts)
158 : {
159 0 : bzero(ndopts, sizeof(*ndopts));
160 0 : ndopts->nd_opts_search = (struct nd_opt_hdr *)opt;
161 0 : ndopts->nd_opts_last
162 0 : = (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len);
163 :
164 0 : if (icmp6len == 0) {
165 0 : ndopts->nd_opts_done = 1;
166 0 : ndopts->nd_opts_search = NULL;
167 0 : }
168 0 : }
169 :
170 : /*
171 : * Take one ND option.
172 : */
173 : struct nd_opt_hdr *
174 0 : nd6_option(union nd_opts *ndopts)
175 : {
176 : struct nd_opt_hdr *nd_opt;
177 : int olen;
178 :
179 0 : if (!ndopts)
180 0 : panic("ndopts == NULL in nd6_option");
181 0 : if (!ndopts->nd_opts_last)
182 0 : panic("%s: uninitialized ndopts", __func__);
183 0 : if (!ndopts->nd_opts_search)
184 0 : return NULL;
185 0 : if (ndopts->nd_opts_done)
186 0 : return NULL;
187 :
188 : nd_opt = ndopts->nd_opts_search;
189 :
190 : /* make sure nd_opt_len is inside the buffer */
191 0 : if ((caddr_t)&nd_opt->nd_opt_len >= (caddr_t)ndopts->nd_opts_last) {
192 0 : bzero(ndopts, sizeof(*ndopts));
193 0 : return NULL;
194 : }
195 :
196 0 : olen = nd_opt->nd_opt_len << 3;
197 0 : if (olen == 0) {
198 : /*
199 : * Message validation requires that all included
200 : * options have a length that is greater than zero.
201 : */
202 0 : bzero(ndopts, sizeof(*ndopts));
203 0 : return NULL;
204 : }
205 :
206 0 : ndopts->nd_opts_search = (struct nd_opt_hdr *)((caddr_t)nd_opt + olen);
207 0 : if (ndopts->nd_opts_search > ndopts->nd_opts_last) {
208 : /* option overruns the end of buffer, invalid */
209 0 : bzero(ndopts, sizeof(*ndopts));
210 0 : return NULL;
211 0 : } else if (ndopts->nd_opts_search == ndopts->nd_opts_last) {
212 : /* reached the end of options chain */
213 0 : ndopts->nd_opts_done = 1;
214 0 : ndopts->nd_opts_search = NULL;
215 0 : }
216 0 : return nd_opt;
217 0 : }
218 :
219 : /*
220 : * Parse multiple ND options.
221 : * This function is much easier to use, for ND routines that do not need
222 : * multiple options of the same type.
223 : */
224 : int
225 0 : nd6_options(union nd_opts *ndopts)
226 : {
227 : struct nd_opt_hdr *nd_opt;
228 : int i = 0;
229 :
230 0 : if (!ndopts)
231 0 : panic("ndopts == NULL in nd6_options");
232 0 : if (!ndopts->nd_opts_last)
233 0 : panic("%s: uninitialized ndopts", __func__);
234 0 : if (!ndopts->nd_opts_search)
235 0 : return 0;
236 :
237 0 : while (1) {
238 0 : nd_opt = nd6_option(ndopts);
239 0 : if (!nd_opt && !ndopts->nd_opts_last) {
240 : /*
241 : * Message validation requires that all included
242 : * options have a length that is greater than zero.
243 : */
244 0 : icmp6stat_inc(icp6s_nd_badopt);
245 0 : bzero(ndopts, sizeof(*ndopts));
246 0 : return -1;
247 : }
248 :
249 0 : if (!nd_opt)
250 : goto skip1;
251 :
252 0 : switch (nd_opt->nd_opt_type) {
253 : case ND_OPT_SOURCE_LINKADDR:
254 : case ND_OPT_TARGET_LINKADDR:
255 : case ND_OPT_MTU:
256 : case ND_OPT_REDIRECTED_HEADER:
257 0 : if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
258 0 : nd6log((LOG_INFO,
259 : "duplicated ND6 option found (type=%d)\n",
260 : nd_opt->nd_opt_type));
261 : /* XXX bark? */
262 : } else {
263 : ndopts->nd_opt_array[nd_opt->nd_opt_type]
264 0 : = nd_opt;
265 : }
266 : break;
267 : case ND_OPT_PREFIX_INFORMATION:
268 0 : if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) {
269 : ndopts->nd_opt_array[nd_opt->nd_opt_type]
270 0 : = nd_opt;
271 0 : }
272 0 : ndopts->nd_opts_pi_end =
273 0 : (struct nd_opt_prefix_info *)nd_opt;
274 0 : break;
275 : default:
276 : /*
277 : * Unknown options must be silently ignored,
278 : * to accommodate future extension to the protocol.
279 : */
280 0 : nd6log((LOG_DEBUG,
281 : "nd6_options: unsupported option %d - "
282 : "option ignored\n", nd_opt->nd_opt_type));
283 : }
284 :
285 : skip1:
286 0 : i++;
287 0 : if (i > nd6_maxndopt) {
288 0 : icmp6stat_inc(icp6s_nd_toomanyopt);
289 0 : nd6log((LOG_INFO, "too many loop in nd opt\n"));
290 : break;
291 : }
292 :
293 0 : if (ndopts->nd_opts_done)
294 : break;
295 : }
296 :
297 0 : return 0;
298 0 : }
299 :
300 : /*
301 : * ND6 timer routine to handle ND6 entries
302 : */
303 : void
304 0 : nd6_llinfo_settimer(struct llinfo_nd6 *ln, unsigned int secs)
305 : {
306 0 : time_t expire = time_uptime + secs;
307 :
308 0 : NET_ASSERT_LOCKED();
309 :
310 0 : ln->ln_rt->rt_expire = expire;
311 0 : if (!timeout_pending(&nd6_timer_to) || expire < nd6_timer_next) {
312 0 : nd6_timer_next = expire;
313 0 : timeout_add_sec(&nd6_timer_to, secs);
314 0 : }
315 0 : }
316 :
317 : void
318 0 : nd6_timer(void *arg)
319 : {
320 : struct llinfo_nd6 *ln, *nln;
321 0 : time_t expire = time_uptime + nd6_gctimer;
322 : int secs;
323 :
324 0 : NET_LOCK();
325 0 : TAILQ_FOREACH_SAFE(ln, &nd6_list, ln_list, nln) {
326 0 : struct rtentry *rt = ln->ln_rt;
327 :
328 0 : if (rt->rt_expire && rt->rt_expire <= time_uptime)
329 0 : if (nd6_llinfo_timer(rt))
330 0 : continue;
331 :
332 0 : if (rt->rt_expire && rt->rt_expire < expire)
333 0 : expire = rt->rt_expire;
334 0 : }
335 :
336 0 : secs = expire - time_uptime;
337 0 : if (secs < 0)
338 : secs = 0;
339 0 : if (!TAILQ_EMPTY(&nd6_list)) {
340 0 : nd6_timer_next = time_uptime + secs;
341 0 : timeout_add_sec(&nd6_timer_to, secs);
342 0 : }
343 :
344 0 : NET_UNLOCK();
345 0 : }
346 :
347 : /*
348 : * ND timer state handling.
349 : *
350 : * Returns 1 if `rt' should no longer be used, 0 otherwise.
351 : */
352 : int
353 0 : nd6_llinfo_timer(struct rtentry *rt)
354 : {
355 0 : struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
356 0 : struct sockaddr_in6 *dst = satosin6(rt_key(rt));
357 : struct ifnet *ifp;
358 : struct nd_ifinfo *ndi = NULL;
359 :
360 0 : NET_ASSERT_LOCKED();
361 :
362 0 : if ((ifp = if_get(rt->rt_ifidx)) == NULL)
363 0 : return 1;
364 :
365 0 : ndi = ND_IFINFO(ifp);
366 :
367 0 : switch (ln->ln_state) {
368 : case ND6_LLINFO_INCOMPLETE:
369 0 : if (ln->ln_asked < nd6_mmaxtries) {
370 0 : ln->ln_asked++;
371 0 : nd6_llinfo_settimer(ln, ndi->retrans / 1000);
372 0 : nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, 0);
373 0 : } else {
374 0 : struct mbuf *m = ln->ln_hold;
375 0 : if (m) {
376 0 : ln->ln_hold = NULL;
377 : /*
378 : * Fake rcvif to make the ICMP error
379 : * more helpful in diagnosing for the
380 : * receiver.
381 : * XXX: should we consider
382 : * older rcvif?
383 : */
384 0 : m->m_pkthdr.ph_ifidx = rt->rt_ifidx;
385 :
386 0 : icmp6_error(m, ICMP6_DST_UNREACH,
387 : ICMP6_DST_UNREACH_ADDR, 0);
388 0 : if (ln->ln_hold == m) {
389 : /* m is back in ln_hold. Discard. */
390 0 : m_freem(ln->ln_hold);
391 0 : ln->ln_hold = NULL;
392 0 : }
393 : }
394 0 : nd6_free(rt);
395 : ln = NULL;
396 : }
397 : break;
398 : case ND6_LLINFO_REACHABLE:
399 0 : if (!ND6_LLINFO_PERMANENT(ln)) {
400 0 : ln->ln_state = ND6_LLINFO_STALE;
401 0 : nd6_llinfo_settimer(ln, nd6_gctimer);
402 0 : }
403 : break;
404 :
405 : case ND6_LLINFO_STALE:
406 : case ND6_LLINFO_PURGE:
407 : /* Garbage Collection(RFC 2461 5.3) */
408 0 : if (!ND6_LLINFO_PERMANENT(ln)) {
409 0 : nd6_free(rt);
410 : ln = NULL;
411 0 : }
412 : break;
413 :
414 : case ND6_LLINFO_DELAY:
415 0 : if (ndi) {
416 : /* We need NUD */
417 0 : ln->ln_asked = 1;
418 0 : ln->ln_state = ND6_LLINFO_PROBE;
419 0 : nd6_llinfo_settimer(ln, ndi->retrans / 1000);
420 0 : nd6_ns_output(ifp, &dst->sin6_addr,
421 : &dst->sin6_addr, ln, 0);
422 0 : }
423 : break;
424 : case ND6_LLINFO_PROBE:
425 0 : if (ln->ln_asked < nd6_umaxtries) {
426 0 : ln->ln_asked++;
427 0 : nd6_llinfo_settimer(ln, ndi->retrans / 1000);
428 0 : nd6_ns_output(ifp, &dst->sin6_addr,
429 : &dst->sin6_addr, ln, 0);
430 0 : } else {
431 0 : nd6_free(rt);
432 : ln = NULL;
433 : }
434 : break;
435 : }
436 :
437 0 : if_put(ifp);
438 :
439 0 : return (ln == NULL);
440 0 : }
441 :
442 : void
443 0 : nd6_expire_timer_update(struct in6_ifaddr *ia6)
444 : {
445 : time_t expire_time = INT64_MAX;
446 : int secs;
447 :
448 0 : KERNEL_ASSERT_LOCKED();
449 :
450 0 : if (ia6->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME)
451 0 : expire_time = ia6->ia6_lifetime.ia6t_expire;
452 :
453 0 : if (!(ia6->ia6_flags & IN6_IFF_DEPRECATED) &&
454 0 : ia6->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME &&
455 0 : expire_time > ia6->ia6_lifetime.ia6t_preferred)
456 0 : expire_time = ia6->ia6_lifetime.ia6t_preferred;
457 :
458 0 : if (expire_time == INT64_MAX)
459 0 : return;
460 :
461 : /*
462 : * IFA6_IS_INVALID() and IFA6_IS_DEPRECATED() check for uptime
463 : * greater than ia6t_expire or ia6t_preferred, not greater or equal.
464 : * Schedule timeout one second later so that either IFA6_IS_INVALID()
465 : * or IFA6_IS_DEPRECATED() is true.
466 : */
467 0 : expire_time++;
468 :
469 0 : if (!timeout_pending(&nd6_expire_timeout) ||
470 0 : nd6_expire_next > expire_time) {
471 0 : secs = expire_time - time_uptime;
472 0 : if (secs < 0)
473 : secs = 0;
474 :
475 0 : timeout_add_sec(&nd6_expire_timeout, secs);
476 0 : nd6_expire_next = expire_time;
477 0 : }
478 0 : }
479 :
480 : /*
481 : * Expire interface addresses.
482 : */
483 : void
484 0 : nd6_expire(void *unused)
485 : {
486 : struct ifnet *ifp;
487 :
488 0 : KERNEL_LOCK();
489 0 : NET_LOCK();
490 :
491 0 : TAILQ_FOREACH(ifp, &ifnet, if_list) {
492 : struct ifaddr *ifa, *nifa;
493 : struct in6_ifaddr *ia6;
494 :
495 0 : TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrlist, ifa_list, nifa) {
496 0 : if (ifa->ifa_addr->sa_family != AF_INET6)
497 : continue;
498 0 : ia6 = ifatoia6(ifa);
499 : /* check address lifetime */
500 0 : if (IFA6_IS_INVALID(ia6)) {
501 0 : in6_purgeaddr(&ia6->ia_ifa);
502 0 : } else {
503 0 : if (IFA6_IS_DEPRECATED(ia6))
504 0 : ia6->ia6_flags |= IN6_IFF_DEPRECATED;
505 0 : nd6_expire_timer_update(ia6);
506 : }
507 : }
508 : }
509 :
510 0 : NET_UNLOCK();
511 0 : KERNEL_UNLOCK();
512 0 : }
513 :
514 : void
515 0 : nd6_expire_timer(void *unused)
516 : {
517 0 : task_add(net_tq(0), &nd6_expire_task);
518 0 : }
519 :
520 : /*
521 : * Nuke neighbor cache/prefix/default router management table, right before
522 : * ifp goes away.
523 : */
524 : void
525 0 : nd6_purge(struct ifnet *ifp)
526 : {
527 : struct llinfo_nd6 *ln, *nln;
528 :
529 0 : NET_ASSERT_LOCKED();
530 :
531 : /*
532 : * Nuke neighbor cache entries for the ifp.
533 : */
534 0 : TAILQ_FOREACH_SAFE(ln, &nd6_list, ln_list, nln) {
535 : struct rtentry *rt;
536 : struct sockaddr_dl *sdl;
537 :
538 0 : rt = ln->ln_rt;
539 0 : if (rt != NULL && rt->rt_gateway != NULL &&
540 0 : rt->rt_gateway->sa_family == AF_LINK) {
541 0 : sdl = satosdl(rt->rt_gateway);
542 0 : if (sdl->sdl_index == ifp->if_index)
543 0 : nd6_free(rt);
544 : }
545 : }
546 0 : }
547 :
548 : struct rtentry *
549 0 : nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp,
550 : u_int rtableid)
551 : {
552 0 : struct rtentry *rt;
553 0 : struct sockaddr_in6 sin6;
554 : int flags;
555 :
556 0 : bzero(&sin6, sizeof(sin6));
557 0 : sin6.sin6_len = sizeof(struct sockaddr_in6);
558 0 : sin6.sin6_family = AF_INET6;
559 0 : sin6.sin6_addr = *addr6;
560 0 : flags = (create) ? RT_RESOLVE : 0;
561 :
562 0 : rt = rtalloc(sin6tosa(&sin6), flags, rtableid);
563 0 : if (rt != NULL && (rt->rt_flags & RTF_LLINFO) == 0) {
564 : /*
565 : * This is the case for the default route.
566 : * If we want to create a neighbor cache for the address, we
567 : * should free the route for the destination and allocate an
568 : * interface route.
569 : */
570 : if (create) {
571 0 : rtfree(rt);
572 0 : rt = NULL;
573 0 : }
574 : }
575 0 : if (rt == NULL) {
576 0 : if (create && ifp) {
577 0 : struct rt_addrinfo info;
578 : struct ifaddr *ifa;
579 : int error;
580 :
581 : /*
582 : * If no route is available and create is set,
583 : * we allocate a host route for the destination
584 : * and treat it like an interface route.
585 : * This hack is necessary for a neighbor which can't
586 : * be covered by our own prefix.
587 : */
588 0 : ifa = ifaof_ifpforaddr(sin6tosa(&sin6), ifp);
589 0 : if (ifa == NULL)
590 0 : return (NULL);
591 :
592 : /*
593 : * Create a new route. RTF_LLINFO is necessary
594 : * to create a Neighbor Cache entry for the
595 : * destination in nd6_rtrequest which will be
596 : * called in rtrequest.
597 : */
598 0 : bzero(&info, sizeof(info));
599 0 : info.rti_ifa = ifa;
600 0 : info.rti_flags = RTF_HOST | RTF_LLINFO;
601 0 : info.rti_info[RTAX_DST] = sin6tosa(&sin6);
602 0 : info.rti_info[RTAX_GATEWAY] = sdltosa(ifp->if_sadl);
603 0 : error = rtrequest(RTM_ADD, &info, RTP_CONNECTED, &rt,
604 : rtableid);
605 0 : if (error)
606 0 : return (NULL);
607 0 : if (rt->rt_llinfo != NULL) {
608 : struct llinfo_nd6 *ln =
609 0 : (struct llinfo_nd6 *)rt->rt_llinfo;
610 0 : ln->ln_state = ND6_LLINFO_NOSTATE;
611 0 : }
612 0 : } else
613 0 : return (NULL);
614 : }
615 : /*
616 : * Validation for the entry.
617 : * Note that the check for rt_llinfo is necessary because a cloned
618 : * route from a parent route that has the L flag (e.g. the default
619 : * route to a p2p interface) may have the flag, too, while the
620 : * destination is not actually a neighbor.
621 : */
622 0 : if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
623 0 : rt->rt_gateway->sa_family != AF_LINK || rt->rt_llinfo == NULL ||
624 0 : (ifp != NULL && rt->rt_ifidx != ifp->if_index)) {
625 0 : if (create) {
626 0 : char addr[INET6_ADDRSTRLEN];
627 0 : nd6log((LOG_DEBUG, "%s: failed to lookup %s (if=%s)\n",
628 : __func__,
629 : inet_ntop(AF_INET6, addr6, addr, sizeof(addr)),
630 : ifp ? ifp->if_xname : "unspec"));
631 0 : }
632 0 : rtfree(rt);
633 0 : return (NULL);
634 : }
635 0 : return (rt);
636 0 : }
637 :
638 : /*
639 : * Detect if a given IPv6 address identifies a neighbor on a given link.
640 : * XXX: should take care of the destination of a p2p link?
641 : */
642 : int
643 0 : nd6_is_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp)
644 : {
645 : struct in6_ifaddr *ia6;
646 : struct ifaddr *ifa;
647 : struct rtentry *rt;
648 :
649 : /*
650 : * A link-local address is always a neighbor.
651 : * XXX: we should use the sin6_scope_id field rather than the embedded
652 : * interface index.
653 : * XXX: a link does not necessarily specify a single interface.
654 : */
655 0 : if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr) &&
656 0 : ntohs(*(u_int16_t *)&addr->sin6_addr.s6_addr[2]) == ifp->if_index)
657 0 : return (1);
658 :
659 0 : TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
660 0 : if (ifa->ifa_addr->sa_family != AF_INET6)
661 : continue;
662 :
663 0 : ia6 = ifatoia6(ifa);
664 :
665 : /* Prefix check down below. */
666 0 : if (ia6->ia6_flags & IN6_IFF_AUTOCONF)
667 : continue;
668 :
669 0 : if (IN6_ARE_MASKED_ADDR_EQUAL(&addr->sin6_addr,
670 : &ia6->ia_addr.sin6_addr,
671 : &ia6->ia_prefixmask.sin6_addr))
672 0 : return (1);
673 : }
674 :
675 : /*
676 : * Even if the address matches none of our addresses, it might be
677 : * in the neighbor cache.
678 : */
679 0 : rt = nd6_lookup(&addr->sin6_addr, 0, ifp, ifp->if_rdomain);
680 0 : if (rt != NULL) {
681 0 : rtfree(rt);
682 0 : return (1);
683 : }
684 :
685 0 : return (0);
686 0 : }
687 :
688 : void
689 0 : nd6_invalidate(struct rtentry *rt)
690 : {
691 0 : struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
692 :
693 0 : m_freem(ln->ln_hold);
694 0 : ln->ln_hold = NULL;
695 0 : ln->ln_state = ND6_LLINFO_INCOMPLETE;
696 0 : ln->ln_asked = 0;
697 0 : }
698 :
699 : /*
700 : * Free an nd6 llinfo entry.
701 : * Since the function would cause significant changes in the kernel, DO NOT
702 : * make it global, unless you have a strong reason for the change, and are sure
703 : * that the change is safe.
704 : */
705 : void
706 0 : nd6_free(struct rtentry *rt)
707 : {
708 0 : struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
709 0 : struct in6_addr in6 = satosin6(rt_key(rt))->sin6_addr;
710 : struct ifnet *ifp;
711 :
712 0 : NET_ASSERT_LOCKED();
713 :
714 0 : ifp = if_get(rt->rt_ifidx);
715 :
716 0 : if (!ip6_forwarding) {
717 0 : if (ln->ln_router) {
718 : /*
719 : * rt6_flush must be called whether or not the neighbor
720 : * is in the Default Router List.
721 : * See a corresponding comment in nd6_na_input().
722 : */
723 0 : rt6_flush(&in6, ifp);
724 0 : }
725 : }
726 :
727 0 : KASSERT(!ISSET(rt->rt_flags, RTF_LOCAL));
728 0 : nd6_invalidate(rt);
729 :
730 : /*
731 : * Detach the route from the routing tree and the list of neighbor
732 : * caches, and disable the route entry not to be used in already
733 : * cached routes.
734 : */
735 0 : if (!ISSET(rt->rt_flags, RTF_STATIC|RTF_CACHED))
736 0 : rtdeletemsg(rt, ifp, ifp->if_rdomain);
737 :
738 0 : if_put(ifp);
739 0 : }
740 :
741 : /*
742 : * Upper-layer reachability hint for Neighbor Unreachability Detection.
743 : *
744 : * XXX cost-effective methods?
745 : */
746 : void
747 0 : nd6_nud_hint(struct rtentry *rt)
748 : {
749 : struct llinfo_nd6 *ln;
750 : struct ifnet *ifp;
751 :
752 0 : ifp = if_get(rt->rt_ifidx);
753 0 : if (ifp == NULL)
754 0 : return;
755 :
756 0 : if ((rt->rt_flags & RTF_GATEWAY) != 0 ||
757 0 : (rt->rt_flags & RTF_LLINFO) == 0 ||
758 0 : rt->rt_llinfo == NULL || rt->rt_gateway == NULL ||
759 0 : rt->rt_gateway->sa_family != AF_LINK) {
760 : /* This is not a host route. */
761 : goto out;
762 : }
763 :
764 0 : ln = (struct llinfo_nd6 *)rt->rt_llinfo;
765 0 : if (ln->ln_state < ND6_LLINFO_REACHABLE)
766 : goto out;
767 :
768 : /*
769 : * if we get upper-layer reachability confirmation many times,
770 : * it is possible we have false information.
771 : */
772 0 : ln->ln_byhint++;
773 0 : if (ln->ln_byhint > nd6_maxnudhint)
774 : goto out;
775 :
776 0 : ln->ln_state = ND6_LLINFO_REACHABLE;
777 0 : if (!ND6_LLINFO_PERMANENT(ln))
778 0 : nd6_llinfo_settimer(ln, ND_IFINFO(ifp)->reachable);
779 : out:
780 0 : if_put(ifp);
781 0 : }
782 :
783 : void
784 0 : nd6_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
785 : {
786 0 : struct sockaddr *gate = rt->rt_gateway;
787 0 : struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
788 : struct ifaddr *ifa;
789 :
790 0 : if (ISSET(rt->rt_flags, RTF_GATEWAY|RTF_MULTICAST))
791 0 : return;
792 :
793 0 : if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) {
794 : /*
795 : * This is probably an interface direct route for a link
796 : * which does not need neighbor caches (e.g. fe80::%lo0/64).
797 : * We do not need special treatment below for such a route.
798 : * Moreover, the RTF_LLINFO flag which would be set below
799 : * would annoy the ndp(8) command.
800 : */
801 0 : return;
802 : }
803 :
804 0 : if (req == RTM_RESOLVE && nd6_need_cache(ifp) == 0) {
805 : /*
806 : * For routing daemons like ospf6d we allow neighbor discovery
807 : * based on the cloning route only. This allows us to sent
808 : * packets directly into a network without having an address
809 : * with matching prefix on the interface. If the cloning
810 : * route is used for an stf interface, we would mistakenly
811 : * make a neighbor cache for the host route, and would see
812 : * strange neighbor solicitation for the corresponding
813 : * destination. In order to avoid confusion, we check if the
814 : * interface is suitable for neighbor discovery, and stop the
815 : * process if not. Additionally, we remove the LLINFO flag
816 : * so that ndp(8) will not try to get the neighbor information
817 : * of the destination.
818 : */
819 0 : rt->rt_flags &= ~RTF_LLINFO;
820 0 : return;
821 : }
822 :
823 0 : switch (req) {
824 : case RTM_ADD:
825 0 : if ((rt->rt_flags & RTF_CLONING) ||
826 0 : ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && ln == NULL)) {
827 0 : if (ln != NULL)
828 0 : nd6_llinfo_settimer(ln, 0);
829 0 : if ((rt->rt_flags & RTF_CLONING) != 0)
830 : break;
831 : }
832 : /*
833 : * In IPv4 code, we try to announce new RTF_ANNOUNCE entry here.
834 : * We don't do that here since llinfo is not ready yet.
835 : *
836 : * There are also couple of other things to be discussed:
837 : * - unsolicited NA code needs improvement beforehand
838 : * - RFC2461 says we MAY send multicast unsolicited NA
839 : * (7.2.6 paragraph 4), however, it also says that we
840 : * SHOULD provide a mechanism to prevent multicast NA storm.
841 : * we don't have anything like it right now.
842 : * note that the mechanism needs a mutual agreement
843 : * between proxies, which means that we need to implement
844 : * a new protocol, or a new kludge.
845 : * - from RFC2461 6.2.4, host MUST NOT send an unsolicited NA.
846 : * we need to check ip6forwarding before sending it.
847 : * (or should we allow proxy ND configuration only for
848 : * routers? there's no mention about proxy ND from hosts)
849 : */
850 : #if 0
851 : /* XXX it does not work */
852 : if (rt->rt_flags & RTF_ANNOUNCE)
853 : nd6_na_output(ifp,
854 : &satosin6(rt_key(rt))->sin6_addr,
855 : &satosin6(rt_key(rt))->sin6_addr,
856 : ip6_forwarding ? ND_NA_FLAG_ROUTER : 0,
857 : 1, NULL);
858 : #endif
859 : /* FALLTHROUGH */
860 : case RTM_RESOLVE:
861 0 : if (gate->sa_family != AF_LINK ||
862 0 : gate->sa_len < sizeof(struct sockaddr_dl)) {
863 0 : log(LOG_DEBUG, "%s: bad gateway value: %s\n",
864 0 : __func__, ifp->if_xname);
865 0 : break;
866 : }
867 0 : satosdl(gate)->sdl_type = ifp->if_type;
868 0 : satosdl(gate)->sdl_index = ifp->if_index;
869 0 : if (ln != NULL)
870 : break; /* This happens on a route change */
871 : /*
872 : * Case 2: This route may come from cloning, or a manual route
873 : * add with a LL address.
874 : */
875 0 : ln = pool_get(&nd6_pool, PR_NOWAIT | PR_ZERO);
876 0 : rt->rt_llinfo = (caddr_t)ln;
877 0 : if (ln == NULL) {
878 0 : log(LOG_DEBUG, "%s: pool get failed\n", __func__);
879 0 : break;
880 : }
881 0 : nd6_inuse++;
882 0 : nd6_allocated++;
883 0 : ln->ln_rt = rt;
884 : /* this is required for "ndp" command. - shin */
885 0 : if (req == RTM_ADD) {
886 : /*
887 : * gate should have some valid AF_LINK entry,
888 : * and ln expire should have some lifetime
889 : * which is specified by ndp command.
890 : */
891 0 : ln->ln_state = ND6_LLINFO_REACHABLE;
892 0 : ln->ln_byhint = 0;
893 0 : } else {
894 : /*
895 : * When req == RTM_RESOLVE, rt is created and
896 : * initialized in rtrequest(), so rt_expire is 0.
897 : */
898 0 : ln->ln_state = ND6_LLINFO_NOSTATE;
899 0 : nd6_llinfo_settimer(ln, 0);
900 : }
901 0 : rt->rt_flags |= RTF_LLINFO;
902 0 : TAILQ_INSERT_HEAD(&nd6_list, ln, ln_list);
903 :
904 : /*
905 : * If we have too many cache entries, initiate immediate
906 : * purging for some "less recently used" entries. Note that
907 : * we cannot directly call nd6_free() here because it would
908 : * cause re-entering rtable related routines triggering an LOR
909 : * problem for FreeBSD.
910 : */
911 0 : if (ip6_neighborgcthresh >= 0 &&
912 0 : nd6_inuse >= ip6_neighborgcthresh) {
913 : int i;
914 :
915 0 : for (i = 0; i < 10; i++) {
916 : struct llinfo_nd6 *ln_end;
917 :
918 0 : ln_end = TAILQ_LAST(&nd6_list, llinfo_nd6_head);
919 0 : if (ln_end == ln)
920 0 : break;
921 :
922 : /* Move this entry to the head */
923 0 : TAILQ_REMOVE(&nd6_list, ln_end, ln_list);
924 0 : TAILQ_INSERT_HEAD(&nd6_list, ln_end, ln_list);
925 :
926 0 : if (ND6_LLINFO_PERMANENT(ln_end))
927 0 : continue;
928 :
929 0 : if (ln_end->ln_state > ND6_LLINFO_INCOMPLETE)
930 0 : ln_end->ln_state = ND6_LLINFO_STALE;
931 : else
932 0 : ln_end->ln_state = ND6_LLINFO_PURGE;
933 0 : nd6_llinfo_settimer(ln_end, 0);
934 0 : }
935 0 : }
936 :
937 : /*
938 : * check if rt_key(rt) is one of my address assigned
939 : * to the interface.
940 : */
941 0 : ifa = &in6ifa_ifpwithaddr(ifp,
942 0 : &satosin6(rt_key(rt))->sin6_addr)->ia_ifa;
943 0 : if (ifa) {
944 0 : ln->ln_state = ND6_LLINFO_REACHABLE;
945 0 : ln->ln_byhint = 0;
946 0 : rt->rt_expire = 0;
947 0 : KASSERT(ifa == rt->rt_ifa);
948 0 : } else if (rt->rt_flags & RTF_ANNOUNCE) {
949 0 : ln->ln_state = ND6_LLINFO_REACHABLE;
950 0 : ln->ln_byhint = 0;
951 0 : rt->rt_expire = 0;
952 :
953 : /* join solicited node multicast for proxy ND */
954 0 : if (ifp->if_flags & IFF_MULTICAST) {
955 0 : struct in6_addr llsol;
956 0 : int error;
957 :
958 0 : llsol = satosin6(rt_key(rt))->sin6_addr;
959 0 : llsol.s6_addr16[0] = htons(0xff02);
960 0 : llsol.s6_addr16[1] = htons(ifp->if_index);
961 0 : llsol.s6_addr32[1] = 0;
962 0 : llsol.s6_addr32[2] = htonl(1);
963 0 : llsol.s6_addr8[12] = 0xff;
964 :
965 0 : if (in6_addmulti(&llsol, ifp, &error)) {
966 0 : char addr[INET6_ADDRSTRLEN];
967 0 : nd6log((LOG_ERR, "%s: failed to join "
968 : "%s (errno=%d)\n", ifp->if_xname,
969 : inet_ntop(AF_INET6, &llsol,
970 : addr, sizeof(addr)),
971 : error));
972 0 : }
973 0 : }
974 : }
975 : break;
976 :
977 : case RTM_DELETE:
978 0 : if (ln == NULL)
979 : break;
980 : /* leave from solicited node multicast for proxy ND */
981 0 : if ((rt->rt_flags & RTF_ANNOUNCE) != 0 &&
982 0 : (ifp->if_flags & IFF_MULTICAST) != 0) {
983 0 : struct in6_addr llsol;
984 : struct in6_multi *in6m;
985 :
986 0 : llsol = satosin6(rt_key(rt))->sin6_addr;
987 0 : llsol.s6_addr16[0] = htons(0xff02);
988 0 : llsol.s6_addr16[1] = htons(ifp->if_index);
989 0 : llsol.s6_addr32[1] = 0;
990 0 : llsol.s6_addr32[2] = htonl(1);
991 0 : llsol.s6_addr8[12] = 0xff;
992 :
993 0 : IN6_LOOKUP_MULTI(llsol, ifp, in6m);
994 0 : if (in6m)
995 0 : in6_delmulti(in6m);
996 0 : }
997 0 : nd6_inuse--;
998 0 : TAILQ_REMOVE(&nd6_list, ln, ln_list);
999 0 : rt->rt_expire = 0;
1000 0 : rt->rt_llinfo = NULL;
1001 0 : rt->rt_flags &= ~RTF_LLINFO;
1002 0 : m_freem(ln->ln_hold);
1003 0 : pool_put(&nd6_pool, ln);
1004 0 : break;
1005 :
1006 : case RTM_INVALIDATE:
1007 0 : if (!ISSET(rt->rt_flags, RTF_LOCAL))
1008 0 : nd6_invalidate(rt);
1009 : break;
1010 : }
1011 0 : }
1012 :
1013 : int
1014 0 : nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
1015 : {
1016 0 : struct in6_ndireq *ndi = (struct in6_ndireq *)data;
1017 0 : struct in6_nbrinfo *nbi = (struct in6_nbrinfo *)data;
1018 : struct rtentry *rt;
1019 :
1020 0 : switch (cmd) {
1021 : case SIOCGIFINFO_IN6:
1022 0 : NET_RLOCK();
1023 0 : ndi->ndi = *ND_IFINFO(ifp);
1024 0 : NET_RUNLOCK();
1025 0 : return (0);
1026 : case SIOCGNBRINFO_IN6:
1027 : {
1028 : struct llinfo_nd6 *ln;
1029 0 : struct in6_addr nb_addr = nbi->addr; /* make local for safety */
1030 : time_t expire;
1031 :
1032 0 : NET_RLOCK();
1033 : /*
1034 : * XXX: KAME specific hack for scoped addresses
1035 : * XXXX: for other scopes than link-local?
1036 : */
1037 0 : if (IN6_IS_ADDR_LINKLOCAL(&nbi->addr) ||
1038 0 : IN6_IS_ADDR_MC_LINKLOCAL(&nbi->addr)) {
1039 0 : u_int16_t *idp = (u_int16_t *)&nb_addr.s6_addr[2];
1040 :
1041 0 : if (*idp == 0)
1042 0 : *idp = htons(ifp->if_index);
1043 0 : }
1044 :
1045 0 : rt = nd6_lookup(&nb_addr, 0, ifp, ifp->if_rdomain);
1046 0 : if (rt == NULL ||
1047 0 : (ln = (struct llinfo_nd6 *)rt->rt_llinfo) == NULL) {
1048 0 : rtfree(rt);
1049 0 : NET_RUNLOCK();
1050 0 : return (EINVAL);
1051 : }
1052 0 : expire = ln->ln_rt->rt_expire;
1053 0 : if (expire != 0) {
1054 0 : expire -= time_uptime;
1055 0 : expire += time_second;
1056 0 : }
1057 :
1058 0 : nbi->state = ln->ln_state;
1059 0 : nbi->asked = ln->ln_asked;
1060 0 : nbi->isrouter = ln->ln_router;
1061 0 : nbi->expire = expire;
1062 :
1063 0 : rtfree(rt);
1064 0 : NET_RUNLOCK();
1065 0 : return (0);
1066 0 : }
1067 : }
1068 0 : return (0);
1069 0 : }
1070 :
1071 : /*
1072 : * Create neighbor cache entry and cache link-layer address,
1073 : * on reception of inbound ND6 packets. (RS/RA/NS/redirect)
1074 : *
1075 : * type - ICMP6 type
1076 : * code - type dependent information
1077 : */
1078 : void
1079 0 : nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
1080 : int lladdrlen, int type, int code)
1081 : {
1082 : struct rtentry *rt = NULL;
1083 : struct llinfo_nd6 *ln = NULL;
1084 : int is_newentry;
1085 : struct sockaddr_dl *sdl = NULL;
1086 : int do_update;
1087 : int olladdr;
1088 : int llchange;
1089 : int newstate = 0;
1090 :
1091 0 : if (!ifp)
1092 0 : panic("ifp == NULL in nd6_cache_lladdr");
1093 0 : if (!from)
1094 0 : panic("from == NULL in nd6_cache_lladdr");
1095 :
1096 : /* nothing must be updated for unspecified address */
1097 0 : if (IN6_IS_ADDR_UNSPECIFIED(from))
1098 0 : return;
1099 :
1100 : /*
1101 : * Validation about ifp->if_addrlen and lladdrlen must be done in
1102 : * the caller.
1103 : *
1104 : * XXX If the link does not have link-layer address, what should
1105 : * we do? (ifp->if_addrlen == 0)
1106 : * Spec says nothing in sections for RA, RS and NA. There's small
1107 : * description on it in NS section (RFC 2461 7.2.3).
1108 : */
1109 :
1110 0 : rt = nd6_lookup(from, 0, ifp, ifp->if_rdomain);
1111 0 : if (rt == NULL) {
1112 : #if 0
1113 : /* nothing must be done if there's no lladdr */
1114 : if (!lladdr || !lladdrlen)
1115 : return NULL;
1116 : #endif
1117 :
1118 0 : rt = nd6_lookup(from, 1, ifp, ifp->if_rdomain);
1119 : is_newentry = 1;
1120 0 : } else {
1121 : /* do nothing if static ndp is set */
1122 0 : if (rt->rt_flags & RTF_STATIC) {
1123 0 : rtfree(rt);
1124 0 : return;
1125 : }
1126 : is_newentry = 0;
1127 : }
1128 :
1129 0 : if (!rt)
1130 0 : return;
1131 0 : if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) != RTF_LLINFO) {
1132 : fail:
1133 0 : nd6_free(rt);
1134 0 : rtfree(rt);
1135 0 : return;
1136 : }
1137 0 : ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1138 0 : if (ln == NULL)
1139 : goto fail;
1140 0 : if (rt->rt_gateway == NULL)
1141 : goto fail;
1142 0 : if (rt->rt_gateway->sa_family != AF_LINK)
1143 : goto fail;
1144 0 : sdl = satosdl(rt->rt_gateway);
1145 :
1146 0 : olladdr = (sdl->sdl_alen) ? 1 : 0;
1147 0 : if (olladdr && lladdr) {
1148 0 : if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen))
1149 0 : llchange = 1;
1150 : else
1151 : llchange = 0;
1152 : } else
1153 : llchange = 0;
1154 :
1155 : /*
1156 : * newentry olladdr lladdr llchange (*=record)
1157 : * 0 n n -- (1)
1158 : * 0 y n -- (2)
1159 : * 0 n y -- (3) * STALE
1160 : * 0 y y n (4) *
1161 : * 0 y y y (5) * STALE
1162 : * 1 -- n -- (6) NOSTATE(= PASSIVE)
1163 : * 1 -- y -- (7) * STALE
1164 : */
1165 :
1166 0 : if (llchange) {
1167 0 : char addr[INET6_ADDRSTRLEN];
1168 0 : log(LOG_INFO, "ndp info overwritten for %s by %s on %s\n",
1169 0 : inet_ntop(AF_INET6, from, addr, sizeof(addr)),
1170 0 : ether_sprintf(lladdr), ifp->if_xname);
1171 0 : }
1172 0 : if (lladdr) { /* (3-5) and (7) */
1173 : /*
1174 : * Record source link-layer address
1175 : * XXX is it dependent to ifp->if_type?
1176 : */
1177 0 : sdl->sdl_alen = ifp->if_addrlen;
1178 0 : bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
1179 0 : }
1180 :
1181 0 : if (!is_newentry) {
1182 0 : if ((!olladdr && lladdr) || /* (3) */
1183 0 : (olladdr && lladdr && llchange)) { /* (5) */
1184 : do_update = 1;
1185 : newstate = ND6_LLINFO_STALE;
1186 0 : } else /* (1-2,4) */
1187 : do_update = 0;
1188 : } else {
1189 : do_update = 1;
1190 0 : if (!lladdr) /* (6) */
1191 0 : newstate = ND6_LLINFO_NOSTATE;
1192 : else /* (7) */
1193 : newstate = ND6_LLINFO_STALE;
1194 : }
1195 :
1196 0 : if (do_update) {
1197 : /*
1198 : * Update the state of the neighbor cache.
1199 : */
1200 0 : ln->ln_state = newstate;
1201 :
1202 0 : if (ln->ln_state == ND6_LLINFO_STALE) {
1203 : /*
1204 : * Since nd6_resolve() in ifp->if_output() will cause
1205 : * state transition to DELAY and reset the timer,
1206 : * we must set the timer now, although it is actually
1207 : * meaningless.
1208 : */
1209 0 : nd6_llinfo_settimer(ln, nd6_gctimer);
1210 :
1211 0 : if (ln->ln_hold) {
1212 : struct mbuf *n = ln->ln_hold;
1213 0 : ln->ln_hold = NULL;
1214 : /*
1215 : * we assume ifp is not a p2p here, so just
1216 : * set the 2nd argument as the 1st one.
1217 : */
1218 0 : ifp->if_output(ifp, n, rt_key(rt), rt);
1219 0 : if (ln->ln_hold == n) {
1220 : /* n is back in ln_hold. Discard. */
1221 0 : m_freem(ln->ln_hold);
1222 0 : ln->ln_hold = NULL;
1223 0 : }
1224 0 : }
1225 0 : } else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
1226 : /* probe right away */
1227 0 : nd6_llinfo_settimer(ln, 0);
1228 0 : }
1229 : }
1230 :
1231 : /*
1232 : * ICMP6 type dependent behavior.
1233 : *
1234 : * NS: clear IsRouter if new entry
1235 : * RS: clear IsRouter
1236 : * RA: set IsRouter if there's lladdr
1237 : * redir: clear IsRouter if new entry
1238 : *
1239 : * RA case, (1):
1240 : * The spec says that we must set IsRouter in the following cases:
1241 : * - If lladdr exist, set IsRouter. This means (1-5).
1242 : * - If it is old entry (!newentry), set IsRouter. This means (7).
1243 : * So, based on the spec, in (1-5) and (7) cases we must set IsRouter.
1244 : * A question arises for (1) case. (1) case has no lladdr in the
1245 : * neighbor cache, this is similar to (6).
1246 : * This case is rare but we figured that we MUST NOT set IsRouter.
1247 : *
1248 : * newentry olladdr lladdr llchange NS RS RA redir
1249 : * D R
1250 : * 0 n n -- (1) c ? s
1251 : * 0 y n -- (2) c s s
1252 : * 0 n y -- (3) c s s
1253 : * 0 y y n (4) c s s
1254 : * 0 y y y (5) c s s
1255 : * 1 -- n -- (6) c c c s
1256 : * 1 -- y -- (7) c c s c s
1257 : *
1258 : * (c=clear s=set)
1259 : */
1260 0 : switch (type & 0xff) {
1261 : case ND_NEIGHBOR_SOLICIT:
1262 : /*
1263 : * New entry must have is_router flag cleared.
1264 : */
1265 0 : if (is_newentry) /* (6-7) */
1266 0 : ln->ln_router = 0;
1267 : break;
1268 : case ND_REDIRECT:
1269 : /*
1270 : * If the icmp is a redirect to a better router, always set the
1271 : * is_router flag. Otherwise, if the entry is newly created,
1272 : * clear the flag. [RFC 2461, sec 8.3]
1273 : */
1274 0 : if (code == ND_REDIRECT_ROUTER)
1275 0 : ln->ln_router = 1;
1276 0 : else if (is_newentry) /* (6-7) */
1277 0 : ln->ln_router = 0;
1278 : break;
1279 : case ND_ROUTER_SOLICIT:
1280 : /*
1281 : * is_router flag must always be cleared.
1282 : */
1283 0 : ln->ln_router = 0;
1284 0 : break;
1285 : case ND_ROUTER_ADVERT:
1286 : /*
1287 : * Mark an entry with lladdr as a router.
1288 : */
1289 0 : if ((!is_newentry && (olladdr || lladdr)) || /* (2-5) */
1290 0 : (is_newentry && lladdr)) { /* (7) */
1291 0 : ln->ln_router = 1;
1292 0 : }
1293 : break;
1294 : }
1295 :
1296 0 : rtfree(rt);
1297 0 : }
1298 :
1299 : void
1300 0 : nd6_slowtimo(void *ignored_arg)
1301 : {
1302 : struct nd_ifinfo *nd6if;
1303 : struct ifnet *ifp;
1304 :
1305 0 : NET_LOCK();
1306 :
1307 0 : timeout_add_sec(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL);
1308 :
1309 0 : TAILQ_FOREACH(ifp, &ifnet, if_list) {
1310 0 : nd6if = ND_IFINFO(ifp);
1311 0 : if (nd6if->basereachable && /* already initialized */
1312 0 : (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
1313 : /*
1314 : * Since reachable time rarely changes by router
1315 : * advertisements, we SHOULD insure that a new random
1316 : * value gets recomputed at least once every few hours.
1317 : * (RFC 2461, 6.3.4)
1318 : */
1319 0 : nd6if->recalctm = nd6_recalc_reachtm_interval;
1320 0 : nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable);
1321 0 : }
1322 : }
1323 0 : NET_UNLOCK();
1324 0 : }
1325 :
1326 : int
1327 0 : nd6_resolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
1328 : struct sockaddr *dst, u_char *desten)
1329 : {
1330 : struct sockaddr_dl *sdl;
1331 : struct rtentry *rt;
1332 : struct llinfo_nd6 *ln = NULL;
1333 :
1334 0 : if (m->m_flags & M_MCAST) {
1335 0 : ETHER_MAP_IPV6_MULTICAST(&satosin6(dst)->sin6_addr, desten);
1336 0 : return (0);
1337 : }
1338 :
1339 0 : rt = rt_getll(rt0);
1340 :
1341 0 : if (ISSET(rt->rt_flags, RTF_REJECT) &&
1342 0 : (rt->rt_expire == 0 || time_uptime < rt->rt_expire)) {
1343 0 : m_freem(m);
1344 0 : return (rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
1345 : }
1346 :
1347 : /*
1348 : * Address resolution or Neighbor Unreachability Detection
1349 : * for the next hop.
1350 : * At this point, the destination of the packet must be a unicast
1351 : * or an anycast address(i.e. not a multicast).
1352 : */
1353 0 : if (!ISSET(rt->rt_flags, RTF_LLINFO)) {
1354 0 : char addr[INET6_ADDRSTRLEN];
1355 0 : log(LOG_DEBUG, "%s: %s: route contains no ND information\n",
1356 0 : __func__, inet_ntop(AF_INET6,
1357 0 : &satosin6(rt_key(rt))->sin6_addr, addr, sizeof(addr)));
1358 0 : m_freem(m);
1359 : return (EINVAL);
1360 0 : }
1361 :
1362 0 : if (rt->rt_gateway->sa_family != AF_LINK) {
1363 0 : printf("%s: something odd happens\n", __func__);
1364 0 : m_freem(m);
1365 0 : return (EINVAL);
1366 : }
1367 :
1368 0 : ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1369 0 : KASSERT(ln != NULL);
1370 :
1371 : /*
1372 : * Move this entry to the head of the queue so that it is less likely
1373 : * for this entry to be a target of forced garbage collection (see
1374 : * nd6_rtrequest()).
1375 : */
1376 0 : TAILQ_REMOVE(&nd6_list, ln, ln_list);
1377 0 : TAILQ_INSERT_HEAD(&nd6_list, ln, ln_list);
1378 :
1379 : /*
1380 : * The first time we send a packet to a neighbor whose entry is
1381 : * STALE, we have to change the state to DELAY and a sets a timer to
1382 : * expire in DELAY_FIRST_PROBE_TIME seconds to ensure do
1383 : * neighbor unreachability detection on expiration.
1384 : * (RFC 2461 7.3.3)
1385 : */
1386 0 : if (ln->ln_state == ND6_LLINFO_STALE) {
1387 0 : ln->ln_asked = 0;
1388 0 : ln->ln_state = ND6_LLINFO_DELAY;
1389 0 : nd6_llinfo_settimer(ln, nd6_delay);
1390 0 : }
1391 :
1392 : /*
1393 : * If the neighbor cache entry has a state other than INCOMPLETE
1394 : * (i.e. its link-layer address is already resolved), just
1395 : * send the packet.
1396 : */
1397 0 : if (ln->ln_state > ND6_LLINFO_INCOMPLETE) {
1398 0 : sdl = satosdl(rt->rt_gateway);
1399 0 : if (sdl->sdl_alen != ETHER_ADDR_LEN) {
1400 0 : char addr[INET6_ADDRSTRLEN];
1401 0 : log(LOG_DEBUG, "%s: %s: incorrect nd6 information\n",
1402 : __func__,
1403 0 : inet_ntop(AF_INET6, &satosin6(dst)->sin6_addr,
1404 0 : addr, sizeof(addr)));
1405 0 : m_freem(m);
1406 : return (EINVAL);
1407 0 : }
1408 :
1409 0 : bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
1410 0 : return (0);
1411 : }
1412 :
1413 : /*
1414 : * There is a neighbor cache entry, but no ethernet address
1415 : * response yet. Replace the held mbuf (if any) with this
1416 : * latest one.
1417 : */
1418 0 : if (ln->ln_state == ND6_LLINFO_NOSTATE)
1419 0 : ln->ln_state = ND6_LLINFO_INCOMPLETE;
1420 0 : m_freem(ln->ln_hold);
1421 0 : ln->ln_hold = m;
1422 :
1423 : /*
1424 : * If there has been no NS for the neighbor after entering the
1425 : * INCOMPLETE state, send the first solicitation.
1426 : */
1427 0 : if (!ND6_LLINFO_PERMANENT(ln) && ln->ln_asked == 0) {
1428 0 : ln->ln_asked++;
1429 0 : nd6_llinfo_settimer(ln, ND_IFINFO(ifp)->retrans / 1000);
1430 0 : nd6_ns_output(ifp, NULL, &satosin6(dst)->sin6_addr, ln, 0);
1431 0 : }
1432 0 : return (EAGAIN);
1433 0 : }
1434 :
1435 : int
1436 0 : nd6_need_cache(struct ifnet *ifp)
1437 : {
1438 : /*
1439 : * RFC2893 says:
1440 : * - unidirectional tunnels needs no ND
1441 : */
1442 0 : switch (ifp->if_type) {
1443 : case IFT_ETHER:
1444 : case IFT_IEEE80211:
1445 : case IFT_CARP:
1446 0 : return (1);
1447 : default:
1448 0 : return (0);
1449 : }
1450 0 : }
|