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