Line data Source code
1 : /* $OpenBSD: in6.c,v 1.227 2018/05/12 09:43:02 tb Exp $ */
2 : /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 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. Neither the name of the University nor the names of its contributors
46 : * may be used to endorse or promote products derived from this software
47 : * without specific prior written permission.
48 : *
49 : * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 : * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 : * SUCH DAMAGE.
60 : *
61 : * @(#)in.c 8.2 (Berkeley) 11/15/93
62 : */
63 :
64 : #include "carp.h"
65 :
66 : #include <sys/param.h>
67 : #include <sys/ioctl.h>
68 : #include <sys/errno.h>
69 : #include <sys/malloc.h>
70 : #include <sys/socket.h>
71 : #include <sys/socketvar.h>
72 : #include <sys/sockio.h>
73 : #include <sys/mbuf.h>
74 : #include <sys/systm.h>
75 : #include <sys/time.h>
76 : #include <sys/kernel.h>
77 : #include <sys/syslog.h>
78 :
79 : #include <net/if.h>
80 : #include <net/if_dl.h>
81 : #include <net/if_types.h>
82 : #include <net/route.h>
83 :
84 : #include <netinet/in.h>
85 : #include <netinet/if_ether.h>
86 :
87 : #include <netinet6/in6_var.h>
88 : #include <netinet/ip6.h>
89 : #include <netinet6/ip6_var.h>
90 : #include <netinet6/nd6.h>
91 : #include <netinet6/mld6_var.h>
92 : #ifdef MROUTING
93 : #include <netinet6/ip6_mroute.h>
94 : #endif
95 : #include <netinet6/in6_ifattach.h>
96 : #if NCARP > 0
97 : #include <netinet/ip_carp.h>
98 : #endif
99 :
100 : /*
101 : * Definitions of some constant IP6 addresses.
102 : */
103 : const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
104 : const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
105 : const struct in6_addr in6addr_intfacelocal_allnodes =
106 : IN6ADDR_INTFACELOCAL_ALLNODES_INIT;
107 : const struct in6_addr in6addr_linklocal_allnodes =
108 : IN6ADDR_LINKLOCAL_ALLNODES_INIT;
109 : const struct in6_addr in6addr_linklocal_allrouters =
110 : IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
111 :
112 : const struct in6_addr in6mask0 = IN6MASK0;
113 : const struct in6_addr in6mask32 = IN6MASK32;
114 : const struct in6_addr in6mask64 = IN6MASK64;
115 : const struct in6_addr in6mask96 = IN6MASK96;
116 : const struct in6_addr in6mask128 = IN6MASK128;
117 :
118 : int in6_ioctl(u_long, caddr_t, struct ifnet *, int);
119 : int in6_ioctl_change_ifaddr(u_long, caddr_t, struct ifnet *);
120 : int in6_ioctl_get(u_long, caddr_t, struct ifnet *);
121 : int in6_check_embed_scope(struct sockaddr_in6 *, unsigned int);
122 : int in6_clear_scope_id(struct sockaddr_in6 *, unsigned int);
123 : int in6_ifinit(struct ifnet *, struct in6_ifaddr *, int);
124 : void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *);
125 :
126 : const struct sockaddr_in6 sa6_any = {
127 : sizeof(sa6_any), AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0
128 : };
129 :
130 : int
131 0 : in6_mask2len(struct in6_addr *mask, u_char *lim0)
132 : {
133 : int x = 0, y;
134 : u_char *lim = lim0, *p;
135 :
136 : /* ignore the scope_id part */
137 0 : if (lim0 == NULL || lim0 - (u_char *)mask > sizeof(*mask))
138 0 : lim = (u_char *)mask + sizeof(*mask);
139 0 : for (p = (u_char *)mask; p < lim; x++, p++) {
140 0 : if (*p != 0xff)
141 : break;
142 : }
143 : y = 0;
144 0 : if (p < lim) {
145 0 : for (y = 0; y < 8; y++) {
146 0 : if ((*p & (0x80 >> y)) == 0)
147 : break;
148 : }
149 : }
150 :
151 : /*
152 : * when the limit pointer is given, do a stricter check on the
153 : * remaining bits.
154 : */
155 0 : if (p < lim) {
156 0 : if (y != 0 && (*p & (0x00ff >> y)) != 0)
157 0 : return (-1);
158 0 : for (p = p + 1; p < lim; p++)
159 0 : if (*p != 0)
160 0 : return (-1);
161 : }
162 :
163 0 : return x * 8 + y;
164 0 : }
165 :
166 : int
167 0 : in6_nam2sin6(const struct mbuf *nam, struct sockaddr_in6 **sin6)
168 : {
169 0 : struct sockaddr *sa = mtod(nam, struct sockaddr *);
170 :
171 0 : if (nam->m_len < offsetof(struct sockaddr, sa_data))
172 0 : return EINVAL;
173 0 : if (sa->sa_family != AF_INET6)
174 0 : return EAFNOSUPPORT;
175 0 : if (sa->sa_len != nam->m_len)
176 0 : return EINVAL;
177 0 : if (sa->sa_len != sizeof(struct sockaddr_in6))
178 0 : return EINVAL;
179 0 : *sin6 = satosin6(sa);
180 :
181 0 : return 0;
182 0 : }
183 :
184 : int
185 0 : in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
186 : {
187 : int privileged;
188 : int error;
189 :
190 : privileged = 0;
191 0 : if ((so->so_state & SS_PRIV) != 0)
192 0 : privileged++;
193 :
194 0 : switch (cmd) {
195 : #ifdef MROUTING
196 : case SIOCGETSGCNT_IN6:
197 : case SIOCGETMIFCNT_IN6:
198 0 : error = mrt6_ioctl(so, cmd, data);
199 0 : break;
200 : #endif /* MROUTING */
201 : default:
202 0 : error = in6_ioctl(cmd, data, ifp, privileged);
203 0 : break;
204 : }
205 :
206 0 : return error;
207 : }
208 :
209 : int
210 0 : in6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
211 : {
212 0 : if (ifp == NULL)
213 0 : return (ENXIO);
214 :
215 0 : switch (cmd) {
216 : case SIOCGIFINFO_IN6:
217 : case SIOCGNBRINFO_IN6:
218 0 : return (nd6_ioctl(cmd, data, ifp));
219 : case SIOCGIFDSTADDR_IN6:
220 : case SIOCGIFNETMASK_IN6:
221 : case SIOCGIFAFLAG_IN6:
222 : case SIOCGIFALIFETIME_IN6:
223 0 : return (in6_ioctl_get(cmd, data, ifp));
224 : case SIOCAIFADDR_IN6:
225 : case SIOCDIFADDR_IN6:
226 0 : if (!privileged)
227 0 : return (EPERM);
228 0 : return (in6_ioctl_change_ifaddr(cmd, data, ifp));
229 : case SIOCSIFADDR:
230 : case SIOCSIFDSTADDR:
231 : case SIOCSIFBRDADDR:
232 : case SIOCSIFNETMASK:
233 : /*
234 : * Do not pass those ioctl to driver handler since they are not
235 : * properly set up. Instead just error out.
236 : */
237 0 : return (EINVAL);
238 : default:
239 0 : return (EOPNOTSUPP);
240 : }
241 0 : }
242 :
243 : int
244 0 : in6_ioctl_change_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp)
245 : {
246 0 : struct in6_ifreq *ifr = (struct in6_ifreq *)data;
247 : struct in6_ifaddr *ia6 = NULL;
248 0 : struct in6_aliasreq *ifra = (struct in6_aliasreq *)data;
249 : struct sockaddr_in6 *sa6;
250 : int error = 0, newifaddr = 0, plen;
251 :
252 : /*
253 : * Find address for this interface, if it exists.
254 : *
255 : * In netinet code, we have checked ifra_addr in SIOCSIF*ADDR operation
256 : * only, and used the first interface address as the target of other
257 : * operations (without checking ifra_addr). This was because netinet
258 : * code/API assumed at most 1 interface address per interface.
259 : * Since IPv6 allows a node to assign multiple addresses
260 : * on a single interface, we almost always look and check the
261 : * presence of ifra_addr, and reject invalid ones here.
262 : * It also decreases duplicated code among SIOC*_IN6 operations.
263 : */
264 0 : switch (cmd) {
265 : case SIOCAIFADDR_IN6:
266 0 : sa6 = &ifra->ifra_addr;
267 0 : break;
268 : case SIOCDIFADDR_IN6:
269 0 : sa6 = &ifr->ifr_addr;
270 0 : break;
271 : default:
272 0 : panic("unknown ioctl %lu", cmd);
273 : }
274 :
275 0 : NET_LOCK();
276 :
277 0 : if (sa6 && sa6->sin6_family == AF_INET6) {
278 0 : error = in6_check_embed_scope(sa6, ifp->if_index);
279 0 : if (error)
280 : goto err;
281 0 : error = in6_clear_scope_id(sa6, ifp->if_index);
282 0 : if (error)
283 : goto err;
284 0 : ia6 = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
285 0 : }
286 :
287 0 : switch (cmd) {
288 : case SIOCDIFADDR_IN6:
289 : /*
290 : * for IPv4, we look for existing in_ifaddr here to allow
291 : * "ifconfig if0 delete" to remove the first IPv4 address on
292 : * the interface. For IPv6, as the spec allows multiple
293 : * interface address from the day one, we consider "remove the
294 : * first one" semantics to be not preferable.
295 : */
296 0 : if (ia6 == NULL) {
297 : error = EADDRNOTAVAIL;
298 0 : break;
299 : }
300 : /*
301 : * We always require users to specify a valid IPv6 address for
302 : * the corresponding operation.
303 : */
304 0 : if (ifra->ifra_addr.sin6_family != AF_INET6 ||
305 0 : ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6)) {
306 : error = EAFNOSUPPORT;
307 0 : break;
308 : }
309 0 : in6_purgeaddr(&ia6->ia_ifa);
310 0 : dohooks(ifp->if_addrhooks, 0);
311 0 : break;
312 :
313 : case SIOCAIFADDR_IN6:
314 : /*
315 : * We always require users to specify a valid IPv6 address for
316 : * the corresponding operation.
317 : */
318 0 : if (ifra->ifra_addr.sin6_family != AF_INET6 ||
319 0 : ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6)) {
320 : error = EAFNOSUPPORT;
321 0 : break;
322 : }
323 :
324 : /* reject read-only flags */
325 0 : if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 ||
326 0 : (ifra->ifra_flags & IN6_IFF_DETACHED) != 0 ||
327 0 : (ifra->ifra_flags & IN6_IFF_DEPRECATED) != 0) {
328 : error = EINVAL;
329 0 : break;
330 : }
331 :
332 0 : if (ia6 == NULL)
333 0 : newifaddr = 1;
334 :
335 : /*
336 : * Make the address tentative before joining multicast
337 : * addresses, so that corresponding MLD responses would
338 : * not have a tentative source address.
339 : */
340 0 : if (newifaddr && in6if_do_dad(ifp))
341 0 : ifra->ifra_flags |= IN6_IFF_TENTATIVE;
342 :
343 : /*
344 : * first, make or update the interface address structure,
345 : * and link it to the list. try to enable inet6 if there
346 : * is no link-local yet.
347 : */
348 0 : error = in6_ifattach(ifp);
349 0 : if (error != 0)
350 : break;
351 0 : error = in6_update_ifa(ifp, ifra, ia6);
352 0 : if (error != 0)
353 : break;
354 :
355 0 : ia6 = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr);
356 0 : if (ia6 == NULL) {
357 : /*
358 : * this can happen when the user specify the 0 valid
359 : * lifetime.
360 : */
361 : break;
362 : }
363 :
364 : /* Perform DAD, if needed. */
365 0 : if (ia6->ia6_flags & IN6_IFF_TENTATIVE)
366 0 : nd6_dad_start(&ia6->ia_ifa);
367 :
368 0 : if (!newifaddr) {
369 0 : dohooks(ifp->if_addrhooks, 0);
370 0 : break;
371 : }
372 :
373 0 : plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL);
374 0 : if ((ifp->if_flags & IFF_LOOPBACK) || plen == 128) {
375 0 : dohooks(ifp->if_addrhooks, 0);
376 0 : break; /* No need to install a connected route. */
377 : }
378 :
379 0 : error = rt_ifa_add(&ia6->ia_ifa, RTF_CLONING | RTF_CONNECTED,
380 0 : ia6->ia_ifa.ifa_addr);
381 0 : if (error) {
382 0 : in6_purgeaddr(&ia6->ia_ifa);
383 0 : break;
384 : }
385 0 : dohooks(ifp->if_addrhooks, 0);
386 0 : break;
387 : }
388 :
389 : err:
390 0 : NET_UNLOCK();
391 0 : return (error);
392 : }
393 :
394 : int
395 0 : in6_ioctl_get(u_long cmd, caddr_t data, struct ifnet *ifp)
396 : {
397 0 : struct in6_ifreq *ifr = (struct in6_ifreq *)data;
398 : struct in6_ifaddr *ia6 = NULL;
399 : struct sockaddr_in6 *sa6;
400 : int error = 0;
401 :
402 0 : sa6 = &ifr->ifr_addr;
403 :
404 0 : NET_RLOCK();
405 :
406 0 : if (sa6 && sa6->sin6_family == AF_INET6) {
407 0 : error = in6_check_embed_scope(sa6, ifp->if_index);
408 0 : if (error)
409 : goto err;
410 0 : error = in6_clear_scope_id(sa6, ifp->if_index);
411 0 : if (error)
412 : goto err;
413 0 : ia6 = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
414 0 : }
415 :
416 : /* must think again about its semantics */
417 0 : if (ia6 == NULL) {
418 : error = EADDRNOTAVAIL;
419 0 : goto err;
420 : }
421 :
422 0 : switch (cmd) {
423 : case SIOCGIFDSTADDR_IN6:
424 0 : if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
425 : error = EINVAL;
426 0 : break;
427 : }
428 : /*
429 : * XXX: should we check if ifa_dstaddr is NULL and return
430 : * an error?
431 : */
432 0 : ifr->ifr_dstaddr = ia6->ia_dstaddr;
433 0 : break;
434 :
435 : case SIOCGIFNETMASK_IN6:
436 0 : ifr->ifr_addr = ia6->ia_prefixmask;
437 0 : break;
438 :
439 : case SIOCGIFAFLAG_IN6:
440 0 : ifr->ifr_ifru.ifru_flags6 = ia6->ia6_flags;
441 0 : break;
442 :
443 : case SIOCGIFALIFETIME_IN6:
444 0 : ifr->ifr_ifru.ifru_lifetime = ia6->ia6_lifetime;
445 0 : if (ia6->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
446 : time_t expire, maxexpire;
447 : struct in6_addrlifetime *retlt =
448 : &ifr->ifr_ifru.ifru_lifetime;
449 :
450 : /*
451 : * XXX: adjust expiration time assuming time_t is
452 : * signed.
453 : */
454 : maxexpire =
455 : (time_t)~(1ULL << ((sizeof(maxexpire) * 8) - 1));
456 0 : if (ia6->ia6_lifetime.ia6t_vltime <
457 0 : maxexpire - ia6->ia6_updatetime) {
458 0 : expire = ia6->ia6_updatetime +
459 : ia6->ia6_lifetime.ia6t_vltime;
460 0 : if (expire != 0) {
461 0 : expire -= time_uptime;
462 0 : expire += time_second;
463 0 : }
464 0 : retlt->ia6t_expire = expire;
465 0 : } else
466 0 : retlt->ia6t_expire = maxexpire;
467 0 : }
468 0 : if (ia6->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
469 : time_t expire, maxexpire;
470 : struct in6_addrlifetime *retlt =
471 : &ifr->ifr_ifru.ifru_lifetime;
472 :
473 : /*
474 : * XXX: adjust expiration time assuming time_t is
475 : * signed.
476 : */
477 : maxexpire =
478 : (time_t)~(1ULL << ((sizeof(maxexpire) * 8) - 1));
479 0 : if (ia6->ia6_lifetime.ia6t_pltime <
480 0 : maxexpire - ia6->ia6_updatetime) {
481 0 : expire = ia6->ia6_updatetime +
482 : ia6->ia6_lifetime.ia6t_pltime;
483 0 : if (expire != 0) {
484 0 : expire -= time_uptime;
485 0 : expire += time_second;
486 0 : }
487 0 : retlt->ia6t_preferred = expire;
488 0 : } else
489 0 : retlt->ia6t_preferred = maxexpire;
490 0 : }
491 : break;
492 :
493 : default:
494 0 : panic("invalid ioctl %lu", cmd);
495 : }
496 :
497 : err:
498 0 : NET_RUNLOCK();
499 0 : return (error);
500 : }
501 :
502 : int
503 0 : in6_check_embed_scope(struct sockaddr_in6 *sa6, unsigned int ifidx)
504 : {
505 0 : if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
506 0 : if (sa6->sin6_addr.s6_addr16[1] == 0) {
507 : /* link ID is not embedded by the user */
508 0 : sa6->sin6_addr.s6_addr16[1] = htons(ifidx);
509 0 : } else if (sa6->sin6_addr.s6_addr16[1] != htons(ifidx))
510 0 : return EINVAL; /* link ID contradicts */
511 : }
512 0 : return 0;
513 0 : }
514 :
515 : int
516 0 : in6_clear_scope_id(struct sockaddr_in6 *sa6, unsigned int ifidx)
517 : {
518 0 : if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
519 0 : if (sa6->sin6_scope_id) {
520 0 : if (sa6->sin6_scope_id != (u_int32_t)ifidx)
521 0 : return EINVAL;
522 0 : sa6->sin6_scope_id = 0; /* XXX: good way? */
523 0 : }
524 : }
525 0 : return 0;
526 0 : }
527 :
528 : /*
529 : * Update parameters of an IPv6 interface address.
530 : * If necessary, a new entry is created and linked into address chains.
531 : * This function is separated from in6_control().
532 : */
533 : int
534 0 : in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
535 : struct in6_ifaddr *ia6)
536 : {
537 0 : int error = 0, hostIsNew = 0, plen = -1;
538 0 : struct sockaddr_in6 dst6;
539 : struct in6_addrlifetime *lt;
540 : struct in6_multi_mship *imm;
541 : struct rtentry *rt;
542 0 : char addr[INET6_ADDRSTRLEN];
543 :
544 0 : NET_ASSERT_LOCKED();
545 :
546 : /* Validate parameters */
547 0 : if (ifp == NULL || ifra == NULL) /* this maybe redundant */
548 0 : return (EINVAL);
549 :
550 : /*
551 : * The destination address for a p2p link must have a family
552 : * of AF_UNSPEC or AF_INET6.
553 : */
554 0 : if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
555 0 : ifra->ifra_dstaddr.sin6_family != AF_INET6 &&
556 0 : ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
557 0 : return (EAFNOSUPPORT);
558 :
559 : /*
560 : * validate ifra_prefixmask. don't check sin6_family, netmask
561 : * does not carry fields other than sin6_len.
562 : */
563 0 : if (ifra->ifra_prefixmask.sin6_len > sizeof(struct sockaddr_in6))
564 0 : return (EINVAL);
565 : /*
566 : * Because the IPv6 address architecture is classless, we require
567 : * users to specify a (non 0) prefix length (mask) for a new address.
568 : * We also require the prefix (when specified) mask is valid, and thus
569 : * reject a non-consecutive mask.
570 : */
571 0 : if (ia6 == NULL && ifra->ifra_prefixmask.sin6_len == 0)
572 0 : return (EINVAL);
573 0 : if (ifra->ifra_prefixmask.sin6_len != 0) {
574 0 : plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
575 0 : (u_char *)&ifra->ifra_prefixmask +
576 : ifra->ifra_prefixmask.sin6_len);
577 0 : if (plen <= 0)
578 0 : return (EINVAL);
579 : } else {
580 : /*
581 : * In this case, ia6 must not be NULL. We just use its prefix
582 : * length.
583 : */
584 0 : plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL);
585 : }
586 : /*
587 : * If the destination address on a p2p interface is specified,
588 : * and the address is a scoped one, validate/set the scope
589 : * zone identifier.
590 : */
591 0 : dst6 = ifra->ifra_dstaddr;
592 0 : if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) != 0 &&
593 0 : (dst6.sin6_family == AF_INET6)) {
594 0 : error = in6_check_embed_scope(&dst6, ifp->if_index);
595 0 : if (error)
596 0 : return error;
597 : }
598 : /*
599 : * The destination address can be specified only for a p2p or a
600 : * loopback interface. If specified, the corresponding prefix length
601 : * must be 128.
602 : */
603 0 : if (ifra->ifra_dstaddr.sin6_family == AF_INET6) {
604 0 : if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0)
605 0 : return (EINVAL);
606 0 : if (plen != 128)
607 0 : return (EINVAL);
608 : }
609 : /* lifetime consistency check */
610 0 : lt = &ifra->ifra_lifetime;
611 0 : if (lt->ia6t_pltime > lt->ia6t_vltime)
612 0 : return (EINVAL);
613 0 : if (lt->ia6t_vltime == 0) {
614 : /*
615 : * the following log might be noisy, but this is a typical
616 : * configuration mistake or a tool's bug.
617 : */
618 0 : nd6log((LOG_INFO,
619 : "in6_update_ifa: valid lifetime is 0 for %s\n",
620 : inet_ntop(AF_INET6, &ifra->ifra_addr.sin6_addr,
621 : addr, sizeof(addr))));
622 :
623 0 : if (ia6 == NULL)
624 0 : return (0); /* there's nothing to do */
625 : }
626 :
627 : /*
628 : * If this is a new address, allocate a new ifaddr and link it
629 : * into chains.
630 : */
631 0 : if (ia6 == NULL) {
632 : hostIsNew = 1;
633 0 : ia6 = malloc(sizeof(*ia6), M_IFADDR, M_WAITOK | M_ZERO);
634 0 : LIST_INIT(&ia6->ia6_memberships);
635 : /* Initialize the address and masks, and put time stamp */
636 0 : ia6->ia_ifa.ifa_addr = sin6tosa(&ia6->ia_addr);
637 0 : ia6->ia_addr.sin6_family = AF_INET6;
638 0 : ia6->ia_addr.sin6_len = sizeof(ia6->ia_addr);
639 0 : ia6->ia6_updatetime = time_uptime;
640 0 : if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
641 : /*
642 : * XXX: some functions expect that ifa_dstaddr is not
643 : * NULL for p2p interfaces.
644 : */
645 0 : ia6->ia_ifa.ifa_dstaddr = sin6tosa(&ia6->ia_dstaddr);
646 0 : } else {
647 0 : ia6->ia_ifa.ifa_dstaddr = NULL;
648 : }
649 0 : ia6->ia_ifa.ifa_netmask = sin6tosa(&ia6->ia_prefixmask);
650 :
651 0 : ia6->ia_ifp = ifp;
652 0 : ia6->ia_addr = ifra->ifra_addr;
653 0 : ifa_add(ifp, &ia6->ia_ifa);
654 0 : }
655 :
656 : /* set prefix mask */
657 0 : if (ifra->ifra_prefixmask.sin6_len) {
658 : /*
659 : * We prohibit changing the prefix length of an existing
660 : * address, because
661 : * + such an operation should be rare in IPv6, and
662 : * + the operation would confuse prefix management.
663 : */
664 0 : if (ia6->ia_prefixmask.sin6_len &&
665 0 : in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL) != plen) {
666 0 : error = EINVAL;
667 0 : goto unlink;
668 : }
669 0 : ia6->ia_prefixmask = ifra->ifra_prefixmask;
670 0 : }
671 :
672 : /*
673 : * If a new destination address is specified, scrub the old one and
674 : * install the new destination. Note that the interface must be
675 : * p2p or loopback (see the check above.)
676 : */
677 0 : if ((ifp->if_flags & IFF_POINTOPOINT) && dst6.sin6_family == AF_INET6 &&
678 0 : !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia6->ia_dstaddr.sin6_addr)) {
679 0 : struct ifaddr *ifa = &ia6->ia_ifa;
680 :
681 0 : if ((ia6->ia_flags & IFA_ROUTE) != 0 &&
682 0 : rt_ifa_del(ifa, RTF_HOST, ifa->ifa_dstaddr) != 0) {
683 0 : nd6log((LOG_ERR, "in6_update_ifa: failed to remove "
684 : "a route to the old destination: %s\n",
685 : inet_ntop(AF_INET6, &ia6->ia_addr.sin6_addr,
686 : addr, sizeof(addr))));
687 : /* proceed anyway... */
688 : } else
689 0 : ia6->ia_flags &= ~IFA_ROUTE;
690 0 : ia6->ia_dstaddr = dst6;
691 0 : }
692 :
693 : /*
694 : * Set lifetimes. We do not refer to ia6t_expire and ia6t_preferred
695 : * to see if the address is deprecated or invalidated, but initialize
696 : * these members for applications.
697 : */
698 0 : ia6->ia6_updatetime = time_uptime;
699 0 : ia6->ia6_lifetime = ifra->ifra_lifetime;
700 0 : if (ia6->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
701 0 : ia6->ia6_lifetime.ia6t_expire =
702 0 : time_uptime + ia6->ia6_lifetime.ia6t_vltime;
703 0 : } else
704 0 : ia6->ia6_lifetime.ia6t_expire = 0;
705 0 : if (ia6->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
706 0 : ia6->ia6_lifetime.ia6t_preferred =
707 0 : time_uptime + ia6->ia6_lifetime.ia6t_pltime;
708 0 : } else
709 0 : ia6->ia6_lifetime.ia6t_preferred = 0;
710 :
711 : /* reset the interface and routing table appropriately. */
712 0 : if ((error = in6_ifinit(ifp, ia6, hostIsNew)) != 0)
713 : goto unlink;
714 :
715 : /* re-run DAD */
716 0 : if (ia6->ia6_flags & (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED))
717 0 : ifra->ifra_flags |= IN6_IFF_TENTATIVE;
718 : /*
719 : * configure address flags.
720 : */
721 0 : ia6->ia6_flags = ifra->ifra_flags;
722 :
723 0 : nd6_expire_timer_update(ia6);
724 :
725 : /*
726 : * We are done if we have simply modified an existing address.
727 : */
728 0 : if (!hostIsNew)
729 0 : return (error);
730 :
731 : /*
732 : * Beyond this point, we should call in6_purgeaddr upon an error,
733 : * not just go to unlink.
734 : */
735 :
736 : /* join necessary multiast groups */
737 0 : if ((ifp->if_flags & IFF_MULTICAST) != 0) {
738 0 : struct sockaddr_in6 mltaddr, mltmask;
739 :
740 : /* join solicited multicast addr for new host id */
741 0 : struct sockaddr_in6 llsol;
742 :
743 0 : bzero(&llsol, sizeof(llsol));
744 0 : llsol.sin6_family = AF_INET6;
745 0 : llsol.sin6_len = sizeof(llsol);
746 0 : llsol.sin6_addr.s6_addr16[0] = htons(0xff02);
747 0 : llsol.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
748 0 : llsol.sin6_addr.s6_addr32[1] = 0;
749 0 : llsol.sin6_addr.s6_addr32[2] = htonl(1);
750 0 : llsol.sin6_addr.s6_addr32[3] =
751 0 : ifra->ifra_addr.sin6_addr.s6_addr32[3];
752 0 : llsol.sin6_addr.s6_addr8[12] = 0xff;
753 0 : imm = in6_joingroup(ifp, &llsol.sin6_addr, &error);
754 0 : if (!imm)
755 0 : goto cleanup;
756 0 : LIST_INSERT_HEAD(&ia6->ia6_memberships, imm, i6mm_chain);
757 :
758 0 : bzero(&mltmask, sizeof(mltmask));
759 0 : mltmask.sin6_len = sizeof(struct sockaddr_in6);
760 0 : mltmask.sin6_family = AF_INET6;
761 0 : mltmask.sin6_addr = in6mask32;
762 :
763 : /*
764 : * join link-local all-nodes address
765 : */
766 0 : bzero(&mltaddr, sizeof(mltaddr));
767 0 : mltaddr.sin6_len = sizeof(struct sockaddr_in6);
768 0 : mltaddr.sin6_family = AF_INET6;
769 0 : mltaddr.sin6_addr = in6addr_linklocal_allnodes;
770 0 : mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
771 0 : mltaddr.sin6_scope_id = 0;
772 :
773 : /*
774 : * XXX: do we really need this automatic routes?
775 : * We should probably reconsider this stuff. Most applications
776 : * actually do not need the routes, since they usually specify
777 : * the outgoing interface.
778 : */
779 0 : rt = rtalloc(sin6tosa(&mltaddr), 0, ifp->if_rdomain);
780 0 : if (rt) {
781 : /* 32bit came from "mltmask" */
782 0 : if (memcmp(&mltaddr.sin6_addr,
783 : &satosin6(rt_key(rt))->sin6_addr,
784 : 32 / 8)) {
785 0 : rtfree(rt);
786 : rt = NULL;
787 0 : }
788 : }
789 0 : if (!rt) {
790 0 : struct rt_addrinfo info;
791 :
792 0 : bzero(&info, sizeof(info));
793 0 : info.rti_ifa = &ia6->ia_ifa;
794 0 : info.rti_info[RTAX_DST] = sin6tosa(&mltaddr);
795 0 : info.rti_info[RTAX_GATEWAY] = sin6tosa(&ia6->ia_addr);
796 0 : info.rti_info[RTAX_NETMASK] = sin6tosa(&mltmask);
797 0 : info.rti_info[RTAX_IFA] = sin6tosa(&ia6->ia_addr);
798 0 : info.rti_flags = RTF_MULTICAST;
799 0 : error = rtrequest(RTM_ADD, &info, RTP_CONNECTED, NULL,
800 0 : ifp->if_rdomain);
801 0 : if (error)
802 0 : goto cleanup;
803 0 : } else {
804 0 : rtfree(rt);
805 : }
806 0 : imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error);
807 0 : if (!imm)
808 0 : goto cleanup;
809 0 : LIST_INSERT_HEAD(&ia6->ia6_memberships, imm, i6mm_chain);
810 :
811 : /*
812 : * join node information group address
813 : */
814 0 : if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr) == 0) {
815 0 : imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error);
816 0 : if (!imm) {
817 : /* XXX not very fatal, go on... */
818 : } else {
819 0 : LIST_INSERT_HEAD(&ia6->ia6_memberships,
820 : imm, i6mm_chain);
821 : }
822 : }
823 :
824 : /*
825 : * join interface-local all-nodes address.
826 : * (ff01::1%ifN, and ff01::%ifN/32)
827 : */
828 0 : bzero(&mltaddr, sizeof(mltaddr));
829 0 : mltaddr.sin6_len = sizeof(struct sockaddr_in6);
830 0 : mltaddr.sin6_family = AF_INET6;
831 0 : mltaddr.sin6_addr = in6addr_intfacelocal_allnodes;
832 0 : mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
833 0 : mltaddr.sin6_scope_id = 0;
834 :
835 : /* XXX: again, do we really need the route? */
836 0 : rt = rtalloc(sin6tosa(&mltaddr), 0, ifp->if_rdomain);
837 0 : if (rt) {
838 : /* 32bit came from "mltmask" */
839 0 : if (memcmp(&mltaddr.sin6_addr,
840 : &satosin6(rt_key(rt))->sin6_addr,
841 : 32 / 8)) {
842 0 : rtfree(rt);
843 : rt = NULL;
844 0 : }
845 : }
846 0 : if (!rt) {
847 0 : struct rt_addrinfo info;
848 :
849 0 : bzero(&info, sizeof(info));
850 0 : info.rti_ifa = &ia6->ia_ifa;
851 0 : info.rti_info[RTAX_DST] = sin6tosa(&mltaddr);
852 0 : info.rti_info[RTAX_GATEWAY] = sin6tosa(&ia6->ia_addr);
853 0 : info.rti_info[RTAX_NETMASK] = sin6tosa(&mltmask);
854 0 : info.rti_info[RTAX_IFA] = sin6tosa(&ia6->ia_addr);
855 0 : info.rti_flags = RTF_MULTICAST;
856 0 : error = rtrequest(RTM_ADD, &info, RTP_CONNECTED, NULL,
857 0 : ifp->if_rdomain);
858 0 : if (error)
859 0 : goto cleanup;
860 0 : } else {
861 0 : rtfree(rt);
862 : }
863 0 : imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error);
864 0 : if (!imm)
865 0 : goto cleanup;
866 0 : LIST_INSERT_HEAD(&ia6->ia6_memberships, imm, i6mm_chain);
867 0 : }
868 :
869 0 : return (error);
870 :
871 : unlink:
872 : /*
873 : * XXX: if a change of an existing address failed, keep the entry
874 : * anyway.
875 : */
876 0 : if (hostIsNew)
877 0 : in6_unlink_ifa(ia6, ifp);
878 0 : return (error);
879 :
880 : cleanup:
881 0 : in6_purgeaddr(&ia6->ia_ifa);
882 0 : return error;
883 0 : }
884 :
885 : void
886 0 : in6_purgeaddr(struct ifaddr *ifa)
887 : {
888 0 : struct ifnet *ifp = ifa->ifa_ifp;
889 0 : struct in6_ifaddr *ia6 = ifatoia6(ifa);
890 : struct in6_multi_mship *imm;
891 :
892 : /* stop DAD processing */
893 0 : nd6_dad_stop(ifa);
894 :
895 : /*
896 : * delete route to the destination of the address being purged.
897 : * The interface must be p2p or loopback in this case.
898 : */
899 0 : if ((ifp->if_flags & IFF_POINTOPOINT) && (ia6->ia_flags & IFA_ROUTE) &&
900 0 : ia6->ia_dstaddr.sin6_len != 0) {
901 : int e;
902 :
903 0 : if ((e = rt_ifa_del(ifa, RTF_HOST, ifa->ifa_dstaddr)) != 0) {
904 0 : char addr[INET6_ADDRSTRLEN];
905 0 : log(LOG_ERR, "in6_purgeaddr: failed to remove "
906 : "a route to the p2p destination: %s on %s, "
907 : "errno=%d\n",
908 0 : inet_ntop(AF_INET6, &ia6->ia_addr.sin6_addr,
909 0 : addr, sizeof(addr)),
910 0 : ifp->if_xname, e);
911 : /* proceed anyway... */
912 0 : } else
913 0 : ia6->ia_flags &= ~IFA_ROUTE;
914 0 : }
915 :
916 : /* Remove ownaddr's loopback rtentry, if it exists. */
917 0 : rt_ifa_dellocal(&(ia6->ia_ifa));
918 :
919 : /*
920 : * leave from multicast groups we have joined for the interface
921 : */
922 0 : while (!LIST_EMPTY(&ia6->ia6_memberships)) {
923 : imm = LIST_FIRST(&ia6->ia6_memberships);
924 0 : LIST_REMOVE(imm, i6mm_chain);
925 0 : in6_leavegroup(imm);
926 : }
927 :
928 0 : in6_unlink_ifa(ia6, ifp);
929 0 : }
930 :
931 : void
932 0 : in6_unlink_ifa(struct in6_ifaddr *ia6, struct ifnet *ifp)
933 : {
934 0 : struct ifaddr *ifa = &ia6->ia_ifa;
935 : extern int ifatrash;
936 : int plen;
937 :
938 0 : NET_ASSERT_LOCKED();
939 :
940 : /* Release the reference to the base prefix. */
941 0 : plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL);
942 0 : if ((ifp->if_flags & IFF_LOOPBACK) == 0 && plen != 128) {
943 0 : rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED,
944 0 : ifa->ifa_addr);
945 0 : }
946 :
947 0 : rt_ifa_purge(ifa);
948 0 : ifa_del(ifp, ifa);
949 :
950 0 : ifatrash++;
951 0 : ia6->ia_ifp = NULL;
952 0 : ifafree(&ia6->ia_ifa);
953 0 : }
954 :
955 : /*
956 : * Initialize an interface's intetnet6 address
957 : * and routing table entry.
958 : */
959 : int
960 0 : in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia6, int newhost)
961 : {
962 : int error = 0, plen, ifacount = 0;
963 : struct ifaddr *ifa;
964 :
965 0 : NET_ASSERT_LOCKED();
966 :
967 : /*
968 : * Give the interface a chance to initialize
969 : * if this is its first address (or it is a CARP interface)
970 : * and to validate the address if necessary.
971 : */
972 0 : TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
973 0 : if (ifa->ifa_addr->sa_family != AF_INET6)
974 : continue;
975 0 : ifacount++;
976 0 : }
977 :
978 0 : if ((ifacount <= 1 || ifp->if_type == IFT_CARP ||
979 0 : (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))) &&
980 0 : (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia6))) {
981 0 : return (error);
982 : }
983 :
984 0 : ia6->ia_ifa.ifa_metric = ifp->if_metric;
985 :
986 : /* we could do in(6)_socktrim here, but just omit it at this moment. */
987 :
988 : /*
989 : * Special case:
990 : * If the destination address is specified for a point-to-point
991 : * interface, install a route to the destination as an interface
992 : * direct route.
993 : */
994 0 : plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL); /* XXX */
995 0 : if ((ifp->if_flags & IFF_POINTOPOINT) && plen == 128 &&
996 0 : ia6->ia_dstaddr.sin6_family == AF_INET6) {
997 : ifa = &ia6->ia_ifa;
998 0 : error = rt_ifa_add(ifa, RTF_HOST, ifa->ifa_dstaddr);
999 0 : if (error != 0)
1000 0 : return (error);
1001 0 : ia6->ia_flags |= IFA_ROUTE;
1002 0 : }
1003 :
1004 0 : if (newhost)
1005 0 : error = rt_ifa_addlocal(&(ia6->ia_ifa));
1006 :
1007 0 : return (error);
1008 0 : }
1009 :
1010 : /*
1011 : * Add an address to the list of IP6 multicast addresses for a
1012 : * given interface.
1013 : */
1014 : struct in6_multi *
1015 0 : in6_addmulti(struct in6_addr *maddr6, struct ifnet *ifp, int *errorp)
1016 : {
1017 0 : struct in6_ifreq ifr;
1018 : struct in6_multi *in6m;
1019 :
1020 0 : NET_ASSERT_LOCKED();
1021 :
1022 0 : *errorp = 0;
1023 : /*
1024 : * See if address already in list.
1025 : */
1026 0 : IN6_LOOKUP_MULTI(*maddr6, ifp, in6m);
1027 0 : if (in6m != NULL) {
1028 : /*
1029 : * Found it; just increment the refrence count.
1030 : */
1031 0 : in6m->in6m_refcnt++;
1032 0 : } else {
1033 : /*
1034 : * New address; allocate a new multicast record
1035 : * and link it into the interface's multicast list.
1036 : */
1037 0 : in6m = malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT | M_ZERO);
1038 0 : if (in6m == NULL) {
1039 0 : *errorp = ENOBUFS;
1040 0 : return (NULL);
1041 : }
1042 :
1043 0 : in6m->in6m_sin.sin6_len = sizeof(struct sockaddr_in6);
1044 0 : in6m->in6m_sin.sin6_family = AF_INET6;
1045 0 : in6m->in6m_sin.sin6_addr = *maddr6;
1046 0 : in6m->in6m_refcnt = 1;
1047 0 : in6m->in6m_ifidx = ifp->if_index;
1048 0 : in6m->in6m_ifma.ifma_addr = sin6tosa(&in6m->in6m_sin);
1049 :
1050 : /*
1051 : * Ask the network driver to update its multicast reception
1052 : * filter appropriately for the new address.
1053 : */
1054 0 : memcpy(&ifr.ifr_addr, &in6m->in6m_sin, sizeof(in6m->in6m_sin));
1055 0 : *errorp = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, (caddr_t)&ifr);
1056 0 : if (*errorp) {
1057 0 : free(in6m, M_IPMADDR, sizeof(*in6m));
1058 0 : return (NULL);
1059 : }
1060 :
1061 0 : TAILQ_INSERT_HEAD(&ifp->if_maddrlist, &in6m->in6m_ifma,
1062 : ifma_list);
1063 :
1064 : /*
1065 : * Let MLD6 know that we have joined a new IP6 multicast
1066 : * group.
1067 : */
1068 0 : mld6_start_listening(in6m);
1069 : }
1070 :
1071 0 : return (in6m);
1072 0 : }
1073 :
1074 : /*
1075 : * Delete a multicast address record.
1076 : */
1077 : void
1078 0 : in6_delmulti(struct in6_multi *in6m)
1079 : {
1080 0 : struct in6_ifreq ifr;
1081 : struct ifnet *ifp;
1082 :
1083 0 : NET_ASSERT_LOCKED();
1084 :
1085 0 : if (--in6m->in6m_refcnt == 0) {
1086 : /*
1087 : * No remaining claims to this record; let MLD6 know
1088 : * that we are leaving the multicast group.
1089 : */
1090 0 : mld6_stop_listening(in6m);
1091 0 : ifp = if_get(in6m->in6m_ifidx);
1092 :
1093 : /*
1094 : * Notify the network driver to update its multicast
1095 : * reception filter.
1096 : */
1097 0 : if (ifp != NULL) {
1098 0 : bzero(&ifr.ifr_addr, sizeof(struct sockaddr_in6));
1099 0 : ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6);
1100 0 : ifr.ifr_addr.sin6_family = AF_INET6;
1101 0 : ifr.ifr_addr.sin6_addr = in6m->in6m_addr;
1102 0 : (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr);
1103 :
1104 0 : TAILQ_REMOVE(&ifp->if_maddrlist, &in6m->in6m_ifma,
1105 : ifma_list);
1106 0 : }
1107 0 : if_put(ifp);
1108 :
1109 0 : free(in6m, M_IPMADDR, sizeof(*in6m));
1110 0 : }
1111 0 : }
1112 :
1113 : /*
1114 : * Return 1 if the multicast group represented by ``maddr6'' has been
1115 : * joined by interface ``ifp'', 0 otherwise.
1116 : */
1117 : int
1118 0 : in6_hasmulti(struct in6_addr *maddr6, struct ifnet *ifp)
1119 : {
1120 : struct in6_multi *in6m;
1121 : int joined;
1122 :
1123 0 : IN6_LOOKUP_MULTI(*maddr6, ifp, in6m);
1124 0 : joined = (in6m != NULL);
1125 :
1126 0 : return (joined);
1127 : }
1128 :
1129 : struct in6_multi_mship *
1130 0 : in6_joingroup(struct ifnet *ifp, struct in6_addr *addr, int *errorp)
1131 : {
1132 : struct in6_multi_mship *imm;
1133 :
1134 0 : imm = malloc(sizeof(*imm), M_IPMADDR, M_NOWAIT);
1135 0 : if (!imm) {
1136 0 : *errorp = ENOBUFS;
1137 0 : return NULL;
1138 : }
1139 0 : imm->i6mm_maddr = in6_addmulti(addr, ifp, errorp);
1140 0 : if (!imm->i6mm_maddr) {
1141 : /* *errorp is alrady set */
1142 0 : free(imm, M_IPMADDR, sizeof(*imm));
1143 0 : return NULL;
1144 : }
1145 0 : return imm;
1146 0 : }
1147 :
1148 : void
1149 0 : in6_leavegroup(struct in6_multi_mship *imm)
1150 : {
1151 :
1152 0 : if (imm->i6mm_maddr)
1153 0 : in6_delmulti(imm->i6mm_maddr);
1154 0 : free(imm, M_IPMADDR, sizeof(*imm));
1155 0 : }
1156 :
1157 : /*
1158 : * Find an IPv6 interface link-local address specific to an interface.
1159 : */
1160 : struct in6_ifaddr *
1161 0 : in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags)
1162 : {
1163 : struct ifaddr *ifa;
1164 :
1165 0 : TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1166 0 : if (ifa->ifa_addr->sa_family != AF_INET6)
1167 : continue;
1168 0 : if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
1169 0 : if ((ifatoia6(ifa)->ia6_flags & ignoreflags) != 0)
1170 : continue;
1171 : break;
1172 : }
1173 : }
1174 :
1175 0 : return (ifatoia6(ifa));
1176 : }
1177 :
1178 :
1179 : /*
1180 : * find the internet address corresponding to a given interface and address.
1181 : */
1182 : struct in6_ifaddr *
1183 0 : in6ifa_ifpwithaddr(struct ifnet *ifp, struct in6_addr *addr)
1184 : {
1185 : struct ifaddr *ifa;
1186 :
1187 0 : TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1188 0 : if (ifa->ifa_addr->sa_family != AF_INET6)
1189 : continue;
1190 0 : if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
1191 : break;
1192 : }
1193 :
1194 0 : return (ifatoia6(ifa));
1195 : }
1196 :
1197 : /*
1198 : * Get a scope of the address. Node-local, link-local, site-local or global.
1199 : */
1200 : int
1201 0 : in6_addrscope(struct in6_addr *addr)
1202 : {
1203 : int scope;
1204 :
1205 0 : if (addr->s6_addr8[0] == 0xfe) {
1206 0 : scope = addr->s6_addr8[1] & 0xc0;
1207 :
1208 0 : switch (scope) {
1209 : case 0x80:
1210 0 : return __IPV6_ADDR_SCOPE_LINKLOCAL;
1211 : break;
1212 : case 0xc0:
1213 0 : return __IPV6_ADDR_SCOPE_SITELOCAL;
1214 : break;
1215 : default:
1216 0 : return __IPV6_ADDR_SCOPE_GLOBAL; /* just in case */
1217 : break;
1218 : }
1219 : }
1220 :
1221 :
1222 0 : if (addr->s6_addr8[0] == 0xff) {
1223 0 : scope = addr->s6_addr8[1] & 0x0f;
1224 :
1225 : /*
1226 : * due to other scope such as reserved,
1227 : * return scope doesn't work.
1228 : */
1229 0 : switch (scope) {
1230 : case __IPV6_ADDR_SCOPE_INTFACELOCAL:
1231 0 : return __IPV6_ADDR_SCOPE_INTFACELOCAL;
1232 : break;
1233 : case __IPV6_ADDR_SCOPE_LINKLOCAL:
1234 0 : return __IPV6_ADDR_SCOPE_LINKLOCAL;
1235 : break;
1236 : case __IPV6_ADDR_SCOPE_SITELOCAL:
1237 0 : return __IPV6_ADDR_SCOPE_SITELOCAL;
1238 : break;
1239 : default:
1240 0 : return __IPV6_ADDR_SCOPE_GLOBAL;
1241 : break;
1242 : }
1243 : }
1244 :
1245 0 : if (bcmp(&in6addr_loopback, addr, sizeof(*addr) - 1) == 0) {
1246 0 : if (addr->s6_addr8[15] == 1) /* loopback */
1247 0 : return __IPV6_ADDR_SCOPE_INTFACELOCAL;
1248 0 : if (addr->s6_addr8[15] == 0) /* unspecified */
1249 0 : return __IPV6_ADDR_SCOPE_LINKLOCAL;
1250 : }
1251 :
1252 0 : return __IPV6_ADDR_SCOPE_GLOBAL;
1253 0 : }
1254 :
1255 : int
1256 0 : in6_addr2scopeid(unsigned int ifidx, struct in6_addr *addr)
1257 : {
1258 0 : int scope = in6_addrscope(addr);
1259 :
1260 0 : switch(scope) {
1261 : case __IPV6_ADDR_SCOPE_INTFACELOCAL:
1262 : case __IPV6_ADDR_SCOPE_LINKLOCAL:
1263 : /* XXX: we do not distinguish between a link and an I/F. */
1264 0 : return (ifidx);
1265 :
1266 : case __IPV6_ADDR_SCOPE_SITELOCAL:
1267 0 : return (0); /* XXX: invalid. */
1268 :
1269 : default:
1270 0 : return (0); /* XXX: treat as global. */
1271 : }
1272 0 : }
1273 :
1274 : /*
1275 : * return length of part which dst and src are equal
1276 : * hard coding...
1277 : */
1278 : int
1279 0 : in6_matchlen(struct in6_addr *src, struct in6_addr *dst)
1280 : {
1281 : int match = 0;
1282 0 : u_char *s = (u_char *)src, *d = (u_char *)dst;
1283 0 : u_char *lim = s + 16, r;
1284 :
1285 0 : while (s < lim)
1286 0 : if ((r = (*d++ ^ *s++)) != 0) {
1287 0 : while (r < 128) {
1288 0 : match++;
1289 0 : r <<= 1;
1290 : }
1291 : break;
1292 : } else
1293 0 : match += 8;
1294 0 : return match;
1295 : }
1296 :
1297 : void
1298 0 : in6_prefixlen2mask(struct in6_addr *maskp, int len)
1299 : {
1300 0 : u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
1301 : int bytelen, bitlen, i;
1302 :
1303 : /* sanity check */
1304 0 : if (0 > len || len > 128) {
1305 0 : log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n",
1306 : len);
1307 0 : return;
1308 : }
1309 :
1310 0 : bzero(maskp, sizeof(*maskp));
1311 0 : bytelen = len / 8;
1312 0 : bitlen = len % 8;
1313 0 : for (i = 0; i < bytelen; i++)
1314 0 : maskp->s6_addr[i] = 0xff;
1315 : /* len == 128 is ok because bitlen == 0 then */
1316 0 : if (bitlen)
1317 0 : maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
1318 0 : }
1319 :
1320 : /*
1321 : * return the best address out of the same scope
1322 : */
1323 : struct in6_ifaddr *
1324 0 : in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst, u_int rdomain)
1325 : {
1326 0 : int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0;
1327 : int blen = -1;
1328 : struct ifaddr *ifa;
1329 : struct ifnet *ifp;
1330 : struct in6_ifaddr *ia6_best = NULL;
1331 :
1332 0 : if (oifp == NULL) {
1333 0 : printf("in6_ifawithscope: output interface is not specified\n");
1334 0 : return (NULL);
1335 : }
1336 :
1337 : /*
1338 : * We search for all addresses on all interfaces from the beginning.
1339 : * Comparing an interface with the outgoing interface will be done
1340 : * only at the final stage of tiebreaking.
1341 : */
1342 0 : TAILQ_FOREACH(ifp, &ifnet, if_list) {
1343 0 : if (ifp->if_rdomain != rdomain)
1344 : continue;
1345 : #if NCARP > 0
1346 : /*
1347 : * Never use a carp address of an interface which is not
1348 : * the master.
1349 : */
1350 0 : if (ifp->if_type == IFT_CARP && !carp_iamatch(ifp))
1351 : continue;
1352 : #endif
1353 :
1354 : /*
1355 : * We can never take an address that breaks the scope zone
1356 : * of the destination.
1357 : */
1358 0 : if (in6_addr2scopeid(ifp->if_index, dst) !=
1359 0 : in6_addr2scopeid(oifp->if_index, dst))
1360 : continue;
1361 :
1362 0 : TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1363 : int tlen = -1, dscopecmp, bscopecmp, matchcmp;
1364 :
1365 0 : if (ifa->ifa_addr->sa_family != AF_INET6)
1366 0 : continue;
1367 :
1368 0 : src_scope = in6_addrscope(IFA_IN6(ifa));
1369 :
1370 : #ifdef ADDRSELECT_DEBUG /* should be removed after stabilization */
1371 : {
1372 : char adst[INET6_ADDRSTRLEN], asrc[INET6_ADDRSTRLEN];
1373 : char bestaddr[INET6_ADDRSTRLEN];
1374 :
1375 :
1376 : dscopecmp = IN6_ARE_SCOPE_CMP(src_scope, dst_scope);
1377 : printf("in6_ifawithscope: dst=%s bestaddr=%s, "
1378 : "newaddr=%s, scope=%x, dcmp=%d, bcmp=%d, "
1379 : "matchlen=%d, flgs=%x\n",
1380 : inet_ntop(AF_INET6, dst, adst, sizeof(adst)),
1381 : (ia6_best == NULL) ? "none" :
1382 : inet_ntop(AF_INET6, &ia6_best->ia_addr.sin6_addr,
1383 : bestaddr, sizeof(bestaddr)),
1384 : inet_ntop(AF_INET6, IFA_IN6(ifa),
1385 : asrc, sizeof(asrc)),
1386 : src_scope, dscopecmp,
1387 : ia6_best ? IN6_ARE_SCOPE_CMP(src_scope, best_scope) : -1,
1388 : in6_matchlen(IFA_IN6(ifa), dst),
1389 : ifatoia6(ifa)->ia6_flags);
1390 : }
1391 : #endif
1392 :
1393 : /*
1394 : * Don't use an address before completing DAD
1395 : * nor a duplicated address.
1396 : */
1397 0 : if (ifatoia6(ifa)->ia6_flags &
1398 : (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED))
1399 0 : continue;
1400 :
1401 : /* XXX: is there any case to allow anycasts? */
1402 0 : if (ifatoia6(ifa)->ia6_flags & IN6_IFF_ANYCAST)
1403 0 : continue;
1404 :
1405 0 : if (ifatoia6(ifa)->ia6_flags & IN6_IFF_DETACHED)
1406 0 : continue;
1407 :
1408 : /*
1409 : * If this is the first address we find,
1410 : * keep it anyway.
1411 : */
1412 0 : if (ia6_best == NULL)
1413 : goto replace;
1414 :
1415 : /*
1416 : * ia6_best is never NULL beyond this line except
1417 : * within the block labeled "replace".
1418 : */
1419 :
1420 : /*
1421 : * If ia6_best has a smaller scope than dst and
1422 : * the current address has a larger one than
1423 : * (or equal to) dst, always replace ia6_best.
1424 : * Also, if the current address has a smaller scope
1425 : * than dst, ignore it unless ia6_best also has a
1426 : * smaller scope.
1427 : */
1428 0 : if (IN6_ARE_SCOPE_CMP(best_scope, dst_scope) < 0 &&
1429 0 : IN6_ARE_SCOPE_CMP(src_scope, dst_scope) >= 0)
1430 : goto replace;
1431 0 : if (IN6_ARE_SCOPE_CMP(src_scope, dst_scope) < 0 &&
1432 0 : IN6_ARE_SCOPE_CMP(best_scope, dst_scope) >= 0)
1433 0 : continue;
1434 :
1435 : /*
1436 : * A deprecated address SHOULD NOT be used in new
1437 : * communications if an alternate (non-deprecated)
1438 : * address is available and has sufficient scope.
1439 : * RFC 2462, Section 5.5.4.
1440 : */
1441 0 : if (ifatoia6(ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
1442 : /*
1443 : * Ignore any deprecated addresses if
1444 : * specified by configuration.
1445 : */
1446 0 : if (!ip6_use_deprecated)
1447 0 : continue;
1448 :
1449 : /*
1450 : * If we have already found a non-deprecated
1451 : * candidate, just ignore deprecated addresses.
1452 : */
1453 0 : if ((ia6_best->ia6_flags & IN6_IFF_DEPRECATED)
1454 0 : == 0)
1455 0 : continue;
1456 : }
1457 :
1458 : /*
1459 : * A non-deprecated address is always preferred
1460 : * to a deprecated one regardless of scopes and
1461 : * address matching.
1462 : */
1463 0 : if ((ia6_best->ia6_flags & IN6_IFF_DEPRECATED) &&
1464 0 : (ifatoia6(ifa)->ia6_flags &
1465 0 : IN6_IFF_DEPRECATED) == 0)
1466 : goto replace;
1467 :
1468 : /* RFC 3484 5. Rule 5: Prefer outgoing interface */
1469 0 : if (ia6_best->ia_ifp == oifp && ifp != oifp)
1470 0 : continue;
1471 0 : if (ia6_best->ia_ifp != oifp && ifp == oifp)
1472 : goto replace;
1473 :
1474 : /*
1475 : * At this point, we have two cases:
1476 : * 1. we are looking at a non-deprecated address,
1477 : * and ia6_best is also non-deprecated.
1478 : * 2. we are looking at a deprecated address,
1479 : * and ia6_best is also deprecated.
1480 : * Also, we do not have to consider a case where
1481 : * the scope of if_best is larger(smaller) than dst and
1482 : * the scope of the current address is smaller(larger)
1483 : * than dst. Such a case has already been covered.
1484 : * Tiebreaking is done according to the following
1485 : * items:
1486 : * - the scope comparison between the address and
1487 : * dst (dscopecmp)
1488 : * - the scope comparison between the address and
1489 : * ia6_best (bscopecmp)
1490 : * - if the address match dst longer than ia6_best
1491 : * (matchcmp)
1492 : * - if the address is on the outgoing I/F (outI/F)
1493 : *
1494 : * Roughly speaking, the selection policy is
1495 : * - the most important item is scope. The same scope
1496 : * is best. Then search for a larger scope.
1497 : * Smaller scopes are the last resort.
1498 : * - A deprecated address is chosen only when we have
1499 : * no address that has an enough scope, but is
1500 : * prefered to any addresses of smaller scopes.
1501 : * - Longest address match against dst is considered
1502 : * only for addresses that has the same scope of dst.
1503 : * - If there is no other reasons to choose one,
1504 : * addresses on the outgoing I/F are preferred.
1505 : *
1506 : * The precise decision table is as follows:
1507 : * dscopecmp bscopecmp matchcmp outI/F | replace?
1508 : * !equal equal N/A Yes | Yes (1)
1509 : * !equal equal N/A No | No (2)
1510 : * larger larger N/A N/A | No (3)
1511 : * larger smaller N/A N/A | Yes (4)
1512 : * smaller larger N/A N/A | Yes (5)
1513 : * smaller smaller N/A N/A | No (6)
1514 : * equal smaller N/A N/A | Yes (7)
1515 : * equal larger (already done)
1516 : * equal equal larger N/A | Yes (8)
1517 : * equal equal smaller N/A | No (9)
1518 : * equal equal equal Yes | Yes (a)
1519 : * equal equal equal No | No (b)
1520 : */
1521 : dscopecmp = IN6_ARE_SCOPE_CMP(src_scope, dst_scope);
1522 0 : bscopecmp = IN6_ARE_SCOPE_CMP(src_scope, best_scope);
1523 :
1524 0 : if (dscopecmp && bscopecmp == 0) {
1525 0 : if (oifp == ifp) /* (1) */
1526 : goto replace;
1527 0 : continue; /* (2) */
1528 : }
1529 0 : if (dscopecmp > 0) {
1530 0 : if (bscopecmp > 0) /* (3) */
1531 0 : continue;
1532 : goto replace; /* (4) */
1533 : }
1534 0 : if (dscopecmp < 0) {
1535 0 : if (bscopecmp > 0) /* (5) */
1536 : goto replace;
1537 0 : continue; /* (6) */
1538 : }
1539 :
1540 : /* now dscopecmp must be 0 */
1541 0 : if (bscopecmp < 0)
1542 : goto replace; /* (7) */
1543 :
1544 : /*
1545 : * At last both dscopecmp and bscopecmp must be 0.
1546 : * We need address matching against dst for
1547 : * tiebreaking.
1548 : * Privacy addresses are preferred over public
1549 : * addresses (RFC3484 requires a config knob for
1550 : * this which we don't provide).
1551 : */
1552 0 : if (oifp == ifp) {
1553 : /* Do not replace temporary autoconf addresses
1554 : * with non-temporary addresses. */
1555 0 : if ((ia6_best->ia6_flags & IN6_IFF_PRIVACY) &&
1556 0 : !(ifatoia6(ifa)->ia6_flags &
1557 : IN6_IFF_PRIVACY))
1558 0 : continue;
1559 :
1560 : /* Replace non-temporary autoconf addresses
1561 : * with temporary addresses. */
1562 0 : if (!(ia6_best->ia6_flags & IN6_IFF_PRIVACY) &&
1563 0 : (ifatoia6(ifa)->ia6_flags &
1564 : IN6_IFF_PRIVACY))
1565 : goto replace;
1566 : }
1567 0 : tlen = in6_matchlen(IFA_IN6(ifa), dst);
1568 0 : matchcmp = tlen - blen;
1569 0 : if (matchcmp > 0) { /* (8) */
1570 : #if NCARP > 0
1571 : /*
1572 : * Don't let carp interfaces win a tie against
1573 : * the output interface based on matchlen.
1574 : * We should only use a carp address if no
1575 : * other interface has a usable address.
1576 : * Otherwise, when communicating from a carp
1577 : * master to a carp slave, the slave won't
1578 : * respond since the carp address is also
1579 : * configured as a local address on the slave.
1580 : * Note that carp interfaces in backup state
1581 : * were already skipped above.
1582 : */
1583 0 : if (ifp->if_type == IFT_CARP &&
1584 0 : oifp->if_type != IFT_CARP)
1585 0 : continue;
1586 : #endif
1587 : goto replace;
1588 : }
1589 0 : if (matchcmp < 0) /* (9) */
1590 0 : continue;
1591 0 : if (oifp == ifp) /* (a) */
1592 : goto replace;
1593 0 : continue; /* (b) */
1594 :
1595 : replace:
1596 0 : ia6_best = ifatoia6(ifa);
1597 0 : blen = tlen >= 0 ? tlen :
1598 0 : in6_matchlen(IFA_IN6(ifa), dst);
1599 0 : best_scope = in6_addrscope(&ia6_best->ia_addr.sin6_addr);
1600 0 : }
1601 : }
1602 :
1603 : /* count statistics for future improvements */
1604 0 : if (ia6_best == NULL)
1605 0 : ip6stat_inc(ip6s_sources_none);
1606 : else {
1607 0 : if (oifp == ia6_best->ia_ifp)
1608 0 : ip6stat_inc(ip6s_sources_sameif + best_scope);
1609 : else
1610 0 : ip6stat_inc(ip6s_sources_otherif + best_scope);
1611 :
1612 0 : if (best_scope == dst_scope)
1613 0 : ip6stat_inc(ip6s_sources_samescope + best_scope);
1614 : else
1615 0 : ip6stat_inc(ip6s_sources_otherscope + best_scope);
1616 :
1617 0 : if ((ia6_best->ia6_flags & IN6_IFF_DEPRECATED) != 0)
1618 0 : ip6stat_inc(ip6s_sources_deprecated + best_scope);
1619 : }
1620 :
1621 0 : return (ia6_best);
1622 0 : }
1623 :
1624 : int
1625 0 : in6if_do_dad(struct ifnet *ifp)
1626 : {
1627 0 : if ((ifp->if_flags & IFF_LOOPBACK) != 0)
1628 0 : return (0);
1629 :
1630 0 : switch (ifp->if_type) {
1631 : #if NCARP > 0
1632 : case IFT_CARP:
1633 : /*
1634 : * XXX: DAD does not work currently on carp(4)
1635 : * so disable it for now.
1636 : */
1637 0 : return (0);
1638 : #endif
1639 : default:
1640 : /*
1641 : * Our DAD routine requires the interface up and running.
1642 : * However, some interfaces can be up before the RUNNING
1643 : * status. Additionaly, users may try to assign addresses
1644 : * before the interface becomes up (or running).
1645 : * We simply skip DAD in such a case as a work around.
1646 : * XXX: we should rather mark "tentative" on such addresses,
1647 : * and do DAD after the interface becomes ready.
1648 : */
1649 0 : if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) !=
1650 : (IFF_UP|IFF_RUNNING))
1651 0 : return (0);
1652 :
1653 0 : return (1);
1654 : }
1655 0 : }
1656 :
1657 : void *
1658 0 : in6_domifattach(struct ifnet *ifp)
1659 : {
1660 : struct in6_ifextra *ext;
1661 :
1662 0 : ext = malloc(sizeof(*ext), M_IFADDR, M_WAITOK | M_ZERO);
1663 :
1664 0 : ext->nd_ifinfo = nd6_ifattach(ifp);
1665 0 : ext->nprefixes = 0;
1666 0 : ext->ndefrouters = 0;
1667 0 : return ext;
1668 : }
1669 :
1670 : void
1671 0 : in6_domifdetach(struct ifnet *ifp, void *aux)
1672 : {
1673 0 : struct in6_ifextra *ext = (struct in6_ifextra *)aux;
1674 :
1675 0 : nd6_ifdetach(ext->nd_ifinfo);
1676 0 : free(ext, M_IFADDR, sizeof(*ext));
1677 0 : }
|