FreeBSD/Linux Kernel Cross Reference
sys/bsd/netinet6/in6.c
1 /* $FreeBSD: src/sys/netinet6/in6.c,v 1.7.2.7 2001/08/06 20:26:22 ume Exp $ */
2 /* $KAME: in6.c,v 1.187 2001/05/24 07:43:59 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
69 #include <sys/param.h>
70 #include <sys/ioctl.h>
71 #include <sys/errno.h>
72 #include <sys/malloc.h>
73 #include <sys/socket.h>
74 #include <sys/socketvar.h>
75 #include <sys/sockio.h>
76 #include <sys/systm.h>
77 #include <sys/time.h>
78 #include <sys/kernel.h>
79 #include <sys/syslog.h>
80 #include <sys/kern_event.h>
81
82 #include <net/if.h>
83 #include <net/if_types.h>
84 #include <net/route.h>
85 #include <net/if_dl.h>
86
87 #include <netinet/in.h>
88 #include <netinet/in_var.h>
89 #include <netinet/if_ether.h>
90 #ifndef SCOPEDROUTING
91 #include <netinet/in_systm.h>
92 #include <netinet/ip.h>
93 #include <netinet/in_pcb.h>
94 #endif
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 #include <netinet6/scope6_var.h>
103 #ifndef SCOPEDROUTING
104 #include <netinet6/in6_pcb.h>
105 #endif
106
107 #include <net/net_osdep.h>
108
109 #ifndef __APPLE__
110 MALLOC_DEFINE(M_IPMADDR, "in6_multi", "internet multicast address");
111 #endif
112 /*
113 * Definitions of some costant IP6 addresses.
114 */
115 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
116 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
117 const struct in6_addr in6addr_nodelocal_allnodes =
118 IN6ADDR_NODELOCAL_ALLNODES_INIT;
119 const struct in6_addr in6addr_linklocal_allnodes =
120 IN6ADDR_LINKLOCAL_ALLNODES_INIT;
121 const struct in6_addr in6addr_linklocal_allrouters =
122 IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
123
124 const struct in6_addr in6mask0 = IN6MASK0;
125 const struct in6_addr in6mask32 = IN6MASK32;
126 const struct in6_addr in6mask64 = IN6MASK64;
127 const struct in6_addr in6mask96 = IN6MASK96;
128 const struct in6_addr in6mask128 = IN6MASK128;
129
130 const struct sockaddr_in6 sa6_any = {sizeof(sa6_any), AF_INET6,
131 0, 0, IN6ADDR_ANY_INIT, 0};
132
133 static int in6_lifaddr_ioctl __P((struct socket *, u_long, caddr_t,
134 struct ifnet *, struct proc *));
135 static int in6_ifinit __P((struct ifnet *, struct in6_ifaddr *,
136 struct sockaddr_in6 *, int));
137 static void in6_unlink_ifa __P((struct in6_ifaddr *, struct ifnet *));
138
139 struct in6_multihead in6_multihead; /* XXX BSS initialization */
140
141 /*
142 * Subroutine for in6_ifaddloop() and in6_ifremloop().
143 * This routine does actual work.
144 */
145 static void
146 in6_ifloop_request(int cmd, struct ifaddr *ifa)
147 {
148 struct sockaddr_in6 all1_sa;
149 struct rtentry *nrt = NULL;
150 int e;
151
152 bzero(&all1_sa, sizeof(all1_sa));
153 all1_sa.sin6_family = AF_INET6;
154 all1_sa.sin6_len = sizeof(struct sockaddr_in6);
155 all1_sa.sin6_addr = in6mask128;
156
157 /*
158 * We specify the address itself as the gateway, and set the
159 * RTF_LLINFO flag, so that the corresponding host route would have
160 * the flag, and thus applications that assume traditional behavior
161 * would be happy. Note that we assume the caller of the function
162 * (probably implicitly) set nd6_rtrequest() to ifa->ifa_rtrequest,
163 * which changes the outgoing interface to the loopback interface.
164 */
165 e = rtrequest(cmd, ifa->ifa_addr, ifa->ifa_addr,
166 (struct sockaddr *)&all1_sa,
167 RTF_UP|RTF_HOST|RTF_LLINFO, &nrt);
168 if (e != 0) {
169 log(LOG_ERR, "in6_ifloop_request: "
170 "%s operation failed for %s (errno=%d)\n",
171 cmd == RTM_ADD ? "ADD" : "DELETE",
172 ip6_sprintf(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr),
173 e);
174 }
175
176 /*
177 * Make sure rt_ifa be equal to IFA, the second argument of the
178 * function.
179 * We need this because when we refer to rt_ifa->ia6_flags in
180 * ip6_input, we assume that the rt_ifa points to the address instead
181 * of the loopback address.
182 */
183 if (cmd == RTM_ADD && nrt && ifa != nrt->rt_ifa) {
184 rtsetifa(nrt, ifa);
185 }
186
187 /*
188 * Report the addition/removal of the address to the routing socket.
189 * XXX: since we called rtinit for a p2p interface with a destination,
190 * we end up reporting twice in such a case. Should we rather
191 * omit the second report?
192 */
193 if (nrt) {
194 rt_newaddrmsg(cmd, ifa, e, nrt);
195 if (cmd == RTM_DELETE) {
196 if (nrt->rt_refcnt <= 0) {
197 /* XXX: we should free the entry ourselves. */
198 rtref(nrt);
199 rtfree(nrt);
200 }
201 } else {
202 /* the cmd must be RTM_ADD here */
203 rtunref(nrt);
204 }
205 }
206 }
207
208 /*
209 * Add ownaddr as loopback rtentry. We previously add the route only if
210 * necessary (ex. on a p2p link). However, since we now manage addresses
211 * separately from prefixes, we should always add the route. We can't
212 * rely on the cloning mechanism from the corresponding interface route
213 * any more.
214 */
215 static void
216 in6_ifaddloop(struct ifaddr *ifa)
217 {
218 struct rtentry *rt;
219
220 /* If there is no loopback entry, allocate one. */
221 rt = rtalloc1(ifa->ifa_addr, 0, 0);
222 if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 ||
223 (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0)
224 in6_ifloop_request(RTM_ADD, ifa);
225 if (rt)
226 rt->rt_refcnt--;
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 struct in6_ifaddr *ia;
237 struct rtentry *rt;
238 int ia_count = 0;
239
240 /*
241 * Some of BSD variants do not remove cloned routes
242 * from an interface direct route, when removing the direct route
243 * (see comments in net/net_osdep.h). Even for variants that do remove
244 * cloned routes, they could fail to remove the cloned routes when
245 * we handle multple addresses that share a common prefix.
246 * So, we should remove the route corresponding to the deleted address
247 * regardless of the result of in6_is_ifloop_auto().
248 */
249
250 /*
251 * Delete the entry only if exact one ifa exists. More than one ifa
252 * can exist if we assign a same single address to multiple
253 * (probably p2p) interfaces.
254 * XXX: we should avoid such a configuration in IPv6...
255 */
256 for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
257 if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ia->ia_addr.sin6_addr)) {
258 ia_count++;
259 if (ia_count > 1)
260 break;
261 }
262 }
263
264 if (ia_count == 1) {
265 /*
266 * Before deleting, check if a corresponding loopbacked host
267 * route surely exists. With this check, we can avoid to
268 * delete an interface direct route whose destination is same
269 * as the address being removed. This can happen when remofing
270 * a subnet-router anycast address on an interface attahced
271 * to a shared medium.
272 */
273 rt = rtalloc1(ifa->ifa_addr, 0, 0);
274 if (rt != NULL && (rt->rt_flags & RTF_HOST) != 0 &&
275 (rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
276 rt->rt_refcnt--;
277 in6_ifloop_request(RTM_DELETE, ifa);
278 }
279 }
280 }
281
282 int
283 in6_ifindex2scopeid(idx)
284 int idx;
285 {
286 struct ifnet *ifp;
287 struct ifaddr *ifa;
288 struct sockaddr_in6 *sin6;
289
290 if (idx < 0 || if_index < idx)
291 return -1;
292 ifp = ifindex2ifnet[idx];
293
294 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
295 {
296 if (ifa->ifa_addr->sa_family != AF_INET6)
297 continue;
298 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
299 if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
300 return sin6->sin6_scope_id & 0xffff;
301 }
302
303 return -1;
304 }
305
306 int
307 in6_mask2len(mask, lim0)
308 struct in6_addr *mask;
309 u_char *lim0;
310 {
311 int x = 0, y;
312 u_char *lim = lim0, *p;
313
314 if (lim0 == NULL ||
315 lim0 - (u_char *)mask > sizeof(*mask)) /* ignore the scope_id part */
316 lim = (u_char *)mask + sizeof(*mask);
317 for (p = (u_char *)mask; p < lim; x++, p++) {
318 if (*p != 0xff)
319 break;
320 }
321 y = 0;
322 if (p < lim) {
323 for (y = 0; y < 8; y++) {
324 if ((*p & (0x80 >> y)) == 0)
325 break;
326 }
327 }
328
329 /*
330 * when the limit pointer is given, do a stricter check on the
331 * remaining bits.
332 */
333 if (p < lim) {
334 if (y != 0 && (*p & (0x00ff >> y)) != 0)
335 return(-1);
336 for (p = p + 1; p < lim; p++)
337 if (*p != 0)
338 return(-1);
339 }
340
341 return x * 8 + y;
342 }
343
344 void
345 in6_len2mask(mask, len)
346 struct in6_addr *mask;
347 int len;
348 {
349 int i;
350
351 bzero(mask, sizeof(*mask));
352 for (i = 0; i < len / 8; i++)
353 mask->s6_addr8[i] = 0xff;
354 if (len % 8)
355 mask->s6_addr8[i] = (0xff00 >> (len % 8)) & 0xff;
356 }
357
358 #define ifa2ia6(ifa) ((struct in6_ifaddr *)(ifa))
359 #define ia62ifa(ia6) (&((ia6)->ia_ifa))
360
361 int
362 in6_control(so, cmd, data, ifp, p)
363 struct socket *so;
364 u_long cmd;
365 caddr_t data;
366 struct ifnet *ifp;
367 struct proc *p;
368 {
369 struct in6_ifreq *ifr = (struct in6_ifreq *)data;
370 struct in6_ifaddr *ia = NULL;
371 struct in6_aliasreq *ifra = (struct in6_aliasreq *)data;
372 int privileged, error = 0;
373 u_long dl_tag;
374
375 privileged = 0;
376 #ifdef __APPLE__
377 if (p == NULL || !suser(p->p_ucred, &p->p_acflag))
378 #else
379 if (p == NULL || !suser(p))
380 #endif
381 privileged++;
382
383 switch (cmd) {
384 case SIOCGETSGCNT_IN6:
385 case SIOCGETMIFCNT_IN6:
386 return (mrt6_ioctl(cmd, data));
387 }
388
389 if (ifp == NULL)
390 return(EOPNOTSUPP);
391
392 switch (cmd) {
393 case SIOCSNDFLUSH_IN6:
394 case SIOCSPFXFLUSH_IN6:
395 case SIOCSRTRFLUSH_IN6:
396 case SIOCSDEFIFACE_IN6:
397 case SIOCSIFINFO_FLAGS:
398 if (!privileged)
399 return(EPERM);
400 /* fall through */
401 case OSIOCGIFINFO_IN6:
402 case SIOCGIFINFO_IN6:
403 case SIOCGDRLST_IN6:
404 case SIOCGPRLST_IN6:
405 case SIOCGNBRINFO_IN6:
406 case SIOCGDEFIFACE_IN6:
407 return(nd6_ioctl(cmd, data, ifp));
408 }
409
410 switch (cmd) {
411 case SIOCSIFPREFIX_IN6:
412 case SIOCDIFPREFIX_IN6:
413 case SIOCAIFPREFIX_IN6:
414 case SIOCCIFPREFIX_IN6:
415 case SIOCSGIFPREFIX_IN6:
416 case SIOCGIFPREFIX_IN6:
417 log(LOG_NOTICE,
418 "prefix ioctls are now invalidated. "
419 "please use ifconfig.\n");
420 return(EOPNOTSUPP);
421 }
422
423 switch (cmd) {
424 case SIOCSSCOPE6:
425 if (!privileged)
426 return(EPERM);
427 return(scope6_set(ifp, ifr->ifr_ifru.ifru_scope_id));
428 break;
429 case SIOCGSCOPE6:
430 return(scope6_get(ifp, ifr->ifr_ifru.ifru_scope_id));
431 break;
432 case SIOCGSCOPE6DEF:
433 return(scope6_get_default(ifr->ifr_ifru.ifru_scope_id));
434 break;
435 }
436
437 switch (cmd) {
438 case SIOCALIFADDR:
439 case SIOCDLIFADDR:
440 if (!privileged)
441 return(EPERM);
442 /* fall through */
443 case SIOCGLIFADDR:
444 return in6_lifaddr_ioctl(so, cmd, data, ifp, p);
445 }
446
447 #ifdef __APPLE__
448
449 switch (cmd) {
450
451 case SIOCAUTOCONF_START:
452 ifp->if_eflags |= IFEF_ACCEPT_RTADVD;
453 return (0);
454
455 case SIOCAUTOCONF_STOP:
456 {
457 struct ifaddr *ifa, *nifa = NULL;
458
459 ifp->if_eflags &= ~IFEF_ACCEPT_RTADVD;
460
461 /* nuke prefix list. this may try to remove some of ifaddrs as well */
462 in6_purgeprefix(ifp);
463
464 /* removed autoconfigured address from interface */
465
466 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; ifa = nifa)
467 {
468 nifa = TAILQ_NEXT(ifa, ifa_list);
469 if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET6)
470 continue;
471 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_AUTOCONF)
472 in6_purgeaddr(ifa);
473 }
474 return (0);
475 }
476
477
478 case SIOCLL_START:
479
480 /* NOTE: All the interface specific DLIL attachements should be done here
481 * They are currently done in in6_ifattach() for the interfaces that need it
482 */
483
484 if (ifp->if_type == IFT_PPP && ifra->ifra_addr.sin6_family == AF_INET6 &&
485 ifra->ifra_dstaddr.sin6_family == AF_INET6)
486 in6_if_up(ifp, ifra); /* PPP may provide LinkLocal addresses */
487 else
488 in6_if_up(ifp, 0);
489
490 return(0);
491
492 case SIOCLL_STOP:
493 {
494 struct ifaddr *ifa, *nifa = NULL;
495
496 /* removed link local addresses from interface */
497
498 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; ifa = nifa)
499 {
500 nifa = TAILQ_NEXT(ifa, ifa_list);
501 if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET6)
502 continue;
503 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa)))
504 in6_purgeaddr(ifa);
505 }
506 return (0);
507 }
508
509
510 case SIOCPROTOATTACH_IN6:
511
512 switch (ifp->if_type) {
513 #if IFT_BRIDGE /*OpenBSD 2.8*/
514 /* some of the interfaces are inherently not IPv6 capable */
515 case IFT_BRIDGE:
516 return;
517 #endif
518 default:
519
520 if (error = dlil_plumb_protocol(PF_INET6, ifp, &dl_tag))
521 printf("SIOCPROTOATTACH_IN6: %s error=%d\n",
522 if_name(ifp), error);
523 break;
524
525 }
526 return (error);
527
528
529 case SIOCPROTODETACH_IN6:
530
531 in6_purgeif(ifp); /* Cleanup interface routes and addresses */
532
533 if (error = dlil_unplumb_protocol(PF_INET6, ifp))
534 printf("SIOCPROTODETACH_IN6: %s error=%d\n",
535 if_name(ifp), error);
536 return(error);
537
538 }
539 #endif
540 /*
541 * Find address for this interface, if it exists.
542 */
543 if (ifra->ifra_addr.sin6_family == AF_INET6) { /* XXX */
544 struct sockaddr_in6 *sa6 =
545 (struct sockaddr_in6 *)&ifra->ifra_addr;
546
547 if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
548 if (sa6->sin6_addr.s6_addr16[1] == 0) {
549 /* link ID is not embedded by the user */
550 sa6->sin6_addr.s6_addr16[1] =
551 htons(ifp->if_index);
552 } else if (sa6->sin6_addr.s6_addr16[1] !=
553 htons(ifp->if_index)) {
554 return(EINVAL); /* link ID contradicts */
555 }
556 if (sa6->sin6_scope_id) {
557 if (sa6->sin6_scope_id !=
558 (u_int32_t)ifp->if_index)
559 return(EINVAL);
560 sa6->sin6_scope_id = 0; /* XXX: good way? */
561 }
562 }
563 ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr);
564 }
565
566 switch (cmd) {
567 case SIOCSIFADDR_IN6:
568 case SIOCSIFDSTADDR_IN6:
569 case SIOCSIFNETMASK_IN6:
570 /*
571 * Since IPv6 allows a node to assign multiple addresses
572 * on a single interface, SIOCSIFxxx ioctls are not suitable
573 * and should be unused.
574 */
575 /* we decided to obsolete this command (20000704) */
576 return(EINVAL);
577
578 case SIOCDIFADDR_IN6:
579 /*
580 * for IPv4, we look for existing in_ifaddr here to allow
581 * "ifconfig if0 delete" to remove first IPv4 address on the
582 * interface. For IPv6, as the spec allow multiple interface
583 * address from the day one, we consider "remove the first one"
584 * semantics to be not preferable.
585 */
586 if (ia == NULL)
587 return(EADDRNOTAVAIL);
588 /* FALLTHROUGH */
589 case SIOCAIFADDR_IN6:
590 /*
591 * We always require users to specify a valid IPv6 address for
592 * the corresponding operation.
593 */
594 if (ifra->ifra_addr.sin6_family != AF_INET6 ||
595 ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6))
596 return(EAFNOSUPPORT);
597 if (!privileged)
598 return(EPERM);
599
600 break;
601
602 case SIOCGIFADDR_IN6:
603 /* This interface is basically deprecated. use SIOCGIFCONF. */
604 /* fall through */
605 case SIOCGIFAFLAG_IN6:
606 case SIOCGIFNETMASK_IN6:
607 case SIOCGIFDSTADDR_IN6:
608 case SIOCGIFALIFETIME_IN6:
609 /* must think again about its semantics */
610 if (ia == NULL)
611 return(EADDRNOTAVAIL);
612 break;
613 case SIOCSIFALIFETIME_IN6:
614 {
615 struct in6_addrlifetime *lt;
616
617 if (!privileged)
618 return(EPERM);
619 if (ia == NULL)
620 return(EADDRNOTAVAIL);
621 /* sanity for overflow - beware unsigned */
622 lt = &ifr->ifr_ifru.ifru_lifetime;
623 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
624 && lt->ia6t_vltime + time_second < time_second) {
625 return EINVAL;
626 }
627 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
628 && lt->ia6t_pltime + time_second < time_second) {
629 return EINVAL;
630 }
631 break;
632 }
633 }
634
635 switch (cmd) {
636
637 case SIOCGIFADDR_IN6:
638 ifr->ifr_addr = ia->ia_addr;
639 break;
640
641 case SIOCGIFDSTADDR_IN6:
642 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
643 return(EINVAL);
644 /*
645 * XXX: should we check if ifa_dstaddr is NULL and return
646 * an error?
647 */
648 ifr->ifr_dstaddr = ia->ia_dstaddr;
649 break;
650
651 case SIOCGIFNETMASK_IN6:
652 ifr->ifr_addr = ia->ia_prefixmask;
653 break;
654
655 case SIOCGIFAFLAG_IN6:
656 ifr->ifr_ifru.ifru_flags6 = ia->ia6_flags;
657 break;
658
659 case SIOCGIFSTAT_IN6:
660 if (ifp == NULL)
661 return EINVAL;
662 if (in6_ifstat == NULL || ifp->if_index >= in6_ifstatmax
663 || in6_ifstat[ifp->if_index] == NULL) {
664 /* return EAFNOSUPPORT? */
665 bzero(&ifr->ifr_ifru.ifru_stat,
666 sizeof(ifr->ifr_ifru.ifru_stat));
667 } else
668 ifr->ifr_ifru.ifru_stat = *in6_ifstat[ifp->if_index];
669 break;
670
671 case SIOCGIFSTAT_ICMP6:
672 if (ifp == NULL)
673 return EINVAL;
674 if (icmp6_ifstat == NULL || ifp->if_index >= icmp6_ifstatmax ||
675 icmp6_ifstat[ifp->if_index] == NULL) {
676 /* return EAFNOSUPPORT? */
677 bzero(&ifr->ifr_ifru.ifru_stat,
678 sizeof(ifr->ifr_ifru.ifru_icmp6stat));
679 } else
680 ifr->ifr_ifru.ifru_icmp6stat =
681 *icmp6_ifstat[ifp->if_index];
682 break;
683
684 case SIOCGIFALIFETIME_IN6:
685 ifr->ifr_ifru.ifru_lifetime = ia->ia6_lifetime;
686 break;
687
688 case SIOCSIFALIFETIME_IN6:
689 ia->ia6_lifetime = ifr->ifr_ifru.ifru_lifetime;
690 /* for sanity */
691 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
692 ia->ia6_lifetime.ia6t_expire =
693 time_second + ia->ia6_lifetime.ia6t_vltime;
694 } else
695 ia->ia6_lifetime.ia6t_expire = 0;
696 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
697 ia->ia6_lifetime.ia6t_preferred =
698 time_second + ia->ia6_lifetime.ia6t_pltime;
699 } else
700 ia->ia6_lifetime.ia6t_preferred = 0;
701 break;
702
703 case SIOCAIFADDR_IN6:
704 {
705 int i, error = 0;
706 struct nd_prefix pr0, *pr;
707
708 if (dlil_find_dltag(ifp->if_family, ifp->if_unit, PF_INET6, &dl_tag) == EPROTONOSUPPORT) {
709 /* Address is added without previous IPv6 configurator support (gif, stf etc...) */
710 if (error = dlil_plumb_protocol(PF_INET6, ifp, &dl_tag)) {
711 printf("SIOCAIFADDR_IN6: %s can't plumb protocol error=%d\n",
712 if_name(ifp), error);
713 return (error);
714 }
715 in6_if_up(ifp, NULL);
716 }
717
718
719 /*
720 * first, make or update the interface address structure,
721 * and link it to the list.
722 */
723 if ((error = in6_update_ifa(ifp, ifra, ia)) != 0)
724 return(error);
725
726 /*
727 * then, make the prefix on-link on the interface.
728 * XXX: we'd rather create the prefix before the address, but
729 * we need at least one address to install the corresponding
730 * interface route, so we configure the address first.
731 */
732
733 /*
734 * convert mask to prefix length (prefixmask has already
735 * been validated in in6_update_ifa().
736 */
737 bzero(&pr0, sizeof(pr0));
738 pr0.ndpr_ifp = ifp;
739 pr0.ndpr_plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
740 NULL);
741 if (pr0.ndpr_plen == 128)
742 break; /* we don't need to install a host route. */
743 pr0.ndpr_prefix = ifra->ifra_addr;
744 pr0.ndpr_mask = ifra->ifra_prefixmask.sin6_addr;
745 /* apply the mask for safety. */
746 for (i = 0; i < 4; i++) {
747 pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
748 ifra->ifra_prefixmask.sin6_addr.s6_addr32[i];
749 }
750 /*
751 * XXX: since we don't have an API to set prefix (not address)
752 * lifetimes, we just use the same lifetimes as addresses.
753 * The (temporarily) installed lifetimes can be overridden by
754 * later advertised RAs (when accept_rtadv is non 0), which is
755 * an intended behavior.
756 */
757 pr0.ndpr_raf_onlink = 1; /* should be configurable? */
758 pr0.ndpr_raf_auto =
759 ((ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0);
760 pr0.ndpr_vltime = ifra->ifra_lifetime.ia6t_vltime;
761 pr0.ndpr_pltime = ifra->ifra_lifetime.ia6t_pltime;
762
763 /* add the prefix if there's one. */
764 if ((pr = nd6_prefix_lookup(&pr0)) == NULL) {
765 /*
766 * nd6_prelist_add will install the corresponding
767 * interface route.
768 */
769 if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0)
770 return(error);
771 if (pr == NULL) {
772 log(LOG_ERR, "nd6_prelist_add succedded but "
773 "no prefix\n");
774 return(EINVAL); /* XXX panic here? */
775 }
776 }
777 if ((ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr))
778 == NULL) {
779 /* XXX: this should not happen! */
780 log(LOG_ERR, "in6_control: addition succeeded, but"
781 " no ifaddr\n");
782 } else {
783 if ((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0 &&
784 ia->ia6_ndpr == NULL) { /* new autoconfed addr */
785 ia->ia6_ndpr = pr;
786 pr->ndpr_refcnt++;
787
788 /*
789 * If this is the first autoconf address from
790 * the prefix, create a temporary address
791 * as well (when specified).
792 */
793 if (ip6_use_tempaddr &&
794 pr->ndpr_refcnt == 1) {
795 int e;
796 if ((e = in6_tmpifadd(ia, 1)) != 0) {
797 log(LOG_NOTICE, "in6_control: "
798 "failed to create a "
799 "temporary address, "
800 "errno=%d\n",
801 e);
802 }
803 }
804 }
805
806 /*
807 * this might affect the status of autoconfigured
808 * addresses, that is, this address might make
809 * other addresses detached.
810 */
811 pfxlist_onlink_check();
812 in6_post_msg(ifp, KEV_INET6_NEW_USER_ADDR, ia);
813 }
814
815 break;
816 }
817
818 case SIOCDIFADDR_IN6:
819 {
820 int i = 0;
821 struct nd_prefix pr0, *pr;
822
823 /*
824 * If the address being deleted is the only one that owns
825 * the corresponding prefix, expire the prefix as well.
826 * XXX: theoretically, we don't have to warry about such
827 * relationship, since we separate the address management
828 * and the prefix management. We do this, however, to provide
829 * as much backward compatibility as possible in terms of
830 * the ioctl operation.
831 */
832 bzero(&pr0, sizeof(pr0));
833 pr0.ndpr_ifp = ifp;
834 pr0.ndpr_plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr,
835 NULL);
836 if (pr0.ndpr_plen == 128)
837 goto purgeaddr;
838 pr0.ndpr_prefix = ia->ia_addr;
839 pr0.ndpr_mask = ia->ia_prefixmask.sin6_addr;
840 for (i = 0; i < 4; i++) {
841 pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
842 ia->ia_prefixmask.sin6_addr.s6_addr32[i];
843 }
844 /*
845 * The logic of the following condition is a bit complicated.
846 * We expire the prefix when
847 * 1. the address obeys autoconfiguration and it is the
848 * only owner of the associated prefix, or
849 * 2. the address does not obey autoconf and there is no
850 * other owner of the prefix.
851 */
852 if ((pr = nd6_prefix_lookup(&pr0)) != NULL &&
853 (((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0 &&
854 pr->ndpr_refcnt == 1) ||
855 ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0 &&
856 pr->ndpr_refcnt == 0))) {
857 pr->ndpr_expire = 1; /* XXX: just for expiration */
858 }
859
860 purgeaddr:
861 in6_purgeaddr(&ia->ia_ifa);
862 break;
863 }
864
865 default:
866 #ifdef __APPLE__
867 error = dlil_ioctl(PF_INET6, ifp, cmd, (caddr_t)data);
868 return error;
869
870 #else
871 if (ifp == NULL || ifp->if_ioctl == 0)
872 return(EOPNOTSUPP);
873 return((*ifp->if_ioctl)(ifp, cmd, data));
874 #endif
875 }
876
877 return(0);
878 }
879
880 /*
881 * Update parameters of an IPv6 interface address.
882 * If necessary, a new entry is created and linked into address chains.
883 * This function is separated from in6_control().
884 * XXX: should this be performed under splnet()?
885 */
886 int
887 in6_update_ifa(ifp, ifra, ia)
888 struct ifnet *ifp;
889 struct in6_aliasreq *ifra;
890 struct in6_ifaddr *ia;
891 {
892 int error = 0, hostIsNew = 0, plen = -1;
893 struct in6_ifaddr *oia;
894 struct sockaddr_in6 dst6;
895 struct in6_addrlifetime *lt;
896
897 /* Validate parameters */
898 if (ifp == NULL || ifra == NULL) /* this maybe redundant */
899 return(EINVAL);
900
901 /*
902 * The destination address for a p2p link must have a family
903 * of AF_UNSPEC or AF_INET6.
904 */
905 if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
906 ifra->ifra_dstaddr.sin6_family != AF_INET6 &&
907 ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
908 return(EAFNOSUPPORT);
909 /*
910 * validate ifra_prefixmask. don't check sin6_family, netmask
911 * does not carry fields other than sin6_len.
912 */
913 if (ifra->ifra_prefixmask.sin6_len > sizeof(struct sockaddr_in6))
914 return(EINVAL);
915 /*
916 * Because the IPv6 address architecture is classless, we require
917 * users to specify a (non 0) prefix length (mask) for a new address.
918 * We also require the prefix (when specified) mask is valid, and thus
919 * reject a non-consecutive mask.
920 */
921 if (ia == NULL && ifra->ifra_prefixmask.sin6_len == 0)
922 return(EINVAL);
923 if (ifra->ifra_prefixmask.sin6_len != 0) {
924 plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
925 (u_char *)&ifra->ifra_prefixmask +
926 ifra->ifra_prefixmask.sin6_len);
927 if (plen <= 0)
928 return(EINVAL);
929 }
930 else {
931 /*
932 * In this case, ia must not be NULL. We just use its prefix
933 * length.
934 */
935 plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
936 }
937 /*
938 * If the destination address on a p2p interface is specified,
939 * and the address is a scoped one, validate/set the scope
940 * zone identifier.
941 */
942 dst6 = ifra->ifra_dstaddr;
943 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) &&
944 (dst6.sin6_family == AF_INET6)) {
945 int scopeid;
946
947 #ifndef SCOPEDROUTING
948 if ((error = in6_recoverscope(&dst6,
949 &ifra->ifra_dstaddr.sin6_addr,
950 ifp)) != 0)
951 return(error);
952 #endif
953 scopeid = in6_addr2scopeid(ifp, &dst6.sin6_addr);
954 if (dst6.sin6_scope_id == 0) /* user omit to specify the ID. */
955 dst6.sin6_scope_id = scopeid;
956 else if (dst6.sin6_scope_id != scopeid)
957 return(EINVAL); /* scope ID mismatch. */
958 #ifndef SCOPEDROUTING
959 if ((error = in6_embedscope(&dst6.sin6_addr, &dst6, NULL, NULL))
960 != 0)
961 return(error);
962 dst6.sin6_scope_id = 0; /* XXX */
963 #endif
964 }
965 /*
966 * The destination address can be specified only for a p2p or a
967 * loopback interface. If specified, the corresponding prefix length
968 * must be 128.
969 */
970 if (ifra->ifra_dstaddr.sin6_family == AF_INET6) {
971 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0) {
972 /* XXX: noisy message */
973 log(LOG_INFO, "in6_update_ifa: a destination can be "
974 "specified for a p2p or a loopback IF only\n");
975 return(EINVAL);
976 }
977 if (plen != 128) {
978 /*
979 * The following message seems noisy, but we dare to
980 * add it for diagnosis.
981 */
982 log(LOG_INFO, "in6_update_ifa: prefixlen must be 128 "
983 "when dstaddr is specified\n");
984 return(EINVAL);
985 }
986 }
987 /* lifetime consistency check */
988 lt = &ifra->ifra_lifetime;
989 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
990 && lt->ia6t_vltime + time_second < time_second) {
991 return EINVAL;
992 }
993 if (lt->ia6t_vltime == 0) {
994 /*
995 * the following log might be noisy, but this is a typical
996 * configuration mistake or a tool's bug.
997 */
998 log(LOG_INFO,
999 "in6_update_ifa: valid lifetime is 0 for %s\n",
1000 ip6_sprintf(&ifra->ifra_addr.sin6_addr));
1001 }
1002 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
1003 && lt->ia6t_pltime + time_second < time_second) {
1004 return EINVAL;
1005 }
1006
1007 /*
1008 * If this is a new address, allocate a new ifaddr and link it
1009 * into chains.
1010 */
1011 if (ia == NULL) {
1012 hostIsNew = 1;
1013 /*
1014 * When in6_update_ifa() is called in a process of a received
1015 * RA, it is called under splnet(). So, we should call malloc
1016 * with M_NOWAIT.
1017 */
1018 ia = (struct in6_ifaddr *)
1019 _MALLOC(sizeof(*ia), M_IFADDR, M_NOWAIT);
1020 if (ia == NULL)
1021 return (ENOBUFS);
1022 bzero((caddr_t)ia, sizeof(*ia));
1023 /* Initialize the address and masks */
1024 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
1025 ia->ia_addr.sin6_family = AF_INET6;
1026 ia->ia_addr.sin6_len = sizeof(ia->ia_addr);
1027 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
1028 /*
1029 * XXX: some functions expect that ifa_dstaddr is not
1030 * NULL for p2p interfaces.
1031 */
1032 ia->ia_ifa.ifa_dstaddr
1033 = (struct sockaddr *)&ia->ia_dstaddr;
1034 } else {
1035 ia->ia_ifa.ifa_dstaddr = NULL;
1036 }
1037 ia->ia_ifa.ifa_netmask
1038 = (struct sockaddr *)&ia->ia_prefixmask;
1039
1040 ia->ia_ifp = ifp;
1041 if ((oia = in6_ifaddr) != NULL) {
1042 for ( ; oia->ia_next; oia = oia->ia_next)
1043 continue;
1044 oia->ia_next = ia;
1045 } else
1046 in6_ifaddr = ia;
1047
1048 TAILQ_INSERT_TAIL(&ifp->if_addrlist, &ia->ia_ifa,
1049 ifa_list);
1050 }
1051
1052 /* set prefix mask */
1053 if (ifra->ifra_prefixmask.sin6_len) {
1054 /*
1055 * We prohibit changing the prefix length of an existing
1056 * address, because
1057 * + such an operation should be rare in IPv6, and
1058 * + the operation would confuse prefix management.
1059 */
1060 if (ia->ia_prefixmask.sin6_len &&
1061 in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL) != plen) {
1062 log(LOG_INFO, "in6_update_ifa: the prefix length of an"
1063 " existing (%s) address should not be changed\n",
1064 ip6_sprintf(&ia->ia_addr.sin6_addr));
1065 error = EINVAL;
1066 goto unlink;
1067 }
1068 ia->ia_prefixmask = ifra->ifra_prefixmask;
1069 }
1070
1071 /*
1072 * If a new destination address is specified, scrub the old one and
1073 * install the new destination. Note that the interface must be
1074 * p2p or loopback (see the check above.)
1075 */
1076 if (dst6.sin6_family == AF_INET6 &&
1077 !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr,
1078 &ia->ia_dstaddr.sin6_addr)) {
1079 int e;
1080
1081 if ((ia->ia_flags & IFA_ROUTE) != 0 &&
1082 (e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST))
1083 != 0) {
1084 log(LOG_ERR, "in6_update_ifa: failed to remove "
1085 "a route to the old destination: %s\n",
1086 ip6_sprintf(&ia->ia_addr.sin6_addr));
1087 /* proceed anyway... */
1088 }
1089 else
1090 ia->ia_flags &= ~IFA_ROUTE;
1091 ia->ia_dstaddr = dst6;
1092 }
1093
1094 /* reset the interface and routing table appropriately. */
1095 if ((error = in6_ifinit(ifp, ia, &ifra->ifra_addr, hostIsNew)) != 0)
1096 goto unlink;
1097
1098 /*
1099 * Beyond this point, we should call in6_purgeaddr upon an error,
1100 * not just go to unlink.
1101 */
1102
1103 #if 0 /* disable this mechanism for now */
1104 /* update prefix list */
1105 if (hostIsNew &&
1106 (ifra->ifra_flags & IN6_IFF_NOPFX) == 0) { /* XXX */
1107 int iilen;
1108
1109 iilen = (sizeof(ia->ia_prefixmask.sin6_addr) << 3) - plen;
1110 if ((error = in6_prefix_add_ifid(iilen, ia)) != 0) {
1111 in6_purgeaddr((struct ifaddr *)ia);
1112 return(error);
1113 }
1114 }
1115 #endif
1116
1117 if ((ifp->if_flags & IFF_MULTICAST) != 0) {
1118 struct sockaddr_in6 mltaddr, mltmask;
1119 struct in6_multi *in6m;
1120
1121 if (hostIsNew) {
1122 /*
1123 * join solicited multicast addr for new host id
1124 */
1125 struct in6_addr llsol;
1126 bzero(&llsol, sizeof(struct in6_addr));
1127 llsol.s6_addr16[0] = htons(0xff02);
1128 llsol.s6_addr16[1] = htons(ifp->if_index);
1129 llsol.s6_addr32[1] = 0;
1130 llsol.s6_addr32[2] = htonl(1);
1131 llsol.s6_addr32[3] =
1132 ifra->ifra_addr.sin6_addr.s6_addr32[3];
1133 llsol.s6_addr8[12] = 0xff;
1134 (void)in6_addmulti(&llsol, ifp, &error);
1135 if (error != 0) {
1136 log(LOG_WARNING,
1137 "in6_update_ifa: addmulti failed for "
1138 "%s on %s (errno=%d)\n",
1139 ip6_sprintf(&llsol), if_name(ifp),
1140 error);
1141 in6_purgeaddr((struct ifaddr *)ia);
1142 return(error);
1143 }
1144 }
1145
1146 bzero(&mltmask, sizeof(mltmask));
1147 mltmask.sin6_len = sizeof(struct sockaddr_in6);
1148 mltmask.sin6_family = AF_INET6;
1149 mltmask.sin6_addr = in6mask32;
1150
1151 /*
1152 * join link-local all-nodes address
1153 */
1154 bzero(&mltaddr, sizeof(mltaddr));
1155 mltaddr.sin6_len = sizeof(struct sockaddr_in6);
1156 mltaddr.sin6_family = AF_INET6;
1157 mltaddr.sin6_addr = in6addr_linklocal_allnodes;
1158 mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
1159
1160 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
1161 if (in6m == NULL) {
1162 rtrequest(RTM_ADD,
1163 (struct sockaddr *)&mltaddr,
1164 (struct sockaddr *)&ia->ia_addr,
1165 (struct sockaddr *)&mltmask,
1166 RTF_UP|RTF_CLONING, /* xxx */
1167 (struct rtentry **)0);
1168 (void)in6_addmulti(&mltaddr.sin6_addr, ifp, &error);
1169 if (error != 0) {
1170 log(LOG_WARNING,
1171 "in6_update_ifa: addmulti failed for "
1172 "%s on %s (errno=%d)\n",
1173 ip6_sprintf(&mltaddr.sin6_addr),
1174 if_name(ifp), error);
1175 }
1176 }
1177
1178 /*
1179 * join node information group address
1180 */
1181 #define hostnamelen strlen(hostname)
1182 if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr.sin6_addr)
1183 == 0) {
1184 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
1185 if (in6m == NULL && ia != NULL) {
1186 (void)in6_addmulti(&mltaddr.sin6_addr,
1187 ifp, &error);
1188 if (error != 0) {
1189 log(LOG_WARNING, "in6_update_ifa: "
1190 "addmulti failed for "
1191 "%s on %s (errno=%d)\n",
1192 ip6_sprintf(&mltaddr.sin6_addr),
1193 if_name(ifp), error);
1194 }
1195 }
1196 }
1197 #undef hostnamelen
1198
1199 /*
1200 * join node-local all-nodes address, on loopback.
1201 * XXX: since "node-local" is obsoleted by interface-local,
1202 * we have to join the group on every interface with
1203 * some interface-boundary restriction.
1204 */
1205 if (ifp->if_flags & IFF_LOOPBACK) {
1206 struct in6_ifaddr *ia_loop;
1207
1208 struct in6_addr loop6 = in6addr_loopback;
1209 ia_loop = in6ifa_ifpwithaddr(ifp, &loop6);
1210
1211 mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
1212
1213 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
1214 if (in6m == NULL && ia_loop != NULL) {
1215 rtrequest(RTM_ADD,
1216 (struct sockaddr *)&mltaddr,
1217 (struct sockaddr *)&ia_loop->ia_addr,
1218 (struct sockaddr *)&mltmask,
1219 RTF_UP,
1220 (struct rtentry **)0);
1221 (void)in6_addmulti(&mltaddr.sin6_addr, ifp,
1222 &error);
1223 if (error != 0) {
1224 log(LOG_WARNING, "in6_update_ifa: "
1225 "addmulti failed for %s on %s "
1226 "(errno=%d)\n",
1227 ip6_sprintf(&mltaddr.sin6_addr),
1228 if_name(ifp), error);
1229 }
1230 }
1231 }
1232 }
1233
1234 ia->ia6_flags = ifra->ifra_flags;
1235 ia->ia6_flags &= ~IN6_IFF_DUPLICATED; /*safety*/
1236 ia->ia6_flags &= ~IN6_IFF_NODAD; /* Mobile IPv6 */
1237
1238 ia->ia6_lifetime = ifra->ifra_lifetime;
1239 /* for sanity */
1240 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
1241 ia->ia6_lifetime.ia6t_expire =
1242 time_second + ia->ia6_lifetime.ia6t_vltime;
1243 } else
1244 ia->ia6_lifetime.ia6t_expire = 0;
1245 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
1246 ia->ia6_lifetime.ia6t_preferred =
1247 time_second + ia->ia6_lifetime.ia6t_pltime;
1248 } else
1249 ia->ia6_lifetime.ia6t_preferred = 0;
1250
1251 /*
1252 * make sure to initialize ND6 information. this is to workaround
1253 * issues with interfaces with IPv6 addresses, which have never brought
1254 * up. We are assuming that it is safe to nd6_ifattach multiple times.
1255 */
1256 nd6_ifattach(ifp);
1257
1258 /*
1259 * Perform DAD, if needed.
1260 * XXX It may be of use, if we can administratively
1261 * disable DAD.
1262 */
1263 if (in6if_do_dad(ifp) && (ifra->ifra_flags & IN6_IFF_NODAD) == 0) {
1264 ia->ia6_flags |= IN6_IFF_TENTATIVE;
1265 nd6_dad_start((struct ifaddr *)ia, NULL);
1266 }
1267
1268 return(error);
1269
1270 unlink:
1271 /*
1272 * XXX: if a change of an existing address failed, keep the entry
1273 * anyway.
1274 */
1275 if (hostIsNew)
1276 in6_unlink_ifa(ia, ifp);
1277 return(error);
1278 }
1279
1280 void
1281 in6_purgeaddr(ifa)
1282 struct ifaddr *ifa;
1283 {
1284 struct ifnet *ifp = ifa->ifa_ifp;
1285 struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
1286
1287 /* stop DAD processing */
1288 nd6_dad_stop(ifa);
1289
1290 /*
1291 * delete route to the destination of the address being purged.
1292 * The interface must be p2p or loopback in this case.
1293 */
1294 if ((ia->ia_flags & IFA_ROUTE) != 0 && ia->ia_dstaddr.sin6_len != 0) {
1295 int e;
1296
1297 if ((e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST))
1298 != 0) {
1299 log(LOG_ERR, "in6_purgeaddr: failed to remove "
1300 "a route to the p2p destination: %s on %s, "
1301 "errno=%d\n",
1302 ip6_sprintf(&ia->ia_addr.sin6_addr), if_name(ifp),
1303 e);
1304 /* proceed anyway... */
1305 }
1306 else
1307 ia->ia_flags &= ~IFA_ROUTE;
1308 }
1309
1310 /* Remove ownaddr's loopback rtentry, if it exists. */
1311 in6_ifremloop(&(ia->ia_ifa));
1312
1313 if (ifp->if_flags & IFF_MULTICAST) {
1314 /*
1315 * delete solicited multicast addr for deleting host id
1316 */
1317 struct in6_multi *in6m;
1318 struct in6_addr llsol;
1319 bzero(&llsol, sizeof(struct in6_addr));
1320 llsol.s6_addr16[0] = htons(0xff02);
1321 llsol.s6_addr16[1] = htons(ifp->if_index);
1322 llsol.s6_addr32[1] = 0;
1323 llsol.s6_addr32[2] = htonl(1);
1324 llsol.s6_addr32[3] =
1325 ia->ia_addr.sin6_addr.s6_addr32[3];
1326 llsol.s6_addr8[12] = 0xff;
1327
1328 IN6_LOOKUP_MULTI(llsol, ifp, in6m);
1329 if (in6m)
1330 in6_delmulti(in6m);
1331 }
1332
1333 in6_post_msg(ifp, KEV_INET6_ADDR_DELETED, ia);
1334 in6_unlink_ifa(ia, ifp);
1335 }
1336
1337 static void
1338 in6_unlink_ifa(ia, ifp)
1339 struct in6_ifaddr *ia;
1340 struct ifnet *ifp;
1341 {
1342 int plen, iilen;
1343 struct in6_ifaddr *oia;
1344 int s = splnet();
1345
1346 TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
1347
1348 oia = ia;
1349 if (oia == (ia = in6_ifaddr))
1350 in6_ifaddr = ia->ia_next;
1351 else {
1352 while (ia->ia_next && (ia->ia_next != oia))
1353 ia = ia->ia_next;
1354 if (ia->ia_next)
1355 ia->ia_next = oia->ia_next;
1356 else {
1357 /* search failed */
1358 printf("Couldn't unlink in6_ifaddr from in6_ifaddr\n");
1359 }
1360 }
1361
1362 if (oia->ia6_ifpr) { /* check for safety */
1363 plen = in6_mask2len(&oia->ia_prefixmask.sin6_addr, NULL);
1364 iilen = (sizeof(oia->ia_prefixmask.sin6_addr) << 3) - plen;
1365 in6_prefix_remove_ifid(iilen, oia);
1366 }
1367
1368 /*
1369 * When an autoconfigured address is being removed, release the
1370 * reference to the base prefix. Also, since the release might
1371 * affect the status of other (detached) addresses, call
1372 * pfxlist_onlink_check().
1373 */
1374 if ((oia->ia6_flags & IN6_IFF_AUTOCONF) != 0) {
1375 if (oia->ia6_ndpr == NULL) {
1376 log(LOG_NOTICE, "in6_unlink_ifa: autoconf'ed address "
1377 "%p has no prefix\n", oia);
1378 } else {
1379 oia->ia6_ndpr->ndpr_refcnt--;
1380 oia->ia6_flags &= ~IN6_IFF_AUTOCONF;
1381 oia->ia6_ndpr = NULL;
1382 }
1383
1384 pfxlist_onlink_check();
1385 }
1386
1387 /*
1388 * release another refcnt for the link from in6_ifaddr.
1389 * Note that we should decrement the refcnt at least once for all *BSD.
1390 */
1391 ifafree(&oia->ia_ifa);
1392
1393 splx(s);
1394 }
1395
1396 void
1397 in6_purgeif(ifp)
1398 struct ifnet *ifp;
1399 {
1400 struct ifaddr *ifa, *nifa = NULL;
1401
1402 if (ifp == NULL || &ifp->if_addrlist == NULL)
1403 return;
1404
1405 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; ifa = nifa)
1406 {
1407 nifa = TAILQ_NEXT(ifa, ifa_list);
1408 if (ifa->ifa_addr == NULL)
1409 continue;
1410 if (ifa->ifa_addr->sa_family != AF_INET6)
1411 continue;
1412 in6_purgeaddr(ifa);
1413 }
1414
1415 in6_ifdetach(ifp);
1416 }
1417
1418 /*
1419 * SIOC[GAD]LIFADDR.
1420 * SIOCGLIFADDR: get first address. (?)
1421 * SIOCGLIFADDR with IFLR_PREFIX:
1422 * get first address that matches the specified prefix.
1423 * SIOCALIFADDR: add the specified address.
1424 * SIOCALIFADDR with IFLR_PREFIX:
1425 * add the specified prefix, filling hostid part from
1426 * the first link-local address. prefixlen must be <= 64.
1427 * SIOCDLIFADDR: delete the specified address.
1428 * SIOCDLIFADDR with IFLR_PREFIX:
1429 * delete the first address that matches the specified prefix.
1430 * return values:
1431 * EINVAL on invalid parameters
1432 * EADDRNOTAVAIL on prefix match failed/specified address not found
1433 * other values may be returned from in6_ioctl()
1434 *
1435 * NOTE: SIOCALIFADDR(with IFLR_PREFIX set) allows prefixlen less than 64.
1436 * this is to accomodate address naming scheme other than RFC2374,
1437 * in the future.
1438 * RFC2373 defines interface id to be 64bit, but it allows non-RFC2374
1439 * address encoding scheme. (see figure on page 8)
1440 */
1441 static int
1442 in6_lifaddr_ioctl(so, cmd, data, ifp, p)
1443 struct socket *so;
1444 u_long cmd;
1445 caddr_t data;
1446 struct ifnet *ifp;
1447 struct proc *p;
1448 {
1449 struct if_laddrreq *iflr = (struct if_laddrreq *)data;
1450 struct ifaddr *ifa;
1451 struct sockaddr *sa;
1452
1453 /* sanity checks */
1454 if (!data || !ifp) {
1455 panic("invalid argument to in6_lifaddr_ioctl");
1456 /*NOTRECHED*/
1457 }
1458
1459 switch (cmd) {
1460 case SIOCGLIFADDR:
1461 /* address must be specified on GET with IFLR_PREFIX */
1462 if ((iflr->flags & IFLR_PREFIX) == 0)
1463 break;
1464 /* FALLTHROUGH */
1465 case SIOCALIFADDR:
1466 case SIOCDLIFADDR:
1467 /* address must be specified on ADD and DELETE */
1468 sa = (struct sockaddr *)&iflr->addr;
1469 if (sa->sa_family != AF_INET6)
1470 return EINVAL;
1471 if (sa->sa_len != sizeof(struct sockaddr_in6))
1472 return EINVAL;
1473 /* XXX need improvement */
1474 sa = (struct sockaddr *)&iflr->dstaddr;
1475 if (sa->sa_family && sa->sa_family != AF_INET6)
1476 return EINVAL;
1477 if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in6))
1478 return EINVAL;
1479 break;
1480 default: /* shouldn't happen */
1481 #if 0
1482 panic("invalid cmd to in6_lifaddr_ioctl");
1483 /* NOTREACHED */
1484 #else
1485 return EOPNOTSUPP;
1486 #endif
1487 }
1488 if (sizeof(struct in6_addr) * 8 < iflr->prefixlen)
1489 return EINVAL;
1490
1491 switch (cmd) {
1492 case SIOCALIFADDR:
1493 {
1494 struct in6_aliasreq ifra;
1495 struct in6_addr *hostid = NULL;
1496 int prefixlen;
1497
1498 if ((iflr->flags & IFLR_PREFIX) != 0) {
1499 struct sockaddr_in6 *sin6;
1500
1501 /*
1502 * hostid is to fill in the hostid part of the
1503 * address. hostid points to the first link-local
1504 * address attached to the interface.
1505 */
1506 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0);
1507 if (!ifa)
1508 return EADDRNOTAVAIL;
1509 hostid = IFA_IN6(ifa);
1510
1511 /* prefixlen must be <= 64. */
1512 if (64 < iflr->prefixlen)
1513 return EINVAL;
1514 prefixlen = iflr->prefixlen;
1515
1516 /* hostid part must be zero. */
1517 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1518 if (sin6->sin6_addr.s6_addr32[2] != 0
1519 || sin6->sin6_addr.s6_addr32[3] != 0) {
1520 return EINVAL;
1521 }
1522 } else
1523 prefixlen = iflr->prefixlen;
1524
1525 /* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
1526 bzero(&ifra, sizeof(ifra));
1527 bcopy(iflr->iflr_name, ifra.ifra_name,
1528 sizeof(ifra.ifra_name));
1529
1530 bcopy(&iflr->addr, &ifra.ifra_addr,
1531 ((struct sockaddr *)&iflr->addr)->sa_len);
1532 if (hostid) {
1533 /* fill in hostid part */
1534 ifra.ifra_addr.sin6_addr.s6_addr32[2] =
1535 hostid->s6_addr32[2];
1536 ifra.ifra_addr.sin6_addr.s6_addr32[3] =
1537 hostid->s6_addr32[3];
1538 }
1539
1540 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /*XXX*/
1541 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
1542 ((struct sockaddr *)&iflr->dstaddr)->sa_len);
1543 if (hostid) {
1544 ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] =
1545 hostid->s6_addr32[2];
1546 ifra.ifra_dstaddr.sin6_addr.s6_addr32[3] =
1547 hostid->s6_addr32[3];
1548 }
1549 }
1550
1551 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
1552 in6_len2mask(&ifra.ifra_prefixmask.sin6_addr, prefixlen);
1553
1554 ifra.ifra_flags = iflr->flags & ~IFLR_PREFIX;
1555 return in6_control(so, SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, p);
1556 }
1557 case SIOCGLIFADDR:
1558 case SIOCDLIFADDR:
1559 {
1560 struct in6_ifaddr *ia;
1561 struct in6_addr mask, candidate, match;
1562 struct sockaddr_in6 *sin6;
1563 int cmp;
1564
1565 bzero(&mask, sizeof(mask));
1566 if (iflr->flags & IFLR_PREFIX) {
1567 /* lookup a prefix rather than address. */
1568 in6_len2mask(&mask, iflr->prefixlen);
1569
1570 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1571 bcopy(&sin6->sin6_addr, &match, sizeof(match));
1572 match.s6_addr32[0] &= mask.s6_addr32[0];
1573 match.s6_addr32[1] &= mask.s6_addr32[1];
1574 match.s6_addr32[2] &= mask.s6_addr32[2];
1575 match.s6_addr32[3] &= mask.s6_addr32[3];
1576
1577 /* if you set extra bits, that's wrong */
1578 if (bcmp(&match, &sin6->sin6_addr, sizeof(match)))
1579 return EINVAL;
1580
1581 cmp = 1;
1582 } else {
1583 if (cmd == SIOCGLIFADDR) {
1584 /* on getting an address, take the 1st match */
1585 cmp = 0; /* XXX */
1586 } else {
1587 /* on deleting an address, do exact match */
1588 in6_len2mask(&mask, 128);
1589 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1590 bcopy(&sin6->sin6_addr, &match, sizeof(match));
1591
1592 cmp = 1;
1593 }
1594 }
1595
1596 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1597 {
1598 if (ifa->ifa_addr->sa_family != AF_INET6)
1599 continue;
1600 if (!cmp)
1601 break;
1602
1603 bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate));
1604 #ifndef SCOPEDROUTING
1605 /*
1606 * XXX: this is adhoc, but is necessary to allow
1607 * a user to specify fe80::/64 (not /10) for a
1608 * link-local address.
1609 */
1610 if (IN6_IS_ADDR_LINKLOCAL(&candidate))
1611 candidate.s6_addr16[1] = 0;
1612 #endif
1613 candidate.s6_addr32[0] &= mask.s6_addr32[0];
1614 candidate.s6_addr32[1] &= mask.s6_addr32[1];
1615 candidate.s6_addr32[2] &= mask.s6_addr32[2];
1616 candidate.s6_addr32[3] &= mask.s6_addr32[3];
1617 if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
1618 break;
1619 }
1620 if (!ifa)
1621 return EADDRNOTAVAIL;
1622 ia = ifa2ia6(ifa);
1623
1624 if (cmd == SIOCGLIFADDR) {
1625 #ifndef SCOPEDROUTING
1626 struct sockaddr_in6 *s6;
1627 #endif
1628
1629 /* fill in the if_laddrreq structure */
1630 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len);
1631 #ifndef SCOPEDROUTING /* XXX see above */
1632 s6 = (struct sockaddr_in6 *)&iflr->addr;
1633 if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) {
1634 s6->sin6_addr.s6_addr16[1] = 0;
1635 s6->sin6_scope_id =
1636 in6_addr2scopeid(ifp, &s6->sin6_addr);
1637 }
1638 #endif
1639 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1640 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
1641 ia->ia_dstaddr.sin6_len);
1642 #ifndef SCOPEDROUTING /* XXX see above */
1643 s6 = (struct sockaddr_in6 *)&iflr->dstaddr;
1644 if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) {
1645 s6->sin6_addr.s6_addr16[1] = 0;
1646 s6->sin6_scope_id =
1647 in6_addr2scopeid(ifp,
1648 &s6->sin6_addr);
1649 }
1650 #endif
1651 } else
1652 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
1653
1654 iflr->prefixlen =
1655 in6_mask2len(&ia->ia_prefixmask.sin6_addr,
1656 NULL);
1657
1658 iflr->flags = ia->ia6_flags; /* XXX */
1659
1660 return 0;
1661 } else {
1662 struct in6_aliasreq ifra;
1663
1664 /* fill in6_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
1665 bzero(&ifra, sizeof(ifra));
1666 bcopy(iflr->iflr_name, ifra.ifra_name,
1667 sizeof(ifra.ifra_name));
1668
1669 bcopy(&ia->ia_addr, &ifra.ifra_addr,
1670 ia->ia_addr.sin6_len);
1671 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1672 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
1673 ia->ia_dstaddr.sin6_len);
1674 } else {
1675 bzero(&ifra.ifra_dstaddr,
1676 sizeof(ifra.ifra_dstaddr));
1677 }
1678 bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr,
1679 ia->ia_prefixmask.sin6_len);
1680
1681 ifra.ifra_flags = ia->ia6_flags;
1682 return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra,
1683 ifp, p);
1684 }
1685 }
1686 }
1687
1688 return EOPNOTSUPP; /* just for safety */
1689 }
1690
1691 /*
1692 * Initialize an interface's intetnet6 address
1693 * and routing table entry.
1694 */
1695 static int
1696 in6_ifinit(ifp, ia, sin6, newhost)
1697 struct ifnet *ifp;
1698 struct in6_ifaddr *ia;
1699 struct sockaddr_in6 *sin6;
1700 int newhost;
1701 {
1702 int error = 0, plen, ifacount = 0;
1703 int s = splimp();
1704 struct ifaddr *ifa;
1705
1706 /*
1707 * Give the interface a chance to initialize
1708 * if this is its first address,
1709 * and to validate the address if necessary.
1710 */
1711 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1712 {
1713 if (ifa->ifa_addr == NULL)
1714 continue; /* just for safety */
1715 if (ifa->ifa_addr->sa_family != AF_INET6)
1716 continue;
1717 ifacount++;
1718 }
1719
1720 ia->ia_addr = *sin6;
1721
1722
1723 if (ifacount <= 1 &&
1724 #ifdef __APPLE__
1725 (error = dlil_ioctl(PF_INET6, ifp, SIOCSIFADDR, (caddr_t)ia))) {
1726 if (error) {
1727 splx(s);
1728 return(error);
1729 }
1730 }
1731 #else
1732 ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
1733 splx(s);
1734 return(error);
1735 }
1736 #endif
1737 splx(s);
1738
1739 ia->ia_ifa.ifa_metric = ifp->if_metric;
1740
1741 /* we could do in(6)_socktrim here, but just omit it at this moment. */
1742
1743 /*
1744 * Special case:
1745 * If the destination address is specified for a point-to-point
1746 * interface, install a route to the destination as an interface
1747 * direct route.
1748 */
1749 plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
1750 if (plen == 128 && ia->ia_dstaddr.sin6_family == AF_INET6) {
1751 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD,
1752 RTF_UP | RTF_HOST)) != 0)
1753 return(error);
1754 ia->ia_flags |= IFA_ROUTE;
1755 }
1756 if (plen < 128) {
1757 /*
1758 * The RTF_CLONING flag is necessary for in6_is_ifloop_auto().
1759 */
1760 ia->ia_ifa.ifa_flags |= RTF_CLONING;
1761 }
1762
1763 /* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
1764 if (newhost) {
1765 /* set the rtrequest function to create llinfo */
1766 ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
1767 in6_ifaddloop(&(ia->ia_ifa));
1768 }
1769
1770 return(error);
1771 }
1772
1773 /*
1774 * Add an address to the list of IP6 multicast addresses for a
1775 * given interface.
1776 */
1777 struct in6_multi *
1778 in6_addmulti(maddr6, ifp, errorp)
1779 struct in6_addr *maddr6;
1780 struct ifnet *ifp;
1781 int *errorp;
1782 {
1783 struct in6_multi *in6m;
1784 struct sockaddr_in6 sin6;
1785 struct ifmultiaddr *ifma;
1786 int s = splnet();
1787
1788 *errorp = 0;
1789
1790 /*
1791 * Call generic routine to add membership or increment
1792 * refcount. It wants addresses in the form of a sockaddr,
1793 * so we build one here (being careful to zero the unused bytes).
1794 */
1795 bzero(&sin6, sizeof sin6);
1796 sin6.sin6_family = AF_INET6;
1797 sin6.sin6_len = sizeof sin6;
1798 sin6.sin6_addr = *maddr6;
1799 *errorp = if_addmulti(ifp, (struct sockaddr *)&sin6, &ifma);
1800 if (*errorp) {
1801 splx(s);
1802 return 0;
1803 }
1804
1805 /*
1806 * If ifma->ifma_protospec is null, then if_addmulti() created
1807 * a new record. Otherwise, we are done.
1808 */
1809 if (ifma->ifma_protospec != 0)
1810 return ifma->ifma_protospec;
1811
1812 /* XXX - if_addmulti uses M_WAITOK. Can this really be called
1813 at interrupt time? If so, need to fix if_addmulti. XXX */
1814 in6m = (struct in6_multi *)_MALLOC(sizeof(*in6m), M_IPMADDR, M_NOWAIT);
1815 if (in6m == NULL) {
1816 splx(s);
1817 return (NULL);
1818 }
1819
1820 bzero(in6m, sizeof *in6m);
1821 in6m->in6m_addr = *maddr6;
1822 in6m->in6m_ifp = ifp;
1823 in6m->in6m_ifma = ifma;
1824 ifma->ifma_protospec = in6m;
1825 LIST_INSERT_HEAD(&in6_multihead, in6m, in6m_entry);
1826
1827 /*
1828 * Let MLD6 know that we have joined a new IP6 multicast
1829 * group.
1830 */
1831 mld6_start_listening(in6m);
1832 splx(s);
1833 return(in6m);
1834 }
1835
1836 /*
1837 * Delete a multicast address record.
1838 */
1839 void
1840 in6_delmulti(in6m)
1841 struct in6_multi *in6m;
1842 {
1843 struct ifmultiaddr *ifma = in6m->in6m_ifma;
1844 int s = splnet();
1845
1846 if (ifma && ifma->ifma_refcount == 1) {
1847 /*
1848 * No remaining claims to this record; let MLD6 know
1849 * that we are leaving the multicast group.
1850 */
1851 mld6_stop_listening(in6m);
1852 ifma->ifma_protospec = 0;
1853 LIST_REMOVE(in6m, in6m_entry);
1854 FREE(in6m, M_IPMADDR);
1855 }
1856 /* XXX - should be separate API for when we have an ifma? */
1857 if (ifma)
1858 if_delmultiaddr(ifma);
1859 splx(s);
1860 }
1861
1862 /*
1863 * Find an IPv6 interface link-local address specific to an interface.
1864 */
1865 struct in6_ifaddr *
1866 in6ifa_ifpforlinklocal(ifp, ignoreflags)
1867 struct ifnet *ifp;
1868 int ignoreflags;
1869 {
1870 struct ifaddr *ifa;
1871
1872 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1873 {
1874 if (ifa->ifa_addr == NULL)
1875 continue; /* just for safety */
1876 if (ifa->ifa_addr->sa_family != AF_INET6)
1877 continue;
1878 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
1879 if ((((struct in6_ifaddr *)ifa)->ia6_flags &
1880 ignoreflags) != 0)
1881 continue;
1882 break;
1883 }
1884 }
1885
1886 return((struct in6_ifaddr *)ifa);
1887 }
1888
1889
1890 /*
1891 * find the internet address corresponding to a given interface and address.
1892 */
1893 struct in6_ifaddr *
1894 in6ifa_ifpwithaddr(ifp, addr)
1895 struct ifnet *ifp;
1896 struct in6_addr *addr;
1897 {
1898 struct ifaddr *ifa;
1899
1900 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1901 {
1902 if (ifa->ifa_addr == NULL)
1903 continue; /* just for safety */
1904 if (ifa->ifa_addr->sa_family != AF_INET6)
1905 continue;
1906 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
1907 break;
1908 }
1909
1910 return((struct in6_ifaddr *)ifa);
1911 }
1912
1913 /*
1914 * Convert IP6 address to printable (loggable) representation.
1915 */
1916 static char digits[] = "0123456789abcdef";
1917 static int ip6round = 0;
1918 char *
1919 ip6_sprintf(addr)
1920 const struct in6_addr *addr;
1921 {
1922 static char ip6buf[8][48];
1923 int i;
1924 char *cp;
1925 const u_short *a = (const u_short *)addr;
1926 const u_char *d;
1927 int dcolon = 0;
1928
1929 ip6round = (ip6round + 1) & 7;
1930 cp = ip6buf[ip6round];
1931
1932 for (i = 0; i < 8; i++) {
1933 if (dcolon == 1) {
1934 if (*a == 0) {
1935 if (i == 7)
1936 *cp++ = ':';
1937 a++;
1938 continue;
1939 } else
1940 dcolon = 2;
1941 }
1942 if (*a == 0) {
1943 if (dcolon == 0 && *(a + 1) == 0) {
1944 if (i == 0)
1945 *cp++ = ':';
1946 *cp++ = ':';
1947 dcolon = 1;
1948 } else {
1949 *cp++ = '';
1950 *cp++ = ':';
1951 }
1952 a++;
1953 continue;
1954 }
1955 d = (const u_char *)a;
1956 *cp++ = digits[*d >> 4];
1957 *cp++ = digits[*d++ & 0xf];
1958 *cp++ = digits[*d >> 4];
1959 *cp++ = digits[*d & 0xf];
1960 *cp++ = ':';
1961 a++;
1962 }
1963 *--cp = 0;
1964 return(ip6buf[ip6round]);
1965 }
1966
1967 int
1968 in6_localaddr(in6)
1969 struct in6_addr *in6;
1970 {
1971 struct in6_ifaddr *ia;
1972
1973 if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6))
1974 return 1;
1975
1976 for (ia = in6_ifaddr; ia; ia = ia->ia_next)
1977 if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr,
1978 &ia->ia_prefixmask.sin6_addr))
1979 return 1;
1980
1981 return (0);
1982 }
1983
1984 int
1985 in6_is_addr_deprecated(sa6)
1986 struct sockaddr_in6 *sa6;
1987 {
1988 struct in6_ifaddr *ia;
1989
1990 for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
1991 if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr,
1992 &sa6->sin6_addr) &&
1993 #if SCOPEDROUTING
1994 ia->ia_addr.sin6_scope_id == sa6->sin6_scope_id &&
1995 #endif
1996 (ia->ia6_flags & IN6_IFF_DEPRECATED) != 0)
1997 return(1); /* true */
1998
1999 /* XXX: do we still have to go thru the rest of the list? */
2000 }
2001
2002 return(0); /* false */
2003 }
2004
2005 /*
2006 * return length of part which dst and src are equal
2007 * hard coding...
2008 */
2009 int
2010 in6_matchlen(src, dst)
2011 struct in6_addr *src, *dst;
2012 {
2013 int match = 0;
2014 u_char *s = (u_char *)src, *d = (u_char *)dst;
2015 u_char *lim = s + 16, r;
2016
2017 while (s < lim)
2018 if ((r = (*d++ ^ *s++)) != 0) {
2019 while (r < 128) {
2020 match++;
2021 r <<= 1;
2022 }
2023 break;
2024 } else
2025 match += 8;
2026 return match;
2027 }
2028
2029 /* XXX: to be scope conscious */
2030 int
2031 in6_are_prefix_equal(p1, p2, len)
2032 struct in6_addr *p1, *p2;
2033 int len;
2034 {
2035 int bytelen, bitlen;
2036
2037 /* sanity check */
2038 if (0 > len || len > 128) {
2039 log(LOG_ERR, "in6_are_prefix_equal: invalid prefix length(%d)\n",
2040 len);
2041 return(0);
2042 }
2043
2044 bytelen = len / 8;
2045 bitlen = len % 8;
2046
2047 if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen))
2048 return(0);
2049 if (p1->s6_addr[bytelen] >> (8 - bitlen) !=
2050 p2->s6_addr[bytelen] >> (8 - bitlen))
2051 return(0);
2052
2053 return(1);
2054 }
2055
2056 void
2057 in6_prefixlen2mask(maskp, len)
2058 struct in6_addr *maskp;
2059 int len;
2060 {
2061 u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
2062 int bytelen, bitlen, i;
2063
2064 /* sanity check */
2065 if (0 > len || len > 128) {
2066 log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n",
2067 len);
2068 return;
2069 }
2070
2071 bzero(maskp, sizeof(*maskp));
2072 bytelen = len / 8;
2073 bitlen = len % 8;
2074 for (i = 0; i < bytelen; i++)
2075 maskp->s6_addr[i] = 0xff;
2076 if (bitlen)
2077 maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
2078 }
2079
2080 /*
2081 * return the best address out of the same scope
2082 */
2083 struct in6_ifaddr *
2084 in6_ifawithscope(oifp, dst)
2085 struct ifnet *oifp;
2086 struct in6_addr *dst;
2087 {
2088 int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0;
2089 int blen = -1;
2090 struct ifaddr *ifa;
2091 struct ifnet *ifp;
2092 struct in6_ifaddr *ifa_best = NULL;
2093
2094 if (oifp == NULL) {
2095 #if 0
2096 printf("in6_ifawithscope: output interface is not specified\n");
2097 #endif
2098 return(NULL);
2099 }
2100
2101 /*
2102 * We search for all addresses on all interfaces from the beginning.
2103 * Comparing an interface with the outgoing interface will be done
2104 * only at the final stage of tiebreaking.
2105 */
2106 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
2107 {
2108 /*
2109 * We can never take an address that breaks the scope zone
2110 * of the destination.
2111 */
2112 if (in6_addr2scopeid(ifp, dst) != in6_addr2scopeid(oifp, dst))
2113 continue;
2114
2115 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
2116 {
2117 int tlen = -1, dscopecmp, bscopecmp, matchcmp;
2118
2119 if (ifa->ifa_addr->sa_family != AF_INET6)
2120 continue;
2121
2122 src_scope = in6_addrscope(IFA_IN6(ifa));
2123
2124 /*
2125 * Don't use an address before completing DAD
2126 * nor a duplicated address.
2127 */
2128 if (((struct in6_ifaddr *)ifa)->ia6_flags &
2129 IN6_IFF_NOTREADY)
2130 continue;
2131
2132 /* XXX: is there any case to allow anycasts? */
2133 if (((struct in6_ifaddr *)ifa)->ia6_flags &
2134 IN6_IFF_ANYCAST)
2135 continue;
2136
2137 if (((struct in6_ifaddr *)ifa)->ia6_flags &
2138 IN6_IFF_DETACHED)
2139 continue;
2140
2141 /*
2142 * If this is the first address we find,
2143 * keep it anyway.
2144 */
2145 if (ifa_best == NULL)
2146 goto replace;
2147
2148 /*
2149 * ifa_best is never NULL beyond this line except
2150 * within the block labeled "replace".
2151 */
2152
2153 /*
2154 * If ifa_best has a smaller scope than dst and
2155 * the current address has a larger one than
2156 * (or equal to) dst, always replace ifa_best.
2157 * Also, if the current address has a smaller scope
2158 * than dst, ignore it unless ifa_best also has a
2159 * smaller scope.
2160 * Consequently, after the two if-clause below,
2161 * the followings must be satisfied:
2162 * (scope(src) < scope(dst) &&
2163 * scope(best) < scope(dst))
2164 * OR
2165 * (scope(best) >= scope(dst) &&
2166 * scope(src) >= scope(dst))
2167 */
2168 if (IN6_ARE_SCOPE_CMP(best_scope, dst_scope) < 0 &&
2169 IN6_ARE_SCOPE_CMP(src_scope, dst_scope) >= 0)
2170 goto replace; /* (A) */
2171 if (IN6_ARE_SCOPE_CMP(src_scope, dst_scope) < 0 &&
2172 IN6_ARE_SCOPE_CMP(best_scope, dst_scope) >= 0)
2173 continue; /* (B) */
2174
2175 /*
2176 * A deprecated address SHOULD NOT be used in new
2177 * communications if an alternate (non-deprecated)
2178 * address is available and has sufficient scope.
2179 * RFC 2462, Section 5.5.4.
2180 */
2181 if (((struct in6_ifaddr *)ifa)->ia6_flags &
2182 IN6_IFF_DEPRECATED) {
2183 /*
2184 * Ignore any deprecated addresses if
2185 * specified by configuration.
2186 */
2187 if (!ip6_use_deprecated)
2188 continue;
2189
2190 /*
2191 * If we have already found a non-deprecated
2192 * candidate, just ignore deprecated addresses.
2193 */
2194 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED)
2195 == 0)
2196 continue;
2197 }
2198
2199 /*
2200 * A non-deprecated address is always preferred
2201 * to a deprecated one regardless of scopes and
2202 * address matching (Note invariants ensured by the
2203 * conditions (A) and (B) above.)
2204 */
2205 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) &&
2206 (((struct in6_ifaddr *)ifa)->ia6_flags &
2207 IN6_IFF_DEPRECATED) == 0)
2208 goto replace;
2209
2210 /*
2211 * When we use temporary addresses described in
2212 * RFC 3041, we prefer temporary addresses to
2213 * public autoconf addresses. Again, note the
2214 * invariants from (A) and (B). Also note that we
2215 * don't have any preference between static addresses
2216 * and autoconf addresses (despite of whether or not
2217 * the latter is temporary or public.)
2218 */
2219 if (ip6_use_tempaddr) {
2220 struct in6_ifaddr *ifat;
2221
2222 ifat = (struct in6_ifaddr *)ifa;
2223 if ((ifa_best->ia6_flags &
2224 (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY))
2225 == IN6_IFF_AUTOCONF &&
2226 (ifat->ia6_flags &
2227 (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY))
2228 == (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY)) {
2229 goto replace;
2230 }
2231 if ((ifa_best->ia6_flags &
2232 (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY))
2233 == (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY) &&
2234 (ifat->ia6_flags &
2235 (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY))
2236 == IN6_IFF_AUTOCONF) {
2237 continue;
2238 }
2239 }
2240
2241 /*
2242 * At this point, we have two cases:
2243 * 1. we are looking at a non-deprecated address,
2244 * and ifa_best is also non-deprecated.
2245 * 2. we are looking at a deprecated address,
2246 * and ifa_best is also deprecated.
2247 * Also, we do not have to consider a case where
2248 * the scope of if_best is larger(smaller) than dst and
2249 * the scope of the current address is smaller(larger)
2250 * than dst. Such a case has already been covered.
2251 * Tiebreaking is done according to the following
2252 * items:
2253 * - the scope comparison between the address and
2254 * dst (dscopecmp)
2255 * - the scope comparison between the address and
2256 * ifa_best (bscopecmp)
2257 * - if the address match dst longer than ifa_best
2258 * (matchcmp)
2259 * - if the address is on the outgoing I/F (outI/F)
2260 *
2261 * Roughly speaking, the selection policy is
2262 * - the most important item is scope. The same scope
2263 * is best. Then search for a larger scope.
2264 * Smaller scopes are the last resort.
2265 * - A deprecated address is chosen only when we have
2266 * no address that has an enough scope, but is
2267 * prefered to any addresses of smaller scopes
2268 * (this must be already done above.)
2269 * - addresses on the outgoing I/F are preferred to
2270 * ones on other interfaces if none of above
2271 * tiebreaks. In the table below, the column "bI"
2272 * means if the best_ifa is on the outgoing
2273 * interface, and the column "sI" means if the ifa
2274 * is on the outgoing interface.
2275 * - If there is no other reasons to choose one,
2276 * longest address match against dst is considered.
2277 *
2278 * The precise decision table is as follows:
2279 * dscopecmp bscopecmp match bI oI | replace?
2280 * N/A equal N/A Y N | No (1)
2281 * N/A equal N/A N Y | Yes (2)
2282 * N/A equal larger N/A | Yes (3)
2283 * N/A equal !larger N/A | No (4)
2284 * larger larger N/A N/A | No (5)
2285 * larger smaller N/A N/A | Yes (6)
2286 * smaller larger N/A N/A | Yes (7)
2287 * smaller smaller N/A N/A | No (8)
2288 * equal smaller N/A N/A | Yes (9)
2289 * equal larger (already done at A above)
2290 */
2291 dscopecmp = IN6_ARE_SCOPE_CMP(src_scope, dst_scope);
2292 bscopecmp = IN6_ARE_SCOPE_CMP(src_scope, best_scope);
2293
2294 if (bscopecmp == 0) {
2295 struct ifnet *bifp = ifa_best->ia_ifp;
2296
2297 if (bifp == oifp && ifp != oifp) /* (1) */
2298 continue;
2299 if (bifp != oifp && ifp == oifp) /* (2) */
2300 goto replace;
2301
2302 /*
2303 * Both bifp and ifp are on the outgoing
2304 * interface, or both two are on a different
2305 * interface from the outgoing I/F.
2306 * now we need address matching against dst
2307 * for tiebreaking.
2308 */
2309 tlen = in6_matchlen(IFA_IN6(ifa), dst);
2310 matchcmp = tlen - blen;
2311 if (matchcmp > 0) /* (3) */
2312 goto replace;
2313 continue; /* (4) */
2314 }
2315 if (dscopecmp > 0) {
2316 if (bscopecmp > 0) /* (5) */
2317 continue;
2318 goto replace; /* (6) */
2319 }
2320 if (dscopecmp < 0) {
2321 if (bscopecmp > 0) /* (7) */
2322 goto replace;
2323 continue; /* (8) */
2324 }
2325
2326 /* now dscopecmp must be 0 */
2327 if (bscopecmp < 0)
2328 goto replace; /* (9) */
2329
2330 replace:
2331 ifa_best = (struct in6_ifaddr *)ifa;
2332 blen = tlen >= 0 ? tlen :
2333 in6_matchlen(IFA_IN6(ifa), dst);
2334 best_scope = in6_addrscope(&ifa_best->ia_addr.sin6_addr);
2335 }
2336 }
2337
2338 /* count statistics for future improvements */
2339 if (ifa_best == NULL)
2340 ip6stat.ip6s_sources_none++;
2341 else {
2342 if (oifp == ifa_best->ia_ifp)
2343 ip6stat.ip6s_sources_sameif[best_scope]++;
2344 else
2345 ip6stat.ip6s_sources_otherif[best_scope]++;
2346
2347 if (best_scope == dst_scope)
2348 ip6stat.ip6s_sources_samescope[best_scope]++;
2349 else
2350 ip6stat.ip6s_sources_otherscope[best_scope]++;
2351
2352 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) != 0)
2353 ip6stat.ip6s_sources_deprecated[best_scope]++;
2354 }
2355
2356 return(ifa_best);
2357 }
2358
2359 /*
2360 * return the best address out of the same scope. if no address was
2361 * found, return the first valid address from designated IF.
2362 */
2363 struct in6_ifaddr *
2364 in6_ifawithifp(ifp, dst)
2365 struct ifnet *ifp;
2366 struct in6_addr *dst;
2367 {
2368 int dst_scope = in6_addrscope(dst), blen = -1, tlen;
2369 struct ifaddr *ifa;
2370 struct in6_ifaddr *besta = 0;
2371 struct in6_ifaddr *dep[2]; /* last-resort: deprecated */
2372
2373 dep[0] = dep[1] = NULL;
2374
2375 /*
2376 * We first look for addresses in the same scope.
2377 * If there is one, return it.
2378 * If two or more, return one which matches the dst longest.
2379 * If none, return one of global addresses assigned other ifs.
2380 */
2381 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
2382 {
2383 if (ifa->ifa_addr->sa_family != AF_INET6)
2384 continue;
2385 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
2386 continue; /* XXX: is there any case to allow anycast? */
2387 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
2388 continue; /* don't use this interface */
2389 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
2390 continue;
2391 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
2392 if (ip6_use_deprecated)
2393 dep[0] = (struct in6_ifaddr *)ifa;
2394 continue;
2395 }
2396
2397 if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
2398 /*
2399 * call in6_matchlen() as few as possible
2400 */
2401 if (besta) {
2402 if (blen == -1)
2403 blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst);
2404 tlen = in6_matchlen(IFA_IN6(ifa), dst);
2405 if (tlen > blen) {
2406 blen = tlen;
2407 besta = (struct in6_ifaddr *)ifa;
2408 }
2409 } else
2410 besta = (struct in6_ifaddr *)ifa;
2411 }
2412 }
2413 if (besta)
2414 return(besta);
2415
2416 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
2417 {
2418 if (ifa->ifa_addr->sa_family != AF_INET6)
2419 continue;
2420 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
2421 continue; /* XXX: is there any case to allow anycast? */
2422 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
2423 continue; /* don't use this interface */
2424 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
2425 continue;
2426 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
2427 if (ip6_use_deprecated)
2428 dep[1] = (struct in6_ifaddr *)ifa;
2429 continue;
2430 }
2431
2432 return (struct in6_ifaddr *)ifa;
2433 }
2434
2435 /* use the last-resort values, that are, deprecated addresses */
2436 if (dep[0])
2437 return dep[0];
2438 if (dep[1])
2439 return dep[1];
2440
2441 return NULL;
2442 }
2443
2444 extern int in6_init2done;
2445
2446 /*
2447 * perform DAD when interface becomes IFF_UP.
2448 */
2449 void
2450 in6_if_up(ifp, ifra)
2451 struct ifnet *ifp;
2452 struct in6_aliasreq *ifra;
2453 {
2454 struct ifaddr *ifa;
2455 struct in6_ifaddr *ia;
2456 int dad_delay; /* delay ticks before DAD output */
2457
2458 if (!in6_init2done)
2459 return;
2460
2461 /*
2462 * special cases, like 6to4, are handled in in6_ifattach
2463 */
2464 in6_ifattach(ifp, NULL, ifra);
2465
2466 dad_delay = 0;
2467 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
2468 {
2469 if (ifa->ifa_addr->sa_family != AF_INET6)
2470 continue;
2471 ia = (struct in6_ifaddr *)ifa;
2472 if (ia->ia6_flags & IN6_IFF_TENTATIVE)
2473 nd6_dad_start(ifa, &dad_delay);
2474 }
2475 }
2476
2477 int
2478 in6if_do_dad(ifp)
2479 struct ifnet *ifp;
2480 {
2481 if ((ifp->if_flags & IFF_LOOPBACK) != 0)
2482 return(0);
2483
2484 switch (ifp->if_type) {
2485 #if IFT_DUMMY
2486 case IFT_DUMMY:
2487 #endif
2488 case IFT_FAITH:
2489 /*
2490 * These interfaces do not have the IFF_LOOPBACK flag,
2491 * but loop packets back. We do not have to do DAD on such
2492 * interfaces. We should even omit it, because loop-backed
2493 * NS would confuse the DAD procedure.
2494 */
2495 return(0);
2496 default:
2497 /*
2498 * Our DAD routine requires the interface up and running.
2499 * However, some interfaces can be up before the RUNNING
2500 * status. Additionaly, users may try to assign addresses
2501 * before the interface becomes up (or running).
2502 * We simply skip DAD in such a case as a work around.
2503 * XXX: we should rather mark "tentative" on such addresses,
2504 * and do DAD after the interface becomes ready.
2505 */
2506 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) !=
2507 (IFF_UP|IFF_RUNNING))
2508 return(0);
2509
2510 return(1);
2511 }
2512 }
2513
2514 /*
2515 * Calculate max IPv6 MTU through all the interfaces and store it
2516 * to in6_maxmtu.
2517 */
2518 void
2519 in6_setmaxmtu()
2520 {
2521 unsigned long maxmtu = 0;
2522 struct ifnet *ifp;
2523
2524 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
2525 {
2526 if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
2527 nd_ifinfo[ifp->if_index].linkmtu > maxmtu)
2528 maxmtu = nd_ifinfo[ifp->if_index].linkmtu;
2529 }
2530 if (maxmtu) /* update only when maxmtu is positive */
2531 in6_maxmtu = maxmtu;
2532 }
2533
2534 /*
2535 * Convert sockaddr_in6 to sockaddr_in. Original sockaddr_in6 must be
2536 * v4 mapped addr or v4 compat addr
2537 */
2538 void
2539 in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
2540 {
2541 bzero(sin, sizeof(*sin));
2542 sin->sin_len = sizeof(struct sockaddr_in);
2543 sin->sin_family = AF_INET;
2544 sin->sin_port = sin6->sin6_port;
2545 sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3];
2546 }
2547
2548 /* Convert sockaddr_in to sockaddr_in6 in v4 mapped addr format. */
2549 void
2550 in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
2551 {
2552 bzero(sin6, sizeof(*sin6));
2553 sin6->sin6_len = sizeof(struct sockaddr_in6);
2554 sin6->sin6_family = AF_INET6;
2555 sin6->sin6_port = sin->sin_port;
2556 sin6->sin6_addr.s6_addr32[0] = 0;
2557 sin6->sin6_addr.s6_addr32[1] = 0;
2558 sin6->sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_SMP;
2559 sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr;
2560 }
2561
2562 /* Convert sockaddr_in6 into sockaddr_in. */
2563 void
2564 in6_sin6_2_sin_in_sock(struct sockaddr *nam)
2565 {
2566 struct sockaddr_in *sin_p;
2567 struct sockaddr_in6 sin6;
2568
2569 /*
2570 * Save original sockaddr_in6 addr and convert it
2571 * to sockaddr_in.
2572 */
2573 sin6 = *(struct sockaddr_in6 *)nam;
2574 sin_p = (struct sockaddr_in *)nam;
2575 in6_sin6_2_sin(sin_p, &sin6);
2576 }
2577
2578 /* Convert sockaddr_in into sockaddr_in6 in v4 mapped addr format. */
2579 void
2580 in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam)
2581 {
2582 struct sockaddr_in *sin_p;
2583 struct sockaddr_in6 *sin6_p;
2584
2585 MALLOC(sin6_p, struct sockaddr_in6 *, sizeof *sin6_p, M_SONAME,
2586 M_WAITOK);
2587 sin_p = (struct sockaddr_in *)*nam;
2588 in6_sin_2_v4mapsin6(sin_p, sin6_p);
2589 FREE(*nam, M_SONAME);
2590 *nam = (struct sockaddr *)sin6_p;
2591 }
2592
2593 /* Posts in6_event_data message kernel events */
2594 void
2595 in6_post_msg(struct ifnet *ifp, u_long event_code, struct in6_ifaddr *ifa)
2596 {
2597 struct kev_msg ev_msg;
2598 struct kev_in6_data in6_event_data;
2599
2600 ev_msg.vendor_code = KEV_VENDOR_APPLE;
2601 ev_msg.kev_class = KEV_NETWORK_CLASS;
2602 ev_msg.kev_subclass = KEV_INET6_SUBCLASS;
2603 ev_msg.event_code = event_code;
2604
2605 in6_event_data.ia_addr = ifa->ia_addr;
2606 in6_event_data.ia_net = ifa->ia_net;
2607 in6_event_data.ia_dstaddr = ifa->ia_dstaddr;
2608 in6_event_data.ia_prefixmask = ifa->ia_prefixmask;
2609 in6_event_data.ia_plen = ifa->ia_plen;
2610 in6_event_data.ia6_flags = (u_int32_t)ifa->ia6_flags;
2611 in6_event_data.ia_lifetime = ifa->ia6_lifetime;
2612
2613 if (ifp != NULL) {
2614 strncpy(&in6_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
2615 in6_event_data.link_data.if_family = ifp->if_family;
2616 in6_event_data.link_data.if_unit = (unsigned long) ifp->if_unit;
2617 }
2618
2619 ev_msg.dv[0].data_ptr = &in6_event_data;
2620 ev_msg.dv[0].data_length = sizeof(struct kev_in6_data);
2621 ev_msg.dv[1].data_length = 0;
2622
2623 kev_post_msg(&ev_msg);
2624 }
Cache object: 368d29a5e889e744d3e6dbdaa6c24b40
|