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