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