Fri Oct 3 10:43:48 2008 UTC ()
Pull up revisions:
  src/sys/netinet6/in6.c	1.141 via patch
  src/sys/netinet6/in6_var.h	1.59 via patch
  src/sys/netinet6/nd6_nbr.c	1.89-1.90 via patch
(requested by adrianp in ticket #1967).

If a neighbor solictation isn't from the unspecified address, make sure
that the source address matches one of the interfaces address prefixes.

Generalize previous fix so that both NS and NA packets are checked.


(jdc)
diff -r1.91 -r1.91.4.1 src/sys/netinet6/in6.c
diff -r1.38 -r1.38.4.1 src/sys/netinet6/in6_var.h
diff -r1.56 -r1.56.2.1 src/sys/netinet6/nd6_nbr.c

cvs diff -r1.91 -r1.91.4.1 src/sys/netinet6/in6.c (switch to unified diff)

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

cvs diff -r1.38 -r1.38.4.1 src/sys/netinet6/in6_var.h (switch to unified diff)

--- src/sys/netinet6/in6_var.h 2005/02/01 15:29:23 1.38
+++ src/sys/netinet6/in6_var.h 2008/10/03 10:43:48 1.38.4.1
@@ -1,612 +1,614 @@ @@ -1,612 +1,614 @@
1/* $NetBSD: in6_var.h,v 1.38 2005/02/01 15:29:23 drochner Exp $ */ 1/* $NetBSD: in6_var.h,v 1.38.4.1 2008/10/03 10:43:48 jdc Exp $ */
2/* $KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $ */ 2/* $KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors 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 17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission. 18 * without specific prior written permission.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 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 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Copyright (c) 1985, 1986, 1993 34 * Copyright (c) 1985, 1986, 1993
35 * The Regents of the University of California. All rights reserved. 35 * The Regents of the University of California. All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
39 * are met: 39 * are met:
40 * 1. Redistributions of source code must retain the above copyright 40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer. 41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright 42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the 43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution. 44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors 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 46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission. 47 * without specific prior written permission.
48 * 48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 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 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE. 59 * SUCH DAMAGE.
60 * 60 *
61 * @(#)in_var.h 8.1 (Berkeley) 6/10/93 61 * @(#)in_var.h 8.1 (Berkeley) 6/10/93
62 */ 62 */
63 63
64#ifndef _NETINET6_IN6_VAR_H_ 64#ifndef _NETINET6_IN6_VAR_H_
65#define _NETINET6_IN6_VAR_H_ 65#define _NETINET6_IN6_VAR_H_
66 66
67/* 67/*
68 * Interface address, Internet version. One of these structures 68 * Interface address, Internet version. One of these structures
69 * is allocated for each interface with an Internet address. 69 * is allocated for each interface with an Internet address.
70 * The ifaddr structure contains the protocol-independent part 70 * The ifaddr structure contains the protocol-independent part
71 * of the structure and is assumed to be first. 71 * of the structure and is assumed to be first.
72 */ 72 */
73 73
74/* 74/*
75 * pltime/vltime are just for future reference (required to implements 2 75 * pltime/vltime are just for future reference (required to implements 2
76 * hour rule for hosts). they should never be modified by nd6_timeout or 76 * hour rule for hosts). they should never be modified by nd6_timeout or
77 * anywhere else. 77 * anywhere else.
78 * userland -> kernel: accept pltime/vltime 78 * userland -> kernel: accept pltime/vltime
79 * kernel -> userland: throw up everything 79 * kernel -> userland: throw up everything
80 * in kernel: modify preferred/expire only 80 * in kernel: modify preferred/expire only
81 */ 81 */
82struct in6_addrlifetime { 82struct in6_addrlifetime {
83 time_t ia6t_expire; /* valid lifetime expiration time */ 83 time_t ia6t_expire; /* valid lifetime expiration time */
84 time_t ia6t_preferred; /* preferred lifetime expiration time */ 84 time_t ia6t_preferred; /* preferred lifetime expiration time */
85 u_int32_t ia6t_vltime; /* valid lifetime */ 85 u_int32_t ia6t_vltime; /* valid lifetime */
86 u_int32_t ia6t_pltime; /* prefix lifetime */ 86 u_int32_t ia6t_pltime; /* prefix lifetime */
87}; 87};
88 88
89struct nd_ifinfo; 89struct nd_ifinfo;
90struct in6_ifextra { 90struct in6_ifextra {
91 struct in6_ifstat *in6_ifstat; 91 struct in6_ifstat *in6_ifstat;
92 struct icmp6_ifstat *icmp6_ifstat; 92 struct icmp6_ifstat *icmp6_ifstat;
93 struct nd_ifinfo *nd_ifinfo; 93 struct nd_ifinfo *nd_ifinfo;
94}; 94};
95 95
96struct in6_ifaddr { 96struct in6_ifaddr {
97 struct ifaddr ia_ifa; /* protocol-independent info */ 97 struct ifaddr ia_ifa; /* protocol-independent info */
98#define ia_ifp ia_ifa.ifa_ifp 98#define ia_ifp ia_ifa.ifa_ifp
99#define ia_flags ia_ifa.ifa_flags 99#define ia_flags ia_ifa.ifa_flags
100 struct sockaddr_in6 ia_addr; /* interface address */ 100 struct sockaddr_in6 ia_addr; /* interface address */
101 struct sockaddr_in6 ia_net; /* network number of interface */ 101 struct sockaddr_in6 ia_net; /* network number of interface */
102 struct sockaddr_in6 ia_dstaddr; /* space for destination addr */ 102 struct sockaddr_in6 ia_dstaddr; /* space for destination addr */
103 struct sockaddr_in6 ia_prefixmask; /* prefix mask */ 103 struct sockaddr_in6 ia_prefixmask; /* prefix mask */
104 u_int32_t ia_plen; /* prefix length */ 104 u_int32_t ia_plen; /* prefix length */
105 struct in6_ifaddr *ia_next; /* next in6 list of IP6 addresses */ 105 struct in6_ifaddr *ia_next; /* next in6 list of IP6 addresses */
106 LIST_HEAD(in6_multihead, in6_multi) ia6_multiaddrs; 106 LIST_HEAD(in6_multihead, in6_multi) ia6_multiaddrs;
107 /* list of multicast addresses */ 107 /* list of multicast addresses */
108 int ia6_flags; 108 int ia6_flags;
109 109
110 struct in6_addrlifetime ia6_lifetime; 110 struct in6_addrlifetime ia6_lifetime;
111 time_t ia6_createtime; /* the creation time of this address, which is 111 time_t ia6_createtime; /* the creation time of this address, which is
112 * currently used for temporary addresses only. 112 * currently used for temporary addresses only.
113 */ 113 */
114 time_t ia6_updatetime; 114 time_t ia6_updatetime;
115 115
116 /* back pointer to the ND prefix (for autoconfigured addresses only) */ 116 /* back pointer to the ND prefix (for autoconfigured addresses only) */
117 struct nd_prefix *ia6_ndpr; 117 struct nd_prefix *ia6_ndpr;
118 118
119 /* multicast addresses joined from the kernel */ 119 /* multicast addresses joined from the kernel */
120 LIST_HEAD(, in6_multi_mship) ia6_memberships; 120 LIST_HEAD(, in6_multi_mship) ia6_memberships;
121}; 121};
122 122
123/* 123/*
124 * IPv6 interface statistics, as defined in RFC2465 Ipv6IfStatsEntry (p12). 124 * IPv6 interface statistics, as defined in RFC2465 Ipv6IfStatsEntry (p12).
125 */ 125 */
126struct in6_ifstat { 126struct in6_ifstat {
127 u_quad_t ifs6_in_receive; /* # of total input datagram */ 127 u_quad_t ifs6_in_receive; /* # of total input datagram */
128 u_quad_t ifs6_in_hdrerr; /* # of datagrams with invalid hdr */ 128 u_quad_t ifs6_in_hdrerr; /* # of datagrams with invalid hdr */
129 u_quad_t ifs6_in_toobig; /* # of datagrams exceeded MTU */ 129 u_quad_t ifs6_in_toobig; /* # of datagrams exceeded MTU */
130 u_quad_t ifs6_in_noroute; /* # of datagrams with no route */ 130 u_quad_t ifs6_in_noroute; /* # of datagrams with no route */
131 u_quad_t ifs6_in_addrerr; /* # of datagrams with invalid dst */ 131 u_quad_t ifs6_in_addrerr; /* # of datagrams with invalid dst */
132 u_quad_t ifs6_in_protounknown; /* # of datagrams with unknown proto */ 132 u_quad_t ifs6_in_protounknown; /* # of datagrams with unknown proto */
133 /* NOTE: increment on final dst if */ 133 /* NOTE: increment on final dst if */
134 u_quad_t ifs6_in_truncated; /* # of truncated datagrams */ 134 u_quad_t ifs6_in_truncated; /* # of truncated datagrams */
135 u_quad_t ifs6_in_discard; /* # of discarded datagrams */ 135 u_quad_t ifs6_in_discard; /* # of discarded datagrams */
136 /* NOTE: fragment timeout is not here */ 136 /* NOTE: fragment timeout is not here */
137 u_quad_t ifs6_in_deliver; /* # of datagrams delivered to ULP */ 137 u_quad_t ifs6_in_deliver; /* # of datagrams delivered to ULP */
138 /* NOTE: increment on final dst if */ 138 /* NOTE: increment on final dst if */
139 u_quad_t ifs6_out_forward; /* # of datagrams forwarded */ 139 u_quad_t ifs6_out_forward; /* # of datagrams forwarded */
140 /* NOTE: increment on outgoing if */ 140 /* NOTE: increment on outgoing if */
141 u_quad_t ifs6_out_request; /* # of outgoing datagrams from ULP */ 141 u_quad_t ifs6_out_request; /* # of outgoing datagrams from ULP */
142 /* NOTE: does not include forwrads */ 142 /* NOTE: does not include forwrads */
143 u_quad_t ifs6_out_discard; /* # of discarded datagrams */ 143 u_quad_t ifs6_out_discard; /* # of discarded datagrams */
144 u_quad_t ifs6_out_fragok; /* # of datagrams fragmented */ 144 u_quad_t ifs6_out_fragok; /* # of datagrams fragmented */
145 u_quad_t ifs6_out_fragfail; /* # of datagrams failed on fragment */ 145 u_quad_t ifs6_out_fragfail; /* # of datagrams failed on fragment */
146 u_quad_t ifs6_out_fragcreat; /* # of fragment datagrams */ 146 u_quad_t ifs6_out_fragcreat; /* # of fragment datagrams */
147 /* NOTE: this is # after fragment */ 147 /* NOTE: this is # after fragment */
148 u_quad_t ifs6_reass_reqd; /* # of incoming fragmented packets */ 148 u_quad_t ifs6_reass_reqd; /* # of incoming fragmented packets */
149 /* NOTE: increment on final dst if */ 149 /* NOTE: increment on final dst if */
150 u_quad_t ifs6_reass_ok; /* # of reassembled packets */ 150 u_quad_t ifs6_reass_ok; /* # of reassembled packets */
151 /* NOTE: this is # after reass */ 151 /* NOTE: this is # after reass */
152 /* NOTE: increment on final dst if */ 152 /* NOTE: increment on final dst if */
153 u_quad_t ifs6_reass_fail; /* # of reass failures */ 153 u_quad_t ifs6_reass_fail; /* # of reass failures */
154 /* NOTE: may not be packet count */ 154 /* NOTE: may not be packet count */
155 /* NOTE: increment on final dst if */ 155 /* NOTE: increment on final dst if */
156 u_quad_t ifs6_in_mcast; /* # of inbound multicast datagrams */ 156 u_quad_t ifs6_in_mcast; /* # of inbound multicast datagrams */
157 u_quad_t ifs6_out_mcast; /* # of outbound multicast datagrams */ 157 u_quad_t ifs6_out_mcast; /* # of outbound multicast datagrams */
158}; 158};
159 159
160/* 160/*
161 * ICMPv6 interface statistics, as defined in RFC2466 Ipv6IfIcmpEntry. 161 * ICMPv6 interface statistics, as defined in RFC2466 Ipv6IfIcmpEntry.
162 * XXX: I'm not sure if this file is the right place for this structure... 162 * XXX: I'm not sure if this file is the right place for this structure...
163 */ 163 */
164struct icmp6_ifstat { 164struct icmp6_ifstat {
165 /* 165 /*
166 * Input statistics 166 * Input statistics
167 */ 167 */
168 /* ipv6IfIcmpInMsgs, total # of input messages */ 168 /* ipv6IfIcmpInMsgs, total # of input messages */
169 u_quad_t ifs6_in_msg; 169 u_quad_t ifs6_in_msg;
170 /* ipv6IfIcmpInErrors, # of input error messages */ 170 /* ipv6IfIcmpInErrors, # of input error messages */
171 u_quad_t ifs6_in_error; 171 u_quad_t ifs6_in_error;
172 /* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */ 172 /* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */
173 u_quad_t ifs6_in_dstunreach; 173 u_quad_t ifs6_in_dstunreach;
174 /* ipv6IfIcmpInAdminProhibs, # of input administratively prohibited errs */ 174 /* ipv6IfIcmpInAdminProhibs, # of input administratively prohibited errs */
175 u_quad_t ifs6_in_adminprohib; 175 u_quad_t ifs6_in_adminprohib;
176 /* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */ 176 /* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */
177 u_quad_t ifs6_in_timeexceed; 177 u_quad_t ifs6_in_timeexceed;
178 /* ipv6IfIcmpInParmProblems, # of input parameter problem errors */ 178 /* ipv6IfIcmpInParmProblems, # of input parameter problem errors */
179 u_quad_t ifs6_in_paramprob; 179 u_quad_t ifs6_in_paramprob;
180 /* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */ 180 /* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */
181 u_quad_t ifs6_in_pkttoobig; 181 u_quad_t ifs6_in_pkttoobig;
182 /* ipv6IfIcmpInEchos, # of input echo requests */ 182 /* ipv6IfIcmpInEchos, # of input echo requests */
183 u_quad_t ifs6_in_echo; 183 u_quad_t ifs6_in_echo;
184 /* ipv6IfIcmpInEchoReplies, # of input echo replies */ 184 /* ipv6IfIcmpInEchoReplies, # of input echo replies */
185 u_quad_t ifs6_in_echoreply; 185 u_quad_t ifs6_in_echoreply;
186 /* ipv6IfIcmpInRouterSolicits, # of input router solicitations */ 186 /* ipv6IfIcmpInRouterSolicits, # of input router solicitations */
187 u_quad_t ifs6_in_routersolicit; 187 u_quad_t ifs6_in_routersolicit;
188 /* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */ 188 /* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */
189 u_quad_t ifs6_in_routeradvert; 189 u_quad_t ifs6_in_routeradvert;
190 /* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */ 190 /* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */
191 u_quad_t ifs6_in_neighborsolicit; 191 u_quad_t ifs6_in_neighborsolicit;
192 /* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advertisements */ 192 /* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advertisements */
193 u_quad_t ifs6_in_neighboradvert; 193 u_quad_t ifs6_in_neighboradvert;
194 /* ipv6IfIcmpInRedirects, # of input redirects */ 194 /* ipv6IfIcmpInRedirects, # of input redirects */
195 u_quad_t ifs6_in_redirect; 195 u_quad_t ifs6_in_redirect;
196 /* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */ 196 /* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */
197 u_quad_t ifs6_in_mldquery; 197 u_quad_t ifs6_in_mldquery;
198 /* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */ 198 /* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */
199 u_quad_t ifs6_in_mldreport; 199 u_quad_t ifs6_in_mldreport;
200 /* ipv6IfIcmpInGroupMembReductions, # of input MLD done */ 200 /* ipv6IfIcmpInGroupMembReductions, # of input MLD done */
201 u_quad_t ifs6_in_mlddone; 201 u_quad_t ifs6_in_mlddone;
202 202
203 /* 203 /*
204 * Output statistics. We should solve unresolved routing problem... 204 * Output statistics. We should solve unresolved routing problem...
205 */ 205 */
206 /* ipv6IfIcmpOutMsgs, total # of output messages */ 206 /* ipv6IfIcmpOutMsgs, total # of output messages */
207 u_quad_t ifs6_out_msg; 207 u_quad_t ifs6_out_msg;
208 /* ipv6IfIcmpOutErrors, # of output error messages */ 208 /* ipv6IfIcmpOutErrors, # of output error messages */
209 u_quad_t ifs6_out_error; 209 u_quad_t ifs6_out_error;
210 /* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */ 210 /* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */
211 u_quad_t ifs6_out_dstunreach; 211 u_quad_t ifs6_out_dstunreach;
212 /* ipv6IfIcmpOutAdminProhibs, # of output administratively prohibited errs */ 212 /* ipv6IfIcmpOutAdminProhibs, # of output administratively prohibited errs */
213 u_quad_t ifs6_out_adminprohib; 213 u_quad_t ifs6_out_adminprohib;
214 /* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */ 214 /* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */
215 u_quad_t ifs6_out_timeexceed; 215 u_quad_t ifs6_out_timeexceed;
216 /* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */ 216 /* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */
217 u_quad_t ifs6_out_paramprob; 217 u_quad_t ifs6_out_paramprob;
218 /* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */ 218 /* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */
219 u_quad_t ifs6_out_pkttoobig; 219 u_quad_t ifs6_out_pkttoobig;
220 /* ipv6IfIcmpOutEchos, # of output echo requests */ 220 /* ipv6IfIcmpOutEchos, # of output echo requests */
221 u_quad_t ifs6_out_echo; 221 u_quad_t ifs6_out_echo;
222 /* ipv6IfIcmpOutEchoReplies, # of output echo replies */ 222 /* ipv6IfIcmpOutEchoReplies, # of output echo replies */
223 u_quad_t ifs6_out_echoreply; 223 u_quad_t ifs6_out_echoreply;
224 /* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */ 224 /* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */
225 u_quad_t ifs6_out_routersolicit; 225 u_quad_t ifs6_out_routersolicit;
226 /* ipv6IfIcmpOutRouterAdvertisements, # of output router advertisements */ 226 /* ipv6IfIcmpOutRouterAdvertisements, # of output router advertisements */
227 u_quad_t ifs6_out_routeradvert; 227 u_quad_t ifs6_out_routeradvert;
228 /* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */ 228 /* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */
229 u_quad_t ifs6_out_neighborsolicit; 229 u_quad_t ifs6_out_neighborsolicit;
230 /* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advertisements */ 230 /* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advertisements */
231 u_quad_t ifs6_out_neighboradvert; 231 u_quad_t ifs6_out_neighboradvert;
232 /* ipv6IfIcmpOutRedirects, # of output redirects */ 232 /* ipv6IfIcmpOutRedirects, # of output redirects */
233 u_quad_t ifs6_out_redirect; 233 u_quad_t ifs6_out_redirect;
234 /* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */ 234 /* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */
235 u_quad_t ifs6_out_mldquery; 235 u_quad_t ifs6_out_mldquery;
236 /* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */ 236 /* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */
237 u_quad_t ifs6_out_mldreport; 237 u_quad_t ifs6_out_mldreport;
238 /* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */ 238 /* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */
239 u_quad_t ifs6_out_mlddone; 239 u_quad_t ifs6_out_mlddone;
240}; 240};
241 241
242struct in6_ifreq { 242struct in6_ifreq {
243 char ifr_name[IFNAMSIZ]; 243 char ifr_name[IFNAMSIZ];
244 union { 244 union {
245 struct sockaddr_in6 ifru_addr; 245 struct sockaddr_in6 ifru_addr;
246 struct sockaddr_in6 ifru_dstaddr; 246 struct sockaddr_in6 ifru_dstaddr;
247 short ifru_flags; 247 short ifru_flags;
248 int ifru_flags6; 248 int ifru_flags6;
249 int ifru_metric; 249 int ifru_metric;
250 caddr_t ifru_data; 250 caddr_t ifru_data;
251 struct in6_addrlifetime ifru_lifetime; 251 struct in6_addrlifetime ifru_lifetime;
252 struct in6_ifstat ifru_stat; 252 struct in6_ifstat ifru_stat;
253 struct icmp6_ifstat ifru_icmp6stat; 253 struct icmp6_ifstat ifru_icmp6stat;
254 } ifr_ifru; 254 } ifr_ifru;
255}; 255};
256 256
257struct in6_aliasreq { 257struct in6_aliasreq {
258 char ifra_name[IFNAMSIZ]; 258 char ifra_name[IFNAMSIZ];
259 struct sockaddr_in6 ifra_addr; 259 struct sockaddr_in6 ifra_addr;
260 struct sockaddr_in6 ifra_dstaddr; 260 struct sockaddr_in6 ifra_dstaddr;
261 struct sockaddr_in6 ifra_prefixmask; 261 struct sockaddr_in6 ifra_prefixmask;
262 int ifra_flags; 262 int ifra_flags;
263 struct in6_addrlifetime ifra_lifetime; 263 struct in6_addrlifetime ifra_lifetime;
264}; 264};
265 265
266/* prefix type macro */ 266/* prefix type macro */
267#define IN6_PREFIX_ND 1 267#define IN6_PREFIX_ND 1
268#define IN6_PREFIX_RR 2 268#define IN6_PREFIX_RR 2
269 269
270/* 270/*
271 * prefix related flags passed between kernel(NDP related part) and 271 * prefix related flags passed between kernel(NDP related part) and
272 * user land command(ifconfig) and daemon(rtadvd). 272 * user land command(ifconfig) and daemon(rtadvd).
273 */ 273 */
274struct prf_ra { 274struct prf_ra {
275 u_char onlink : 1; 275 u_char onlink : 1;
276 u_char autonomous : 1; 276 u_char autonomous : 1;
277 u_char router : 1; 277 u_char router : 1;
278 u_char reserved : 5; 278 u_char reserved : 5;
279}; 279};
280 280
281struct in6_prflags { 281struct in6_prflags {
282 struct prf_ra prf_ra; 282 struct prf_ra prf_ra;
283 u_char prf_reserved1; 283 u_char prf_reserved1;
284 u_short prf_reserved2; 284 u_short prf_reserved2;
285 /* want to put this on 4byte offset */ 285 /* want to put this on 4byte offset */
286 struct prf_rr { 286 struct prf_rr {
287 u_char decrvalid : 1; 287 u_char decrvalid : 1;
288 u_char decrprefd : 1; 288 u_char decrprefd : 1;
289 u_char reserved : 6; 289 u_char reserved : 6;
290 } prf_rr; 290 } prf_rr;
291 u_char prf_reserved3; 291 u_char prf_reserved3;
292 u_short prf_reserved4; 292 u_short prf_reserved4;
293}; 293};
294 294
295struct in6_prefixreq { 295struct in6_prefixreq {
296 char ipr_name[IFNAMSIZ]; 296 char ipr_name[IFNAMSIZ];
297 u_char ipr_origin; 297 u_char ipr_origin;
298 u_char ipr_plen; 298 u_char ipr_plen;
299 u_int32_t ipr_vltime; 299 u_int32_t ipr_vltime;
300 u_int32_t ipr_pltime; 300 u_int32_t ipr_pltime;
301 struct in6_prflags ipr_flags; 301 struct in6_prflags ipr_flags;
302 struct sockaddr_in6 ipr_prefix; 302 struct sockaddr_in6 ipr_prefix;
303}; 303};
304 304
305#define PR_ORIG_RA 0 305#define PR_ORIG_RA 0
306#define PR_ORIG_RR 1 306#define PR_ORIG_RR 1
307#define PR_ORIG_STATIC 2 307#define PR_ORIG_STATIC 2
308#define PR_ORIG_KERNEL 3 308#define PR_ORIG_KERNEL 3
309 309
310#define ipr_raf_onlink ipr_flags.prf_ra.onlink 310#define ipr_raf_onlink ipr_flags.prf_ra.onlink
311#define ipr_raf_auto ipr_flags.prf_ra.autonomous 311#define ipr_raf_auto ipr_flags.prf_ra.autonomous
312 312
313#define ipr_statef_onlink ipr_flags.prf_state.onlink 313#define ipr_statef_onlink ipr_flags.prf_state.onlink
314 314
315#define ipr_rrf_decrvalid ipr_flags.prf_rr.decrvalid 315#define ipr_rrf_decrvalid ipr_flags.prf_rr.decrvalid
316#define ipr_rrf_decrprefd ipr_flags.prf_rr.decrprefd 316#define ipr_rrf_decrprefd ipr_flags.prf_rr.decrprefd
317 317
318struct in6_rrenumreq { 318struct in6_rrenumreq {
319 char irr_name[IFNAMSIZ]; 319 char irr_name[IFNAMSIZ];
320 u_char irr_origin; 320 u_char irr_origin;
321 u_char irr_m_len; /* match len for matchprefix */ 321 u_char irr_m_len; /* match len for matchprefix */
322 u_char irr_m_minlen; /* minlen for matching prefix */ 322 u_char irr_m_minlen; /* minlen for matching prefix */
323 u_char irr_m_maxlen; /* maxlen for matching prefix */ 323 u_char irr_m_maxlen; /* maxlen for matching prefix */
324 u_char irr_u_uselen; /* uselen for adding prefix */ 324 u_char irr_u_uselen; /* uselen for adding prefix */
325 u_char irr_u_keeplen; /* keeplen from matching prefix */ 325 u_char irr_u_keeplen; /* keeplen from matching prefix */
326 struct irr_raflagmask { 326 struct irr_raflagmask {
327 u_char onlink : 1; 327 u_char onlink : 1;
328 u_char autonomous : 1; 328 u_char autonomous : 1;
329 u_char reserved : 6; 329 u_char reserved : 6;
330 } irr_raflagmask; 330 } irr_raflagmask;
331 u_int32_t irr_vltime; 331 u_int32_t irr_vltime;
332 u_int32_t irr_pltime; 332 u_int32_t irr_pltime;
333 struct in6_prflags irr_flags; 333 struct in6_prflags irr_flags;
334 struct sockaddr_in6 irr_matchprefix; 334 struct sockaddr_in6 irr_matchprefix;
335 struct sockaddr_in6 irr_useprefix; 335 struct sockaddr_in6 irr_useprefix;
336}; 336};
337 337
338#define irr_raf_mask_onlink irr_raflagmask.onlink 338#define irr_raf_mask_onlink irr_raflagmask.onlink
339#define irr_raf_mask_auto irr_raflagmask.autonomous 339#define irr_raf_mask_auto irr_raflagmask.autonomous
340#define irr_raf_mask_reserved irr_raflagmask.reserved 340#define irr_raf_mask_reserved irr_raflagmask.reserved
341 341
342#define irr_raf_onlink irr_flags.prf_ra.onlink 342#define irr_raf_onlink irr_flags.prf_ra.onlink
343#define irr_raf_auto irr_flags.prf_ra.autonomous 343#define irr_raf_auto irr_flags.prf_ra.autonomous
344 344
345#define irr_statef_onlink irr_flags.prf_state.onlink 345#define irr_statef_onlink irr_flags.prf_state.onlink
346 346
347#define irr_rrf irr_flags.prf_rr 347#define irr_rrf irr_flags.prf_rr
348#define irr_rrf_decrvalid irr_flags.prf_rr.decrvalid 348#define irr_rrf_decrvalid irr_flags.prf_rr.decrvalid
349#define irr_rrf_decrprefd irr_flags.prf_rr.decrprefd 349#define irr_rrf_decrprefd irr_flags.prf_rr.decrprefd
350 350
351/* 351/*
352 * Given a pointer to an in6_ifaddr (ifaddr), 352 * Given a pointer to an in6_ifaddr (ifaddr),
353 * return a pointer to the addr as a sockaddr_in6 353 * return a pointer to the addr as a sockaddr_in6
354 */ 354 */
355#define IA6_IN6(ia) (&((ia)->ia_addr.sin6_addr)) 355#define IA6_IN6(ia) (&((ia)->ia_addr.sin6_addr))
356#define IA6_DSTIN6(ia) (&((ia)->ia_dstaddr.sin6_addr)) 356#define IA6_DSTIN6(ia) (&((ia)->ia_dstaddr.sin6_addr))
357#define IA6_MASKIN6(ia) (&((ia)->ia_prefixmask.sin6_addr)) 357#define IA6_MASKIN6(ia) (&((ia)->ia_prefixmask.sin6_addr))
358#define IA6_SIN6(ia) (&((ia)->ia_addr)) 358#define IA6_SIN6(ia) (&((ia)->ia_addr))
359#define IA6_DSTSIN6(ia) (&((ia)->ia_dstaddr)) 359#define IA6_DSTSIN6(ia) (&((ia)->ia_dstaddr))
360#define IFA_IN6(x) (&((struct sockaddr_in6 *)((x)->ifa_addr))->sin6_addr) 360#define IFA_IN6(x) (&((struct sockaddr_in6 *)((x)->ifa_addr))->sin6_addr)
361#define IFA_DSTIN6(x) (&((struct sockaddr_in6 *)((x)->ifa_dstaddr))->sin6_addr) 361#define IFA_DSTIN6(x) (&((struct sockaddr_in6 *)((x)->ifa_dstaddr))->sin6_addr)
362 362
363#ifdef _KERNEL 363#ifdef _KERNEL
364#define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \ 364#define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
365 (((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \ 365 (((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \
366 (((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \ 366 (((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \
367 (((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \ 367 (((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \
368 (((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 ) 368 (((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 )
369#endif 369#endif
370 370
371#define SIOCSIFADDR_IN6 _IOW('i', 12, struct in6_ifreq) 371#define SIOCSIFADDR_IN6 _IOW('i', 12, struct in6_ifreq)
372#define SIOCGIFADDR_IN6 _IOWR('i', 33, struct in6_ifreq) 372#define SIOCGIFADDR_IN6 _IOWR('i', 33, struct in6_ifreq)
373 373
374#ifdef _KERNEL 374#ifdef _KERNEL
375/* 375/*
376 * SIOCSxxx ioctls should be unused (see comments in in6.c), but 376 * SIOCSxxx ioctls should be unused (see comments in in6.c), but
377 * we do not shift numbers for binary compatibility. 377 * we do not shift numbers for binary compatibility.
378 */ 378 */
379#define SIOCSIFDSTADDR_IN6 _IOW('i', 14, struct in6_ifreq) 379#define SIOCSIFDSTADDR_IN6 _IOW('i', 14, struct in6_ifreq)
380#define SIOCSIFNETMASK_IN6 _IOW('i', 22, struct in6_ifreq) 380#define SIOCSIFNETMASK_IN6 _IOW('i', 22, struct in6_ifreq)
381#endif 381#endif
382 382
383#define SIOCGIFDSTADDR_IN6 _IOWR('i', 34, struct in6_ifreq) 383#define SIOCGIFDSTADDR_IN6 _IOWR('i', 34, struct in6_ifreq)
384#define SIOCGIFNETMASK_IN6 _IOWR('i', 37, struct in6_ifreq) 384#define SIOCGIFNETMASK_IN6 _IOWR('i', 37, struct in6_ifreq)
385 385
386#define SIOCDIFADDR_IN6 _IOW('i', 25, struct in6_ifreq) 386#define SIOCDIFADDR_IN6 _IOW('i', 25, struct in6_ifreq)
387#define SIOCAIFADDR_IN6 _IOW('i', 26, struct in6_aliasreq) 387#define SIOCAIFADDR_IN6 _IOW('i', 26, struct in6_aliasreq)
388 388
389#define SIOCSIFPHYADDR_IN6 _IOW('i', 70, struct in6_aliasreq) 389#define SIOCSIFPHYADDR_IN6 _IOW('i', 70, struct in6_aliasreq)
390#define SIOCGIFPSRCADDR_IN6 _IOWR('i', 71, struct in6_ifreq) 390#define SIOCGIFPSRCADDR_IN6 _IOWR('i', 71, struct in6_ifreq)
391#define SIOCGIFPDSTADDR_IN6 _IOWR('i', 72, struct in6_ifreq) 391#define SIOCGIFPDSTADDR_IN6 _IOWR('i', 72, struct in6_ifreq)
392 392
393#define SIOCGIFAFLAG_IN6 _IOWR('i', 73, struct in6_ifreq) 393#define SIOCGIFAFLAG_IN6 _IOWR('i', 73, struct in6_ifreq)
394 394
395#define SIOCGDRLST_IN6 _IOWR('i', 74, struct in6_drlist) 395#define SIOCGDRLST_IN6 _IOWR('i', 74, struct in6_drlist)
396#define SIOCGPRLST_IN6 _IOWR('i', 75, struct in6_oprlist) 396#define SIOCGPRLST_IN6 _IOWR('i', 75, struct in6_oprlist)
397#ifdef _KERNEL 397#ifdef _KERNEL
398#define OSIOCGIFINFO_IN6 _IOWR('i', 76, struct in6_ondireq) 398#define OSIOCGIFINFO_IN6 _IOWR('i', 76, struct in6_ondireq)
399#endif 399#endif
400#define SIOCGIFINFO_IN6 _IOWR('i', 108, struct in6_ndireq) 400#define SIOCGIFINFO_IN6 _IOWR('i', 108, struct in6_ndireq)
401#define SIOCSNDFLUSH_IN6 _IOWR('i', 77, struct in6_ifreq) 401#define SIOCSNDFLUSH_IN6 _IOWR('i', 77, struct in6_ifreq)
402#define SIOCGNBRINFO_IN6 _IOWR('i', 78, struct in6_nbrinfo) 402#define SIOCGNBRINFO_IN6 _IOWR('i', 78, struct in6_nbrinfo)
403#define SIOCSPFXFLUSH_IN6 _IOWR('i', 79, struct in6_ifreq) 403#define SIOCSPFXFLUSH_IN6 _IOWR('i', 79, struct in6_ifreq)
404#define SIOCSRTRFLUSH_IN6 _IOWR('i', 80, struct in6_ifreq) 404#define SIOCSRTRFLUSH_IN6 _IOWR('i', 80, struct in6_ifreq)
405 405
406#define SIOCGIFALIFETIME_IN6 _IOWR('i', 81, struct in6_ifreq) 406#define SIOCGIFALIFETIME_IN6 _IOWR('i', 81, struct in6_ifreq)
407#define SIOCSIFALIFETIME_IN6 _IOWR('i', 82, struct in6_ifreq) 407#define SIOCSIFALIFETIME_IN6 _IOWR('i', 82, struct in6_ifreq)
408#define SIOCGIFSTAT_IN6 _IOWR('i', 83, struct in6_ifreq) 408#define SIOCGIFSTAT_IN6 _IOWR('i', 83, struct in6_ifreq)
409#define SIOCGIFSTAT_ICMP6 _IOWR('i', 84, struct in6_ifreq) 409#define SIOCGIFSTAT_ICMP6 _IOWR('i', 84, struct in6_ifreq)
410 410
411#define SIOCSDEFIFACE_IN6 _IOWR('i', 85, struct in6_ndifreq) 411#define SIOCSDEFIFACE_IN6 _IOWR('i', 85, struct in6_ndifreq)
412#define SIOCGDEFIFACE_IN6 _IOWR('i', 86, struct in6_ndifreq) 412#define SIOCGDEFIFACE_IN6 _IOWR('i', 86, struct in6_ndifreq)
413 413
414#define SIOCSIFINFO_FLAGS _IOWR('i', 87, struct in6_ndireq) /* XXX */ 414#define SIOCSIFINFO_FLAGS _IOWR('i', 87, struct in6_ndireq) /* XXX */
415 415
416#define SIOCSIFPREFIX_IN6 _IOW('i', 100, struct in6_prefixreq) /* set */ 416#define SIOCSIFPREFIX_IN6 _IOW('i', 100, struct in6_prefixreq) /* set */
417#define SIOCGIFPREFIX_IN6 _IOWR('i', 101, struct in6_prefixreq) /* get */ 417#define SIOCGIFPREFIX_IN6 _IOWR('i', 101, struct in6_prefixreq) /* get */
418#define SIOCDIFPREFIX_IN6 _IOW('i', 102, struct in6_prefixreq) /* del */ 418#define SIOCDIFPREFIX_IN6 _IOW('i', 102, struct in6_prefixreq) /* del */
419#define SIOCAIFPREFIX_IN6 _IOW('i', 103, struct in6_rrenumreq) /* add */ 419#define SIOCAIFPREFIX_IN6 _IOW('i', 103, struct in6_rrenumreq) /* add */
420#define SIOCCIFPREFIX_IN6 _IOW('i', 104, \ 420#define SIOCCIFPREFIX_IN6 _IOW('i', 104, \
421 struct in6_rrenumreq) /* change */ 421 struct in6_rrenumreq) /* change */
422#define SIOCSGIFPREFIX_IN6 _IOW('i', 105, \ 422#define SIOCSGIFPREFIX_IN6 _IOW('i', 105, \
423 struct in6_rrenumreq) /* set global */ 423 struct in6_rrenumreq) /* set global */
424 424
425#define SIOCGETSGCNT_IN6 _IOWR('u', 106, \ 425#define SIOCGETSGCNT_IN6 _IOWR('u', 106, \
426 struct sioc_sg_req6) /* get s,g pkt cnt */ 426 struct sioc_sg_req6) /* get s,g pkt cnt */
427#define SIOCGETMIFCNT_IN6 _IOWR('u', 107, \ 427#define SIOCGETMIFCNT_IN6 _IOWR('u', 107, \
428 struct sioc_mif_req6) /* get pkt cnt per if */ 428 struct sioc_mif_req6) /* get pkt cnt per if */
429 429
430#define IN6_IFF_ANYCAST 0x01 /* anycast address */ 430#define IN6_IFF_ANYCAST 0x01 /* anycast address */
431#define IN6_IFF_TENTATIVE 0x02 /* tentative address */ 431#define IN6_IFF_TENTATIVE 0x02 /* tentative address */
432#define IN6_IFF_DUPLICATED 0x04 /* DAD detected duplicate */ 432#define IN6_IFF_DUPLICATED 0x04 /* DAD detected duplicate */
433#define IN6_IFF_DETACHED 0x08 /* may be detached from the link */ 433#define IN6_IFF_DETACHED 0x08 /* may be detached from the link */
434#define IN6_IFF_DEPRECATED 0x10 /* deprecated address */ 434#define IN6_IFF_DEPRECATED 0x10 /* deprecated address */
435#define IN6_IFF_NODAD 0x20 /* don't perform DAD on this address 435#define IN6_IFF_NODAD 0x20 /* don't perform DAD on this address
436 * (used only at first SIOC* call) 436 * (used only at first SIOC* call)
437 */ 437 */
438#define IN6_IFF_AUTOCONF 0x40 /* autoconfigurable address. */ 438#define IN6_IFF_AUTOCONF 0x40 /* autoconfigurable address. */
439 439
440/* do not input/output */ 440/* do not input/output */
441#define IN6_IFF_NOTREADY (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED) 441#define IN6_IFF_NOTREADY (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED)
442 442
443#ifdef _KERNEL 443#ifdef _KERNEL
444#define IN6_ARE_SCOPE_CMP(a,b) ((a)-(b)) 444#define IN6_ARE_SCOPE_CMP(a,b) ((a)-(b))
445#define IN6_ARE_SCOPE_EQUAL(a,b) ((a)==(b)) 445#define IN6_ARE_SCOPE_EQUAL(a,b) ((a)==(b))
446#endif 446#endif
447 447
448#ifdef _KERNEL 448#ifdef _KERNEL
449MALLOC_DECLARE(M_IP6OPT); 449MALLOC_DECLARE(M_IP6OPT);
450 450
451extern struct in6_ifaddr *in6_ifaddr; 451extern struct in6_ifaddr *in6_ifaddr;
452 452
453extern struct icmp6stat icmp6stat; 453extern struct icmp6stat icmp6stat;
454#define in6_ifstat_inc(ifp, tag) \ 454#define in6_ifstat_inc(ifp, tag) \
455do { \ 455do { \
456 if (ifp) \ 456 if (ifp) \
457 ((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->in6_ifstat->tag++; \ 457 ((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->in6_ifstat->tag++; \
458} while (/*CONSTCOND*/ 0) 458} while (/*CONSTCOND*/ 0)
459 459
460extern struct ifqueue ip6intrq; /* IP6 packet input queue */ 460extern struct ifqueue ip6intrq; /* IP6 packet input queue */
461extern struct in6_addr zeroin6_addr; 461extern struct in6_addr zeroin6_addr;
462extern u_char inet6ctlerrmap[]; 462extern u_char inet6ctlerrmap[];
463extern unsigned long in6_maxmtu; 463extern unsigned long in6_maxmtu;
464 464
465/* 465/*
466 * Macro for finding the internet address structure (in6_ifaddr) corresponding 466 * Macro for finding the internet address structure (in6_ifaddr) corresponding
467 * to a given interface (ifnet structure). 467 * to a given interface (ifnet structure).
468 */ 468 */
469 469
470#define IFP_TO_IA6(ifp, ia) \ 470#define IFP_TO_IA6(ifp, ia) \
471/* struct ifnet *ifp; */ \ 471/* struct ifnet *ifp; */ \
472/* struct in6_ifaddr *ia; */ \ 472/* struct in6_ifaddr *ia; */ \
473do { \ 473do { \
474 struct ifaddr *ifa; \ 474 struct ifaddr *ifa; \
475 for (ifa = (ifp)->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next) { \ 475 for (ifa = (ifp)->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next) { \
476 if (!ifa->ifa_addr) \ 476 if (!ifa->ifa_addr) \
477 continue; \ 477 continue; \
478 if (ifa->ifa_addr->sa_family == AF_INET6) \ 478 if (ifa->ifa_addr->sa_family == AF_INET6) \
479 break; \ 479 break; \
480 } \ 480 } \
481 (ia) = (struct in6_ifaddr *)ifa; \ 481 (ia) = (struct in6_ifaddr *)ifa; \
482} while (/*CONSTCOND*/ 0) 482} while (/*CONSTCOND*/ 0)
483 483
484#endif /* _KERNEL */ 484#endif /* _KERNEL */
485 485
486/* 486/*
487 * Multi-cast membership entry. One for each group/ifp that a PCB 487 * Multi-cast membership entry. One for each group/ifp that a PCB
488 * belongs to. 488 * belongs to.
489 */ 489 */
490struct in6_multi_mship { 490struct in6_multi_mship {
491 struct in6_multi *i6mm_maddr; /* Multicast address pointer */ 491 struct in6_multi *i6mm_maddr; /* Multicast address pointer */
492 LIST_ENTRY(in6_multi_mship) i6mm_chain; /* multicast options chain */ 492 LIST_ENTRY(in6_multi_mship) i6mm_chain; /* multicast options chain */
493}; 493};
494 494
495struct in6_multi { 495struct in6_multi {
496 LIST_ENTRY(in6_multi) in6m_entry; /* list glue */ 496 LIST_ENTRY(in6_multi) in6m_entry; /* list glue */
497 struct in6_addr in6m_addr; /* IP6 multicast address */ 497 struct in6_addr in6m_addr; /* IP6 multicast address */
498 struct ifnet *in6m_ifp; /* back pointer to ifnet */ 498 struct ifnet *in6m_ifp; /* back pointer to ifnet */
499 struct in6_ifaddr *in6m_ia; /* back pointer to in6_ifaddr */ 499 struct in6_ifaddr *in6m_ia; /* back pointer to in6_ifaddr */
500 u_int in6m_refcount; /* # membership claims by sockets */ 500 u_int in6m_refcount; /* # membership claims by sockets */
501 u_int in6m_state; /* state of the membership */ 501 u_int in6m_state; /* state of the membership */
502 u_int in6m_timer; /* MLD6 listener report timer */ 502 u_int in6m_timer; /* MLD6 listener report timer */
503}; 503};
504 504
505#ifdef _KERNEL 505#ifdef _KERNEL
506 506
507/* 507/*
508 * Structure used by macros below to remember position when stepping through 508 * Structure used by macros below to remember position when stepping through
509 * all of the in6_multi records. 509 * all of the in6_multi records.
510 */ 510 */
511struct in6_multistep { 511struct in6_multistep {
512 struct in6_ifaddr *i_ia; 512 struct in6_ifaddr *i_ia;
513 struct in6_multi *i_in6m; 513 struct in6_multi *i_in6m;
514}; 514};
515 515
516/* 516/*
517 * Macros for looking up the in6_multi record for a given IP6 multicast 517 * Macros for looking up the in6_multi record for a given IP6 multicast
518 * address on a given interface. If no matching record is found, "in6m" 518 * address on a given interface. If no matching record is found, "in6m"
519 * returns NLL. 519 * returns NLL.
520 */ 520 */
521 521
522#define IN6_LOOKUP_MULTI(addr, ifp, in6m) \ 522#define IN6_LOOKUP_MULTI(addr, ifp, in6m) \
523/* struct in6_addr addr; */ \ 523/* struct in6_addr addr; */ \
524/* struct ifnet *ifp; */ \ 524/* struct ifnet *ifp; */ \
525/* struct in6_multi *in6m; */ \ 525/* struct in6_multi *in6m; */ \
526do { \ 526do { \
527 struct in6_ifaddr *ia; \ 527 struct in6_ifaddr *ia; \
528 \ 528 \
529 IFP_TO_IA6((ifp), ia); \ 529 IFP_TO_IA6((ifp), ia); \
530 if (ia == NULL) \ 530 if (ia == NULL) \
531 (in6m) = NULL; \ 531 (in6m) = NULL; \
532 else \ 532 else \
533 for ((in6m) = ia->ia6_multiaddrs.lh_first; \ 533 for ((in6m) = ia->ia6_multiaddrs.lh_first; \
534 (in6m) != NULL && \ 534 (in6m) != NULL && \
535 !IN6_ARE_ADDR_EQUAL(&(in6m)->in6m_addr, &(addr)); \ 535 !IN6_ARE_ADDR_EQUAL(&(in6m)->in6m_addr, &(addr)); \
536 (in6m) = (in6m)->in6m_entry.le_next) \ 536 (in6m) = (in6m)->in6m_entry.le_next) \
537 continue; \ 537 continue; \
538} while (/*CONSTCOND*/ 0) 538} while (/*CONSTCOND*/ 0)
539 539
540/* 540/*
541 * Macro to step through all of the in6_multi records, one at a time. 541 * Macro to step through all of the in6_multi records, one at a time.
542 * The current position is remembered in "step", which the caller must 542 * The current position is remembered in "step", which the caller must
543 * provide. IN6_FIRST_MULTI(), below, must be called to initialize "step" 543 * provide. IN6_FIRST_MULTI(), below, must be called to initialize "step"
544 * and get the first record. Both macros return a NULL "in6m" when there 544 * and get the first record. Both macros return a NULL "in6m" when there
545 * are no remaining records. 545 * are no remaining records.
546 */ 546 */
547#define IN6_NEXT_MULTI(step, in6m) \ 547#define IN6_NEXT_MULTI(step, in6m) \
548/* struct in6_multistep step; */ \ 548/* struct in6_multistep step; */ \
549/* struct in6_multi *in6m; */ \ 549/* struct in6_multi *in6m; */ \
550do { \ 550do { \
551 if (((in6m) = (step).i_in6m) != NULL) \ 551 if (((in6m) = (step).i_in6m) != NULL) \
552 (step).i_in6m = (in6m)->in6m_entry.le_next; \ 552 (step).i_in6m = (in6m)->in6m_entry.le_next; \
553 else \ 553 else \
554 while ((step).i_ia != NULL) { \ 554 while ((step).i_ia != NULL) { \
555 (in6m) = (step).i_ia->ia6_multiaddrs.lh_first; \ 555 (in6m) = (step).i_ia->ia6_multiaddrs.lh_first; \
556 (step).i_ia = (step).i_ia->ia_next; \ 556 (step).i_ia = (step).i_ia->ia_next; \
557 if ((in6m) != NULL) { \ 557 if ((in6m) != NULL) { \
558 (step).i_in6m = (in6m)->in6m_entry.le_next; \ 558 (step).i_in6m = (in6m)->in6m_entry.le_next; \
559 break; \ 559 break; \
560 } \ 560 } \
561 } \ 561 } \
562} while (/*CONSTCOND*/ 0) 562} while (/*CONSTCOND*/ 0)
563 563
564#define IN6_FIRST_MULTI(step, in6m) \ 564#define IN6_FIRST_MULTI(step, in6m) \
565/* struct in6_multistep step; */ \ 565/* struct in6_multistep step; */ \
566/* struct in6_multi *in6m */ \ 566/* struct in6_multi *in6m */ \
567do { \ 567do { \
568 (step).i_ia = in6_ifaddr; \ 568 (step).i_ia = in6_ifaddr; \
569 (step).i_in6m = NULL; \ 569 (step).i_in6m = NULL; \
570 IN6_NEXT_MULTI((step), (in6m)); \ 570 IN6_NEXT_MULTI((step), (in6m)); \
571} while (/*CONSTCOND*/ 0) 571} while (/*CONSTCOND*/ 0)
572 572
573struct in6_multi *in6_addmulti __P((struct in6_addr *, struct ifnet *, 573struct in6_multi *in6_addmulti __P((struct in6_addr *, struct ifnet *,
574 int *)); 574 int *));
575void in6_delmulti __P((struct in6_multi *)); 575void in6_delmulti __P((struct in6_multi *));
576struct in6_multi_mship *in6_joingroup __P((struct ifnet *, struct in6_addr *, 576struct in6_multi_mship *in6_joingroup __P((struct ifnet *, struct in6_addr *,
577 int *)); 577 int *));
578int in6_leavegroup __P((struct in6_multi_mship *)); 578int in6_leavegroup __P((struct in6_multi_mship *));
579int in6_mask2len __P((struct in6_addr *, u_char *)); 579int in6_mask2len __P((struct in6_addr *, u_char *));
580int in6_control __P((struct socket *, u_long, caddr_t, struct ifnet *, 580int in6_control __P((struct socket *, u_long, caddr_t, struct ifnet *,
581 struct proc *)); 581 struct proc *));
582int in6_update_ifa __P((struct ifnet *, struct in6_aliasreq *, 582int in6_update_ifa __P((struct ifnet *, struct in6_aliasreq *,
583 struct in6_ifaddr *)); 583 struct in6_ifaddr *));
584void in6_purgeaddr __P((struct ifaddr *)); 584void in6_purgeaddr __P((struct ifaddr *));
585int in6if_do_dad __P((struct ifnet *)); 585int in6if_do_dad __P((struct ifnet *));
586void in6_purgeif __P((struct ifnet *)); 586void in6_purgeif __P((struct ifnet *));
587void in6_savemkludge __P((struct in6_ifaddr *)); 587void in6_savemkludge __P((struct in6_ifaddr *));
588void in6_setmaxmtu __P((void)); 588void in6_setmaxmtu __P((void));
589void *in6_domifattach __P((struct ifnet *)); 589void *in6_domifattach __P((struct ifnet *));
590void in6_domifdetach __P((struct ifnet *, void *)); 590void in6_domifdetach __P((struct ifnet *, void *));
591void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *)); 591void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *));
592void in6_createmkludge __P((struct ifnet *)); 592void in6_createmkludge __P((struct ifnet *));
593void in6_purgemkludge __P((struct ifnet *)); 593void in6_purgemkludge __P((struct ifnet *));
594struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *, int)); 594struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *, int));
 595struct in6_ifaddr *in6ifa_ifplocaladdr __P((const struct ifnet *,
 596 const struct in6_addr *));
595struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *, struct in6_addr *)); 597struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *, struct in6_addr *));
596char *ip6_sprintf __P((const struct in6_addr *)); 598char *ip6_sprintf __P((const struct in6_addr *));
597int in6_addr2scopeid __P((struct ifnet *, struct in6_addr *)); 599int in6_addr2scopeid __P((struct ifnet *, struct in6_addr *));
598int in6_matchlen __P((struct in6_addr *, struct in6_addr *)); 600int in6_matchlen __P((struct in6_addr *, struct in6_addr *));
599int in6_are_prefix_equal __P((struct in6_addr *, struct in6_addr *, int)); 601int in6_are_prefix_equal __P((struct in6_addr *, struct in6_addr *, int));
600void in6_prefixlen2mask __P((struct in6_addr *, int)); 602void in6_prefixlen2mask __P((struct in6_addr *, int));
601void in6_purgeprefix __P((struct ifnet *)); 603void in6_purgeprefix __P((struct ifnet *));
602 604
603int in6_is_addr_deprecated __P((struct sockaddr_in6 *)); 605int in6_is_addr_deprecated __P((struct sockaddr_in6 *));
604struct in6pcb; 606struct in6pcb;
605int in6_embedscope __P((struct in6_addr *, const struct sockaddr_in6 *, 607int in6_embedscope __P((struct in6_addr *, const struct sockaddr_in6 *,
606 struct in6pcb *, struct ifnet **)); 608 struct in6pcb *, struct ifnet **));
607int in6_recoverscope __P((struct sockaddr_in6 *, const struct in6_addr *, 609int in6_recoverscope __P((struct sockaddr_in6 *, const struct in6_addr *,
608 struct ifnet *)); 610 struct ifnet *));
609void in6_clearscope __P((struct in6_addr *)); 611void in6_clearscope __P((struct in6_addr *));
610#endif /* _KERNEL */ 612#endif /* _KERNEL */
611 613
612#endif /* _NETINET6_IN6_VAR_H_ */ 614#endif /* _NETINET6_IN6_VAR_H_ */

cvs diff -r1.56 -r1.56.2.1 src/sys/netinet6/nd6_nbr.c (switch to unified diff)

--- src/sys/netinet6/nd6_nbr.c 2005/02/26 22:45:13 1.56
+++ src/sys/netinet6/nd6_nbr.c 2008/10/03 10:43:48 1.56.2.1
@@ -1,1394 +1,1410 @@ @@ -1,1394 +1,1410 @@
1/* $NetBSD: nd6_nbr.c,v 1.56 2005/02/26 22:45:13 perry Exp $ */ 1/* $NetBSD: nd6_nbr.c,v 1.56.2.1 2008/10/03 10:43:48 jdc Exp $ */
2/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ 2/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors 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 17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission. 18 * without specific prior written permission.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 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 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.56 2005/02/26 22:45:13 perry Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.56.2.1 2008/10/03 10:43:48 jdc Exp $");
35 35
36#include "opt_inet.h" 36#include "opt_inet.h"
37#include "opt_ipsec.h" 37#include "opt_ipsec.h"
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/malloc.h> 41#include <sys/malloc.h>
42#include <sys/mbuf.h> 42#include <sys/mbuf.h>
43#include <sys/socket.h> 43#include <sys/socket.h>
44#include <sys/sockio.h> 44#include <sys/sockio.h>
45#include <sys/time.h> 45#include <sys/time.h>
46#include <sys/kernel.h> 46#include <sys/kernel.h>
47#include <sys/errno.h> 47#include <sys/errno.h>
48#include <sys/ioctl.h> 48#include <sys/ioctl.h>
49#include <sys/syslog.h> 49#include <sys/syslog.h>
50#include <sys/queue.h> 50#include <sys/queue.h>
51#include <sys/callout.h> 51#include <sys/callout.h>
52 52
53#include <net/if.h> 53#include <net/if.h>
54#include <net/if_types.h> 54#include <net/if_types.h>
55#include <net/if_dl.h> 55#include <net/if_dl.h>
56#include <net/route.h> 56#include <net/route.h>
57 57
58#include <netinet/in.h> 58#include <netinet/in.h>
59#include <netinet/in_var.h> 59#include <netinet/in_var.h>
60#include <netinet6/in6_var.h> 60#include <netinet6/in6_var.h>
61#include <netinet/ip6.h> 61#include <netinet/ip6.h>
62#include <netinet6/ip6_var.h> 62#include <netinet6/ip6_var.h>
63#include <netinet6/nd6.h> 63#include <netinet6/nd6.h>
64#include <netinet/icmp6.h> 64#include <netinet/icmp6.h>
65 65
66#ifdef IPSEC 66#ifdef IPSEC
67#include <netinet6/ipsec.h> 67#include <netinet6/ipsec.h>
68#endif 68#endif
69 69
70#include <net/net_osdep.h> 70#include <net/net_osdep.h>
71 71
72#define SDL(s) ((struct sockaddr_dl *)s) 72#define SDL(s) ((struct sockaddr_dl *)s)
73 73
74struct dadq; 74struct dadq;
75static struct dadq *nd6_dad_find __P((struct ifaddr *)); 75static struct dadq *nd6_dad_find __P((struct ifaddr *));
76static void nd6_dad_starttimer __P((struct dadq *, int)); 76static void nd6_dad_starttimer __P((struct dadq *, int));
77static void nd6_dad_stoptimer __P((struct dadq *)); 77static void nd6_dad_stoptimer __P((struct dadq *));
78static void nd6_dad_timer __P((struct ifaddr *)); 78static void nd6_dad_timer __P((struct ifaddr *));
79static void nd6_dad_ns_output __P((struct dadq *, struct ifaddr *)); 79static void nd6_dad_ns_output __P((struct dadq *, struct ifaddr *));
80static void nd6_dad_ns_input __P((struct ifaddr *)); 80static void nd6_dad_ns_input __P((struct ifaddr *));
81static void nd6_dad_na_input __P((struct ifaddr *)); 81static void nd6_dad_na_input __P((struct ifaddr *));
82 82
83static int dad_ignore_ns = 0; /* ignore NS in DAD - specwise incorrect*/ 83static int dad_ignore_ns = 0; /* ignore NS in DAD - specwise incorrect*/
84static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */ 84static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */
85 85
86/* 86/*
87 * Input an Neighbor Solicitation Message. 87 * Input an Neighbor Solicitation Message.
88 * 88 *
89 * Based on RFC 2461 89 * Based on RFC 2461
90 * Based on RFC 2462 (duplicated address detection) 90 * Based on RFC 2462 (duplicated address detection)
91 */ 91 */
92void 92void
93nd6_ns_input(m, off, icmp6len) 93nd6_ns_input(m, off, icmp6len)
94 struct mbuf *m; 94 struct mbuf *m;
95 int off, icmp6len; 95 int off, icmp6len;
96{ 96{
97 struct ifnet *ifp = m->m_pkthdr.rcvif; 97 struct ifnet *ifp = m->m_pkthdr.rcvif;
98 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 98 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
99 struct nd_neighbor_solicit *nd_ns; 99 struct nd_neighbor_solicit *nd_ns;
100 struct in6_addr saddr6 = ip6->ip6_src; 100 struct in6_addr saddr6 = ip6->ip6_src;
101 struct in6_addr daddr6 = ip6->ip6_dst; 101 struct in6_addr daddr6 = ip6->ip6_dst;
102 struct in6_addr taddr6; 102 struct in6_addr taddr6;
103 struct in6_addr myaddr6; 103 struct in6_addr myaddr6;
104 char *lladdr = NULL; 104 char *lladdr = NULL;
105 struct ifaddr *ifa; 105 struct ifaddr *ifa;
106 int lladdrlen = 0; 106 int lladdrlen = 0;
107 int anycast = 0, proxy = 0, tentative = 0; 107 int anycast = 0, proxy = 0, tentative = 0;
108 int router = ip6_forwarding; 108 int router = ip6_forwarding;
109 int tlladdr; 109 int tlladdr;
110 union nd_opts ndopts; 110 union nd_opts ndopts;
111 struct sockaddr_dl *proxydl = NULL; 111 struct sockaddr_dl *proxydl = NULL;
112 112
113 IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len); 113 IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len);
114 if (nd_ns == NULL) { 114 if (nd_ns == NULL) {
115 icmp6stat.icp6s_tooshort++; 115 icmp6stat.icp6s_tooshort++;
116 return; 116 return;
117 } 117 }
118 ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */ 118 ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */
119 taddr6 = nd_ns->nd_ns_target; 119 taddr6 = nd_ns->nd_ns_target;
120 120
121 if (ip6->ip6_hlim != 255) { 121 if (ip6->ip6_hlim != 255) {
122 nd6log((LOG_ERR, 122 nd6log((LOG_ERR,
123 "nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n", 123 "nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n",
124 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 124 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
125 ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); 125 ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
126 goto bad; 126 goto bad;
127 } 127 }
128 128
129 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) { 129 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
130 /* dst has to be solicited node multicast address. */ 130 /* dst has to be solicited node multicast address. */
131 /* don't check ifindex portion */ 131 /* don't check ifindex portion */
132 if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL && 132 if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
133 daddr6.s6_addr32[1] == 0 && 133 daddr6.s6_addr32[1] == 0 &&
134 daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE && 134 daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE &&
135 daddr6.s6_addr8[12] == 0xff) { 135 daddr6.s6_addr8[12] == 0xff) {
136 ; /* good */ 136 ; /* good */
137 } else { 137 } else {
138 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet " 138 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
139 "(wrong ip6 dst)\n")); 139 "(wrong ip6 dst)\n"));
140 goto bad; 140 goto bad;
141 } 141 }
 142 } else {
 143 /*
 144 * Make sure the source address is from a neighbor's address.
 145 */
 146 if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) {
 147 nd6log((LOG_INFO, "nd6_ns_input: "
 148 "NS packet from non-neighbor\n"));
 149 goto bad;
 150 }
142 } 151 }
143 152
 153
144 if (IN6_IS_ADDR_MULTICAST(&taddr6)) { 154 if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
145 nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n")); 155 nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n"));
146 goto bad; 156 goto bad;
147 } 157 }
148 158
149 if (IN6_IS_SCOPE_LINKLOCAL(&taddr6)) 159 if (IN6_IS_SCOPE_LINKLOCAL(&taddr6))
150 taddr6.s6_addr16[1] = htons(ifp->if_index); 160 taddr6.s6_addr16[1] = htons(ifp->if_index);
151 161
152 icmp6len -= sizeof(*nd_ns); 162 icmp6len -= sizeof(*nd_ns);
153 nd6_option_init(nd_ns + 1, icmp6len, &ndopts); 163 nd6_option_init(nd_ns + 1, icmp6len, &ndopts);
154 if (nd6_options(&ndopts) < 0) { 164 if (nd6_options(&ndopts) < 0) {
155 nd6log((LOG_INFO, 165 nd6log((LOG_INFO,
156 "nd6_ns_input: invalid ND option, ignored\n")); 166 "nd6_ns_input: invalid ND option, ignored\n"));
157 /* nd6_options have incremented stats */ 167 /* nd6_options have incremented stats */
158 goto freeit; 168 goto freeit;
159 } 169 }
160 170
161 if (ndopts.nd_opts_src_lladdr) { 171 if (ndopts.nd_opts_src_lladdr) {
162 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 172 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
163 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 173 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
164 } 174 }
165 175
166 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && lladdr) { 176 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && lladdr) {
167 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet " 177 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
168 "(link-layer address option)\n")); 178 "(link-layer address option)\n"));
169 goto bad; 179 goto bad;
170 } 180 }
171 181
172 /* 182 /*
173 * Attaching target link-layer address to the NA? 183 * Attaching target link-layer address to the NA?
174 * (RFC 2461 7.2.4) 184 * (RFC 2461 7.2.4)
175 * 185 *
176 * NS IP dst is unicast/anycast MUST NOT add 186 * NS IP dst is unicast/anycast MUST NOT add
177 * NS IP dst is solicited-node multicast MUST add 187 * NS IP dst is solicited-node multicast MUST add
178 * 188 *
179 * In implementation, we add target link-layer address by default. 189 * In implementation, we add target link-layer address by default.
180 * We do not add one in MUST NOT cases. 190 * We do not add one in MUST NOT cases.
181 */ 191 */
182#if 0 /* too much! */ 192#if 0 /* too much! */
183 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &daddr6); 193 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &daddr6);
184 if (ifa && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)) 194 if (ifa && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST))
185 tlladdr = 0; 195 tlladdr = 0;
186 else 196 else
187#endif 197#endif
188 if (!IN6_IS_ADDR_MULTICAST(&daddr6)) 198 if (!IN6_IS_ADDR_MULTICAST(&daddr6))
189 tlladdr = 0; 199 tlladdr = 0;
190 else 200 else
191 tlladdr = 1; 201 tlladdr = 1;
192 202
193 /* 203 /*
194 * Target address (taddr6) must be either: 204 * Target address (taddr6) must be either:
195 * (1) Valid unicast/anycast address for my receiving interface, 205 * (1) Valid unicast/anycast address for my receiving interface,
196 * (2) Unicast address for which I'm offering proxy service, or 206 * (2) Unicast address for which I'm offering proxy service, or
197 * (3) "tentative" address on which DAD is being performed. 207 * (3) "tentative" address on which DAD is being performed.
198 */ 208 */
199 /* (1) and (3) check. */ 209 /* (1) and (3) check. */
200 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); 210 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
201 211
202 /* (2) check. */ 212 /* (2) check. */
203 if (!ifa) { 213 if (!ifa) {
204 struct rtentry *rt; 214 struct rtentry *rt;
205 struct sockaddr_in6 tsin6; 215 struct sockaddr_in6 tsin6;
206 216
207 bzero(&tsin6, sizeof tsin6); 217 bzero(&tsin6, sizeof tsin6);
208 tsin6.sin6_len = sizeof(struct sockaddr_in6); 218 tsin6.sin6_len = sizeof(struct sockaddr_in6);
209 tsin6.sin6_family = AF_INET6; 219 tsin6.sin6_family = AF_INET6;
210 tsin6.sin6_addr = taddr6; 220 tsin6.sin6_addr = taddr6;
211 221
212 rt = rtalloc1((struct sockaddr *)&tsin6, 0); 222 rt = rtalloc1((struct sockaddr *)&tsin6, 0);
213 if (rt && (rt->rt_flags & RTF_ANNOUNCE) != 0 && 223 if (rt && (rt->rt_flags & RTF_ANNOUNCE) != 0 &&
214 rt->rt_gateway->sa_family == AF_LINK) { 224 rt->rt_gateway->sa_family == AF_LINK) {
215 /* 225 /*
216 * proxy NDP for single entry 226 * proxy NDP for single entry
217 */ 227 */
218 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 228 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp,
219 IN6_IFF_NOTREADY|IN6_IFF_ANYCAST); 229 IN6_IFF_NOTREADY|IN6_IFF_ANYCAST);
220 if (ifa) { 230 if (ifa) {
221 proxy = 1; 231 proxy = 1;
222 proxydl = SDL(rt->rt_gateway); 232 proxydl = SDL(rt->rt_gateway);
223 router = 0; /* XXX */ 233 router = 0; /* XXX */
224 } 234 }
225 } 235 }
226 if (rt) 236 if (rt)
227 rtfree(rt); 237 rtfree(rt);
228 } 238 }
229 if (!ifa) { 239 if (!ifa) {
230 /* 240 /*
231 * We've got an NS packet, and we don't have that adddress 241 * We've got an NS packet, and we don't have that adddress
232 * assigned for us. We MUST silently ignore it. 242 * assigned for us. We MUST silently ignore it.
233 * See RFC2461 7.2.3. 243 * See RFC2461 7.2.3.
234 */ 244 */
235 goto freeit; 245 goto freeit;
236 } 246 }
237 myaddr6 = *IFA_IN6(ifa); 247 myaddr6 = *IFA_IN6(ifa);
238 anycast = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST; 248 anycast = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST;
239 tentative = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE; 249 tentative = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE;
240 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DUPLICATED) 250 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DUPLICATED)
241 goto freeit; 251 goto freeit;
242 252
243 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 253 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
244 nd6log((LOG_INFO, "nd6_ns_input: lladdrlen mismatch for %s " 254 nd6log((LOG_INFO, "nd6_ns_input: lladdrlen mismatch for %s "
245 "(if %d, NS packet %d)\n", 255 "(if %d, NS packet %d)\n",
246 ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2)); 256 ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2));
247 goto bad; 257 goto bad;
248 } 258 }
249 259
250 if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) { 260 if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) {
251 nd6log((LOG_INFO, "nd6_ns_input: duplicate IP6 address %s\n", 261 nd6log((LOG_INFO, "nd6_ns_input: duplicate IP6 address %s\n",
252 ip6_sprintf(&saddr6))); 262 ip6_sprintf(&saddr6)));
253 goto freeit; 263 goto freeit;
254 } 264 }
255 265
256 /* 266 /*
257 * We have neighbor solicitation packet, with target address equals to 267 * We have neighbor solicitation packet, with target address equals to
258 * one of my tentative address. 268 * one of my tentative address.
259 * 269 *
260 * src addr how to process? 270 * src addr how to process?
261 * --- --- 271 * --- ---
262 * multicast of course, invalid (rejected in ip6_input) 272 * multicast of course, invalid (rejected in ip6_input)
263 * unicast somebody is doing address resolution -> ignore 273 * unicast somebody is doing address resolution -> ignore
264 * unspec dup address detection 274 * unspec dup address detection
265 * 275 *
266 * The processing is defined in RFC 2462. 276 * The processing is defined in RFC 2462.
267 */ 277 */
268 if (tentative) { 278 if (tentative) {
269 /* 279 /*
270 * If source address is unspecified address, it is for 280 * If source address is unspecified address, it is for
271 * duplicated address detection. 281 * duplicated address detection.
272 * 282 *
273 * If not, the packet is for addess resolution; 283 * If not, the packet is for addess resolution;
274 * silently ignore it. 284 * silently ignore it.
275 */ 285 */
276 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) 286 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6))
277 nd6_dad_ns_input(ifa); 287 nd6_dad_ns_input(ifa);
278 288
279 goto freeit; 289 goto freeit;
280 } 290 }
281 291
282 /* 292 /*
283 * If the source address is unspecified address, entries must not 293 * If the source address is unspecified address, entries must not
284 * be created or updated. 294 * be created or updated.
285 * It looks that sender is performing DAD. Output NA toward 295 * It looks that sender is performing DAD. Output NA toward
286 * all-node multicast address, to tell the sender that I'm using 296 * all-node multicast address, to tell the sender that I'm using
287 * the address. 297 * the address.
288 * S bit ("solicited") must be zero. 298 * S bit ("solicited") must be zero.
289 */ 299 */
290 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) { 300 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
291 saddr6 = in6addr_linklocal_allnodes; 301 saddr6 = in6addr_linklocal_allnodes;
292 saddr6.s6_addr16[1] = htons(ifp->if_index); 302 saddr6.s6_addr16[1] = htons(ifp->if_index);
293 nd6_na_output(ifp, &saddr6, &taddr6, 303 nd6_na_output(ifp, &saddr6, &taddr6,
294 ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) | 304 ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
295 (router ? ND_NA_FLAG_ROUTER : 0), 305 (router ? ND_NA_FLAG_ROUTER : 0),
296 tlladdr, (struct sockaddr *)proxydl); 306 tlladdr, (struct sockaddr *)proxydl);
297 goto freeit; 307 goto freeit;
298 } 308 }
299 309
300 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_NEIGHBOR_SOLICIT, 0); 310 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_NEIGHBOR_SOLICIT, 0);
301 311
302 nd6_na_output(ifp, &saddr6, &taddr6, 312 nd6_na_output(ifp, &saddr6, &taddr6,
303 ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) | 313 ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
304 (router ? ND_NA_FLAG_ROUTER : 0) | ND_NA_FLAG_SOLICITED, 314 (router ? ND_NA_FLAG_ROUTER : 0) | ND_NA_FLAG_SOLICITED,
305 tlladdr, (struct sockaddr *)proxydl); 315 tlladdr, (struct sockaddr *)proxydl);
306 freeit: 316 freeit:
307 m_freem(m); 317 m_freem(m);
308 return; 318 return;
309 319
310 bad: 320 bad:
311 nd6log((LOG_ERR, "nd6_ns_input: src=%s\n", ip6_sprintf(&saddr6))); 321 nd6log((LOG_ERR, "nd6_ns_input: src=%s\n", ip6_sprintf(&saddr6)));
312 nd6log((LOG_ERR, "nd6_ns_input: dst=%s\n", ip6_sprintf(&daddr6))); 322 nd6log((LOG_ERR, "nd6_ns_input: dst=%s\n", ip6_sprintf(&daddr6)));
313 nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n", ip6_sprintf(&taddr6))); 323 nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n", ip6_sprintf(&taddr6)));
314 icmp6stat.icp6s_badns++; 324 icmp6stat.icp6s_badns++;
315 m_freem(m); 325 m_freem(m);
316} 326}
317 327
318/* 328/*
319 * Output an Neighbor Solicitation Message. Caller specifies: 329 * Output an Neighbor Solicitation Message. Caller specifies:
320 * - ICMP6 header source IP6 address 330 * - ICMP6 header source IP6 address
321 * - ND6 header target IP6 address 331 * - ND6 header target IP6 address
322 * - ND6 header source datalink address 332 * - ND6 header source datalink address
323 * 333 *
324 * Based on RFC 2461 334 * Based on RFC 2461
325 * Based on RFC 2462 (duplicated address detection) 335 * Based on RFC 2462 (duplicated address detection)
326 */ 336 */
327void 337void
328nd6_ns_output(ifp, daddr6, taddr6, ln, dad) 338nd6_ns_output(ifp, daddr6, taddr6, ln, dad)
329 struct ifnet *ifp; 339 struct ifnet *ifp;
330 const struct in6_addr *daddr6, *taddr6; 340 const struct in6_addr *daddr6, *taddr6;
331 struct llinfo_nd6 *ln; /* for source address determination */ 341 struct llinfo_nd6 *ln; /* for source address determination */
332 int dad; /* duplicated address detection */ 342 int dad; /* duplicated address detection */
333{ 343{
334 struct mbuf *m; 344 struct mbuf *m;
335 struct ip6_hdr *ip6; 345 struct ip6_hdr *ip6;
336 struct nd_neighbor_solicit *nd_ns; 346 struct nd_neighbor_solicit *nd_ns;
337 struct sockaddr_in6 src_sa, dst_sa; 347 struct sockaddr_in6 src_sa, dst_sa;
338 struct ip6_moptions im6o; 348 struct ip6_moptions im6o;
339 int icmp6len; 349 int icmp6len;
340 int maxlen; 350 int maxlen;
341 caddr_t mac; 351 caddr_t mac;
342 struct route_in6 ro; 352 struct route_in6 ro;
343 353
344 bzero(&ro, sizeof(ro)); 354 bzero(&ro, sizeof(ro));
345 355
346 if (IN6_IS_ADDR_MULTICAST(taddr6)) 356 if (IN6_IS_ADDR_MULTICAST(taddr6))
347 return; 357 return;
348 358
349 /* estimate the size of message */ 359 /* estimate the size of message */
350 maxlen = sizeof(*ip6) + sizeof(*nd_ns); 360 maxlen = sizeof(*ip6) + sizeof(*nd_ns);
351 maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7; 361 maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
352#ifdef DIAGNOSTIC 362#ifdef DIAGNOSTIC
353 if (max_linkhdr + maxlen >= MCLBYTES) { 363 if (max_linkhdr + maxlen >= MCLBYTES) {
354 printf("nd6_ns_output: max_linkhdr + maxlen >= MCLBYTES " 364 printf("nd6_ns_output: max_linkhdr + maxlen >= MCLBYTES "
355 "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES); 365 "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES);
356 panic("nd6_ns_output: insufficient MCLBYTES"); 366 panic("nd6_ns_output: insufficient MCLBYTES");
357 /* NOTREACHED */ 367 /* NOTREACHED */
358 } 368 }
359#endif 369#endif
360 370
361 MGETHDR(m, M_DONTWAIT, MT_DATA); 371 MGETHDR(m, M_DONTWAIT, MT_DATA);
362 if (m && max_linkhdr + maxlen >= MHLEN) { 372 if (m && max_linkhdr + maxlen >= MHLEN) {
363 MCLGET(m, M_DONTWAIT); 373 MCLGET(m, M_DONTWAIT);
364 if ((m->m_flags & M_EXT) == 0) { 374 if ((m->m_flags & M_EXT) == 0) {
365 m_free(m); 375 m_free(m);
366 m = NULL; 376 m = NULL;
367 } 377 }
368 } 378 }
369 if (m == NULL) 379 if (m == NULL)
370 return; 380 return;
371 m->m_pkthdr.rcvif = NULL; 381 m->m_pkthdr.rcvif = NULL;
372 382
373 if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) { 383 if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) {
374 m->m_flags |= M_MCAST; 384 m->m_flags |= M_MCAST;
375 im6o.im6o_multicast_ifp = ifp; 385 im6o.im6o_multicast_ifp = ifp;
376 im6o.im6o_multicast_hlim = 255; 386 im6o.im6o_multicast_hlim = 255;
377 im6o.im6o_multicast_loop = 0; 387 im6o.im6o_multicast_loop = 0;
378 } 388 }
379 389
380 icmp6len = sizeof(*nd_ns); 390 icmp6len = sizeof(*nd_ns);
381 m->m_pkthdr.len = m->m_len = sizeof(*ip6) + icmp6len; 391 m->m_pkthdr.len = m->m_len = sizeof(*ip6) + icmp6len;
382 m->m_data += max_linkhdr; /* or MH_ALIGN() equivalent? */ 392 m->m_data += max_linkhdr; /* or MH_ALIGN() equivalent? */
383 393
384 /* fill neighbor solicitation packet */ 394 /* fill neighbor solicitation packet */
385 ip6 = mtod(m, struct ip6_hdr *); 395 ip6 = mtod(m, struct ip6_hdr *);
386 ip6->ip6_flow = 0; 396 ip6->ip6_flow = 0;
387 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 397 ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
388 ip6->ip6_vfc |= IPV6_VERSION; 398 ip6->ip6_vfc |= IPV6_VERSION;
389 /* ip6->ip6_plen will be set later */ 399 /* ip6->ip6_plen will be set later */
390 ip6->ip6_nxt = IPPROTO_ICMPV6; 400 ip6->ip6_nxt = IPPROTO_ICMPV6;
391 ip6->ip6_hlim = 255; 401 ip6->ip6_hlim = 255;
392 /* determine the source and destination addresses */ 402 /* determine the source and destination addresses */
393 bzero(&src_sa, sizeof(src_sa)); 403 bzero(&src_sa, sizeof(src_sa));
394 bzero(&dst_sa, sizeof(dst_sa)); 404 bzero(&dst_sa, sizeof(dst_sa));
395 src_sa.sin6_family = dst_sa.sin6_family = AF_INET6; 405 src_sa.sin6_family = dst_sa.sin6_family = AF_INET6;
396 src_sa.sin6_len = dst_sa.sin6_len = sizeof(struct sockaddr_in6); 406 src_sa.sin6_len = dst_sa.sin6_len = sizeof(struct sockaddr_in6);
397 if (daddr6) 407 if (daddr6)
398 dst_sa.sin6_addr = *daddr6; 408 dst_sa.sin6_addr = *daddr6;
399 else { 409 else {
400 dst_sa.sin6_addr.s6_addr16[0] = IPV6_ADDR_INT16_MLL; 410 dst_sa.sin6_addr.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
401 dst_sa.sin6_addr.s6_addr16[1] = htons(ifp->if_index); 411 dst_sa.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
402 dst_sa.sin6_addr.s6_addr32[1] = 0; 412 dst_sa.sin6_addr.s6_addr32[1] = 0;
403 dst_sa.sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_ONE; 413 dst_sa.sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
404 dst_sa.sin6_addr.s6_addr32[3] = taddr6->s6_addr32[3]; 414 dst_sa.sin6_addr.s6_addr32[3] = taddr6->s6_addr32[3];
405 dst_sa.sin6_addr.s6_addr8[12] = 0xff; 415 dst_sa.sin6_addr.s6_addr8[12] = 0xff;
406 } 416 }
407 ip6->ip6_dst = dst_sa.sin6_addr; 417 ip6->ip6_dst = dst_sa.sin6_addr;
408 if (!dad) { 418 if (!dad) {
409 /* 419 /*
410 * RFC2461 7.2.2: 420 * RFC2461 7.2.2:
411 * "If the source address of the packet prompting the 421 * "If the source address of the packet prompting the
412 * solicitation is the same as one of the addresses assigned 422 * solicitation is the same as one of the addresses assigned
413 * to the outgoing interface, that address SHOULD be placed 423 * to the outgoing interface, that address SHOULD be placed
414 * in the IP Source Address of the outgoing solicitation. 424 * in the IP Source Address of the outgoing solicitation.
415 * Otherwise, any one of the addresses assigned to the 425 * Otherwise, any one of the addresses assigned to the
416 * interface should be used." 426 * interface should be used."
417 * 427 *
418 * We use the source address for the prompting packet 428 * We use the source address for the prompting packet
419 * (saddr6), if: 429 * (saddr6), if:
420 * - saddr6 is given from the caller (by giving "ln"), and 430 * - saddr6 is given from the caller (by giving "ln"), and
421 * - saddr6 belongs to the outgoing interface. 431 * - saddr6 belongs to the outgoing interface.
422 * Otherwise, we perform the source address selection as usual. 432 * Otherwise, we perform the source address selection as usual.
423 */ 433 */
424 struct ip6_hdr *hip6; /* hold ip6 */ 434 struct ip6_hdr *hip6; /* hold ip6 */
425 struct in6_addr *saddr6; 435 struct in6_addr *saddr6;
426 436
427 if (ln && ln->ln_hold) { 437 if (ln && ln->ln_hold) {
428 hip6 = mtod(ln->ln_hold, struct ip6_hdr *); 438 hip6 = mtod(ln->ln_hold, struct ip6_hdr *);
429 /* XXX pullup? */ 439 /* XXX pullup? */
430 if (sizeof(*hip6) < ln->ln_hold->m_len) 440 if (sizeof(*hip6) < ln->ln_hold->m_len)
431 saddr6 = &hip6->ip6_src; 441 saddr6 = &hip6->ip6_src;
432 else 442 else
433 saddr6 = NULL; 443 saddr6 = NULL;
434 } else 444 } else
435 saddr6 = NULL; 445 saddr6 = NULL;
436 if (saddr6 && in6ifa_ifpwithaddr(ifp, saddr6)) 446 if (saddr6 && in6ifa_ifpwithaddr(ifp, saddr6))
437 src_sa.sin6_addr = *saddr6; 447 src_sa.sin6_addr = *saddr6;
438 else { 448 else {
439 struct in6_addr *src0; 449 struct in6_addr *src0;
440 int error; 450 int error;
441 451
442 bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa)); 452 bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa));
443 src0 = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL, 453 src0 = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL,
444 &error); 454 &error);
445 if (src0 == NULL) { 455 if (src0 == NULL) {
446 nd6log((LOG_DEBUG, 456 nd6log((LOG_DEBUG,
447 "nd6_ns_output: source can't be " 457 "nd6_ns_output: source can't be "
448 "determined: dst=%s, error=%d\n", 458 "determined: dst=%s, error=%d\n",
449 ip6_sprintf(&dst_sa.sin6_addr), error)); 459 ip6_sprintf(&dst_sa.sin6_addr), error));
450 goto bad; 460 goto bad;
451 } 461 }
452 src_sa.sin6_addr = *src0; 462 src_sa.sin6_addr = *src0;
453 } 463 }
454 } else { 464 } else {
455 /* 465 /*
456 * Source address for DAD packet must always be IPv6 466 * Source address for DAD packet must always be IPv6
457 * unspecified address. (0::0) 467 * unspecified address. (0::0)
458 * We actually don't have to 0-clear the address (we did it 468 * We actually don't have to 0-clear the address (we did it
459 * above), but we do so here explicitly to make the intention 469 * above), but we do so here explicitly to make the intention
460 * clearer. 470 * clearer.
461 */ 471 */
462 bzero(&src_sa.sin6_addr, sizeof(src_sa.sin6_addr)); 472 bzero(&src_sa.sin6_addr, sizeof(src_sa.sin6_addr));
463 } 473 }
464 ip6->ip6_src = src_sa.sin6_addr; 474 ip6->ip6_src = src_sa.sin6_addr;
465 nd_ns = (struct nd_neighbor_solicit *)(ip6 + 1); 475 nd_ns = (struct nd_neighbor_solicit *)(ip6 + 1);
466 nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT; 476 nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT;
467 nd_ns->nd_ns_code = 0; 477 nd_ns->nd_ns_code = 0;
468 nd_ns->nd_ns_reserved = 0; 478 nd_ns->nd_ns_reserved = 0;
469 nd_ns->nd_ns_target = *taddr6; 479 nd_ns->nd_ns_target = *taddr6;
470 480
471 if (IN6_IS_SCOPE_LINKLOCAL(&nd_ns->nd_ns_target)) 481 if (IN6_IS_SCOPE_LINKLOCAL(&nd_ns->nd_ns_target))
472 nd_ns->nd_ns_target.s6_addr16[1] = 0; 482 nd_ns->nd_ns_target.s6_addr16[1] = 0;
473 483
474 /* 484 /*
475 * Add source link-layer address option. 485 * Add source link-layer address option.
476 * 486 *
477 * spec implementation 487 * spec implementation
478 * --- --- 488 * --- ---
479 * DAD packet MUST NOT do not add the option 489 * DAD packet MUST NOT do not add the option
480 * there's no link layer address: 490 * there's no link layer address:
481 * impossible do not add the option 491 * impossible do not add the option
482 * there's link layer address: 492 * there's link layer address:
483 * Multicast NS MUST add one add the option 493 * Multicast NS MUST add one add the option
484 * Unicast NS SHOULD add one add the option 494 * Unicast NS SHOULD add one add the option
485 */ 495 */
486 if (!dad && (mac = nd6_ifptomac(ifp))) { 496 if (!dad && (mac = nd6_ifptomac(ifp))) {
487 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen; 497 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
488 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1); 498 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
489 /* 8 byte alignments... */ 499 /* 8 byte alignments... */
490 optlen = (optlen + 7) & ~7; 500 optlen = (optlen + 7) & ~7;
491 501
492 m->m_pkthdr.len += optlen; 502 m->m_pkthdr.len += optlen;
493 m->m_len += optlen; 503 m->m_len += optlen;
494 icmp6len += optlen; 504 icmp6len += optlen;
495 bzero((caddr_t)nd_opt, optlen); 505 bzero((caddr_t)nd_opt, optlen);
496 nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; 506 nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
497 nd_opt->nd_opt_len = optlen >> 3; 507 nd_opt->nd_opt_len = optlen >> 3;
498 bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen); 508 bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen);
499 } 509 }
500 510
501 ip6->ip6_plen = htons((u_int16_t)icmp6len); 511 ip6->ip6_plen = htons((u_int16_t)icmp6len);
502 nd_ns->nd_ns_cksum = 0; 512 nd_ns->nd_ns_cksum = 0;
503 nd_ns->nd_ns_cksum = 513 nd_ns->nd_ns_cksum =
504 in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len); 514 in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
505 515
506 ip6_output(m, NULL, &ro, dad ? IPV6_UNSPECSRC : 0, 516 ip6_output(m, NULL, &ro, dad ? IPV6_UNSPECSRC : 0,
507 &im6o, (struct socket *)NULL, NULL); 517 &im6o, (struct socket *)NULL, NULL);
508 icmp6_ifstat_inc(ifp, ifs6_out_msg); 518 icmp6_ifstat_inc(ifp, ifs6_out_msg);
509 icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit); 519 icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit);
510 icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++; 520 icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++;
511 521
512 if (ro.ro_rt) { /* we don't cache this route. */ 522 if (ro.ro_rt) { /* we don't cache this route. */
513 RTFREE(ro.ro_rt); 523 RTFREE(ro.ro_rt);
514 } 524 }
515 return; 525 return;
516 526
517 bad: 527 bad:
518 if (ro.ro_rt) { 528 if (ro.ro_rt) {
519 RTFREE(ro.ro_rt); 529 RTFREE(ro.ro_rt);
520 } 530 }
521 m_freem(m); 531 m_freem(m);
522 return; 532 return;
523} 533}
524 534
525/* 535/*
526 * Neighbor advertisement input handling. 536 * Neighbor advertisement input handling.
527 * 537 *
528 * Based on RFC 2461 538 * Based on RFC 2461
529 * Based on RFC 2462 (duplicated address detection) 539 * Based on RFC 2462 (duplicated address detection)
530 * 540 *
531 * the following items are not implemented yet: 541 * the following items are not implemented yet:
532 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD) 542 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
533 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD) 543 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
534 */ 544 */
535void 545void
536nd6_na_input(m, off, icmp6len) 546nd6_na_input(m, off, icmp6len)
537 struct mbuf *m; 547 struct mbuf *m;
538 int off, icmp6len; 548 int off, icmp6len;
539{ 549{
540 struct ifnet *ifp = m->m_pkthdr.rcvif; 550 struct ifnet *ifp = m->m_pkthdr.rcvif;
541 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 551 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
542 struct nd_neighbor_advert *nd_na; 552 struct nd_neighbor_advert *nd_na;
543#if 0 
544 struct in6_addr saddr6 = ip6->ip6_src; 553 struct in6_addr saddr6 = ip6->ip6_src;
545#endif 
546 struct in6_addr daddr6 = ip6->ip6_dst; 554 struct in6_addr daddr6 = ip6->ip6_dst;
547 struct in6_addr taddr6; 555 struct in6_addr taddr6;
548 int flags; 556 int flags;
549 int is_router; 557 int is_router;
550 int is_solicited; 558 int is_solicited;
551 int is_override; 559 int is_override;
552 char *lladdr = NULL; 560 char *lladdr = NULL;
553 int lladdrlen = 0; 561 int lladdrlen = 0;
554 struct ifaddr *ifa; 562 struct ifaddr *ifa;
555 struct llinfo_nd6 *ln; 563 struct llinfo_nd6 *ln;
556 struct rtentry *rt; 564 struct rtentry *rt;
557 struct sockaddr_dl *sdl; 565 struct sockaddr_dl *sdl;
558 union nd_opts ndopts; 566 union nd_opts ndopts;
559 567
560 if (ip6->ip6_hlim != 255) { 568 if (ip6->ip6_hlim != 255) {
561 nd6log((LOG_ERR, 569 nd6log((LOG_ERR,
562 "nd6_na_input: invalid hlim (%d) from %s to %s on %s\n", 570 "nd6_na_input: invalid hlim (%d) from %s to %s on %s\n",
563 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 571 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
564 ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); 572 ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
565 goto bad; 573 goto bad;
566 } 574 }
567 575
568 IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len); 576 IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len);
569 if (nd_na == NULL) { 577 if (nd_na == NULL) {
570 icmp6stat.icp6s_tooshort++; 578 icmp6stat.icp6s_tooshort++;
571 return; 579 return;
572 } 580 }
573 taddr6 = nd_na->nd_na_target; 581 taddr6 = nd_na->nd_na_target;
574 flags = nd_na->nd_na_flags_reserved; 582 flags = nd_na->nd_na_flags_reserved;
575 is_router = ((flags & ND_NA_FLAG_ROUTER) != 0); 583 is_router = ((flags & ND_NA_FLAG_ROUTER) != 0);
576 is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0); 584 is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0);
577 is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0); 585 is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0);
578 586
579 if (IN6_IS_SCOPE_LINKLOCAL(&taddr6)) 587 if (IN6_IS_SCOPE_LINKLOCAL(&taddr6))
580 taddr6.s6_addr16[1] = htons(ifp->if_index); 588 taddr6.s6_addr16[1] = htons(ifp->if_index);
581 589
582 if (IN6_IS_ADDR_MULTICAST(&taddr6)) { 590 if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
583 nd6log((LOG_ERR, 591 nd6log((LOG_ERR,
584 "nd6_na_input: invalid target address %s\n", 592 "nd6_na_input: invalid target address %s\n",
585 ip6_sprintf(&taddr6))); 593 ip6_sprintf(&taddr6)));
586 goto bad; 594 goto bad;
587 } 595 }
588 if (is_solicited && IN6_IS_ADDR_MULTICAST(&daddr6)) { 596 if (is_solicited && IN6_IS_ADDR_MULTICAST(&daddr6)) {
589 nd6log((LOG_ERR, 597 nd6log((LOG_ERR,
590 "nd6_na_input: a solicited adv is multicasted\n")); 598 "nd6_na_input: a solicited adv is multicasted\n"));
591 goto bad; 599 goto bad;
592 } 600 }
593 601
594 icmp6len -= sizeof(*nd_na); 602 icmp6len -= sizeof(*nd_na);
595 nd6_option_init(nd_na + 1, icmp6len, &ndopts); 603 nd6_option_init(nd_na + 1, icmp6len, &ndopts);
596 if (nd6_options(&ndopts) < 0) { 604 if (nd6_options(&ndopts) < 0) {
597 nd6log((LOG_INFO, 605 nd6log((LOG_INFO,
598 "nd6_na_input: invalid ND option, ignored\n")); 606 "nd6_na_input: invalid ND option, ignored\n"));
599 /* nd6_options have incremented stats */ 607 /* nd6_options have incremented stats */
600 goto freeit; 608 goto freeit;
601 } 609 }
602 610
603 if (ndopts.nd_opts_tgt_lladdr) { 611 if (ndopts.nd_opts_tgt_lladdr) {
604 lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1); 612 lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
605 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; 613 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
606 } 614 }
607 615
608 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); 616 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
609 617
610 /* 618 /*
611 * Target address matches one of my interface address. 619 * Target address matches one of my interface address.
612 * 620 *
613 * If my address is tentative, this means that there's somebody 621 * If my address is tentative, this means that there's somebody
614 * already using the same address as mine. This indicates DAD failure. 622 * already using the same address as mine. This indicates DAD failure.
615 * This is defined in RFC 2462. 623 * This is defined in RFC 2462.
616 * 624 *
617 * Otherwise, process as defined in RFC 2461. 625 * Otherwise, process as defined in RFC 2461.
618 */ 626 */
619 if (ifa 627 if (ifa
620 && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) { 628 && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) {
621 nd6_dad_na_input(ifa); 629 nd6_dad_na_input(ifa);
622 goto freeit; 630 goto freeit;
623 } 631 }
624 632
625 /* Just for safety, maybe unnecessary. */ 633 /* Just for safety, maybe unnecessary. */
626 if (ifa) { 634 if (ifa) {
627 log(LOG_ERR, 635 log(LOG_ERR,
628 "nd6_na_input: duplicate IP6 address %s\n", 636 "nd6_na_input: duplicate IP6 address %s\n",
629 ip6_sprintf(&taddr6)); 637 ip6_sprintf(&taddr6));
630 goto freeit; 638 goto freeit;
631 } 639 }
 640 /*
 641 * Make sure the source address is from a neighbor's address.
 642 */
 643 if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) {
 644 nd6log((LOG_INFO, "nd6_ns_input: "
 645 "ND packet from non-neighbor\n"));
 646 goto bad;
 647 }
