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