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