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