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