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