in6.c revision 1.16 1 /* $NetBSD: in6.c,v 1.16 2000/02/06 12:49:43 itojun Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1982, 1986, 1991, 1993
34 * The Regents of the University of California. All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the University of
47 * California, Berkeley and its contributors.
48 * 4. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 *
64 * @(#)in.c 8.2 (Berkeley) 11/15/93
65 */
66
67 #include "opt_inet.h"
68
69 #include <sys/param.h>
70 #include <sys/ioctl.h>
71 #include <sys/errno.h>
72 #include <sys/malloc.h>
73 #include <sys/socket.h>
74 #include <sys/socketvar.h>
75 #include <sys/sockio.h>
76 #include <sys/systm.h>
77 #include <sys/proc.h>
78 #include <sys/time.h>
79 #include <sys/kernel.h>
80 #include <sys/syslog.h>
81
82 #include <net/if.h>
83 #include <net/if_types.h>
84 #include <net/route.h>
85 #include "gif.h"
86 #if NGIF > 0
87 #include <net/if_gif.h>
88 #endif
89 #include <net/if_dl.h>
90
91 #include <netinet/in.h>
92 #include <netinet/in_var.h>
93 #include <net/if_ether.h>
94
95 #include <netinet6/nd6.h>
96 #include <netinet/ip6.h>
97 #include <netinet6/ip6_var.h>
98 #include <netinet6/mld6_var.h>
99 #include <netinet6/ip6_mroute.h>
100 #include <netinet6/in6_ifattach.h>
101
102 #include <net/net_osdep.h>
103
104 /*
105 * Definitions of some costant IP6 addresses.
106 */
107 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
108 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
109 const struct in6_addr in6addr_nodelocal_allnodes =
110 IN6ADDR_NODELOCAL_ALLNODES_INIT;
111 const struct in6_addr in6addr_linklocal_allnodes =
112 IN6ADDR_LINKLOCAL_ALLNODES_INIT;
113 const struct in6_addr in6addr_linklocal_allrouters =
114 IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
115
116 const struct in6_addr in6mask0 = IN6MASK0;
117 const struct in6_addr in6mask32 = IN6MASK32;
118 const struct in6_addr in6mask64 = IN6MASK64;
119 const struct in6_addr in6mask96 = IN6MASK96;
120 const struct in6_addr in6mask128 = IN6MASK128;
121
122 static int in6_lifaddr_ioctl __P((struct socket *, u_long, caddr_t,
123 struct ifnet *, struct proc *));
124
125 /*
126 * This structure is used to keep track of in6_multi chains which belong to
127 * deleted interface addresses.
128 */
129 static LIST_HEAD(, multi6_kludge) in6_mk; /* XXX BSS initialization */
130
131 struct multi6_kludge {
132 LIST_ENTRY(multi6_kludge) mk_entry;
133 struct ifnet *mk_ifp;
134 struct in6_multihead mk_head;
135 };
136
137 /*
138 * Determine whether an IP6 address is in a reserved set of addresses
139 * that may not be forwarded, or whether datagrams to that destination
140 * may be forwarded.
141 */
142 int
143 in6_canforward(src, dst)
144 struct in6_addr *src, *dst;
145 {
146 if (IN6_IS_ADDR_LINKLOCAL(src) ||
147 IN6_IS_ADDR_LINKLOCAL(dst) ||
148 IN6_IS_ADDR_MULTICAST(dst))
149 return(0);
150 return(1);
151 }
152
153 /*
154 * Check if the loopback entry will be automatically generated.
155 * if 0 returned, will not be automatically generated.
156 * if 1 returned, will be automatically generated.
157 */
158 static int
159 in6_is_ifloop_auto(struct ifaddr *ifa)
160 {
161 #define SIN6(s) ((struct sockaddr_in6 *)s)
162 /*
163 * If RTF_CLONING is unset, or (IFF_LOOPBACK | IFF_POINTOPOINT),
164 * or netmask is all0 or all1, then cloning will not happen,
165 * then we can't rely on its loopback entry generation.
166 */
167 if ((ifa->ifa_flags & RTF_CLONING) == 0 ||
168 (ifa->ifa_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) ||
169 (SIN6(ifa->ifa_netmask)->sin6_len == sizeof(struct sockaddr_in6)
170 &&
171 IN6_ARE_ADDR_EQUAL(&SIN6(ifa->ifa_netmask)->sin6_addr,
172 &in6mask128)) ||
173 ((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_len == 0)
174 return 0;
175 else
176 return 1;
177 #undef SIN6
178 }
179
180 /*
181 * Subroutine for in6_ifaddloop() and in6_ifremloop().
182 * This routine does actual work.
183 */
184 static void
185 in6_ifloop_request(int cmd, struct ifaddr *ifa)
186 {
187 struct sockaddr_in6 lo_sa;
188 struct sockaddr_in6 all1_sa;
189 struct rtentry *nrt = NULL;
190
191 bzero(&lo_sa, sizeof(lo_sa));
192 bzero(&all1_sa, sizeof(all1_sa));
193 lo_sa.sin6_family = AF_INET6;
194 lo_sa.sin6_len = sizeof(struct sockaddr_in6);
195 all1_sa = lo_sa;
196 lo_sa.sin6_addr = in6addr_loopback;
197 all1_sa.sin6_addr = in6mask128;
198
199 /* So we add or remove static loopback entry, here. */
200 rtrequest(cmd, ifa->ifa_addr,
201 (struct sockaddr *)&lo_sa,
202 (struct sockaddr *)&all1_sa,
203 RTF_UP|RTF_HOST, &nrt);
204
205 /*
206 * Make sure rt_ifa be equal to IFA, the second argument of the
207 * function.
208 * We need this because when we refer rt_ifa->ia6_flags in ip6_input,
209 * we assume that the rt_ifa points to the address instead of the
210 * loopback address.
211 */
212 if (cmd == RTM_ADD && nrt && ifa != nrt->rt_ifa) {
213 IFAFREE(nrt->rt_ifa);
214 IFAREF(ifa);
215 nrt->rt_ifa = ifa;
216 }
217 if (nrt)
218 nrt->rt_refcnt--;
219 }
220
221 /*
222 * Add ownaddr as loopback rtentry, if necessary(ex. on p2p link).
223 * Because, KAME needs loopback rtentry for ownaddr check in
224 * ip6_input().
225 */
226 static void
227 in6_ifaddloop(struct ifaddr *ifa)
228 {
229 if (!in6_is_ifloop_auto(ifa)) {
230 struct rtentry *rt;
231
232 /* If there is no loopback entry, allocate one. */
233 rt = rtalloc1(ifa->ifa_addr, 0);
234 if (rt == 0 || (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0)
235 in6_ifloop_request(RTM_ADD, ifa);
236 if (rt)
237 rt->rt_refcnt--;
238 }
239 }
240
241 /*
242 * Remove loopback rtentry of ownaddr generated by in6_ifaddloop(),
243 * if it exists.
244 */
245 static void
246 in6_ifremloop(struct ifaddr *ifa)
247 {
248 if (!in6_is_ifloop_auto(ifa)) {
249 struct in6_ifaddr *ia;
250 int ia_count = 0;
251
252 /* If only one ifa for the loopback entry, delete it. */
253 for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
254 if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa),
255 &ia->ia_addr.sin6_addr)) {
256 ia_count++;
257 if (ia_count > 1)
258 break;
259 }
260 }
261 if (ia_count == 1)
262 in6_ifloop_request(RTM_DELETE, ifa);
263 }
264 }
265
266 /*
267 * Subroutine for in6_ifaddproxy() and in6_ifremproxy().
268 * This routine does actual work.
269 * call in6_addmulti() when cmd == 1.
270 * call in6_delmulti() when cmd == 2.
271 */
272 static int
273 in6_ifproxy_request(int cmd, struct in6_ifaddr *ia)
274 {
275 int error = 0;
276
277 /*
278 * If we have an IPv6 dstaddr on adding p2p interface,
279 * join dstaddr's solicited multicast on necessary interface.
280 */
281 if ((ia->ia_ifp->if_flags & IFF_POINTOPOINT) &&
282 ia->ia_dstaddr.sin6_family == AF_INET6 &&
283 !IN6_IS_ADDR_LINKLOCAL(&ia->ia_dstaddr.sin6_addr)) {
284 struct in6_ifaddr *ia_lan;
285
286 /*
287 * TODO: Join only on some specified interfaces by some
288 * configuration.
289 * Unsolicited Neighbor Advertisements will be also necessary.
290 *
291 * Now, join on interfaces which meets following.
292 * -IFF_BROADCAST and IFF_MULTICAST
293 * (NBMA is out of scope)
294 * -the prefix value is same as p2p dstaddr
295 */
296 for (ia_lan = in6_ifaddr; ia_lan; ia_lan = ia_lan->ia_next) {
297 struct in6_addr llsol;
298
299 if ((ia_lan->ia_ifp->if_flags &
300 (IFF_BROADCAST|IFF_MULTICAST)) !=
301 (IFF_BROADCAST|IFF_MULTICAST))
302 continue;
303 if (!IN6_ARE_MASKED_ADDR_EQUAL(IA6_IN6(ia),
304 IA6_IN6(ia_lan),
305 IA6_MASKIN6(ia_lan)))
306 continue;
307 if (ia_lan->ia_ifp == ia->ia_ifp)
308 continue;
309
310 /* init llsol */
311 bzero(&llsol, sizeof(struct in6_addr));
312 llsol.s6_addr16[0] = htons(0xff02);
313 llsol.s6_addr16[1] = htons(ia_lan->ia_ifp->if_index);
314 llsol.s6_addr32[1] = 0;
315 llsol.s6_addr32[2] = htonl(1);
316 llsol.s6_addr32[3] =
317 ia->ia_dstaddr.sin6_addr.s6_addr32[3];
318 llsol.s6_addr8[12] = 0xff;
319
320 if (cmd == 1)
321 (void)in6_addmulti(&llsol,
322 ia_lan->ia_ifp,
323 &error);
324 else if (cmd == 2) {
325 struct in6_multi *in6m;
326
327 IN6_LOOKUP_MULTI(llsol,
328 ia_lan->ia_ifp,
329 in6m);
330 if (in6m)
331 in6_delmulti(in6m);
332 }
333 }
334 }
335 return error;
336 }
337
338 static int
339 in6_ifaddproxy(struct in6_ifaddr *ia)
340 {
341 return(in6_ifproxy_request(1, ia));
342 }
343
344 static void
345 in6_ifremproxy(struct in6_ifaddr *ia)
346 {
347 in6_ifproxy_request(2, ia);
348 }
349
350 int
351 in6_ifindex2scopeid(idx)
352 int idx;
353 {
354 struct ifnet *ifp;
355 struct ifaddr *ifa;
356 struct sockaddr_in6 *sin6;
357
358 if (idx < 0 || if_index < idx)
359 return -1;
360 ifp = ifindex2ifnet[idx];
361
362 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
363 {
364 if (ifa->ifa_addr->sa_family != AF_INET6)
365 continue;
366 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
367 if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
368 return sin6->sin6_scope_id & 0xffff;
369 }
370
371 return -1;
372 }
373
374 int
375 in6_mask2len(mask)
376 struct in6_addr *mask;
377 {
378 int x, y;
379
380 for (x = 0; x < sizeof(*mask); x++) {
381 if (mask->s6_addr8[x] != 0xff)
382 break;
383 }
384 y = 0;
385 if (x < sizeof(*mask)) {
386 for (y = 0; y < 8; y++) {
387 if ((mask->s6_addr8[x] & (0x80 >> y)) == 0)
388 break;
389 }
390 }
391 return x * 8 + y;
392 }
393
394 void
395 in6_len2mask(mask, len)
396 struct in6_addr *mask;
397 int len;
398 {
399 int i;
400
401 bzero(mask, sizeof(*mask));
402 for (i = 0; i < len / 8; i++)
403 mask->s6_addr8[i] = 0xff;
404 if (len % 8)
405 mask->s6_addr8[i] = (0xff00 >> (len % 8)) & 0xff;
406 }
407
408 int in6_interfaces; /* number of external internet interfaces */
409
410 #define ifa2ia6(ifa) ((struct in6_ifaddr *)(ifa))
411 #define ia62ifa(ia6) (&(((ia6)->ia_ifa))
412
413 int
414 in6_control(so, cmd, data, ifp, p)
415 struct socket *so;
416 u_long cmd;
417 caddr_t data;
418 struct ifnet *ifp;
419 struct proc *p;
420 {
421 struct in6_ifreq *ifr = (struct in6_ifreq *)data;
422 struct in6_ifaddr *ia, *oia;
423 struct in6_aliasreq *ifra = (struct in6_aliasreq *)data;
424 struct sockaddr_in6 oldaddr, net;
425 int error = 0, hostIsNew, prefixIsNew;
426 time_t time_second = (time_t)time.tv_sec;
427 int privileged;
428
429 privileged = 0;
430 if (p && !suser(p->p_ucred, &p->p_acflag))
431 privileged++;
432
433 /*
434 * xxx should prevent processes for link-local addresses?
435 */
436 #if NGIF > 0
437 if (ifp && ifp->if_type == IFT_GIF) {
438 switch (cmd) {
439 case SIOCSIFPHYADDR_IN6:
440 if (!privileged)
441 return(EPERM);
442 /*fall through*/
443 case SIOCGIFPSRCADDR_IN6:
444 case SIOCGIFPDSTADDR_IN6:
445 return gif_ioctl(ifp, cmd, data);
446 }
447 }
448 #endif
449 switch (cmd) {
450 case SIOCGETSGCNT_IN6:
451 case SIOCGETMIFCNT_IN6:
452 return (mrt6_ioctl(cmd, data));
453 }
454
455 if (ifp == 0)
456 return(EOPNOTSUPP);
457
458 switch (cmd) {
459 case SIOCSNDFLUSH_IN6:
460 case SIOCSPFXFLUSH_IN6:
461 case SIOCSRTRFLUSH_IN6:
462 case SIOCSDEFIFACE_IN6:
463 if (!privileged)
464 return(EPERM);
465 /*fall through*/
466 case SIOCGIFINFO_IN6:
467 case SIOCGDRLST_IN6:
468 case SIOCGPRLST_IN6:
469 case SIOCGNBRINFO_IN6:
470 case SIOCGDEFIFACE_IN6:
471 return(nd6_ioctl(cmd, data, ifp));
472 }
473
474 switch (cmd) {
475 case SIOCSIFPREFIX_IN6:
476 case SIOCDIFPREFIX_IN6:
477 case SIOCAIFPREFIX_IN6:
478 case SIOCCIFPREFIX_IN6:
479 case SIOCSGIFPREFIX_IN6:
480 if (!privileged)
481 return(EPERM);
482 /*fall through*/
483 case SIOCGIFPREFIX_IN6:
484 return(in6_prefix_ioctl(so, cmd, data, ifp));
485 }
486
487 switch (cmd) {
488 case SIOCALIFADDR:
489 case SIOCDLIFADDR:
490 if (!privileged)
491 return(EPERM);
492 /*fall through*/
493 case SIOCGLIFADDR:
494 return in6_lifaddr_ioctl(so, cmd, data, ifp, p);
495 }
496
497 /*
498 * Find address for this interface, if it exists.
499 */
500 {
501
502 struct sockaddr_in6 *sa6 =
503 (struct sockaddr_in6 *)&ifra->ifra_addr;
504
505 if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
506 if (sa6->sin6_addr.s6_addr16[1] == 0) {
507 /* interface ID is not embedded by the user */
508 sa6->sin6_addr.s6_addr16[1] =
509 htons(ifp->if_index);
510 }
511 else
512 if (sa6->sin6_addr.s6_addr16[1] !=
513 htons(ifp->if_index))
514 return(EINVAL); /* ifid is contradict */
515 if (sa6->sin6_scope_id) {
516 if (sa6->sin6_scope_id !=
517 (u_int32_t)ifp->if_index)
518 return(EINVAL);
519 sa6->sin6_scope_id = 0; /* XXX: good way? */
520 }
521 }
522 }
523 ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr);
524
525 switch (cmd) {
526
527 case SIOCDIFADDR_IN6:
528 if (ia == 0)
529 return(EADDRNOTAVAIL);
530 /* FALLTHROUGH */
531 case SIOCAIFADDR_IN6:
532 case SIOCSIFADDR_IN6:
533 case SIOCSIFNETMASK_IN6:
534 case SIOCSIFDSTADDR_IN6:
535 if (!privileged)
536 return(EPERM);
537 if (ia == 0) {
538 ia = (struct in6_ifaddr *)
539 malloc(sizeof(*ia), M_IFADDR, M_WAITOK);
540 if (ia == NULL)
541 return (ENOBUFS);
542 bzero((caddr_t)ia, sizeof(*ia));
543 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
544 ia->ia_ifa.ifa_dstaddr
545 = (struct sockaddr *)&ia->ia_dstaddr;
546 ia->ia_ifa.ifa_netmask
547 = (struct sockaddr *)&ia->ia_prefixmask;
548
549 ia->ia_ifp = ifp;
550 if ((oia = in6_ifaddr) != NULL) {
551 for ( ; oia->ia_next; oia = oia->ia_next)
552 continue;
553 oia->ia_next = ia;
554 } else
555 in6_ifaddr = ia;
556 IFAREF(&ia->ia_ifa);
557
558 TAILQ_INSERT_TAIL(&ifp->if_addrlist, &ia->ia_ifa,
559 ifa_list);
560 IFAREF(&ia->ia_ifa);
561
562 if ((ifp->if_flags & IFF_LOOPBACK) == 0)
563 in6_interfaces++; /*XXX*/
564 }
565
566 if (cmd == SIOCAIFADDR_IN6) {
567 /* sanity for overflow - beware unsigned */
568 struct in6_addrlifetime *lt;
569 lt = &ifra->ifra_lifetime;
570 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
571 && lt->ia6t_vltime + time_second < time_second) {
572 return EINVAL;
573 }
574 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
575 && lt->ia6t_pltime + time_second < time_second) {
576 return EINVAL;
577 }
578 }
579 break;
580
581 case SIOCGIFADDR_IN6:
582 /* This interface is basically deprecated. use SIOCGIFCONF. */
583 /* fall through */
584 case SIOCGIFAFLAG_IN6:
585 case SIOCGIFNETMASK_IN6:
586 case SIOCGIFDSTADDR_IN6:
587 case SIOCGIFALIFETIME_IN6:
588 /* must think again about its semantics */
589 if (ia == 0)
590 return(EADDRNOTAVAIL);
591 break;
592 case SIOCSIFALIFETIME_IN6:
593 {
594 struct in6_addrlifetime *lt;
595
596 if (!privileged)
597 return(EPERM);
598 if (ia == 0)
599 return(EADDRNOTAVAIL);
600 /* sanity for overflow - beware unsigned */
601 lt = &ifr->ifr_ifru.ifru_lifetime;
602 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
603 && lt->ia6t_vltime + time_second < time_second) {
604 return EINVAL;
605 }
606 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
607 && lt->ia6t_pltime + time_second < time_second) {
608 return EINVAL;
609 }
610 break;
611 }
612 }
613
614 switch (cmd) {
615
616 case SIOCGIFADDR_IN6:
617 ifr->ifr_addr = ia->ia_addr;
618 break;
619
620 case SIOCGIFDSTADDR_IN6:
621 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
622 return(EINVAL);
623 ifr->ifr_dstaddr = ia->ia_dstaddr;
624 break;
625
626 case SIOCGIFNETMASK_IN6:
627 ifr->ifr_addr = ia->ia_prefixmask;
628 break;
629
630 case SIOCGIFAFLAG_IN6:
631 ifr->ifr_ifru.ifru_flags6 = ia->ia6_flags;
632 break;
633
634 case SIOCGIFSTAT_IN6:
635 if (ifp == NULL)
636 return EINVAL;
637 if (in6_ifstat == NULL || ifp->if_index >= in6_ifstatmax
638 || in6_ifstat[ifp->if_index] == NULL) {
639 /* return EAFNOSUPPORT? */
640 bzero(&ifr->ifr_ifru.ifru_stat,
641 sizeof(ifr->ifr_ifru.ifru_stat));
642 } else
643 ifr->ifr_ifru.ifru_stat = *in6_ifstat[ifp->if_index];
644 break;
645
646 case SIOCGIFSTAT_ICMP6:
647 if (ifp == NULL)
648 return EINVAL;
649 if (icmp6_ifstat == NULL || ifp->if_index >= icmp6_ifstatmax ||
650 icmp6_ifstat[ifp->if_index] == NULL) {
651 /* return EAFNOSUPPORT? */
652 bzero(&ifr->ifr_ifru.ifru_stat,
653 sizeof(ifr->ifr_ifru.ifru_icmp6stat));
654 } else
655 ifr->ifr_ifru.ifru_icmp6stat =
656 *icmp6_ifstat[ifp->if_index];
657 break;
658
659 case SIOCSIFDSTADDR_IN6:
660 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
661 return(EINVAL);
662 oldaddr = ia->ia_dstaddr;
663 ia->ia_dstaddr = ifr->ifr_dstaddr;
664
665 /* link-local index check */
666 if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_dstaddr.sin6_addr)) {
667 if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] == 0) {
668 /* interface ID is not embedded by the user */
669 ia->ia_dstaddr.sin6_addr.s6_addr16[1]
670 = htons(ifp->if_index);
671 }
672 else
673 if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] !=
674 htons(ifp->if_index)) {
675 ia->ia_dstaddr = oldaddr;
676 return(EINVAL); /* ifid is contradict */
677 }
678 }
679
680 if (ifp->if_ioctl && (error = (ifp->if_ioctl)
681 (ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
682 ia->ia_dstaddr = oldaddr;
683 return(error);
684 }
685 if (ia->ia_flags & IFA_ROUTE) {
686 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
687 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
688 ia->ia_ifa.ifa_dstaddr =
689 (struct sockaddr *)&ia->ia_dstaddr;
690 rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
691 }
692 break;
693
694 case SIOCGIFALIFETIME_IN6:
695 ifr->ifr_ifru.ifru_lifetime = ia->ia6_lifetime;
696 break;
697
698 case SIOCSIFALIFETIME_IN6:
699 ia->ia6_lifetime = ifr->ifr_ifru.ifru_lifetime;
700 /* for sanity */
701 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
702 ia->ia6_lifetime.ia6t_expire =
703 time_second + ia->ia6_lifetime.ia6t_vltime;
704 } else
705 ia->ia6_lifetime.ia6t_expire = 0;
706 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
707 ia->ia6_lifetime.ia6t_preferred =
708 time_second + ia->ia6_lifetime.ia6t_pltime;
709 } else
710 ia->ia6_lifetime.ia6t_preferred = 0;
711 break;
712
713 case SIOCSIFADDR_IN6:
714 return(in6_ifinit(ifp, ia, &ifr->ifr_addr, 1));
715
716 case SIOCSIFNETMASK_IN6:
717 ia->ia_prefixmask = ifr->ifr_addr;
718 bzero(&net, sizeof(net));
719 net.sin6_len = sizeof(struct sockaddr_in6);
720 net.sin6_family = AF_INET6;
721 net.sin6_port = htons(0);
722 net.sin6_flowinfo = htonl(0);
723 net.sin6_addr.s6_addr32[0]
724 = ia->ia_addr.sin6_addr.s6_addr32[0] &
725 ia->ia_prefixmask.sin6_addr.s6_addr32[0];
726 net.sin6_addr.s6_addr32[1]
727 = ia->ia_addr.sin6_addr.s6_addr32[1] &
728 ia->ia_prefixmask.sin6_addr.s6_addr32[1];
729 net.sin6_addr.s6_addr32[2]
730 = ia->ia_addr.sin6_addr.s6_addr32[2] &
731 ia->ia_prefixmask.sin6_addr.s6_addr32[2];
732 net.sin6_addr.s6_addr32[3]
733 = ia->ia_addr.sin6_addr.s6_addr32[3] &
734 ia->ia_prefixmask.sin6_addr.s6_addr32[3];
735 ia->ia_net = net;
736 break;
737
738 case SIOCAIFADDR_IN6:
739 prefixIsNew = 0;
740 hostIsNew = 1;
741
742 if (ifra->ifra_addr.sin6_len == 0) {
743 ifra->ifra_addr = ia->ia_addr;
744 hostIsNew = 0;
745 } else if (IN6_ARE_ADDR_EQUAL(&ifra->ifra_addr.sin6_addr,
746 &ia->ia_addr.sin6_addr))
747 hostIsNew = 0;
748
749 if (ifra->ifra_prefixmask.sin6_len) {
750 in6_ifscrub(ifp, ia);
751 ia->ia_prefixmask = ifra->ifra_prefixmask;
752 prefixIsNew = 1;
753 }
754 if ((ifp->if_flags & IFF_POINTOPOINT) &&
755 (ifra->ifra_dstaddr.sin6_family == AF_INET6)) {
756 in6_ifscrub(ifp, ia);
757 ia->ia_dstaddr = ifra->ifra_dstaddr;
758 /* link-local index check: should be a separate function? */
759 if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_dstaddr.sin6_addr)) {
760 if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] == 0) {
761 /*
762 * interface ID is not embedded by
763 * the user
764 */
765 ia->ia_dstaddr.sin6_addr.s6_addr16[1]
766 = htons(ifp->if_index);
767 }
768 else
769 if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] !=
770 htons(ifp->if_index)) {
771 ia->ia_dstaddr = oldaddr;
772 return(EINVAL); /* ifid is contradict */
773 }
774 }
775 prefixIsNew = 1; /* We lie; but effect's the same */
776 }
777 if (ifra->ifra_addr.sin6_family == AF_INET6 &&
778 (hostIsNew || prefixIsNew))
779 error = in6_ifinit(ifp, ia, &ifra->ifra_addr, 0);
780 if (ifra->ifra_addr.sin6_family == AF_INET6
781 && hostIsNew && (ifp->if_flags & IFF_MULTICAST)) {
782 int error_local = 0;
783
784 /*
785 * join solicited multicast addr for new host id
786 */
787 struct in6_addr llsol;
788 bzero(&llsol, sizeof(struct in6_addr));
789 llsol.s6_addr16[0] = htons(0xff02);
790 llsol.s6_addr16[1] = htons(ifp->if_index);
791 llsol.s6_addr32[1] = 0;
792 llsol.s6_addr32[2] = htonl(1);
793 llsol.s6_addr32[3] =
794 ifra->ifra_addr.sin6_addr.s6_addr32[3];
795 llsol.s6_addr8[12] = 0xff;
796 (void)in6_addmulti(&llsol, ifp, &error_local);
797 if (error == 0)
798 error = error_local;
799 }
800 /* Join dstaddr's solicited multicast if necessary. */
801 if (nd6_proxyall && hostIsNew) {
802 int error_local;
803
804 error_local = in6_ifaddproxy(ia);
805 if (error == 0)
806 error = error_local;
807 }
808
809 ia->ia6_flags = ifra->ifra_flags;
810 ia->ia6_flags &= ~IN6_IFF_DUPLICATED; /*safety*/
811
812 ia->ia6_lifetime = ifra->ifra_lifetime;
813 /* for sanity */
814 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
815 ia->ia6_lifetime.ia6t_expire =
816 time_second + ia->ia6_lifetime.ia6t_vltime;
817 } else
818 ia->ia6_lifetime.ia6t_expire = 0;
819 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
820 ia->ia6_lifetime.ia6t_preferred =
821 time_second + ia->ia6_lifetime.ia6t_pltime;
822 } else
823 ia->ia6_lifetime.ia6t_preferred = 0;
824
825 /*
826 * Perform DAD, if needed.
827 * XXX It may be of use, if we can administratively
828 * disable DAD.
829 */
830 switch (ifp->if_type) {
831 case IFT_ARCNET:
832 case IFT_ETHER:
833 case IFT_FDDI:
834 #if 0
835 case IFT_ATM:
836 case IFT_SLIP:
837 case IFT_PPP:
838 #endif
839 ia->ia6_flags |= IN6_IFF_TENTATIVE;
840 nd6_dad_start(&ia->ia_ifa, NULL);
841 break;
842 case IFT_FAITH:
843 case IFT_GIF:
844 case IFT_LOOP:
845 default:
846 break;
847 }
848
849 if (hostIsNew) {
850 int iilen;
851 int error_local = 0;
852
853 iilen = (sizeof(ia->ia_prefixmask.sin6_addr) << 3) -
854 in6_mask2len(&ia->ia_prefixmask.sin6_addr);
855 error_local = in6_prefix_add_ifid(iilen, ia);
856 if (error == 0)
857 error = error_local;
858 }
859
860 return(error);
861
862 case SIOCDIFADDR_IN6:
863 in6_purgeaddr(&ia->ia_ifa, ifp);
864 break;
865
866 default:
867 if (ifp == 0 || ifp->if_ioctl == 0)
868 return(EOPNOTSUPP);
869 return((*ifp->if_ioctl)(ifp, cmd, data));
870 }
871 return(0);
872 }
873
874 void
875 in6_purgeaddr(ifa, ifp)
876 struct ifaddr *ifa;
877 struct ifnet *ifp;
878 {
879 struct in6_ifaddr *oia, *ia = (void *) ifa;
880
881 in6_ifscrub(ifp, ia);
882
883 if (ifp->if_flags & IFF_MULTICAST) {
884 /*
885 * delete solicited multicast addr for deleting host id
886 */
887 struct in6_multi *in6m;
888 struct in6_addr llsol;
889 bzero(&llsol, sizeof(struct in6_addr));
890 llsol.s6_addr16[0] = htons(0xff02);
891 llsol.s6_addr16[1] = htons(ifp->if_index);
892 llsol.s6_addr32[1] = 0;
893 llsol.s6_addr32[2] = htonl(1);
894 llsol.s6_addr32[3] =
895 ia->ia_addr.sin6_addr.s6_addr32[3];
896 llsol.s6_addr8[12] = 0xff;
897
898 IN6_LOOKUP_MULTI(llsol, ifp, in6m);
899 if (in6m)
900 in6_delmulti(in6m);
901 }
902 /* Leave dstaddr's solicited multicast if necessary. */
903 if (nd6_proxyall)
904 in6_ifremproxy(ia);
905
906 TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
907 IFAFREE(&ia->ia_ifa);
908
909 oia = ia;
910 if (oia == (ia = in6_ifaddr))
911 in6_ifaddr = ia->ia_next;
912 else {
913 while (ia->ia_next && (ia->ia_next != oia))
914 ia = ia->ia_next;
915 if (ia->ia_next)
916 ia->ia_next = oia->ia_next;
917 else
918 printf("Didn't unlink in6_ifaddr from list\n");
919 }
920 {
921 int iilen;
922
923 iilen = (sizeof(oia->ia_prefixmask.sin6_addr) << 3) -
924 in6_mask2len(&oia->ia_prefixmask.sin6_addr);
925 in6_prefix_remove_ifid(iilen, oia);
926 }
927 if (oia->ia6_multiaddrs.lh_first != NULL) {
928 /*
929 * XXX thorpej (at) netbsd.org -- if the interface is going
930 * XXX away, don't save the multicast entries, delete them!
931 */
932 if (oia->ia_ifa.ifa_ifp->if_output == if_nulloutput) {
933 struct in6_multi *in6m;
934
935 while ((in6m =
936 LIST_FIRST(&oia->ia6_multiaddrs)) != NULL)
937 in6_delmulti(in6m);
938 } else
939 in6_savemkludge(oia);
940 }
941
942 IFAFREE(&oia->ia_ifa);
943 }
944
945 void
946 in6_purgeif(ifp)
947 struct ifnet *ifp;
948 {
949 struct ifaddr *ifa, *nifa;
950
951 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; ifa = nifa) {
952 nifa = TAILQ_NEXT(ifa, ifa_list);
953 if (ifa->ifa_addr->sa_family != AF_INET6)
954 continue;
955 in6_purgeaddr(ifa, ifp);
956 }
957
958 in6_ifdetach(ifp);
959 }
960
961 /*
962 * SIOC[GAD]LIFADDR.
963 * SIOCGLIFADDR: get first address. (???)
964 * SIOCGLIFADDR with IFLR_PREFIX:
965 * get first address that matches the specified prefix.
966 * SIOCALIFADDR: add the specified address.
967 * SIOCALIFADDR with IFLR_PREFIX:
968 * add the specified prefix, filling hostid part from
969 * the first link-local address. prefixlen must be <= 64.
970 * SIOCDLIFADDR: delete the specified address.
971 * SIOCDLIFADDR with IFLR_PREFIX:
972 * delete the first address that matches the specified prefix.
973 * return values:
974 * EINVAL on invalid parameters
975 * EADDRNOTAVAIL on prefix match failed/specified address not found
976 * other values may be returned from in6_ioctl()
977 *
978 * NOTE: SIOCALIFADDR(with IFLR_PREFIX set) allows prefixlen less than 64.
979 * this is to accomodate address naming scheme other than RFC2374,
980 * in the future.
981 * RFC2373 defines interface id to be 64bit, but it allows non-RFC2374
982 * address encoding scheme. (see figure on page 8)
983 */
984 static int
985 in6_lifaddr_ioctl(so, cmd, data, ifp, p)
986 struct socket *so;
987 u_long cmd;
988 caddr_t data;
989 struct ifnet *ifp;
990 struct proc *p;
991 {
992 struct if_laddrreq *iflr = (struct if_laddrreq *)data;
993 struct ifaddr *ifa;
994 struct sockaddr *sa;
995
996 /* sanity checks */
997 if (!data || !ifp) {
998 panic("invalid argument to in6_lifaddr_ioctl");
999 /*NOTRECHED*/
1000 }
1001
1002 switch (cmd) {
1003 case SIOCGLIFADDR:
1004 /* address must be specified on GET with IFLR_PREFIX */
1005 if ((iflr->flags & IFLR_PREFIX) == 0)
1006 break;
1007 /*FALLTHROUGH*/
1008 case SIOCALIFADDR:
1009 case SIOCDLIFADDR:
1010 /* address must be specified on ADD and DELETE */
1011 sa = (struct sockaddr *)&iflr->addr;
1012 if (sa->sa_family != AF_INET6)
1013 return EINVAL;
1014 if (sa->sa_len != sizeof(struct sockaddr_in6))
1015 return EINVAL;
1016 /* XXX need improvement */
1017 sa = (struct sockaddr *)&iflr->dstaddr;
1018 if (sa->sa_family && sa->sa_family != AF_INET6)
1019 return EINVAL;
1020 if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in6))
1021 return EINVAL;
1022 break;
1023 default: /*shouldn't happen*/
1024 #if 0
1025 panic("invalid cmd to in6_lifaddr_ioctl");
1026 /*NOTREACHED*/
1027 #else
1028 return EOPNOTSUPP;
1029 #endif
1030 }
1031 if (sizeof(struct in6_addr) * 8 < iflr->prefixlen)
1032 return EINVAL;
1033
1034 switch (cmd) {
1035 case SIOCALIFADDR:
1036 {
1037 struct in6_aliasreq ifra;
1038 struct in6_addr *hostid = NULL;
1039 int prefixlen;
1040
1041 if ((iflr->flags & IFLR_PREFIX) != 0) {
1042 struct sockaddr_in6 *sin6;
1043
1044 /*
1045 * hostid is to fill in the hostid part of the
1046 * address. hostid points to the first link-local
1047 * address attached to the interface.
1048 */
1049 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp);
1050 if (!ifa)
1051 return EADDRNOTAVAIL;
1052 hostid = IFA_IN6(ifa);
1053
1054 /* prefixlen must be <= 64. */
1055 if (64 < iflr->prefixlen)
1056 return EINVAL;
1057 prefixlen = iflr->prefixlen;
1058
1059 /* hostid part must be zero. */
1060 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1061 if (sin6->sin6_addr.s6_addr32[2] != 0
1062 || sin6->sin6_addr.s6_addr32[3] != 0) {
1063 return EINVAL;
1064 }
1065 } else
1066 prefixlen = iflr->prefixlen;
1067
1068 /* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
1069 bzero(&ifra, sizeof(ifra));
1070 bcopy(iflr->iflr_name, ifra.ifra_name,
1071 sizeof(ifra.ifra_name));
1072
1073 bcopy(&iflr->addr, &ifra.ifra_addr,
1074 ((struct sockaddr *)&iflr->addr)->sa_len);
1075 if (hostid) {
1076 /* fill in hostid part */
1077 ifra.ifra_addr.sin6_addr.s6_addr32[2] =
1078 hostid->s6_addr32[2];
1079 ifra.ifra_addr.sin6_addr.s6_addr32[3] =
1080 hostid->s6_addr32[3];
1081 }
1082
1083 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /*XXX*/
1084 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
1085 ((struct sockaddr *)&iflr->dstaddr)->sa_len);
1086 if (hostid) {
1087 ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] =
1088 hostid->s6_addr32[2];
1089 ifra.ifra_dstaddr.sin6_addr.s6_addr32[3] =
1090 hostid->s6_addr32[3];
1091 }
1092 }
1093
1094 ifra.ifra_prefixmask.sin6_family = AF_INET6;
1095 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
1096 in6_len2mask(&ifra.ifra_prefixmask.sin6_addr, prefixlen);
1097
1098 ifra.ifra_flags = iflr->flags & ~IFLR_PREFIX;
1099 return in6_control(so, SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, p);
1100 }
1101 case SIOCGLIFADDR:
1102 case SIOCDLIFADDR:
1103 {
1104 struct in6_ifaddr *ia;
1105 struct in6_addr mask, candidate, match;
1106 struct sockaddr_in6 *sin6;
1107 int cmp;
1108
1109 bzero(&mask, sizeof(mask));
1110 if (iflr->flags & IFLR_PREFIX) {
1111 /* lookup a prefix rather than address. */
1112 in6_len2mask(&mask, iflr->prefixlen);
1113
1114 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1115 bcopy(&sin6->sin6_addr, &match, sizeof(match));
1116 match.s6_addr32[0] &= mask.s6_addr32[0];
1117 match.s6_addr32[1] &= mask.s6_addr32[1];
1118 match.s6_addr32[2] &= mask.s6_addr32[2];
1119 match.s6_addr32[3] &= mask.s6_addr32[3];
1120
1121 /* if you set extra bits, that's wrong */
1122 if (bcmp(&match, &sin6->sin6_addr, sizeof(match)))
1123 return EINVAL;
1124
1125 cmp = 1;
1126 } else {
1127 if (cmd == SIOCGLIFADDR) {
1128 /* on getting an address, take the 1st match */
1129 cmp = 0; /*XXX*/
1130 } else {
1131 /* on deleting an address, do exact match */
1132 in6_len2mask(&mask, 128);
1133 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1134 bcopy(&sin6->sin6_addr, &match, sizeof(match));
1135
1136 cmp = 1;
1137 }
1138 }
1139
1140 for (ifa = ifp->if_addrlist.tqh_first;
1141 ifa;
1142 ifa = ifa->ifa_list.tqe_next)
1143 {
1144 if (ifa->ifa_addr->sa_family != AF_INET6)
1145 continue;
1146 if (!cmp)
1147 break;
1148 bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate));
1149 candidate.s6_addr32[0] &= mask.s6_addr32[0];
1150 candidate.s6_addr32[1] &= mask.s6_addr32[1];
1151 candidate.s6_addr32[2] &= mask.s6_addr32[2];
1152 candidate.s6_addr32[3] &= mask.s6_addr32[3];
1153 if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
1154 break;
1155 }
1156 if (!ifa)
1157 return EADDRNOTAVAIL;
1158 ia = ifa2ia6(ifa);
1159
1160 if (cmd == SIOCGLIFADDR) {
1161 /* fill in the if_laddrreq structure */
1162 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len);
1163
1164 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1165 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
1166 ia->ia_dstaddr.sin6_len);
1167 } else
1168 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
1169
1170 iflr->prefixlen =
1171 in6_mask2len(&ia->ia_prefixmask.sin6_addr);
1172
1173 iflr->flags = ia->ia6_flags; /*XXX*/
1174
1175 return 0;
1176 } else {
1177 struct in6_aliasreq ifra;
1178
1179 /* fill in6_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
1180 bzero(&ifra, sizeof(ifra));
1181 bcopy(iflr->iflr_name, ifra.ifra_name,
1182 sizeof(ifra.ifra_name));
1183
1184 bcopy(&ia->ia_addr, &ifra.ifra_addr,
1185 ia->ia_addr.sin6_len);
1186 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1187 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
1188 ia->ia_dstaddr.sin6_len);
1189 }
1190 bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr,
1191 ia->ia_prefixmask.sin6_len);
1192
1193 ifra.ifra_flags = ia->ia6_flags;
1194 return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra,
1195 ifp, p);
1196 }
1197 }
1198 }
1199
1200 return EOPNOTSUPP; /*just for safety*/
1201 }
1202
1203 /*
1204 * Delete any existing route for an interface.
1205 */
1206 void
1207 in6_ifscrub(ifp, ia)
1208 register struct ifnet *ifp;
1209 register struct in6_ifaddr *ia;
1210 {
1211 if ((ia->ia_flags & IFA_ROUTE) == 0)
1212 return;
1213 if (ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
1214 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
1215 else
1216 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
1217 ia->ia_flags &= ~IFA_ROUTE;
1218
1219 /* Remove ownaddr's loopback rtentry, if it exists. */
1220 in6_ifremloop(&(ia->ia_ifa));
1221 }
1222
1223 /*
1224 * Initialize an interface's intetnet6 address
1225 * and routing table entry.
1226 */
1227 int
1228 in6_ifinit(ifp, ia, sin6, scrub)
1229 struct ifnet *ifp;
1230 struct in6_ifaddr *ia;
1231 struct sockaddr_in6 *sin6;
1232 int scrub;
1233 {
1234 struct sockaddr_in6 oldaddr;
1235 int error, flags = RTF_UP;
1236 int s = splimp();
1237
1238 oldaddr = ia->ia_addr;
1239 ia->ia_addr = *sin6;
1240 /*
1241 * Give the interface a chance to initialize
1242 * if this is its first address,
1243 * and to validate the address if necessary.
1244 */
1245 if (ifp->if_ioctl &&
1246 (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
1247 splx(s);
1248 ia->ia_addr = oldaddr;
1249 return(error);
1250 }
1251
1252 switch (ifp->if_type) {
1253 case IFT_ARCNET:
1254 case IFT_ETHER:
1255 case IFT_FDDI:
1256 ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
1257 ia->ia_ifa.ifa_flags |= RTF_CLONING;
1258 break;
1259 case IFT_PPP:
1260 ia->ia_ifa.ifa_rtrequest = nd6_p2p_rtrequest;
1261 ia->ia_ifa.ifa_flags |= RTF_CLONING;
1262 break;
1263 }
1264
1265 splx(s);
1266 if (scrub) {
1267 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
1268 in6_ifscrub(ifp, ia);
1269 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
1270 }
1271 /* xxx
1272 * in_socktrim
1273 */
1274 /*
1275 * Add route for the network.
1276 */
1277 ia->ia_ifa.ifa_metric = ifp->if_metric;
1278 if (ifp->if_flags & IFF_LOOPBACK) {
1279 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
1280 flags |= RTF_HOST;
1281 } else if (ifp->if_flags & IFF_POINTOPOINT) {
1282 if (ia->ia_dstaddr.sin6_family != AF_INET6)
1283 return(0);
1284 flags |= RTF_HOST;
1285 }
1286 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
1287 ia->ia_flags |= IFA_ROUTE;
1288
1289 /* Add ownaddr as loopback rtentry, if necessary(ex. on p2p link). */
1290 in6_ifaddloop(&(ia->ia_ifa));
1291
1292 if (ifp->if_flags & IFF_MULTICAST)
1293 in6_restoremkludge(ia, ifp);
1294
1295 return(error);
1296 }
1297
1298 /*
1299 * Multicast address kludge:
1300 * If there were any multicast addresses attached to this interface address,
1301 * either move them to another address on this interface, or save them until
1302 * such time as this interface is reconfigured for IPv6.
1303 */
1304 void
1305 in6_savemkludge(oia)
1306 struct in6_ifaddr *oia;
1307 {
1308 struct in6_ifaddr *ia;
1309 struct in6_multi *in6m, *next;
1310
1311 IFP_TO_IA6(oia->ia_ifp, ia);
1312 if (ia) { /* there is another address */
1313 for (in6m = oia->ia6_multiaddrs.lh_first; in6m; in6m = next){
1314 next = in6m->in6m_entry.le_next;
1315 IFAFREE(&in6m->in6m_ia->ia_ifa);
1316 IFAREF(&ia->ia_ifa);
1317 in6m->in6m_ia = ia;
1318 LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);
1319 }
1320 } else { /* last address on this if deleted, save */
1321 struct multi6_kludge *mk;
1322
1323 mk = malloc(sizeof(*mk), M_IPMADDR, M_WAITOK);
1324
1325 LIST_INIT(&mk->mk_head);
1326 mk->mk_ifp = oia->ia_ifp;
1327
1328 for (in6m = oia->ia6_multiaddrs.lh_first; in6m; in6m = next){
1329 next = in6m->in6m_entry.le_next;
1330 IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */
1331 in6m->in6m_ia = NULL;
1332 LIST_INSERT_HEAD(&mk->mk_head, in6m, in6m_entry);
1333 }
1334
1335 if (mk->mk_head.lh_first != NULL) {
1336 LIST_INSERT_HEAD(&in6_mk, mk, mk_entry);
1337 }
1338 else {
1339 FREE(mk, M_IPMADDR);
1340 }
1341 }
1342 }
1343
1344 /*
1345 * Continuation of multicast address hack:
1346 * If there was a multicast group list previously saved for this interface,
1347 * then we re-attach it to the first address configured on the i/f.
1348 */
1349 void
1350 in6_restoremkludge(ia, ifp)
1351 struct in6_ifaddr *ia;
1352 struct ifnet *ifp;
1353 {
1354 struct multi6_kludge *mk;
1355
1356 for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
1357 if (mk->mk_ifp == ifp) {
1358 struct in6_multi *in6m, *next;
1359
1360 for (in6m = mk->mk_head.lh_first; in6m; in6m = next){
1361 next = in6m->in6m_entry.le_next;
1362 in6m->in6m_ia = ia;
1363 IFAREF(&ia->ia_ifa); /* gain a reference */
1364 LIST_INSERT_HEAD(&ia->ia6_multiaddrs,
1365 in6m, in6m_entry);
1366 }
1367 LIST_REMOVE(mk, mk_entry);
1368 free(mk, M_IPMADDR);
1369 break;
1370 }
1371 }
1372 }
1373
1374 void
1375 in6_purgemkludge(ifp)
1376 struct ifnet *ifp;
1377 {
1378 struct multi6_kludge *mk;
1379 struct in6_multi *in6m;
1380
1381 for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
1382 if (mk->mk_ifp != ifp)
1383 continue;
1384
1385 /* leave from all multicast groups joined */
1386 while ((in6m = LIST_FIRST(&mk->mk_head)) != NULL)
1387 in6_delmulti(in6m);
1388 LIST_REMOVE(mk, mk_entry);
1389 free(mk, M_IPMADDR);
1390 break;
1391 }
1392 }
1393
1394 /*
1395 * Add an address to the list of IP6 multicast addresses for a
1396 * given interface.
1397 */
1398 struct in6_multi *
1399 in6_addmulti(maddr6, ifp, errorp)
1400 register struct in6_addr *maddr6;
1401 register struct ifnet *ifp;
1402 int *errorp;
1403 {
1404 struct in6_ifaddr *ia;
1405 struct in6_ifreq ifr;
1406 struct in6_multi *in6m;
1407 int s = splsoftnet();
1408
1409 *errorp = 0;
1410 /*
1411 * See if address already in list.
1412 */
1413 IN6_LOOKUP_MULTI(*maddr6, ifp, in6m);
1414 if (in6m != NULL) {
1415 /*
1416 * Found it; just increment the refrence count.
1417 */
1418 in6m->in6m_refcount++;
1419 } else {
1420 /*
1421 * New address; allocate a new multicast record
1422 * and link it into the interface's multicast list.
1423 */
1424 in6m = (struct in6_multi *)
1425 malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT);
1426 if (in6m == NULL) {
1427 splx(s);
1428 *errorp = ENOBUFS;
1429 return(NULL);
1430 }
1431 in6m->in6m_addr = *maddr6;
1432 in6m->in6m_ifp = ifp;
1433 in6m->in6m_refcount = 1;
1434 IFP_TO_IA6(ifp, ia);
1435 if (ia == NULL) {
1436 free(in6m, M_IPMADDR);
1437 splx(s);
1438 *errorp = EADDRNOTAVAIL; /* appropriate? */
1439 return(NULL);
1440 }
1441 in6m->in6m_ia = ia;
1442 IFAREF(&ia->ia_ifa); /* gain a reference */
1443 LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);
1444
1445 /*
1446 * Ask the network driver to update its multicast reception
1447 * filter appropriately for the new address.
1448 */
1449 bzero(&ifr.ifr_addr, sizeof(struct sockaddr_in6));
1450 ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6);
1451 ifr.ifr_addr.sin6_family = AF_INET6;
1452 ifr.ifr_addr.sin6_addr = *maddr6;
1453 if (ifp->if_ioctl == NULL)
1454 *errorp = ENXIO; /* XXX: appropriate? */
1455 else
1456 *errorp = (*ifp->if_ioctl)(ifp, SIOCADDMULTI,
1457 (caddr_t)&ifr);
1458 if (*errorp) {
1459 LIST_REMOVE(in6m, in6m_entry);
1460 free(in6m, M_IPMADDR);
1461 splx(s);
1462 return(NULL);
1463 }
1464 /*
1465 * Let MLD6 know that we have joined a new IP6 multicast
1466 * group.
1467 */
1468 mld6_start_listening(in6m);
1469 }
1470 splx(s);
1471 return(in6m);
1472 }
1473
1474 /*
1475 * Delete a multicast address record.
1476 */
1477 void
1478 in6_delmulti(in6m)
1479 struct in6_multi *in6m;
1480 {
1481 struct in6_ifreq ifr;
1482 int s = splsoftnet();
1483
1484 if (--in6m->in6m_refcount == 0) {
1485 /*
1486 * No remaining claims to this record; let MLD6 know
1487 * that we are leaving the multicast group.
1488 */
1489 mld6_stop_listening(in6m);
1490
1491 /*
1492 * Unlink from list.
1493 */
1494 LIST_REMOVE(in6m, in6m_entry);
1495 if (in6m->in6m_ia)
1496 IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */
1497
1498 /*
1499 * Notify the network driver to update its multicast
1500 * reception filter.
1501 */
1502 bzero(&ifr.ifr_addr, sizeof(struct sockaddr_in6));
1503 ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6);
1504 ifr.ifr_addr.sin6_family = AF_INET6;
1505 ifr.ifr_addr.sin6_addr = in6m->in6m_addr;
1506 (*in6m->in6m_ifp->if_ioctl)(in6m->in6m_ifp,
1507 SIOCDELMULTI, (caddr_t)&ifr);
1508 free(in6m, M_IPMADDR);
1509 }
1510 splx(s);
1511 }
1512
1513 /*
1514 * Find an IPv6 interface link-local address specific to an interface.
1515 */
1516 struct in6_ifaddr *
1517 in6ifa_ifpforlinklocal(ifp)
1518 struct ifnet *ifp;
1519 {
1520 register struct ifaddr *ifa;
1521
1522 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
1523 {
1524 if (ifa->ifa_addr == NULL)
1525 continue; /* just for safety */
1526 if (ifa->ifa_addr->sa_family != AF_INET6)
1527 continue;
1528 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa)))
1529 break;
1530 }
1531
1532 return((struct in6_ifaddr *)ifa);
1533 }
1534
1535
1536 /*
1537 * find the internet address corresponding to a given interface and address.
1538 */
1539 struct in6_ifaddr *
1540 in6ifa_ifpwithaddr(ifp, addr)
1541 struct ifnet *ifp;
1542 struct in6_addr *addr;
1543 {
1544 register struct ifaddr *ifa;
1545
1546 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
1547 {
1548 if (ifa->ifa_addr == NULL)
1549 continue; /* just for safety */
1550 if (ifa->ifa_addr->sa_family != AF_INET6)
1551 continue;
1552 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
1553 break;
1554 }
1555
1556 return((struct in6_ifaddr *)ifa);
1557 }
1558
1559 /*
1560 * Convert IP6 address to printable (loggable) representation.
1561 */
1562 static char digits[] = "0123456789abcdef";
1563 static int ip6round = 0;
1564 char *
1565 ip6_sprintf(addr)
1566 register struct in6_addr *addr;
1567 {
1568 static char ip6buf[8][48];
1569 register int i;
1570 register char *cp;
1571 register u_short *a = (u_short *)addr;
1572 register u_char *d;
1573 int dcolon = 0;
1574
1575 ip6round = (ip6round + 1) & 7;
1576 cp = ip6buf[ip6round];
1577
1578 for (i = 0; i < 8; i++) {
1579 if (dcolon == 1) {
1580 if (*a == 0) {
1581 if (i == 7)
1582 *cp++ = ':';
1583 a++;
1584 continue;
1585 } else
1586 dcolon = 2;
1587 }
1588 if (*a == 0) {
1589 if (dcolon == 0 && *(a + 1) == 0) {
1590 if (i == 0)
1591 *cp++ = ':';
1592 *cp++ = ':';
1593 dcolon = 1;
1594 } else {
1595 *cp++ = '0';
1596 *cp++ = ':';
1597 }
1598 a++;
1599 continue;
1600 }
1601 d = (u_char *)a;
1602 *cp++ = digits[*d >> 4];
1603 *cp++ = digits[*d++ & 0xf];
1604 *cp++ = digits[*d >> 4];
1605 *cp++ = digits[*d & 0xf];
1606 *cp++ = ':';
1607 a++;
1608 }
1609 *--cp = 0;
1610 return(ip6buf[ip6round]);
1611 }
1612
1613 int
1614 in6_localaddr(in6)
1615 struct in6_addr *in6;
1616 {
1617 struct in6_ifaddr *ia;
1618
1619 if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6))
1620 return 1;
1621
1622 for (ia = in6_ifaddr; ia; ia = ia->ia_next)
1623 if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr,
1624 &ia->ia_prefixmask.sin6_addr))
1625 return 1;
1626
1627 return (0);
1628 }
1629
1630 /*
1631 * Get a scope of the address. Node-local, link-local, site-local or global.
1632 */
1633 int
1634 in6_addrscope (addr)
1635 struct in6_addr *addr;
1636 {
1637 int scope;
1638
1639 if (addr->s6_addr8[0] == 0xfe) {
1640 scope = addr->s6_addr8[1] & 0xc0;
1641
1642 switch (scope) {
1643 case 0x80:
1644 return IPV6_ADDR_SCOPE_LINKLOCAL;
1645 break;
1646 case 0xc0:
1647 return IPV6_ADDR_SCOPE_SITELOCAL;
1648 break;
1649 default:
1650 return IPV6_ADDR_SCOPE_GLOBAL; /* just in case */
1651 break;
1652 }
1653 }
1654
1655
1656 if (addr->s6_addr8[0] == 0xff) {
1657 scope = addr->s6_addr8[1] & 0x0f;
1658
1659 /*
1660 * due to other scope such as reserved,
1661 * return scope doesn't work.
1662 */
1663 switch (scope) {
1664 case IPV6_ADDR_SCOPE_NODELOCAL:
1665 return IPV6_ADDR_SCOPE_NODELOCAL;
1666 break;
1667 case IPV6_ADDR_SCOPE_LINKLOCAL:
1668 return IPV6_ADDR_SCOPE_LINKLOCAL;
1669 break;
1670 case IPV6_ADDR_SCOPE_SITELOCAL:
1671 return IPV6_ADDR_SCOPE_SITELOCAL;
1672 break;
1673 default:
1674 return IPV6_ADDR_SCOPE_GLOBAL;
1675 break;
1676 }
1677 }
1678
1679 if (bcmp(&in6addr_loopback, addr, sizeof(addr) - 1) == 0) {
1680 if (addr->s6_addr8[15] == 1) /* loopback */
1681 return IPV6_ADDR_SCOPE_NODELOCAL;
1682 if (addr->s6_addr8[15] == 0) /* unspecified */
1683 return IPV6_ADDR_SCOPE_LINKLOCAL;
1684 }
1685
1686 return IPV6_ADDR_SCOPE_GLOBAL;
1687 }
1688
1689 /*
1690 * return length of part which dst and src are equal
1691 * hard coding...
1692 */
1693
1694 int
1695 in6_matchlen(src, dst)
1696 struct in6_addr *src, *dst;
1697 {
1698 int match = 0;
1699 u_char *s = (u_char *)src, *d = (u_char *)dst;
1700 u_char *lim = s + 16, r;
1701
1702 while (s < lim)
1703 if ((r = (*d++ ^ *s++)) != 0) {
1704 while (r < 128) {
1705 match++;
1706 r <<= 1;
1707 }
1708 break;
1709 } else
1710 match += 8;
1711 return match;
1712 }
1713
1714 int
1715 in6_are_prefix_equal(p1, p2, len)
1716 struct in6_addr *p1, *p2;
1717 int len;
1718 {
1719 int bytelen, bitlen;
1720
1721 /* sanity check */
1722 if (0 > len || len > 128) {
1723 log(LOG_ERR, "in6_are_prefix_equal: invalid prefix length(%d)\n",
1724 len);
1725 return(0);
1726 }
1727
1728 bytelen = len / 8;
1729 bitlen = len % 8;
1730
1731 if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen))
1732 return(0);
1733 if (p1->s6_addr[bytelen] >> (8 - bitlen) !=
1734 p2->s6_addr[bytelen] >> (8 - bitlen))
1735 return(0);
1736
1737 return(1);
1738 }
1739
1740 void
1741 in6_prefixlen2mask(maskp, len)
1742 struct in6_addr *maskp;
1743 int len;
1744 {
1745 u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
1746 int bytelen, bitlen, i;
1747
1748 /* sanity check */
1749 if (0 > len || len > 128) {
1750 log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n",
1751 len);
1752 return;
1753 }
1754
1755 bzero(maskp, sizeof(*maskp));
1756 bytelen = len / 8;
1757 bitlen = len % 8;
1758 for (i = 0; i < bytelen; i++)
1759 maskp->s6_addr[i] = 0xff;
1760 if (bitlen)
1761 maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
1762 }
1763
1764 /*
1765 * return the best address out of the same scope
1766 */
1767
1768 struct in6_ifaddr *
1769 in6_ifawithscope(ifp, dst)
1770 register struct ifnet *ifp;
1771 register struct in6_addr *dst;
1772 {
1773 int dst_scope = in6_addrscope(dst), blen = -1, tlen;
1774 struct ifaddr *ifa;
1775 struct in6_ifaddr *besta = NULL, *ia;
1776 struct in6_ifaddr *dep[2]; /*last-resort: deprecated*/
1777
1778 dep[0] = dep[1] = NULL;
1779
1780 /*
1781 * We first look for addresses in the same scope.
1782 * If there is one, return it.
1783 * If two or more, return one which matches the dst longest.
1784 * If none, return one of global addresses assigned other ifs.
1785 */
1786 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
1787 {
1788 if (ifa->ifa_addr->sa_family != AF_INET6)
1789 continue;
1790 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
1791 continue; /* XXX: is there any case to allow anycast? */
1792 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
1793 continue; /* don't use this interface */
1794 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
1795 continue;
1796 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
1797 if (ip6_use_deprecated)
1798 dep[0] = (struct in6_ifaddr *)ifa;
1799 continue;
1800 }
1801
1802 if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
1803 /*
1804 * call in6_matchlen() as few as possible
1805 */
1806 if (besta) {
1807 if (blen == -1)
1808 blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst);
1809 tlen = in6_matchlen(IFA_IN6(ifa), dst);
1810 if (tlen > blen) {
1811 blen = tlen;
1812 besta = (struct in6_ifaddr *)ifa;
1813 }
1814 } else
1815 besta = (struct in6_ifaddr *)ifa;
1816 }
1817 }
1818 if (besta)
1819 return besta;
1820
1821 for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
1822 if (IPV6_ADDR_SCOPE_GLOBAL !=
1823 in6_addrscope(&(ia->ia_addr.sin6_addr)))
1824 continue;
1825 /* XXX: is there any case to allow anycast? */
1826 if ((ia->ia6_flags & IN6_IFF_ANYCAST) != 0)
1827 continue;
1828 if ((ia->ia6_flags & IN6_IFF_NOTREADY) != 0)
1829 continue;
1830 if ((ia->ia6_flags & IN6_IFF_DETACHED) != 0)
1831 continue;
1832 if ((ia->ia6_flags & IN6_IFF_DEPRECATED) != 0) {
1833 if (ip6_use_deprecated)
1834 dep[1] = (struct in6_ifaddr *)ifa;
1835 continue;
1836 }
1837 return ia;
1838 }
1839
1840 /* use the last-resort values, that are, deprecated addresses */
1841 if (dep[0])
1842 return dep[0];
1843 if (dep[1])
1844 return dep[1];
1845
1846 return NULL;
1847 }
1848
1849 /*
1850 * return the best address out of the same scope. if no address was
1851 * found, return the first valid address from designated IF.
1852 */
1853
1854 struct in6_ifaddr *
1855 in6_ifawithifp(ifp, dst)
1856 register struct ifnet *ifp;
1857 register struct in6_addr *dst;
1858 {
1859 int dst_scope = in6_addrscope(dst), blen = -1, tlen;
1860 struct ifaddr *ifa;
1861 struct in6_ifaddr *besta = 0;
1862 struct in6_ifaddr *dep[2]; /*last-resort: deprecated*/
1863
1864 dep[0] = dep[1] = NULL;
1865
1866 /*
1867 * We first look for addresses in the same scope.
1868 * If there is one, return it.
1869 * If two or more, return one which matches the dst longest.
1870 * If none, return one of global addresses assigned other ifs.
1871 */
1872 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
1873 {
1874 if (ifa->ifa_addr->sa_family != AF_INET6)
1875 continue;
1876 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
1877 continue; /* XXX: is there any case to allow anycast? */
1878 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
1879 continue; /* don't use this interface */
1880 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
1881 continue;
1882 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
1883 if (ip6_use_deprecated)
1884 dep[0] = (struct in6_ifaddr *)ifa;
1885 continue;
1886 }
1887
1888 if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
1889 /*
1890 * call in6_matchlen() as few as possible
1891 */
1892 if (besta) {
1893 if (blen == -1)
1894 blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst);
1895 tlen = in6_matchlen(IFA_IN6(ifa), dst);
1896 if (tlen > blen) {
1897 blen = tlen;
1898 besta = (struct in6_ifaddr *)ifa;
1899 }
1900 } else
1901 besta = (struct in6_ifaddr *)ifa;
1902 }
1903 }
1904 if (besta)
1905 return(besta);
1906
1907 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
1908 {
1909 if (ifa->ifa_addr->sa_family != AF_INET6)
1910 continue;
1911 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
1912 continue; /* XXX: is there any case to allow anycast? */
1913 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
1914 continue; /* don't use this interface */
1915 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
1916 continue;
1917 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
1918 if (ip6_use_deprecated)
1919 dep[1] = (struct in6_ifaddr *)ifa;
1920 continue;
1921 }
1922
1923 return (struct in6_ifaddr *)ifa;
1924 }
1925
1926 /* use the last-resort values, that are, deprecated addresses */
1927 if (dep[0])
1928 return dep[0];
1929 if (dep[1])
1930 return dep[1];
1931
1932 return NULL;
1933 }
1934
1935 /*
1936 * perform DAD when interface becomes IFF_UP.
1937 */
1938 void
1939 in6_if_up(ifp)
1940 struct ifnet *ifp;
1941 {
1942 struct ifaddr *ifa;
1943 struct in6_ifaddr *ia;
1944 struct sockaddr_dl *sdl;
1945 int type;
1946 struct ether_addr ea;
1947 int off;
1948 int dad_delay; /* delay ticks before DAD output */
1949
1950 bzero(&ea, sizeof(ea));
1951 sdl = NULL;
1952
1953 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
1954 {
1955 if (ifa->ifa_addr->sa_family == AF_INET6
1956 && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
1957 goto dad;
1958 }
1959 if (ifa->ifa_addr->sa_family != AF_LINK)
1960 continue;
1961 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1962 break;
1963 }
1964
1965 switch (ifp->if_type) {
1966 case IFT_LOOP:
1967 in6_ifattach(ifp, IN6_IFT_LOOP, NULL, 1);
1968 break;
1969 case IFT_SLIP:
1970 case IFT_PPP:
1971 case IFT_GIF:
1972 case IFT_FAITH:
1973 type = IN6_IFT_P2P;
1974 in6_ifattach(ifp, type, 0, 1);
1975 break;
1976 case IFT_ETHER:
1977 case IFT_FDDI:
1978 case IFT_ATM:
1979 type = IN6_IFT_802;
1980 if (sdl == NULL)
1981 break;
1982 off = sdl->sdl_nlen;
1983 if (bcmp(&sdl->sdl_data[off], &ea, sizeof(ea)) != 0)
1984 in6_ifattach(ifp, type, LLADDR(sdl), 0);
1985 break;
1986 case IFT_ARCNET:
1987 type = IN6_IFT_ARCNET;
1988 if (sdl == NULL)
1989 break;
1990 off = sdl->sdl_nlen;
1991 if (sdl->sdl_data[off] != 0) /* XXX ?: */
1992 in6_ifattach(ifp, type, LLADDR(sdl), 0);
1993 break;
1994 default:
1995 break;
1996 }
1997
1998 dad:
1999 dad_delay = 0;
2000 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
2001 {
2002 if (ifa->ifa_addr->sa_family != AF_INET6)
2003 continue;
2004 ia = (struct in6_ifaddr *)ifa;
2005 if (ia->ia6_flags & IN6_IFF_TENTATIVE)
2006 nd6_dad_start(ifa, &dad_delay);
2007 }
2008 }
2009
2010 /*
2011 * Calculate max IPv6 MTU through all the interfaces and store it
2012 * to in6_maxmtu.
2013 */
2014 void
2015 in6_setmaxmtu()
2016 {
2017 unsigned long maxmtu = 0;
2018 struct ifnet *ifp;
2019
2020 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
2021 {
2022 if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
2023 nd_ifinfo[ifp->if_index].linkmtu > maxmtu)
2024 maxmtu = nd_ifinfo[ifp->if_index].linkmtu;
2025 }
2026 if (maxmtu) /* update only when maxmtu is positive */
2027 in6_maxmtu = maxmtu;
2028 }
2029