nd6_nbr.c revision 1.1.2.4 1 /*
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__NetBSD__)
31 #include "opt_inet.h"
32 #ifdef __NetBSD__ /*XXX*/
33 #include "opt_ipsec.h"
34 #endif
35 #endif
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/malloc.h>
40 #include <sys/mbuf.h>
41 #include <sys/socket.h>
42 #include <sys/sockio.h>
43 #include <sys/time.h>
44 #include <sys/kernel.h>
45 #include <sys/errno.h>
46 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
47 #include <sys/ioctl.h>
48 #endif
49 #include <sys/syslog.h>
50 #include <sys/queue.h>
51
52 #include <net/if.h>
53 #include <net/if_types.h>
54 #include <net/if_dl.h>
55 #include <net/route.h>
56
57 #include <netinet/in.h>
58 #include <netinet/in_var.h>
59 #include <netinet6/in6_var.h>
60 #include <netinet6/ip6.h>
61 #include <netinet6/ip6_var.h>
62 #include <netinet6/nd6.h>
63 #include <netinet6/icmp6.h>
64
65 #include <net/net_osdep.h>
66
67 #define SDL(s) ((struct sockaddr_dl *)s)
68
69 #if 0
70 extern struct timeval time;
71 #endif
72
73 struct dadq;
74 static struct dadq *nd6_dad_find __P((struct ifaddr *));
75 static void nd6_dad_timer __P((struct ifaddr *));
76 static void nd6_dad_ns_input __P((struct ifaddr *));
77 static void nd6_dad_na_input __P((struct ifaddr *));
78
79 /* ignore NS in DAD - specwise incorrect, */
80 int dad_ignore_ns = 0;
81
82 /*
83 * Input an Neighbor Solicitation Message.
84 *
85 * Based on RFC 2461
86 * Based on RFC 2462 (duplicated address detection)
87 *
88 * XXX proxy advertisement
89 */
90 void
91 nd6_ns_input(m, off, icmp6len)
92 struct mbuf *m;
93 int off, icmp6len;
94 {
95 struct ifnet *ifp = m->m_pkthdr.rcvif;
96 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
97 struct nd_neighbor_solicit *nd_ns
98 = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
99 struct in6_addr saddr6 = ip6->ip6_src;
100 struct in6_addr daddr6 = ip6->ip6_dst;
101 struct in6_addr taddr6 = nd_ns->nd_ns_target;
102 struct in6_addr myaddr6;
103 char *lladdr = NULL;
104 struct ifaddr *ifa;
105 int lladdrlen = 0;
106 int anycast = 0, proxy = 0, tentative = 0;
107 int tlladdr;
108 union nd_opts ndopts;
109
110 if (ip6->ip6_hlim != 255) {
111 log(LOG_ERR,
112 "nd6_ns_input: invalid hlim %d\n", ip6->ip6_hlim);
113 return;
114 }
115
116 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
117 /* dst has to be solicited node multicast address. */
118 if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL
119 /*don't check ifindex portion*/
120 && daddr6.s6_addr32[1] == 0
121 && daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE
122 && daddr6.s6_addr8[12] == 0xff) {
123 ; /*good*/
124 } else {
125 log(LOG_INFO, "nd6_ns_input: bad DAD packet "
126 "(wrong ip6 dst)\n");
127 goto bad;
128 }
129 }
130
131 if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
132 log(LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n");
133 goto bad;
134 }
135
136 if (IN6_IS_SCOPE_LINKLOCAL(&taddr6))
137 taddr6.s6_addr16[1] = htons(ifp->if_index);
138
139 icmp6len -= sizeof(*nd_ns);
140 nd6_option_init(nd_ns + 1, icmp6len, &ndopts);
141 if (nd6_options(&ndopts) < 0) {
142 log(LOG_INFO, "nd6_ns_input: invalid ND option, ignored\n");
143 goto bad;
144 }
145
146 if (ndopts.nd_opts_src_lladdr) {
147 lladdr = (char *)(ndopts.nd_opts_src_lladdr +1);
148 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
149 }
150
151 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && lladdr) {
152 log(LOG_INFO, "nd6_ns_input: bad DAD packet "
153 "(link-layer address option)\n");
154 goto bad;
155 }
156
157 /*
158 * Attaching target link-layer address to the NA?
159 * (RFC 2461 7.2.4)
160 *
161 * NS IP dst is unicast/anycast MUST NOT add
162 * NS IP dst is solicited-node multicast MUST add
163 *
164 * In implementation, we add target link-layer address by default.
165 * We do not add one in MUST NOT cases.
166 */
167 #if 0 /* too much! */
168 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &daddr6);
169 if (ifa && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST))
170 tlladdr = 0;
171 else
172 #endif
173 if (!IN6_IS_ADDR_MULTICAST(&daddr6))
174 tlladdr = 0;
175 else
176 tlladdr = 1;
177
178 /*
179 * Target address (taddr6) must be either:
180 * (1) Valid unicast/anycast address for my receiving interface,
181 * (2) Unicast address for which I'm offering proxy service, or
182 * (3) "tentative" address on which DAD is being performed.
183 */
184 /* (1) and (3) check. */
185 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
186
187 /* (2) check. */
188 if (!ifa && nd6_proxyall) {
189 struct rtentry *rt;
190 struct sockaddr_in6 tsin6;
191
192 bzero(&tsin6, sizeof tsin6);
193 tsin6.sin6_len = sizeof(struct sockaddr_in6);
194 tsin6.sin6_family = AF_INET6;
195 tsin6.sin6_addr = taddr6;
196
197 rt = rtalloc1((struct sockaddr *)&tsin6, 0
198 #ifdef __FreeBSD__
199 , 0
200 #endif /* __FreeBSD__ */
201 );
202 if (rt && rt->rt_ifp != ifp) {
203 /*
204 * search link local addr for ifp, and use it for
205 * proxy NA.
206 */
207 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp);
208 if (ifa)
209 proxy = 1;
210 }
211 rtfree(rt);
212 }
213 if (!ifa) {
214 /*
215 * We've got a NS packet, and we don't have that adddress
216 * assigned for us. We MUST silently ignore it.
217 * See RFC2461 7.2.3.
218 */
219 return;
220 }
221 myaddr6 = *IFA_IN6(ifa);
222 anycast = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST;
223 tentative = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE;
224 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DUPLICATED)
225 return;
226
227 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
228 log(LOG_INFO,
229 "nd6_ns_input: lladdrlen mismatch for %s "
230 "(if %d, NS packet %d)\n",
231 ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2);
232 }
233
234 if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) {
235 log(LOG_INFO,
236 "nd6_ns_input: duplicate IP6 address %s\n",
237 ip6_sprintf(&saddr6));
238 return;
239 }
240
241 /*
242 * We have neighbor solicitation packet, with target address equals to
243 * one of my tentative address.
244 *
245 * src addr how to process?
246 * --- ---
247 * multicast of course, invalid (rejected in ip6_input)
248 * unicast somebody is doing address resolution -> ignore
249 * unspec dup address detection
250 *
251 * The processing is defined in RFC 2462.
252 */
253 if (tentative) {
254 /*
255 * If source address is unspecified address, it is for
256 * duplicated address detection.
257 *
258 * If not, the packet is for addess resolution;
259 * silently ignore it.
260 */
261 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6))
262 nd6_dad_ns_input(ifa);
263
264 return;
265 }
266
267 /*
268 * If the source address is unspecified address, entries must not
269 * be created or updated.
270 * It looks that sender is performing DAD. Output NA toward
271 * all-node multicast address, to tell the sender that I'm using
272 * the address.
273 * S bit ("solicited") must be zero.
274 */
275 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
276 saddr6 = in6addr_linklocal_allnodes;
277 saddr6.s6_addr16[1] = htons(ifp->if_index);
278 nd6_na_output(ifp, &saddr6, &taddr6,
279 ((anycast || proxy || !tlladdr)
280 ? 0 : ND_NA_FLAG_OVERRIDE)
281 | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0),
282 tlladdr);
283 return;
284 }
285
286 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_NEIGHBOR_SOLICIT, 0);
287
288 nd6_na_output(ifp, &saddr6, &taddr6,
289 ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE)
290 | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0)
291 | ND_NA_FLAG_SOLICITED,
292 tlladdr);
293 return;
294
295 bad:
296 log(LOG_ERR, "nd6_ns_input: src=%s\n", ip6_sprintf(&saddr6));
297 log(LOG_ERR, "nd6_ns_input: dst=%s\n", ip6_sprintf(&daddr6));
298 log(LOG_ERR, "nd6_ns_input: tgt=%s\n", ip6_sprintf(&taddr6));
299 return;
300 }
301
302 /*
303 * Output an Neighbor Solicitation Message. Caller specifies:
304 * - ICMP6 header source IP6 address
305 * - ND6 header target IP6 address
306 * - ND6 header source datalink address
307 *
308 * Based on RFC 2461
309 * Based on RFC 2462 (duplicated address detection)
310 */
311 void
312 nd6_ns_output(ifp, daddr6, taddr6, ln, dad)
313 struct ifnet *ifp;
314 struct in6_addr *daddr6, *taddr6;
315 struct llinfo_nd6 *ln; /* for source address determination */
316 int dad; /* duplicated address detection */
317 {
318 struct mbuf *m;
319 struct ip6_hdr *ip6;
320 struct nd_neighbor_solicit *nd_ns;
321 struct in6_ifaddr *ia = NULL;
322 struct ip6_moptions im6o;
323 int icmp6len;
324 caddr_t mac;
325 struct ifnet *outif = NULL;
326
327 if (IN6_IS_ADDR_MULTICAST(taddr6))
328 return;
329
330 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
331 return;
332
333 if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) {
334 m->m_flags |= M_MCAST;
335 im6o.im6o_multicast_ifp = ifp;
336 im6o.im6o_multicast_hlim = 255;
337 im6o.im6o_multicast_loop = 0;
338 }
339
340 icmp6len = sizeof(*nd_ns);
341 m->m_pkthdr.len = m->m_len = sizeof(*ip6) + icmp6len;
342 MH_ALIGN(m, m->m_len + 16); /* 1+1+6 is enought. but just in case */
343
344 /* fill neighbor solicitation packet */
345 ip6 = mtod(m, struct ip6_hdr *);
346 ip6->ip6_flow = 0;
347 ip6->ip6_vfc = IPV6_VERSION;
348 /* ip6->ip6_plen will be set later */
349 ip6->ip6_nxt = IPPROTO_ICMPV6;
350 ip6->ip6_hlim = 255;
351 if (daddr6)
352 ip6->ip6_dst = *daddr6;
353 else {
354 ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
355 ip6->ip6_dst.s6_addr16[1] = htons(ifp->if_index);
356 ip6->ip6_dst.s6_addr32[1] = 0;
357 ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
358 ip6->ip6_dst.s6_addr32[3] = taddr6->s6_addr32[3];
359 ip6->ip6_dst.s6_addr8[12] = 0xff;
360 }
361 if (!dad) {
362 #if 0 /* KAME way, exact address scope match */
363 /*
364 * Select a source whose scope is the same as that of the dest.
365 * Typically, the dest is link-local solicitation multicast
366 * (i.e. neighbor discovery) or link-local/global unicast
367 * (i.e. neighbor un-reachability detection).
368 */
369 ia = in6_ifawithifp(ifp, &ip6->ip6_dst);
370 if (ia == NULL) {
371 m_freem(m);
372 return;
373 }
374 ip6->ip6_src = ia->ia_addr.sin6_addr;
375 #else /* spec-wise correct */
376 /*
377 * RFC2461 7.2.2:
378 * "If the source address of the packet prompting the
379 * solicitation is the same as one of the addresses assigned
380 * to the outgoing interface, that address SHOULD be placed
381 * in the IP Source Address of the outgoing solicitation.
382 * Otherwise, any one of the addresses assigned to the
383 * interface should be used."
384 *
385 * We use the source address for the prompting packet
386 * (saddr6), if:
387 * - saddr6 is given from the caller (by giving "ln"), and
388 * - saddr6 belongs to the outgoing interface.
389 * Otherwise, we perform a scope-wise match.
390 */
391 struct ip6_hdr *hip6; /*hold ip6*/
392 struct in6_addr *saddr6;
393
394 if (ln && ln->ln_hold) {
395 hip6 = mtod(ln->ln_hold, struct ip6_hdr *);
396 /* XXX pullup? */
397 if (sizeof(*hip6) < ln->ln_hold->m_len)
398 saddr6 = &hip6->ip6_src;
399 else
400 saddr6 = NULL;
401 } else
402 saddr6 = NULL;
403 if (saddr6 && in6ifa_ifpwithaddr(ifp, saddr6))
404 bcopy(saddr6, &ip6->ip6_src, sizeof(*saddr6));
405 else {
406 ia = in6_ifawithifp(ifp, &ip6->ip6_dst);
407 if (ia == NULL) {
408 m_freem(m); /*XXX*/
409 return;
410 }
411 ip6->ip6_src = ia->ia_addr.sin6_addr;
412 }
413 #endif
414 } else {
415 /*
416 * Source address for DAD packet must always be IPv6
417 * unspecified address. (0::0)
418 */
419 bzero(&ip6->ip6_src, sizeof(ip6->ip6_src));
420 }
421 nd_ns = (struct nd_neighbor_solicit *)(ip6 + 1);
422 nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT;
423 nd_ns->nd_ns_code = 0;
424 nd_ns->nd_ns_reserved = 0;
425 nd_ns->nd_ns_target = *taddr6;
426
427 if (IN6_IS_SCOPE_LINKLOCAL(&nd_ns->nd_ns_target))
428 nd_ns->nd_ns_target.s6_addr16[1] = 0;
429
430 /*
431 * Add source link-layer address option.
432 *
433 * spec implementation
434 * --- ---
435 * DAD packet MUST NOT do not add the option
436 * there's no link layer address:
437 * impossible do not add the option
438 * there's link layer address:
439 * Multicast NS MUST add one add the option
440 * Unicast NS SHOULD add one add the option
441 */
442 if (!dad && (mac = nd6_ifptomac(ifp))) {
443 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
444 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
445 /* 8 byte alignments... */
446 optlen = (optlen + 7) & ~7;
447
448 m->m_pkthdr.len += optlen;
449 m->m_len += optlen;
450 icmp6len += optlen;
451 bzero((caddr_t)nd_opt, optlen);
452 nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
453 nd_opt->nd_opt_len = optlen >> 3;
454 bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen);
455 }
456
457 ip6->ip6_plen = htons((u_short)icmp6len);
458 nd_ns->nd_ns_cksum = 0;
459 nd_ns->nd_ns_cksum
460 = in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
461
462 #ifdef IPSEC
463 #ifndef __OpenBSD__ /*KAME IPSEC*/
464 m->m_pkthdr.rcvif = NULL;
465 #endif
466 #endif /*IPSEC*/
467 ip6_output(m, NULL, NULL, dad ? IPV6_DADOUTPUT : 0, &im6o, &outif);
468 if (outif) {
469 icmp6_ifstat_inc(outif, ifs6_out_msg);
470 icmp6_ifstat_inc(outif, ifs6_out_neighborsolicit);
471 }
472 icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++;
473 }
474
475 /*
476 * Neighbor advertisement input handling.
477 *
478 * Based on RFC 2461
479 * Based on RFC 2462 (duplicated address detection)
480 */
481 void
482 nd6_na_input(m, off, icmp6len)
483 struct mbuf *m;
484 int off, icmp6len;
485 {
486 struct ifnet *ifp = m->m_pkthdr.rcvif;
487 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
488 struct nd_neighbor_advert *nd_na
489 = (struct nd_neighbor_advert *)((caddr_t)ip6 + off);
490 #if 0
491 struct in6_addr saddr6 = ip6->ip6_src;
492 #endif
493 struct in6_addr daddr6 = ip6->ip6_dst;
494 struct in6_addr taddr6 = nd_na->nd_na_target;
495 int flags = nd_na->nd_na_flags_reserved;
496 int is_router = ((flags & ND_NA_FLAG_ROUTER) != 0);
497 int is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0);
498 int is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0);
499 char *lladdr = NULL;
500 int lladdrlen = 0;
501 struct ifaddr *ifa;
502 struct llinfo_nd6 *ln;
503 struct rtentry *rt;
504 struct sockaddr_dl *sdl;
505 union nd_opts ndopts;
506
507 if (ip6->ip6_hlim != 255) {
508 log(LOG_ERR,
509 "nd6_na_input: invalid hlim %d\n", ip6->ip6_hlim);
510 return;
511 }
512
513 if (IN6_IS_SCOPE_LINKLOCAL(&taddr6))
514 taddr6.s6_addr16[1] = htons(ifp->if_index);
515
516 if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
517 log(LOG_ERR,
518 "nd6_na_input: invalid target address %s\n",
519 ip6_sprintf(&taddr6));
520 return;
521 }
522 if (IN6_IS_ADDR_MULTICAST(&daddr6))
523 if (is_solicited) {
524 log(LOG_ERR,
525 "nd6_na_input: a solicited adv is multicasted\n");
526 return;
527 }
528
529 icmp6len -= sizeof(*nd_na);
530 nd6_option_init(nd_na + 1, icmp6len, &ndopts);
531 if (nd6_options(&ndopts) < 0) {
532 log(LOG_INFO, "nd6_na_input: invalid ND option, ignored\n");
533 return;
534 }
535
536 if (ndopts.nd_opts_tgt_lladdr) {
537 lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
538 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
539 }
540
541 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
542
543 /*
544 * Target address matches one of my interface address.
545 *
546 * If my address is tentative, this means that there's somebody
547 * already using the same address as mine. This indicates DAD failure.
548 * This is defined in RFC 2462.
549 *
550 * Otherwise, process as defined in RFC 2461.
551 */
552 if (ifa
553 && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) {
554 nd6_dad_na_input(ifa);
555 return;
556 }
557
558 /* Just for safety, maybe unnecessery. */
559 if (ifa) {
560 log(LOG_ERR,
561 "nd6_na_input: duplicate IP6 address %s\n",
562 ip6_sprintf(&taddr6));
563 return;
564 }
565
566 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
567 log(LOG_INFO,
568 "nd6_na_input: lladdrlen mismatch for %s "
569 "(if %d, NA packet %d)\n",
570 ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2);
571 }
572
573 /*
574 * If no neighbor cache entry is found, NA SHOULD silently be discarded.
575 */
576 rt = nd6_lookup(&taddr6, 0, ifp);
577 if ((rt == NULL) ||
578 ((ln = (struct llinfo_nd6 *)rt->rt_llinfo) == NULL) ||
579 ((sdl = SDL(rt->rt_gateway)) == NULL))
580 return;
581
582 if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
583 /*
584 * If the link-layer has address, and no lladdr option came,
585 * discard the packet.
586 */
587 if (ifp->if_addrlen && !lladdr)
588 return;
589
590 /*
591 * Record link-layer address, and update the state.
592 */
593 sdl->sdl_alen = ifp->if_addrlen;
594 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
595 if (is_solicited) {
596 ln->ln_state = ND6_LLINFO_REACHABLE;
597 if (ln->ln_expire)
598 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
599 ln->ln_expire = time.tv_sec +
600 #else
601 ln->ln_expire = time_second +
602 #endif
603 nd_ifinfo[rt->rt_ifp->if_index].reachable;
604 } else
605 ln->ln_state = ND6_LLINFO_STALE;
606 ln->ln_router = is_router;
607 } else {
608 int llchange;
609
610 /*
611 * Check if the link-layer address has changed or not.
612 */
613 if (!lladdr)
614 llchange = 0;
615 else {
616 if (sdl->sdl_alen) {
617 if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen))
618 llchange = 1;
619 else
620 llchange = 0;
621 } else
622 llchange = 1;
623 }
624
625 /*
626 * This is VERY complex. Look at it with care.
627 *
628 * override solicit lladdr llchange action
629 * (L: record lladdr)
630 *
631 * 0 0 n -- (2c)
632 * 0 0 y n (2b) L
633 * 0 0 y y (1) REACHABLE->STALE
634 * 0 1 n -- (2c) *->REACHABLE
635 * 0 1 y n (2b) L *->REACHABLE
636 * 0 1 y y (1) REACHABLE->STALE
637 * 1 0 n -- (2a)
638 * 1 0 y n (2a) L
639 * 1 0 y y (2a) L *->STALE
640 * 1 1 n -- (2a) *->REACHABLE
641 * 1 1 y n (2a) L *->REACHABLE
642 * 1 1 y y (2a) L *->REACHABLE
643 */
644 if (!is_override && (lladdr && llchange)) { /* (1) */
645 /*
646 * If state is REACHABLE, make it STALE.
647 * no other updates should be done.
648 */
649 if (ln->ln_state == ND6_LLINFO_REACHABLE)
650 ln->ln_state = ND6_LLINFO_STALE;
651 return;
652 } else if (is_override /* (2a) */
653 || (!is_override && (lladdr && !llchange)) /* (2b) */
654 || !lladdr) { /* (2c) */
655 /*
656 * Update link-local address, if any.
657 */
658 if (lladdr) {
659 sdl->sdl_alen = ifp->if_addrlen;
660 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
661 }
662
663 /*
664 * If solicited, make the state REACHABLE.
665 * If not solicited and the link-layer address was
666 * changed, make it STALE.
667 */
668 if (is_solicited) {
669 ln->ln_state = ND6_LLINFO_REACHABLE;
670 if (ln->ln_expire) {
671 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
672 ln->ln_expire = time.tv_sec +
673 #else
674 ln->ln_expire = time_second +
675 #endif
676 nd_ifinfo[ifp->if_index].reachable;
677 }
678 } else {
679 if (lladdr && llchange)
680 ln->ln_state = ND6_LLINFO_STALE;
681 }
682 }
683
684 if (ln->ln_router && !is_router) {
685 /*
686 * The peer dropped the router flag.
687 * Remove the sender from the Default Router List and
688 * update the Destination Cache entries.
689 */
690 struct nd_defrouter *dr;
691 struct in6_addr *in6;
692 int s;
693
694 in6 = &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr;
695 #ifdef __NetBSD__
696 s = splsoftnet();
697 #else
698 s = splnet();
699 #endif
700 dr = defrouter_lookup(in6, rt->rt_ifp);
701 if (dr)
702 defrtrlist_del(dr);
703 else if (!ip6_forwarding && ip6_accept_rtadv) {
704 /*
705 * Even if the neighbor is not in the default
706 * router list, the neighbor may be used
707 * as a next hop for some destinations
708 * (e.g. redirect case). So we must
709 * call rt6_flush explicitly.
710 */
711 rt6_flush(&ip6->ip6_src, rt->rt_ifp);
712 }
713 splx(s);
714 }
715 ln->ln_router = is_router;
716 }
717 rt->rt_flags &= ~RTF_REJECT;
718 ln->ln_asked = 0;
719 if (ln->ln_hold) {
720 #ifdef OLDIP6OUTPUT
721 (*ifp->if_output)(ifp, ln->ln_hold, rt_key(rt), rt);
722 #else
723 nd6_output(ifp, ln->ln_hold,
724 (struct sockaddr_in6 *)rt_key(rt), rt);
725 #endif
726 ln->ln_hold = 0;
727 }
728 }
729
730 /*
731 * Neighbor advertisement output handling.
732 *
733 * Based on RFC 2461
734 *
735 * XXX NA delay for anycast address is not implemented yet
736 * (RFC 2461 7.2.7)
737 * XXX proxy advertisement?
738 */
739 void
740 nd6_na_output(ifp, daddr6, taddr6, flags, tlladdr)
741 struct ifnet *ifp;
742 struct in6_addr *daddr6, *taddr6;
743 u_long flags;
744 int tlladdr; /* 1 if include target link-layer address */
745 {
746 struct mbuf *m;
747 struct ip6_hdr *ip6;
748 struct nd_neighbor_advert *nd_na;
749 struct in6_ifaddr *ia = NULL;
750 struct ip6_moptions im6o;
751 int icmp6len;
752 caddr_t mac;
753 struct ifnet *outif = NULL;
754
755 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
756 return;
757
758 if (IN6_IS_ADDR_MULTICAST(daddr6)) {
759 m->m_flags |= M_MCAST;
760 im6o.im6o_multicast_ifp = ifp;
761 im6o.im6o_multicast_hlim = 255;
762 im6o.im6o_multicast_loop = 0;
763 }
764
765 icmp6len = sizeof(*nd_na);
766 m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + icmp6len;
767 MH_ALIGN(m, m->m_len + 16); /* 1+1+6 is enough. but just in case */
768
769 /* fill neighbor advertisement packet */
770 ip6 = mtod(m, struct ip6_hdr *);
771 ip6->ip6_flow = 0;
772 ip6->ip6_vfc = IPV6_VERSION;
773 ip6->ip6_nxt = IPPROTO_ICMPV6;
774 ip6->ip6_hlim = 255;
775 if (IN6_IS_ADDR_UNSPECIFIED(daddr6)) {
776 /* reply to DAD */
777 ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
778 ip6->ip6_dst.s6_addr16[1] = htons(ifp->if_index);
779 ip6->ip6_dst.s6_addr32[1] = 0;
780 ip6->ip6_dst.s6_addr32[2] = 0;
781 ip6->ip6_dst.s6_addr32[3] = IPV6_ADDR_INT32_ONE;
782 flags &= ~ND_NA_FLAG_SOLICITED;
783 } else
784 ip6->ip6_dst = *daddr6;
785
786 /*
787 * Select a source whose scope is the same as that of the dest.
788 */
789 ia = in6_ifawithifp(ifp, &ip6->ip6_dst);
790 if (ia == NULL) {
791 m_freem(m);
792 return;
793 }
794 ip6->ip6_src = ia->ia_addr.sin6_addr;
795 nd_na = (struct nd_neighbor_advert *)(ip6 + 1);
796 nd_na->nd_na_type = ND_NEIGHBOR_ADVERT;
797 nd_na->nd_na_code = 0;
798 nd_na->nd_na_target = *taddr6;
799 if (IN6_IS_SCOPE_LINKLOCAL(&nd_na->nd_na_target))
800 nd_na->nd_na_target.s6_addr16[1] = 0;
801
802 /*
803 * "tlladdr" indicates NS's condition for adding tlladdr or not.
804 * see nd6_ns_input() for details.
805 * Basically, if NS packet is sent to unicast/anycast addr,
806 * target lladdr option SHOULD NOT be included.
807 */
808 if (tlladdr && (mac = nd6_ifptomac(ifp))) {
809 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
810 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_na + 1);
811
812 /* roundup to 8 bytes alignment! */
813 optlen = (optlen + 7) & ~7;
814
815 m->m_pkthdr.len += optlen;
816 m->m_len += optlen;
817 icmp6len += optlen;
818 bzero((caddr_t)nd_opt, optlen);
819 nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
820 nd_opt->nd_opt_len = optlen >> 3;
821 bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen);
822 } else
823 flags &= ~ND_NA_FLAG_OVERRIDE;
824
825 ip6->ip6_plen = htons((u_short)icmp6len);
826 nd_na->nd_na_flags_reserved = flags;
827 nd_na->nd_na_cksum = 0;
828 nd_na->nd_na_cksum =
829 in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len);
830
831 #ifdef IPSEC
832 #ifndef __OpenBSD__ /*KAME IPSEC*/
833 m->m_pkthdr.rcvif = NULL;
834 #endif
835 #endif /*IPSEC*/
836 ip6_output(m, NULL, NULL, 0, &im6o, &outif);
837 if (outif) {
838 icmp6_ifstat_inc(outif, ifs6_out_msg);
839 icmp6_ifstat_inc(outif, ifs6_out_neighboradvert);
840 }
841 icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]++;
842 }
843
844 caddr_t
845 nd6_ifptomac(ifp)
846 struct ifnet *ifp;
847 {
848 switch (ifp->if_type) {
849 case IFT_ARCNET:
850 case IFT_ETHER:
851 case IFT_FDDI:
852 #ifdef __NetBSD__
853 return LLADDR(ifp->if_sadl);
854 #else
855 return ((caddr_t)(ifp + 1));
856 #endif
857 break;
858 default:
859 return NULL;
860 }
861 }
862
863 TAILQ_HEAD(dadq_head, dadq);
864 struct dadq {
865 TAILQ_ENTRY(dadq) dad_list;
866 struct ifaddr *dad_ifa;
867 int dad_count; /* max NS to send */
868 int dad_ns_ocount; /* NS sent so far */
869 int dad_ns_icount;
870 int dad_na_icount;
871 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
872 struct callout_handle dad_timer;
873 #endif
874 };
875
876 static struct dadq_head dadq;
877
878 static struct dadq *
879 nd6_dad_find(ifa)
880 struct ifaddr *ifa;
881 {
882 struct dadq *dp;
883
884 for (dp = dadq.tqh_first; dp; dp = dp->dad_list.tqe_next) {
885 if (dp->dad_ifa == ifa)
886 return dp;
887 }
888 return NULL;
889 }
890
891 /*
892 * Start Duplicated Address Detection (DAD) for specified interface address.
893 */
894 void
895 nd6_dad_start(ifa, tick)
896 struct ifaddr *ifa;
897 int *tick; /* minimum delay ticks for IFF_UP event */
898 {
899 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
900 struct dadq *dp;
901 static int dad_init = 0;
902
903 if (!dad_init) {
904 TAILQ_INIT(&dadq);
905 dad_init++;
906 }
907
908 /*
909 * If we don't need DAD, don't do it.
910 * There are several cases:
911 * - DAD is disabled (ip6_dad_count == 0)
912 * - the interface address is anycast
913 */
914 if (!(ia->ia6_flags & IN6_IFF_TENTATIVE)) {
915 printf("nd6_dad_start: called with non-tentative address "
916 "%s(%s)\n",
917 ip6_sprintf(&ia->ia_addr.sin6_addr),
918 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
919 return;
920 }
921 if (ia->ia6_flags & IN6_IFF_ANYCAST) {
922 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
923 return;
924 }
925 if (!ip6_dad_count) {
926 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
927 return;
928 }
929 if (!ifa->ifa_ifp)
930 panic("nd6_dad_start: ifa->ifa_ifp == NULL");
931 if (!(ifa->ifa_ifp->if_flags & IFF_UP))
932 return;
933 if (nd6_dad_find(ifa) != NULL) {
934 /* DAD already in progress */
935 return;
936 }
937
938 dp = malloc(sizeof(*dp), M_IP6NDP, M_NOWAIT);
939 if (dp == NULL) {
940 printf("nd6_dad_start: memory allocation failed for "
941 "%s(%s)\n",
942 ip6_sprintf(&ia->ia_addr.sin6_addr),
943 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
944 return;
945 }
946 bzero(dp, sizeof(*dp));
947 TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list);
948
949 /* XXXJRT This is probably a purely debugging message. */
950 printf("%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
951 ip6_sprintf(&ia->ia_addr.sin6_addr));
952
953 /*
954 * Send NS packet for DAD, ip6_dad_count times.
955 * Note that we must delay the first transmission, if this is the
956 * first packet to be sent from the interface after interface
957 * (re)initialization.
958 */
959 dp->dad_ifa = ifa;
960 ifa->ifa_refcnt++; /*just for safety*/
961 dp->dad_count = ip6_dad_count;
962 dp->dad_ns_icount = dp->dad_na_icount = 0;
963 dp->dad_ns_ocount = 0;
964 if (!tick) {
965 dp->dad_ns_ocount++;
966 nd6_ns_output(ifa->ifa_ifp, NULL, &ia->ia_addr.sin6_addr,
967 NULL, 1);
968 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
969 dp->dad_timer =
970 #endif
971 timeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa,
972 nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000);
973 } else {
974 int ntick;
975
976 if (*tick == 0)
977 ntick = random() % (MAX_RTR_SOLICITATION_DELAY * hz);
978 else
979 ntick = *tick + random() % (hz / 2);
980 *tick = ntick;
981 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
982 dp->dad_timer =
983 #endif
984 timeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa,
985 ntick);
986 }
987 }
988
989 static void
990 nd6_dad_timer(ifa)
991 struct ifaddr *ifa;
992 {
993 int s;
994 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
995 struct dadq *dp;
996
997 #ifdef __NetBSD__
998 s = splsoftnet(); /*XXX*/
999 #else
1000 s = splnet(); /*XXX*/
1001 #endif
1002
1003 /* Sanity check */
1004 if (ia == NULL) {
1005 printf("nd6_dad_timer: called with null parameter\n");
1006 goto done;
1007 }
1008 dp = nd6_dad_find(ifa);
1009 if (dp == NULL) {
1010 printf("nd6_dad_timer: DAD structure not found\n");
1011 goto done;
1012 }
1013 if (ia->ia6_flags & IN6_IFF_DUPLICATED) {
1014 printf("nd6_dad_timer: called with duplicated address "
1015 "%s(%s)\n",
1016 ip6_sprintf(&ia->ia_addr.sin6_addr),
1017 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1018 goto done;
1019 }
1020 if ((ia->ia6_flags & IN6_IFF_TENTATIVE) == 0) {
1021 printf("nd6_dad_timer: called with non-tentative address "
1022 "%s(%s)\n",
1023 ip6_sprintf(&ia->ia_addr.sin6_addr),
1024 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1025 goto done;
1026 }
1027
1028 /* Need more checks? */
1029 if (dp->dad_ns_ocount < dp->dad_count) {
1030 /*
1031 * We have more NS to go. Send NS packet for DAD.
1032 */
1033 dp->dad_ns_ocount++;
1034 nd6_ns_output(ifa->ifa_ifp, NULL, &ia->ia_addr.sin6_addr,
1035 NULL, 1);
1036 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
1037 dp->dad_timer =
1038 #endif
1039 timeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa,
1040 nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000);
1041 } else {
1042 /*
1043 * We have transmitted sufficient number of DAD packets.
1044 * See what we've got.
1045 */
1046 int duplicate;
1047
1048 duplicate = 0;
1049
1050 if (dp->dad_na_icount) {
1051 /*
1052 * the check is in nd6_dad_na_input(),
1053 * but just in case
1054 */
1055 duplicate++;
1056 }
1057
1058 if (dp->dad_ns_icount) {
1059 #if 0 /*heuristics*/
1060 /*
1061 * if
1062 * - we have sent many(?) DAD NS, and
1063 * - the number of NS we sent equals to the
1064 * number of NS we've got, and
1065 * - we've got no NA
1066 * we may have a faulty network card/driver which
1067 * loops back multicasts to myself.
1068 */
1069 if (3 < dp->dad_count
1070 && dp->dad_ns_icount == dp->dad_count
1071 && dp->dad_na_icount == 0) {
1072 log(LOG_INFO, "DAD questionable for %s(%s): "
1073 "network card loops back multicast?\n",
1074 ip6_sprintf(&ia->ia_addr.sin6_addr),
1075 if_name(ifa->ifa_ifp));
1076 /* XXX consider it a duplicate or not? */
1077 /* duplicate++; */
1078 } else {
1079 /* We've seen NS, means DAD has failed. */
1080 duplicate++;
1081 }
1082 #else
1083 /* We've seen NS, means DAD has failed. */
1084 duplicate++;
1085 #endif
1086 }
1087
1088 if (duplicate) {
1089 /* (*dp) will be freed in nd6_dad_duplicated() */
1090 dp = NULL;
1091 nd6_dad_duplicated(ifa);
1092 } else {
1093 /*
1094 * We are done with DAD. No NA came, no NS came.
1095 * duplicated address found.
1096 */
1097 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1098
1099 /* XXXJRT This is probably a purely debugging message */
1100 printf("%s: DAD complete for %s - no duplicates "
1101 "found\n", if_name(ifa->ifa_ifp),
1102 ip6_sprintf(&ia->ia_addr.sin6_addr));
1103
1104 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
1105 free(dp, M_IP6NDP);
1106 dp = NULL;
1107 ifa->ifa_refcnt--;
1108 }
1109 }
1110
1111 done:
1112 splx(s);
1113 }
1114
1115 void
1116 nd6_dad_duplicated(ifa)
1117 struct ifaddr *ifa;
1118 {
1119 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1120 struct dadq *dp;
1121
1122 dp = nd6_dad_find(ifa);
1123 if (dp == NULL) {
1124 printf("nd6_dad_duplicated: DAD structure not found\n");
1125 return;
1126 }
1127
1128 log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: %d NS, "
1129 "%d NA\n", if_name(ifa->ifa_ifp),
1130 ip6_sprintf(&ia->ia_addr.sin6_addr),
1131 dp->dad_ns_icount, dp->dad_na_icount);
1132
1133 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1134 ia->ia6_flags |= IN6_IFF_DUPLICATED;
1135
1136 /* We are done with DAD, with duplicated address found. (failure) */
1137 untimeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa
1138 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
1139 , dp->dad_timer
1140 #endif
1141 );
1142
1143 printf("%s: DAD complete for %s - duplicate found\n",
1144 if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr));
1145 printf("%s: manual intervention required\n", if_name(ifa->ifa_ifp));
1146
1147 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
1148 free(dp, M_IP6NDP);
1149 dp = NULL;
1150 ifa->ifa_refcnt--;
1151 }
1152
1153 void
1154 nd6_dad_ns_input(ifa)
1155 struct ifaddr *ifa;
1156 {
1157 struct in6_ifaddr *ia;
1158 struct ifnet *ifp;
1159 struct in6_addr *taddr6;
1160 struct dadq *dp;
1161 int duplicate;
1162
1163 if (!ifa)
1164 panic("ifa == NULL in nd6_dad_ns_input");
1165
1166 ia = (struct in6_ifaddr *)ifa;
1167 ifp = ifa->ifa_ifp;
1168 taddr6 = &ia->ia_addr.sin6_addr;
1169 duplicate = 0;
1170 dp = nd6_dad_find(ifa);
1171
1172 /*
1173 * If it is from myself, ignore this.
1174 */
1175 if (ifp && (ifp->if_flags & IFF_LOOPBACK))
1176 return;
1177
1178 /* Quickhack - completely ignore DAD NS packets */
1179 if (dad_ignore_ns) {
1180 log(LOG_INFO, "nd6_dad_ns_input: ignoring DAD NS packet for "
1181 "address %s(%s)\n", ip6_sprintf(taddr6),
1182 if_name(ifa->ifa_ifp));
1183 return;
1184 }
1185
1186 /*
1187 * if I'm yet to start DAD, someone else started using this address
1188 * first. I have a duplicate and you win.
1189 */
1190 if (!dp || dp->dad_ns_ocount == 0)
1191 duplicate++;
1192
1193 /* XXX more checks for loopback situation - see nd6_dad_timer too */
1194
1195 if (duplicate) {
1196 dp = NULL; /* will be freed in nd6_dad_duplicated() */
1197 nd6_dad_duplicated(ifa);
1198 } else {
1199 /*
1200 * not sure if I got a duplicate.
1201 * increment ns count and see what happens.
1202 */
1203 if (dp)
1204 dp->dad_ns_icount++;
1205 }
1206 }
1207
1208 void
1209 nd6_dad_na_input(ifa)
1210 struct ifaddr *ifa;
1211 {
1212 struct dadq *dp;
1213
1214 if (!ifa)
1215 panic("ifa == NULL in nd6_dad_na_input");
1216
1217 dp = nd6_dad_find(ifa);
1218 if (dp)
1219 dp->dad_na_icount++;
1220
1221 /* remove the address. */
1222 nd6_dad_duplicated(ifa);
1223 }
1224