FreeBSD/Linux Kernel Cross Reference
sys/netinet6/in6.c
1 /* $FreeBSD: releng/5.2/sys/netinet6/in6.c 122334 2003-11-08 23:36:32Z sam $ */
2 /* $KAME: in6.c,v 1.259 2002/01/21 11:37:50 keiichi 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 #include "opt_inet6.h"
70
71 #include <sys/param.h>
72 #include <sys/errno.h>
73 #include <sys/malloc.h>
74 #include <sys/socket.h>
75 #include <sys/socketvar.h>
76 #include <sys/sockio.h>
77 #include <sys/systm.h>
78 #include <sys/proc.h>
79 #include <sys/time.h>
80 #include <sys/kernel.h>
81 #include <sys/syslog.h>
82
83 #include <net/if.h>
84 #include <net/if_types.h>
85 #include <net/route.h>
86 #include <net/if_dl.h>
87
88 #include <netinet/in.h>
89 #include <netinet/in_var.h>
90 #include <netinet/if_ether.h>
91 #include <netinet/in_systm.h>
92 #include <netinet/ip.h>
93 #include <netinet/in_pcb.h>
94
95 #include <netinet/ip6.h>
96 #include <netinet6/ip6_var.h>
97 #include <netinet6/nd6.h>
98 #include <netinet6/mld6_var.h>
99 #include <netinet6/ip6_mroute.h>
100 #include <netinet6/in6_ifattach.h>
101 #include <netinet6/scope6_var.h>
102 #include <netinet6/in6_pcb.h>
103
104 #include <net/net_osdep.h>
105
106 MALLOC_DEFINE(M_IPMADDR, "in6_multi", "internet multicast address");
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 const struct sockaddr_in6 sa6_any = {sizeof(sa6_any), AF_INET6,
127 0, 0, IN6ADDR_ANY_INIT, 0};
128
129 static int in6_lifaddr_ioctl __P((struct socket *, u_long, caddr_t,
130 struct ifnet *, struct thread *));
131 static int in6_ifinit __P((struct ifnet *, struct in6_ifaddr *,
132 struct sockaddr_in6 *, int));
133 static void in6_unlink_ifa __P((struct in6_ifaddr *, struct ifnet *));
134
135 struct in6_multihead in6_multihead; /* XXX BSS initialization */
136 int (*faithprefix_p)(struct in6_addr *);
137
138 /*
139 * Subroutine for in6_ifaddloop() and in6_ifremloop().
140 * This routine does actual work.
141 */
142 static void
143 in6_ifloop_request(int cmd, struct ifaddr *ifa)
144 {
145 struct sockaddr_in6 all1_sa;
146 struct rtentry *nrt = NULL;
147 int e;
148
149 bzero(&all1_sa, sizeof(all1_sa));
150 all1_sa.sin6_family = AF_INET6;
151 all1_sa.sin6_len = sizeof(struct sockaddr_in6);
152 all1_sa.sin6_addr = in6mask128;
153
154 /*
155 * We specify the address itself as the gateway, and set the
156 * RTF_LLINFO flag, so that the corresponding host route would have
157 * the flag, and thus applications that assume traditional behavior
158 * would be happy. Note that we assume the caller of the function
159 * (probably implicitly) set nd6_rtrequest() to ifa->ifa_rtrequest,
160 * which changes the outgoing interface to the loopback interface.
161 */
162 e = rtrequest(cmd, ifa->ifa_addr, ifa->ifa_addr,
163 (struct sockaddr *)&all1_sa, RTF_UP|RTF_HOST|RTF_LLINFO, &nrt);
164 if (e != 0) {
165 /* XXX need more descriptive message */
166 log(LOG_ERR, "in6_ifloop_request: "
167 "%s operation failed for %s (errno=%d)\n",
168 cmd == RTM_ADD ? "ADD" : "DELETE",
169 ip6_sprintf(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr),
170 e);
171 }
172
173 if (nrt) {
174 RT_LOCK(nrt);
175 /*
176 * Make sure rt_ifa be equal to IFA, the second argument of
177 * the function. We need this because when we refer to
178 * rt_ifa->ia6_flags in ip6_input, we assume that the rt_ifa
179 * points to the address instead of the loopback address.
180 */
181 if (cmd == RTM_ADD && ifa != nrt->rt_ifa) {
182 IFAFREE(nrt->rt_ifa);
183 IFAREF(ifa);
184 nrt->rt_ifa = ifa;
185 }
186
187 /*
188 * Report the addition/removal of the address to the routing
189 * socket.
190 *
191 * XXX: since we called rtinit for a p2p interface with a
192 * destination, we end up reporting twice in such a case.
193 * Should we rather omit the second report?
194 */
195 rt_newaddrmsg(cmd, ifa, e, nrt);
196 if (cmd == RTM_DELETE) {
197 rtfree(nrt);
198 } else {
199 /* the cmd must be RTM_ADD here */
200 RT_REMREF(nrt);
201 RT_UNLOCK(nrt);
202 }
203 }
204 }
205
206 /*
207 * Add ownaddr as loopback rtentry. We previously add the route only if
208 * necessary (ex. on a p2p link). However, since we now manage addresses
209 * separately from prefixes, we should always add the route. We can't
210 * rely on the cloning mechanism from the corresponding interface route
211 * any more.
212 */
213 static void
214 in6_ifaddloop(struct ifaddr *ifa)
215 {
216 struct rtentry *rt;
217 int need_loop;
218
219 /* If there is no loopback entry, allocate one. */
220 rt = rtalloc1(ifa->ifa_addr, 0, 0);
221 need_loop = (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 ||
222 (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0);
223 if (rt)
224 rtfree(rt);
225 if (need_loop)
226 in6_ifloop_request(RTM_ADD, ifa);
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 removing
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) {
275 if ((rt->rt_flags & RTF_HOST) != 0 &&
276 (rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
277 rtfree(rt);
278 in6_ifloop_request(RTM_DELETE, ifa);
279 } else
280 RT_UNLOCK(rt);
281 }
282 }
283 }
284
285 int
286 in6_mask2len(mask, lim0)
287 struct in6_addr *mask;
288 u_char *lim0;
289 {
290 int x = 0, y;
291 u_char *lim = lim0, *p;
292
293 /* ignore the scope_id part */
294 if (lim0 == NULL || lim0 - (u_char *)mask > sizeof(*mask))
295 lim = (u_char *)mask + sizeof(*mask);
296 for (p = (u_char *)mask; p < lim; x++, p++) {
297 if (*p != 0xff)
298 break;
299 }
300 y = 0;
301 if (p < lim) {
302 for (y = 0; y < 8; y++) {
303 if ((*p & (0x80 >> y)) == 0)
304 break;
305 }
306 }
307
308 /*
309 * when the limit pointer is given, do a stricter check on the
310 * remaining bits.
311 */
312 if (p < lim) {
313 if (y != 0 && (*p & (0x00ff >> y)) != 0)
314 return (-1);
315 for (p = p + 1; p < lim; p++)
316 if (*p != 0)
317 return (-1);
318 }
319
320 return x * 8 + y;
321 }
322
323 #define ifa2ia6(ifa) ((struct in6_ifaddr *)(ifa))
324 #define ia62ifa(ia6) (&((ia6)->ia_ifa))
325
326 int
327 in6_control(so, cmd, data, ifp, td)
328 struct socket *so;
329 u_long cmd;
330 caddr_t data;
331 struct ifnet *ifp;
332 struct thread *td;
333 {
334 struct in6_ifreq *ifr = (struct in6_ifreq *)data;
335 struct in6_ifaddr *ia = NULL;
336 struct in6_aliasreq *ifra = (struct in6_aliasreq *)data;
337 int privileged;
338
339 privileged = 0;
340 if (td == NULL || !suser(td))
341 privileged++;
342
343 switch (cmd) {
344 case SIOCGETSGCNT_IN6:
345 case SIOCGETMIFCNT_IN6:
346 return (mrt6_ioctl(cmd, data));
347 }
348
349 switch(cmd) {
350 case SIOCAADDRCTL_POLICY:
351 case SIOCDADDRCTL_POLICY:
352 if (!privileged)
353 return (EPERM);
354 return (in6_src_ioctl(cmd, data));
355 }
356
357 if (ifp == NULL)
358 return (EOPNOTSUPP);
359
360 switch (cmd) {
361 case SIOCSNDFLUSH_IN6:
362 case SIOCSPFXFLUSH_IN6:
363 case SIOCSRTRFLUSH_IN6:
364 case SIOCSDEFIFACE_IN6:
365 case SIOCSIFINFO_FLAGS:
366 if (!privileged)
367 return (EPERM);
368 /* FALLTHROUGH */
369 case OSIOCGIFINFO_IN6:
370 case SIOCGIFINFO_IN6:
371 case SIOCGDRLST_IN6:
372 case SIOCGPRLST_IN6:
373 case SIOCGNBRINFO_IN6:
374 case SIOCGDEFIFACE_IN6:
375 return (nd6_ioctl(cmd, data, ifp));
376 }
377
378 switch (cmd) {
379 case SIOCSIFPREFIX_IN6:
380 case SIOCDIFPREFIX_IN6:
381 case SIOCAIFPREFIX_IN6:
382 case SIOCCIFPREFIX_IN6:
383 case SIOCSGIFPREFIX_IN6:
384 case SIOCGIFPREFIX_IN6:
385 log(LOG_NOTICE,
386 "prefix ioctls are now invalidated. "
387 "please use ifconfig.\n");
388 return (EOPNOTSUPP);
389 }
390
391 switch (cmd) {
392 case SIOCSSCOPE6:
393 if (!privileged)
394 return (EPERM);
395 return (scope6_set(ifp,
396 (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id));
397 case SIOCGSCOPE6:
398 return (scope6_get(ifp,
399 (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id));
400 case SIOCGSCOPE6DEF:
401 return (scope6_get_default((struct scope6_id *)
402 ifr->ifr_ifru.ifru_scope_id));
403 }
404
405 switch (cmd) {
406 case SIOCALIFADDR:
407 case SIOCDLIFADDR:
408 if (!privileged)
409 return (EPERM);
410 /* FALLTHROUGH */
411 case SIOCGLIFADDR:
412 return in6_lifaddr_ioctl(so, cmd, data, ifp, td);
413 }
414
415 /*
416 * Find address for this interface, if it exists.
417 */
418 if (ifra->ifra_addr.sin6_family == AF_INET6) { /* XXX */
419 struct sockaddr_in6 *sa6 =
420 (struct sockaddr_in6 *)&ifra->ifra_addr;
421
422 if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
423 if (sa6->sin6_addr.s6_addr16[1] == 0) {
424 /* link ID is not embedded by the user */
425 sa6->sin6_addr.s6_addr16[1] =
426 htons(ifp->if_index);
427 } else if (sa6->sin6_addr.s6_addr16[1] !=
428 htons(ifp->if_index)) {
429 return (EINVAL); /* link ID contradicts */
430 }
431 if (sa6->sin6_scope_id) {
432 if (sa6->sin6_scope_id !=
433 (u_int32_t)ifp->if_index)
434 return (EINVAL);
435 sa6->sin6_scope_id = 0; /* XXX: good way? */
436 }
437 }
438 ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr);
439 }
440
441 switch (cmd) {
442 case SIOCSIFADDR_IN6:
443 case SIOCSIFDSTADDR_IN6:
444 case SIOCSIFNETMASK_IN6:
445 /*
446 * Since IPv6 allows a node to assign multiple addresses
447 * on a single interface, SIOCSIFxxx ioctls are not suitable
448 * and should be unused.
449 */
450 /* we decided to obsolete this command (20000704) */
451 return (EINVAL);
452
453 case SIOCDIFADDR_IN6:
454 /*
455 * for IPv4, we look for existing in_ifaddr here to allow
456 * "ifconfig if0 delete" to remove first IPv4 address on the
457 * interface. For IPv6, as the spec allow multiple interface
458 * address from the day one, we consider "remove the first one"
459 * semantics to be not preferable.
460 */
461 if (ia == NULL)
462 return (EADDRNOTAVAIL);
463 /* FALLTHROUGH */
464 case SIOCAIFADDR_IN6:
465 /*
466 * We always require users to specify a valid IPv6 address for
467 * the corresponding operation.
468 */
469 if (ifra->ifra_addr.sin6_family != AF_INET6 ||
470 ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6))
471 return (EAFNOSUPPORT);
472 if (!privileged)
473 return (EPERM);
474
475 break;
476
477 case SIOCGIFADDR_IN6:
478 /* This interface is basically deprecated. use SIOCGIFCONF. */
479 /* FALLTHROUGH */
480 case SIOCGIFAFLAG_IN6:
481 case SIOCGIFNETMASK_IN6:
482 case SIOCGIFDSTADDR_IN6:
483 case SIOCGIFALIFETIME_IN6:
484 /* must think again about its semantics */
485 if (ia == NULL)
486 return (EADDRNOTAVAIL);
487 break;
488 case SIOCSIFALIFETIME_IN6:
489 {
490 struct in6_addrlifetime *lt;
491
492 if (!privileged)
493 return (EPERM);
494 if (ia == NULL)
495 return (EADDRNOTAVAIL);
496 /* sanity for overflow - beware unsigned */
497 lt = &ifr->ifr_ifru.ifru_lifetime;
498 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
499 && lt->ia6t_vltime + time_second < time_second) {
500 return EINVAL;
501 }
502 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
503 && lt->ia6t_pltime + time_second < time_second) {
504 return EINVAL;
505 }
506 break;
507 }
508 }
509
510 switch (cmd) {
511
512 case SIOCGIFADDR_IN6:
513 ifr->ifr_addr = ia->ia_addr;
514 break;
515
516 case SIOCGIFDSTADDR_IN6:
517 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
518 return (EINVAL);
519 /*
520 * XXX: should we check if ifa_dstaddr is NULL and return
521 * an error?
522 */
523 ifr->ifr_dstaddr = ia->ia_dstaddr;
524 break;
525
526 case SIOCGIFNETMASK_IN6:
527 ifr->ifr_addr = ia->ia_prefixmask;
528 break;
529
530 case SIOCGIFAFLAG_IN6:
531 ifr->ifr_ifru.ifru_flags6 = ia->ia6_flags;
532 break;
533
534 case SIOCGIFSTAT_IN6:
535 if (ifp == NULL)
536 return EINVAL;
537 bzero(&ifr->ifr_ifru.ifru_stat,
538 sizeof(ifr->ifr_ifru.ifru_stat));
539 ifr->ifr_ifru.ifru_stat =
540 *((struct in6_ifextra *)ifp->if_afdata[AF_INET6])->in6_ifstat;
541 break;
542
543 case SIOCGIFSTAT_ICMP6:
544 if (ifp == NULL)
545 return EINVAL;
546 bzero(&ifr->ifr_ifru.ifru_stat,
547 sizeof(ifr->ifr_ifru.ifru_icmp6stat));
548 ifr->ifr_ifru.ifru_icmp6stat =
549 *((struct in6_ifextra *)ifp->if_afdata[AF_INET6])->icmp6_ifstat;
550 break;
551
552 case SIOCGIFALIFETIME_IN6:
553 ifr->ifr_ifru.ifru_lifetime = ia->ia6_lifetime;
554 break;
555
556 case SIOCSIFALIFETIME_IN6:
557 ia->ia6_lifetime = ifr->ifr_ifru.ifru_lifetime;
558 /* for sanity */
559 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
560 ia->ia6_lifetime.ia6t_expire =
561 time_second + ia->ia6_lifetime.ia6t_vltime;
562 } else
563 ia->ia6_lifetime.ia6t_expire = 0;
564 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
565 ia->ia6_lifetime.ia6t_preferred =
566 time_second + ia->ia6_lifetime.ia6t_pltime;
567 } else
568 ia->ia6_lifetime.ia6t_preferred = 0;
569 break;
570
571 case SIOCAIFADDR_IN6:
572 {
573 int i, error = 0;
574 struct nd_prefix pr0, *pr;
575
576 /*
577 * first, make or update the interface address structure,
578 * and link it to the list.
579 */
580 if ((error = in6_update_ifa(ifp, ifra, ia)) != 0)
581 return (error);
582
583 /*
584 * then, make the prefix on-link on the interface.
585 * XXX: we'd rather create the prefix before the address, but
586 * we need at least one address to install the corresponding
587 * interface route, so we configure the address first.
588 */
589
590 /*
591 * convert mask to prefix length (prefixmask has already
592 * been validated in in6_update_ifa().
593 */
594 bzero(&pr0, sizeof(pr0));
595 pr0.ndpr_ifp = ifp;
596 pr0.ndpr_plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
597 NULL);
598 if (pr0.ndpr_plen == 128) {
599 break; /* we don't need to install a host route. */
600 }
601 pr0.ndpr_prefix = ifra->ifra_addr;
602 pr0.ndpr_mask = ifra->ifra_prefixmask.sin6_addr;
603 /* apply the mask for safety. */
604 for (i = 0; i < 4; i++) {
605 pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
606 ifra->ifra_prefixmask.sin6_addr.s6_addr32[i];
607 }
608 /*
609 * XXX: since we don't have an API to set prefix (not address)
610 * lifetimes, we just use the same lifetimes as addresses.
611 * The (temporarily) installed lifetimes can be overridden by
612 * later advertised RAs (when accept_rtadv is non 0), which is
613 * an intended behavior.
614 */
615 pr0.ndpr_raf_onlink = 1; /* should be configurable? */
616 pr0.ndpr_raf_auto =
617 ((ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0);
618 pr0.ndpr_vltime = ifra->ifra_lifetime.ia6t_vltime;
619 pr0.ndpr_pltime = ifra->ifra_lifetime.ia6t_pltime;
620
621 /* add the prefix if not yet. */
622 if ((pr = nd6_prefix_lookup(&pr0)) == NULL) {
623 /*
624 * nd6_prelist_add will install the corresponding
625 * interface route.
626 */
627 if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0)
628 return (error);
629 if (pr == NULL) {
630 log(LOG_ERR, "nd6_prelist_add succeeded but "
631 "no prefix\n");
632 return (EINVAL); /* XXX panic here? */
633 }
634 }
635 if ((ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr))
636 == NULL) {
637 /* XXX: this should not happen! */
638 log(LOG_ERR, "in6_control: addition succeeded, but"
639 " no ifaddr\n");
640 } else {
641 if ((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0 &&
642 ia->ia6_ndpr == NULL) { /* new autoconfed addr */
643 ia->ia6_ndpr = pr;
644 pr->ndpr_refcnt++;
645
646 /*
647 * If this is the first autoconf address from
648 * the prefix, create a temporary address
649 * as well (when specified).
650 */
651 if (ip6_use_tempaddr &&
652 pr->ndpr_refcnt == 1) {
653 int e;
654 if ((e = in6_tmpifadd(ia, 1)) != 0) {
655 log(LOG_NOTICE, "in6_control: "
656 "failed to create a "
657 "temporary address, "
658 "errno=%d\n", e);
659 }
660 }
661 }
662
663 /*
664 * this might affect the status of autoconfigured
665 * addresses, that is, this address might make
666 * other addresses detached.
667 */
668 pfxlist_onlink_check();
669 }
670 break;
671 }
672
673 case SIOCDIFADDR_IN6:
674 {
675 int i = 0;
676 struct nd_prefix pr0, *pr;
677
678 /*
679 * If the address being deleted is the only one that owns
680 * the corresponding prefix, expire the prefix as well.
681 * XXX: theoretically, we don't have to worry about such
682 * relationship, since we separate the address management
683 * and the prefix management. We do this, however, to provide
684 * as much backward compatibility as possible in terms of
685 * the ioctl operation.
686 */
687 bzero(&pr0, sizeof(pr0));
688 pr0.ndpr_ifp = ifp;
689 pr0.ndpr_plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr,
690 NULL);
691 if (pr0.ndpr_plen == 128)
692 goto purgeaddr;
693 pr0.ndpr_prefix = ia->ia_addr;
694 pr0.ndpr_mask = ia->ia_prefixmask.sin6_addr;
695 for (i = 0; i < 4; i++) {
696 pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
697 ia->ia_prefixmask.sin6_addr.s6_addr32[i];
698 }
699 /*
700 * The logic of the following condition is a bit complicated.
701 * We expire the prefix when
702 * 1. the address obeys autoconfiguration and it is the
703 * only owner of the associated prefix, or
704 * 2. the address does not obey autoconf and there is no
705 * other owner of the prefix.
706 */
707 if ((pr = nd6_prefix_lookup(&pr0)) != NULL &&
708 (((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0 &&
709 pr->ndpr_refcnt == 1) ||
710 ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0 &&
711 pr->ndpr_refcnt == 0))) {
712 pr->ndpr_expire = 1; /* XXX: just for expiration */
713 }
714
715 purgeaddr:
716 in6_purgeaddr(&ia->ia_ifa);
717 break;
718 }
719
720 default:
721 if (ifp == NULL || ifp->if_ioctl == 0)
722 return (EOPNOTSUPP);
723 return ((*ifp->if_ioctl)(ifp, cmd, data));
724 }
725
726 return (0);
727 }
728
729 /*
730 * Update parameters of an IPv6 interface address.
731 * If necessary, a new entry is created and linked into address chains.
732 * This function is separated from in6_control().
733 * XXX: should this be performed under splnet()?
734 */
735 int
736 in6_update_ifa(ifp, ifra, ia)
737 struct ifnet *ifp;
738 struct in6_aliasreq *ifra;
739 struct in6_ifaddr *ia;
740 {
741 int error = 0, hostIsNew = 0, plen = -1;
742 struct in6_ifaddr *oia;
743 struct sockaddr_in6 dst6;
744 struct in6_addrlifetime *lt;
745
746 /* Validate parameters */
747 if (ifp == NULL || ifra == NULL) /* this maybe redundant */
748 return (EINVAL);
749
750 /*
751 * The destination address for a p2p link must have a family
752 * of AF_UNSPEC or AF_INET6.
753 */
754 if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
755 ifra->ifra_dstaddr.sin6_family != AF_INET6 &&
756 ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
757 return (EAFNOSUPPORT);
758 /*
759 * validate ifra_prefixmask. don't check sin6_family, netmask
760 * does not carry fields other than sin6_len.
761 */
762 if (ifra->ifra_prefixmask.sin6_len > sizeof(struct sockaddr_in6))
763 return (EINVAL);
764 /*
765 * Because the IPv6 address architecture is classless, we require
766 * users to specify a (non 0) prefix length (mask) for a new address.
767 * We also require the prefix (when specified) mask is valid, and thus
768 * reject a non-consecutive mask.
769 */
770 if (ia == NULL && ifra->ifra_prefixmask.sin6_len == 0)
771 return (EINVAL);
772 if (ifra->ifra_prefixmask.sin6_len != 0) {
773 plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
774 (u_char *)&ifra->ifra_prefixmask +
775 ifra->ifra_prefixmask.sin6_len);
776 if (plen <= 0)
777 return (EINVAL);
778 } else {
779 /*
780 * In this case, ia must not be NULL. We just use its prefix
781 * length.
782 */
783 plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
784 }
785 /*
786 * If the destination address on a p2p interface is specified,
787 * and the address is a scoped one, validate/set the scope
788 * zone identifier.
789 */
790 dst6 = ifra->ifra_dstaddr;
791 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) != 0 &&
792 (dst6.sin6_family == AF_INET6)) {
793 int scopeid;
794
795 if ((error = in6_recoverscope(&dst6,
796 &ifra->ifra_dstaddr.sin6_addr, ifp)) != 0)
797 return (error);
798 if (in6_addr2zoneid(ifp, &dst6.sin6_addr, &scopeid))
799 return (EINVAL);
800 if (dst6.sin6_scope_id == 0) /* user omit to specify the ID. */
801 dst6.sin6_scope_id = scopeid;
802 else if (dst6.sin6_scope_id != scopeid)
803 return (EINVAL); /* scope ID mismatch. */
804 if ((error = in6_embedscope(&dst6.sin6_addr, &dst6, NULL, NULL))
805 != 0)
806 return (error);
807 dst6.sin6_scope_id = 0; /* XXX */
808 }
809 /*
810 * The destination address can be specified only for a p2p or a
811 * loopback interface. If specified, the corresponding prefix length
812 * must be 128.
813 */
814 if (ifra->ifra_dstaddr.sin6_family == AF_INET6) {
815 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0) {
816 nd6log((LOG_INFO, "in6_update_ifa: a destination can "
817 "be specified for a p2p or a loopback IF only\n"));
818 return (EINVAL);
819 }
820 if (plen != 128) {
821 nd6log((LOG_INFO, "in6_update_ifa: prefixlen should "
822 "be 128 when dstaddr is specified\n"));
823 return (EINVAL);
824 }
825 }
826 /* lifetime consistency check */
827 lt = &ifra->ifra_lifetime;
828 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
829 && lt->ia6t_vltime + time_second < time_second) {
830 return EINVAL;
831 }
832 if (lt->ia6t_vltime == 0) {
833 /*
834 * the following log might be noisy, but this is a typical
835 * configuration mistake or a tool's bug.
836 */
837 nd6log((LOG_INFO,
838 "in6_update_ifa: valid lifetime is 0 for %s\n",
839 ip6_sprintf(&ifra->ifra_addr.sin6_addr)));
840 }
841 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
842 && lt->ia6t_pltime + time_second < time_second) {
843 return EINVAL;
844 }
845
846 /*
847 * If this is a new address, allocate a new ifaddr and link it
848 * into chains.
849 */
850 if (ia == NULL) {
851 hostIsNew = 1;
852 /*
853 * When in6_update_ifa() is called in a process of a received
854 * RA, it is called under an interrupt context. So, we should
855 * call malloc with M_NOWAIT.
856 */
857 ia = (struct in6_ifaddr *) malloc(sizeof(*ia), M_IFADDR,
858 M_NOWAIT);
859 if (ia == NULL)
860 return (ENOBUFS);
861 bzero((caddr_t)ia, sizeof(*ia));
862 /* Initialize the address and masks */
863 IFA_LOCK_INIT(&ia->ia_ifa);
864 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
865 ia->ia_addr.sin6_family = AF_INET6;
866 ia->ia_addr.sin6_len = sizeof(ia->ia_addr);
867 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
868 /*
869 * XXX: some functions expect that ifa_dstaddr is not
870 * NULL for p2p interfaces.
871 */
872 ia->ia_ifa.ifa_dstaddr =
873 (struct sockaddr *)&ia->ia_dstaddr;
874 } else {
875 ia->ia_ifa.ifa_dstaddr = NULL;
876 }
877 ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask;
878
879 ia->ia_ifp = ifp;
880 if ((oia = in6_ifaddr) != NULL) {
881 for ( ; oia->ia_next; oia = oia->ia_next)
882 continue;
883 oia->ia_next = ia;
884 } else
885 in6_ifaddr = ia;
886
887 ia->ia_ifa.ifa_refcnt = 1;
888 TAILQ_INSERT_TAIL(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
889 }
890
891 /* set prefix mask */
892 if (ifra->ifra_prefixmask.sin6_len) {
893 /*
894 * We prohibit changing the prefix length of an existing
895 * address, because
896 * + such an operation should be rare in IPv6, and
897 * + the operation would confuse prefix management.
898 */
899 if (ia->ia_prefixmask.sin6_len &&
900 in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL) != plen) {
901 nd6log((LOG_INFO, "in6_update_ifa: the prefix length of an"
902 " existing (%s) address should not be changed\n",
903 ip6_sprintf(&ia->ia_addr.sin6_addr)));
904 error = EINVAL;
905 goto unlink;
906 }
907 ia->ia_prefixmask = ifra->ifra_prefixmask;
908 }
909
910 /*
911 * If a new destination address is specified, scrub the old one and
912 * install the new destination. Note that the interface must be
913 * p2p or loopback (see the check above.)
914 */
915 if (dst6.sin6_family == AF_INET6 &&
916 !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia->ia_dstaddr.sin6_addr)) {
917 int e;
918
919 if ((ia->ia_flags & IFA_ROUTE) != 0 &&
920 (e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST)) != 0) {
921 nd6log((LOG_ERR, "in6_update_ifa: failed to remove "
922 "a route to the old destination: %s\n",
923 ip6_sprintf(&ia->ia_addr.sin6_addr)));
924 /* proceed anyway... */
925 } else
926 ia->ia_flags &= ~IFA_ROUTE;
927 ia->ia_dstaddr = dst6;
928 }
929
930 /* reset the interface and routing table appropriately. */
931 if ((error = in6_ifinit(ifp, ia, &ifra->ifra_addr, hostIsNew)) != 0)
932 goto unlink;
933
934 /*
935 * Beyond this point, we should call in6_purgeaddr upon an error,
936 * not just go to unlink.
937 */
938
939 if ((ifp->if_flags & IFF_MULTICAST) != 0) {
940 struct sockaddr_in6 mltaddr, mltmask;
941 struct in6_multi *in6m;
942
943 if (hostIsNew) {
944 /* join solicited multicast addr for new host id */
945 struct in6_addr llsol;
946
947 bzero(&llsol, sizeof(struct in6_addr));
948 llsol.s6_addr16[0] = htons(0xff02);
949 llsol.s6_addr16[1] = htons(ifp->if_index);
950 llsol.s6_addr32[1] = 0;
951 llsol.s6_addr32[2] = htonl(1);
952 llsol.s6_addr32[3] =
953 ifra->ifra_addr.sin6_addr.s6_addr32[3];
954 llsol.s6_addr8[12] = 0xff;
955 (void)in6_addmulti(&llsol, ifp, &error);
956 if (error != 0) {
957 nd6log((LOG_WARNING,
958 "in6_update_ifa: addmulti failed for "
959 "%s on %s (errno=%d)\n",
960 ip6_sprintf(&llsol), if_name(ifp),
961 error));
962 in6_purgeaddr((struct ifaddr *)ia);
963 return (error);
964 }
965 }
966
967 bzero(&mltmask, sizeof(mltmask));
968 mltmask.sin6_len = sizeof(struct sockaddr_in6);
969 mltmask.sin6_family = AF_INET6;
970 mltmask.sin6_addr = in6mask32;
971
972 /*
973 * join link-local all-nodes address
974 */
975 bzero(&mltaddr, sizeof(mltaddr));
976 mltaddr.sin6_len = sizeof(struct sockaddr_in6);
977 mltaddr.sin6_family = AF_INET6;
978 mltaddr.sin6_addr = in6addr_linklocal_allnodes;
979 mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
980
981 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
982 if (in6m == NULL) {
983 rtrequest(RTM_ADD,
984 (struct sockaddr *)&mltaddr,
985 (struct sockaddr *)&ia->ia_addr,
986 (struct sockaddr *)&mltmask,
987 RTF_UP|RTF_CLONING, /* xxx */
988 (struct rtentry **)0);
989 (void)in6_addmulti(&mltaddr.sin6_addr, ifp, &error);
990 if (error != 0) {
991 nd6log((LOG_WARNING,
992 "in6_update_ifa: addmulti failed for "
993 "%s on %s (errno=%d)\n",
994 ip6_sprintf(&mltaddr.sin6_addr),
995 if_name(ifp), error));
996 }
997 }
998
999 /*
1000 * join node information group address
1001 */
1002 #define hostnamelen strlen(hostname)
1003 if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr.sin6_addr)
1004 == 0) {
1005 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
1006 if (in6m == NULL && ia != NULL) {
1007 (void)in6_addmulti(&mltaddr.sin6_addr,
1008 ifp, &error);
1009 if (error != 0) {
1010 nd6log((LOG_WARNING, "in6_update_ifa: "
1011 "addmulti failed for "
1012 "%s on %s (errno=%d)\n",
1013 ip6_sprintf(&mltaddr.sin6_addr),
1014 if_name(ifp), error));
1015 }
1016 }
1017 }
1018 #undef hostnamelen
1019
1020 /*
1021 * join node-local all-nodes address, on loopback.
1022 * XXX: since "node-local" is obsoleted by interface-local,
1023 * we have to join the group on every interface with
1024 * some interface-boundary restriction.
1025 */
1026 if (ifp->if_flags & IFF_LOOPBACK) {
1027 struct in6_ifaddr *ia_loop;
1028
1029 struct in6_addr loop6 = in6addr_loopback;
1030 ia_loop = in6ifa_ifpwithaddr(ifp, &loop6);
1031
1032 mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
1033
1034 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
1035 if (in6m == NULL && ia_loop != NULL) {
1036 rtrequest(RTM_ADD,
1037 (struct sockaddr *)&mltaddr,
1038 (struct sockaddr *)&ia_loop->ia_addr,
1039 (struct sockaddr *)&mltmask,
1040 RTF_UP,
1041 (struct rtentry **)0);
1042 (void)in6_addmulti(&mltaddr.sin6_addr, ifp,
1043 &error);
1044 if (error != 0) {
1045 nd6log((LOG_WARNING, "in6_update_ifa: "
1046 "addmulti failed for %s on %s "
1047 "(errno=%d)\n",
1048 ip6_sprintf(&mltaddr.sin6_addr),
1049 if_name(ifp), error));
1050 }
1051 }
1052 }
1053 }
1054
1055 ia->ia6_flags = ifra->ifra_flags;
1056 ia->ia6_flags &= ~IN6_IFF_DUPLICATED; /*safety*/
1057 ia->ia6_flags &= ~IN6_IFF_NODAD; /* Mobile IPv6 */
1058
1059 ia->ia6_lifetime = ifra->ifra_lifetime;
1060 /* for sanity */
1061 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
1062 ia->ia6_lifetime.ia6t_expire =
1063 time_second + ia->ia6_lifetime.ia6t_vltime;
1064 } else
1065 ia->ia6_lifetime.ia6t_expire = 0;
1066 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
1067 ia->ia6_lifetime.ia6t_preferred =
1068 time_second + ia->ia6_lifetime.ia6t_pltime;
1069 } else
1070 ia->ia6_lifetime.ia6t_preferred = 0;
1071
1072 /*
1073 * Perform DAD, if needed.
1074 * XXX It may be of use, if we can administratively
1075 * disable DAD.
1076 */
1077 if (in6if_do_dad(ifp) && (ifra->ifra_flags & IN6_IFF_NODAD) == 0) {
1078 ia->ia6_flags |= IN6_IFF_TENTATIVE;
1079 nd6_dad_start((struct ifaddr *)ia, NULL);
1080 }
1081
1082 return (error);
1083
1084 unlink:
1085 /*
1086 * XXX: if a change of an existing address failed, keep the entry
1087 * anyway.
1088 */
1089 if (hostIsNew)
1090 in6_unlink_ifa(ia, ifp);
1091 return (error);
1092 }
1093
1094 void
1095 in6_purgeaddr(ifa)
1096 struct ifaddr *ifa;
1097 {
1098 struct ifnet *ifp = ifa->ifa_ifp;
1099 struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
1100
1101 /* stop DAD processing */
1102 nd6_dad_stop(ifa);
1103
1104 /*
1105 * delete route to the destination of the address being purged.
1106 * The interface must be p2p or loopback in this case.
1107 */
1108 if ((ia->ia_flags & IFA_ROUTE) != 0 && ia->ia_dstaddr.sin6_len != 0) {
1109 int e;
1110
1111 if ((e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST))
1112 != 0) {
1113 log(LOG_ERR, "in6_purgeaddr: failed to remove "
1114 "a route to the p2p destination: %s on %s, "
1115 "errno=%d\n",
1116 ip6_sprintf(&ia->ia_addr.sin6_addr), if_name(ifp),
1117 e);
1118 /* proceed anyway... */
1119 } else
1120 ia->ia_flags &= ~IFA_ROUTE;
1121 }
1122
1123 /* Remove ownaddr's loopback rtentry, if it exists. */
1124 in6_ifremloop(&(ia->ia_ifa));
1125
1126 if (ifp->if_flags & IFF_MULTICAST) {
1127 /*
1128 * delete solicited multicast addr for deleting host id
1129 */
1130 struct in6_multi *in6m;
1131 struct in6_addr llsol;
1132 bzero(&llsol, sizeof(struct in6_addr));
1133 llsol.s6_addr16[0] = htons(0xff02);
1134 llsol.s6_addr16[1] = htons(ifp->if_index);
1135 llsol.s6_addr32[1] = 0;
1136 llsol.s6_addr32[2] = htonl(1);
1137 llsol.s6_addr32[3] =
1138 ia->ia_addr.sin6_addr.s6_addr32[3];
1139 llsol.s6_addr8[12] = 0xff;
1140
1141 IN6_LOOKUP_MULTI(llsol, ifp, in6m);
1142 if (in6m)
1143 in6_delmulti(in6m);
1144 }
1145
1146 in6_unlink_ifa(ia, ifp);
1147 }
1148
1149 static void
1150 in6_unlink_ifa(ia, ifp)
1151 struct in6_ifaddr *ia;
1152 struct ifnet *ifp;
1153 {
1154 int plen, iilen;
1155 struct in6_ifaddr *oia;
1156 int s = splnet();
1157
1158 TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
1159
1160 oia = ia;
1161 if (oia == (ia = in6_ifaddr))
1162 in6_ifaddr = ia->ia_next;
1163 else {
1164 while (ia->ia_next && (ia->ia_next != oia))
1165 ia = ia->ia_next;
1166 if (ia->ia_next)
1167 ia->ia_next = oia->ia_next;
1168 else {
1169 /* search failed */
1170 printf("Couldn't unlink in6_ifaddr from in6_ifaddr\n");
1171 }
1172 }
1173
1174 if (oia->ia6_ifpr) { /* check for safety */
1175 plen = in6_mask2len(&oia->ia_prefixmask.sin6_addr, NULL);
1176 iilen = (sizeof(oia->ia_prefixmask.sin6_addr) << 3) - plen;
1177 in6_prefix_remove_ifid(iilen, oia);
1178 }
1179
1180 /*
1181 * When an autoconfigured address is being removed, release the
1182 * reference to the base prefix. Also, since the release might
1183 * affect the status of other (detached) addresses, call
1184 * pfxlist_onlink_check().
1185 */
1186 if ((oia->ia6_flags & IN6_IFF_AUTOCONF) != 0) {
1187 if (oia->ia6_ndpr == NULL) {
1188 nd6log((LOG_NOTICE, "in6_unlink_ifa: autoconf'ed address "
1189 "%p has no prefix\n", oia));
1190 } else {
1191 oia->ia6_ndpr->ndpr_refcnt--;
1192 oia->ia6_flags &= ~IN6_IFF_AUTOCONF;
1193 oia->ia6_ndpr = NULL;
1194 }
1195
1196 pfxlist_onlink_check();
1197 }
1198
1199 /*
1200 * release another refcnt for the link from in6_ifaddr.
1201 * Note that we should decrement the refcnt at least once for all *BSD.
1202 */
1203 IFAFREE(&oia->ia_ifa);
1204
1205 splx(s);
1206 }
1207
1208 void
1209 in6_purgeif(ifp)
1210 struct ifnet *ifp;
1211 {
1212 struct ifaddr *ifa, *nifa;
1213
1214 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; ifa = nifa) {
1215 nifa = TAILQ_NEXT(ifa, ifa_list);
1216 if (ifa->ifa_addr->sa_family != AF_INET6)
1217 continue;
1218 in6_purgeaddr(ifa);
1219 }
1220
1221 in6_ifdetach(ifp);
1222 }
1223
1224 /*
1225 * SIOC[GAD]LIFADDR.
1226 * SIOCGLIFADDR: get first address. (?)
1227 * SIOCGLIFADDR with IFLR_PREFIX:
1228 * get first address that matches the specified prefix.
1229 * SIOCALIFADDR: add the specified address.
1230 * SIOCALIFADDR with IFLR_PREFIX:
1231 * add the specified prefix, filling hostid part from
1232 * the first link-local address. prefixlen must be <= 64.
1233 * SIOCDLIFADDR: delete the specified address.
1234 * SIOCDLIFADDR with IFLR_PREFIX:
1235 * delete the first address that matches the specified prefix.
1236 * return values:
1237 * EINVAL on invalid parameters
1238 * EADDRNOTAVAIL on prefix match failed/specified address not found
1239 * other values may be returned from in6_ioctl()
1240 *
1241 * NOTE: SIOCALIFADDR(with IFLR_PREFIX set) allows prefixlen less than 64.
1242 * this is to accomodate address naming scheme other than RFC2374,
1243 * in the future.
1244 * RFC2373 defines interface id to be 64bit, but it allows non-RFC2374
1245 * address encoding scheme. (see figure on page 8)
1246 */
1247 static int
1248 in6_lifaddr_ioctl(so, cmd, data, ifp, td)
1249 struct socket *so;
1250 u_long cmd;
1251 caddr_t data;
1252 struct ifnet *ifp;
1253 struct thread *td;
1254 {
1255 struct if_laddrreq *iflr = (struct if_laddrreq *)data;
1256 struct ifaddr *ifa;
1257 struct sockaddr *sa;
1258
1259 /* sanity checks */
1260 if (!data || !ifp) {
1261 panic("invalid argument to in6_lifaddr_ioctl");
1262 /* NOTREACHED */
1263 }
1264
1265 switch (cmd) {
1266 case SIOCGLIFADDR:
1267 /* address must be specified on GET with IFLR_PREFIX */
1268 if ((iflr->flags & IFLR_PREFIX) == 0)
1269 break;
1270 /* FALLTHROUGH */
1271 case SIOCALIFADDR:
1272 case SIOCDLIFADDR:
1273 /* address must be specified on ADD and DELETE */
1274 sa = (struct sockaddr *)&iflr->addr;
1275 if (sa->sa_family != AF_INET6)
1276 return EINVAL;
1277 if (sa->sa_len != sizeof(struct sockaddr_in6))
1278 return EINVAL;
1279 /* XXX need improvement */
1280 sa = (struct sockaddr *)&iflr->dstaddr;
1281 if (sa->sa_family && sa->sa_family != AF_INET6)
1282 return EINVAL;
1283 if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in6))
1284 return EINVAL;
1285 break;
1286 default: /* shouldn't happen */
1287 #if 0
1288 panic("invalid cmd to in6_lifaddr_ioctl");
1289 /* NOTREACHED */
1290 #else
1291 return EOPNOTSUPP;
1292 #endif
1293 }
1294 if (sizeof(struct in6_addr) * 8 < iflr->prefixlen)
1295 return EINVAL;
1296
1297 switch (cmd) {
1298 case SIOCALIFADDR:
1299 {
1300 struct in6_aliasreq ifra;
1301 struct in6_addr *hostid = NULL;
1302 int prefixlen;
1303
1304 if ((iflr->flags & IFLR_PREFIX) != 0) {
1305 struct sockaddr_in6 *sin6;
1306
1307 /*
1308 * hostid is to fill in the hostid part of the
1309 * address. hostid points to the first link-local
1310 * address attached to the interface.
1311 */
1312 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0);
1313 if (!ifa)
1314 return EADDRNOTAVAIL;
1315 hostid = IFA_IN6(ifa);
1316
1317 /* prefixlen must be <= 64. */
1318 if (64 < iflr->prefixlen)
1319 return EINVAL;
1320 prefixlen = iflr->prefixlen;
1321
1322 /* hostid part must be zero. */
1323 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1324 if (sin6->sin6_addr.s6_addr32[2] != 0
1325 || sin6->sin6_addr.s6_addr32[3] != 0) {
1326 return EINVAL;
1327 }
1328 } else
1329 prefixlen = iflr->prefixlen;
1330
1331 /* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
1332 bzero(&ifra, sizeof(ifra));
1333 bcopy(iflr->iflr_name, ifra.ifra_name, sizeof(ifra.ifra_name));
1334
1335 bcopy(&iflr->addr, &ifra.ifra_addr,
1336 ((struct sockaddr *)&iflr->addr)->sa_len);
1337 if (hostid) {
1338 /* fill in hostid part */
1339 ifra.ifra_addr.sin6_addr.s6_addr32[2] =
1340 hostid->s6_addr32[2];
1341 ifra.ifra_addr.sin6_addr.s6_addr32[3] =
1342 hostid->s6_addr32[3];
1343 }
1344
1345 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /* XXX */
1346 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
1347 ((struct sockaddr *)&iflr->dstaddr)->sa_len);
1348 if (hostid) {
1349 ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] =
1350 hostid->s6_addr32[2];
1351 ifra.ifra_dstaddr.sin6_addr.s6_addr32[3] =
1352 hostid->s6_addr32[3];
1353 }
1354 }
1355
1356 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
1357 in6_prefixlen2mask(&ifra.ifra_prefixmask.sin6_addr, prefixlen);
1358
1359 ifra.ifra_flags = iflr->flags & ~IFLR_PREFIX;
1360 return in6_control(so, SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, td);
1361 }
1362 case SIOCGLIFADDR:
1363 case SIOCDLIFADDR:
1364 {
1365 struct in6_ifaddr *ia;
1366 struct in6_addr mask, candidate, match;
1367 struct sockaddr_in6 *sin6;
1368 int cmp;
1369
1370 bzero(&mask, sizeof(mask));
1371 if (iflr->flags & IFLR_PREFIX) {
1372 /* lookup a prefix rather than address. */
1373 in6_prefixlen2mask(&mask, iflr->prefixlen);
1374
1375 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1376 bcopy(&sin6->sin6_addr, &match, sizeof(match));
1377 match.s6_addr32[0] &= mask.s6_addr32[0];
1378 match.s6_addr32[1] &= mask.s6_addr32[1];
1379 match.s6_addr32[2] &= mask.s6_addr32[2];
1380 match.s6_addr32[3] &= mask.s6_addr32[3];
1381
1382 /* if you set extra bits, that's wrong */
1383 if (bcmp(&match, &sin6->sin6_addr, sizeof(match)))
1384 return EINVAL;
1385
1386 cmp = 1;
1387 } else {
1388 if (cmd == SIOCGLIFADDR) {
1389 /* on getting an address, take the 1st match */
1390 cmp = 0; /* XXX */
1391 } else {
1392 /* on deleting an address, do exact match */
1393 in6_prefixlen2mask(&mask, 128);
1394 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1395 bcopy(&sin6->sin6_addr, &match, sizeof(match));
1396
1397 cmp = 1;
1398 }
1399 }
1400
1401 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1402 if (ifa->ifa_addr->sa_family != AF_INET6)
1403 continue;
1404 if (!cmp)
1405 break;
1406
1407 bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate));
1408 /*
1409 * XXX: this is adhoc, but is necessary to allow
1410 * a user to specify fe80::/64 (not /10) for a
1411 * link-local address.
1412 */
1413 if (IN6_IS_ADDR_LINKLOCAL(&candidate))
1414 candidate.s6_addr16[1] = 0;
1415 candidate.s6_addr32[0] &= mask.s6_addr32[0];
1416 candidate.s6_addr32[1] &= mask.s6_addr32[1];
1417 candidate.s6_addr32[2] &= mask.s6_addr32[2];
1418 candidate.s6_addr32[3] &= mask.s6_addr32[3];
1419 if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
1420 break;
1421 }
1422 if (!ifa)
1423 return EADDRNOTAVAIL;
1424 ia = ifa2ia6(ifa);
1425
1426 if (cmd == SIOCGLIFADDR) {
1427 struct sockaddr_in6 *s6;
1428
1429 /* fill in the if_laddrreq structure */
1430 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len);
1431 s6 = (struct sockaddr_in6 *)&iflr->addr;
1432 if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) {
1433 s6->sin6_addr.s6_addr16[1] = 0;
1434 if (in6_addr2zoneid(ifp, &s6->sin6_addr,
1435 &s6->sin6_scope_id))
1436 return (EINVAL);/* XXX */
1437 }
1438 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1439 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
1440 ia->ia_dstaddr.sin6_len);
1441 s6 = (struct sockaddr_in6 *)&iflr->dstaddr;
1442 if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) {
1443 s6->sin6_addr.s6_addr16[1] = 0;
1444 if (in6_addr2zoneid(ifp,
1445 &s6->sin6_addr, &s6->sin6_scope_id))
1446 return (EINVAL); /* EINVAL */
1447 }
1448 } else
1449 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
1450
1451 iflr->prefixlen =
1452 in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
1453
1454 iflr->flags = ia->ia6_flags; /* XXX */
1455
1456 return 0;
1457 } else {
1458 struct in6_aliasreq ifra;
1459
1460 /* fill in6_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
1461 bzero(&ifra, sizeof(ifra));
1462 bcopy(iflr->iflr_name, ifra.ifra_name,
1463 sizeof(ifra.ifra_name));
1464
1465 bcopy(&ia->ia_addr, &ifra.ifra_addr,
1466 ia->ia_addr.sin6_len);
1467 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1468 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
1469 ia->ia_dstaddr.sin6_len);
1470 } else {
1471 bzero(&ifra.ifra_dstaddr,
1472 sizeof(ifra.ifra_dstaddr));
1473 }
1474 bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr,
1475 ia->ia_prefixmask.sin6_len);
1476
1477 ifra.ifra_flags = ia->ia6_flags;
1478 return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra,
1479 ifp, td);
1480 }
1481 }
1482 }
1483
1484 return EOPNOTSUPP; /* just for safety */
1485 }
1486
1487 /*
1488 * Initialize an interface's intetnet6 address
1489 * and routing table entry.
1490 */
1491 static int
1492 in6_ifinit(ifp, ia, sin6, newhost)
1493 struct ifnet *ifp;
1494 struct in6_ifaddr *ia;
1495 struct sockaddr_in6 *sin6;
1496 int newhost;
1497 {
1498 int error = 0, plen, ifacount = 0;
1499 int s = splimp();
1500 struct ifaddr *ifa;
1501
1502 /*
1503 * Give the interface a chance to initialize
1504 * if this is its first address,
1505 * and to validate the address if necessary.
1506 */
1507 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1508 if (ifa->ifa_addr == NULL)
1509 continue; /* just for safety */
1510 if (ifa->ifa_addr->sa_family != AF_INET6)
1511 continue;
1512 ifacount++;
1513 }
1514
1515 ia->ia_addr = *sin6;
1516
1517 if (ifacount <= 1 && ifp->if_ioctl &&
1518 (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
1519 splx(s);
1520 return (error);
1521 }
1522 splx(s);
1523
1524 ia->ia_ifa.ifa_metric = ifp->if_metric;
1525
1526 /* we could do in(6)_socktrim here, but just omit it at this moment. */
1527
1528 /*
1529 * Special case:
1530 * If the destination address is specified for a point-to-point
1531 * interface, install a route to the destination as an interface
1532 * direct route.
1533 */
1534 plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
1535 if (plen == 128 && ia->ia_dstaddr.sin6_family == AF_INET6) {
1536 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD,
1537 RTF_UP | RTF_HOST)) != 0)
1538 return (error);
1539 ia->ia_flags |= IFA_ROUTE;
1540 }
1541 if (plen < 128) {
1542 /*
1543 * The RTF_CLONING flag is necessary for in6_is_ifloop_auto().
1544 */
1545 ia->ia_ifa.ifa_flags |= RTF_CLONING;
1546 }
1547
1548 /* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
1549 if (newhost) {
1550 /* set the rtrequest function to create llinfo */
1551 ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
1552 in6_ifaddloop(&(ia->ia_ifa));
1553 }
1554
1555 return (error);
1556 }
1557
1558 /*
1559 * Add an address to the list of IP6 multicast addresses for a
1560 * given interface.
1561 */
1562 struct in6_multi *
1563 in6_addmulti(maddr6, ifp, errorp)
1564 struct in6_addr *maddr6;
1565 struct ifnet *ifp;
1566 int *errorp;
1567 {
1568 struct in6_multi *in6m;
1569 struct sockaddr_in6 sin6;
1570 struct ifmultiaddr *ifma;
1571 int s = splnet();
1572
1573 *errorp = 0;
1574
1575 /*
1576 * Call generic routine to add membership or increment
1577 * refcount. It wants addresses in the form of a sockaddr,
1578 * so we build one here (being careful to zero the unused bytes).
1579 */
1580 bzero(&sin6, sizeof sin6);
1581 sin6.sin6_family = AF_INET6;
1582 sin6.sin6_len = sizeof sin6;
1583 sin6.sin6_addr = *maddr6;
1584 *errorp = if_addmulti(ifp, (struct sockaddr *)&sin6, &ifma);
1585 if (*errorp) {
1586 splx(s);
1587 return 0;
1588 }
1589
1590 /*
1591 * If ifma->ifma_protospec is null, then if_addmulti() created
1592 * a new record. Otherwise, we are done.
1593 */
1594 if (ifma->ifma_protospec != 0)
1595 return ifma->ifma_protospec;
1596
1597 /* XXX - if_addmulti uses M_WAITOK. Can this really be called
1598 at interrupt time? If so, need to fix if_addmulti. XXX */
1599 in6m = (struct in6_multi *)malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT);
1600 if (in6m == NULL) {
1601 splx(s);
1602 return (NULL);
1603 }
1604
1605 bzero(in6m, sizeof *in6m);
1606 in6m->in6m_addr = *maddr6;
1607 in6m->in6m_ifp = ifp;
1608 in6m->in6m_ifma = ifma;
1609 ifma->ifma_protospec = in6m;
1610 LIST_INSERT_HEAD(&in6_multihead, in6m, in6m_entry);
1611
1612 /*
1613 * Let MLD6 know that we have joined a new IPv6 multicast
1614 * group.
1615 */
1616 mld6_start_listening(in6m);
1617 splx(s);
1618 return (in6m);
1619 }
1620
1621 /*
1622 * Delete a multicast address record.
1623 */
1624 void
1625 in6_delmulti(in6m)
1626 struct in6_multi *in6m;
1627 {
1628 struct ifmultiaddr *ifma = in6m->in6m_ifma;
1629 int s = splnet();
1630
1631 if (ifma->ifma_refcount == 1) {
1632 /*
1633 * No remaining claims to this record; let MLD6 know
1634 * that we are leaving the multicast group.
1635 */
1636 mld6_stop_listening(in6m);
1637 ifma->ifma_protospec = 0;
1638 LIST_REMOVE(in6m, in6m_entry);
1639 free(in6m, M_IPMADDR);
1640 }
1641 /* XXX - should be separate API for when we have an ifma? */
1642 if_delmulti(ifma->ifma_ifp, ifma->ifma_addr);
1643 splx(s);
1644 }
1645
1646 /*
1647 * Find an IPv6 interface link-local address specific to an interface.
1648 */
1649 struct in6_ifaddr *
1650 in6ifa_ifpforlinklocal(ifp, ignoreflags)
1651 struct ifnet *ifp;
1652 int ignoreflags;
1653 {
1654 struct ifaddr *ifa;
1655
1656 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1657 if (ifa->ifa_addr == NULL)
1658 continue; /* just for safety */
1659 if (ifa->ifa_addr->sa_family != AF_INET6)
1660 continue;
1661 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
1662 if ((((struct in6_ifaddr *)ifa)->ia6_flags &
1663 ignoreflags) != 0)
1664 continue;
1665 break;
1666 }
1667 }
1668
1669 return ((struct in6_ifaddr *)ifa);
1670 }
1671
1672
1673 /*
1674 * find the internet address corresponding to a given interface and address.
1675 */
1676 struct in6_ifaddr *
1677 in6ifa_ifpwithaddr(ifp, addr)
1678 struct ifnet *ifp;
1679 struct in6_addr *addr;
1680 {
1681 struct ifaddr *ifa;
1682
1683 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1684 if (ifa->ifa_addr == NULL)
1685 continue; /* just for safety */
1686 if (ifa->ifa_addr->sa_family != AF_INET6)
1687 continue;
1688 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
1689 break;
1690 }
1691
1692 return ((struct in6_ifaddr *)ifa);
1693 }
1694
1695 /*
1696 * Convert IP6 address to printable (loggable) representation.
1697 */
1698 static char digits[] = "0123456789abcdef";
1699 static int ip6round = 0;
1700 char *
1701 ip6_sprintf(addr)
1702 const struct in6_addr *addr;
1703 {
1704 static char ip6buf[8][48];
1705 int i;
1706 char *cp;
1707 const u_short *a = (const u_short *)addr;
1708 const u_char *d;
1709 int dcolon = 0;
1710
1711 ip6round = (ip6round + 1) & 7;
1712 cp = ip6buf[ip6round];
1713
1714 for (i = 0; i < 8; i++) {
1715 if (dcolon == 1) {
1716 if (*a == 0) {
1717 if (i == 7)
1718 *cp++ = ':';
1719 a++;
1720 continue;
1721 } else
1722 dcolon = 2;
1723 }
1724 if (*a == 0) {
1725 if (dcolon == 0 && *(a + 1) == 0) {
1726 if (i == 0)
1727 *cp++ = ':';
1728 *cp++ = ':';
1729 dcolon = 1;
1730 } else {
1731 *cp++ = '';
1732 *cp++ = ':';
1733 }
1734 a++;
1735 continue;
1736 }
1737 d = (const u_char *)a;
1738 *cp++ = digits[*d >> 4];
1739 *cp++ = digits[*d++ & 0xf];
1740 *cp++ = digits[*d >> 4];
1741 *cp++ = digits[*d & 0xf];
1742 *cp++ = ':';
1743 a++;
1744 }
1745 *--cp = 0;
1746 return (ip6buf[ip6round]);
1747 }
1748
1749 int
1750 in6_localaddr(in6)
1751 struct in6_addr *in6;
1752 {
1753 struct in6_ifaddr *ia;
1754
1755 if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6))
1756 return 1;
1757
1758 for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
1759 if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr,
1760 &ia->ia_prefixmask.sin6_addr)) {
1761 return 1;
1762 }
1763 }
1764
1765 return (0);
1766 }
1767
1768 int
1769 in6_is_addr_deprecated(sa6)
1770 struct sockaddr_in6 *sa6;
1771 {
1772 struct in6_ifaddr *ia;
1773
1774 for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
1775 if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr,
1776 &sa6->sin6_addr) &&
1777 (ia->ia6_flags & IN6_IFF_DEPRECATED) != 0)
1778 return (1); /* true */
1779
1780 /* XXX: do we still have to go thru the rest of the list? */
1781 }
1782
1783 return (0); /* false */
1784 }
1785
1786 /*
1787 * return length of part which dst and src are equal
1788 * hard coding...
1789 */
1790 int
1791 in6_matchlen(src, dst)
1792 struct in6_addr *src, *dst;
1793 {
1794 int match = 0;
1795 u_char *s = (u_char *)src, *d = (u_char *)dst;
1796 u_char *lim = s + 16, r;
1797
1798 while (s < lim)
1799 if ((r = (*d++ ^ *s++)) != 0) {
1800 while (r < 128) {
1801 match++;
1802 r <<= 1;
1803 }
1804 break;
1805 } else
1806 match += 8;
1807 return match;
1808 }
1809
1810 /* XXX: to be scope conscious */
1811 int
1812 in6_are_prefix_equal(p1, p2, len)
1813 struct in6_addr *p1, *p2;
1814 int len;
1815 {
1816 int bytelen, bitlen;
1817
1818 /* sanity check */
1819 if (0 > len || len > 128) {
1820 log(LOG_ERR, "in6_are_prefix_equal: invalid prefix length(%d)\n",
1821 len);
1822 return (0);
1823 }
1824
1825 bytelen = len / 8;
1826 bitlen = len % 8;
1827
1828 if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen))
1829 return (0);
1830 if (p1->s6_addr[bytelen] >> (8 - bitlen) !=
1831 p2->s6_addr[bytelen] >> (8 - bitlen))
1832 return (0);
1833
1834 return (1);
1835 }
1836
1837 void
1838 in6_prefixlen2mask(maskp, len)
1839 struct in6_addr *maskp;
1840 int len;
1841 {
1842 u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
1843 int bytelen, bitlen, i;
1844
1845 /* sanity check */
1846 if (0 > len || len > 128) {
1847 log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n",
1848 len);
1849 return;
1850 }
1851
1852 bzero(maskp, sizeof(*maskp));
1853 bytelen = len / 8;
1854 bitlen = len % 8;
1855 for (i = 0; i < bytelen; i++)
1856 maskp->s6_addr[i] = 0xff;
1857 if (bitlen)
1858 maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
1859 }
1860
1861 /*
1862 * return the best address out of the same scope. if no address was
1863 * found, return the first valid address from designated IF.
1864 */
1865 struct in6_ifaddr *
1866 in6_ifawithifp(ifp, dst)
1867 struct ifnet *ifp;
1868 struct in6_addr *dst;
1869 {
1870 int dst_scope = in6_addrscope(dst), blen = -1, tlen;
1871 struct ifaddr *ifa;
1872 struct in6_ifaddr *besta = 0;
1873 struct in6_ifaddr *dep[2]; /* last-resort: deprecated */
1874
1875 dep[0] = dep[1] = NULL;
1876
1877 /*
1878 * We first look for addresses in the same scope.
1879 * If there is one, return it.
1880 * If two or more, return one which matches the dst longest.
1881 * If none, return one of global addresses assigned other ifs.
1882 */
1883 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1884 if (ifa->ifa_addr->sa_family != AF_INET6)
1885 continue;
1886 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
1887 continue; /* XXX: is there any case to allow anycast? */
1888 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
1889 continue; /* don't use this interface */
1890 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
1891 continue;
1892 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
1893 if (ip6_use_deprecated)
1894 dep[0] = (struct in6_ifaddr *)ifa;
1895 continue;
1896 }
1897
1898 if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
1899 /*
1900 * call in6_matchlen() as few as possible
1901 */
1902 if (besta) {
1903 if (blen == -1)
1904 blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst);
1905 tlen = in6_matchlen(IFA_IN6(ifa), dst);
1906 if (tlen > blen) {
1907 blen = tlen;
1908 besta = (struct in6_ifaddr *)ifa;
1909 }
1910 } else
1911 besta = (struct in6_ifaddr *)ifa;
1912 }
1913 }
1914 if (besta)
1915 return (besta);
1916
1917 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1918 if (ifa->ifa_addr->sa_family != AF_INET6)
1919 continue;
1920 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
1921 continue; /* XXX: is there any case to allow anycast? */
1922 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
1923 continue; /* don't use this interface */
1924 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
1925 continue;
1926 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
1927 if (ip6_use_deprecated)
1928 dep[1] = (struct in6_ifaddr *)ifa;
1929 continue;
1930 }
1931
1932 return (struct in6_ifaddr *)ifa;
1933 }
1934
1935 /* use the last-resort values, that are, deprecated addresses */
1936 if (dep[0])
1937 return dep[0];
1938 if (dep[1])
1939 return dep[1];
1940
1941 return NULL;
1942 }
1943
1944 /*
1945 * perform DAD when interface becomes IFF_UP.
1946 */
1947 void
1948 in6_if_up(ifp)
1949 struct ifnet *ifp;
1950 {
1951 struct ifaddr *ifa;
1952 struct in6_ifaddr *ia;
1953 int dad_delay; /* delay ticks before DAD output */
1954
1955 /*
1956 * special cases, like 6to4, are handled in in6_ifattach
1957 */
1958 in6_ifattach(ifp, NULL);
1959
1960 dad_delay = 0;
1961 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1962 if (ifa->ifa_addr->sa_family != AF_INET6)
1963 continue;
1964 ia = (struct in6_ifaddr *)ifa;
1965 if (ia->ia6_flags & IN6_IFF_TENTATIVE)
1966 nd6_dad_start(ifa, &dad_delay);
1967 }
1968 }
1969
1970 int
1971 in6if_do_dad(ifp)
1972 struct ifnet *ifp;
1973 {
1974 if ((ifp->if_flags & IFF_LOOPBACK) != 0)
1975 return (0);
1976
1977 switch (ifp->if_type) {
1978 #ifdef IFT_DUMMY
1979 case IFT_DUMMY:
1980 #endif
1981 case IFT_FAITH:
1982 /*
1983 * These interfaces do not have the IFF_LOOPBACK flag,
1984 * but loop packets back. We do not have to do DAD on such
1985 * interfaces. We should even omit it, because loop-backed
1986 * NS would confuse the DAD procedure.
1987 */
1988 return (0);
1989 default:
1990 /*
1991 * Our DAD routine requires the interface up and running.
1992 * However, some interfaces can be up before the RUNNING
1993 * status. Additionaly, users may try to assign addresses
1994 * before the interface becomes up (or running).
1995 * We simply skip DAD in such a case as a work around.
1996 * XXX: we should rather mark "tentative" on such addresses,
1997 * and do DAD after the interface becomes ready.
1998 */
1999 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) !=
2000 (IFF_UP|IFF_RUNNING))
2001 return (0);
2002
2003 return (1);
2004 }
2005 }
2006
2007 /*
2008 * Calculate max IPv6 MTU through all the interfaces and store it
2009 * to in6_maxmtu.
2010 */
2011 void
2012 in6_setmaxmtu()
2013 {
2014 unsigned long maxmtu = 0;
2015 struct ifnet *ifp;
2016
2017 IFNET_RLOCK();
2018 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) {
2019 /* this function can be called during ifnet initialization */
2020 if (!ifp->if_afdata[AF_INET6])
2021 continue;
2022 if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
2023 IN6_LINKMTU(ifp) > maxmtu)
2024 maxmtu = IN6_LINKMTU(ifp);
2025 }
2026 IFNET_RUNLOCK();
2027 if (maxmtu) /* update only when maxmtu is positive */
2028 in6_maxmtu = maxmtu;
2029 }
2030
2031 void *
2032 in6_domifattach(ifp)
2033 struct ifnet *ifp;
2034 {
2035 struct in6_ifextra *ext;
2036
2037 ext = (struct in6_ifextra *)malloc(sizeof(*ext), M_IFADDR, M_WAITOK);
2038 bzero(ext, sizeof(*ext));
2039
2040 ext->in6_ifstat = (struct in6_ifstat *)malloc(sizeof(struct in6_ifstat),
2041 M_IFADDR, M_WAITOK);
2042 bzero(ext->in6_ifstat, sizeof(*ext->in6_ifstat));
2043
2044 ext->icmp6_ifstat =
2045 (struct icmp6_ifstat *)malloc(sizeof(struct icmp6_ifstat),
2046 M_IFADDR, M_WAITOK);
2047 bzero(ext->icmp6_ifstat, sizeof(*ext->icmp6_ifstat));
2048
2049 ext->nd_ifinfo = nd6_ifattach(ifp);
2050 ext->scope6_id = scope6_ifattach(ifp);
2051 return ext;
2052 }
2053
2054 void
2055 in6_domifdetach(ifp, aux)
2056 struct ifnet *ifp;
2057 void *aux;
2058 {
2059 struct in6_ifextra *ext = (struct in6_ifextra *)aux;
2060
2061 scope6_ifdetach(ext->scope6_id);
2062 nd6_ifdetach(ext->nd_ifinfo);
2063 free(ext->in6_ifstat, M_IFADDR);
2064 free(ext->icmp6_ifstat, M_IFADDR);
2065 free(ext, M_IFADDR);
2066 }
2067
2068 /*
2069 * Convert sockaddr_in6 to sockaddr_in. Original sockaddr_in6 must be
2070 * v4 mapped addr or v4 compat addr
2071 */
2072 void
2073 in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
2074 {
2075 bzero(sin, sizeof(*sin));
2076 sin->sin_len = sizeof(struct sockaddr_in);
2077 sin->sin_family = AF_INET;
2078 sin->sin_port = sin6->sin6_port;
2079 sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3];
2080 }
2081
2082 /* Convert sockaddr_in to sockaddr_in6 in v4 mapped addr format. */
2083 void
2084 in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
2085 {
2086 bzero(sin6, sizeof(*sin6));
2087 sin6->sin6_len = sizeof(struct sockaddr_in6);
2088 sin6->sin6_family = AF_INET6;
2089 sin6->sin6_port = sin->sin_port;
2090 sin6->sin6_addr.s6_addr32[0] = 0;
2091 sin6->sin6_addr.s6_addr32[1] = 0;
2092 sin6->sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_SMP;
2093 sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr;
2094 }
2095
2096 /* Convert sockaddr_in6 into sockaddr_in. */
2097 void
2098 in6_sin6_2_sin_in_sock(struct sockaddr *nam)
2099 {
2100 struct sockaddr_in *sin_p;
2101 struct sockaddr_in6 sin6;
2102
2103 /*
2104 * Save original sockaddr_in6 addr and convert it
2105 * to sockaddr_in.
2106 */
2107 sin6 = *(struct sockaddr_in6 *)nam;
2108 sin_p = (struct sockaddr_in *)nam;
2109 in6_sin6_2_sin(sin_p, &sin6);
2110 }
2111
2112 /* Convert sockaddr_in into sockaddr_in6 in v4 mapped addr format. */
2113 void
2114 in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam)
2115 {
2116 struct sockaddr_in *sin_p;
2117 struct sockaddr_in6 *sin6_p;
2118
2119 MALLOC(sin6_p, struct sockaddr_in6 *, sizeof *sin6_p, M_SONAME,
2120 M_WAITOK);
2121 sin_p = (struct sockaddr_in *)*nam;
2122 in6_sin_2_v4mapsin6(sin_p, sin6_p);
2123 FREE(*nam, M_SONAME);
2124 *nam = (struct sockaddr *)sin6_p;
2125 }
Cache object: 2b1b579850dd492be3e60d4f5eaf3aec
|