in6.c revision 1.46 1 /* $NetBSD: in6.c,v 1.46 2001/07/18 13:12:27 itojun Exp $ */
2 /* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun 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 <netinet/ip6.h>
93 #include <netinet6/ip6_var.h>
94 #include <netinet6/nd6.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 contradicts */
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 contradicts */
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 contradicts */
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 = splnet();
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 for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
1315 if (mk->mk_ifp == oia->ia_ifp)
1316 break;
1317 }
1318 if (mk == NULL) /* this should not happen! */
1319 panic("in6_savemkludge: no kludge space");
1320
1321 for (in6m = oia->ia6_multiaddrs.lh_first; in6m; in6m = next){
1322 next = in6m->in6m_entry.le_next;
1323 IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */
1324 in6m->in6m_ia = NULL;
1325 LIST_INSERT_HEAD(&mk->mk_head, in6m, in6m_entry);
1326 }
1327 }
1328 }
1329
1330 /*
1331 * Continuation of multicast address hack:
1332 * If there was a multicast group list previously saved for this interface,
1333 * then we re-attach it to the first address configured on the i/f.
1334 */
1335 void
1336 in6_restoremkludge(ia, ifp)
1337 struct in6_ifaddr *ia;
1338 struct ifnet *ifp;
1339 {
1340 struct multi6_kludge *mk;
1341
1342 for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
1343 if (mk->mk_ifp == ifp) {
1344 struct in6_multi *in6m, *next;
1345
1346 for (in6m = mk->mk_head.lh_first; in6m; in6m = next) {
1347 next = in6m->in6m_entry.le_next;
1348 in6m->in6m_ia = ia;
1349 IFAREF(&ia->ia_ifa);
1350 LIST_INSERT_HEAD(&ia->ia6_multiaddrs,
1351 in6m, in6m_entry);
1352 }
1353 LIST_INIT(&mk->mk_head);
1354 break;
1355 }
1356 }
1357 }
1358
1359 /*
1360 * Allocate space for the kludge at interface initialization time.
1361 * Formerly, we dynamically allocated the space in in6_savemkludge() with
1362 * malloc(M_WAITOK). However, it was wrong since the function could be called
1363 * under an interrupt context (software timer on address lifetime expiration).
1364 * Also, we cannot just give up allocating the strucutre, since the group
1365 * membership structure is very complex and we need to keep it anyway.
1366 * Of course, this function MUST NOT be called under an interrupt context.
1367 * Specifically, it is expected to be called only from in6_ifattach(), though
1368 * it is a global function.
1369 */
1370 void
1371 in6_createmkludge(ifp)
1372 struct ifnet *ifp;
1373 {
1374 struct multi6_kludge *mk;
1375
1376 for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
1377 /* If we've already had one, do not allocate. */
1378 if (mk->mk_ifp == ifp)
1379 return;
1380 }
1381
1382 mk = malloc(sizeof(*mk), M_IPMADDR, M_WAITOK);
1383
1384 bzero(mk, sizeof(*mk));
1385 LIST_INIT(&mk->mk_head);
1386 mk->mk_ifp = ifp;
1387 LIST_INSERT_HEAD(&in6_mk, mk, mk_entry);
1388 }
1389
1390 void
1391 in6_purgemkludge(ifp)
1392 struct ifnet *ifp;
1393 {
1394 struct multi6_kludge *mk;
1395 struct in6_multi *in6m;
1396
1397 for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
1398 if (mk->mk_ifp != ifp)
1399 continue;
1400
1401 /* leave from all multicast groups joined */
1402 while ((in6m = LIST_FIRST(&mk->mk_head)) != NULL)
1403 in6_delmulti(in6m);
1404 LIST_REMOVE(mk, mk_entry);
1405 free(mk, M_IPMADDR);
1406 break;
1407 }
1408 }
1409
1410 /*
1411 * Add an address to the list of IP6 multicast addresses for a
1412 * given interface.
1413 */
1414 struct in6_multi *
1415 in6_addmulti(maddr6, ifp, errorp)
1416 struct in6_addr *maddr6;
1417 struct ifnet *ifp;
1418 int *errorp;
1419 {
1420 struct in6_ifaddr *ia;
1421 struct in6_ifreq ifr;
1422 struct in6_multi *in6m;
1423 int s = splsoftnet();
1424
1425 *errorp = 0;
1426 /*
1427 * See if address already in list.
1428 */
1429 IN6_LOOKUP_MULTI(*maddr6, ifp, in6m);
1430 if (in6m != NULL) {
1431 /*
1432 * Found it; just increment the refrence count.
1433 */
1434 in6m->in6m_refcount++;
1435 } else {
1436 /*
1437 * New address; allocate a new multicast record
1438 * and link it into the interface's multicast list.
1439 */
1440 in6m = (struct in6_multi *)
1441 malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT);
1442 if (in6m == NULL) {
1443 splx(s);
1444 *errorp = ENOBUFS;
1445 return(NULL);
1446 }
1447 in6m->in6m_addr = *maddr6;
1448 in6m->in6m_ifp = ifp;
1449 in6m->in6m_refcount = 1;
1450 IFP_TO_IA6(ifp, ia);
1451 if (ia == NULL) {
1452 free(in6m, M_IPMADDR);
1453 splx(s);
1454 *errorp = EADDRNOTAVAIL; /* appropriate? */
1455 return(NULL);
1456 }
1457 in6m->in6m_ia = ia;
1458 IFAREF(&ia->ia_ifa); /* gain a reference */
1459 LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);
1460
1461 /*
1462 * Ask the network driver to update its multicast reception
1463 * filter appropriately for the new address.
1464 */
1465 bzero(&ifr.ifr_addr, sizeof(struct sockaddr_in6));
1466 ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6);
1467 ifr.ifr_addr.sin6_family = AF_INET6;
1468 ifr.ifr_addr.sin6_addr = *maddr6;
1469 if (ifp->if_ioctl == NULL)
1470 *errorp = ENXIO; /* XXX: appropriate? */
1471 else
1472 *errorp = (*ifp->if_ioctl)(ifp, SIOCADDMULTI,
1473 (caddr_t)&ifr);
1474 if (*errorp) {
1475 LIST_REMOVE(in6m, in6m_entry);
1476 free(in6m, M_IPMADDR);
1477 IFAFREE(&ia->ia_ifa);
1478 splx(s);
1479 return(NULL);
1480 }
1481 /*
1482 * Let MLD6 know that we have joined a new IP6 multicast
1483 * group.
1484 */
1485 mld6_start_listening(in6m);
1486 }
1487 splx(s);
1488 return(in6m);
1489 }
1490
1491 /*
1492 * Delete a multicast address record.
1493 */
1494 void
1495 in6_delmulti(in6m)
1496 struct in6_multi *in6m;
1497 {
1498 struct in6_ifreq ifr;
1499 int s = splsoftnet();
1500
1501 if (--in6m->in6m_refcount == 0) {
1502 /*
1503 * No remaining claims to this record; let MLD6 know
1504 * that we are leaving the multicast group.
1505 */
1506 mld6_stop_listening(in6m);
1507
1508 /*
1509 * Unlink from list.
1510 */
1511 LIST_REMOVE(in6m, in6m_entry);
1512 if (in6m->in6m_ia) {
1513 IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */
1514 }
1515
1516 /*
1517 * Notify the network driver to update its multicast
1518 * reception filter.
1519 */
1520 bzero(&ifr.ifr_addr, sizeof(struct sockaddr_in6));
1521 ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6);
1522 ifr.ifr_addr.sin6_family = AF_INET6;
1523 ifr.ifr_addr.sin6_addr = in6m->in6m_addr;
1524 (*in6m->in6m_ifp->if_ioctl)(in6m->in6m_ifp,
1525 SIOCDELMULTI, (caddr_t)&ifr);
1526 free(in6m, M_IPMADDR);
1527 }
1528 splx(s);
1529 }
1530
1531 /*
1532 * Find an IPv6 interface link-local address specific to an interface.
1533 */
1534 struct in6_ifaddr *
1535 in6ifa_ifpforlinklocal(ifp, ignoreflags)
1536 struct ifnet *ifp;
1537 int ignoreflags;
1538 {
1539 struct ifaddr *ifa;
1540
1541 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
1542 {
1543 if (ifa->ifa_addr == NULL)
1544 continue; /* just for safety */
1545 if (ifa->ifa_addr->sa_family != AF_INET6)
1546 continue;
1547 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
1548 if ((((struct in6_ifaddr *)ifa)->ia6_flags &
1549 ignoreflags) != 0)
1550 continue;
1551 break;
1552 }
1553 }
1554
1555 return((struct in6_ifaddr *)ifa);
1556 }
1557
1558
1559 /*
1560 * find the internet address corresponding to a given interface and address.
1561 */
1562 struct in6_ifaddr *
1563 in6ifa_ifpwithaddr(ifp, addr)
1564 struct ifnet *ifp;
1565 struct in6_addr *addr;
1566 {
1567 struct ifaddr *ifa;
1568
1569 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
1570 {
1571 if (ifa->ifa_addr == NULL)
1572 continue; /* just for safety */
1573 if (ifa->ifa_addr->sa_family != AF_INET6)
1574 continue;
1575 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
1576 break;
1577 }
1578
1579 return((struct in6_ifaddr *)ifa);
1580 }
1581
1582 /*
1583 * Convert IP6 address to printable (loggable) representation.
1584 */
1585 static char digits[] = "0123456789abcdef";
1586 static int ip6round = 0;
1587 char *
1588 ip6_sprintf(addr)
1589 struct in6_addr *addr;
1590 {
1591 static char ip6buf[8][48];
1592 int i;
1593 char *cp;
1594 u_short *a = (u_short *)addr;
1595 u_char *d;
1596 int dcolon = 0;
1597
1598 ip6round = (ip6round + 1) & 7;
1599 cp = ip6buf[ip6round];
1600
1601 for (i = 0; i < 8; i++) {
1602 if (dcolon == 1) {
1603 if (*a == 0) {
1604 if (i == 7)
1605 *cp++ = ':';
1606 a++;
1607 continue;
1608 } else
1609 dcolon = 2;
1610 }
1611 if (*a == 0) {
1612 if (dcolon == 0 && *(a + 1) == 0) {
1613 if (i == 0)
1614 *cp++ = ':';
1615 *cp++ = ':';
1616 dcolon = 1;
1617 } else {
1618 *cp++ = '0';
1619 *cp++ = ':';
1620 }
1621 a++;
1622 continue;
1623 }
1624 d = (u_char *)a;
1625 *cp++ = digits[*d >> 4];
1626 *cp++ = digits[*d++ & 0xf];
1627 *cp++ = digits[*d >> 4];
1628 *cp++ = digits[*d & 0xf];
1629 *cp++ = ':';
1630 a++;
1631 }
1632 *--cp = 0;
1633 return(ip6buf[ip6round]);
1634 }
1635
1636 int
1637 in6_localaddr(in6)
1638 struct in6_addr *in6;
1639 {
1640 struct in6_ifaddr *ia;
1641
1642 if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6))
1643 return 1;
1644
1645 for (ia = in6_ifaddr; ia; ia = ia->ia_next)
1646 if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr,
1647 &ia->ia_prefixmask.sin6_addr))
1648 return 1;
1649
1650 return (0);
1651 }
1652
1653 /*
1654 * Get a scope of the address. Node-local, link-local, site-local or global.
1655 */
1656 int
1657 in6_addrscope (addr)
1658 struct in6_addr *addr;
1659 {
1660 int scope;
1661
1662 if (addr->s6_addr8[0] == 0xfe) {
1663 scope = addr->s6_addr8[1] & 0xc0;
1664
1665 switch (scope) {
1666 case 0x80:
1667 return IPV6_ADDR_SCOPE_LINKLOCAL;
1668 break;
1669 case 0xc0:
1670 return IPV6_ADDR_SCOPE_SITELOCAL;
1671 break;
1672 default:
1673 return IPV6_ADDR_SCOPE_GLOBAL; /* just in case */
1674 break;
1675 }
1676 }
1677
1678
1679 if (addr->s6_addr8[0] == 0xff) {
1680 scope = addr->s6_addr8[1] & 0x0f;
1681
1682 /*
1683 * due to other scope such as reserved,
1684 * return scope doesn't work.
1685 */
1686 switch (scope) {
1687 case IPV6_ADDR_SCOPE_NODELOCAL:
1688 return IPV6_ADDR_SCOPE_NODELOCAL;
1689 break;
1690 case IPV6_ADDR_SCOPE_LINKLOCAL:
1691 return IPV6_ADDR_SCOPE_LINKLOCAL;
1692 break;
1693 case IPV6_ADDR_SCOPE_SITELOCAL:
1694 return IPV6_ADDR_SCOPE_SITELOCAL;
1695 break;
1696 default:
1697 return IPV6_ADDR_SCOPE_GLOBAL;
1698 break;
1699 }
1700 }
1701
1702 if (bcmp(&in6addr_loopback, addr, sizeof(addr) - 1) == 0) {
1703 if (addr->s6_addr8[15] == 1) /* loopback */
1704 return IPV6_ADDR_SCOPE_NODELOCAL;
1705 if (addr->s6_addr8[15] == 0) /* unspecified */
1706 return IPV6_ADDR_SCOPE_LINKLOCAL;
1707 }
1708
1709 return IPV6_ADDR_SCOPE_GLOBAL;
1710 }
1711
1712 int
1713 in6_addr2scopeid(ifp, addr)
1714 struct ifnet *ifp; /* must not be NULL */
1715 struct in6_addr *addr; /* must not be NULL */
1716 {
1717 int scope = in6_addrscope(addr);
1718
1719 switch(scope) {
1720 case IPV6_ADDR_SCOPE_NODELOCAL:
1721 return(-1); /* XXX: is this an appropriate value? */
1722
1723 case IPV6_ADDR_SCOPE_LINKLOCAL:
1724 /* XXX: we do not distinguish between a link and an I/F. */
1725 return(ifp->if_index);
1726
1727 case IPV6_ADDR_SCOPE_SITELOCAL:
1728 return(0); /* XXX: invalid. */
1729
1730 default:
1731 return(0); /* XXX: treat as global. */
1732 }
1733 }
1734
1735 /*
1736 * return length of part which dst and src are equal
1737 * hard coding...
1738 */
1739 int
1740 in6_matchlen(src, dst)
1741 struct in6_addr *src, *dst;
1742 {
1743 int match = 0;
1744 u_char *s = (u_char *)src, *d = (u_char *)dst;
1745 u_char *lim = s + 16, r;
1746
1747 while (s < lim)
1748 if ((r = (*d++ ^ *s++)) != 0) {
1749 while (r < 128) {
1750 match++;
1751 r <<= 1;
1752 }
1753 break;
1754 } else
1755 match += 8;
1756 return match;
1757 }
1758
1759 int
1760 in6_are_prefix_equal(p1, p2, len)
1761 struct in6_addr *p1, *p2;
1762 int len;
1763 {
1764 int bytelen, bitlen;
1765
1766 /* sanity check */
1767 if (0 > len || len > 128) {
1768 log(LOG_ERR, "in6_are_prefix_equal: invalid prefix length(%d)\n",
1769 len);
1770 return(0);
1771 }
1772
1773 bytelen = len / 8;
1774 bitlen = len % 8;
1775
1776 if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen))
1777 return(0);
1778 if (p1->s6_addr[bytelen] >> (8 - bitlen) !=
1779 p2->s6_addr[bytelen] >> (8 - bitlen))
1780 return(0);
1781
1782 return(1);
1783 }
1784
1785 void
1786 in6_prefixlen2mask(maskp, len)
1787 struct in6_addr *maskp;
1788 int len;
1789 {
1790 u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
1791 int bytelen, bitlen, i;
1792
1793 /* sanity check */
1794 if (0 > len || len > 128) {
1795 log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n",
1796 len);
1797 return;
1798 }
1799
1800 bzero(maskp, sizeof(*maskp));
1801 bytelen = len / 8;
1802 bitlen = len % 8;
1803 for (i = 0; i < bytelen; i++)
1804 maskp->s6_addr[i] = 0xff;
1805 if (bitlen)
1806 maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
1807 }
1808
1809 /*
1810 * return the best address out of the same scope
1811 */
1812 struct in6_ifaddr *
1813 in6_ifawithscope(oifp, dst)
1814 struct ifnet *oifp;
1815 struct in6_addr *dst;
1816 {
1817 int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0;
1818 int blen = -1;
1819 struct ifaddr *ifa;
1820 struct ifnet *ifp;
1821 struct in6_ifaddr *ifa_best = NULL;
1822
1823 if (oifp == NULL) {
1824 printf("in6_ifawithscope: output interface is not specified\n");
1825 return(NULL);
1826 }
1827
1828 /*
1829 * We search for all addresses on all interfaces from the beginning.
1830 * Comparing an interface with the outgoing interface will be done
1831 * only at the final stage of tiebreaking.
1832 */
1833 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
1834 {
1835 /*
1836 * We can never take an address that breaks the scope zone
1837 * of the destination.
1838 */
1839 if (in6_addr2scopeid(ifp, dst) != in6_addr2scopeid(oifp, dst))
1840 continue;
1841
1842 for (ifa = ifp->if_addrlist.tqh_first; ifa;
1843 ifa = ifa->ifa_list.tqe_next)
1844 {
1845 int tlen = -1, dscopecmp, bscopecmp, matchcmp;
1846
1847 if (ifa->ifa_addr->sa_family != AF_INET6)
1848 continue;
1849
1850 src_scope = in6_addrscope(IFA_IN6(ifa));
1851
1852 #ifdef ADDRSELECT_DEBUG /* should be removed after stabilization */
1853 dscopecmp = IN6_ARE_SCOPE_CMP(src_scope, dst_scope);
1854 printf("in6_ifawithscope: dst=%s bestaddr=%s, "
1855 "newaddr=%s, scope=%x, dcmp=%d, bcmp=%d, "
1856 "matchlen=%d, flgs=%x\n",
1857 ip6_sprintf(dst),
1858 ifa_best ? ip6_sprintf(&ifa_best->ia_addr.sin6_addr) : "none",
1859 ip6_sprintf(IFA_IN6(ifa)), src_scope,
1860 dscopecmp,
1861 ifa_best ? IN6_ARE_SCOPE_CMP(src_scope, best_scope) : -1,
1862 in6_matchlen(IFA_IN6(ifa), dst),
1863 ((struct in6_ifaddr *)ifa)->ia6_flags);
1864 #endif
1865
1866 /*
1867 * Don't use an address before completing DAD
1868 * nor a duplicated address.
1869 */
1870 if (((struct in6_ifaddr *)ifa)->ia6_flags &
1871 IN6_IFF_NOTREADY)
1872 continue;
1873
1874 /* XXX: is there any case to allow anycasts? */
1875 if (((struct in6_ifaddr *)ifa)->ia6_flags &
1876 IN6_IFF_ANYCAST)
1877 continue;
1878
1879 if (((struct in6_ifaddr *)ifa)->ia6_flags &
1880 IN6_IFF_DETACHED)
1881 continue;
1882
1883 /*
1884 * If this is the first address we find,
1885 * keep it anyway.
1886 */
1887 if (ifa_best == NULL)
1888 goto replace;
1889
1890 /*
1891 * ifa_best is never NULL beyond this line except
1892 * within the block labeled "replace".
1893 */
1894
1895 /*
1896 * If ifa_best has a smaller scope than dst and
1897 * the current address has a larger one than
1898 * (or equal to) dst, always replace ifa_best.
1899 * Also, if the current address has a smaller scope
1900 * than dst, ignore it unless ifa_best also has a
1901 * smaller scope.
1902 */
1903 if (IN6_ARE_SCOPE_CMP(best_scope, dst_scope) < 0 &&
1904 IN6_ARE_SCOPE_CMP(src_scope, dst_scope) >= 0)
1905 goto replace;
1906 if (IN6_ARE_SCOPE_CMP(src_scope, dst_scope) < 0 &&
1907 IN6_ARE_SCOPE_CMP(best_scope, dst_scope) >= 0)
1908 continue;
1909
1910 /*
1911 * A deprecated address SHOULD NOT be used in new
1912 * communications if an alternate (non-deprecated)
1913 * address is available and has sufficient scope.
1914 * RFC 2462, Section 5.5.4.
1915 */
1916 if (((struct in6_ifaddr *)ifa)->ia6_flags &
1917 IN6_IFF_DEPRECATED) {
1918 /*
1919 * Ignore any deprecated addresses if
1920 * specified by configuration.
1921 */
1922 if (!ip6_use_deprecated)
1923 continue;
1924
1925 /*
1926 * If we have already found a non-deprecated
1927 * candidate, just ignore deprecated addresses.
1928 */
1929 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED)
1930 == 0)
1931 continue;
1932 }
1933
1934 /*
1935 * A non-deprecated address is always preferred
1936 * to a deprecated one regardless of scopes and
1937 * address matching.
1938 */
1939 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) &&
1940 (((struct in6_ifaddr *)ifa)->ia6_flags &
1941 IN6_IFF_DEPRECATED) == 0)
1942 goto replace;
1943
1944 /*
1945 * At this point, we have two cases:
1946 * 1. we are looking at a non-deprecated address,
1947 * and ifa_best is also non-deprecated.
1948 * 2. we are looking at a deprecated address,
1949 * and ifa_best is also deprecated.
1950 * Also, we do not have to consider a case where
1951 * the scope of if_best is larger(smaller) than dst and
1952 * the scope of the current address is smaller(larger)
1953 * than dst. Such a case has already been covered.
1954 * Tiebreaking is done according to the following
1955 * items:
1956 * - the scope comparison between the address and
1957 * dst (dscopecmp)
1958 * - the scope comparison between the address and
1959 * ifa_best (bscopecmp)
1960 * - if the address match dst longer than ifa_best
1961 * (matchcmp)
1962 * - if the address is on the outgoing I/F (outI/F)
1963 *
1964 * Roughly speaking, the selection policy is
1965 * - the most important item is scope. The same scope
1966 * is best. Then search for a larger scope.
1967 * Smaller scopes are the last resort.
1968 * - A deprecated address is chosen only when we have
1969 * no address that has an enough scope, but is
1970 * prefered to any addresses of smaller scopes.
1971 * - Longest address match against dst is considered
1972 * only for addresses that has the same scope of dst.
1973 * - If there is no other reasons to choose one,
1974 * addresses on the outgoing I/F are preferred.
1975 *
1976 * The precise decision table is as follows:
1977 * dscopecmp bscopecmp matchcmp outI/F | replace?
1978 * !equal equal N/A Yes | Yes (1)
1979 * !equal equal N/A No | No (2)
1980 * larger larger N/A N/A | No (3)
1981 * larger smaller N/A N/A | Yes (4)
1982 * smaller larger N/A N/A | Yes (5)
1983 * smaller smaller N/A N/A | No (6)
1984 * equal smaller N/A N/A | Yes (7)
1985 * equal larger (already done)
1986 * equal equal larger N/A | Yes (8)
1987 * equal equal smaller N/A | No (9)
1988 * equal equal equal Yes | Yes (a)
1989 * eaual eqaul equal No | No (b)
1990 */
1991 dscopecmp = IN6_ARE_SCOPE_CMP(src_scope, dst_scope);
1992 bscopecmp = IN6_ARE_SCOPE_CMP(src_scope, best_scope);
1993
1994 if (dscopecmp && bscopecmp == 0) {
1995 if (oifp == ifp) /* (1) */
1996 goto replace;
1997 continue; /* (2) */
1998 }
1999 if (dscopecmp > 0) {
2000 if (bscopecmp > 0) /* (3) */
2001 continue;
2002 goto replace; /* (4) */
2003 }
2004 if (dscopecmp < 0) {
2005 if (bscopecmp > 0) /* (5) */
2006 goto replace;
2007 continue; /* (6) */
2008 }
2009
2010 /* now dscopecmp must be 0 */
2011 if (bscopecmp < 0)
2012 goto replace; /* (7) */
2013
2014 /*
2015 * At last both dscopecmp and bscopecmp must be 0.
2016 * We need address matching against dst for
2017 * tiebreaking.
2018 */
2019 tlen = in6_matchlen(IFA_IN6(ifa), dst);
2020 matchcmp = tlen - blen;
2021 if (matchcmp > 0) /* (8) */
2022 goto replace;
2023 if (matchcmp < 0) /* (9) */
2024 continue;
2025 if (oifp == ifp) /* (a) */
2026 goto replace;
2027 continue; /* (b) */
2028
2029 replace:
2030 ifa_best = (struct in6_ifaddr *)ifa;
2031 blen = tlen >= 0 ? tlen :
2032 in6_matchlen(IFA_IN6(ifa), dst);
2033 best_scope = in6_addrscope(&ifa_best->ia_addr.sin6_addr);
2034 }
2035 }
2036
2037 /* count statistics for future improvements */
2038 if (ifa_best == NULL)
2039 ip6stat.ip6s_sources_none++;
2040 else {
2041 if (oifp == ifa_best->ia_ifp)
2042 ip6stat.ip6s_sources_sameif[best_scope]++;
2043 else
2044 ip6stat.ip6s_sources_otherif[best_scope]++;
2045
2046 if (best_scope == dst_scope)
2047 ip6stat.ip6s_sources_samescope[best_scope]++;
2048 else
2049 ip6stat.ip6s_sources_otherscope[best_scope]++;
2050
2051 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) != 0)
2052 ip6stat.ip6s_sources_deprecated[best_scope]++;
2053 }
2054
2055 return(ifa_best);
2056 }
2057
2058 /*
2059 * return the best address out of the same scope. if no address was
2060 * found, return the first valid address from designated IF.
2061 */
2062 struct in6_ifaddr *
2063 in6_ifawithifp(ifp, dst)
2064 struct ifnet *ifp;
2065 struct in6_addr *dst;
2066 {
2067 int dst_scope = in6_addrscope(dst), blen = -1, tlen;
2068 struct ifaddr *ifa;
2069 struct in6_ifaddr *besta = 0;
2070 struct in6_ifaddr *dep[2]; /*last-resort: deprecated*/
2071
2072 dep[0] = dep[1] = NULL;
2073
2074 /*
2075 * We first look for addresses in the same scope.
2076 * If there is one, return it.
2077 * If two or more, return one which matches the dst longest.
2078 * If none, return one of global addresses assigned other ifs.
2079 */
2080 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
2081 {
2082 if (ifa->ifa_addr->sa_family != AF_INET6)
2083 continue;
2084 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
2085 continue; /* XXX: is there any case to allow anycast? */
2086 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
2087 continue; /* don't use this interface */
2088 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
2089 continue;
2090 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
2091 if (ip6_use_deprecated)
2092 dep[0] = (struct in6_ifaddr *)ifa;
2093 continue;
2094 }
2095
2096 if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
2097 /*
2098 * call in6_matchlen() as few as possible
2099 */
2100 if (besta) {
2101 if (blen == -1)
2102 blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst);
2103 tlen = in6_matchlen(IFA_IN6(ifa), dst);
2104 if (tlen > blen) {
2105 blen = tlen;
2106 besta = (struct in6_ifaddr *)ifa;
2107 }
2108 } else
2109 besta = (struct in6_ifaddr *)ifa;
2110 }
2111 }
2112 if (besta)
2113 return(besta);
2114
2115 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
2116 {
2117 if (ifa->ifa_addr->sa_family != AF_INET6)
2118 continue;
2119 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
2120 continue; /* XXX: is there any case to allow anycast? */
2121 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
2122 continue; /* don't use this interface */
2123 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
2124 continue;
2125 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
2126 if (ip6_use_deprecated)
2127 dep[1] = (struct in6_ifaddr *)ifa;
2128 continue;
2129 }
2130
2131 return (struct in6_ifaddr *)ifa;
2132 }
2133
2134 /* use the last-resort values, that are, deprecated addresses */
2135 if (dep[0])
2136 return dep[0];
2137 if (dep[1])
2138 return dep[1];
2139
2140 return NULL;
2141 }
2142
2143 /*
2144 * perform DAD when interface becomes IFF_UP.
2145 */
2146 void
2147 in6_if_up(ifp)
2148 struct ifnet *ifp;
2149 {
2150 struct ifaddr *ifa;
2151 struct in6_ifaddr *ia;
2152 int dad_delay; /* delay ticks before DAD output */
2153
2154 /*
2155 * special cases, like 6to4, are handled in in6_ifattach
2156 */
2157 in6_ifattach(ifp, NULL);
2158
2159 dad_delay = 0;
2160 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
2161 {
2162 if (ifa->ifa_addr->sa_family != AF_INET6)
2163 continue;
2164 ia = (struct in6_ifaddr *)ifa;
2165 if (ia->ia6_flags & IN6_IFF_TENTATIVE)
2166 nd6_dad_start(ifa, &dad_delay);
2167 }
2168 }
2169
2170 /*
2171 * Calculate max IPv6 MTU through all the interfaces and store it
2172 * to in6_maxmtu.
2173 */
2174 void
2175 in6_setmaxmtu()
2176 {
2177 unsigned long maxmtu = 0;
2178 struct ifnet *ifp;
2179
2180 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
2181 {
2182 if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
2183 nd_ifinfo[ifp->if_index].linkmtu > maxmtu)
2184 maxmtu = nd_ifinfo[ifp->if_index].linkmtu;
2185 }
2186 if (maxmtu) /* update only when maxmtu is positive */
2187 in6_maxmtu = maxmtu;
2188 }
2189