632 648
633 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 649 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
634 nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s " 650 nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s "
635 "(if %d, NA packet %d)\n", ip6_sprintf(&taddr6), 651 "(if %d, NA packet %d)\n", ip6_sprintf(&taddr6),
636 ifp->if_addrlen, lladdrlen - 2)); 652 ifp->if_addrlen, lladdrlen - 2));
637 goto bad; 653 goto bad;
638 } 654 }
639 655
640 /* 656 /*
641 * If no neighbor cache entry is found, NA SHOULD silently be 657 * If no neighbor cache entry is found, NA SHOULD silently be
642 * discarded. 658 * discarded.
643 */ 659 */
644 rt = nd6_lookup(&taddr6, 0, ifp); 660 rt = nd6_lookup(&taddr6, 0, ifp);
645 if ((rt == NULL) || 661 if ((rt == NULL) ||
646 ((ln = (struct llinfo_nd6 *)rt->rt_llinfo) == NULL) || 662 ((ln = (struct llinfo_nd6 *)rt->rt_llinfo) == NULL) ||
647 ((sdl = SDL(rt->rt_gateway)) == NULL)) 663 ((sdl = SDL(rt->rt_gateway)) == NULL))
648 goto freeit; 664 goto freeit;
649 665
650 if (ln->ln_state == ND6_LLINFO_INCOMPLETE) { 666 if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
651 /* 667 /*
652 * If the link-layer has address, and no lladdr option came, 668 * If the link-layer has address, and no lladdr option came,
653 * discard the packet. 669 * discard the packet.
654 */ 670 */
655 if (ifp->if_addrlen && !lladdr) 671 if (ifp->if_addrlen && !lladdr)
656 goto freeit; 672 goto freeit;
657 673
658 /* 674 /*
659 * Record link-layer address, and update the state. 675 * Record link-layer address, and update the state.
660 */ 676 */
661 sdl->sdl_alen = ifp->if_addrlen; 677 sdl->sdl_alen = ifp->if_addrlen;
662 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen); 678 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
663 if (is_solicited) { 679 if (is_solicited) {
664 ln->ln_state = ND6_LLINFO_REACHABLE; 680 ln->ln_state = ND6_LLINFO_REACHABLE;
665 ln->ln_byhint = 0; 681 ln->ln_byhint = 0;
666 if (!ND6_LLINFO_PERMANENT(ln)) { 682 if (!ND6_LLINFO_PERMANENT(ln)) {
667 nd6_llinfo_settimer(ln, 683 nd6_llinfo_settimer(ln,
668 (long)ND_IFINFO(rt->rt_ifp)->reachable * hz); 684 (long)ND_IFINFO(rt->rt_ifp)->reachable * hz);
669 } 685 }
670 } else { 686 } else {
671 ln->ln_state = ND6_LLINFO_STALE; 687 ln->ln_state = ND6_LLINFO_STALE;
672 nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz); 688 nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz);
673 } 689 }
674 if ((ln->ln_router = is_router) != 0) { 690 if ((ln->ln_router = is_router) != 0) {
675 /* 691 /*
676 * This means a router's state has changed from 692 * This means a router's state has changed from
677 * non-reachable to probably reachable, and might 693 * non-reachable to probably reachable, and might
678 * affect the status of associated prefixes.. 694 * affect the status of associated prefixes..
679 */ 695 */
680 pfxlist_onlink_check(); 696 pfxlist_onlink_check();
681 } 697 }
682 } else { 698 } else {
683 int llchange; 699 int llchange;
684 700
685 /* 701 /*
686 * Check if the link-layer address has changed or not. 702 * Check if the link-layer address has changed or not.
687 */ 703 */
688 if (!lladdr) 704 if (!lladdr)
689 llchange = 0; 705 llchange = 0;
690 else { 706 else {
691 if (sdl->sdl_alen) { 707 if (sdl->sdl_alen) {
692 if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen)) 708 if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen))
693 llchange = 1; 709 llchange = 1;
694 else 710 else
695 llchange = 0; 711 llchange = 0;
696 } else 712 } else
697 llchange = 1; 713 llchange = 1;
698 } 714 }
699 715
700 /* 716 /*
701 * This is VERY complex. Look at it with care. 717 * This is VERY complex. Look at it with care.
702 * 718 *
703 * override solicit lladdr llchange action 719 * override solicit lladdr llchange action
704 * (L: record lladdr) 720 * (L: record lladdr)
705 * 721 *
706 * 0 0 n -- (2c) 722 * 0 0 n -- (2c)
707 * 0 0 y n (2b) L 723 * 0 0 y n (2b) L
708 * 0 0 y y (1) REACHABLE->STALE 724 * 0 0 y y (1) REACHABLE->STALE
709 * 0 1 n -- (2c) *->REACHABLE 725 * 0 1 n -- (2c) *->REACHABLE
710 * 0 1 y n (2b) L *->REACHABLE 726 * 0 1 y n (2b) L *->REACHABLE
711 * 0 1 y y (1) REACHABLE->STALE 727 * 0 1 y y (1) REACHABLE->STALE
712 * 1 0 n -- (2a) 728 * 1 0 n -- (2a)
713 * 1 0 y n (2a) L 729 * 1 0 y n (2a) L
714 * 1 0 y y (2a) L *->STALE 730 * 1 0 y y (2a) L *->STALE
715 * 1 1 n -- (2a) *->REACHABLE 731 * 1 1 n -- (2a) *->REACHABLE
716 * 1 1 y n (2a) L *->REACHABLE 732 * 1 1 y n (2a) L *->REACHABLE
717 * 1 1 y y (2a) L *->REACHABLE 733 * 1 1 y y (2a) L *->REACHABLE
718 */ 734 */
719 if (!is_override && (lladdr && llchange)) { /* (1) */ 735 if (!is_override && (lladdr && llchange)) { /* (1) */
720 /* 736 /*
721 * If state is REACHABLE, make it STALE. 737 * If state is REACHABLE, make it STALE.
722 * no other updates should be done. 738 * no other updates should be done.
723 */ 739 */
724 if (ln->ln_state == ND6_LLINFO_REACHABLE) { 740 if (ln->ln_state == ND6_LLINFO_REACHABLE) {
725 ln->ln_state = ND6_LLINFO_STALE; 741 ln->ln_state = ND6_LLINFO_STALE;
726 nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz); 742 nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz);
727 } 743 }
728 goto freeit; 744 goto freeit;
729 } else if (is_override /* (2a) */ 745 } else if (is_override /* (2a) */
730 || (!is_override && (lladdr && !llchange)) /* (2b) */ 746 || (!is_override && (lladdr && !llchange)) /* (2b) */
731 || !lladdr) { /* (2c) */ 747 || !lladdr) { /* (2c) */
732 /* 748 /*
733 * Update link-local address, if any. 749 * Update link-local address, if any.
734 */ 750 */
735 if (lladdr) { 751 if (lladdr) {
736 sdl->sdl_alen = ifp->if_addrlen; 752 sdl->sdl_alen = ifp->if_addrlen;
737 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen); 753 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
738 } 754 }
739 755
740 /* 756 /*
741 * If solicited, make the state REACHABLE. 757 * If solicited, make the state REACHABLE.
742 * If not solicited and the link-layer address was 758 * If not solicited and the link-layer address was
743 * changed, make it STALE. 759 * changed, make it STALE.
744 */ 760 */
745 if (is_solicited) { 761 if (is_solicited) {
746 ln->ln_state = ND6_LLINFO_REACHABLE; 762 ln->ln_state = ND6_LLINFO_REACHABLE;
747 ln->ln_byhint = 0; 763 ln->ln_byhint = 0;
748 if (!ND6_LLINFO_PERMANENT(ln)) { 764 if (!ND6_LLINFO_PERMANENT(ln)) {
749 nd6_llinfo_settimer(ln, 765 nd6_llinfo_settimer(ln,
750 (long)ND_IFINFO(ifp)->reachable * hz); 766 (long)ND_IFINFO(ifp)->reachable * hz);
751 } 767 }
752 } else { 768 } else {
753 if (lladdr && llchange) { 769 if (lladdr && llchange) {
754 ln->ln_state = ND6_LLINFO_STALE; 770 ln->ln_state = ND6_LLINFO_STALE;
755 nd6_llinfo_settimer(ln, 771 nd6_llinfo_settimer(ln,
756 (long)nd6_gctimer * hz); 772 (long)nd6_gctimer * hz);
757 } 773 }
758 } 774 }
759 } 775 }
760 776
761 if (ln->ln_router && !is_router) { 777 if (ln->ln_router && !is_router) {
762 /* 778 /*
763 * The peer dropped the router flag. 779 * The peer dropped the router flag.
764 * Remove the sender from the Default Router List and 780 * Remove the sender from the Default Router List and
765 * update the Destination Cache entries. 781 * update the Destination Cache entries.
766 */ 782 */
767 struct nd_defrouter *dr; 783 struct nd_defrouter *dr;
768 struct in6_addr *in6; 784 struct in6_addr *in6;
769 int s; 785 int s;
770 786
771 in6 = &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr; 787 in6 = &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr;
772 788
773 /* 789 /*
774 * Lock to protect the default router list. 790 * Lock to protect the default router list.
775 * XXX: this might be unnecessary, since this function 791 * XXX: this might be unnecessary, since this function
776 * is only called under the network software interrupt 792 * is only called under the network software interrupt
777 * context. However, we keep it just for safety. 793 * context. However, we keep it just for safety.
778 */ 794 */
779 s = splsoftnet(); 795 s = splsoftnet();
780 dr = defrouter_lookup(in6, rt->rt_ifp); 796 dr = defrouter_lookup(in6, rt->rt_ifp);
781 if (dr) 797 if (dr)
782 defrtrlist_del(dr); 798 defrtrlist_del(dr);
783 else if (!ip6_forwarding) { 799 else if (!ip6_forwarding) {
784 /* 800 /*
785 * Even if the neighbor is not in the default 801 * Even if the neighbor is not in the default
786 * router list, the neighbor may be used 802 * router list, the neighbor may be used
787 * as a next hop for some destinations 803 * as a next hop for some destinations
788 * (e.g. redirect case). So we must 804 * (e.g. redirect case). So we must
789 * call rt6_flush explicitly. 805 * call rt6_flush explicitly.
790 */ 806 */
791 rt6_flush(&ip6->ip6_src, rt->rt_ifp); 807 rt6_flush(&ip6->ip6_src, rt->rt_ifp);
792 } 808 }
793 splx(s); 809 splx(s);
794 } 810 }
795 ln->ln_router = is_router; 811 ln->ln_router = is_router;
796 } 812 }
797 rt->rt_flags &= ~RTF_REJECT; 813 rt->rt_flags &= ~RTF_REJECT;
798 ln->ln_asked = 0; 814 ln->ln_asked = 0;
799 if (ln->ln_hold) { 815 if (ln->ln_hold) {
800 /* 816 /*
801 * we assume ifp is not a loopback here, so just set the 2nd 817 * we assume ifp is not a loopback here, so just set the 2nd
802 * argument as the 1st one. 818 * argument as the 1st one.
803 */ 819 */
804 nd6_output(ifp, ifp, ln->ln_hold, 820 nd6_output(ifp, ifp, ln->ln_hold,
805 (struct sockaddr_in6 *)rt_key(rt), rt); 821 (struct sockaddr_in6 *)rt_key(rt), rt);
806 ln->ln_hold = NULL; 822 ln->ln_hold = NULL;
807 } 823 }
808 824
809 freeit: 825 freeit:
810 m_freem(m); 826 m_freem(m);
811 return; 827 return;
812 828
813 bad: 829 bad:
814 icmp6stat.icp6s_badna++; 830 icmp6stat.icp6s_badna++;
815 m_freem(m); 831 m_freem(m);
816} 832}
817 833
818/* 834/*
819 * Neighbor advertisement output handling. 835 * Neighbor advertisement output handling.
820 * 836 *
821 * Based on RFC 2461 837 * Based on RFC 2461
822 * 838 *
823 * the following items are not implemented yet: 839 * the following items are not implemented yet:
824 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD) 840 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
825 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD) 841 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
826 */ 842 */
827void 843void
828nd6_na_output(ifp, daddr6, taddr6, flags, tlladdr, sdl0) 844nd6_na_output(ifp, daddr6, taddr6, flags, tlladdr, sdl0)
829 struct ifnet *ifp; 845 struct ifnet *ifp;
830 const struct in6_addr *daddr6, *taddr6; 846 const struct in6_addr *daddr6, *taddr6;
831 u_long flags; 847 u_long flags;
832 int tlladdr; /* 1 if include target link-layer address */ 848 int tlladdr; /* 1 if include target link-layer address */
833 struct sockaddr *sdl0; /* sockaddr_dl (= proxy NA) or NULL */ 849 struct sockaddr *sdl0; /* sockaddr_dl (= proxy NA) or NULL */
834{ 850{
835 struct mbuf *m; 851 struct mbuf *m;
836 struct ip6_hdr *ip6; 852 struct ip6_hdr *ip6;
837 struct nd_neighbor_advert *nd_na; 853 struct nd_neighbor_advert *nd_na;
838 struct ip6_moptions im6o; 854 struct ip6_moptions im6o;
839 struct sockaddr_in6 dst_sa; 855 struct sockaddr_in6 dst_sa;
840 struct in6_addr *src0; 856 struct in6_addr *src0;
841 int icmp6len, maxlen, error; 857 int icmp6len, maxlen, error;
842 caddr_t mac; 858 caddr_t mac;
843 struct route_in6 ro; 859 struct route_in6 ro;
844 860
845 mac = NULL; 861 mac = NULL;
846 bzero(&ro, sizeof(ro)); 862 bzero(&ro, sizeof(ro));
847 863
848 /* estimate the size of message */ 864 /* estimate the size of message */
849 maxlen = sizeof(*ip6) + sizeof(*nd_na); 865 maxlen = sizeof(*ip6) + sizeof(*nd_na);
850 maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7; 866 maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
851#ifdef DIAGNOSTIC 867#ifdef DIAGNOSTIC
852 if (max_linkhdr + maxlen >= MCLBYTES) { 868 if (max_linkhdr + maxlen >= MCLBYTES) {
853 printf("nd6_na_output: max_linkhdr + maxlen >= MCLBYTES " 869 printf("nd6_na_output: max_linkhdr + maxlen >= MCLBYTES "
854 "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES); 870 "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES);
855 panic("nd6_na_output: insufficient MCLBYTES"); 871 panic("nd6_na_output: insufficient MCLBYTES");
856 /* NOTREACHED */ 872 /* NOTREACHED */
857 } 873 }
858#endif 874#endif
859 875
860 MGETHDR(m, M_DONTWAIT, MT_DATA); 876 MGETHDR(m, M_DONTWAIT, MT_DATA);
861 if (m && max_linkhdr + maxlen >= MHLEN) { 877 if (m && max_linkhdr + maxlen >= MHLEN) {
862 MCLGET(m, M_DONTWAIT); 878 MCLGET(m, M_DONTWAIT);
863 if ((m->m_flags & M_EXT) == 0) { 879 if ((m->m_flags & M_EXT) == 0) {
864 m_free(m); 880 m_free(m);
865 m = NULL; 881 m = NULL;
866 } 882 }
867 } 883 }
868 if (m == NULL) 884 if (m == NULL)
869 return; 885 return;
870 m->m_pkthdr.rcvif = NULL; 886 m->m_pkthdr.rcvif = NULL;
871 887
872 if (IN6_IS_ADDR_MULTICAST(daddr6)) { 888 if (IN6_IS_ADDR_MULTICAST(daddr6)) {
873 m->m_flags |= M_MCAST; 889 m->m_flags |= M_MCAST;
874 im6o.im6o_multicast_ifp = ifp; 890 im6o.im6o_multicast_ifp = ifp;
875 im6o.im6o_multicast_hlim = 255; 891 im6o.im6o_multicast_hlim = 255;
876 im6o.im6o_multicast_loop = 0; 892 im6o.im6o_multicast_loop = 0;
877 } 893 }
878 894
879 icmp6len = sizeof(*nd_na); 895 icmp6len = sizeof(*nd_na);
880 m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + icmp6len; 896 m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + icmp6len;
881 m->m_data += max_linkhdr; /* or MH_ALIGN() equivalent? */ 897 m->m_data += max_linkhdr; /* or MH_ALIGN() equivalent? */
882 898
883 /* fill neighbor advertisement packet */ 899 /* fill neighbor advertisement packet */
884 ip6 = mtod(m, struct ip6_hdr *); 900 ip6 = mtod(m, struct ip6_hdr *);
885 ip6->ip6_flow = 0; 901 ip6->ip6_flow = 0;
886 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 902 ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
887 ip6->ip6_vfc |= IPV6_VERSION; 903 ip6->ip6_vfc |= IPV6_VERSION;
888 ip6->ip6_nxt = IPPROTO_ICMPV6; 904 ip6->ip6_nxt = IPPROTO_ICMPV6;
889 ip6->ip6_hlim = 255; 905 ip6->ip6_hlim = 255;
890 bzero(&dst_sa, sizeof(dst_sa)); 906 bzero(&dst_sa, sizeof(dst_sa));
891 dst_sa.sin6_len = sizeof(struct sockaddr_in6); 907 dst_sa.sin6_len = sizeof(struct sockaddr_in6);
892 dst_sa.sin6_family = AF_INET6; 908 dst_sa.sin6_family = AF_INET6;
893 dst_sa.sin6_addr = *daddr6; 909 dst_sa.sin6_addr = *daddr6;
894 if (IN6_IS_ADDR_UNSPECIFIED(daddr6)) { 910 if (IN6_IS_ADDR_UNSPECIFIED(daddr6)) {
895 /* reply to DAD */ 911 /* reply to DAD */
896 dst_sa.sin6_addr.s6_addr16[0] = IPV6_ADDR_INT16_MLL; 912 dst_sa.sin6_addr.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
897 dst_sa.sin6_addr.s6_addr16[1] = htons(ifp->if_index); 913 dst_sa.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
898 dst_sa.sin6_addr.s6_addr32[1] = 0; 914 dst_sa.sin6_addr.s6_addr32[1] = 0;
899 dst_sa.sin6_addr.s6_addr32[2] = 0; 915 dst_sa.sin6_addr.s6_addr32[2] = 0;
900 dst_sa.sin6_addr.s6_addr32[3] = IPV6_ADDR_INT32_ONE; 916 dst_sa.sin6_addr.s6_addr32[3] = IPV6_ADDR_INT32_ONE;
901 917
902 flags &= ~ND_NA_FLAG_SOLICITED; 918 flags &= ~ND_NA_FLAG_SOLICITED;
903 } 919 }
904 ip6->ip6_dst = dst_sa.sin6_addr; 920 ip6->ip6_dst = dst_sa.sin6_addr;
905 921
906 /* 922 /*
907 * Select a source whose scope is the same as that of the dest. 923 * Select a source whose scope is the same as that of the dest.
908 */ 924 */
909 bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa)); 925 bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa));
910 src0 = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL, &error); 926 src0 = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL, &error);
911 if (src0 == NULL) { 927 if (src0 == NULL) {
912 nd6log((LOG_DEBUG, "nd6_na_output: source can't be " 928 nd6log((LOG_DEBUG, "nd6_na_output: source can't be "
913 "determined: dst=%s, error=%d\n", 929 "determined: dst=%s, error=%d\n",
914 ip6_sprintf(&dst_sa.sin6_addr), error)); 930 ip6_sprintf(&dst_sa.sin6_addr), error));
915 goto bad; 931 goto bad;
916 } 932 }
917 ip6->ip6_src = *src0; 933 ip6->ip6_src = *src0;
918 nd_na = (struct nd_neighbor_advert *)(ip6 + 1); 934 nd_na = (struct nd_neighbor_advert *)(ip6 + 1);
919 nd_na->nd_na_type = ND_NEIGHBOR_ADVERT; 935 nd_na->nd_na_type = ND_NEIGHBOR_ADVERT;
920 nd_na->nd_na_code = 0; 936 nd_na->nd_na_code = 0;
921 nd_na->nd_na_target = *taddr6; 937 nd_na->nd_na_target = *taddr6;
922 if (IN6_IS_SCOPE_LINKLOCAL(&nd_na->nd_na_target)) 938 if (IN6_IS_SCOPE_LINKLOCAL(&nd_na->nd_na_target))
923 nd_na->nd_na_target.s6_addr16[1] = 0; 939 nd_na->nd_na_target.s6_addr16[1] = 0;
924 940
925 /* 941 /*
926 * "tlladdr" indicates NS's condition for adding tlladdr or not. 942 * "tlladdr" indicates NS's condition for adding tlladdr or not.
927 * see nd6_ns_input() for details. 943 * see nd6_ns_input() for details.
928 * Basically, if NS packet is sent to unicast/anycast addr, 944 * Basically, if NS packet is sent to unicast/anycast addr,
929 * target lladdr option SHOULD NOT be included. 945 * target lladdr option SHOULD NOT be included.
930 */ 946 */
931 if (tlladdr) { 947 if (tlladdr) {
932 /* 948 /*
933 * sdl0 != NULL indicates proxy NA. If we do proxy, use 949 * sdl0 != NULL indicates proxy NA. If we do proxy, use
934 * lladdr in sdl0. If we are not proxying (sending NA for 950 * lladdr in sdl0. If we are not proxying (sending NA for
935 * my address) use lladdr configured for the interface. 951 * my address) use lladdr configured for the interface.
936 */ 952 */
937 if (sdl0 == NULL) 953 if (sdl0 == NULL)
938 mac = nd6_ifptomac(ifp); 954 mac = nd6_ifptomac(ifp);
939 else if (sdl0->sa_family == AF_LINK) { 955 else if (sdl0->sa_family == AF_LINK) {
940 struct sockaddr_dl *sdl; 956 struct sockaddr_dl *sdl;
941 sdl = (struct sockaddr_dl *)sdl0; 957 sdl = (struct sockaddr_dl *)sdl0;
942 if (sdl->sdl_alen == ifp->if_addrlen) 958 if (sdl->sdl_alen == ifp->if_addrlen)
943 mac = LLADDR(sdl); 959 mac = LLADDR(sdl);
944 } 960 }
945 } 961 }
946 if (tlladdr && mac) { 962 if (tlladdr && mac) {
947 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen; 963 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
948 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_na + 1); 964 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_na + 1);
949 965
950 /* roundup to 8 bytes alignment! */ 966 /* roundup to 8 bytes alignment! */
951 optlen = (optlen + 7) & ~7; 967 optlen = (optlen + 7) & ~7;
952 968
953 m->m_pkthdr.len += optlen; 969 m->m_pkthdr.len += optlen;
954 m->m_len += optlen; 970 m->m_len += optlen;
955 icmp6len += optlen; 971 icmp6len += optlen;
956 bzero((caddr_t)nd_opt, optlen); 972 bzero((caddr_t)nd_opt, optlen);
957 nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR; 973 nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
958 nd_opt->nd_opt_len = optlen >> 3; 974 nd_opt->nd_opt_len = optlen >> 3;
959 bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen); 975 bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen);
960 } else 976 } else
961 flags &= ~ND_NA_FLAG_OVERRIDE; 977 flags &= ~ND_NA_FLAG_OVERRIDE;
962 978
963 ip6->ip6_plen = htons((u_int16_t)icmp6len); 979 ip6->ip6_plen = htons((u_int16_t)icmp6len);
964 nd_na->nd_na_flags_reserved = flags; 980 nd_na->nd_na_flags_reserved = flags;
965 nd_na->nd_na_cksum = 0; 981 nd_na->nd_na_cksum = 0;
966 nd_na->nd_na_cksum = 982 nd_na->nd_na_cksum =
967 in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len); 983 in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len);
968 984
969 ip6_output(m, NULL, NULL, 0, &im6o, (struct socket *)NULL, NULL); 985 ip6_output(m, NULL, NULL, 0, &im6o, (struct socket *)NULL, NULL);
970 986
971 icmp6_ifstat_inc(ifp, ifs6_out_msg); 987 icmp6_ifstat_inc(ifp, ifs6_out_msg);
972 icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert); 988 icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert);
973 icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]++; 989 icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]++;
974 990
975 if (ro.ro_rt) { /* we don't cache this route. */ 991 if (ro.ro_rt) { /* we don't cache this route. */
976 RTFREE(ro.ro_rt); 992 RTFREE(ro.ro_rt);
977 } 993 }
978 return; 994 return;
979 995
980 bad: 996 bad:
981 if (ro.ro_rt) { 997 if (ro.ro_rt) {
982 RTFREE(ro.ro_rt); 998 RTFREE(ro.ro_rt);
983 } 999 }
984 m_freem(m); 1000 m_freem(m);
985 return; 1001 return;
986} 1002}
987 1003
988caddr_t 1004caddr_t
989nd6_ifptomac(ifp) 1005nd6_ifptomac(ifp)
990 struct ifnet *ifp; 1006 struct ifnet *ifp;
991{ 1007{
992 switch (ifp->if_type) { 1008 switch (ifp->if_type) {
993 case IFT_ARCNET: 1009 case IFT_ARCNET:
994 case IFT_ETHER: 1010 case IFT_ETHER:
995 case IFT_FDDI: 1011 case IFT_FDDI:
996 case IFT_IEEE1394: 1012 case IFT_IEEE1394:
997 case IFT_PROPVIRTUAL: 1013 case IFT_PROPVIRTUAL:
998 case IFT_L2VLAN: 1014 case IFT_L2VLAN:
999 case IFT_IEEE80211: 1015 case IFT_IEEE80211:
1000 return LLADDR(ifp->if_sadl); 1016 return LLADDR(ifp->if_sadl);
1001 default: 1017 default:
1002 return NULL; 1018 return NULL;
1003 } 1019 }
1004} 1020}
1005 1021
1006TAILQ_HEAD(dadq_head, dadq); 1022TAILQ_HEAD(dadq_head, dadq);
1007struct dadq { 1023struct dadq {
1008 TAILQ_ENTRY(dadq) dad_list; 1024 TAILQ_ENTRY(dadq) dad_list;
1009 struct ifaddr *dad_ifa; 1025 struct ifaddr *dad_ifa;
1010 int dad_count; /* max NS to send */ 1026 int dad_count; /* max NS to send */
1011 int dad_ns_tcount; /* # of trials to send NS */ 1027 int dad_ns_tcount; /* # of trials to send NS */
1012 int dad_ns_ocount; /* NS sent so far */ 1028 int dad_ns_ocount; /* NS sent so far */
1013 int dad_ns_icount; 1029 int dad_ns_icount;
1014 int dad_na_icount; 1030 int dad_na_icount;
1015 struct callout dad_timer_ch; 1031 struct callout dad_timer_ch;
1016}; 1032};
1017 1033
1018static struct dadq_head dadq; 1034static struct dadq_head dadq;
1019static int dad_init = 0; 1035static int dad_init = 0;
1020 1036
1021static struct dadq * 1037static struct dadq *
1022nd6_dad_find(ifa) 1038nd6_dad_find(ifa)
1023 struct ifaddr *ifa; 1039 struct ifaddr *ifa;
1024{ 1040{
1025 struct dadq *dp; 1041 struct dadq *dp;
1026 1042
1027 for (dp = dadq.tqh_first; dp; dp = dp->dad_list.tqe_next) { 1043 for (dp = dadq.tqh_first; dp; dp = dp->dad_list.tqe_next) {
1028 if (dp->dad_ifa == ifa) 1044 if (dp->dad_ifa == ifa)
1029 return dp; 1045 return dp;
1030 } 1046 }
1031 return NULL; 1047 return NULL;
1032} 1048}
1033 1049
1034static void 1050static void
1035nd6_dad_starttimer(dp, ticks) 1051nd6_dad_starttimer(dp, ticks)
1036 struct dadq *dp; 1052 struct dadq *dp;
1037 int ticks; 1053 int ticks;
1038{ 1054{
1039 1055
1040 callout_reset(&dp->dad_timer_ch, ticks, 1056 callout_reset(&dp->dad_timer_ch, ticks,
1041 (void (*) __P((void *)))nd6_dad_timer, (void *)dp->dad_ifa); 1057 (void (*) __P((void *)))nd6_dad_timer, (void *)dp->dad_ifa);
1042} 1058}
1043 1059
1044static void 1060static void
1045nd6_dad_stoptimer(dp) 1061nd6_dad_stoptimer(dp)
1046 struct dadq *dp; 1062 struct dadq *dp;
1047{ 1063{
1048 1064
1049 callout_stop(&dp->dad_timer_ch); 1065 callout_stop(&dp->dad_timer_ch);
1050} 1066}
1051 1067
1052/* 1068/*
1053 * Start Duplicated Address Detection (DAD) for specified interface address. 1069 * Start Duplicated Address Detection (DAD) for specified interface address.
1054 */ 1070 */
1055void 1071void
1056nd6_dad_start(ifa, tick) 1072nd6_dad_start(ifa, tick)
1057 struct ifaddr *ifa; 1073 struct ifaddr *ifa;
1058 int *tick; /* minimum delay ticks for IFF_UP event */ 1074 int *tick; /* minimum delay ticks for IFF_UP event */
1059{ 1075{
1060 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1076 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1061 struct dadq *dp; 1077 struct dadq *dp;
1062 1078
1063 if (!dad_init) { 1079 if (!dad_init) {
1064 TAILQ_INIT(&dadq); 1080 TAILQ_INIT(&dadq);
1065 dad_init++; 1081 dad_init++;
1066 } 1082 }
1067 1083
1068 /* 1084 /*
1069 * If we don't need DAD, don't do it. 1085 * If we don't need DAD, don't do it.
1070 * There are several cases: 1086 * There are several cases:
1071 * - DAD is disabled (ip6_dad_count == 0) 1087 * - DAD is disabled (ip6_dad_count == 0)
1072 * - the interface address is anycast 1088 * - the interface address is anycast
1073 */ 1089 */
1074 if (!(ia->ia6_flags & IN6_IFF_TENTATIVE)) { 1090 if (!(ia->ia6_flags & IN6_IFF_TENTATIVE)) {
1075 log(LOG_DEBUG, 1091 log(LOG_DEBUG,
1076 "nd6_dad_start: called with non-tentative address " 1092 "nd6_dad_start: called with non-tentative address "
1077 "%s(%s)\n", 1093 "%s(%s)\n",
1078 ip6_sprintf(&ia->ia_addr.sin6_addr), 1094 ip6_sprintf(&ia->ia_addr.sin6_addr),
1079 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1095 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1080 return; 1096 return;
1081 } 1097 }
1082 if (ia->ia6_flags & IN6_IFF_ANYCAST) { 1098 if (ia->ia6_flags & IN6_IFF_ANYCAST) {
1083 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 1099 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1084 return; 1100 return;
1085 } 1101 }
1086 if (!ip6_dad_count) { 1102 if (!ip6_dad_count) {
1087 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 1103 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1088 return; 1104 return;
1089 } 1105 }
1090 if (!ifa->ifa_ifp) 1106 if (!ifa->ifa_ifp)
1091 panic("nd6_dad_start: ifa->ifa_ifp == NULL"); 1107 panic("nd6_dad_start: ifa->ifa_ifp == NULL");
1092 if (!(ifa->ifa_ifp->if_flags & IFF_UP)) 1108 if (!(ifa->ifa_ifp->if_flags & IFF_UP))
1093 return; 1109 return;
1094 if (nd6_dad_find(ifa) != NULL) { 1110 if (nd6_dad_find(ifa) != NULL) {
1095 /* DAD already in progress */ 1111 /* DAD already in progress */
1096 return; 1112 return;
1097 } 1113 }
1098 1114
1099 dp = malloc(sizeof(*dp), M_IP6NDP, M_NOWAIT); 1115 dp = malloc(sizeof(*dp), M_IP6NDP, M_NOWAIT);
1100 if (dp == NULL) { 1116 if (dp == NULL) {
1101 log(LOG_ERR, "nd6_dad_start: memory allocation failed for " 1117 log(LOG_ERR, "nd6_dad_start: memory allocation failed for "
1102 "%s(%s)\n", 1118 "%s(%s)\n",
1103 ip6_sprintf(&ia->ia_addr.sin6_addr), 1119 ip6_sprintf(&ia->ia_addr.sin6_addr),
1104 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1120 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1105 return; 1121 return;
1106 } 1122 }
1107 bzero(dp, sizeof(*dp)); 1123 bzero(dp, sizeof(*dp));
1108 callout_init(&dp->dad_timer_ch); 1124 callout_init(&dp->dad_timer_ch);
1109 TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list); 1125 TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list);
1110 1126
1111 nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), 1127 nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
1112 ip6_sprintf(&ia->ia_addr.sin6_addr))); 1128 ip6_sprintf(&ia->ia_addr.sin6_addr)));
1113 1129
1114 /* 1130 /*
1115 * Send NS packet for DAD, ip6_dad_count times. 1131 * Send NS packet for DAD, ip6_dad_count times.
1116 * Note that we must delay the first transmission, if this is the 1132 * Note that we must delay the first transmission, if this is the
1117 * first packet to be sent from the interface after interface 1133 * first packet to be sent from the interface after interface
1118 * (re)initialization. 1134 * (re)initialization.
1119 */ 1135 */
1120 dp->dad_ifa = ifa; 1136 dp->dad_ifa = ifa;
1121 IFAREF(ifa); /* just for safety */ 1137 IFAREF(ifa); /* just for safety */
1122 dp->dad_count = ip6_dad_count; 1138 dp->dad_count = ip6_dad_count;
1123 dp->dad_ns_icount = dp->dad_na_icount = 0; 1139 dp->dad_ns_icount = dp->dad_na_icount = 0;
1124 dp->dad_ns_ocount = dp->dad_ns_tcount = 0; 1140 dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
1125 if (tick == NULL) { 1141 if (tick == NULL) {
1126 nd6_dad_ns_output(dp, ifa); 1142 nd6_dad_ns_output(dp, ifa);
1127 nd6_dad_starttimer(dp, 1143 nd6_dad_starttimer(dp,
1128 (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); 1144 (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
1129 } else { 1145 } else {
1130 int ntick; 1146 int ntick;
1131 1147
1132 if (*tick == 0) 1148 if (*tick == 0)
1133 ntick = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz); 1149 ntick = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz);
1134 else 1150 else
1135 ntick = *tick + arc4random() % (hz / 2); 1151 ntick = *tick + arc4random() % (hz / 2);
1136 *tick = ntick; 1152 *tick = ntick;
1137 nd6_dad_starttimer(dp, ntick); 1153 nd6_dad_starttimer(dp, ntick);
1138 } 1154 }
1139} 1155}
1140 1156
1141/* 1157/*
1142 * terminate DAD unconditionally. used for address removals. 1158 * terminate DAD unconditionally. used for address removals.
1143 */ 1159 */
1144void 1160void
1145nd6_dad_stop(ifa) 1161nd6_dad_stop(ifa)
1146 struct ifaddr *ifa; 1162 struct ifaddr *ifa;
1147{ 1163{
1148 struct dadq *dp; 1164 struct dadq *dp;
1149 1165
1150 if (!dad_init) 1166 if (!dad_init)
1151 return; 1167 return;
1152 dp = nd6_dad_find(ifa); 1168 dp = nd6_dad_find(ifa);
1153 if (!dp) { 1169 if (!dp) {
1154 /* DAD wasn't started yet */ 1170 /* DAD wasn't started yet */
1155 return; 1171 return;
1156 } 1172 }
1157 1173
1158 nd6_dad_stoptimer(dp); 1174 nd6_dad_stoptimer(dp);
1159 1175
1160 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list); 1176 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
1161 free(dp, M_IP6NDP); 1177 free(dp, M_IP6NDP);
1162 dp = NULL; 1178 dp = NULL;
1163 IFAFREE(ifa); 1179 IFAFREE(ifa);
1164} 1180}
1165 1181
1166static void 1182static void
1167nd6_dad_timer(ifa) 1183nd6_dad_timer(ifa)
1168 struct ifaddr *ifa; 1184 struct ifaddr *ifa;
1169{ 1185{
1170 int s; 1186 int s;
1171 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1187 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1172 struct dadq *dp; 1188 struct dadq *dp;
1173 1189
1174 s = splsoftnet(); /* XXX */ 1190 s = splsoftnet(); /* XXX */
1175 1191
1176 /* Sanity check */ 1192 /* Sanity check */
1177 if (ia == NULL) { 1193 if (ia == NULL) {
1178 log(LOG_ERR, "nd6_dad_timer: called with null parameter\n"); 1194 log(LOG_ERR, "nd6_dad_timer: called with null parameter\n");
1179 goto done; 1195 goto done;
1180 } 1196 }
1181 dp = nd6_dad_find(ifa); 1197 dp = nd6_dad_find(ifa);
1182 if (dp == NULL) { 1198 if (dp == NULL) {
1183 log(LOG_ERR, "nd6_dad_timer: DAD structure not found\n"); 1199 log(LOG_ERR, "nd6_dad_timer: DAD structure not found\n");
1184 goto done; 1200 goto done;
1185 } 1201 }
1186 if (ia->ia6_flags & IN6_IFF_DUPLICATED) { 1202 if (ia->ia6_flags & IN6_IFF_DUPLICATED) {
1187 log(LOG_ERR, "nd6_dad_timer: called with duplicated address " 1203 log(LOG_ERR, "nd6_dad_timer: called with duplicated address "
1188 "%s(%s)\n", 1204 "%s(%s)\n",
1189 ip6_sprintf(&ia->ia_addr.sin6_addr), 1205 ip6_sprintf(&ia->ia_addr.sin6_addr),
1190 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1206 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1191 goto done; 1207 goto done;
1192 } 1208 }
1193 if ((ia->ia6_flags & IN6_IFF_TENTATIVE) == 0) { 1209 if ((ia->ia6_flags & IN6_IFF_TENTATIVE) == 0) {
1194 log(LOG_ERR, "nd6_dad_timer: called with non-tentative address " 1210 log(LOG_ERR, "nd6_dad_timer: called with non-tentative address "
1195 "%s(%s)\n", 1211 "%s(%s)\n",
1196 ip6_sprintf(&ia->ia_addr.sin6_addr), 1212 ip6_sprintf(&ia->ia_addr.sin6_addr),
1197 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1213 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1198 goto done; 1214 goto done;
1199 } 1215 }
1200 1216
1201 /* timeouted with IFF_{RUNNING,UP} check */ 1217 /* timeouted with IFF_{RUNNING,UP} check */
1202 if (dp->dad_ns_tcount > dad_maxtry) { 1218 if (dp->dad_ns_tcount > dad_maxtry) {
1203 nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n", 1219 nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n",
1204 if_name(ifa->ifa_ifp))); 1220 if_name(ifa->ifa_ifp)));
1205 1221
1206 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list); 1222 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
1207 free(dp, M_IP6NDP); 1223 free(dp, M_IP6NDP);
1208 dp = NULL; 1224 dp = NULL;
1209 IFAFREE(ifa); 1225 IFAFREE(ifa);
1210 goto done; 1226 goto done;
1211 } 1227 }
1212 1228
1213 /* Need more checks? */ 1229 /* Need more checks? */
1214 if (dp->dad_ns_ocount < dp->dad_count) { 1230 if (dp->dad_ns_ocount < dp->dad_count) {
1215 /* 1231 /*
1216 * We have more NS to go. Send NS packet for DAD. 1232 * We have more NS to go. Send NS packet for DAD.
1217 */ 1233 */
1218 nd6_dad_ns_output(dp, ifa); 1234 nd6_dad_ns_output(dp, ifa);
1219 nd6_dad_starttimer(dp, 1235 nd6_dad_starttimer(dp,
1220 (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); 1236 (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
1221 } else { 1237 } else {
1222 /* 1238 /*
1223 * We have transmitted sufficient number of DAD packets. 1239 * We have transmitted sufficient number of DAD packets.
1224 * See what we've got. 1240 * See what we've got.
1225 */ 1241 */
1226 int duplicate; 1242 int duplicate;
1227 1243
1228 duplicate = 0; 1244 duplicate = 0;
1229 1245
1230 if (dp->dad_na_icount) { 1246 if (dp->dad_na_icount) {
1231 /* 1247 /*
1232 * the check is in nd6_dad_na_input(), 1248 * the check is in nd6_dad_na_input(),
1233 * but just in case 1249 * but just in case
1234 */ 1250 */
1235 duplicate++; 1251 duplicate++;
1236 } 1252 }
1237 1253
1238 if (dp->dad_ns_icount) { 1254 if (dp->dad_ns_icount) {
1239 /* We've seen NS, means DAD has failed. */ 1255 /* We've seen NS, means DAD has failed. */
1240 duplicate++; 1256 duplicate++;
1241 } 1257 }
1242 1258
1243 if (duplicate) { 1259 if (duplicate) {
1244 /* (*dp) will be freed in nd6_dad_duplicated() */ 1260 /* (*dp) will be freed in nd6_dad_duplicated() */
1245 dp = NULL; 1261 dp = NULL;
1246 nd6_dad_duplicated(ifa); 1262 nd6_dad_duplicated(ifa);
1247 } else { 1263 } else {
1248 /* 1264 /*
1249 * We are done with DAD. No NA came, no NS came. 1265 * We are done with DAD. No NA came, no NS came.
1250 * duplicated address found. 1266 * duplicated address found.
1251 */ 1267 */
1252 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 1268 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1253 1269
1254 nd6log((LOG_DEBUG, 1270 nd6log((LOG_DEBUG,
1255 "%s: DAD complete for %s - no duplicates found\n", 1271 "%s: DAD complete for %s - no duplicates found\n",
1256 if_name(ifa->ifa_ifp), 1272 if_name(ifa->ifa_ifp),
1257 ip6_sprintf(&ia->ia_addr.sin6_addr))); 1273 ip6_sprintf(&ia->ia_addr.sin6_addr)));
1258 1274
1259 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list); 1275 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
1260 free(dp, M_IP6NDP); 1276 free(dp, M_IP6NDP);
1261 dp = NULL; 1277 dp = NULL;
1262 IFAFREE(ifa); 1278 IFAFREE(ifa);
1263 } 1279 }
1264 } 1280 }
1265 1281
1266done: 1282done:
1267 splx(s); 1283 splx(s);
1268} 1284}
1269 1285
1270void 1286void
1271nd6_dad_duplicated(ifa) 1287nd6_dad_duplicated(ifa)
1272 struct ifaddr *ifa; 1288 struct ifaddr *ifa;
1273{ 1289{
1274 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1290 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1275 struct dadq *dp; 1291 struct dadq *dp;
1276 1292
1277 dp = nd6_dad_find(ifa); 1293 dp = nd6_dad_find(ifa);
1278 if (dp == NULL) { 1294 if (dp == NULL) {
1279 log(LOG_ERR, "nd6_dad_duplicated: DAD structure not found\n"); 1295 log(LOG_ERR, "nd6_dad_duplicated: DAD structure not found\n");
1280 return; 1296 return;
1281 } 1297 }
1282 1298
1283 log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: " 1299 log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: "
1284 "NS in/out=%d/%d, NA in=%d\n", 1300 "NS in/out=%d/%d, NA in=%d\n",
1285 if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr), 1301 if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr),
1286 dp->dad_ns_icount, dp->dad_ns_ocount, dp->dad_na_icount); 1302 dp->dad_ns_icount, dp->dad_ns_ocount, dp->dad_na_icount);
1287 1303
1288 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 1304 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1289 ia->ia6_flags |= IN6_IFF_DUPLICATED; 1305 ia->ia6_flags |= IN6_IFF_DUPLICATED;
1290 1306
1291 /* We are done with DAD, with duplicated address found. (failure) */ 1307 /* We are done with DAD, with duplicated address found. (failure) */
1292 nd6_dad_stoptimer(dp); 1308 nd6_dad_stoptimer(dp);
1293 1309
1294 log(LOG_ERR, "%s: DAD complete for %s - duplicate found\n", 1310 log(LOG_ERR, "%s: DAD complete for %s - duplicate found\n",
1295 if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr)); 1311 if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr));
1296 log(LOG_ERR, "%s: manual intervention required\n", 1312 log(LOG_ERR, "%s: manual intervention required\n",
1297 if_name(ifa->ifa_ifp)); 1313 if_name(ifa->ifa_ifp));
1298 1314
1299 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list); 1315 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
1300 free(dp, M_IP6NDP); 1316 free(dp, M_IP6NDP);
1301 dp = NULL; 1317 dp = NULL;
1302 IFAFREE(ifa); 1318 IFAFREE(ifa);
1303} 1319}
1304 1320
1305static void 1321static void
1306nd6_dad_ns_output(dp, ifa) 1322nd6_dad_ns_output(dp, ifa)
1307 struct dadq *dp; 1323 struct dadq *dp;
1308 struct ifaddr *ifa; 1324 struct ifaddr *ifa;
1309{ 1325{
1310 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1326 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1311 struct ifnet *ifp = ifa->ifa_ifp; 1327 struct ifnet *ifp = ifa->ifa_ifp;
1312 1328
1313 dp->dad_ns_tcount++; 1329 dp->dad_ns_tcount++;
1314 if ((ifp->if_flags & IFF_UP) == 0) { 1330 if ((ifp->if_flags & IFF_UP) == 0) {
1315#if 0 1331#if 0
1316 printf("%s: interface down?\n", if_name(ifp)); 1332 printf("%s: interface down?\n", if_name(ifp));
1317#endif 1333#endif
1318 return; 1334 return;
1319 } 1335 }
1320 if ((ifp->if_flags & IFF_RUNNING) == 0) { 1336 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1321#if 0 1337#if 0
1322 printf("%s: interface not running?\n", if_name(ifp)); 1338 printf("%s: interface not running?\n", if_name(ifp));
1323#endif 1339#endif
1324 return; 1340 return;
1325 } 1341 }
1326 1342
1327 dp->dad_ns_ocount++; 1343 dp->dad_ns_ocount++;
1328 nd6_ns_output(ifp, NULL, &ia->ia_addr.sin6_addr, NULL, 1); 1344 nd6_ns_output(ifp, NULL, &ia->ia_addr.sin6_addr, NULL, 1);
1329} 1345}
1330 1346
1331static void 1347static void
1332nd6_dad_ns_input(ifa) 1348nd6_dad_ns_input(ifa)
1333 struct ifaddr *ifa; 1349 struct ifaddr *ifa;
1334{ 1350{
1335 struct in6_ifaddr *ia; 1351 struct in6_ifaddr *ia;
1336 const struct in6_addr *taddr6; 1352 const struct in6_addr *taddr6;
1337 struct dadq *dp; 1353 struct dadq *dp;
1338 int duplicate; 1354 int duplicate;
1339 1355
1340 if (!ifa) 1356 if (!ifa)
1341 panic("ifa == NULL in nd6_dad_ns_input"); 1357 panic("ifa == NULL in nd6_dad_ns_input");
1342 1358
1343 ia = (struct in6_ifaddr *)ifa; 1359 ia = (struct in6_ifaddr *)ifa;
1344 taddr6 = &ia->ia_addr.sin6_addr; 1360 taddr6 = &ia->ia_addr.sin6_addr;
1345 duplicate = 0; 1361 duplicate = 0;
1346 dp = nd6_dad_find(ifa); 1362 dp = nd6_dad_find(ifa);
1347 1363
1348 /* Quickhack - completely ignore DAD NS packets */ 1364 /* Quickhack - completely ignore DAD NS packets */
1349 if (dad_ignore_ns) { 1365 if (dad_ignore_ns) {
1350 nd6log((LOG_INFO, 1366 nd6log((LOG_INFO,
1351 "nd6_dad_ns_input: ignoring DAD NS packet for " 1367 "nd6_dad_ns_input: ignoring DAD NS packet for "
1352 "address %s(%s)\n", ip6_sprintf(taddr6), 1368 "address %s(%s)\n", ip6_sprintf(taddr6),
1353 if_name(ifa->ifa_ifp))); 1369 if_name(ifa->ifa_ifp)));
1354 return; 1370 return;
1355 } 1371 }
1356 1372
1357 /* 1373 /*
1358 * if I'm yet to start DAD, someone else started using this address 1374 * if I'm yet to start DAD, someone else started using this address
1359 * first. I have a duplicate and you win. 1375 * first. I have a duplicate and you win.
1360 */ 1376 */
1361 if (!dp || dp->dad_ns_ocount == 0) 1377 if (!dp || dp->dad_ns_ocount == 0)
1362 duplicate++; 1378 duplicate++;
1363 1379
1364 /* XXX more checks for loopback situation - see nd6_dad_timer too */ 1380 /* XXX more checks for loopback situation - see nd6_dad_timer too */
1365 1381
1366 if (duplicate) { 1382 if (duplicate) {
1367 dp = NULL; /* will be freed in nd6_dad_duplicated() */ 1383 dp = NULL; /* will be freed in nd6_dad_duplicated() */
1368 nd6_dad_duplicated(ifa); 1384 nd6_dad_duplicated(ifa);
1369 } else { 1385 } else {
1370 /* 1386 /*
1371 * not sure if I got a duplicate. 1387 * not sure if I got a duplicate.
1372 * increment ns count and see what happens. 1388 * increment ns count and see what happens.
1373 */ 1389 */
1374 if (dp) 1390 if (dp)
1375 dp->dad_ns_icount++; 1391 dp->dad_ns_icount++;
1376 } 1392 }
1377} 1393}
1378 1394
1379static void 1395static void
1380nd6_dad_na_input(ifa) 1396nd6_dad_na_input(ifa)
1381 struct ifaddr *ifa; 1397 struct ifaddr *ifa;
1382{ 1398{
1383 struct dadq *dp; 1399 struct dadq *dp;
1384 1400
1385 if (!ifa) 1401 if (!ifa)
1386 panic("ifa == NULL in nd6_dad_na_input"); 1402 panic("ifa == NULL in nd6_dad_na_input");
1387 1403
1388 dp = nd6_dad_find(ifa); 1404 dp = nd6_dad_find(ifa);
1389 if (dp) 1405 if (dp)
1390 dp->dad_na_icount++; 1406 dp->dad_na_icount++;
1391 1407
1392 /* remove the address. */ 1408 /* remove the address. */
1393 nd6_dad_duplicated(ifa); 1409 nd6_dad_duplicated(ifa);
1394} 1410}