1 /* $FreeBSD: src/sys/netinet6/nd6_nbr.c,v 1.4.2.6 2003/01/23 21:06:47 sam Exp $ */ 2 /* $KAME: nd6_nbr.c,v 1.86 2002/01/21 02:33:04 jinmei 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 "opt_inet.h" 34 #include "opt_inet6.h" 35 #include "opt_ipsec.h" 36 #include "opt_carp.h" 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/malloc.h> 41 #include <sys/mbuf.h> 42 #include <sys/socket.h> 43 #include <sys/sockio.h> 44 #include <sys/time.h> 45 #include <sys/kernel.h> 46 #include <sys/errno.h> 47 #include <sys/syslog.h> 48 #include <sys/queue.h> 49 #include <sys/callout.h> 50 #include <sys/mutex.h> 51 52 #include <sys/thread2.h> 53 #include <sys/mutex2.h> 54 55 #include <net/if.h> 56 #include <net/if_types.h> 57 #include <net/if_dl.h> 58 #include <net/route.h> 59 60 #include <netinet/in.h> 61 #include <netinet/in_var.h> 62 #include <netinet6/in6_var.h> 63 #include <netinet/ip6.h> 64 #include <netinet6/ip6_var.h> 65 #include <netinet6/nd6.h> 66 #include <netinet/icmp6.h> 67 68 #ifdef IPSEC 69 #include <netinet6/ipsec.h> 70 #ifdef INET6 71 #include <netinet6/ipsec6.h> 72 #endif 73 #endif 74 75 #include <net/net_osdep.h> 76 77 #ifdef CARP 78 #include <netinet/ip_carp.h> 79 #endif 80 81 82 #define SDL(s) ((struct sockaddr_dl *)s) 83 84 struct dadq; 85 static struct dadq *nd6_dad_find (struct ifaddr *); 86 static void nd6_dad_starttimer (struct dadq *, int); 87 static void nd6_dad_stoptimer (struct dadq *); 88 static void nd6_dad_timer (struct ifaddr *); 89 static void nd6_dad_ns_output (struct dadq *, struct ifaddr *); 90 static void nd6_dad_ns_input (struct ifaddr *); 91 static void nd6_dad_na_input (struct ifaddr *); 92 93 static int dad_ignore_ns = 0; /* ignore NS in DAD - specwise incorrect*/ 94 static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */ 95 96 /* 97 * Input an Neighbor Solicitation Message. 98 * 99 * Based on RFC 2461 100 * Based on RFC 2462 (duplicated address detection) 101 */ 102 void 103 nd6_ns_input(struct mbuf *m, int off, int icmp6len) 104 { 105 struct ifnet *ifp = m->m_pkthdr.rcvif; 106 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 107 struct nd_neighbor_solicit *nd_ns; 108 struct in6_addr saddr6 = ip6->ip6_src; 109 struct in6_addr daddr6 = ip6->ip6_dst; 110 struct in6_addr taddr6; 111 struct in6_addr myaddr6; 112 char *lladdr = NULL; 113 struct ifaddr *ifa = NULL; 114 int lladdrlen = 0; 115 int anycast = 0, proxy = 0, tentative = 0; 116 int tlladdr; 117 union nd_opts ndopts; 118 struct sockaddr_dl *proxydl = NULL; 119 120 #ifndef PULLDOWN_TEST 121 IP6_EXTHDR_CHECK(m, off, icmp6len,); 122 nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off); 123 #else 124 IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len); 125 if (nd_ns == NULL) { 126 icmp6stat.icp6s_tooshort++; 127 return; 128 } 129 #endif 130 ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */ 131 taddr6 = nd_ns->nd_ns_target; 132 133 if (ip6->ip6_hlim != 255) { 134 nd6log((LOG_ERR, 135 "nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n", 136 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 137 ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); 138 goto bad; 139 } 140 141 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) { 142 /* dst has to be solicited node multicast address. */ 143 if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL 144 /* don't check ifindex portion */ 145 && daddr6.s6_addr32[1] == 0 146 && daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE 147 && daddr6.s6_addr8[12] == 0xff) { 148 ; /* good */ 149 } else { 150 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet " 151 "(wrong ip6 dst)\n")); 152 goto bad; 153 } 154 } else { 155 /* 156 * Make sure the source address is from a neighbor's address. 157 */ 158 if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) { 159 nd6log((LOG_INFO, "nd6_ns_input: " 160 "NS packet from non-neighbor\n")); 161 goto bad; 162 } 163 } 164 165 if (IN6_IS_ADDR_MULTICAST(&taddr6)) { 166 nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n")); 167 goto bad; 168 } 169 170 if (IN6_IS_SCOPE_LINKLOCAL(&taddr6)) 171 taddr6.s6_addr16[1] = htons(ifp->if_index); 172 173 icmp6len -= sizeof(*nd_ns); 174 nd6_option_init(nd_ns + 1, icmp6len, &ndopts); 175 if (nd6_options(&ndopts) < 0) { 176 nd6log((LOG_INFO, 177 "nd6_ns_input: invalid ND option, ignored\n")); 178 /* nd6_options have incremented stats */ 179 goto freeit; 180 } 181 182 if (ndopts.nd_opts_src_lladdr) { 183 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 184 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 185 } 186 187 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && lladdr) { 188 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet " 189 "(link-layer address option)\n")); 190 goto bad; 191 } 192 193 /* 194 * Attaching target link-layer address to the NA? 195 * (RFC 2461 7.2.4) 196 * 197 * NS IP dst is unicast/anycast MUST NOT add 198 * NS IP dst is solicited-node multicast MUST add 199 * 200 * In implementation, we add target link-layer address by default. 201 * We do not add one in MUST NOT cases. 202 */ 203 #if 0 /* too much! */ 204 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &daddr6); 205 if (ifa && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)) 206 tlladdr = 0; 207 else 208 #endif 209 if (!IN6_IS_ADDR_MULTICAST(&daddr6)) 210 tlladdr = 0; 211 else 212 tlladdr = 1; 213 214 /* 215 * Target address (taddr6) must be either: 216 * (1) Valid unicast/anycast address for my receiving interface, 217 * (2) Unicast address for which I'm offering proxy service, or 218 * (3) "tentative" address on which DAD is being performed. 219 */ 220 /* (1) and (3) check. */ 221 #ifdef CARP 222 if (ifp->if_carp) 223 ifa = carp_iamatch6(ifp->if_carp, &taddr6); 224 if (!ifa) 225 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); 226 #else 227 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); 228 #endif 229 230 /* (2) check. */ 231 if (!ifa) { 232 struct rtentry *rt; 233 struct sockaddr_in6 tsin6; 234 235 bzero(&tsin6, sizeof tsin6); 236 tsin6.sin6_len = sizeof(struct sockaddr_in6); 237 tsin6.sin6_family = AF_INET6; 238 tsin6.sin6_addr = taddr6; 239 240 rt = rtpurelookup((struct sockaddr *)&tsin6); 241 if (rt != NULL && (rt->rt_flags & RTF_ANNOUNCE) && 242 rt->rt_gateway->sa_family == AF_LINK) { 243 /* 244 * proxy NDP for single entry 245 */ 246 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 247 IN6_IFF_NOTREADY|IN6_IFF_ANYCAST); 248 if (ifa) { 249 proxy = 1; 250 proxydl = SDL(rt->rt_gateway); 251 } 252 } 253 if (rt != NULL) 254 --rt->rt_refcnt; 255 } 256 if (ifa == NULL) { 257 /* 258 * We've got an NS packet, and we don't have that adddress 259 * assigned for us. We MUST silently ignore it. 260 * See RFC2461 7.2.3. 261 */ 262 goto freeit; 263 } 264 myaddr6 = *IFA_IN6(ifa); 265 anycast = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST; 266 tentative = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE; 267 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DUPLICATED) 268 goto freeit; 269 270 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 271 nd6log((LOG_INFO, 272 "nd6_ns_input: lladdrlen mismatch for %s " 273 "(if %d, NS packet %d)\n", 274 ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2)); 275 goto bad; 276 } 277 278 if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) { 279 nd6log((LOG_INFO, 280 "nd6_ns_input: duplicate IP6 address %s\n", 281 ip6_sprintf(&saddr6))); 282 goto freeit; 283 } 284 285 /* 286 * We have neighbor solicitation packet, with target address equals to 287 * one of my tentative address. 288 * 289 * src addr how to process? 290 * --- --- 291 * multicast of course, invalid (rejected in ip6_input) 292 * unicast somebody is doing address resolution -> ignore 293 * unspec dup address detection 294 * 295 * The processing is defined in RFC 2462. 296 */ 297 if (tentative) { 298 /* 299 * If source address is unspecified address, it is for 300 * duplicated address detection. 301 * 302 * If not, the packet is for addess resolution; 303 * silently ignore it. 304 */ 305 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) 306 nd6_dad_ns_input(ifa); 307 308 goto freeit; 309 } 310 311 /* 312 * If the source address is unspecified address, entries must not 313 * be created or updated. 314 * It looks that sender is performing DAD. Output NA toward 315 * all-node multicast address, to tell the sender that I'm using 316 * the address. 317 * S bit ("solicited") must be zero. 318 */ 319 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) { 320 saddr6 = kin6addr_linklocal_allnodes; 321 saddr6.s6_addr16[1] = htons(ifp->if_index); 322 nd6_na_output(ifp, &saddr6, &taddr6, 323 ((anycast || proxy || !tlladdr) 324 ? 0 : ND_NA_FLAG_OVERRIDE) 325 | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0), 326 tlladdr, (struct sockaddr *)proxydl); 327 goto freeit; 328 } 329 330 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_NEIGHBOR_SOLICIT, 0); 331 332 nd6_na_output(ifp, &saddr6, &taddr6, 333 ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) 334 | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0) 335 | ND_NA_FLAG_SOLICITED, 336 tlladdr, (struct sockaddr *)proxydl); 337 freeit: 338 m_freem(m); 339 return; 340 341 bad: 342 nd6log((LOG_ERR, "nd6_ns_input: src=%s\n", ip6_sprintf(&saddr6))); 343 nd6log((LOG_ERR, "nd6_ns_input: dst=%s\n", ip6_sprintf(&daddr6))); 344 nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n", ip6_sprintf(&taddr6))); 345 icmp6stat.icp6s_badns++; 346 m_freem(m); 347 } 348 349 /* 350 * Output an Neighbor Solicitation Message. Caller specifies: 351 * - ICMP6 header source IP6 address 352 * - ND6 header target IP6 address 353 * - ND6 header source datalink address 354 * 355 * Based on RFC 2461 356 * Based on RFC 2462 (duplicated address detection) 357 */ 358 void 359 nd6_ns_output(struct ifnet *ifp, const struct in6_addr *daddr6, 360 const struct in6_addr *taddr6, 361 struct llinfo_nd6 *ln, /* for source address determination */ 362 int dad) /* duplicated address detection */ 363 { 364 struct mbuf *m; 365 struct ip6_hdr *ip6; 366 struct nd_neighbor_solicit *nd_ns; 367 struct in6_ifaddr *ia = NULL; 368 struct ip6_moptions im6o; 369 int icmp6len; 370 int maxlen; 371 caddr_t mac; 372 struct ifnet *outif = NULL; 373 374 if (IN6_IS_ADDR_MULTICAST(taddr6)) 375 return; 376 377 /* estimate the size of message */ 378 maxlen = sizeof(*ip6) + sizeof(*nd_ns); 379 maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7; 380 if (max_linkhdr + maxlen >= MCLBYTES) { 381 #ifdef DIAGNOSTIC 382 kprintf("nd6_ns_output: max_linkhdr + maxlen >= MCLBYTES " 383 "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES); 384 #endif 385 return; 386 } 387 388 m = m_getb(max_linkhdr + maxlen, MB_DONTWAIT, MT_DATA, M_PKTHDR); 389 if (m == NULL) 390 return; 391 392 if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) { 393 m->m_flags |= M_MCAST; 394 im6o.im6o_multicast_ifp = ifp; 395 im6o.im6o_multicast_hlim = 255; 396 im6o.im6o_multicast_loop = 0; 397 } 398 399 icmp6len = sizeof(*nd_ns); 400 m->m_pkthdr.len = m->m_len = sizeof(*ip6) + icmp6len; 401 m->m_data += max_linkhdr; /* or MH_ALIGN() equivalent? */ 402 403 /* fill neighbor solicitation packet */ 404 ip6 = mtod(m, struct ip6_hdr *); 405 ip6->ip6_flow = 0; 406 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 407 ip6->ip6_vfc |= IPV6_VERSION; 408 /* ip6->ip6_plen will be set later */ 409 ip6->ip6_nxt = IPPROTO_ICMPV6; 410 ip6->ip6_hlim = 255; 411 if (daddr6) 412 ip6->ip6_dst = *daddr6; 413 else { 414 ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL; 415 ip6->ip6_dst.s6_addr16[1] = htons(ifp->if_index); 416 ip6->ip6_dst.s6_addr32[1] = 0; 417 ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE; 418 ip6->ip6_dst.s6_addr32[3] = taddr6->s6_addr32[3]; 419 ip6->ip6_dst.s6_addr8[12] = 0xff; 420 } 421 if (!dad) { 422 #if 0 /* KAME way, exact address scope match */ 423 /* 424 * Select a source whose scope is the same as that of the dest. 425 * Typically, the dest is link-local solicitation multicast 426 * (i.e. neighbor discovery) or link-local/global unicast 427 * (i.e. neighbor un-reachability detection). 428 */ 429 ia = in6_ifawithifp(ifp, &ip6->ip6_dst); 430 if (ia == NULL) { 431 m_freem(m); 432 return; 433 } 434 ip6->ip6_src = ia->ia_addr.sin6_addr; 435 #else /* spec-wise correct */ 436 /* 437 * RFC2461 7.2.2: 438 * "If the source address of the packet prompting the 439 * solicitation is the same as one of the addresses assigned 440 * to the outgoing interface, that address SHOULD be placed 441 * in the IP Source Address of the outgoing solicitation. 442 * Otherwise, any one of the addresses assigned to the 443 * interface should be used." 444 * 445 * We use the source address for the prompting packet 446 * (saddr6), if: 447 * - saddr6 is given from the caller (by giving "ln"), and 448 * - saddr6 belongs to the outgoing interface. 449 * Otherwise, we perform a scope-wise match. 450 */ 451 struct ip6_hdr *hip6; /* hold ip6 */ 452 struct in6_addr *saddr6; 453 454 if (ln && ln->ln_hold) { 455 hip6 = mtod(ln->ln_hold, struct ip6_hdr *); 456 /* XXX pullup? */ 457 if (sizeof(*hip6) < ln->ln_hold->m_len) 458 saddr6 = &hip6->ip6_src; 459 else 460 saddr6 = NULL; 461 } else 462 saddr6 = NULL; 463 if (saddr6 && in6ifa_ifpwithaddr(ifp, saddr6)) 464 bcopy(saddr6, &ip6->ip6_src, sizeof(*saddr6)); 465 else { 466 ia = in6_ifawithifp(ifp, &ip6->ip6_dst); 467 if (ia == NULL) { 468 m_freem(m); 469 return; 470 } 471 ip6->ip6_src = ia->ia_addr.sin6_addr; 472 } 473 #endif 474 } else { 475 /* 476 * Source address for DAD packet must always be IPv6 477 * unspecified address. (0::0) 478 */ 479 bzero(&ip6->ip6_src, sizeof(ip6->ip6_src)); 480 } 481 nd_ns = (struct nd_neighbor_solicit *)(ip6 + 1); 482 nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT; 483 nd_ns->nd_ns_code = 0; 484 nd_ns->nd_ns_reserved = 0; 485 nd_ns->nd_ns_target = *taddr6; 486 487 if (IN6_IS_SCOPE_LINKLOCAL(&nd_ns->nd_ns_target)) 488 nd_ns->nd_ns_target.s6_addr16[1] = 0; 489 490 /* 491 * Add source link-layer address option. 492 * 493 * spec implementation 494 * --- --- 495 * DAD packet MUST NOT do not add the option 496 * there's no link layer address: 497 * impossible do not add the option 498 * there's link layer address: 499 * Multicast NS MUST add one add the option 500 * Unicast NS SHOULD add one add the option 501 */ 502 if (!dad && (mac = nd6_ifptomac(ifp))) { 503 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen; 504 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1); 505 /* 8 byte alignments... */ 506 optlen = (optlen + 7) & ~7; 507 508 m->m_pkthdr.len += optlen; 509 m->m_len += optlen; 510 icmp6len += optlen; 511 bzero((caddr_t)nd_opt, optlen); 512 nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; 513 nd_opt->nd_opt_len = optlen >> 3; 514 bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen); 515 } 516 517 ip6->ip6_plen = htons((u_short)icmp6len); 518 nd_ns->nd_ns_cksum = 0; 519 nd_ns->nd_ns_cksum 520 = in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len); 521 522 ip6_output(m, NULL, NULL, dad ? IPV6_DADOUTPUT : 0, &im6o, &outif, NULL); 523 if (outif) { 524 icmp6_ifstat_inc(outif, ifs6_out_msg); 525 icmp6_ifstat_inc(outif, ifs6_out_neighborsolicit); 526 } 527 icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++; 528 } 529 530 /* 531 * Neighbor advertisement input handling. 532 * 533 * Based on RFC 2461 534 * Based on RFC 2462 (duplicated address detection) 535 * 536 * the following items are not implemented yet: 537 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD) 538 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD) 539 */ 540 void 541 nd6_na_input(struct mbuf *m, int off, int icmp6len) 542 { 543 struct ifnet *ifp = m->m_pkthdr.rcvif; 544 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 545 struct nd_neighbor_advert *nd_na; 546 struct in6_addr saddr6 = ip6->ip6_src; 547 struct in6_addr daddr6 = ip6->ip6_dst; 548 struct in6_addr taddr6; 549 int flags; 550 int is_router; 551 int is_solicited; 552 int is_override; 553 char *lladdr = NULL; 554 int lladdrlen = 0; 555 struct ifaddr *ifa; 556 struct llinfo_nd6 *ln; 557 struct rtentry *rt; 558 struct sockaddr_dl *sdl; 559 union nd_opts ndopts; 560 561 if (ip6->ip6_hlim != 255) { 562 nd6log((LOG_ERR, 563 "nd6_na_input: invalid hlim (%d) from %s to %s on %s\n", 564 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 565 ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); 566 goto bad; 567 } 568 569 #ifndef PULLDOWN_TEST 570 IP6_EXTHDR_CHECK(m, off, icmp6len,); 571 nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off); 572 #else 573 IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len); 574 if (nd_na == NULL) { 575 icmp6stat.icp6s_tooshort++; 576 return; 577 } 578 #endif 579 taddr6 = nd_na->nd_na_target; 580 flags = nd_na->nd_na_flags_reserved; 581 is_router = ((flags & ND_NA_FLAG_ROUTER) != 0); 582 is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0); 583 is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0); 584 585 if (IN6_IS_SCOPE_LINKLOCAL(&taddr6)) 586 taddr6.s6_addr16[1] = htons(ifp->if_index); 587 588 if (IN6_IS_ADDR_MULTICAST(&taddr6)) { 589 nd6log((LOG_ERR, 590 "nd6_na_input: invalid target address %s\n", 591 ip6_sprintf(&taddr6))); 592 goto bad; 593 } 594 if (IN6_IS_ADDR_MULTICAST(&daddr6)) 595 if (is_solicited) { 596 nd6log((LOG_ERR, 597 "nd6_na_input: a solicited adv is multicasted\n")); 598 goto bad; 599 } 600 601 icmp6len -= sizeof(*nd_na); 602 nd6_option_init(nd_na + 1, icmp6len, &ndopts); 603 if (nd6_options(&ndopts) < 0) { 604 nd6log((LOG_INFO, 605 "nd6_na_input: invalid ND option, ignored\n")); 606 /* nd6_options have incremented stats */ 607 goto freeit; 608 } 609 610 if (ndopts.nd_opts_tgt_lladdr) { 611 lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1); 612 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; 613 } 614 615 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); 616 617 /* 618 * Target address matches one of my interface address. 619 * 620 * If my address is tentative, this means that there's somebody 621 * already using the same address as mine. This indicates DAD failure. 622 * This is defined in RFC 2462. 623 * 624 * Otherwise, process as defined in RFC 2461. 625 */ 626 if (ifa 627 && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) { 628 nd6_dad_na_input(ifa); 629 goto freeit; 630 } 631 632 /* Just for safety, maybe unnecessary. */ 633 if (ifa) { 634 log(LOG_ERR, 635 "nd6_na_input: duplicate IP6 address %s\n", 636 ip6_sprintf(&taddr6)); 637 goto freeit; 638 } 639 640 /* 641 * Make sure the source address is from a neighbor's address. 642 */ 643 if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) { 644 nd6log((LOG_INFO, "nd6_na_input: " 645 "NA packet from non-neighbor\n")); 646 goto bad; 647 } 648 649 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 650 nd6log((LOG_INFO, 651 "nd6_na_input: lladdrlen mismatch for %s " 652 "(if %d, NA packet %d)\n", 653 ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2)); 654 goto bad; 655 } 656 657 /* 658 * If no neighbor cache entry is found, NA SHOULD silently be discarded. 659 */ 660 rt = nd6_lookup(&taddr6, 0, ifp); 661 if ((rt == NULL) || 662 ((ln = (struct llinfo_nd6 *)rt->rt_llinfo) == NULL) || 663 ((sdl = SDL(rt->rt_gateway)) == NULL)) 664 goto freeit; 665 666 if (ln->ln_state == ND6_LLINFO_INCOMPLETE) { 667 /* 668 * If the link-layer has address, and no lladdr option came, 669 * discard the packet. 670 */ 671 if (ifp->if_addrlen && !lladdr) 672 goto freeit; 673 674 /* 675 * Record link-layer address, and update the state. 676 */ 677 sdl->sdl_alen = ifp->if_addrlen; 678 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen); 679 if (is_solicited) { 680 ln->ln_state = ND6_LLINFO_REACHABLE; 681 ln->ln_byhint = 0; 682 if (ln->ln_expire) 683 ln->ln_expire = time_second + 684 ND_IFINFO(rt->rt_ifp)->reachable; 685 } else { 686 ln->ln_state = ND6_LLINFO_STALE; 687 ln->ln_expire = time_second + nd6_gctimer; 688 } 689 if ((ln->ln_router = is_router) != 0) { 690 /* 691 * This means a router's state has changed from 692 * non-reachable to probably reachable, and might 693 * affect the status of associated prefixes.. 694 */ 695 pfxlist_onlink_check(); 696 } 697 } else { 698 int llchange; 699 700 /* 701 * Check if the link-layer address has changed or not. 702 */ 703 if (!lladdr) 704 llchange = 0; 705 else { 706 if (sdl->sdl_alen) { 707 if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen)) 708 llchange = 1; 709 else 710 llchange = 0; 711 } else 712 llchange = 1; 713 } 714 715 /* 716 * This is VERY complex. Look at it with care. 717 * 718 * override solicit lladdr llchange action 719 * (L: record lladdr) 720 * 721 * 0 0 n -- (2c) 722 * 0 0 y n (2b) L 723 * 0 0 y y (1) REACHABLE->STALE 724 * 0 1 n -- (2c) *->REACHABLE 725 * 0 1 y n (2b) L *->REACHABLE 726 * 0 1 y y (1) REACHABLE->STALE 727 * 1 0 n -- (2a) 728 * 1 0 y n (2a) L 729 * 1 0 y y (2a) L *->STALE 730 * 1 1 n -- (2a) *->REACHABLE 731 * 1 1 y n (2a) L *->REACHABLE 732 * 1 1 y y (2a) L *->REACHABLE 733 */ 734 if (!is_override && (lladdr && llchange)) { /* (1) */ 735 /* 736 * If state is REACHABLE, make it STALE. 737 * no other updates should be done. 738 */ 739 if (ln->ln_state == ND6_LLINFO_REACHABLE) { 740 ln->ln_state = ND6_LLINFO_STALE; 741 ln->ln_expire = time_second + nd6_gctimer; 742 } 743 goto freeit; 744 } else if (is_override /* (2a) */ 745 || (!is_override && (lladdr && !llchange)) /* (2b) */ 746 || !lladdr) { /* (2c) */ 747 /* 748 * Update link-local address, if any. 749 */ 750 if (lladdr) { 751 sdl->sdl_alen = ifp->if_addrlen; 752 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen); 753 } 754 755 /* 756 * If solicited, make the state REACHABLE. 757 * If not solicited and the link-layer address was 758 * changed, make it STALE. 759 */ 760 if (is_solicited) { 761 ln->ln_state = ND6_LLINFO_REACHABLE; 762 ln->ln_byhint = 0; 763 if (ln->ln_expire) { 764 ln->ln_expire = time_second + 765 ND_IFINFO(ifp)->reachable; 766 } 767 } else { 768 if (lladdr && llchange) { 769 ln->ln_state = ND6_LLINFO_STALE; 770 ln->ln_expire = time_second + nd6_gctimer; 771 } 772 } 773 } 774 775 if (ln->ln_router && !is_router) { 776 /* 777 * The peer dropped the router flag. 778 * Remove the sender from the Default Router List and 779 * update the Destination Cache entries. 780 */ 781 struct nd_defrouter *dr; 782 struct in6_addr *in6; 783 784 in6 = &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr; 785 786 /* 787 * Lock to protect the default router list. 788 * XXX: this might be unnecessary, since this function 789 * is only called under the network software interrupt 790 * context. However, we keep it just for safety. 791 */ 792 mtx_lock(&nd6_mtx); 793 dr = defrouter_lookup(in6, rt->rt_ifp); 794 if (dr) 795 defrtrlist_del(dr); 796 mtx_unlock(&nd6_mtx); 797 798 if (dr == NULL && !ip6_forwarding && ip6_accept_rtadv) { 799 /* 800 * Even if the neighbor is not in the default 801 * router list, the neighbor may be used 802 * as a next hop for some destinations 803 * (e.g. redirect case). So we must 804 * call rt6_flush explicitly. 805 */ 806 rt6_flush(&ip6->ip6_src, rt->rt_ifp); 807 } 808 } 809 ln->ln_router = is_router; 810 } 811 rt->rt_flags &= ~RTF_REJECT; 812 ln->ln_asked = 0; 813 if (ln->ln_hold) { 814 /* 815 * we assume ifp is not a loopback here, so just set the 2nd 816 * argument as the 1st one. 817 */ 818 nd6_output(ifp, ifp, ln->ln_hold, 819 (struct sockaddr_in6 *)rt_key(rt), rt); 820 ln->ln_hold = 0; 821 } 822 823 freeit: 824 m_freem(m); 825 return; 826 827 bad: 828 icmp6stat.icp6s_badna++; 829 m_freem(m); 830 } 831 832 /* 833 * Neighbor advertisement output handling. 834 * 835 * Based on RFC 2461 836 * 837 * the following items are not implemented yet: 838 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD) 839 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD) 840 */ 841 void 842 nd6_na_output(struct ifnet *ifp, const struct in6_addr *daddr6, 843 const struct in6_addr *taddr6, u_long flags, 844 int tlladdr, /* 1 if include target link-layer address */ 845 struct sockaddr *sdl0) /* sockaddr_dl (= proxy NA) or NULL */ 846 { 847 struct mbuf *m; 848 struct ip6_hdr *ip6; 849 struct nd_neighbor_advert *nd_na; 850 struct in6_ifaddr *ia = NULL; 851 struct ip6_moptions im6o; 852 int icmp6len; 853 int maxlen; 854 caddr_t mac; 855 struct ifnet *outif = NULL; 856 857 /* estimate the size of message */ 858 maxlen = sizeof(*ip6) + sizeof(*nd_na); 859 maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7; 860 if (max_linkhdr + maxlen >= MCLBYTES) { 861 #ifdef DIAGNOSTIC 862 kprintf("nd6_na_output: max_linkhdr + maxlen >= MCLBYTES " 863 "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES); 864 #endif 865 return; 866 } 867 868 m = m_getb(max_linkhdr + maxlen, MB_DONTWAIT, MT_DATA, M_PKTHDR); 869 if (m == NULL) 870 return; 871 872 if (IN6_IS_ADDR_MULTICAST(daddr6)) { 873 m->m_flags |= M_MCAST; 874 im6o.im6o_multicast_ifp = ifp; 875 im6o.im6o_multicast_hlim = 255; 876 im6o.im6o_multicast_loop = 0; 877 } 878 879 icmp6len = sizeof(*nd_na); 880 m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + icmp6len; 881 m->m_data += max_linkhdr; /* or MH_ALIGN() equivalent? */ 882 883 /* fill neighbor advertisement packet */ 884 ip6 = mtod(m, struct ip6_hdr *); 885 ip6->ip6_flow = 0; 886 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 887 ip6->ip6_vfc |= IPV6_VERSION; 888 ip6->ip6_nxt = IPPROTO_ICMPV6; 889 ip6->ip6_hlim = 255; 890 if (IN6_IS_ADDR_UNSPECIFIED(daddr6)) { 891 /* reply to DAD */ 892 ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL; 893 ip6->ip6_dst.s6_addr16[1] = htons(ifp->if_index); 894 ip6->ip6_dst.s6_addr32[1] = 0; 895 ip6->ip6_dst.s6_addr32[2] = 0; 896 ip6->ip6_dst.s6_addr32[3] = IPV6_ADDR_INT32_ONE; 897 flags &= ~ND_NA_FLAG_SOLICITED; 898 } else 899 ip6->ip6_dst = *daddr6; 900 901 /* 902 * Select a source whose scope is the same as that of the dest. 903 */ 904 ia = in6_ifawithifp(ifp, &ip6->ip6_dst); 905 if (ia == NULL) { 906 m_freem(m); 907 return; 908 } 909 ip6->ip6_src = ia->ia_addr.sin6_addr; 910 nd_na = (struct nd_neighbor_advert *)(ip6 + 1); 911 nd_na->nd_na_type = ND_NEIGHBOR_ADVERT; 912 nd_na->nd_na_code = 0; 913 nd_na->nd_na_target = *taddr6; 914 if (IN6_IS_SCOPE_LINKLOCAL(&nd_na->nd_na_target)) 915 nd_na->nd_na_target.s6_addr16[1] = 0; 916 917 /* 918 * "tlladdr" indicates NS's condition for adding tlladdr or not. 919 * see nd6_ns_input() for details. 920 * Basically, if NS packet is sent to unicast/anycast addr, 921 * target lladdr option SHOULD NOT be included. 922 */ 923 mac = NULL; 924 if (tlladdr) { 925 /* 926 * sdl0 != NULL indicates proxy NA. If we do proxy, use 927 * lladdr in sdl0. If we are not proxying (sending NA for 928 * my address) use lladdr configured for the interface. 929 */ 930 if (sdl0 == NULL) { 931 #ifdef CARP 932 if (ifp->if_carp) 933 mac = carp_macmatch6(ifp->if_carp, m, taddr6); 934 if (mac == NULL) 935 mac = nd6_ifptomac(ifp); 936 #else 937 mac = nd6_ifptomac(ifp); 938 #endif 939 } else if (sdl0->sa_family == AF_LINK) { 940 struct sockaddr_dl *sdl; 941 sdl = (struct sockaddr_dl *)sdl0; 942 if (sdl->sdl_alen == ifp->if_addrlen) 943 mac = LLADDR(sdl); 944 } 945 } 946 if (mac != NULL) { 947 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen; 948 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_na + 1); 949 950 /* roundup to 8 bytes alignment! */ 951 optlen = (optlen + 7) & ~7; 952 953 m->m_pkthdr.len += optlen; 954 m->m_len += optlen; 955 icmp6len += optlen; 956 bzero((caddr_t)nd_opt, optlen); 957 nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR; 958 nd_opt->nd_opt_len = optlen >> 3; 959 bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen); 960 } else 961 flags &= ~ND_NA_FLAG_OVERRIDE; 962 963 ip6->ip6_plen = htons((u_short)icmp6len); 964 nd_na->nd_na_flags_reserved = flags; 965 nd_na->nd_na_cksum = 0; 966 nd_na->nd_na_cksum = 967 in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len); 968 969 ip6_output(m, NULL, NULL, 0, &im6o, &outif, NULL); 970 if (outif) { 971 icmp6_ifstat_inc(outif, ifs6_out_msg); 972 icmp6_ifstat_inc(outif, ifs6_out_neighboradvert); 973 } 974 icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]++; 975 } 976 977 caddr_t 978 nd6_ifptomac(struct ifnet *ifp) 979 { 980 switch (ifp->if_type) { 981 case IFT_ETHER: 982 case IFT_IEEE1394: 983 #ifdef IFT_L2VLAN 984 case IFT_L2VLAN: 985 #endif 986 #ifdef IFT_IEEE80211 987 case IFT_IEEE80211: 988 #endif 989 #ifdef IFT_CARP 990 case IFT_CARP: 991 #endif 992 return ((caddr_t)(ifp + 1)); 993 break; 994 default: 995 return NULL; 996 } 997 } 998 999 TAILQ_HEAD(dadq_head, dadq); 1000 struct dadq { 1001 TAILQ_ENTRY(dadq) dad_list; 1002 struct ifaddr *dad_ifa; 1003 int dad_count; /* max NS to send */ 1004 int dad_ns_tcount; /* # of trials to send NS */ 1005 int dad_ns_ocount; /* NS sent so far */ 1006 int dad_ns_icount; 1007 int dad_na_icount; 1008 struct callout dad_timer_ch; 1009 }; 1010 1011 static struct dadq_head dadq; 1012 static int dad_init = 0; 1013 1014 static struct dadq * 1015 nd6_dad_find(struct ifaddr *ifa) 1016 { 1017 struct dadq *dp; 1018 1019 TAILQ_FOREACH(dp, &dadq, dad_list) { 1020 if (dp->dad_ifa == ifa) 1021 return dp; 1022 } 1023 return NULL; 1024 } 1025 1026 static void 1027 nd6_dad_starttimer(struct dadq *dp, int ticks) 1028 { 1029 1030 callout_reset(&dp->dad_timer_ch, ticks, 1031 (void (*) (void *))nd6_dad_timer, (void *)dp->dad_ifa); 1032 } 1033 1034 static void 1035 nd6_dad_stoptimer(struct dadq *dp) 1036 { 1037 1038 callout_stop(&dp->dad_timer_ch); 1039 } 1040 1041 /* 1042 * Start Duplicated Address Detection (DAD) for specified interface address. 1043 */ 1044 void 1045 nd6_dad_start(struct ifaddr *ifa, 1046 int *tick) /* minimum delay ticks for IFF_UP event */ 1047 { 1048 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1049 struct dadq *dp; 1050 1051 if (!dad_init) { 1052 TAILQ_INIT(&dadq); 1053 dad_init++; 1054 } 1055 1056 /* 1057 * If we don't need DAD, don't do it. 1058 * There are several cases: 1059 * - DAD is disabled (ip6_dad_count == 0) 1060 * - the interface address is anycast 1061 */ 1062 if (!(ia->ia6_flags & IN6_IFF_TENTATIVE)) { 1063 log(LOG_DEBUG, 1064 "nd6_dad_start: called with non-tentative address " 1065 "%s(%s)\n", 1066 ip6_sprintf(&ia->ia_addr.sin6_addr), 1067 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1068 return; 1069 } 1070 if (ia->ia6_flags & IN6_IFF_ANYCAST) { 1071 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 1072 return; 1073 } 1074 if (!ip6_dad_count) { 1075 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 1076 return; 1077 } 1078 if (!ifa->ifa_ifp) 1079 panic("nd6_dad_start: ifa->ifa_ifp == NULL"); 1080 if (!(ifa->ifa_ifp->if_flags & IFF_UP)) 1081 return; 1082 if (nd6_dad_find(ifa) != NULL) { 1083 /* DAD already in progress */ 1084 return; 1085 } 1086 1087 dp = kmalloc(sizeof(*dp), M_IP6NDP, M_NOWAIT | M_ZERO); 1088 if (dp == NULL) { 1089 log(LOG_ERR, "nd6_dad_start: memory allocation failed for " 1090 "%s(%s)\n", 1091 ip6_sprintf(&ia->ia_addr.sin6_addr), 1092 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1093 return; 1094 } 1095 callout_init(&dp->dad_timer_ch); 1096 TAILQ_INSERT_TAIL(&dadq, dp, dad_list); 1097 1098 nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), 1099 ip6_sprintf(&ia->ia_addr.sin6_addr))); 1100 1101 /* 1102 * Send NS packet for DAD, ip6_dad_count times. 1103 * Note that we must delay the first transmission, if this is the 1104 * first packet to be sent from the interface after interface 1105 * (re)initialization. 1106 */ 1107 dp->dad_ifa = ifa; 1108 _IFAREF(ifa, 0); /* just for safety */ 1109 dp->dad_count = ip6_dad_count; 1110 dp->dad_ns_icount = dp->dad_na_icount = 0; 1111 dp->dad_ns_ocount = dp->dad_ns_tcount = 0; 1112 if (tick == NULL) { 1113 nd6_dad_ns_output(dp, ifa); 1114 nd6_dad_starttimer(dp, 1115 ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); 1116 } else { 1117 int ntick; 1118 1119 if (*tick == 0) 1120 ntick = krandom() % (MAX_RTR_SOLICITATION_DELAY * hz); 1121 else 1122 ntick = *tick + krandom() % (hz / 2); 1123 *tick = ntick; 1124 nd6_dad_starttimer(dp, ntick); 1125 } 1126 } 1127 1128 /* 1129 * terminate DAD unconditionally. used for address removals. 1130 */ 1131 void 1132 nd6_dad_stop(struct ifaddr *ifa) 1133 { 1134 struct dadq *dp; 1135 1136 if (!dad_init) 1137 return; 1138 dp = nd6_dad_find(ifa); 1139 if (!dp) { 1140 /* DAD wasn't started yet */ 1141 return; 1142 } 1143 1144 nd6_dad_stoptimer(dp); 1145 1146 TAILQ_REMOVE(&dadq, dp, dad_list); 1147 kfree(dp, M_IP6NDP); 1148 dp = NULL; 1149 _IFAFREE(ifa, 0); 1150 } 1151 1152 static void 1153 nd6_dad_timer(struct ifaddr *ifa) 1154 { 1155 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1156 struct dadq *dp; 1157 1158 mtx_lock(&nd6_mtx); 1159 1160 /* Sanity check */ 1161 if (ia == NULL) { 1162 log(LOG_ERR, "nd6_dad_timer: called with null parameter\n"); 1163 goto done; 1164 } 1165 dp = nd6_dad_find(ifa); 1166 if (dp == NULL) { 1167 log(LOG_ERR, "nd6_dad_timer: DAD structure not found\n"); 1168 goto done; 1169 } 1170 if (ia->ia6_flags & IN6_IFF_DUPLICATED) { 1171 log(LOG_ERR, "nd6_dad_timer: called with duplicated address " 1172 "%s(%s)\n", 1173 ip6_sprintf(&ia->ia_addr.sin6_addr), 1174 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1175 goto done; 1176 } 1177 if (!(ia->ia6_flags & IN6_IFF_TENTATIVE)) { 1178 log(LOG_ERR, "nd6_dad_timer: called with non-tentative address " 1179 "%s(%s)\n", 1180 ip6_sprintf(&ia->ia_addr.sin6_addr), 1181 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1182 goto done; 1183 } 1184 1185 /* timeouted with IFF_{RUNNING,UP} check */ 1186 if (dp->dad_ns_tcount > dad_maxtry) { 1187 nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n", 1188 if_name(ifa->ifa_ifp))); 1189 1190 TAILQ_REMOVE(&dadq, dp, dad_list); 1191 kfree(dp, M_IP6NDP); 1192 dp = NULL; 1193 _IFAFREE(ifa, 0); 1194 goto done; 1195 } 1196 1197 /* Need more checks? */ 1198 if (dp->dad_ns_ocount < dp->dad_count) { 1199 /* 1200 * We have more NS to go. Send NS packet for DAD. 1201 */ 1202 nd6_dad_ns_output(dp, ifa); 1203 nd6_dad_starttimer(dp, 1204 ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); 1205 } else { 1206 /* 1207 * We have transmitted sufficient number of DAD packets. 1208 * See what we've got. 1209 */ 1210 int duplicate; 1211 1212 duplicate = 0; 1213 1214 if (dp->dad_na_icount) { 1215 /* 1216 * the check is in nd6_dad_na_input(), 1217 * but just in case 1218 */ 1219 duplicate++; 1220 } 1221 1222 if (dp->dad_ns_icount) { 1223 #if 0 /* heuristics */ 1224 /* 1225 * if 1226 * - we have sent many(?) DAD NS, and 1227 * - the number of NS we sent equals to the 1228 * number of NS we've got, and 1229 * - we've got no NA 1230 * we may have a faulty network card/driver which 1231 * loops back multicasts to myself. 1232 */ 1233 if (3 < dp->dad_count 1234 && dp->dad_ns_icount == dp->dad_count 1235 && dp->dad_na_icount == 0) { 1236 log(LOG_INFO, "DAD questionable for %s(%s): " 1237 "network card loops back multicast?\n", 1238 ip6_sprintf(&ia->ia_addr.sin6_addr), 1239 if_name(ifa->ifa_ifp)); 1240 /* XXX consider it a duplicate or not? */ 1241 /* duplicate++; */ 1242 } else { 1243 /* We've seen NS, means DAD has failed. */ 1244 duplicate++; 1245 } 1246 #else 1247 /* We've seen NS, means DAD has failed. */ 1248 duplicate++; 1249 #endif 1250 } 1251 1252 if (duplicate) { 1253 /* (*dp) will be freed in nd6_dad_duplicated() */ 1254 dp = NULL; 1255 nd6_dad_duplicated(ifa); 1256 } else { 1257 /* 1258 * We are done with DAD. No NA came, no NS came. 1259 * duplicated address found. 1260 */ 1261 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 1262 1263 nd6log((LOG_DEBUG, 1264 "%s: DAD complete for %s - no duplicates found\n", 1265 if_name(ifa->ifa_ifp), 1266 ip6_sprintf(&ia->ia_addr.sin6_addr))); 1267 1268 TAILQ_REMOVE(&dadq, dp, dad_list); 1269 kfree(dp, M_IP6NDP); 1270 dp = NULL; 1271 _IFAFREE(ifa, 0); 1272 } 1273 } 1274 1275 done: 1276 mtx_unlock(&nd6_mtx); 1277 } 1278 1279 void 1280 nd6_dad_duplicated(struct ifaddr *ifa) 1281 { 1282 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1283 struct dadq *dp; 1284 1285 dp = nd6_dad_find(ifa); 1286 if (dp == NULL) { 1287 log(LOG_ERR, "nd6_dad_duplicated: DAD structure not found\n"); 1288 return; 1289 } 1290 1291 log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: " 1292 "NS in/out=%d/%d, NA in=%d\n", 1293 if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr), 1294 dp->dad_ns_icount, dp->dad_ns_ocount, dp->dad_na_icount); 1295 1296 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 1297 ia->ia6_flags |= IN6_IFF_DUPLICATED; 1298 1299 /* We are done with DAD, with duplicated address found. (failure) */ 1300 nd6_dad_stoptimer(dp); 1301 1302 log(LOG_ERR, "%s: DAD complete for %s - duplicate found\n", 1303 if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr)); 1304 log(LOG_ERR, "%s: manual intervention required\n", 1305 if_name(ifa->ifa_ifp)); 1306 1307 TAILQ_REMOVE(&dadq, dp, dad_list); 1308 kfree(dp, M_IP6NDP); 1309 dp = NULL; 1310 _IFAFREE(ifa, 0); 1311 } 1312 1313 static void 1314 nd6_dad_ns_output(struct dadq *dp, struct ifaddr *ifa) 1315 { 1316 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1317 struct ifnet *ifp = ifa->ifa_ifp; 1318 1319 dp->dad_ns_tcount++; 1320 if (!(ifp->if_flags & IFF_UP)) { 1321 #if 0 1322 kprintf("%s: interface down?\n", if_name(ifp)); 1323 #endif 1324 return; 1325 } 1326 if (!(ifp->if_flags & IFF_RUNNING)) { 1327 #if 0 1328 kprintf("%s: interface not running?\n", if_name(ifp)); 1329 #endif 1330 return; 1331 } 1332 1333 dp->dad_ns_ocount++; 1334 nd6_ns_output(ifp, NULL, &ia->ia_addr.sin6_addr, NULL, 1); 1335 } 1336 1337 static void 1338 nd6_dad_ns_input(struct ifaddr *ifa) 1339 { 1340 struct in6_ifaddr *ia; 1341 struct ifnet *ifp; 1342 const struct in6_addr *taddr6; 1343 struct dadq *dp; 1344 int duplicate; 1345 1346 if (!ifa) 1347 panic("ifa == NULL in nd6_dad_ns_input"); 1348 1349 ia = (struct in6_ifaddr *)ifa; 1350 ifp = ifa->ifa_ifp; 1351 taddr6 = &ia->ia_addr.sin6_addr; 1352 duplicate = 0; 1353 dp = nd6_dad_find(ifa); 1354 1355 /* Quickhack - completely ignore DAD NS packets */ 1356 if (dad_ignore_ns) { 1357 nd6log((LOG_INFO, 1358 "nd6_dad_ns_input: ignoring DAD NS packet for " 1359 "address %s(%s)\n", ip6_sprintf(taddr6), 1360 if_name(ifa->ifa_ifp))); 1361 return; 1362 } 1363 1364 /* 1365 * if I'm yet to start DAD, someone else started using this address 1366 * first. I have a duplicate and you win. 1367 */ 1368 if (!dp || dp->dad_ns_ocount == 0) 1369 duplicate++; 1370 1371 /* XXX more checks for loopback situation - see nd6_dad_timer too */ 1372 1373 if (duplicate) { 1374 dp = NULL; /* will be freed in nd6_dad_duplicated() */ 1375 nd6_dad_duplicated(ifa); 1376 } else { 1377 /* 1378 * not sure if I got a duplicate. 1379 * increment ns count and see what happens. 1380 */ 1381 if (dp) 1382 dp->dad_ns_icount++; 1383 } 1384 } 1385 1386 static void 1387 nd6_dad_na_input(struct ifaddr *ifa) 1388 { 1389 struct dadq *dp; 1390 1391 if (!ifa) 1392 panic("ifa == NULL in nd6_dad_na_input"); 1393 1394 dp = nd6_dad_find(ifa); 1395 if (dp) 1396 dp->dad_na_icount++; 1397 1398 /* remove the address. */ 1399 nd6_dad_duplicated(ifa); 1400 } 1401