Fri Apr 1 05:11:38 2016 UTC ()
Tidy up nd6_timer initialization


(ozaki-r)
diff -r1.155 -r1.156 src/sys/netinet6/ip6_input.c
diff -r1.185 -r1.186 src/sys/netinet6/nd6.c
diff -r1.69 -r1.70 src/sys/netinet6/nd6.h

cvs diff -r1.155 -r1.156 src/sys/netinet6/ip6_input.c (switch to unified diff)

--- src/sys/netinet6/ip6_input.c 2016/02/04 02:48:37 1.155
+++ src/sys/netinet6/ip6_input.c 2016/04/01 05:11:38 1.156
@@ -1,1204 +1,1200 @@ @@ -1,1204 +1,1200 @@
1/* $NetBSD: ip6_input.c,v 1.155 2016/02/04 02:48:37 riastradh Exp $ */ 1/* $NetBSD: ip6_input.c,v 1.156 2016/04/01 05:11:38 ozaki-r Exp $ */
2/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ 2/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 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, 1988, 1993 34 * Copyright (c) 1982, 1986, 1988, 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 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 61 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
62 */ 62 */
63 63
64#include <sys/cdefs.h> 64#include <sys/cdefs.h>
65__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.155 2016/02/04 02:48:37 riastradh Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.156 2016/04/01 05:11:38 ozaki-r Exp $");
66 66
67#ifdef _KERNEL_OPT 67#ifdef _KERNEL_OPT
68#include "opt_gateway.h" 68#include "opt_gateway.h"
69#include "opt_inet.h" 69#include "opt_inet.h"
70#include "opt_inet6.h" 70#include "opt_inet6.h"
71#include "opt_ipsec.h" 71#include "opt_ipsec.h"
72#include "opt_compat_netbsd.h" 72#include "opt_compat_netbsd.h"
73#endif 73#endif
74 74
75#include <sys/param.h> 75#include <sys/param.h>
76#include <sys/systm.h> 76#include <sys/systm.h>
77#include <sys/malloc.h> 77#include <sys/malloc.h>
78#include <sys/mbuf.h> 78#include <sys/mbuf.h>
79#include <sys/domain.h> 79#include <sys/domain.h>
80#include <sys/protosw.h> 80#include <sys/protosw.h>
81#include <sys/socket.h> 81#include <sys/socket.h>
82#include <sys/socketvar.h> 82#include <sys/socketvar.h>
83#include <sys/errno.h> 83#include <sys/errno.h>
84#include <sys/time.h> 84#include <sys/time.h>
85#include <sys/kernel.h> 85#include <sys/kernel.h>
86#include <sys/syslog.h> 86#include <sys/syslog.h>
87#include <sys/proc.h> 87#include <sys/proc.h>
88#include <sys/sysctl.h> 88#include <sys/sysctl.h>
89#include <sys/cprng.h> 89#include <sys/cprng.h>
90 90
91#include <net/if.h> 91#include <net/if.h>
92#include <net/if_types.h> 92#include <net/if_types.h>
93#include <net/if_dl.h> 93#include <net/if_dl.h>
94#include <net/route.h> 94#include <net/route.h>
95#include <net/pktqueue.h> 95#include <net/pktqueue.h>
96#include <net/pfil.h> 96#include <net/pfil.h>
97 97
98#include <netinet/in.h> 98#include <netinet/in.h>
99#include <netinet/in_systm.h> 99#include <netinet/in_systm.h>
100#ifdef INET 100#ifdef INET
101#include <netinet/ip.h> 101#include <netinet/ip.h>
102#include <netinet/ip_var.h> 102#include <netinet/ip_var.h>
103#include <netinet/ip_icmp.h> 103#include <netinet/ip_icmp.h>
104#endif /* INET */ 104#endif /* INET */
105#include <netinet/ip6.h> 105#include <netinet/ip6.h>
106#include <netinet/portalgo.h> 106#include <netinet/portalgo.h>
107#include <netinet6/in6_var.h> 107#include <netinet6/in6_var.h>
108#include <netinet6/ip6_var.h> 108#include <netinet6/ip6_var.h>
109#include <netinet6/ip6_private.h> 109#include <netinet6/ip6_private.h>
110#include <netinet6/in6_pcb.h> 110#include <netinet6/in6_pcb.h>
111#include <netinet/icmp6.h> 111#include <netinet/icmp6.h>
112#include <netinet6/scope6_var.h> 112#include <netinet6/scope6_var.h>
113#include <netinet6/in6_ifattach.h> 113#include <netinet6/in6_ifattach.h>
114#include <netinet6/nd6.h> 114#include <netinet6/nd6.h>
115 115
116#ifdef IPSEC 116#ifdef IPSEC
117#include <netipsec/ipsec.h> 117#include <netipsec/ipsec.h>
118#include <netipsec/ipsec6.h> 118#include <netipsec/ipsec6.h>
119#include <netipsec/key.h> 119#include <netipsec/key.h>
120#endif /* IPSEC */ 120#endif /* IPSEC */
121 121
122#ifdef COMPAT_50 122#ifdef COMPAT_50
123#include <compat/sys/time.h> 123#include <compat/sys/time.h>
124#include <compat/sys/socket.h> 124#include <compat/sys/socket.h>
125#endif 125#endif
126 126
127#include <netinet6/ip6protosw.h> 127#include <netinet6/ip6protosw.h>
128 128
129#include "faith.h" 129#include "faith.h"
130 130
131#include <net/net_osdep.h> 131#include <net/net_osdep.h>
132 132
133extern struct domain inet6domain; 133extern struct domain inet6domain;
134 134
135u_char ip6_protox[IPPROTO_MAX]; 135u_char ip6_protox[IPPROTO_MAX];
136struct in6_ifaddr *in6_ifaddr; 136struct in6_ifaddr *in6_ifaddr;
137pktqueue_t *ip6_pktq __read_mostly; 137pktqueue_t *ip6_pktq __read_mostly;
138 138
139int ip6_forward_srcrt; /* XXX */ 139int ip6_forward_srcrt; /* XXX */
140int ip6_sourcecheck; /* XXX */ 140int ip6_sourcecheck; /* XXX */
141int ip6_sourcecheck_interval; /* XXX */ 141int ip6_sourcecheck_interval; /* XXX */
142 142
143pfil_head_t *inet6_pfil_hook; 143pfil_head_t *inet6_pfil_hook;
144 144
145percpu_t *ip6stat_percpu; 145percpu_t *ip6stat_percpu;
146 146
147static void ip6_init2(void *); 147static void ip6_init2(void);
148static void ip6intr(void *); 148static void ip6intr(void *);
149static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *); 149static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *);
150 150
151static int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *, 151static int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *,
152 u_int32_t *); 152 u_int32_t *);
153static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); 153static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
154static void sysctl_net_inet6_ip6_setup(struct sysctllog **); 154static void sysctl_net_inet6_ip6_setup(struct sysctllog **);
155 155
156/* 156/*
157 * IP6 initialization: fill in IP6 protocol switch table. 157 * IP6 initialization: fill in IP6 protocol switch table.
158 * All protocols not implemented in kernel go to raw IP6 protocol handler. 158 * All protocols not implemented in kernel go to raw IP6 protocol handler.
159 */ 159 */
160void 160void
161ip6_init(void) 161ip6_init(void)
162{ 162{
163 const struct ip6protosw *pr; 163 const struct ip6protosw *pr;
164 int i; 164 int i;
165 165
166 sysctl_net_inet6_ip6_setup(NULL); 166 sysctl_net_inet6_ip6_setup(NULL);
167 pr = (const struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); 167 pr = (const struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
168 if (pr == 0) 168 if (pr == 0)
169 panic("ip6_init"); 169 panic("ip6_init");
170 for (i = 0; i < IPPROTO_MAX; i++) 170 for (i = 0; i < IPPROTO_MAX; i++)
171 ip6_protox[i] = pr - inet6sw; 171 ip6_protox[i] = pr - inet6sw;
172 for (pr = (const struct ip6protosw *)inet6domain.dom_protosw; 172 for (pr = (const struct ip6protosw *)inet6domain.dom_protosw;
173 pr < (const struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++) 173 pr < (const struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++)
174 if (pr->pr_domain->dom_family == PF_INET6 && 174 if (pr->pr_domain->dom_family == PF_INET6 &&
175 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) 175 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
176 ip6_protox[pr->pr_protocol] = pr - inet6sw; 176 ip6_protox[pr->pr_protocol] = pr - inet6sw;
177 177
178 ip6_pktq = pktq_create(IFQ_MAXLEN, ip6intr, NULL); 178 ip6_pktq = pktq_create(IFQ_MAXLEN, ip6intr, NULL);
179 KASSERT(ip6_pktq != NULL); 179 KASSERT(ip6_pktq != NULL);
180 180
181 scope6_init(); 181 scope6_init();
182 addrsel_policy_init(); 182 addrsel_policy_init();
183 nd6_init(); 183 nd6_init();
184 frag6_init(); 184 frag6_init();
185 ip6_desync_factor = cprng_fast32() % MAX_TEMP_DESYNC_FACTOR; 185 ip6_desync_factor = cprng_fast32() % MAX_TEMP_DESYNC_FACTOR;
186 186
187 ip6_init2(NULL); 187 ip6_init2();
188#ifdef GATEWAY 188#ifdef GATEWAY
189 ip6flow_init(ip6_hashsize); 189 ip6flow_init(ip6_hashsize);
190#endif 190#endif
191 /* Register our Packet Filter hook. */ 191 /* Register our Packet Filter hook. */
192 inet6_pfil_hook = pfil_head_create(PFIL_TYPE_AF, (void *)AF_INET6); 192 inet6_pfil_hook = pfil_head_create(PFIL_TYPE_AF, (void *)AF_INET6);
193 KASSERT(inet6_pfil_hook != NULL); 193 KASSERT(inet6_pfil_hook != NULL);
194 194
195 ip6stat_percpu = percpu_alloc(sizeof(uint64_t) * IP6_NSTATS); 195 ip6stat_percpu = percpu_alloc(sizeof(uint64_t) * IP6_NSTATS);
196} 196}
197 197
198static void 198static void
199ip6_init2(void *dummy) 199ip6_init2(void)
200{ 200{
201 201
202 /* nd6_timer_init */ 
203 callout_init(&nd6_timer_ch, CALLOUT_MPSAFE); 
204 callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL); 
205 
206 /* timer for regeneranation of temporary addresses randomize ID */ 202 /* timer for regeneranation of temporary addresses randomize ID */
207 callout_init(&in6_tmpaddrtimer_ch, CALLOUT_MPSAFE); 203 callout_init(&in6_tmpaddrtimer_ch, CALLOUT_MPSAFE);
208 callout_reset(&in6_tmpaddrtimer_ch, 204 callout_reset(&in6_tmpaddrtimer_ch,
209 (ip6_temp_preferred_lifetime - ip6_desync_factor - 205 (ip6_temp_preferred_lifetime - ip6_desync_factor -
210 ip6_temp_regen_advance) * hz, 206 ip6_temp_regen_advance) * hz,
211 in6_tmpaddrtimer, NULL); 207 in6_tmpaddrtimer, NULL);
212} 208}
213 209
214/* 210/*
215 * IP6 input interrupt handling. Just pass the packet to ip6_input. 211 * IP6 input interrupt handling. Just pass the packet to ip6_input.
216 */ 212 */
217static void 213static void
218ip6intr(void *arg __unused) 214ip6intr(void *arg __unused)
219{ 215{
220 struct mbuf *m; 216 struct mbuf *m;
221 217
222 mutex_enter(softnet_lock); 218 mutex_enter(softnet_lock);
223 while ((m = pktq_dequeue(ip6_pktq)) != NULL) { 219 while ((m = pktq_dequeue(ip6_pktq)) != NULL) {
224 const ifnet_t *ifp = m->m_pkthdr.rcvif; 220 const ifnet_t *ifp = m->m_pkthdr.rcvif;
225 221
226 /* 222 /*
227 * Drop the packet if IPv6 is disabled on the interface. 223 * Drop the packet if IPv6 is disabled on the interface.
228 */ 224 */
229 if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) { 225 if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) {
230 m_freem(m); 226 m_freem(m);
231 continue; 227 continue;
232 } 228 }
233 ip6_input(m); 229 ip6_input(m);
234 } 230 }
235 mutex_exit(softnet_lock); 231 mutex_exit(softnet_lock);
236} 232}
237 233
238extern struct route ip6_forward_rt; 234extern struct route ip6_forward_rt;
239 235
240void 236void
241ip6_input(struct mbuf *m) 237ip6_input(struct mbuf *m)
242{ 238{
243 struct ip6_hdr *ip6; 239 struct ip6_hdr *ip6;
244 int hit, off = sizeof(struct ip6_hdr), nest; 240 int hit, off = sizeof(struct ip6_hdr), nest;
245 u_int32_t plen; 241 u_int32_t plen;
246 u_int32_t rtalert = ~0; 242 u_int32_t rtalert = ~0;
247 int nxt, ours = 0, rh_present = 0; 243 int nxt, ours = 0, rh_present = 0;
248 struct ifnet *deliverifp = NULL; 244 struct ifnet *deliverifp = NULL;
249 int srcrt = 0; 245 int srcrt = 0;
250 const struct rtentry *rt; 246 const struct rtentry *rt;
251 union { 247 union {
252 struct sockaddr dst; 248 struct sockaddr dst;
253 struct sockaddr_in6 dst6; 249 struct sockaddr_in6 dst6;
254 } u; 250 } u;
255 251
256 /* 252 /*
257 * make sure we don't have onion peering information into m_tag. 253 * make sure we don't have onion peering information into m_tag.
258 */ 254 */
259 ip6_delaux(m); 255 ip6_delaux(m);
260 256
261 /* 257 /*
262 * mbuf statistics 258 * mbuf statistics
263 */ 259 */
264 if (m->m_flags & M_EXT) { 260 if (m->m_flags & M_EXT) {
265 if (m->m_next) 261 if (m->m_next)
266 IP6_STATINC(IP6_STAT_MEXT2M); 262 IP6_STATINC(IP6_STAT_MEXT2M);
267 else 263 else
268 IP6_STATINC(IP6_STAT_MEXT1); 264 IP6_STATINC(IP6_STAT_MEXT1);
269 } else { 265 } else {
270#define M2MMAX 32 266#define M2MMAX 32
271 if (m->m_next) { 267 if (m->m_next) {
272 if (m->m_flags & M_LOOP) { 268 if (m->m_flags & M_LOOP) {
273 /*XXX*/ IP6_STATINC(IP6_STAT_M2M + lo0ifp->if_index); 269 /*XXX*/ IP6_STATINC(IP6_STAT_M2M + lo0ifp->if_index);
274 } else if (m->m_pkthdr.rcvif->if_index < M2MMAX) { 270 } else if (m->m_pkthdr.rcvif->if_index < M2MMAX) {
275 IP6_STATINC(IP6_STAT_M2M + 271 IP6_STATINC(IP6_STAT_M2M +
276 m->m_pkthdr.rcvif->if_index); 272 m->m_pkthdr.rcvif->if_index);
277 } else 273 } else
278 IP6_STATINC(IP6_STAT_M2M); 274 IP6_STATINC(IP6_STAT_M2M);
279 } else 275 } else
280 IP6_STATINC(IP6_STAT_M1); 276 IP6_STATINC(IP6_STAT_M1);
281#undef M2MMAX 277#undef M2MMAX
282 } 278 }
283 279
284 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive); 280 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive);
285 IP6_STATINC(IP6_STAT_TOTAL); 281 IP6_STATINC(IP6_STAT_TOTAL);
286 282
287 /* 283 /*
288 * If the IPv6 header is not aligned, slurp it up into a new 284 * If the IPv6 header is not aligned, slurp it up into a new
289 * mbuf with space for link headers, in the event we forward 285 * mbuf with space for link headers, in the event we forward
290 * it. Otherwise, if it is aligned, make sure the entire base 286 * it. Otherwise, if it is aligned, make sure the entire base
291 * IPv6 header is in the first mbuf of the chain. 287 * IPv6 header is in the first mbuf of the chain.
292 */ 288 */
293 if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) { 289 if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) {
294 struct ifnet *inifp = m->m_pkthdr.rcvif; 290 struct ifnet *inifp = m->m_pkthdr.rcvif;
295 if ((m = m_copyup(m, sizeof(struct ip6_hdr), 291 if ((m = m_copyup(m, sizeof(struct ip6_hdr),
296 (max_linkhdr + 3) & ~3)) == NULL) { 292 (max_linkhdr + 3) & ~3)) == NULL) {
297 /* XXXJRT new stat, please */ 293 /* XXXJRT new stat, please */
298 IP6_STATINC(IP6_STAT_TOOSMALL); 294 IP6_STATINC(IP6_STAT_TOOSMALL);
299 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 295 in6_ifstat_inc(inifp, ifs6_in_hdrerr);
300 return; 296 return;
301 } 297 }
302 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { 298 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
303 struct ifnet *inifp = m->m_pkthdr.rcvif; 299 struct ifnet *inifp = m->m_pkthdr.rcvif;
304 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { 300 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
305 IP6_STATINC(IP6_STAT_TOOSMALL); 301 IP6_STATINC(IP6_STAT_TOOSMALL);
306 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 302 in6_ifstat_inc(inifp, ifs6_in_hdrerr);
307 return; 303 return;
308 } 304 }
309 } 305 }
310 306
311 ip6 = mtod(m, struct ip6_hdr *); 307 ip6 = mtod(m, struct ip6_hdr *);
312 308
313 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 309 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
314 IP6_STATINC(IP6_STAT_BADVERS); 310 IP6_STATINC(IP6_STAT_BADVERS);
315 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 311 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
316 goto bad; 312 goto bad;
317 } 313 }
318 314
319 /* 315 /*
320 * Assume that we can create a fast-forward IP flow entry 316 * Assume that we can create a fast-forward IP flow entry
321 * based on this packet. 317 * based on this packet.
322 */ 318 */
323 m->m_flags |= M_CANFASTFWD; 319 m->m_flags |= M_CANFASTFWD;
324 320
325 /* 321 /*
326 * Run through list of hooks for input packets. If there are any 322 * Run through list of hooks for input packets. If there are any
327 * filters which require that additional packets in the flow are 323 * filters which require that additional packets in the flow are
328 * not fast-forwarded, they must clear the M_CANFASTFWD flag. 324 * not fast-forwarded, they must clear the M_CANFASTFWD flag.
329 * Note that filters must _never_ set this flag, as another filter 325 * Note that filters must _never_ set this flag, as another filter
330 * in the list may have previously cleared it. 326 * in the list may have previously cleared it.
331 */ 327 */
332 /* 328 /*
333 * let ipfilter look at packet on the wire, 329 * let ipfilter look at packet on the wire,
334 * not the decapsulated packet. 330 * not the decapsulated packet.
335 */ 331 */
336#if defined(IPSEC) 332#if defined(IPSEC)
337 if (!ipsec_used || !ipsec_indone(m)) 333 if (!ipsec_used || !ipsec_indone(m))
338#else 334#else
339 if (1) 335 if (1)
340#endif 336#endif
341 { 337 {
342 struct in6_addr odst; 338 struct in6_addr odst;
343 339
344 odst = ip6->ip6_dst; 340 odst = ip6->ip6_dst;
345 if (pfil_run_hooks(inet6_pfil_hook, &m, m->m_pkthdr.rcvif, 341 if (pfil_run_hooks(inet6_pfil_hook, &m, m->m_pkthdr.rcvif,
346 PFIL_IN) != 0) 342 PFIL_IN) != 0)
347 return; 343 return;
348 if (m == NULL) 344 if (m == NULL)
349 return; 345 return;
350 ip6 = mtod(m, struct ip6_hdr *); 346 ip6 = mtod(m, struct ip6_hdr *);
351 srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); 347 srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);
352 } 348 }
353 349
354 IP6_STATINC(IP6_STAT_NXTHIST + ip6->ip6_nxt); 350 IP6_STATINC(IP6_STAT_NXTHIST + ip6->ip6_nxt);
355 351
356#ifdef ALTQ 352#ifdef ALTQ
357 if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) { 353 if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) {
358 /* packet is dropped by traffic conditioner */ 354 /* packet is dropped by traffic conditioner */
359 return; 355 return;
360 } 356 }
361#endif 357#endif
362 358
363 /* 359 /*
364 * Check against address spoofing/corruption. 360 * Check against address spoofing/corruption.
365 */ 361 */
366 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) || 362 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) ||
367 IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) { 363 IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {
368 /* 364 /*
369 * XXX: "badscope" is not very suitable for a multicast source. 365 * XXX: "badscope" is not very suitable for a multicast source.
370 */ 366 */
371 IP6_STATINC(IP6_STAT_BADSCOPE); 367 IP6_STATINC(IP6_STAT_BADSCOPE);
372 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 368 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
373 goto bad; 369 goto bad;
374 } 370 }
375 /* 371 /*
376 * The following check is not documented in specs. A malicious 372 * The following check is not documented in specs. A malicious
377 * party may be able to use IPv4 mapped addr to confuse tcp/udp stack 373 * party may be able to use IPv4 mapped addr to confuse tcp/udp stack
378 * and bypass security checks (act as if it was from 127.0.0.1 by using 374 * and bypass security checks (act as if it was from 127.0.0.1 by using
379 * IPv6 src ::ffff:127.0.0.1). Be cautious. 375 * IPv6 src ::ffff:127.0.0.1). Be cautious.
380 * 376 *
381 * This check chokes if we are in an SIIT cloud. As none of BSDs 377 * This check chokes if we are in an SIIT cloud. As none of BSDs
382 * support IPv4-less kernel compilation, we cannot support SIIT 378 * support IPv4-less kernel compilation, we cannot support SIIT
383 * environment at all. So, it makes more sense for us to reject any 379 * environment at all. So, it makes more sense for us to reject any
384 * malicious packets for non-SIIT environment, than try to do a 380 * malicious packets for non-SIIT environment, than try to do a
385 * partial support for SIIT environment. 381 * partial support for SIIT environment.
386 */ 382 */
387 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 383 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
388 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 384 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
389 IP6_STATINC(IP6_STAT_BADSCOPE); 385 IP6_STATINC(IP6_STAT_BADSCOPE);
390 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 386 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
391 goto bad; 387 goto bad;
392 } 388 }
393#if 0 389#if 0
394 /* 390 /*
395 * Reject packets with IPv4 compatible addresses (auto tunnel). 391 * Reject packets with IPv4 compatible addresses (auto tunnel).
396 * 392 *
397 * The code forbids auto tunnel relay case in RFC1933 (the check is 393 * The code forbids auto tunnel relay case in RFC1933 (the check is
398 * stronger than RFC1933). We may want to re-enable it if mech-xx 394 * stronger than RFC1933). We may want to re-enable it if mech-xx
399 * is revised to forbid relaying case. 395 * is revised to forbid relaying case.
400 */ 396 */
401 if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || 397 if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) ||
402 IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { 398 IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {
403 IP6_STATINC(IP6_STAT_BADSCOPE); 399 IP6_STATINC(IP6_STAT_BADSCOPE);
404 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 400 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
405 goto bad; 401 goto bad;
406 } 402 }
407#endif 403#endif
408 404
409 /* 405 /*
410 * Disambiguate address scope zones (if there is ambiguity). 406 * Disambiguate address scope zones (if there is ambiguity).
411 * We first make sure that the original source or destination address 407 * We first make sure that the original source or destination address
412 * is not in our internal form for scoped addresses. Such addresses 408 * is not in our internal form for scoped addresses. Such addresses
413 * are not necessarily invalid spec-wise, but we cannot accept them due 409 * are not necessarily invalid spec-wise, but we cannot accept them due
414 * to the usage conflict. 410 * to the usage conflict.
415 * in6_setscope() then also checks and rejects the cases where src or 411 * in6_setscope() then also checks and rejects the cases where src or
416 * dst are the loopback address and the receiving interface 412 * dst are the loopback address and the receiving interface
417 * is not loopback.  413 * is not loopback.
418 */ 414 */
419 if (__predict_false( 415 if (__predict_false(
420 m_makewritable(&m, 0, sizeof(struct ip6_hdr), M_DONTWAIT))) 416 m_makewritable(&m, 0, sizeof(struct ip6_hdr), M_DONTWAIT)))
421 goto bad; 417 goto bad;
422 ip6 = mtod(m, struct ip6_hdr *); 418 ip6 = mtod(m, struct ip6_hdr *);
423 if (in6_clearscope(&ip6->ip6_src) || in6_clearscope(&ip6->ip6_dst)) { 419 if (in6_clearscope(&ip6->ip6_src) || in6_clearscope(&ip6->ip6_dst)) {
424 IP6_STATINC(IP6_STAT_BADSCOPE); /* XXX */ 420 IP6_STATINC(IP6_STAT_BADSCOPE); /* XXX */
425 goto bad; 421 goto bad;
426 } 422 }
427 if (in6_setscope(&ip6->ip6_src, m->m_pkthdr.rcvif, NULL) || 423 if (in6_setscope(&ip6->ip6_src, m->m_pkthdr.rcvif, NULL) ||
428 in6_setscope(&ip6->ip6_dst, m->m_pkthdr.rcvif, NULL)) { 424 in6_setscope(&ip6->ip6_dst, m->m_pkthdr.rcvif, NULL)) {
429 IP6_STATINC(IP6_STAT_BADSCOPE); 425 IP6_STATINC(IP6_STAT_BADSCOPE);
430 goto bad; 426 goto bad;
431 } 427 }
432 428
433 /* 429 /*
434 * Multicast check 430 * Multicast check
435 */ 431 */
436 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 432 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
437 struct in6_multi *in6m = 0; 433 struct in6_multi *in6m = 0;
438 434
439 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast); 435 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast);
440 /* 436 /*
441 * See if we belong to the destination multicast group on the 437 * See if we belong to the destination multicast group on the
442 * arrival interface. 438 * arrival interface.
443 */ 439 */
444 IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m); 440 IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m);
445 if (in6m) 441 if (in6m)
446 ours = 1; 442 ours = 1;
447 else if (!ip6_mrouter) { 443 else if (!ip6_mrouter) {
448 uint64_t *ip6s = IP6_STAT_GETREF(); 444 uint64_t *ip6s = IP6_STAT_GETREF();
449 ip6s[IP6_STAT_NOTMEMBER]++; 445 ip6s[IP6_STAT_NOTMEMBER]++;
450 ip6s[IP6_STAT_CANTFORWARD]++; 446 ip6s[IP6_STAT_CANTFORWARD]++;
451 IP6_STAT_PUTREF(); 447 IP6_STAT_PUTREF();
452 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 448 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
453 goto bad; 449 goto bad;
454 } 450 }
455 deliverifp = m->m_pkthdr.rcvif; 451 deliverifp = m->m_pkthdr.rcvif;
456 goto hbhcheck; 452 goto hbhcheck;
457 } 453 }
458 454
459 sockaddr_in6_init(&u.dst6, &ip6->ip6_dst, 0, 0, 0); 455 sockaddr_in6_init(&u.dst6, &ip6->ip6_dst, 0, 0, 0);
460 456
461 /* 457 /*
462 * Unicast check 458 * Unicast check
463 */ 459 */
464 rt = rtcache_lookup2(&ip6_forward_rt, &u.dst, 1, &hit); 460 rt = rtcache_lookup2(&ip6_forward_rt, &u.dst, 1, &hit);
465 if (hit) 461 if (hit)
466 IP6_STATINC(IP6_STAT_FORWARD_CACHEHIT); 462 IP6_STATINC(IP6_STAT_FORWARD_CACHEHIT);
467 else 463 else
468 IP6_STATINC(IP6_STAT_FORWARD_CACHEMISS); 464 IP6_STATINC(IP6_STAT_FORWARD_CACHEMISS);
469 465
470#define rt6_getkey(__rt) satocsin6(rt_getkey(__rt)) 466#define rt6_getkey(__rt) satocsin6(rt_getkey(__rt))
471 467
472 /* 468 /*
473 * Accept the packet if the forwarding interface to the destination 469 * Accept the packet if the forwarding interface to the destination
474 * according to the routing table is the loopback interface, 470 * according to the routing table is the loopback interface,
475 * unless the associated route has a gateway. 471 * unless the associated route has a gateway.
476 * Note that this approach causes to accept a packet if there is a 472 * Note that this approach causes to accept a packet if there is a
477 * route to the loopback interface for the destination of the packet. 473 * route to the loopback interface for the destination of the packet.
478 * But we think it's even useful in some situations, e.g. when using 474 * But we think it's even useful in some situations, e.g. when using
479 * a special daemon which wants to intercept the packet. 475 * a special daemon which wants to intercept the packet.
480 */ 476 */
481 if (rt != NULL && 477 if (rt != NULL &&
482 (rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST && 478 (rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST &&
483 !(rt->rt_flags & RTF_CLONED) && 479 !(rt->rt_flags & RTF_CLONED) &&
484#if 0 480#if 0
485 /* 481 /*
486 * The check below is redundant since the comparison of 482 * The check below is redundant since the comparison of
487 * the destination and the key of the rtentry has 483 * the destination and the key of the rtentry has
488 * already done through looking up the routing table. 484 * already done through looking up the routing table.
489 */ 485 */
490 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &rt6_getkey(rt)->sin6_addr) && 486 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &rt6_getkey(rt)->sin6_addr) &&
491#endif 487#endif
492 rt->rt_ifp->if_type == IFT_LOOP) { 488 rt->rt_ifp->if_type == IFT_LOOP) {
493 struct in6_ifaddr *ia6 = (struct in6_ifaddr *)rt->rt_ifa; 489 struct in6_ifaddr *ia6 = (struct in6_ifaddr *)rt->rt_ifa;
494 if (ia6->ia6_flags & IN6_IFF_ANYCAST) 490 if (ia6->ia6_flags & IN6_IFF_ANYCAST)
495 m->m_flags |= M_ANYCAST6; 491 m->m_flags |= M_ANYCAST6;
496 /* 492 /*
497 * packets to a tentative, duplicated, or somehow invalid 493 * packets to a tentative, duplicated, or somehow invalid
498 * address must not be accepted. 494 * address must not be accepted.
499 */ 495 */
500 if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) { 496 if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) {
501 /* this address is ready */ 497 /* this address is ready */
502 ours = 1; 498 ours = 1;
503 deliverifp = ia6->ia_ifp; /* correct? */ 499 deliverifp = ia6->ia_ifp; /* correct? */
504 goto hbhcheck; 500 goto hbhcheck;
505 } else { 501 } else {
506 /* address is not ready, so discard the packet. */ 502 /* address is not ready, so discard the packet. */
507 nd6log((LOG_INFO, 503 nd6log((LOG_INFO,
508 "ip6_input: packet to an unready address %s->%s\n", 504 "ip6_input: packet to an unready address %s->%s\n",
509 ip6_sprintf(&ip6->ip6_src), 505 ip6_sprintf(&ip6->ip6_src),
510 ip6_sprintf(&ip6->ip6_dst))); 506 ip6_sprintf(&ip6->ip6_dst)));
511 507
512 goto bad; 508 goto bad;
513 } 509 }
514 } 510 }
515 511
516 /* 512 /*
517 * FAITH (Firewall Aided Internet Translator) 513 * FAITH (Firewall Aided Internet Translator)
518 */ 514 */
519#if defined(NFAITH) && 0 < NFAITH 515#if defined(NFAITH) && 0 < NFAITH
520 if (ip6_keepfaith) { 516 if (ip6_keepfaith) {
521 if (rt != NULL && rt->rt_ifp != NULL && 517 if (rt != NULL && rt->rt_ifp != NULL &&
522 rt->rt_ifp->if_type == IFT_FAITH) { 518 rt->rt_ifp->if_type == IFT_FAITH) {
523 /* XXX do we need more sanity checks? */ 519 /* XXX do we need more sanity checks? */
524 ours = 1; 520 ours = 1;
525 deliverifp = rt->rt_ifp; /* faith */ 521 deliverifp = rt->rt_ifp; /* faith */
526 goto hbhcheck; 522 goto hbhcheck;
527 } 523 }
528 } 524 }
529#endif 525#endif
530 526
531#if 0 527#if 0
532 { 528 {
533 /* 529 /*
534 * Last resort: check in6_ifaddr for incoming interface. 530 * Last resort: check in6_ifaddr for incoming interface.
535 * The code is here until I update the "goto ours hack" code above 531 * The code is here until I update the "goto ours hack" code above
536 * working right. 532 * working right.
537 */ 533 */
538 struct ifaddr *ifa; 534 struct ifaddr *ifa;
539 IFADDR_FOREACH(ifa, m->m_pkthdr.rcvif) { 535 IFADDR_FOREACH(ifa, m->m_pkthdr.rcvif) {
540 if (ifa->ifa_addr == NULL) 536 if (ifa->ifa_addr == NULL)
541 continue; /* just for safety */ 537 continue; /* just for safety */
542 if (ifa->ifa_addr->sa_family != AF_INET6) 538 if (ifa->ifa_addr->sa_family != AF_INET6)
543 continue; 539 continue;
544 if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ip6->ip6_dst)) { 540 if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ip6->ip6_dst)) {
545 ours = 1; 541 ours = 1;
546 deliverifp = ifa->ifa_ifp; 542 deliverifp = ifa->ifa_ifp;
547 goto hbhcheck; 543 goto hbhcheck;
548 } 544 }
549 } 545 }
550 } 546 }
551#endif 547#endif
552 548
553 /* 549 /*
554 * Now there is no reason to process the packet if it's not our own 550 * Now there is no reason to process the packet if it's not our own
555 * and we're not a router. 551 * and we're not a router.
556 */ 552 */
557 if (!ip6_forwarding) { 553 if (!ip6_forwarding) {
558 IP6_STATINC(IP6_STAT_CANTFORWARD); 554 IP6_STATINC(IP6_STAT_CANTFORWARD);
559 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 555 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
560 goto bad; 556 goto bad;
561 } 557 }
562 558
563 hbhcheck: 559 hbhcheck:
564 /* 560 /*
565 * record address information into m_tag, if we don't have one yet. 561 * record address information into m_tag, if we don't have one yet.
566 * note that we are unable to record it, if the address is not listed 562 * note that we are unable to record it, if the address is not listed
567 * as our interface address (e.g. multicast addresses, addresses 563 * as our interface address (e.g. multicast addresses, addresses
568 * within FAITH prefixes and such). 564 * within FAITH prefixes and such).
569 */ 565 */
570 if (deliverifp && ip6_getdstifaddr(m) == NULL) { 566 if (deliverifp && ip6_getdstifaddr(m) == NULL) {
571 struct in6_ifaddr *ia6; 567 struct in6_ifaddr *ia6;
572 568
573 ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst); 569 ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
574 if (ia6 != NULL && ip6_setdstifaddr(m, ia6) == NULL) { 570 if (ia6 != NULL && ip6_setdstifaddr(m, ia6) == NULL) {
575 /* 571 /*
576 * XXX maybe we should drop the packet here, 572 * XXX maybe we should drop the packet here,
577 * as we could not provide enough information 573 * as we could not provide enough information
578 * to the upper layers. 574 * to the upper layers.
579 */ 575 */
580 } 576 }
581 } 577 }
582 578
583 /* 579 /*
584 * Process Hop-by-Hop options header if it's contained. 580 * Process Hop-by-Hop options header if it's contained.
585 * m may be modified in ip6_hopopts_input(). 581 * m may be modified in ip6_hopopts_input().
586 * If a JumboPayload option is included, plen will also be modified. 582 * If a JumboPayload option is included, plen will also be modified.
587 */ 583 */
588 plen = (u_int32_t)ntohs(ip6->ip6_plen); 584 plen = (u_int32_t)ntohs(ip6->ip6_plen);
589 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { 585 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
590 struct ip6_hbh *hbh; 586 struct ip6_hbh *hbh;
591 587
592 if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) { 588 if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) {
593#if 0 /*touches NULL pointer*/ 589#if 0 /*touches NULL pointer*/
594 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 590 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
595#endif 591#endif
596 return; /* m have already been freed */ 592 return; /* m have already been freed */
597 } 593 }
598 594
599 /* adjust pointer */ 595 /* adjust pointer */
600 ip6 = mtod(m, struct ip6_hdr *); 596 ip6 = mtod(m, struct ip6_hdr *);
601 597
602 /* 598 /*
603 * if the payload length field is 0 and the next header field 599 * if the payload length field is 0 and the next header field
604 * indicates Hop-by-Hop Options header, then a Jumbo Payload 600 * indicates Hop-by-Hop Options header, then a Jumbo Payload
605 * option MUST be included. 601 * option MUST be included.
606 */ 602 */
607 if (ip6->ip6_plen == 0 && plen == 0) { 603 if (ip6->ip6_plen == 0 && plen == 0) {
608 /* 604 /*
609 * Note that if a valid jumbo payload option is 605 * Note that if a valid jumbo payload option is
610 * contained, ip6_hopopts_input() must set a valid 606 * contained, ip6_hopopts_input() must set a valid
611 * (non-zero) payload length to the variable plen. 607 * (non-zero) payload length to the variable plen.
612 */ 608 */
613 IP6_STATINC(IP6_STAT_BADOPTIONS); 609 IP6_STATINC(IP6_STAT_BADOPTIONS);
614 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 610 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
615 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 611 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
616 icmp6_error(m, ICMP6_PARAM_PROB, 612 icmp6_error(m, ICMP6_PARAM_PROB,
617 ICMP6_PARAMPROB_HEADER, 613 ICMP6_PARAMPROB_HEADER,
618 (char *)&ip6->ip6_plen - (char *)ip6); 614 (char *)&ip6->ip6_plen - (char *)ip6);
619 return; 615 return;
620 } 616 }
621 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), 617 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
622 sizeof(struct ip6_hbh)); 618 sizeof(struct ip6_hbh));
623 if (hbh == NULL) { 619 if (hbh == NULL) {
624 IP6_STATINC(IP6_STAT_TOOSHORT); 620 IP6_STATINC(IP6_STAT_TOOSHORT);
625 return; 621 return;
626 } 622 }
627 KASSERT(IP6_HDR_ALIGNED_P(hbh)); 623 KASSERT(IP6_HDR_ALIGNED_P(hbh));
628 nxt = hbh->ip6h_nxt; 624 nxt = hbh->ip6h_nxt;
629 625
630 /* 626 /*
631 * accept the packet if a router alert option is included 627 * accept the packet if a router alert option is included
632 * and we act as an IPv6 router. 628 * and we act as an IPv6 router.
633 */ 629 */
634 if (rtalert != ~0 && ip6_forwarding) 630 if (rtalert != ~0 && ip6_forwarding)
635 ours = 1; 631 ours = 1;
636 } else 632 } else
637 nxt = ip6->ip6_nxt; 633 nxt = ip6->ip6_nxt;
638 634
639 /* 635 /*
640 * Check that the amount of data in the buffers 636 * Check that the amount of data in the buffers
641 * is as at least much as the IPv6 header would have us expect. 637 * is as at least much as the IPv6 header would have us expect.
642 * Trim mbufs if longer than we expect. 638 * Trim mbufs if longer than we expect.
643 * Drop packet if shorter than we expect. 639 * Drop packet if shorter than we expect.
644 */ 640 */
645 if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) { 641 if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
646 IP6_STATINC(IP6_STAT_TOOSHORT); 642 IP6_STATINC(IP6_STAT_TOOSHORT);
647 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 643 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
648 goto bad; 644 goto bad;
649 } 645 }
650 if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { 646 if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
651 if (m->m_len == m->m_pkthdr.len) { 647 if (m->m_len == m->m_pkthdr.len) {
652 m->m_len = sizeof(struct ip6_hdr) + plen; 648 m->m_len = sizeof(struct ip6_hdr) + plen;
653 m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen; 649 m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen;
654 } else 650 } else
655 m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len); 651 m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len);
656 } 652 }
657 653
658 /* 654 /*
659 * Forward if desirable. 655 * Forward if desirable.
660 */ 656 */
661 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 657 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
662 /* 658 /*
663 * If we are acting as a multicast router, all 659 * If we are acting as a multicast router, all
664 * incoming multicast packets are passed to the 660 * incoming multicast packets are passed to the
665 * kernel-level multicast forwarding function. 661 * kernel-level multicast forwarding function.
666 * The packet is returned (relatively) intact; if 662 * The packet is returned (relatively) intact; if
667 * ip6_mforward() returns a non-zero value, the packet 663 * ip6_mforward() returns a non-zero value, the packet
668 * must be discarded, else it may be accepted below. 664 * must be discarded, else it may be accepted below.
669 */ 665 */
670 if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) { 666 if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) {
671 IP6_STATINC(IP6_STAT_CANTFORWARD); 667 IP6_STATINC(IP6_STAT_CANTFORWARD);
672 m_freem(m); 668 m_freem(m);
673 return; 669 return;
674 } 670 }
675 if (!ours) { 671 if (!ours) {
676 m_freem(m); 672 m_freem(m);
677 return; 673 return;
678 } 674 }
679 } else if (!ours) { 675 } else if (!ours) {
680 ip6_forward(m, srcrt); 676 ip6_forward(m, srcrt);
681 return; 677 return;
682 } 678 }
683 679
684 ip6 = mtod(m, struct ip6_hdr *); 680 ip6 = mtod(m, struct ip6_hdr *);
685 681
686 /* 682 /*
687 * Malicious party may be able to use IPv4 mapped addr to confuse 683 * Malicious party may be able to use IPv4 mapped addr to confuse
688 * tcp/udp stack and bypass security checks (act as if it was from 684 * tcp/udp stack and bypass security checks (act as if it was from
689 * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1). Be cautious. 685 * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1). Be cautious.
690 * 686 *
691 * For SIIT end node behavior, you may want to disable the check. 687 * For SIIT end node behavior, you may want to disable the check.
692 * However, you will become vulnerable to attacks using IPv4 mapped 688 * However, you will become vulnerable to attacks using IPv4 mapped
693 * source. 689 * source.
694 */ 690 */
695 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 691 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
696 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 692 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
697 IP6_STATINC(IP6_STAT_BADSCOPE); 693 IP6_STATINC(IP6_STAT_BADSCOPE);
698 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 694 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
699 goto bad; 695 goto bad;
700 } 696 }
701 697
702 /* 698 /*
703 * Tell launch routine the next header 699 * Tell launch routine the next header
704 */ 700 */
705#ifdef IFA_STATS 701#ifdef IFA_STATS
706 if (deliverifp != NULL) { 702 if (deliverifp != NULL) {
707 struct in6_ifaddr *ia6; 703 struct in6_ifaddr *ia6;
708 ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst); 704 ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
709 if (ia6) 705 if (ia6)
710 ia6->ia_ifa.ifa_data.ifad_inbytes += m->m_pkthdr.len; 706 ia6->ia_ifa.ifa_data.ifad_inbytes += m->m_pkthdr.len;
711 } 707 }
712#endif 708#endif
713 IP6_STATINC(IP6_STAT_DELIVERED); 709 IP6_STATINC(IP6_STAT_DELIVERED);
714 in6_ifstat_inc(deliverifp, ifs6_in_deliver); 710 in6_ifstat_inc(deliverifp, ifs6_in_deliver);
715 nest = 0; 711 nest = 0;
716 712
717 rh_present = 0; 713 rh_present = 0;
718 while (nxt != IPPROTO_DONE) { 714 while (nxt != IPPROTO_DONE) {
719 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { 715 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
720 IP6_STATINC(IP6_STAT_TOOMANYHDR); 716 IP6_STATINC(IP6_STAT_TOOMANYHDR);
721 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 717 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
722 goto bad; 718 goto bad;
723 } 719 }
724 720
725 /* 721 /*
726 * protection against faulty packet - there should be 722 * protection against faulty packet - there should be
727 * more sanity checks in header chain processing. 723 * more sanity checks in header chain processing.
728 */ 724 */
729 if (m->m_pkthdr.len < off) { 725 if (m->m_pkthdr.len < off) {
730 IP6_STATINC(IP6_STAT_TOOSHORT); 726 IP6_STATINC(IP6_STAT_TOOSHORT);
731 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 727 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
732 goto bad; 728 goto bad;
733 } 729 }
734 730
735 if (nxt == IPPROTO_ROUTING) { 731 if (nxt == IPPROTO_ROUTING) {
736 if (rh_present++) { 732 if (rh_present++) {
737 in6_ifstat_inc(m->m_pkthdr.rcvif, 733 in6_ifstat_inc(m->m_pkthdr.rcvif,
738 ifs6_in_hdrerr); 734 ifs6_in_hdrerr);
739 IP6_STATINC(IP6_STAT_BADOPTIONS); 735 IP6_STATINC(IP6_STAT_BADOPTIONS);
740 goto bad; 736 goto bad;
741 } 737 }
742 } 738 }
743 739
744#ifdef IPSEC 740#ifdef IPSEC
745 if (ipsec_used) { 741 if (ipsec_used) {
746 /* 742 /*
747 * enforce IPsec policy checking if we are seeing last 743 * enforce IPsec policy checking if we are seeing last
748 * header. note that we do not visit this with 744 * header. note that we do not visit this with
749 * protocols with pcb layer code - like udp/tcp/raw ip. 745 * protocols with pcb layer code - like udp/tcp/raw ip.
750 */ 746 */
751 if ((inet6sw[ip_protox[nxt]].pr_flags 747 if ((inet6sw[ip_protox[nxt]].pr_flags
752 & PR_LASTHDR) != 0) { 748 & PR_LASTHDR) != 0) {
753 int error = ipsec6_input(m); 749 int error = ipsec6_input(m);
754 if (error) 750 if (error)
755 goto bad; 751 goto bad;
756 } 752 }
757 } 753 }
758#endif /* IPSEC */ 754#endif /* IPSEC */
759 755
760 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); 756 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
761 } 757 }
762 return; 758 return;
763 bad: 759 bad:
764 m_freem(m); 760 m_freem(m);
765} 761}
766 762
767/* 763/*
768 * set/grab in6_ifaddr correspond to IPv6 destination address. 764 * set/grab in6_ifaddr correspond to IPv6 destination address.
769 */ 765 */
770static struct m_tag * 766static struct m_tag *
771ip6_setdstifaddr(struct mbuf *m, const struct in6_ifaddr *ia) 767ip6_setdstifaddr(struct mbuf *m, const struct in6_ifaddr *ia)
772{ 768{
773 struct m_tag *mtag; 769 struct m_tag *mtag;
774 struct ip6aux *ip6a; 770 struct ip6aux *ip6a;
775 771
776 mtag = ip6_addaux(m); 772 mtag = ip6_addaux(m);
777 if (mtag == NULL) 773 if (mtag == NULL)
778 return NULL; 774 return NULL;
779 775
780 ip6a = (struct ip6aux *)(mtag + 1); 776 ip6a = (struct ip6aux *)(mtag + 1);
781 if (in6_setscope(&ip6a->ip6a_src, ia->ia_ifp, &ip6a->ip6a_scope_id)) { 777 if (in6_setscope(&ip6a->ip6a_src, ia->ia_ifp, &ip6a->ip6a_scope_id)) {
782 IP6_STATINC(IP6_STAT_BADSCOPE); 778 IP6_STATINC(IP6_STAT_BADSCOPE);
783 return NULL; 779 return NULL;
784 } 780 }
785 781
786 ip6a->ip6a_src = ia->ia_addr.sin6_addr; 782 ip6a->ip6a_src = ia->ia_addr.sin6_addr;
787 ip6a->ip6a_flags = ia->ia6_flags; 783 ip6a->ip6a_flags = ia->ia6_flags;
788 return mtag; 784 return mtag;
789} 785}
790 786
791const struct ip6aux * 787const struct ip6aux *
792ip6_getdstifaddr(struct mbuf *m) 788ip6_getdstifaddr(struct mbuf *m)
793{ 789{
794 struct m_tag *mtag; 790 struct m_tag *mtag;
795 791
796 mtag = ip6_findaux(m); 792 mtag = ip6_findaux(m);
797 if (mtag != NULL) 793 if (mtag != NULL)
798 return (struct ip6aux *)(mtag + 1); 794 return (struct ip6aux *)(mtag + 1);
799 else 795 else
800 return NULL; 796 return NULL;
801} 797}
802 798
803/* 799/*
804 * Hop-by-Hop options header processing. If a valid jumbo payload option is 800 * Hop-by-Hop options header processing. If a valid jumbo payload option is
805 * included, the real payload length will be stored in plenp. 801 * included, the real payload length will be stored in plenp.
806 * 802 *
807 * rtalertp - XXX: should be stored more smart way 803 * rtalertp - XXX: should be stored more smart way
808 */ 804 */
809int 805int
810ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,  806ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,
811 struct mbuf **mp, int *offp) 807 struct mbuf **mp, int *offp)
812{ 808{
813 struct mbuf *m = *mp; 809 struct mbuf *m = *mp;
814 int off = *offp, hbhlen; 810 int off = *offp, hbhlen;
815 struct ip6_hbh *hbh; 811 struct ip6_hbh *hbh;
816 812
817 /* validation of the length of the header */ 813 /* validation of the length of the header */
818 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, 814 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m,
819 sizeof(struct ip6_hdr), sizeof(struct ip6_hbh)); 815 sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
820 if (hbh == NULL) { 816 if (hbh == NULL) {
821 IP6_STATINC(IP6_STAT_TOOSHORT); 817 IP6_STATINC(IP6_STAT_TOOSHORT);
822 return -1; 818 return -1;
823 } 819 }
824 hbhlen = (hbh->ip6h_len + 1) << 3; 820 hbhlen = (hbh->ip6h_len + 1) << 3;
825 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), 821 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
826 hbhlen); 822 hbhlen);
827 if (hbh == NULL) { 823 if (hbh == NULL) {
828 IP6_STATINC(IP6_STAT_TOOSHORT); 824 IP6_STATINC(IP6_STAT_TOOSHORT);
829 return -1; 825 return -1;
830 } 826 }
831 KASSERT(IP6_HDR_ALIGNED_P(hbh)); 827 KASSERT(IP6_HDR_ALIGNED_P(hbh));
832 off += hbhlen; 828 off += hbhlen;
833 hbhlen -= sizeof(struct ip6_hbh); 829 hbhlen -= sizeof(struct ip6_hbh);
834 830
835 if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), 831 if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
836 hbhlen, rtalertp, plenp) < 0) 832 hbhlen, rtalertp, plenp) < 0)
837 return (-1); 833 return (-1);
838 834
839 *offp = off; 835 *offp = off;
840 *mp = m; 836 *mp = m;
841 return (0); 837 return (0);
842} 838}
843 839
844/* 840/*
845 * Search header for all Hop-by-hop options and process each option. 841 * Search header for all Hop-by-hop options and process each option.
846 * This function is separate from ip6_hopopts_input() in order to 842 * This function is separate from ip6_hopopts_input() in order to
847 * handle a case where the sending node itself process its hop-by-hop 843 * handle a case where the sending node itself process its hop-by-hop
848 * options header. In such a case, the function is called from ip6_output(). 844 * options header. In such a case, the function is called from ip6_output().
849 * 845 *
850 * The function assumes that hbh header is located right after the IPv6 header 846 * The function assumes that hbh header is located right after the IPv6 header
851 * (RFC2460 p7), opthead is pointer into data content in m, and opthead to 847 * (RFC2460 p7), opthead is pointer into data content in m, and opthead to
852 * opthead + hbhlen is located in continuous memory region. 848 * opthead + hbhlen is located in continuous memory region.
853 */ 849 */
854static int 850static int
855ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,  851ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,
856 u_int32_t *rtalertp, u_int32_t *plenp) 852 u_int32_t *rtalertp, u_int32_t *plenp)
857{ 853{
858 struct ip6_hdr *ip6; 854 struct ip6_hdr *ip6;
859 int optlen = 0; 855 int optlen = 0;
860 u_int8_t *opt = opthead; 856 u_int8_t *opt = opthead;
861 u_int16_t rtalert_val; 857 u_int16_t rtalert_val;
862 u_int32_t jumboplen; 858 u_int32_t jumboplen;
863 const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh); 859 const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh);
864 860
865 for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) { 861 for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) {
866 switch (*opt) { 862 switch (*opt) {
867 case IP6OPT_PAD1: 863 case IP6OPT_PAD1:
868 optlen = 1; 864 optlen = 1;
869 break; 865 break;
870 case IP6OPT_PADN: 866 case IP6OPT_PADN:
871 if (hbhlen < IP6OPT_MINLEN) { 867 if (hbhlen < IP6OPT_MINLEN) {
872 IP6_STATINC(IP6_STAT_TOOSMALL); 868 IP6_STATINC(IP6_STAT_TOOSMALL);
873 goto bad; 869 goto bad;
874 } 870 }
875 optlen = *(opt + 1) + 2; 871 optlen = *(opt + 1) + 2;
876 break; 872 break;
877 case IP6OPT_RTALERT: 873 case IP6OPT_RTALERT:
878 /* XXX may need check for alignment */ 874 /* XXX may need check for alignment */
879 if (hbhlen < IP6OPT_RTALERT_LEN) { 875 if (hbhlen < IP6OPT_RTALERT_LEN) {
880 IP6_STATINC(IP6_STAT_TOOSMALL); 876 IP6_STATINC(IP6_STAT_TOOSMALL);
881 goto bad; 877 goto bad;
882 } 878 }
883 if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) { 879 if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) {
884 /* XXX stat */ 880 /* XXX stat */
885 icmp6_error(m, ICMP6_PARAM_PROB, 881 icmp6_error(m, ICMP6_PARAM_PROB,
886 ICMP6_PARAMPROB_HEADER, 882 ICMP6_PARAMPROB_HEADER,
887 erroff + opt + 1 - opthead); 883 erroff + opt + 1 - opthead);
888 return (-1); 884 return (-1);
889 } 885 }
890 optlen = IP6OPT_RTALERT_LEN; 886 optlen = IP6OPT_RTALERT_LEN;
891 memcpy((void *)&rtalert_val, (void *)(opt + 2), 2); 887 memcpy((void *)&rtalert_val, (void *)(opt + 2), 2);
892 *rtalertp = ntohs(rtalert_val); 888 *rtalertp = ntohs(rtalert_val);
893 break; 889 break;
894 case IP6OPT_JUMBO: 890 case IP6OPT_JUMBO:
895 /* XXX may need check for alignment */ 891 /* XXX may need check for alignment */
896 if (hbhlen < IP6OPT_JUMBO_LEN) { 892 if (hbhlen < IP6OPT_JUMBO_LEN) {
897 IP6_STATINC(IP6_STAT_TOOSMALL); 893 IP6_STATINC(IP6_STAT_TOOSMALL);
898 goto bad; 894 goto bad;
899 } 895 }
900 if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) { 896 if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) {
901 /* XXX stat */ 897 /* XXX stat */
902 icmp6_error(m, ICMP6_PARAM_PROB, 898 icmp6_error(m, ICMP6_PARAM_PROB,
903 ICMP6_PARAMPROB_HEADER, 899 ICMP6_PARAMPROB_HEADER,
904 erroff + opt + 1 - opthead); 900 erroff + opt + 1 - opthead);
905 return (-1); 901 return (-1);
906 } 902 }
907 optlen = IP6OPT_JUMBO_LEN; 903 optlen = IP6OPT_JUMBO_LEN;
908 904
909 /* 905 /*
910 * IPv6 packets that have non 0 payload length 906 * IPv6 packets that have non 0 payload length
911 * must not contain a jumbo payload option. 907 * must not contain a jumbo payload option.
912 */ 908 */
913 ip6 = mtod(m, struct ip6_hdr *); 909 ip6 = mtod(m, struct ip6_hdr *);
914 if (ip6->ip6_plen) { 910 if (ip6->ip6_plen) {
915 IP6_STATINC(IP6_STAT_BADOPTIONS); 911 IP6_STATINC(IP6_STAT_BADOPTIONS);
916 icmp6_error(m, ICMP6_PARAM_PROB, 912 icmp6_error(m, ICMP6_PARAM_PROB,
917 ICMP6_PARAMPROB_HEADER, 913 ICMP6_PARAMPROB_HEADER,
918 erroff + opt - opthead); 914 erroff + opt - opthead);
919 return (-1); 915 return (-1);
920 } 916 }
921 917
922 /* 918 /*
923 * We may see jumbolen in unaligned location, so 919 * We may see jumbolen in unaligned location, so
924 * we'd need to perform bcopy(). 920 * we'd need to perform bcopy().
925 */ 921 */
926 memcpy(&jumboplen, opt + 2, sizeof(jumboplen)); 922 memcpy(&jumboplen, opt + 2, sizeof(jumboplen));
927 jumboplen = (u_int32_t)htonl(jumboplen); 923 jumboplen = (u_int32_t)htonl(jumboplen);
928 924
929#if 1 925#if 1
930 /* 926 /*
931 * if there are multiple jumbo payload options, 927 * if there are multiple jumbo payload options,
932 * *plenp will be non-zero and the packet will be 928 * *plenp will be non-zero and the packet will be
933 * rejected. 929 * rejected.
934 * the behavior may need some debate in ipngwg - 930 * the behavior may need some debate in ipngwg -
935 * multiple options does not make sense, however, 931 * multiple options does not make sense, however,
936 * there's no explicit mention in specification. 932 * there's no explicit mention in specification.
937 */ 933 */
938 if (*plenp != 0) { 934 if (*plenp != 0) {
939 IP6_STATINC(IP6_STAT_BADOPTIONS); 935 IP6_STATINC(IP6_STAT_BADOPTIONS);
940 icmp6_error(m, ICMP6_PARAM_PROB, 936 icmp6_error(m, ICMP6_PARAM_PROB,
941 ICMP6_PARAMPROB_HEADER, 937 ICMP6_PARAMPROB_HEADER,
942 erroff + opt + 2 - opthead); 938 erroff + opt + 2 - opthead);
943 return (-1); 939 return (-1);
944 } 940 }
945#endif 941#endif
946 942
947 /* 943 /*
948 * jumbo payload length must be larger than 65535. 944 * jumbo payload length must be larger than 65535.
949 */ 945 */
950 if (jumboplen <= IPV6_MAXPACKET) { 946 if (jumboplen <= IPV6_MAXPACKET) {
951 IP6_STATINC(IP6_STAT_BADOPTIONS); 947 IP6_STATINC(IP6_STAT_BADOPTIONS);
952 icmp6_error(m, ICMP6_PARAM_PROB, 948 icmp6_error(m, ICMP6_PARAM_PROB,
953 ICMP6_PARAMPROB_HEADER, 949 ICMP6_PARAMPROB_HEADER,
954 erroff + opt + 2 - opthead); 950 erroff + opt + 2 - opthead);
955 return (-1); 951 return (-1);
956 } 952 }
957 *plenp = jumboplen; 953 *plenp = jumboplen;
958 954
959 break; 955 break;
960 default: /* unknown option */ 956 default: /* unknown option */
961 if (hbhlen < IP6OPT_MINLEN) { 957 if (hbhlen < IP6OPT_MINLEN) {
962 IP6_STATINC(IP6_STAT_TOOSMALL); 958 IP6_STATINC(IP6_STAT_TOOSMALL);
963 goto bad; 959 goto bad;
964 } 960 }
965 optlen = ip6_unknown_opt(opt, m, 961 optlen = ip6_unknown_opt(opt, m,
966 erroff + opt - opthead); 962 erroff + opt - opthead);
967 if (optlen == -1) 963 if (optlen == -1)
968 return (-1); 964 return (-1);
969 optlen += 2; 965 optlen += 2;
970 break; 966 break;
971 } 967 }
972 } 968 }
973 969
974 return (0); 970 return (0);
975 971
976 bad: 972 bad:
977 m_freem(m); 973 m_freem(m);
978 return (-1); 974 return (-1);
979} 975}
980 976
981/* 977/*
982 * Unknown option processing. 978 * Unknown option processing.
983 * The third argument `off' is the offset from the IPv6 header to the option, 979 * The third argument `off' is the offset from the IPv6 header to the option,
984 * which is necessary if the IPv6 header the and option header and IPv6 header 980 * which is necessary if the IPv6 header the and option header and IPv6 header
985 * is not continuous in order to return an ICMPv6 error. 981 * is not continuous in order to return an ICMPv6 error.
986 */ 982 */
987int 983int
988ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off) 984ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off)
989{ 985{
990 struct ip6_hdr *ip6; 986 struct ip6_hdr *ip6;
991 987
992 switch (IP6OPT_TYPE(*optp)) { 988 switch (IP6OPT_TYPE(*optp)) {
993 case IP6OPT_TYPE_SKIP: /* ignore the option */ 989 case IP6OPT_TYPE_SKIP: /* ignore the option */
994 return ((int)*(optp + 1)); 990 return ((int)*(optp + 1));
995 case IP6OPT_TYPE_DISCARD: /* silently discard */ 991 case IP6OPT_TYPE_DISCARD: /* silently discard */
996 m_freem(m); 992 m_freem(m);
997 return (-1); 993 return (-1);
998 case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */ 994 case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */
999 IP6_STATINC(IP6_STAT_BADOPTIONS); 995 IP6_STATINC(IP6_STAT_BADOPTIONS);
1000 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); 996 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off);
1001 return (-1); 997 return (-1);
1002 case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */ 998 case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */
1003 IP6_STATINC(IP6_STAT_BADOPTIONS); 999 IP6_STATINC(IP6_STAT_BADOPTIONS);
1004 ip6 = mtod(m, struct ip6_hdr *); 1000 ip6 = mtod(m, struct ip6_hdr *);
1005 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || 1001 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
1006 (m->m_flags & (M_BCAST|M_MCAST))) 1002 (m->m_flags & (M_BCAST|M_MCAST)))
1007 m_freem(m); 1003 m_freem(m);
1008 else 1004 else
1009 icmp6_error(m, ICMP6_PARAM_PROB, 1005 icmp6_error(m, ICMP6_PARAM_PROB,
1010 ICMP6_PARAMPROB_OPTION, off); 1006 ICMP6_PARAMPROB_OPTION, off);
1011 return (-1); 1007 return (-1);
1012 } 1008 }
1013 1009
1014 m_freem(m); /* XXX: NOTREACHED */ 1010 m_freem(m); /* XXX: NOTREACHED */
1015 return (-1); 1011 return (-1);
1016} 1012}
1017 1013
1018/* 1014/*
1019 * Create the "control" list for this pcb. 1015 * Create the "control" list for this pcb.
1020 * 1016 *
1021 * The routine will be called from upper layer handlers like tcp6_input(). 1017 * The routine will be called from upper layer handlers like tcp6_input().
1022 * Thus the routine assumes that the caller (tcp6_input) have already 1018 * Thus the routine assumes that the caller (tcp6_input) have already
1023 * called IP6_EXTHDR_CHECK() and all the extension headers are located in the 1019 * called IP6_EXTHDR_CHECK() and all the extension headers are located in the
1024 * very first mbuf on the mbuf chain. 1020 * very first mbuf on the mbuf chain.
1025 * We may want to add some infinite loop prevention or sanity checks for safety. 1021 * We may want to add some infinite loop prevention or sanity checks for safety.
1026 * (This applies only when you are using KAME mbuf chain restriction, i.e. 1022 * (This applies only when you are using KAME mbuf chain restriction, i.e.
1027 * you are using IP6_EXTHDR_CHECK() not m_pulldown()) 1023 * you are using IP6_EXTHDR_CHECK() not m_pulldown())
1028 */ 1024 */
1029void 1025void
1030ip6_savecontrol(struct in6pcb *in6p, struct mbuf **mp,  1026ip6_savecontrol(struct in6pcb *in6p, struct mbuf **mp,
1031 struct ip6_hdr *ip6, struct mbuf *m) 1027 struct ip6_hdr *ip6, struct mbuf *m)
1032{ 1028{
1033#ifdef RFC2292 1029#ifdef RFC2292
1034#define IS2292(x, y) ((in6p->in6p_flags & IN6P_RFC2292) ? (x) : (y)) 1030#define IS2292(x, y) ((in6p->in6p_flags & IN6P_RFC2292) ? (x) : (y))
1035#else 1031#else
1036#define IS2292(x, y) (y) 1032#define IS2292(x, y) (y)
1037#endif 1033#endif
1038 1034
1039 if (in6p->in6p_socket->so_options & SO_TIMESTAMP 1035 if (in6p->in6p_socket->so_options & SO_TIMESTAMP
1040#ifdef SO_OTIMESTAMP 1036#ifdef SO_OTIMESTAMP
1041 || in6p->in6p_socket->so_options & SO_OTIMESTAMP 1037 || in6p->in6p_socket->so_options & SO_OTIMESTAMP
1042#endif 1038#endif
1043 ) { 1039 ) {
1044 struct timeval tv; 1040 struct timeval tv;
1045 1041
1046 microtime(&tv); 1042 microtime(&tv);
1047#ifdef SO_OTIMESTAMP 1043#ifdef SO_OTIMESTAMP
1048 if (in6p->in6p_socket->so_options & SO_OTIMESTAMP) { 1044 if (in6p->in6p_socket->so_options & SO_OTIMESTAMP) {
1049 struct timeval50 tv50; 1045 struct timeval50 tv50;
1050 timeval_to_timeval50(&tv, &tv50); 1046 timeval_to_timeval50(&tv, &tv50);
1051 *mp = sbcreatecontrol((void *) &tv50, sizeof(tv50), 1047 *mp = sbcreatecontrol((void *) &tv50, sizeof(tv50),
1052 SCM_OTIMESTAMP, SOL_SOCKET); 1048 SCM_OTIMESTAMP, SOL_SOCKET);
1053 } else 1049 } else
1054#endif 1050#endif
1055 *mp = sbcreatecontrol((void *) &tv, sizeof(tv), 1051 *mp = sbcreatecontrol((void *) &tv, sizeof(tv),
1056 SCM_TIMESTAMP, SOL_SOCKET); 1052 SCM_TIMESTAMP, SOL_SOCKET);
1057 if (*mp) 1053 if (*mp)
1058 mp = &(*mp)->m_next; 1054 mp = &(*mp)->m_next;
1059 } 1055 }
1060 1056
1061 /* some OSes call this logic with IPv4 packet, for SO_TIMESTAMP */ 1057 /* some OSes call this logic with IPv4 packet, for SO_TIMESTAMP */
1062 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) 1058 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION)
1063 return; 1059 return;
1064 1060
1065 /* RFC 2292 sec. 5 */ 1061 /* RFC 2292 sec. 5 */
1066 if ((in6p->in6p_flags & IN6P_PKTINFO) != 0) { 1062 if ((in6p->in6p_flags & IN6P_PKTINFO) != 0) {
1067 struct in6_pktinfo pi6; 1063 struct in6_pktinfo pi6;
1068 1064
1069 memcpy(&pi6.ipi6_addr, &ip6->ip6_dst, sizeof(struct in6_addr)); 1065 memcpy(&pi6.ipi6_addr, &ip6->ip6_dst, sizeof(struct in6_addr));
1070 in6_clearscope(&pi6.ipi6_addr); /* XXX */ 1066 in6_clearscope(&pi6.ipi6_addr); /* XXX */
1071 pi6.ipi6_ifindex = m->m_pkthdr.rcvif ? 1067 pi6.ipi6_ifindex = m->m_pkthdr.rcvif ?
1072 m->m_pkthdr.rcvif->if_index : 0; 1068 m->m_pkthdr.rcvif->if_index : 0;
1073 *mp = sbcreatecontrol((void *) &pi6, 1069 *mp = sbcreatecontrol((void *) &pi6,
1074 sizeof(struct in6_pktinfo), 1070 sizeof(struct in6_pktinfo),
1075 IS2292(IPV6_2292PKTINFO, IPV6_PKTINFO), IPPROTO_IPV6); 1071 IS2292(IPV6_2292PKTINFO, IPV6_PKTINFO), IPPROTO_IPV6);
1076 if (*mp) 1072 if (*mp)
1077 mp = &(*mp)->m_next; 1073 mp = &(*mp)->m_next;
1078 } 1074 }
1079 1075
1080 if (in6p->in6p_flags & IN6P_HOPLIMIT) { 1076 if (in6p->in6p_flags & IN6P_HOPLIMIT) {
1081 int hlim = ip6->ip6_hlim & 0xff; 1077 int hlim = ip6->ip6_hlim & 0xff;
1082 1078
1083 *mp = sbcreatecontrol((void *) &hlim, sizeof(int), 1079 *mp = sbcreatecontrol((void *) &hlim, sizeof(int),
1084 IS2292(IPV6_2292HOPLIMIT, IPV6_HOPLIMIT), IPPROTO_IPV6); 1080 IS2292(IPV6_2292HOPLIMIT, IPV6_HOPLIMIT), IPPROTO_IPV6);
1085 if (*mp) 1081 if (*mp)
1086 mp = &(*mp)->m_next; 1082 mp = &(*mp)->m_next;
1087 } 1083 }
1088 1084
1089 if ((in6p->in6p_flags & IN6P_TCLASS) != 0) { 1085 if ((in6p->in6p_flags & IN6P_TCLASS) != 0) {
1090 u_int32_t flowinfo; 1086 u_int32_t flowinfo;
1091 int tclass; 1087 int tclass;
1092 1088
1093 flowinfo = (u_int32_t)ntohl(ip6->ip6_flow & IPV6_FLOWINFO_MASK); 1089 flowinfo = (u_int32_t)ntohl(ip6->ip6_flow & IPV6_FLOWINFO_MASK);
1094 flowinfo >>= 20; 1090 flowinfo >>= 20;
1095 1091
1096 tclass = flowinfo & 0xff; 1092 tclass = flowinfo & 0xff;
1097 *mp = sbcreatecontrol((void *)&tclass, sizeof(tclass), 1093 *mp = sbcreatecontrol((void *)&tclass, sizeof(tclass),
1098 IPV6_TCLASS, IPPROTO_IPV6); 1094 IPV6_TCLASS, IPPROTO_IPV6);
1099 1095
1100 if (*mp) 1096 if (*mp)
1101 mp = &(*mp)->m_next; 1097 mp = &(*mp)->m_next;
1102 } 1098 }
1103 1099
1104 /* 1100 /*
1105 * IPV6_HOPOPTS socket option. Recall that we required super-user 1101 * IPV6_HOPOPTS socket option. Recall that we required super-user
1106 * privilege for the option (see ip6_ctloutput), but it might be too 1102 * privilege for the option (see ip6_ctloutput), but it might be too
1107 * strict, since there might be some hop-by-hop options which can be 1103 * strict, since there might be some hop-by-hop options which can be
1108 * returned to normal user. 1104 * returned to normal user.
1109 * See also RFC3542 section 8 (or RFC2292 section 6). 1105 * See also RFC3542 section 8 (or RFC2292 section 6).
1110 */ 1106 */
1111 if ((in6p->in6p_flags & IN6P_HOPOPTS) != 0) { 1107 if ((in6p->in6p_flags & IN6P_HOPOPTS) != 0) {
1112 /* 1108 /*
1113 * Check if a hop-by-hop options header is contatined in the 1109 * Check if a hop-by-hop options header is contatined in the
1114 * received packet, and if so, store the options as ancillary 1110 * received packet, and if so, store the options as ancillary
1115 * data. Note that a hop-by-hop options header must be 1111 * data. Note that a hop-by-hop options header must be
1116 * just after the IPv6 header, which fact is assured through 1112 * just after the IPv6 header, which fact is assured through
1117 * the IPv6 input processing. 1113 * the IPv6 input processing.
1118 */ 1114 */
1119 struct ip6_hdr *xip6 = mtod(m, struct ip6_hdr *); 1115 struct ip6_hdr *xip6 = mtod(m, struct ip6_hdr *);
1120 if (xip6->ip6_nxt == IPPROTO_HOPOPTS) { 1116 if (xip6->ip6_nxt == IPPROTO_HOPOPTS) {
1121 struct ip6_hbh *hbh; 1117 struct ip6_hbh *hbh;
1122 int hbhlen; 1118 int hbhlen;
1123 struct mbuf *ext; 1119 struct mbuf *ext;
1124 1120
1125 ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr), 1121 ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr),
1126 xip6->ip6_nxt); 1122 xip6->ip6_nxt);
1127 if (ext == NULL) { 1123 if (ext == NULL) {
1128 IP6_STATINC(IP6_STAT_TOOSHORT); 1124 IP6_STATINC(IP6_STAT_TOOSHORT);
1129 return; 1125 return;
1130 } 1126 }
1131 hbh = mtod(ext, struct ip6_hbh *); 1127 hbh = mtod(ext, struct ip6_hbh *);
1132 hbhlen = (hbh->ip6h_len + 1) << 3; 1128 hbhlen = (hbh->ip6h_len + 1) << 3;
1133 if (hbhlen != ext->m_len) { 1129 if (hbhlen != ext->m_len) {
1134 m_freem(ext); 1130 m_freem(ext);
1135 IP6_STATINC(IP6_STAT_TOOSHORT); 1131 IP6_STATINC(IP6_STAT_TOOSHORT);
1136 return; 1132 return;
1137 } 1133 }
1138 1134
1139 /* 1135 /*
1140 * XXX: We copy whole the header even if a jumbo 1136 * XXX: We copy whole the header even if a jumbo
1141 * payload option is included, which option is to 1137 * payload option is included, which option is to
1142 * be removed before returning in the RFC 2292. 1138 * be removed before returning in the RFC 2292.
1143 * Note: this constraint is removed in RFC3542. 1139 * Note: this constraint is removed in RFC3542.
1144 */ 1140 */
1145 *mp = sbcreatecontrol((void *)hbh, hbhlen, 1141 *mp = sbcreatecontrol((void *)hbh, hbhlen,
1146 IS2292(IPV6_2292HOPOPTS, IPV6_HOPOPTS), 1142 IS2292(IPV6_2292HOPOPTS, IPV6_HOPOPTS),
1147 IPPROTO_IPV6); 1143 IPPROTO_IPV6);
1148 if (*mp) 1144 if (*mp)
1149 mp = &(*mp)->m_next; 1145 mp = &(*mp)->m_next;
1150 m_freem(ext); 1146 m_freem(ext);
1151 } 1147 }
1152 } 1148 }
1153 1149
1154 /* IPV6_DSTOPTS and IPV6_RTHDR socket options */ 1150 /* IPV6_DSTOPTS and IPV6_RTHDR socket options */
1155 if (in6p->in6p_flags & (IN6P_DSTOPTS | IN6P_RTHDR)) { 1151 if (in6p->in6p_flags & (IN6P_DSTOPTS | IN6P_RTHDR)) {
1156 struct ip6_hdr *xip6 = mtod(m, struct ip6_hdr *); 1152 struct ip6_hdr *xip6 = mtod(m, struct ip6_hdr *);
1157 int nxt = xip6->ip6_nxt, off = sizeof(struct ip6_hdr); 1153 int nxt = xip6->ip6_nxt, off = sizeof(struct ip6_hdr);
1158 1154
1159 /* 1155 /*
1160 * Search for destination options headers or routing 1156 * Search for destination options headers or routing
1161 * header(s) through the header chain, and stores each 1157 * header(s) through the header chain, and stores each
1162 * header as ancillary data. 1158 * header as ancillary data.
1163 * Note that the order of the headers remains in 1159 * Note that the order of the headers remains in
1164 * the chain of ancillary data. 1160 * the chain of ancillary data.
1165 */ 1161 */
1166 for (;;) { /* is explicit loop prevention necessary? */ 1162 for (;;) { /* is explicit loop prevention necessary? */
1167 struct ip6_ext *ip6e = NULL; 1163 struct ip6_ext *ip6e = NULL;
1168 int elen; 1164 int elen;
1169 struct mbuf *ext = NULL; 1165 struct mbuf *ext = NULL;
1170 1166
1171 /* 1167 /*
1172 * if it is not an extension header, don't try to 1168 * if it is not an extension header, don't try to
1173 * pull it from the chain. 1169 * pull it from the chain.
1174 */ 1170 */
1175 switch (nxt) { 1171 switch (nxt) {
1176 case IPPROTO_DSTOPTS: 1172 case IPPROTO_DSTOPTS:
1177 case IPPROTO_ROUTING: 1173 case IPPROTO_ROUTING:
1178 case IPPROTO_HOPOPTS: 1174 case IPPROTO_HOPOPTS:
1179 case IPPROTO_AH: /* is it possible? */ 1175 case IPPROTO_AH: /* is it possible? */
1180 break; 1176 break;
1181 default: 1177 default:
1182 goto loopend; 1178 goto loopend;
1183 } 1179 }
1184 1180
1185 ext = ip6_pullexthdr(m, off, nxt); 1181 ext = ip6_pullexthdr(m, off, nxt);
1186 if (ext == NULL) { 1182 if (ext == NULL) {
1187 IP6_STATINC(IP6_STAT_TOOSHORT); 1183 IP6_STATINC(IP6_STAT_TOOSHORT);
1188 return; 1184 return;
1189 } 1185 }
1190 ip6e = mtod(ext, struct ip6_ext *); 1186 ip6e = mtod(ext, struct ip6_ext *);
1191 if (nxt == IPPROTO_AH) 1187 if (nxt == IPPROTO_AH)
1192 elen = (ip6e->ip6e_len + 2) << 2; 1188 elen = (ip6e->ip6e_len + 2) << 2;
1193 else 1189 else
1194 elen = (ip6e->ip6e_len + 1) << 3; 1190 elen = (ip6e->ip6e_len + 1) << 3;
1195 if (elen != ext->m_len) { 1191 if (elen != ext->m_len) {
1196 m_freem(ext); 1192 m_freem(ext);
1197 IP6_STATINC(IP6_STAT_TOOSHORT); 1193 IP6_STATINC(IP6_STAT_TOOSHORT);
1198 return; 1194 return;
1199 } 1195 }
1200 KASSERT(IP6_HDR_ALIGNED_P(ip6e)); 1196 KASSERT(IP6_HDR_ALIGNED_P(ip6e));
1201 1197
1202 switch (nxt) { 1198 switch (nxt) {
1203 case IPPROTO_DSTOPTS: 1199 case IPPROTO_DSTOPTS:
1204 if (!(in6p->in6p_flags & IN6P_DSTOPTS)) 1200 if (!(in6p->in6p_flags & IN6P_DSTOPTS))

cvs diff -r1.185 -r1.186 src/sys/netinet6/nd6.c (switch to unified diff)

--- src/sys/netinet6/nd6.c 2016/02/04 02:48:37 1.185
+++ src/sys/netinet6/nd6.c 2016/04/01 05:11:38 1.186
@@ -1,1594 +1,1588 @@ @@ -1,1594 +1,1588 @@
1/* $NetBSD: nd6.c,v 1.185 2016/02/04 02:48:37 riastradh Exp $ */ 1/* $NetBSD: nd6.c,v 1.186 2016/04/01 05:11:38 ozaki-r Exp $ */
2/* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */ 2/* $KAME: nd6.c,v 1.279 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#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.185 2016/02/04 02:48:37 riastradh Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.186 2016/04/01 05:11:38 ozaki-r Exp $");
35 35
36#ifdef _KERNEL_OPT 36#ifdef _KERNEL_OPT
37#include "opt_net_mpsafe.h" 37#include "opt_net_mpsafe.h"
38#endif 38#endif
39 39
40#include "bridge.h" 40#include "bridge.h"
41#include "carp.h" 41#include "carp.h"
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/callout.h> 45#include <sys/callout.h>
46#include <sys/malloc.h> 46#include <sys/malloc.h>
47#include <sys/mbuf.h> 47#include <sys/mbuf.h>
48#include <sys/socket.h> 48#include <sys/socket.h>
49#include <sys/socketvar.h> 49#include <sys/socketvar.h>
50#include <sys/sockio.h> 50#include <sys/sockio.h>
51#include <sys/time.h> 51#include <sys/time.h>
52#include <sys/kernel.h> 52#include <sys/kernel.h>
53#include <sys/protosw.h> 53#include <sys/protosw.h>
54#include <sys/errno.h> 54#include <sys/errno.h>
55#include <sys/ioctl.h> 55#include <sys/ioctl.h>
56#include <sys/syslog.h> 56#include <sys/syslog.h>
57#include <sys/queue.h> 57#include <sys/queue.h>
58#include <sys/cprng.h> 58#include <sys/cprng.h>
59 59
60#include <net/if.h> 60#include <net/if.h>
61#include <net/if_dl.h> 61#include <net/if_dl.h>
62#include <net/if_llatbl.h> 62#include <net/if_llatbl.h>
63#include <net/if_types.h> 63#include <net/if_types.h>
64#include <net/route.h> 64#include <net/route.h>
65#include <net/if_ether.h> 65#include <net/if_ether.h>
66#include <net/if_fddi.h> 66#include <net/if_fddi.h>
67#include <net/if_arc.h> 67#include <net/if_arc.h>
68 68
69#include <netinet/in.h> 69#include <netinet/in.h>
70#include <netinet6/in6_var.h> 70#include <netinet6/in6_var.h>
71#include <netinet/ip6.h> 71#include <netinet/ip6.h>
72#include <netinet6/ip6_var.h> 72#include <netinet6/ip6_var.h>
73#include <netinet6/scope6_var.h> 73#include <netinet6/scope6_var.h>
74#include <netinet6/nd6.h> 74#include <netinet6/nd6.h>
75#include <netinet6/in6_ifattach.h> 75#include <netinet6/in6_ifattach.h>
76#include <netinet/icmp6.h> 76#include <netinet/icmp6.h>
77#include <netinet6/icmp6_private.h> 77#include <netinet6/icmp6_private.h>
78 78
79#include <net/net_osdep.h> 79#include <net/net_osdep.h>
80 80
81#define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */ 81#define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */
82#define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */ 82#define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */
83 83
84/* timer values */ 84/* timer values */
85int nd6_prune = 1; /* walk list every 1 seconds */ 85int nd6_prune = 1; /* walk list every 1 seconds */
86int nd6_delay = 5; /* delay first probe time 5 second */ 86int nd6_delay = 5; /* delay first probe time 5 second */
87int nd6_umaxtries = 3; /* maximum unicast query */ 87int nd6_umaxtries = 3; /* maximum unicast query */
88int nd6_mmaxtries = 3; /* maximum multicast query */ 88int nd6_mmaxtries = 3; /* maximum multicast query */
89int nd6_useloopback = 1; /* use loopback interface for local traffic */ 89int nd6_useloopback = 1; /* use loopback interface for local traffic */
90int nd6_gctimer = (60 * 60 * 24); /* 1 day: garbage collection timer */ 90int nd6_gctimer = (60 * 60 * 24); /* 1 day: garbage collection timer */
91 91
92/* preventing too many loops in ND option parsing */ 92/* preventing too many loops in ND option parsing */
93int nd6_maxndopt = 10; /* max # of ND options allowed */ 93int nd6_maxndopt = 10; /* max # of ND options allowed */
94 94
95int nd6_maxnudhint = 0; /* max # of subsequent upper layer hints */ 95int nd6_maxnudhint = 0; /* max # of subsequent upper layer hints */
96 96
97int nd6_maxqueuelen = 1; /* max # of packets cached in unresolved ND entries */ 97int nd6_maxqueuelen = 1; /* max # of packets cached in unresolved ND entries */
98 98
99#ifdef ND6_DEBUG 99#ifdef ND6_DEBUG
100int nd6_debug = 1; 100int nd6_debug = 1;
101#else 101#else
102int nd6_debug = 0; 102int nd6_debug = 0;
103#endif 103#endif
104 104
105/* for debugging? */ 105/* for debugging? */
106static int nd6_inuse, nd6_allocated; 106static int nd6_inuse, nd6_allocated;
107 107
108struct nd_drhead nd_defrouter; 108struct nd_drhead nd_defrouter;
109struct nd_prhead nd_prefix = { 0 }; 109struct nd_prhead nd_prefix = { 0 };
110 110
111int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL; 111int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
112static const struct sockaddr_in6 all1_sa = { 112static const struct sockaddr_in6 all1_sa = {
113 .sin6_family = AF_INET6 113 .sin6_family = AF_INET6
114 , .sin6_len = sizeof(struct sockaddr_in6) 114 , .sin6_len = sizeof(struct sockaddr_in6)
115 , .sin6_addr = {.s6_addr = {0xff, 0xff, 0xff, 0xff, 115 , .sin6_addr = {.s6_addr = {0xff, 0xff, 0xff, 0xff,
116 0xff, 0xff, 0xff, 0xff, 116 0xff, 0xff, 0xff, 0xff,
117 0xff, 0xff, 0xff, 0xff, 117 0xff, 0xff, 0xff, 0xff,
118 0xff, 0xff, 0xff, 0xff}} 118 0xff, 0xff, 0xff, 0xff}}
119}; 119};
120 120
121static void nd6_setmtu0(struct ifnet *, struct nd_ifinfo *); 121static void nd6_setmtu0(struct ifnet *, struct nd_ifinfo *);
122static void nd6_slowtimo(void *); 122static void nd6_slowtimo(void *);
123static int regen_tmpaddr(struct in6_ifaddr *); 123static int regen_tmpaddr(struct in6_ifaddr *);
124static void nd6_free(struct rtentry *, struct llentry *, int); 124static void nd6_free(struct rtentry *, struct llentry *, int);
125static void nd6_llinfo_timer(void *); 125static void nd6_llinfo_timer(void *);
 126static void nd6_timer(void *);
126static void clear_llinfo_pqueue(struct llentry *); 127static void clear_llinfo_pqueue(struct llentry *);
127 128
128callout_t nd6_slowtimo_ch; 129static callout_t nd6_slowtimo_ch;
129callout_t nd6_timer_ch; 130static callout_t nd6_timer_ch;
130 131
131static int fill_drlist(void *, size_t *, size_t); 132static int fill_drlist(void *, size_t *, size_t);
132static int fill_prlist(void *, size_t *, size_t); 133static int fill_prlist(void *, size_t *, size_t);
133 134
134MALLOC_DEFINE(M_IP6NDP, "NDP", "IPv6 Neighbour Discovery"); 135MALLOC_DEFINE(M_IP6NDP, "NDP", "IPv6 Neighbour Discovery");
135 136
136void 137void
137nd6_init(void) 138nd6_init(void)
138{ 139{
139 static int nd6_init_done = 0; 
140 
141 if (nd6_init_done) { 
142 log(LOG_NOTICE, "nd6_init called more than once(ignored)\n"); 
143 return; 
144 } 
145 140
146 /* initialization of the default router list */ 141 /* initialization of the default router list */
147 TAILQ_INIT(&nd_defrouter); 142 TAILQ_INIT(&nd_defrouter);
148 143
149 nd6_init_done = 1; 
150 
151 callout_init(&nd6_slowtimo_ch, CALLOUT_MPSAFE); 144 callout_init(&nd6_slowtimo_ch, CALLOUT_MPSAFE);
152 callout_init(&nd6_timer_ch, CALLOUT_MPSAFE); 145 callout_init(&nd6_timer_ch, CALLOUT_MPSAFE);
153 146
154 /* start timer */ 147 /* start timer */
155 callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, 148 callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
156 nd6_slowtimo, NULL); 149 nd6_slowtimo, NULL);
 150 callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL);
157} 151}
158 152
159struct nd_ifinfo * 153struct nd_ifinfo *
160nd6_ifattach(struct ifnet *ifp) 154nd6_ifattach(struct ifnet *ifp)
161{ 155{
162 struct nd_ifinfo *nd; 156 struct nd_ifinfo *nd;
163 157
164 nd = (struct nd_ifinfo *)malloc(sizeof(*nd), M_IP6NDP, M_WAITOK|M_ZERO); 158 nd = (struct nd_ifinfo *)malloc(sizeof(*nd), M_IP6NDP, M_WAITOK|M_ZERO);
165 159
166 nd->initialized = 1; 160 nd->initialized = 1;
167 161
168 nd->chlim = IPV6_DEFHLIM; 162 nd->chlim = IPV6_DEFHLIM;
169 nd->basereachable = REACHABLE_TIME; 163 nd->basereachable = REACHABLE_TIME;
170 nd->reachable = ND_COMPUTE_RTIME(nd->basereachable); 164 nd->reachable = ND_COMPUTE_RTIME(nd->basereachable);
171 nd->retrans = RETRANS_TIMER; 165 nd->retrans = RETRANS_TIMER;
172 166
173 nd->flags = ND6_IFF_PERFORMNUD | ND6_IFF_ACCEPT_RTADV; 167 nd->flags = ND6_IFF_PERFORMNUD | ND6_IFF_ACCEPT_RTADV;
174 168
175 /* A loopback interface always has ND6_IFF_AUTO_LINKLOCAL. 169 /* A loopback interface always has ND6_IFF_AUTO_LINKLOCAL.
176 * A bridge interface should not have ND6_IFF_AUTO_LINKLOCAL 170 * A bridge interface should not have ND6_IFF_AUTO_LINKLOCAL
177 * because one of its members should. */ 171 * because one of its members should. */
178 if ((ip6_auto_linklocal && ifp->if_type != IFT_BRIDGE) || 172 if ((ip6_auto_linklocal && ifp->if_type != IFT_BRIDGE) ||
179 (ifp->if_flags & IFF_LOOPBACK)) 173 (ifp->if_flags & IFF_LOOPBACK))
180 nd->flags |= ND6_IFF_AUTO_LINKLOCAL; 174 nd->flags |= ND6_IFF_AUTO_LINKLOCAL;
181 175
182 /* A loopback interface does not need to accept RTADV. 176 /* A loopback interface does not need to accept RTADV.
183 * A bridge interface should not accept RTADV 177 * A bridge interface should not accept RTADV
184 * because one of its members should. */ 178 * because one of its members should. */
185 if (ip6_accept_rtadv && 179 if (ip6_accept_rtadv &&
186 !(ifp->if_flags & IFF_LOOPBACK) && 180 !(ifp->if_flags & IFF_LOOPBACK) &&
187 !(ifp->if_type != IFT_BRIDGE)) 181 !(ifp->if_type != IFT_BRIDGE))
188 nd->flags |= ND6_IFF_ACCEPT_RTADV; 182 nd->flags |= ND6_IFF_ACCEPT_RTADV;
189 183
190 /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */ 184 /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */
191 nd6_setmtu0(ifp, nd); 185 nd6_setmtu0(ifp, nd);
192 186
193 return nd; 187 return nd;
194} 188}
195 189
196void 190void
197nd6_ifdetach(struct ifnet *ifp, struct in6_ifextra *ext) 191nd6_ifdetach(struct ifnet *ifp, struct in6_ifextra *ext)
198{ 192{
199 193
200 nd6_purge(ifp, ext); 194 nd6_purge(ifp, ext);
201 free(ext->nd_ifinfo, M_IP6NDP); 195 free(ext->nd_ifinfo, M_IP6NDP);
202} 196}
203 197
204void 198void
205nd6_setmtu(struct ifnet *ifp) 199nd6_setmtu(struct ifnet *ifp)
206{ 200{
207 nd6_setmtu0(ifp, ND_IFINFO(ifp)); 201 nd6_setmtu0(ifp, ND_IFINFO(ifp));
208} 202}
209 203
210void 204void
211nd6_setmtu0(struct ifnet *ifp, struct nd_ifinfo *ndi) 205nd6_setmtu0(struct ifnet *ifp, struct nd_ifinfo *ndi)
212{ 206{
213 u_int32_t omaxmtu; 207 u_int32_t omaxmtu;
214 208
215 omaxmtu = ndi->maxmtu; 209 omaxmtu = ndi->maxmtu;
216 210
217 switch (ifp->if_type) { 211 switch (ifp->if_type) {
218 case IFT_ARCNET: 212 case IFT_ARCNET:
219 ndi->maxmtu = MIN(ARC_PHDS_MAXMTU, ifp->if_mtu); /* RFC2497 */ 213 ndi->maxmtu = MIN(ARC_PHDS_MAXMTU, ifp->if_mtu); /* RFC2497 */
220 break; 214 break;
221 case IFT_FDDI: 215 case IFT_FDDI:
222 ndi->maxmtu = MIN(FDDIIPMTU, ifp->if_mtu); 216 ndi->maxmtu = MIN(FDDIIPMTU, ifp->if_mtu);
223 break; 217 break;
224 default: 218 default:
225 ndi->maxmtu = ifp->if_mtu; 219 ndi->maxmtu = ifp->if_mtu;
226 break; 220 break;
227 } 221 }
228 222
229 /* 223 /*
230 * Decreasing the interface MTU under IPV6 minimum MTU may cause 224 * Decreasing the interface MTU under IPV6 minimum MTU may cause
231 * undesirable situation. We thus notify the operator of the change 225 * undesirable situation. We thus notify the operator of the change
232 * explicitly. The check for omaxmtu is necessary to restrict the 226 * explicitly. The check for omaxmtu is necessary to restrict the
233 * log to the case of changing the MTU, not initializing it. 227 * log to the case of changing the MTU, not initializing it.
234 */ 228 */
235 if (omaxmtu >= IPV6_MMTU && ndi->maxmtu < IPV6_MMTU) { 229 if (omaxmtu >= IPV6_MMTU && ndi->maxmtu < IPV6_MMTU) {
236 log(LOG_NOTICE, "nd6_setmtu0: new link MTU on %s (%lu) is too" 230 log(LOG_NOTICE, "nd6_setmtu0: new link MTU on %s (%lu) is too"
237 " small for IPv6 which needs %lu\n", 231 " small for IPv6 which needs %lu\n",
238 if_name(ifp), (unsigned long)ndi->maxmtu, (unsigned long) 232 if_name(ifp), (unsigned long)ndi->maxmtu, (unsigned long)
239 IPV6_MMTU); 233 IPV6_MMTU);
240 } 234 }
241 235
242 if (ndi->maxmtu > in6_maxmtu) 236 if (ndi->maxmtu > in6_maxmtu)
243 in6_setmaxmtu(); /* check all interfaces just in case */ 237 in6_setmaxmtu(); /* check all interfaces just in case */
244} 238}
245 239
246void 240void
247nd6_option_init(void *opt, int icmp6len, union nd_opts *ndopts) 241nd6_option_init(void *opt, int icmp6len, union nd_opts *ndopts)
248{ 242{
249 243
250 memset(ndopts, 0, sizeof(*ndopts)); 244 memset(ndopts, 0, sizeof(*ndopts));
251 ndopts->nd_opts_search = (struct nd_opt_hdr *)opt; 245 ndopts->nd_opts_search = (struct nd_opt_hdr *)opt;
252 ndopts->nd_opts_last 246 ndopts->nd_opts_last
253 = (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len); 247 = (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len);
254 248
255 if (icmp6len == 0) { 249 if (icmp6len == 0) {
256 ndopts->nd_opts_done = 1; 250 ndopts->nd_opts_done = 1;
257 ndopts->nd_opts_search = NULL; 251 ndopts->nd_opts_search = NULL;
258 } 252 }
259} 253}
260 254
261/* 255/*
262 * Take one ND option. 256 * Take one ND option.
263 */ 257 */
264struct nd_opt_hdr * 258struct nd_opt_hdr *
265nd6_option(union nd_opts *ndopts) 259nd6_option(union nd_opts *ndopts)
266{ 260{
267 struct nd_opt_hdr *nd_opt; 261 struct nd_opt_hdr *nd_opt;
268 int olen; 262 int olen;
269 263
270 KASSERT(ndopts != NULL); 264 KASSERT(ndopts != NULL);
271 KASSERT(ndopts->nd_opts_last != NULL); 265 KASSERT(ndopts->nd_opts_last != NULL);
272 266
273 if (ndopts->nd_opts_search == NULL) 267 if (ndopts->nd_opts_search == NULL)
274 return NULL; 268 return NULL;
275 if (ndopts->nd_opts_done) 269 if (ndopts->nd_opts_done)
276 return NULL; 270 return NULL;
277 271
278 nd_opt = ndopts->nd_opts_search; 272 nd_opt = ndopts->nd_opts_search;
279 273
280 /* make sure nd_opt_len is inside the buffer */ 274 /* make sure nd_opt_len is inside the buffer */
281 if ((void *)&nd_opt->nd_opt_len >= (void *)ndopts->nd_opts_last) { 275 if ((void *)&nd_opt->nd_opt_len >= (void *)ndopts->nd_opts_last) {
282 memset(ndopts, 0, sizeof(*ndopts)); 276 memset(ndopts, 0, sizeof(*ndopts));
283 return NULL; 277 return NULL;
284 } 278 }
285 279
286 olen = nd_opt->nd_opt_len << 3; 280 olen = nd_opt->nd_opt_len << 3;
287 if (olen == 0) { 281 if (olen == 0) {
288 /* 282 /*
289 * Message validation requires that all included 283 * Message validation requires that all included
290 * options have a length that is greater than zero. 284 * options have a length that is greater than zero.
291 */ 285 */
292 memset(ndopts, 0, sizeof(*ndopts)); 286 memset(ndopts, 0, sizeof(*ndopts));
293 return NULL; 287 return NULL;
294 } 288 }
295 289
296 ndopts->nd_opts_search = (struct nd_opt_hdr *)((char *)nd_opt + olen); 290 ndopts->nd_opts_search = (struct nd_opt_hdr *)((char *)nd_opt + olen);
297 if (ndopts->nd_opts_search > ndopts->nd_opts_last) { 291 if (ndopts->nd_opts_search > ndopts->nd_opts_last) {
298 /* option overruns the end of buffer, invalid */ 292 /* option overruns the end of buffer, invalid */
299 memset(ndopts, 0, sizeof(*ndopts)); 293 memset(ndopts, 0, sizeof(*ndopts));
300 return NULL; 294 return NULL;
301 } else if (ndopts->nd_opts_search == ndopts->nd_opts_last) { 295 } else if (ndopts->nd_opts_search == ndopts->nd_opts_last) {
302 /* reached the end of options chain */ 296 /* reached the end of options chain */
303 ndopts->nd_opts_done = 1; 297 ndopts->nd_opts_done = 1;
304 ndopts->nd_opts_search = NULL; 298 ndopts->nd_opts_search = NULL;
305 } 299 }
306 return nd_opt; 300 return nd_opt;
307} 301}
308 302
309/* 303/*
310 * Parse multiple ND options. 304 * Parse multiple ND options.
311 * This function is much easier to use, for ND routines that do not need 305 * This function is much easier to use, for ND routines that do not need
312 * multiple options of the same type. 306 * multiple options of the same type.
313 */ 307 */
314int 308int
315nd6_options(union nd_opts *ndopts) 309nd6_options(union nd_opts *ndopts)
316{ 310{
317 struct nd_opt_hdr *nd_opt; 311 struct nd_opt_hdr *nd_opt;
318 int i = 0; 312 int i = 0;
319 313
320 KASSERT(ndopts != NULL); 314 KASSERT(ndopts != NULL);
321 KASSERT(ndopts->nd_opts_last != NULL); 315 KASSERT(ndopts->nd_opts_last != NULL);
322 316
323 if (ndopts->nd_opts_search == NULL) 317 if (ndopts->nd_opts_search == NULL)
324 return 0; 318 return 0;
325  319
326 while (1) { 320 while (1) {
327 nd_opt = nd6_option(ndopts); 321 nd_opt = nd6_option(ndopts);
328 if (nd_opt == NULL && ndopts->nd_opts_last == NULL) { 322 if (nd_opt == NULL && ndopts->nd_opts_last == NULL) {
329 /* 323 /*
330 * Message validation requires that all included 324 * Message validation requires that all included
331 * options have a length that is greater than zero. 325 * options have a length that is greater than zero.
332 */ 326 */
333 ICMP6_STATINC(ICMP6_STAT_ND_BADOPT); 327 ICMP6_STATINC(ICMP6_STAT_ND_BADOPT);
334 memset(ndopts, 0, sizeof(*ndopts)); 328 memset(ndopts, 0, sizeof(*ndopts));
335 return -1; 329 return -1;
336 } 330 }
337 331
338 if (nd_opt == NULL) 332 if (nd_opt == NULL)
339 goto skip1; 333 goto skip1;
340 334
341 switch (nd_opt->nd_opt_type) { 335 switch (nd_opt->nd_opt_type) {
342 case ND_OPT_SOURCE_LINKADDR: 336 case ND_OPT_SOURCE_LINKADDR:
343 case ND_OPT_TARGET_LINKADDR: 337 case ND_OPT_TARGET_LINKADDR:
344 case ND_OPT_MTU: 338 case ND_OPT_MTU:
345 case ND_OPT_REDIRECTED_HEADER: 339 case ND_OPT_REDIRECTED_HEADER:
346 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) { 340 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
347 nd6log((LOG_INFO, 341 nd6log((LOG_INFO,
348 "duplicated ND6 option found (type=%d)\n", 342 "duplicated ND6 option found (type=%d)\n",
349 nd_opt->nd_opt_type)); 343 nd_opt->nd_opt_type));
350 /* XXX bark? */ 344 /* XXX bark? */
351 } else { 345 } else {
352 ndopts->nd_opt_array[nd_opt->nd_opt_type] 346 ndopts->nd_opt_array[nd_opt->nd_opt_type]
353 = nd_opt; 347 = nd_opt;
354 } 348 }
355 break; 349 break;
356 case ND_OPT_PREFIX_INFORMATION: 350 case ND_OPT_PREFIX_INFORMATION:
357 if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) { 351 if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) {
358 ndopts->nd_opt_array[nd_opt->nd_opt_type] 352 ndopts->nd_opt_array[nd_opt->nd_opt_type]
359 = nd_opt; 353 = nd_opt;
360 } 354 }
361 ndopts->nd_opts_pi_end = 355 ndopts->nd_opts_pi_end =
362 (struct nd_opt_prefix_info *)nd_opt; 356 (struct nd_opt_prefix_info *)nd_opt;
363 break; 357 break;
364 default: 358 default:
365 /* 359 /*
366 * Unknown options must be silently ignored, 360 * Unknown options must be silently ignored,
367 * to accommodate future extension to the protocol. 361 * to accommodate future extension to the protocol.
368 */ 362 */
369 nd6log((LOG_DEBUG, 363 nd6log((LOG_DEBUG,
370 "nd6_options: unsupported option %d - " 364 "nd6_options: unsupported option %d - "
371 "option ignored\n", nd_opt->nd_opt_type)); 365 "option ignored\n", nd_opt->nd_opt_type));
372 } 366 }
373 367
374skip1: 368skip1:
375 i++; 369 i++;
376 if (i > nd6_maxndopt) { 370 if (i > nd6_maxndopt) {
377 ICMP6_STATINC(ICMP6_STAT_ND_TOOMANYOPT); 371 ICMP6_STATINC(ICMP6_STAT_ND_TOOMANYOPT);
378 nd6log((LOG_INFO, "too many loop in nd opt\n")); 372 nd6log((LOG_INFO, "too many loop in nd opt\n"));
379 break; 373 break;
380 } 374 }
381 375
382 if (ndopts->nd_opts_done) 376 if (ndopts->nd_opts_done)
383 break; 377 break;
384 } 378 }
385 379
386 return 0; 380 return 0;
387} 381}
388 382
389/* 383/*
390 * ND6 timer routine to handle ND6 entries 384 * ND6 timer routine to handle ND6 entries
391 */ 385 */
392void 386void
393nd6_llinfo_settimer_locked(struct llentry *ln, time_t xtick) 387nd6_llinfo_settimer_locked(struct llentry *ln, time_t xtick)
394{ 388{
395 389
396 CTASSERT(sizeof(time_t) > sizeof(int)); 390 CTASSERT(sizeof(time_t) > sizeof(int));
397 LLE_WLOCK_ASSERT(ln); 391 LLE_WLOCK_ASSERT(ln);
398 392
399 if (xtick < 0) { 393 if (xtick < 0) {
400 ln->ln_expire = 0; 394 ln->ln_expire = 0;
401 ln->ln_ntick = 0; 395 ln->ln_ntick = 0;
402 callout_halt(&ln->ln_timer_ch, &ln->lle_lock); 396 callout_halt(&ln->ln_timer_ch, &ln->lle_lock);
403 } else { 397 } else {
404 ln->ln_expire = time_uptime + xtick / hz; 398 ln->ln_expire = time_uptime + xtick / hz;
405 LLE_ADDREF(ln); 399 LLE_ADDREF(ln);
406 if (xtick > INT_MAX) { 400 if (xtick > INT_MAX) {
407 ln->ln_ntick = xtick - INT_MAX; 401 ln->ln_ntick = xtick - INT_MAX;
408 callout_reset(&ln->ln_timer_ch, INT_MAX, 402 callout_reset(&ln->ln_timer_ch, INT_MAX,
409 nd6_llinfo_timer, ln); 403 nd6_llinfo_timer, ln);
410 } else { 404 } else {
411 ln->ln_ntick = 0; 405 ln->ln_ntick = 0;
412 callout_reset(&ln->ln_timer_ch, xtick, 406 callout_reset(&ln->ln_timer_ch, xtick,
413 nd6_llinfo_timer, ln); 407 nd6_llinfo_timer, ln);
414 } 408 }
415 } 409 }
416} 410}
417 411
418void 412void
419nd6_llinfo_settimer(struct llentry *ln, time_t xtick) 413nd6_llinfo_settimer(struct llentry *ln, time_t xtick)
420{ 414{
421 415
422 LLE_WLOCK(ln); 416 LLE_WLOCK(ln);
423 nd6_llinfo_settimer_locked(ln, xtick); 417 nd6_llinfo_settimer_locked(ln, xtick);
424 LLE_WUNLOCK(ln); 418 LLE_WUNLOCK(ln);
425} 419}
426 420
427/* 421/*
428 * Gets source address of the first packet in hold queue 422 * Gets source address of the first packet in hold queue
429 * and stores it in @src. 423 * and stores it in @src.
430 * Returns pointer to @src (if hold queue is not empty) or NULL. 424 * Returns pointer to @src (if hold queue is not empty) or NULL.
431 */ 425 */
432static struct in6_addr * 426static struct in6_addr *
433nd6_llinfo_get_holdsrc(struct llentry *ln, struct in6_addr *src) 427nd6_llinfo_get_holdsrc(struct llentry *ln, struct in6_addr *src)
434{ 428{
435 struct ip6_hdr *hip6; 429 struct ip6_hdr *hip6;
436 430
437 if (ln == NULL || ln->ln_hold == NULL) 431 if (ln == NULL || ln->ln_hold == NULL)
438 return NULL; 432 return NULL;
439 433
440 /* 434 /*
441 * assuming every packet in ln_hold has the same IP header 435 * assuming every packet in ln_hold has the same IP header
442 */ 436 */
443 hip6 = mtod(ln->ln_hold, struct ip6_hdr *); 437 hip6 = mtod(ln->ln_hold, struct ip6_hdr *);
444 /* XXX pullup? */ 438 /* XXX pullup? */
445 if (sizeof(*hip6) < ln->ln_hold->m_len) 439 if (sizeof(*hip6) < ln->ln_hold->m_len)
446 *src = hip6->ip6_src; 440 *src = hip6->ip6_src;
447 else 441 else
448 src = NULL; 442 src = NULL;
449 443
450 return src; 444 return src;
451} 445}
452 446
453static void 447static void
454nd6_llinfo_timer(void *arg) 448nd6_llinfo_timer(void *arg)
455{ 449{
456 struct llentry *ln = arg; 450 struct llentry *ln = arg;
457 struct rtentry *rt; 451 struct rtentry *rt;
458 const struct sockaddr_in6 *dst; 452 const struct sockaddr_in6 *dst;
459 struct ifnet *ifp; 453 struct ifnet *ifp;
460 struct nd_ifinfo *ndi = NULL; 454 struct nd_ifinfo *ndi = NULL;
461 bool send_ns = false; 455 bool send_ns = false;
462 const struct in6_addr *daddr6 = NULL; 456 const struct in6_addr *daddr6 = NULL;
463 457
464 mutex_enter(softnet_lock); 458 mutex_enter(softnet_lock);
465 KERNEL_LOCK(1, NULL); 459 KERNEL_LOCK(1, NULL);
466 460
467 LLE_WLOCK(ln); 461 LLE_WLOCK(ln);
468 if (ln->ln_ntick > 0) { 462 if (ln->ln_ntick > 0) {
469 nd6_llinfo_settimer_locked(ln, ln->ln_ntick); 463 nd6_llinfo_settimer_locked(ln, ln->ln_ntick);
470 goto out; 464 goto out;
471 } 465 }
472 466
473 if (callout_pending(&ln->la_timer)) { 467 if (callout_pending(&ln->la_timer)) {
474 /* 468 /*
475 * Here we are a bit odd here in the treatment of 469 * Here we are a bit odd here in the treatment of
476 * active/pending. If the pending bit is set, it got 470 * active/pending. If the pending bit is set, it got
477 * rescheduled before I ran. The active 471 * rescheduled before I ran. The active
478 * bit we ignore, since if it was stopped 472 * bit we ignore, since if it was stopped
479 * in ll_tablefree() and was currently running 473 * in ll_tablefree() and was currently running
480 * it would have return 0 so the code would 474 * it would have return 0 so the code would
481 * not have deleted it since the callout could 475 * not have deleted it since the callout could
482 * not be stopped so we want to go through 476 * not be stopped so we want to go through
483 * with the delete here now. If the callout 477 * with the delete here now. If the callout
484 * was restarted, the pending bit will be back on and 478 * was restarted, the pending bit will be back on and
485 * we just want to bail since the callout_reset would 479 * we just want to bail since the callout_reset would
486 * return 1 and our reference would have been removed 480 * return 1 and our reference would have been removed
487 * by nd6_llinfo_settimer_locked above since canceled 481 * by nd6_llinfo_settimer_locked above since canceled
488 * would have been 1. 482 * would have been 1.
489 */ 483 */
490 goto out; 484 goto out;
491 } 485 }
492 486
493 ifp = ln->lle_tbl->llt_ifp; 487 ifp = ln->lle_tbl->llt_ifp;
494 rt = ln->ln_rt; 488 rt = ln->ln_rt;
495 489
496 KASSERT(rt != NULL); 490 KASSERT(rt != NULL);
497 KASSERT(ifp != NULL); 491 KASSERT(ifp != NULL);
498 492
499 ndi = ND_IFINFO(ifp); 493 ndi = ND_IFINFO(ifp);
500 dst = satocsin6(rt_getkey(rt)); 494 dst = satocsin6(rt_getkey(rt));
501 495
502 /* sanity check */ 496 /* sanity check */
503 if (rt->rt_llinfo && (struct llentry *)rt->rt_llinfo != ln) 497 if (rt->rt_llinfo && (struct llentry *)rt->rt_llinfo != ln)
504 panic("rt_llinfo(%p) is not equal to ln(%p)", 498 panic("rt_llinfo(%p) is not equal to ln(%p)",
505 rt->rt_llinfo, ln); 499 rt->rt_llinfo, ln);
506 if (!dst) 500 if (!dst)
507 panic("dst=0 in nd6_timer(ln=%p)", ln); 501 panic("dst=0 in nd6_timer(ln=%p)", ln);
508 502
509 switch (ln->ln_state) { 503 switch (ln->ln_state) {
510 case ND6_LLINFO_INCOMPLETE: 504 case ND6_LLINFO_INCOMPLETE:
511 if (ln->ln_asked < nd6_mmaxtries) { 505 if (ln->ln_asked < nd6_mmaxtries) {
512 ln->ln_asked++; 506 ln->ln_asked++;
513 send_ns = true; 507 send_ns = true;
514 } else { 508 } else {
515 struct mbuf *m = ln->ln_hold; 509 struct mbuf *m = ln->ln_hold;
516 if (m) { 510 if (m) {
517 struct mbuf *m0; 511 struct mbuf *m0;
518 512
519 /* 513 /*
520 * assuming every packet in ln_hold has 514 * assuming every packet in ln_hold has
521 * the same IP header 515 * the same IP header
522 */ 516 */
523 m0 = m->m_nextpkt; 517 m0 = m->m_nextpkt;
524 m->m_nextpkt = NULL; 518 m->m_nextpkt = NULL;
525 ln->ln_hold = m0; 519 ln->ln_hold = m0;
526 clear_llinfo_pqueue(ln); 520 clear_llinfo_pqueue(ln);
527 } 521 }
528 nd6_free(rt, ln, 0); 522 nd6_free(rt, ln, 0);
529 ln = NULL; 523 ln = NULL;
530 if (m != NULL) 524 if (m != NULL)
531 icmp6_error2(m, ICMP6_DST_UNREACH, 525 icmp6_error2(m, ICMP6_DST_UNREACH,
532 ICMP6_DST_UNREACH_ADDR, 0, ifp); 526 ICMP6_DST_UNREACH_ADDR, 0, ifp);
533 } 527 }
534 break; 528 break;
535 case ND6_LLINFO_REACHABLE: 529 case ND6_LLINFO_REACHABLE:
536 if (!ND6_LLINFO_PERMANENT(ln)) { 530 if (!ND6_LLINFO_PERMANENT(ln)) {
537 ln->ln_state = ND6_LLINFO_STALE; 531 ln->ln_state = ND6_LLINFO_STALE;
538 nd6_llinfo_settimer_locked(ln, nd6_gctimer * hz); 532 nd6_llinfo_settimer_locked(ln, nd6_gctimer * hz);
539 } 533 }
540 break; 534 break;
541 535
542 case ND6_LLINFO_PURGE: 536 case ND6_LLINFO_PURGE:
543 case ND6_LLINFO_STALE: 537 case ND6_LLINFO_STALE:
544 /* Garbage Collection(RFC 2461 5.3) */ 538 /* Garbage Collection(RFC 2461 5.3) */
545 if (!ND6_LLINFO_PERMANENT(ln)) { 539 if (!ND6_LLINFO_PERMANENT(ln)) {
546 nd6_free(rt, ln, 1); 540 nd6_free(rt, ln, 1);
547 ln = NULL; 541 ln = NULL;
548 } 542 }
549 break; 543 break;
550 544
551 case ND6_LLINFO_DELAY: 545 case ND6_LLINFO_DELAY:
552 if (ndi && (ndi->flags & ND6_IFF_PERFORMNUD) != 0) { 546 if (ndi && (ndi->flags & ND6_IFF_PERFORMNUD) != 0) {
553 /* We need NUD */ 547 /* We need NUD */
554 ln->ln_asked = 1; 548 ln->ln_asked = 1;
555 ln->ln_state = ND6_LLINFO_PROBE; 549 ln->ln_state = ND6_LLINFO_PROBE;
556 daddr6 = &dst->sin6_addr; 550 daddr6 = &dst->sin6_addr;
557 send_ns = true; 551 send_ns = true;
558 } else { 552 } else {
559 ln->ln_state = ND6_LLINFO_STALE; /* XXX */ 553 ln->ln_state = ND6_LLINFO_STALE; /* XXX */
560 nd6_llinfo_settimer_locked(ln, nd6_gctimer * hz); 554 nd6_llinfo_settimer_locked(ln, nd6_gctimer * hz);
561 } 555 }
562 break; 556 break;
563 case ND6_LLINFO_PROBE: 557 case ND6_LLINFO_PROBE:
564 if (ln->ln_asked < nd6_umaxtries) { 558 if (ln->ln_asked < nd6_umaxtries) {
565 ln->ln_asked++; 559 ln->ln_asked++;
566 daddr6 = &dst->sin6_addr; 560 daddr6 = &dst->sin6_addr;
567 send_ns = true; 561 send_ns = true;
568 } else { 562 } else {
569 nd6_free(rt, ln, 0); 563 nd6_free(rt, ln, 0);
570 ln = NULL; 564 ln = NULL;
571 } 565 }
572 break; 566 break;
573 } 567 }
574 568
575 if (send_ns) { 569 if (send_ns) {
576 struct in6_addr src, *psrc; 570 struct in6_addr src, *psrc;
577 571
578 nd6_llinfo_settimer_locked(ln, ndi->retrans * hz / 1000); 572 nd6_llinfo_settimer_locked(ln, ndi->retrans * hz / 1000);
579 psrc = nd6_llinfo_get_holdsrc(ln, &src); 573 psrc = nd6_llinfo_get_holdsrc(ln, &src);
580 LLE_FREE_LOCKED(ln); 574 LLE_FREE_LOCKED(ln);
581 ln = NULL; 575 ln = NULL;
582 nd6_ns_output(ifp, daddr6, &dst->sin6_addr, psrc, 0); 576 nd6_ns_output(ifp, daddr6, &dst->sin6_addr, psrc, 0);
583 } 577 }
584 578
585out: 579out:
586 if (ln != NULL) 580 if (ln != NULL)
587 LLE_FREE_LOCKED(ln); 581 LLE_FREE_LOCKED(ln);
588 KERNEL_UNLOCK_ONE(NULL); 582 KERNEL_UNLOCK_ONE(NULL);
589 mutex_exit(softnet_lock); 583 mutex_exit(softnet_lock);
590} 584}
591 585
592/* 586/*
593 * ND6 timer routine to expire default route list and prefix list 587 * ND6 timer routine to expire default route list and prefix list
594 */ 588 */
595void 589static void
596nd6_timer(void *ignored_arg) 590nd6_timer(void *ignored_arg)
597{ 591{
598 struct nd_defrouter *next_dr, *dr; 592 struct nd_defrouter *next_dr, *dr;
599 struct nd_prefix *next_pr, *pr; 593 struct nd_prefix *next_pr, *pr;
600 struct in6_ifaddr *ia6, *nia6; 594 struct in6_ifaddr *ia6, *nia6;
601 595
602 callout_reset(&nd6_timer_ch, nd6_prune * hz, 596 callout_reset(&nd6_timer_ch, nd6_prune * hz,
603 nd6_timer, NULL); 597 nd6_timer, NULL);
604 598
605 mutex_enter(softnet_lock); 599 mutex_enter(softnet_lock);
606 KERNEL_LOCK(1, NULL); 600 KERNEL_LOCK(1, NULL);
607 601
608 /* expire default router list */ 602 /* expire default router list */
609  603
610 TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, next_dr) { 604 TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, next_dr) {
611 if (dr->expire && dr->expire < time_uptime) { 605 if (dr->expire && dr->expire < time_uptime) {
612 defrtrlist_del(dr, NULL); 606 defrtrlist_del(dr, NULL);
613 } 607 }
614 } 608 }
615 609
616 /* 610 /*
617 * expire interface addresses. 611 * expire interface addresses.
618 * in the past the loop was inside prefix expiry processing. 612 * in the past the loop was inside prefix expiry processing.
619 * However, from a stricter speci-confrmance standpoint, we should 613 * However, from a stricter speci-confrmance standpoint, we should
620 * rather separate address lifetimes and prefix lifetimes. 614 * rather separate address lifetimes and prefix lifetimes.
621 */ 615 */
622 addrloop: 616 addrloop:
623 for (ia6 = in6_ifaddr; ia6; ia6 = nia6) { 617 for (ia6 = in6_ifaddr; ia6; ia6 = nia6) {
624 nia6 = ia6->ia_next; 618 nia6 = ia6->ia_next;
625 /* check address lifetime */ 619 /* check address lifetime */
626 if (IFA6_IS_INVALID(ia6)) { 620 if (IFA6_IS_INVALID(ia6)) {
627 int regen = 0; 621 int regen = 0;
628 622
629 /* 623 /*
630 * If the expiring address is temporary, try 624 * If the expiring address is temporary, try
631 * regenerating a new one. This would be useful when 625 * regenerating a new one. This would be useful when
632 * we suspended a laptop PC, then turned it on after a 626 * we suspended a laptop PC, then turned it on after a
633 * period that could invalidate all temporary 627 * period that could invalidate all temporary
634 * addresses. Although we may have to restart the 628 * addresses. Although we may have to restart the
635 * loop (see below), it must be after purging the 629 * loop (see below), it must be after purging the
636 * address. Otherwise, we'd see an infinite loop of 630 * address. Otherwise, we'd see an infinite loop of
637 * regeneration. 631 * regeneration.
638 */ 632 */
639 if (ip6_use_tempaddr && 633 if (ip6_use_tempaddr &&
640 (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0) { 634 (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0) {
641 if (regen_tmpaddr(ia6) == 0) 635 if (regen_tmpaddr(ia6) == 0)
642 regen = 1; 636 regen = 1;
643 } 637 }
644 638
645 in6_purgeaddr(&ia6->ia_ifa); 639 in6_purgeaddr(&ia6->ia_ifa);
646 640
647 if (regen) 641 if (regen)
648 goto addrloop; /* XXX: see below */ 642 goto addrloop; /* XXX: see below */
649 } else if (IFA6_IS_DEPRECATED(ia6)) { 643 } else if (IFA6_IS_DEPRECATED(ia6)) {
650 int oldflags = ia6->ia6_flags; 644 int oldflags = ia6->ia6_flags;
651 645
652 if ((oldflags & IN6_IFF_DEPRECATED) == 0) { 646 if ((oldflags & IN6_IFF_DEPRECATED) == 0) {
653 ia6->ia6_flags |= IN6_IFF_DEPRECATED; 647 ia6->ia6_flags |= IN6_IFF_DEPRECATED;
654 rt_newaddrmsg(RTM_NEWADDR, 648 rt_newaddrmsg(RTM_NEWADDR,
655 (struct ifaddr *)ia6, 0, NULL); 649 (struct ifaddr *)ia6, 0, NULL);
656 } 650 }
657 651
658 /* 652 /*
659 * If a temporary address has just become deprecated, 653 * If a temporary address has just become deprecated,
660 * regenerate a new one if possible. 654 * regenerate a new one if possible.
661 */ 655 */
662 if (ip6_use_tempaddr && 656 if (ip6_use_tempaddr &&
663 (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && 657 (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
664 (oldflags & IN6_IFF_DEPRECATED) == 0) { 658 (oldflags & IN6_IFF_DEPRECATED) == 0) {
665 659
666 if (regen_tmpaddr(ia6) == 0) { 660 if (regen_tmpaddr(ia6) == 0) {
667 /* 661 /*
668 * A new temporary address is 662 * A new temporary address is
669 * generated. 663 * generated.
670 * XXX: this means the address chain 664 * XXX: this means the address chain
671 * has changed while we are still in 665 * has changed while we are still in
672 * the loop. Although the change 666 * the loop. Although the change
673 * would not cause disaster (because 667 * would not cause disaster (because
674 * it's not a deletion, but an 668 * it's not a deletion, but an
675 * addition,) we'd rather restart the 669 * addition,) we'd rather restart the
676 * loop just for safety. Or does this 670 * loop just for safety. Or does this
677 * significantly reduce performance?? 671 * significantly reduce performance??
678 */ 672 */
679 goto addrloop; 673 goto addrloop;
680 } 674 }
681 } 675 }
682 } else { 676 } else {
683 /* 677 /*
684 * A new RA might have made a deprecated address 678 * A new RA might have made a deprecated address
685 * preferred. 679 * preferred.
686 */ 680 */
687 if (ia6->ia6_flags & IN6_IFF_DEPRECATED) { 681 if (ia6->ia6_flags & IN6_IFF_DEPRECATED) {
688 ia6->ia6_flags &= ~IN6_IFF_DEPRECATED; 682 ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
689 rt_newaddrmsg(RTM_NEWADDR, 683 rt_newaddrmsg(RTM_NEWADDR,
690 (struct ifaddr *)ia6, 0, NULL); 684 (struct ifaddr *)ia6, 0, NULL);
691 } 685 }
692 } 686 }
693 } 687 }
694 688
695 /* expire prefix list */ 689 /* expire prefix list */
696 LIST_FOREACH_SAFE(pr, &nd_prefix, ndpr_entry, next_pr) { 690 LIST_FOREACH_SAFE(pr, &nd_prefix, ndpr_entry, next_pr) {
697 /* 691 /*
698 * check prefix lifetime. 692 * check prefix lifetime.
699 * since pltime is just for autoconf, pltime processing for 693 * since pltime is just for autoconf, pltime processing for
700 * prefix is not necessary. 694 * prefix is not necessary.
701 */ 695 */
702 if (pr->ndpr_vltime != ND6_INFINITE_LIFETIME && 696 if (pr->ndpr_vltime != ND6_INFINITE_LIFETIME &&
703 time_uptime - pr->ndpr_lastupdate > pr->ndpr_vltime) { 697 time_uptime - pr->ndpr_lastupdate > pr->ndpr_vltime) {
704 698
705 /* 699 /*
706 * address expiration and prefix expiration are 700 * address expiration and prefix expiration are
707 * separate. NEVER perform in6_purgeaddr here. 701 * separate. NEVER perform in6_purgeaddr here.
708 */ 702 */
709 703
710 prelist_remove(pr); 704 prelist_remove(pr);
711 } 705 }
712 } 706 }
713 707
714 KERNEL_UNLOCK_ONE(NULL); 708 KERNEL_UNLOCK_ONE(NULL);
715 mutex_exit(softnet_lock); 709 mutex_exit(softnet_lock);
716} 710}
717 711
718/* ia6: deprecated/invalidated temporary address */ 712/* ia6: deprecated/invalidated temporary address */
719static int 713static int
720regen_tmpaddr(struct in6_ifaddr *ia6) 714regen_tmpaddr(struct in6_ifaddr *ia6)
721{ 715{
722 struct ifaddr *ifa; 716 struct ifaddr *ifa;
723 struct ifnet *ifp; 717 struct ifnet *ifp;
724 struct in6_ifaddr *public_ifa6 = NULL; 718 struct in6_ifaddr *public_ifa6 = NULL;
725 719
726 ifp = ia6->ia_ifa.ifa_ifp; 720 ifp = ia6->ia_ifa.ifa_ifp;
727 IFADDR_FOREACH(ifa, ifp) { 721 IFADDR_FOREACH(ifa, ifp) {
728 struct in6_ifaddr *it6; 722 struct in6_ifaddr *it6;
729 723
730 if (ifa->ifa_addr->sa_family != AF_INET6) 724 if (ifa->ifa_addr->sa_family != AF_INET6)
731 continue; 725 continue;
732 726
733 it6 = (struct in6_ifaddr *)ifa; 727 it6 = (struct in6_ifaddr *)ifa;
734 728
735 /* ignore no autoconf addresses. */ 729 /* ignore no autoconf addresses. */
736 if ((it6->ia6_flags & IN6_IFF_AUTOCONF) == 0) 730 if ((it6->ia6_flags & IN6_IFF_AUTOCONF) == 0)
737 continue; 731 continue;
738 732
739 /* ignore autoconf addresses with different prefixes. */ 733 /* ignore autoconf addresses with different prefixes. */
740 if (it6->ia6_ndpr == NULL || it6->ia6_ndpr != ia6->ia6_ndpr) 734 if (it6->ia6_ndpr == NULL || it6->ia6_ndpr != ia6->ia6_ndpr)
741 continue; 735 continue;
742 736
743 /* 737 /*
744 * Now we are looking at an autoconf address with the same 738 * Now we are looking at an autoconf address with the same
745 * prefix as ours. If the address is temporary and is still 739 * prefix as ours. If the address is temporary and is still
746 * preferred, do not create another one. It would be rare, but 740 * preferred, do not create another one. It would be rare, but
747 * could happen, for example, when we resume a laptop PC after 741 * could happen, for example, when we resume a laptop PC after
748 * a long period. 742 * a long period.
749 */ 743 */
750 if ((it6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && 744 if ((it6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
751 !IFA6_IS_DEPRECATED(it6)) { 745 !IFA6_IS_DEPRECATED(it6)) {
752 public_ifa6 = NULL; 746 public_ifa6 = NULL;
753 break; 747 break;
754 } 748 }
755 749
756 /* 750 /*
757 * This is a public autoconf address that has the same prefix 751 * This is a public autoconf address that has the same prefix
758 * as ours. If it is preferred, keep it. We can't break the 752 * as ours. If it is preferred, keep it. We can't break the
759 * loop here, because there may be a still-preferred temporary 753 * loop here, because there may be a still-preferred temporary
760 * address with the prefix. 754 * address with the prefix.
761 */ 755 */
762 if (!IFA6_IS_DEPRECATED(it6)) 756 if (!IFA6_IS_DEPRECATED(it6))
763 public_ifa6 = it6; 757 public_ifa6 = it6;
764 } 758 }
765 759
766 if (public_ifa6 != NULL) { 760 if (public_ifa6 != NULL) {
767 int e; 761 int e;
768 762
769 /* 763 /*
770 * Random factor is introduced in the preferred lifetime, so 764 * Random factor is introduced in the preferred lifetime, so
771 * we do not need additional delay (3rd arg to in6_tmpifadd). 765 * we do not need additional delay (3rd arg to in6_tmpifadd).
772 */ 766 */
773 if ((e = in6_tmpifadd(public_ifa6, 0, 0)) != 0) { 767 if ((e = in6_tmpifadd(public_ifa6, 0, 0)) != 0) {
774 log(LOG_NOTICE, "regen_tmpaddr: failed to create a new" 768 log(LOG_NOTICE, "regen_tmpaddr: failed to create a new"
775 " tmp addr, errno=%d\n", e); 769 " tmp addr, errno=%d\n", e);
776 return -1; 770 return -1;
777 } 771 }
778 return 0; 772 return 0;
779 } 773 }
780 774
781 return -1; 775 return -1;
782} 776}
783 777
784bool 778bool
785nd6_accepts_rtadv(const struct nd_ifinfo *ndi) 779nd6_accepts_rtadv(const struct nd_ifinfo *ndi)
786{ 780{
787 switch (ndi->flags & (ND6_IFF_ACCEPT_RTADV|ND6_IFF_OVERRIDE_RTADV)) { 781 switch (ndi->flags & (ND6_IFF_ACCEPT_RTADV|ND6_IFF_OVERRIDE_RTADV)) {
788 case ND6_IFF_OVERRIDE_RTADV|ND6_IFF_ACCEPT_RTADV: 782 case ND6_IFF_OVERRIDE_RTADV|ND6_IFF_ACCEPT_RTADV:
789 return true; 783 return true;
790 case ND6_IFF_ACCEPT_RTADV: 784 case ND6_IFF_ACCEPT_RTADV:
791 return ip6_accept_rtadv != 0; 785 return ip6_accept_rtadv != 0;
792 case ND6_IFF_OVERRIDE_RTADV: 786 case ND6_IFF_OVERRIDE_RTADV:
793 case 0: 787 case 0:
794 default: 788 default:
795 return false; 789 return false;
796 } 790 }
797} 791}
798 792
799/* 793/*
800 * Nuke neighbor cache/prefix/default router management table, right before 794 * Nuke neighbor cache/prefix/default router management table, right before
801 * ifp goes away. 795 * ifp goes away.
802 */ 796 */
803void 797void
804nd6_purge(struct ifnet *ifp, struct in6_ifextra *ext) 798nd6_purge(struct ifnet *ifp, struct in6_ifextra *ext)
805{ 799{
806 struct nd_defrouter *dr, *ndr; 800 struct nd_defrouter *dr, *ndr;
807 struct nd_prefix *pr, *npr; 801 struct nd_prefix *pr, *npr;
808 802
809 /* 803 /*
810 * During detach, the ND info might be already removed, but 804 * During detach, the ND info might be already removed, but
811 * then is explitly passed as argument. 805 * then is explitly passed as argument.
812 * Otherwise get it from ifp->if_afdata. 806 * Otherwise get it from ifp->if_afdata.
813 */ 807 */
814 if (ext == NULL) 808 if (ext == NULL)
815 ext = ifp->if_afdata[AF_INET6]; 809 ext = ifp->if_afdata[AF_INET6];
816 if (ext == NULL) 810 if (ext == NULL)
817 return; 811 return;
818 812
819 /* 813 /*
820 * Nuke default router list entries toward ifp. 814 * Nuke default router list entries toward ifp.
821 * We defer removal of default router list entries that is installed 815 * We defer removal of default router list entries that is installed
822 * in the routing table, in order to keep additional side effects as 816 * in the routing table, in order to keep additional side effects as
823 * small as possible. 817 * small as possible.
824 */ 818 */
825 TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, ndr) { 819 TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, ndr) {
826 if (dr->installed) 820 if (dr->installed)
827 continue; 821 continue;
828 822
829 if (dr->ifp == ifp) { 823 if (dr->ifp == ifp) {
830 KASSERT(ext != NULL); 824 KASSERT(ext != NULL);
831 defrtrlist_del(dr, ext); 825 defrtrlist_del(dr, ext);
832 } 826 }
833 } 827 }
834 828
835 TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, ndr) { 829 TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, ndr) {
836 if (!dr->installed) 830 if (!dr->installed)
837 continue; 831 continue;
838 832
839 if (dr->ifp == ifp) { 833 if (dr->ifp == ifp) {
840 KASSERT(ext != NULL); 834 KASSERT(ext != NULL);
841 defrtrlist_del(dr, ext); 835 defrtrlist_del(dr, ext);
842 } 836 }
843 } 837 }
844 838
845 /* Nuke prefix list entries toward ifp */ 839 /* Nuke prefix list entries toward ifp */
846 LIST_FOREACH_SAFE(pr, &nd_prefix, ndpr_entry, npr) { 840 LIST_FOREACH_SAFE(pr, &nd_prefix, ndpr_entry, npr) {
847 if (pr->ndpr_ifp == ifp) { 841 if (pr->ndpr_ifp == ifp) {
848 /* 842 /*
849 * Because if_detach() does *not* release prefixes 843 * Because if_detach() does *not* release prefixes
850 * while purging addresses the reference count will 844 * while purging addresses the reference count will
851 * still be above zero. We therefore reset it to 845 * still be above zero. We therefore reset it to
852 * make sure that the prefix really gets purged. 846 * make sure that the prefix really gets purged.
853 */ 847 */
854 pr->ndpr_refcnt = 0; 848 pr->ndpr_refcnt = 0;
855 /* 849 /*
856 * Previously, pr->ndpr_addr is removed as well, 850 * Previously, pr->ndpr_addr is removed as well,
857 * but I strongly believe we don't have to do it. 851 * but I strongly believe we don't have to do it.
858 * nd6_purge() is only called from in6_ifdetach(), 852 * nd6_purge() is only called from in6_ifdetach(),
859 * which removes all the associated interface addresses 853 * which removes all the associated interface addresses
860 * by itself. 854 * by itself.
861 * (jinmei@kame.net 20010129) 855 * (jinmei@kame.net 20010129)
862 */ 856 */
863 prelist_remove(pr); 857 prelist_remove(pr);
864 } 858 }
865 } 859 }
866 860
867 /* cancel default outgoing interface setting */ 861 /* cancel default outgoing interface setting */
868 if (nd6_defifindex == ifp->if_index) 862 if (nd6_defifindex == ifp->if_index)
869 nd6_setdefaultiface(0); 863 nd6_setdefaultiface(0);
870 864
871 /* XXX: too restrictive? */ 865 /* XXX: too restrictive? */
872 if (!ip6_forwarding && ifp->if_afdata[AF_INET6]) { 866 if (!ip6_forwarding && ifp->if_afdata[AF_INET6]) {
873 struct nd_ifinfo *ndi = ND_IFINFO(ifp); 867 struct nd_ifinfo *ndi = ND_IFINFO(ifp);
874 if (ndi && nd6_accepts_rtadv(ndi)) { 868 if (ndi && nd6_accepts_rtadv(ndi)) {
875 /* refresh default router list */ 869 /* refresh default router list */
876 defrouter_select(); 870 defrouter_select();
877 } 871 }
878 } 872 }
879 873
880 /* 874 /*
881 * We may not need to nuke the neighbor cache entries here 875 * We may not need to nuke the neighbor cache entries here
882 * because the neighbor cache is kept in if_afdata[AF_INET6]. 876 * because the neighbor cache is kept in if_afdata[AF_INET6].
883 * nd6_purge() is invoked by in6_ifdetach() which is called 877 * nd6_purge() is invoked by in6_ifdetach() which is called
884 * from if_detach() where everything gets purged. However 878 * from if_detach() where everything gets purged. However
885 * in6_ifdetach is directly called from vlan(4), so we still 879 * in6_ifdetach is directly called from vlan(4), so we still
886 * need to purge entries here. 880 * need to purge entries here.
887 */ 881 */
888 if (ext->lltable != NULL) 882 if (ext->lltable != NULL)
889 lltable_purge_entries(ext->lltable); 883 lltable_purge_entries(ext->lltable);
890} 884}
891 885
892static struct rtentry * 886static struct rtentry *
893nd6_lookup1(const struct in6_addr *addr6, int create, struct ifnet *ifp, 887nd6_lookup1(const struct in6_addr *addr6, int create, struct ifnet *ifp,
894 int cloning) 888 int cloning)
895{ 889{
896 struct rtentry *rt; 890 struct rtentry *rt;
897 struct sockaddr_in6 sin6; 891 struct sockaddr_in6 sin6;
898 892
899 sockaddr_in6_init(&sin6, addr6, 0, 0, 0); 893 sockaddr_in6_init(&sin6, addr6, 0, 0, 0);
900 rt = rtalloc1((struct sockaddr *)&sin6, create); 894 rt = rtalloc1((struct sockaddr *)&sin6, create);
901 if (rt != NULL && (rt->rt_flags & RTF_LLINFO) == 0) { 895 if (rt != NULL && (rt->rt_flags & RTF_LLINFO) == 0) {
902 /* 896 /*
903 * This is the case for the default route. 897 * This is the case for the default route.
904 * If we want to create a neighbor cache for the address, we 898 * If we want to create a neighbor cache for the address, we
905 * should free the route for the destination and allocate an 899 * should free the route for the destination and allocate an
906 * interface route. 900 * interface route.
907 */ 901 */
908 if (create) { 902 if (create) {
909 rtfree(rt); 903 rtfree(rt);
910 rt = NULL; 904 rt = NULL;
911 } 905 }
912 } 906 }
913 if (rt != NULL) 907 if (rt != NULL)
914 ; 908 ;
915 else if (create && ifp) { 909 else if (create && ifp) {
916 int e; 910 int e;
917 911
918 /* 912 /*
919 * If no route is available and create is set, 913 * If no route is available and create is set,
920 * we allocate a host route for the destination 914 * we allocate a host route for the destination
921 * and treat it like an interface route. 915 * and treat it like an interface route.
922 * This hack is necessary for a neighbor which can't 916 * This hack is necessary for a neighbor which can't
923 * be covered by our own prefix. 917 * be covered by our own prefix.
924 */ 918 */
925 struct ifaddr *ifa = 919 struct ifaddr *ifa =
926 ifaof_ifpforaddr((struct sockaddr *)&sin6, ifp); 920 ifaof_ifpforaddr((struct sockaddr *)&sin6, ifp);
927 if (ifa == NULL) 921 if (ifa == NULL)
928 return NULL; 922 return NULL;
929 923
930 /* 924 /*
931 * Create a new route. RTF_LLINFO is necessary 925 * Create a new route. RTF_LLINFO is necessary
932 * to create a Neighbor Cache entry for the 926 * to create a Neighbor Cache entry for the
933 * destination in nd6_rtrequest which will be 927 * destination in nd6_rtrequest which will be
934 * called in rtrequest via ifa->ifa_rtrequest. 928 * called in rtrequest via ifa->ifa_rtrequest.
935 */ 929 */
936 if ((e = rtrequest(RTM_ADD, (const struct sockaddr *)&sin6, 930 if ((e = rtrequest(RTM_ADD, (const struct sockaddr *)&sin6,
937 ifa->ifa_addr, (const struct sockaddr *)&all1_sa, 931 ifa->ifa_addr, (const struct sockaddr *)&all1_sa,
938 (ifa->ifa_flags | RTF_HOST | RTF_LLINFO) & 932 (ifa->ifa_flags | RTF_HOST | RTF_LLINFO) &
939 ~RTF_CLONING, &rt)) != 0) { 933 ~RTF_CLONING, &rt)) != 0) {
940#if 0 934#if 0
941 log(LOG_ERR, 935 log(LOG_ERR,
942 "nd6_lookup: failed to add route for a " 936 "nd6_lookup: failed to add route for a "
943 "neighbor(%s), errno=%d\n", 937 "neighbor(%s), errno=%d\n",
944 ip6_sprintf(addr6), e); 938 ip6_sprintf(addr6), e);
945#endif 939#endif
946 return NULL; 940 return NULL;
947 } 941 }
948 if (rt == NULL) 942 if (rt == NULL)
949 return NULL; 943 return NULL;
950 if (rt->rt_llinfo) { 944 if (rt->rt_llinfo) {
951 struct llentry *ln = rt->rt_llinfo; 945 struct llentry *ln = rt->rt_llinfo;
952 ln->ln_state = ND6_LLINFO_NOSTATE; 946 ln->ln_state = ND6_LLINFO_NOSTATE;
953 } 947 }
954 } else 948 } else
955 return NULL; 949 return NULL;
956 950
957 /* 951 /*
958 * Check for a cloning route to match the address. 952 * Check for a cloning route to match the address.
959 * This should only be set from in6_is_addr_neighbor so we avoid 953 * This should only be set from in6_is_addr_neighbor so we avoid
960 * a potentially expensive second call to rtalloc1. 954 * a potentially expensive second call to rtalloc1.
961 */ 955 */
962 if (cloning && 956 if (cloning &&
963 rt->rt_flags & (RTF_CLONING | RTF_CLONED) && 957 rt->rt_flags & (RTF_CLONING | RTF_CLONED) &&
964 (rt->rt_ifp == ifp 958 (rt->rt_ifp == ifp
965#if NBRIDGE > 0 959#if NBRIDGE > 0
966 || rt->rt_ifp->if_bridge == ifp->if_bridge 960 || rt->rt_ifp->if_bridge == ifp->if_bridge
967#endif 961#endif
968#if NCARP > 0 962#if NCARP > 0
969 || (ifp->if_type == IFT_CARP && rt->rt_ifp == ifp->if_carpdev) || 963 || (ifp->if_type == IFT_CARP && rt->rt_ifp == ifp->if_carpdev) ||
970 (rt->rt_ifp->if_type == IFT_CARP && rt->rt_ifp->if_carpdev == ifp)|| 964 (rt->rt_ifp->if_type == IFT_CARP && rt->rt_ifp->if_carpdev == ifp)||
971 (ifp->if_type == IFT_CARP && rt->rt_ifp->if_type == IFT_CARP && 965 (ifp->if_type == IFT_CARP && rt->rt_ifp->if_type == IFT_CARP &&
972 rt->rt_ifp->if_carpdev == ifp->if_carpdev) 966 rt->rt_ifp->if_carpdev == ifp->if_carpdev)
973#endif 967#endif
974 )) 968 ))
975 return rt; 969 return rt;
976 970
977 /* 971 /*
978 * Validation for the entry. 972 * Validation for the entry.
979 * Note that the check for rt_llinfo is necessary because a cloned 973 * Note that the check for rt_llinfo is necessary because a cloned
980 * route from a parent route that has the L flag (e.g. the default 974 * route from a parent route that has the L flag (e.g. the default
981 * route to a p2p interface) may have the flag, too, while the 975 * route to a p2p interface) may have the flag, too, while the
982 * destination is not actually a neighbor. 976 * destination is not actually a neighbor.
983 * XXX: we can't use rt->rt_ifp to check for the interface, since 977 * XXX: we can't use rt->rt_ifp to check for the interface, since
984 * it might be the loopback interface if the entry is for our 978 * it might be the loopback interface if the entry is for our
985 * own address on a non-loopback interface. Instead, we should 979 * own address on a non-loopback interface. Instead, we should
986 * use rt->rt_ifa->ifa_ifp, which would specify the REAL 980 * use rt->rt_ifa->ifa_ifp, which would specify the REAL
987 * interface. 981 * interface.
988 * Note also that ifa_ifp and ifp may differ when we connect two 982 * Note also that ifa_ifp and ifp may differ when we connect two
989 * interfaces to a same link, install a link prefix to an interface, 983 * interfaces to a same link, install a link prefix to an interface,
990 * and try to install a neighbor cache on an interface that does not 984 * and try to install a neighbor cache on an interface that does not
991 * have a route to the prefix. 985 * have a route to the prefix.
992 */ 986 */
993 if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 || 987 if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
994 rt->rt_gateway->sa_family != AF_LINK || rt->rt_llinfo == NULL || 988 rt->rt_gateway->sa_family != AF_LINK || rt->rt_llinfo == NULL ||
995 (ifp && rt->rt_ifa->ifa_ifp != ifp)) { 989 (ifp && rt->rt_ifa->ifa_ifp != ifp)) {
996 if (create) { 990 if (create) {
997 nd6log((LOG_DEBUG, 991 nd6log((LOG_DEBUG,
998 "nd6_lookup: failed to lookup %s (if = %s)\n", 992 "nd6_lookup: failed to lookup %s (if = %s)\n",
999 ip6_sprintf(addr6), 993 ip6_sprintf(addr6),
1000 ifp ? if_name(ifp) : "unspec")); 994 ifp ? if_name(ifp) : "unspec"));
1001 } 995 }
1002 rtfree(rt); 996 rtfree(rt);
1003 return NULL; 997 return NULL;
1004 } 998 }
1005 return rt; 999 return rt;
1006} 1000}
1007 1001
1008struct rtentry * 1002struct rtentry *
1009nd6_lookup(const struct in6_addr *addr6, int create, struct ifnet *ifp) 1003nd6_lookup(const struct in6_addr *addr6, int create, struct ifnet *ifp)
1010{ 1004{
1011 1005
1012 return nd6_lookup1(addr6, create, ifp, 0); 1006 return nd6_lookup1(addr6, create, ifp, 0);
1013} 1007}
1014 1008
1015/* 1009/*
1016 * Detect if a given IPv6 address identifies a neighbor on a given link. 1010 * Detect if a given IPv6 address identifies a neighbor on a given link.
1017 * XXX: should take care of the destination of a p2p link? 1011 * XXX: should take care of the destination of a p2p link?
1018 */ 1012 */
1019int 1013int
1020nd6_is_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp) 1014nd6_is_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
1021{ 1015{
1022 struct nd_prefix *pr; 1016 struct nd_prefix *pr;
1023 struct rtentry *rt; 1017 struct rtentry *rt;
1024 1018
1025 /* 1019 /*
1026 * A link-local address is always a neighbor. 1020 * A link-local address is always a neighbor.
1027 * XXX: a link does not necessarily specify a single interface. 1021 * XXX: a link does not necessarily specify a single interface.
1028 */ 1022 */
1029 if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) { 1023 if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
1030 struct sockaddr_in6 sin6_copy; 1024 struct sockaddr_in6 sin6_copy;
1031 u_int32_t zone; 1025 u_int32_t zone;
1032 1026
1033 /* 1027 /*
1034 * We need sin6_copy since sa6_recoverscope() may modify the 1028 * We need sin6_copy since sa6_recoverscope() may modify the
1035 * content (XXX). 1029 * content (XXX).
1036 */ 1030 */
1037 sin6_copy = *addr; 1031 sin6_copy = *addr;
1038 if (sa6_recoverscope(&sin6_copy)) 1032 if (sa6_recoverscope(&sin6_copy))
1039 return 0; /* XXX: should be impossible */ 1033 return 0; /* XXX: should be impossible */
1040 if (in6_setscope(&sin6_copy.sin6_addr, ifp, &zone)) 1034 if (in6_setscope(&sin6_copy.sin6_addr, ifp, &zone))
1041 return 0; 1035 return 0;
1042 if (sin6_copy.sin6_scope_id == zone) 1036 if (sin6_copy.sin6_scope_id == zone)
1043 return 1; 1037 return 1;
1044 else 1038 else
1045 return 0; 1039 return 0;
1046 } 1040 }
1047 1041
1048 /* 1042 /*
1049 * If the address matches one of our on-link prefixes, it should be a 1043 * If the address matches one of our on-link prefixes, it should be a
1050 * neighbor. 1044 * neighbor.
1051 */ 1045 */
1052 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { 1046 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
1053 if (pr->ndpr_ifp != ifp) 1047 if (pr->ndpr_ifp != ifp)
1054 continue; 1048 continue;
1055 1049
1056 if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) 1050 if (!(pr->ndpr_stateflags & NDPRF_ONLINK))
1057 continue; 1051 continue;
1058 1052
1059 if (IN6_ARE_MASKED_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr, 1053 if (IN6_ARE_MASKED_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr,
1060 &addr->sin6_addr, &pr->ndpr_mask)) 1054 &addr->sin6_addr, &pr->ndpr_mask))
1061 return 1; 1055 return 1;
1062 } 1056 }
1063 1057
1064 /* 1058 /*
1065 * If the default router list is empty, all addresses are regarded 1059 * If the default router list is empty, all addresses are regarded
1066 * as on-link, and thus, as a neighbor. 1060 * as on-link, and thus, as a neighbor.
1067 * XXX: we restrict the condition to hosts, because routers usually do 1061 * XXX: we restrict the condition to hosts, because routers usually do
1068 * not have the "default router list". 1062 * not have the "default router list".
1069 */ 1063 */
1070 if (!ip6_forwarding && TAILQ_FIRST(&nd_defrouter) == NULL && 1064 if (!ip6_forwarding && TAILQ_FIRST(&nd_defrouter) == NULL &&
1071 nd6_defifindex == ifp->if_index) { 1065 nd6_defifindex == ifp->if_index) {
1072 return 1; 1066 return 1;
1073 } 1067 }
1074 1068
1075 /* 1069 /*
1076 * Even if the address matches none of our addresses, it might match 1070 * Even if the address matches none of our addresses, it might match
1077 * a cloning route or be in the neighbor cache. 1071 * a cloning route or be in the neighbor cache.
1078 */ 1072 */
1079 rt = nd6_lookup1(&addr->sin6_addr, 0, ifp, 1); 1073 rt = nd6_lookup1(&addr->sin6_addr, 0, ifp, 1);
1080 if (rt != NULL) { 1074 if (rt != NULL) {
1081 rtfree(rt); 1075 rtfree(rt);
1082 return 1; 1076 return 1;
1083 } 1077 }
1084 1078
1085 return 0; 1079 return 0;
1086} 1080}
1087 1081
1088/* 1082/*
1089 * Free an nd6 llinfo entry. 1083 * Free an nd6 llinfo entry.
1090 * Since the function would cause significant changes in the kernel, DO NOT 1084 * Since the function would cause significant changes in the kernel, DO NOT
1091 * make it global, unless you have a strong reason for the change, and are sure 1085 * make it global, unless you have a strong reason for the change, and are sure
1092 * that the change is safe. 1086 * that the change is safe.
1093 */ 1087 */
1094static void 1088static void
1095nd6_free(struct rtentry *rt, struct llentry *ln, int gc) 1089nd6_free(struct rtentry *rt, struct llentry *ln, int gc)
1096{ 1090{
1097 struct in6_addr in6 = satocsin6(rt_getkey(rt))->sin6_addr; 1091 struct in6_addr in6 = satocsin6(rt_getkey(rt))->sin6_addr;
1098 struct nd_defrouter *dr; 1092 struct nd_defrouter *dr;
1099 int error; 1093 int error;
1100 1094
1101 KASSERT(ln != NULL); 1095 KASSERT(ln != NULL);
1102 KASSERT(ln == rt->rt_llinfo); 1096 KASSERT(ln == rt->rt_llinfo);
1103 LLE_WLOCK_ASSERT(ln); 1097 LLE_WLOCK_ASSERT(ln);
1104 1098
1105 /* 1099 /*
1106 * we used to have pfctlinput(PRC_HOSTDEAD) here. 1100 * we used to have pfctlinput(PRC_HOSTDEAD) here.
1107 * even though it is not harmful, it was not really necessary. 1101 * even though it is not harmful, it was not really necessary.
1108 */ 1102 */
1109 1103
1110 /* cancel timer */ 1104 /* cancel timer */
1111 nd6_llinfo_settimer_locked(ln, -1); 1105 nd6_llinfo_settimer_locked(ln, -1);
1112 1106
1113 if (!ip6_forwarding) { 1107 if (!ip6_forwarding) {
1114 int s; 1108 int s;
1115 s = splsoftnet(); 1109 s = splsoftnet();
1116 dr = defrouter_lookup(&satocsin6(rt_getkey(rt))->sin6_addr, 1110 dr = defrouter_lookup(&satocsin6(rt_getkey(rt))->sin6_addr,
1117 rt->rt_ifp); 1111 rt->rt_ifp);
1118 1112
1119 if (dr != NULL && dr->expire && 1113 if (dr != NULL && dr->expire &&
1120 ln->ln_state == ND6_LLINFO_STALE && gc) { 1114 ln->ln_state == ND6_LLINFO_STALE && gc) {
1121 /* 1115 /*
1122 * If the reason for the deletion is just garbage 1116 * If the reason for the deletion is just garbage
1123 * collection, and the neighbor is an active default 1117 * collection, and the neighbor is an active default
1124 * router, do not delete it. Instead, reset the GC 1118 * router, do not delete it. Instead, reset the GC
1125 * timer using the router's lifetime. 1119 * timer using the router's lifetime.
1126 * Simply deleting the entry would affect default 1120 * Simply deleting the entry would affect default
1127 * router selection, which is not necessarily a good 1121 * router selection, which is not necessarily a good
1128 * thing, especially when we're using router preference 1122 * thing, especially when we're using router preference
1129 * values. 1123 * values.
1130 * XXX: the check for ln_state would be redundant, 1124 * XXX: the check for ln_state would be redundant,
1131 * but we intentionally keep it just in case. 1125 * but we intentionally keep it just in case.
1132 */ 1126 */
1133 if (dr->expire > time_uptime) 1127 if (dr->expire > time_uptime)
1134 nd6_llinfo_settimer_locked(ln, 1128 nd6_llinfo_settimer_locked(ln,
1135 (dr->expire - time_uptime) * hz); 1129 (dr->expire - time_uptime) * hz);
1136 else 1130 else
1137 nd6_llinfo_settimer_locked(ln, 1131 nd6_llinfo_settimer_locked(ln,
1138 nd6_gctimer * hz); 1132 nd6_gctimer * hz);
1139 splx(s); 1133 splx(s);
1140 LLE_WUNLOCK(ln); 1134 LLE_WUNLOCK(ln);
1141 return; 1135 return;
1142 } 1136 }
1143 1137
1144 if (ln->ln_router || dr) { 1138 if (ln->ln_router || dr) {
1145 /* 1139 /*
1146 * rt6_flush must be called whether or not the neighbor 1140 * rt6_flush must be called whether or not the neighbor
1147 * is in the Default Router List. 1141 * is in the Default Router List.
1148 * See a corresponding comment in nd6_na_input(). 1142 * See a corresponding comment in nd6_na_input().
1149 */ 1143 */
1150 rt6_flush(&in6, rt->rt_ifp); 1144 rt6_flush(&in6, rt->rt_ifp);
1151 } 1145 }
1152 1146
1153 if (dr) { 1147 if (dr) {
1154 /* 1148 /*
1155 * Unreachablity of a router might affect the default 1149 * Unreachablity of a router might affect the default
1156 * router selection and on-link detection of advertised 1150 * router selection and on-link detection of advertised
1157 * prefixes. 1151 * prefixes.
1158 */ 1152 */
1159 1153
1160 /* 1154 /*
1161 * Temporarily fake the state to choose a new default 1155 * Temporarily fake the state to choose a new default
1162 * router and to perform on-link determination of 1156 * router and to perform on-link determination of
1163 * prefixes correctly. 1157 * prefixes correctly.
1164 * Below the state will be set correctly, 1158 * Below the state will be set correctly,
1165 * or the entry itself will be deleted. 1159 * or the entry itself will be deleted.
1166 */ 1160 */
1167 ln->ln_state = ND6_LLINFO_INCOMPLETE; 1161 ln->ln_state = ND6_LLINFO_INCOMPLETE;
1168 1162
1169 /* 1163 /*
1170 * Since defrouter_select() does not affect the 1164 * Since defrouter_select() does not affect the
1171 * on-link determination and MIP6 needs the check 1165 * on-link determination and MIP6 needs the check
1172 * before the default router selection, we perform 1166 * before the default router selection, we perform
1173 * the check now. 1167 * the check now.
1174 */ 1168 */
1175 pfxlist_onlink_check(); 1169 pfxlist_onlink_check();
1176 1170
1177 /* 1171 /*
1178 * refresh default router list 1172 * refresh default router list
1179 */ 1173 */
1180 defrouter_select(); 1174 defrouter_select();
1181 } 1175 }
1182 splx(s); 1176 splx(s);
1183 } 1177 }
1184 1178
1185 LLE_WUNLOCK(ln); 1179 LLE_WUNLOCK(ln);
1186 /* 1180 /*
1187 * Detach the route from the routing tree and the list of neighbor 1181 * Detach the route from the routing tree and the list of neighbor
1188 * caches, and disable the route entry not to be used in already 1182 * caches, and disable the route entry not to be used in already
1189 * cached routes. 1183 * cached routes.
1190 */ 1184 */
1191 error = rtrequest_newmsg(RTM_DELETE, rt_getkey(rt), NULL, 1185 error = rtrequest_newmsg(RTM_DELETE, rt_getkey(rt), NULL,
1192 rt_mask(rt), 0); 1186 rt_mask(rt), 0);
1193 if (error != 0) { 1187 if (error != 0) {
1194 /* XXX need error message? */; 1188 /* XXX need error message? */;
1195 } 1189 }
1196} 1190}
1197 1191
1198/* 1192/*
1199 * Upper-layer reachability hint for Neighbor Unreachability Detection. 1193 * Upper-layer reachability hint for Neighbor Unreachability Detection.
1200 * 1194 *
1201 * XXX cost-effective methods? 1195 * XXX cost-effective methods?
1202 */ 1196 */
1203void 1197void
1204nd6_nud_hint(struct rtentry *rt) 1198nd6_nud_hint(struct rtentry *rt)
1205{ 1199{
1206 struct llentry *ln; 1200 struct llentry *ln;
1207 1201
1208 if (rt == NULL) 1202 if (rt == NULL)
1209 return; 1203 return;
1210 1204
1211 if ((rt->rt_flags & RTF_GATEWAY) != 0 || 1205 if ((rt->rt_flags & RTF_GATEWAY) != 0 ||
1212 (rt->rt_flags & RTF_LLINFO) == 0 || 1206 (rt->rt_flags & RTF_LLINFO) == 0 ||
1213 !rt->rt_llinfo || !rt->rt_gateway || 1207 !rt->rt_llinfo || !rt->rt_gateway ||
1214 rt->rt_gateway->sa_family != AF_LINK) { 1208 rt->rt_gateway->sa_family != AF_LINK) {
1215 /* This is not a host route. */ 1209 /* This is not a host route. */
1216 return; 1210 return;
1217 } 1211 }
1218 1212
1219 ln = rt->rt_llinfo; 1213 ln = rt->rt_llinfo;
1220 if (ln->ln_state < ND6_LLINFO_REACHABLE) 1214 if (ln->ln_state < ND6_LLINFO_REACHABLE)
1221 return; 1215 return;
1222 1216
1223 /* 1217 /*
1224 * if we get upper-layer reachability confirmation many times, 1218 * if we get upper-layer reachability confirmation many times,
1225 * it is possible we have false information. 1219 * it is possible we have false information.
1226 */ 1220 */
1227 ln->ln_byhint++; 1221 ln->ln_byhint++;
1228 if (ln->ln_byhint > nd6_maxnudhint) 1222 if (ln->ln_byhint > nd6_maxnudhint)
1229 return; 1223 return;
1230 1224
1231 ln->ln_state = ND6_LLINFO_REACHABLE; 1225 ln->ln_state = ND6_LLINFO_REACHABLE;
1232 if (!ND6_LLINFO_PERMANENT(ln)) { 1226 if (!ND6_LLINFO_PERMANENT(ln)) {
1233 nd6_llinfo_settimer(ln, 1227 nd6_llinfo_settimer(ln,
1234 ND_IFINFO(rt->rt_ifp)->reachable * hz); 1228 ND_IFINFO(rt->rt_ifp)->reachable * hz);
1235 } 1229 }
1236 1230
1237 return; 1231 return;
1238} 1232}
1239 1233
1240static int 1234static int
1241nd6_purge_entry(struct lltable *llt, struct llentry *ln, void *farg) 1235nd6_purge_entry(struct lltable *llt, struct llentry *ln, void *farg)
1242{ 1236{
1243 int *n = farg; 1237 int *n = farg;
1244 1238
1245 if (*n <= 0) 1239 if (*n <= 0)
1246 return 0; 1240 return 0;
1247 1241
1248 if (ND6_LLINFO_PERMANENT(ln)) 1242 if (ND6_LLINFO_PERMANENT(ln))
1249 return 0; 1243 return 0;
1250 1244
1251 LLE_WLOCK(ln); 1245 LLE_WLOCK(ln);
1252 if (ln->ln_state > ND6_LLINFO_INCOMPLETE) 1246 if (ln->ln_state > ND6_LLINFO_INCOMPLETE)
1253 ln->ln_state = ND6_LLINFO_STALE; 1247 ln->ln_state = ND6_LLINFO_STALE;
1254 else 1248 else
1255 ln->ln_state = ND6_LLINFO_PURGE; 1249 ln->ln_state = ND6_LLINFO_PURGE;
1256 nd6_llinfo_settimer_locked(ln, 0); 1250 nd6_llinfo_settimer_locked(ln, 0);
1257 LLE_WUNLOCK(ln); 1251 LLE_WUNLOCK(ln);
1258 1252
1259 (*n)--; 1253 (*n)--;
1260 return 0; 1254 return 0;
1261} 1255}
1262 1256
1263static void 1257static void
1264nd6_gc_neighbors(struct lltable *llt) 1258nd6_gc_neighbors(struct lltable *llt)
1265{ 1259{
1266 int max_gc_entries = 10; 1260 int max_gc_entries = 10;
1267 1261
1268 if (ip6_neighborgcthresh >= 0 && 1262 if (ip6_neighborgcthresh >= 0 &&
1269 lltable_get_entry_count(llt) >= ip6_neighborgcthresh) { 1263 lltable_get_entry_count(llt) >= ip6_neighborgcthresh) {
1270 /* 1264 /*
1271 * XXX entries that are "less recently used" should be 1265 * XXX entries that are "less recently used" should be
1272 * freed first. 1266 * freed first.
1273 */ 1267 */
1274 lltable_foreach_lle(llt, nd6_purge_entry, &max_gc_entries); 1268 lltable_foreach_lle(llt, nd6_purge_entry, &max_gc_entries);
1275 } 1269 }
1276} 1270}
1277 1271
1278void 1272void
1279nd6_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info) 1273nd6_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info)
1280{ 1274{
1281 struct sockaddr *gate = rt->rt_gateway; 1275 struct sockaddr *gate = rt->rt_gateway;
1282 struct llentry *ln; 1276 struct llentry *ln;
1283 struct ifnet *ifp = rt->rt_ifp; 1277 struct ifnet *ifp = rt->rt_ifp;
1284 uint8_t namelen = strlen(ifp->if_xname), addrlen = ifp->if_addrlen; 1278 uint8_t namelen = strlen(ifp->if_xname), addrlen = ifp->if_addrlen;
1285 struct ifaddr *ifa; 1279 struct ifaddr *ifa;
1286 int flags = 0; 1280 int flags = 0;
1287 bool use_lo0ifp = false; 1281 bool use_lo0ifp = false;
1288 1282
1289 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1283 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1290 1284
1291 if (req == RTM_LLINFO_UPD) { 1285 if (req == RTM_LLINFO_UPD) {
1292 int rc; 1286 int rc;
1293 struct in6_addr *in6; 1287 struct in6_addr *in6;
1294 struct in6_addr in6_all; 1288 struct in6_addr in6_all;
1295 int anycast; 1289 int anycast;
1296 1290
1297 if ((ifa = info->rti_ifa) == NULL) 1291 if ((ifa = info->rti_ifa) == NULL)
1298 return; 1292 return;
1299 1293
1300 in6 = &ifatoia6(ifa)->ia_addr.sin6_addr; 1294 in6 = &ifatoia6(ifa)->ia_addr.sin6_addr;
1301 anycast = ifatoia6(ifa)->ia6_flags & IN6_IFF_ANYCAST; 1295 anycast = ifatoia6(ifa)->ia6_flags & IN6_IFF_ANYCAST;
1302 1296
1303 in6_all = in6addr_linklocal_allnodes; 1297 in6_all = in6addr_linklocal_allnodes;
1304 if ((rc = in6_setscope(&in6_all, ifa->ifa_ifp, NULL)) != 0) { 1298 if ((rc = in6_setscope(&in6_all, ifa->ifa_ifp, NULL)) != 0) {
1305 log(LOG_ERR, "%s: failed to set scope %s " 1299 log(LOG_ERR, "%s: failed to set scope %s "
1306 "(errno=%d)\n", __func__, if_name(ifp), rc); 1300 "(errno=%d)\n", __func__, if_name(ifp), rc);
1307 return; 1301 return;
1308 } 1302 }
1309 1303
1310 /* XXX don't set Override for proxy addresses */ 1304 /* XXX don't set Override for proxy addresses */
1311 nd6_na_output(ifa->ifa_ifp, &in6_all, in6, 1305 nd6_na_output(ifa->ifa_ifp, &in6_all, in6,
1312 (anycast ? 0 : ND_NA_FLAG_OVERRIDE) 1306 (anycast ? 0 : ND_NA_FLAG_OVERRIDE)
1313#if 0 1307#if 0
1314 | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0) 1308 | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0)
1315#endif 1309#endif
1316 , 1, NULL); 1310 , 1, NULL);
1317 return; 1311 return;
1318 } 1312 }
1319 1313
1320 if ((rt->rt_flags & RTF_GATEWAY) != 0) 1314 if ((rt->rt_flags & RTF_GATEWAY) != 0)
1321 return; 1315 return;
1322 1316
1323 if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) { 1317 if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) {
1324 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1318 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1325 /* 1319 /*
1326 * This is probably an interface direct route for a link 1320 * This is probably an interface direct route for a link
1327 * which does not need neighbor caches (e.g. fe80::%lo0/64). 1321 * which does not need neighbor caches (e.g. fe80::%lo0/64).
1328 * We do not need special treatment below for such a route. 1322 * We do not need special treatment below for such a route.
1329 * Moreover, the RTF_LLINFO flag which would be set below 1323 * Moreover, the RTF_LLINFO flag which would be set below
1330 * would annoy the ndp(8) command. 1324 * would annoy the ndp(8) command.
1331 */ 1325 */
1332 return; 1326 return;
1333 } 1327 }
1334 1328
1335 IF_AFDATA_RLOCK(ifp); 1329 IF_AFDATA_RLOCK(ifp);
1336 ln = lla_lookup(LLTABLE6(ifp), flags, rt_getkey(rt)); 1330 ln = lla_lookup(LLTABLE6(ifp), flags, rt_getkey(rt));
1337 IF_AFDATA_RUNLOCK(ifp); 1331 IF_AFDATA_RUNLOCK(ifp);
1338 1332
1339 if (req == RTM_RESOLVE && 1333 if (req == RTM_RESOLVE &&
1340 (nd6_need_cache(ifp) == 0 || /* stf case */ 1334 (nd6_need_cache(ifp) == 0 || /* stf case */
1341 !nd6_is_addr_neighbor(satocsin6(rt_getkey(rt)), ifp))) { 1335 !nd6_is_addr_neighbor(satocsin6(rt_getkey(rt)), ifp))) {
1342 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1336 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1343 /* 1337 /*
1344 * FreeBSD and BSD/OS often make a cloned host route based 1338 * FreeBSD and BSD/OS often make a cloned host route based
1345 * on a less-specific route (e.g. the default route). 1339 * on a less-specific route (e.g. the default route).
1346 * If the less specific route does not have a "gateway" 1340 * If the less specific route does not have a "gateway"
1347 * (this is the case when the route just goes to a p2p or an 1341 * (this is the case when the route just goes to a p2p or an
1348 * stf interface), we'll mistakenly make a neighbor cache for 1342 * stf interface), we'll mistakenly make a neighbor cache for
1349 * the host route, and will see strange neighbor solicitation 1343 * the host route, and will see strange neighbor solicitation
1350 * for the corresponding destination. In order to avoid the 1344 * for the corresponding destination. In order to avoid the
1351 * confusion, we check if the destination of the route is 1345 * confusion, we check if the destination of the route is
1352 * a neighbor in terms of neighbor discovery, and stop the 1346 * a neighbor in terms of neighbor discovery, and stop the
1353 * process if not. Additionally, we remove the LLINFO flag 1347 * process if not. Additionally, we remove the LLINFO flag
1354 * so that ndp(8) will not try to get the neighbor information 1348 * so that ndp(8) will not try to get the neighbor information
1355 * of the destination. 1349 * of the destination.
1356 */ 1350 */
1357 rt->rt_flags &= ~RTF_LLINFO; 1351 rt->rt_flags &= ~RTF_LLINFO;
1358 return; 1352 return;
1359 } 1353 }
1360 1354
1361 switch (req) { 1355 switch (req) {
1362 case RTM_ADD: 1356 case RTM_ADD:
1363 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1357 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1364 /* 1358 /*
1365 * There is no backward compatibility :) 1359 * There is no backward compatibility :)
1366 * 1360 *
1367 * if ((rt->rt_flags & RTF_HOST) == 0 && 1361 * if ((rt->rt_flags & RTF_HOST) == 0 &&
1368 * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff) 1362 * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
1369 * rt->rt_flags |= RTF_CLONING; 1363 * rt->rt_flags |= RTF_CLONING;
1370 */ 1364 */
1371 if ((rt->rt_flags & RTF_CLONING) || 1365 if ((rt->rt_flags & RTF_CLONING) ||
1372 ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && ln == NULL)) { 1366 ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && ln == NULL)) {
1373 union { 1367 union {
1374 struct sockaddr sa; 1368 struct sockaddr sa;
1375 struct sockaddr_dl sdl; 1369 struct sockaddr_dl sdl;
1376 struct sockaddr_storage ss; 1370 struct sockaddr_storage ss;
1377 } u; 1371 } u;
1378 /* 1372 /*
1379 * Case 1: This route should come from a route to 1373 * Case 1: This route should come from a route to
1380 * interface (RTF_CLONING case) or the route should be 1374 * interface (RTF_CLONING case) or the route should be
1381 * treated as on-link but is currently not 1375 * treated as on-link but is currently not
1382 * (RTF_LLINFO && ln == NULL case). 1376 * (RTF_LLINFO && ln == NULL case).
1383 */ 1377 */
1384 if (sockaddr_dl_init(&u.sdl, sizeof(u.ss), 1378 if (sockaddr_dl_init(&u.sdl, sizeof(u.ss),
1385 ifp->if_index, ifp->if_type, 1379 ifp->if_index, ifp->if_type,
1386 NULL, namelen, NULL, addrlen) == NULL) { 1380 NULL, namelen, NULL, addrlen) == NULL) {
1387 printf("%s.%d: sockaddr_dl_init(, %zu, ) " 1381 printf("%s.%d: sockaddr_dl_init(, %zu, ) "
1388 "failed on %s\n", __func__, __LINE__, 1382 "failed on %s\n", __func__, __LINE__,
1389 sizeof(u.ss), if_name(ifp)); 1383 sizeof(u.ss), if_name(ifp));
1390 } 1384 }
1391 rt_setgate(rt, &u.sa); 1385 rt_setgate(rt, &u.sa);
1392 gate = rt->rt_gateway; 1386 gate = rt->rt_gateway;
1393 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1387 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1394 if (ln != NULL) 1388 if (ln != NULL)
1395 nd6_llinfo_settimer_locked(ln, 0); 1389 nd6_llinfo_settimer_locked(ln, 0);
1396 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1390 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1397 if ((rt->rt_flags & RTF_CLONING) != 0) 1391 if ((rt->rt_flags & RTF_CLONING) != 0)
1398 break; 1392 break;
1399 } 1393 }
1400 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1394 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1401 /* 1395 /*
1402 * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here. 1396 * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here.
1403 * We don't do that here since llinfo is not ready yet. 1397 * We don't do that here since llinfo is not ready yet.
1404 * 1398 *
1405 * There are also couple of other things to be discussed: 1399 * There are also couple of other things to be discussed:
1406 * - unsolicited NA code needs improvement beforehand 1400 * - unsolicited NA code needs improvement beforehand
1407 * - RFC2461 says we MAY send multicast unsolicited NA 1401 * - RFC2461 says we MAY send multicast unsolicited NA
1408 * (7.2.6 paragraph 4), however, it also says that we 1402 * (7.2.6 paragraph 4), however, it also says that we
1409 * SHOULD provide a mechanism to prevent multicast NA storm. 1403 * SHOULD provide a mechanism to prevent multicast NA storm.
1410 * we don't have anything like it right now. 1404 * we don't have anything like it right now.
1411 * note that the mechanism needs a mutual agreement 1405 * note that the mechanism needs a mutual agreement
1412 * between proxies, which means that we need to implement 1406 * between proxies, which means that we need to implement
1413 * a new protocol, or a new kludge. 1407 * a new protocol, or a new kludge.
1414 * - from RFC2461 6.2.4, host MUST NOT send an unsolicited NA. 1408 * - from RFC2461 6.2.4, host MUST NOT send an unsolicited NA.
1415 * we need to check ip6forwarding before sending it. 1409 * we need to check ip6forwarding before sending it.
1416 * (or should we allow proxy ND configuration only for 1410 * (or should we allow proxy ND configuration only for
1417 * routers? there's no mention about proxy ND from hosts) 1411 * routers? there's no mention about proxy ND from hosts)
1418 */ 1412 */
1419#if 0 1413#if 0
1420 /* XXX it does not work */ 1414 /* XXX it does not work */
1421 if (rt->rt_flags & RTF_ANNOUNCE) 1415 if (rt->rt_flags & RTF_ANNOUNCE)
1422 nd6_na_output(ifp, 1416 nd6_na_output(ifp,
1423 &satocsin6(rt_getkey(rt))->sin6_addr, 1417 &satocsin6(rt_getkey(rt))->sin6_addr,
1424 &satocsin6(rt_getkey(rt))->sin6_addr, 1418 &satocsin6(rt_getkey(rt))->sin6_addr,
1425 ip6_forwarding ? ND_NA_FLAG_ROUTER : 0, 1419 ip6_forwarding ? ND_NA_FLAG_ROUTER : 0,
1426 1, NULL); 1420 1, NULL);
1427#endif 1421#endif
1428 /* FALLTHROUGH */ 1422 /* FALLTHROUGH */
1429 case RTM_RESOLVE: 1423 case RTM_RESOLVE:
1430 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) { 1424 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) {
1431 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1425 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1432 /* 1426 /*
1433 * Address resolution isn't necessary for a point to 1427 * Address resolution isn't necessary for a point to
1434 * point link, so we can skip this test for a p2p link. 1428 * point link, so we can skip this test for a p2p link.
1435 */ 1429 */
1436 if (gate->sa_family != AF_LINK || 1430 if (gate->sa_family != AF_LINK ||
1437 gate->sa_len < 1431 gate->sa_len <
1438 sockaddr_dl_measure(namelen, addrlen)) { 1432 sockaddr_dl_measure(namelen, addrlen)) {
1439 log(LOG_DEBUG, 1433 log(LOG_DEBUG,
1440 "nd6_rtrequest: bad gateway value: %s\n", 1434 "nd6_rtrequest: bad gateway value: %s\n",
1441 if_name(ifp)); 1435 if_name(ifp));
1442 break; 1436 break;
1443 } 1437 }
1444 satosdl(gate)->sdl_type = ifp->if_type; 1438 satosdl(gate)->sdl_type = ifp->if_type;
1445 satosdl(gate)->sdl_index = ifp->if_index; 1439 satosdl(gate)->sdl_index = ifp->if_index;
1446 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1440 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1447 } 1441 }
1448 if (ln != NULL) 1442 if (ln != NULL)
1449 break; /* This happens on a route change */ 1443 break; /* This happens on a route change */
1450 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1444 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1451 1445
1452 /* Determine to use lo0ifp or not before lla_create */ 1446 /* Determine to use lo0ifp or not before lla_create */
1453 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, 1447 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp,
1454 &satocsin6(rt_getkey(rt))->sin6_addr); 1448 &satocsin6(rt_getkey(rt))->sin6_addr);
1455 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1449 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1456 if (ifa != NULL && nd6_useloopback) 1450 if (ifa != NULL && nd6_useloopback)
1457 use_lo0ifp = true; 1451 use_lo0ifp = true;
1458 1452
1459 /* 1453 /*
1460 * Case 2: This route may come from cloning, or a manual route 1454 * Case 2: This route may come from cloning, or a manual route
1461 * add with a LL address. 1455 * add with a LL address.
1462 */ 1456 */
1463 flags = LLE_EXCLUSIVE; 1457 flags = LLE_EXCLUSIVE;
1464 if ((rt->rt_flags & RTF_CLONED) == 0) 1458 if ((rt->rt_flags & RTF_CLONED) == 0)
1465 flags |= LLE_IFADDR; 1459 flags |= LLE_IFADDR;
1466 1460
1467#define _IFP() (use_lo0ifp ? lo0ifp : ifp) 1461#define _IFP() (use_lo0ifp ? lo0ifp : ifp)
1468 IF_AFDATA_WLOCK(_IFP()); 1462 IF_AFDATA_WLOCK(_IFP());
1469 ln = lla_create(LLTABLE6(_IFP()), flags, rt_getkey(rt)); 1463 ln = lla_create(LLTABLE6(_IFP()), flags, rt_getkey(rt));
1470 IF_AFDATA_WUNLOCK(_IFP()); 1464 IF_AFDATA_WUNLOCK(_IFP());
1471 1465
1472 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1466 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1473 if (ln == NULL) { 1467 if (ln == NULL) {
1474 log(LOG_DEBUG, "nd6_rtrequest: malloc failed\n"); 1468 log(LOG_DEBUG, "nd6_rtrequest: malloc failed\n");
1475 break; 1469 break;
1476 } 1470 }
1477 1471
1478 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1472 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1479 nd6_inuse++; 1473 nd6_inuse++;
1480 nd6_allocated++; 1474 nd6_allocated++;
1481 ln->ln_rt = rt; 1475 ln->ln_rt = rt;
1482 rt->rt_refcnt++; 1476 rt->rt_refcnt++;
1483 rt->rt_llinfo = ln; 1477 rt->rt_llinfo = ln;
1484 LLE_ADDREF(ln); 1478 LLE_ADDREF(ln);
1485 rt->rt_flags |= RTF_LLINFO; 1479 rt->rt_flags |= RTF_LLINFO;
1486 switch (_IFP()->if_type) { 1480 switch (_IFP()->if_type) {
1487#if NTOKEN > 0 1481#if NTOKEN > 0
1488 case IFT_ISO88025: 1482 case IFT_ISO88025:
1489 ln->la_opaque = kmem_alloc(sizeof(struct token_rif), 1483 ln->la_opaque = kmem_alloc(sizeof(struct token_rif),
1490 KM_SLEEP); 1484 KM_SLEEP);
1491 break; 1485 break;
1492#endif /* NTOKEN > 0 */ 1486#endif /* NTOKEN > 0 */
1493 default: 1487 default:
1494 break; 1488 break;
1495 } 1489 }
1496#undef _IFP 1490#undef _IFP
1497 1491
1498 /* this is required for "ndp" command. - shin */ 1492 /* this is required for "ndp" command. - shin */
1499 if (req == RTM_ADD) { 1493 if (req == RTM_ADD) {
1500 /* 1494 /*
1501 * gate should have some valid AF_LINK entry, 1495 * gate should have some valid AF_LINK entry,
1502 * and ln->ln_expire should have some lifetime 1496 * and ln->ln_expire should have some lifetime
1503 * which is specified by ndp command. 1497 * which is specified by ndp command.
1504 */ 1498 */
1505 ln->ln_state = ND6_LLINFO_REACHABLE; 1499 ln->ln_state = ND6_LLINFO_REACHABLE;
1506 ln->ln_byhint = 0; 1500 ln->ln_byhint = 0;
1507 } else { 1501 } else {
1508 /* 1502 /*
1509 * When req == RTM_RESOLVE, rt is created and 1503 * When req == RTM_RESOLVE, rt is created and
1510 * initialized in rtrequest(), so rt_expire is 0. 1504 * initialized in rtrequest(), so rt_expire is 0.
1511 */ 1505 */
1512 ln->ln_state = ND6_LLINFO_NOSTATE; 1506 ln->ln_state = ND6_LLINFO_NOSTATE;
1513 nd6_llinfo_settimer_locked(ln, 0); 1507 nd6_llinfo_settimer_locked(ln, 0);
1514 } 1508 }
1515 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt)); 1509 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
1516 1510
1517 /* 1511 /*
1518 * check if rt_getkey(rt) is an address assigned 1512 * check if rt_getkey(rt) is an address assigned
1519 * to the interface. 1513 * to the interface.
1520 */ 1514 */
1521 if (ifa != NULL) { 1515 if (ifa != NULL) {
1522 const void *mac; 1516 const void *mac;
1523 nd6_llinfo_settimer_locked(ln, -1); 1517 nd6_llinfo_settimer_locked(ln, -1);
1524 ln->ln_state = ND6_LLINFO_REACHABLE; 1518 ln->ln_state = ND6_LLINFO_REACHABLE;
1525 ln->ln_byhint = 0; 1519 ln->ln_byhint = 0;
1526 if ((mac = nd6_ifptomac(ifp)) != NULL) { 1520 if ((mac = nd6_ifptomac(ifp)) != NULL) {
1527 /* XXX check for error */ 1521 /* XXX check for error */
1528 if (sockaddr_dl_setaddr(satosdl(gate), 1522 if (sockaddr_dl_setaddr(satosdl(gate),
1529 gate->sa_len, mac, 1523 gate->sa_len, mac,
1530 ifp->if_addrlen) == NULL) { 1524 ifp->if_addrlen) == NULL) {
1531 printf("%s.%d: " 1525 printf("%s.%d: "
1532 "sockaddr_dl_setaddr(, %d, ) " 1526 "sockaddr_dl_setaddr(, %d, ) "
1533 "failed on %s\n", __func__, 1527 "failed on %s\n", __func__,
1534 __LINE__, gate->sa_len, 1528 __LINE__, gate->sa_len,
1535 if_name(ifp)); 1529 if_name(ifp));
1536 } 1530 }
1537 } 1531 }
1538 if (nd6_useloopback) { 1532 if (nd6_useloopback) {
1539 ifp = rt->rt_ifp = lo0ifp; /* XXX */ 1533 ifp = rt->rt_ifp = lo0ifp; /* XXX */
1540 /* 1534 /*
1541 * Make sure rt_ifa be equal to the ifaddr 1535 * Make sure rt_ifa be equal to the ifaddr
1542 * corresponding to the address. 1536 * corresponding to the address.
1543 * We need this because when we refer 1537 * We need this because when we refer
1544 * rt_ifa->ia6_flags in ip6_input, we assume 1538 * rt_ifa->ia6_flags in ip6_input, we assume
1545 * that the rt_ifa points to the address instead 1539 * that the rt_ifa points to the address instead
1546 * of the loopback address. 1540 * of the loopback address.
1547 */ 1541 */
1548 if (ifa != rt->rt_ifa) 1542 if (ifa != rt->rt_ifa)
1549 rt_replace_ifa(rt, ifa); 1543 rt_replace_ifa(rt, ifa);
1550 rt->rt_rmx.rmx_mtu = 0; 1544 rt->rt_rmx.rmx_mtu = 0;
1551 rt->rt_flags &= ~RTF_CLONED; 1545 rt->rt_flags &= ~RTF_CLONED;
1552 } 1546 }
1553 rt->rt_flags |= RTF_LOCAL; 1547 rt->rt_flags |= RTF_LOCAL;
1554 } else if (rt->rt_flags & RTF_ANNOUNCE) { 1548 } else if (rt->rt_flags & RTF_ANNOUNCE) {
1555 nd6_llinfo_settimer_locked(ln, -1); 1549 nd6_llinfo_settimer_locked(ln, -1);
1556 ln->ln_state = ND6_LLINFO_REACHABLE; 1550 ln->ln_state = ND6_LLINFO_REACHABLE;
1557 ln->ln_byhint = 0; 1551 ln->ln_byhint = 0;
1558 1552
1559 /* join solicited node multicast for proxy ND */ 1553 /* join solicited node multicast for proxy ND */
1560 if (ifp->if_flags & IFF_MULTICAST) { 1554 if (ifp->if_flags & IFF_MULTICAST) {
1561 struct in6_addr llsol; 1555 struct in6_addr llsol;
1562 int error; 1556 int error;
1563 1557
1564 llsol = satocsin6(rt_getkey(rt))->sin6_addr; 1558 llsol = satocsin6(rt_getkey(rt))->sin6_addr;
1565 llsol.s6_addr32[0] = htonl(0xff020000); 1559 llsol.s6_addr32[0] = htonl(0xff020000);
1566 llsol.s6_addr32[1] = 0; 1560 llsol.s6_addr32[1] = 0;
1567 llsol.s6_addr32[2] = htonl(1); 1561 llsol.s6_addr32[2] = htonl(1);
1568 llsol.s6_addr8[12] = 0xff; 1562 llsol.s6_addr8[12] = 0xff;
1569 if (in6_setscope(&llsol, ifp, NULL)) 1563 if (in6_setscope(&llsol, ifp, NULL))
1570 break; 1564 break;
1571 if (!in6_addmulti(&llsol, ifp, &error, 0)) { 1565 if (!in6_addmulti(&llsol, ifp, &error, 0)) {
1572 nd6log((LOG_ERR, "%s: failed to join " 1566 nd6log((LOG_ERR, "%s: failed to join "
1573 "%s (errno=%d)\n", if_name(ifp), 1567 "%s (errno=%d)\n", if_name(ifp),
1574 ip6_sprintf(&llsol), error)); 1568 ip6_sprintf(&llsol), error));
1575 } 1569 }
1576 } 1570 }
1577 } 1571 }
1578 LLE_WUNLOCK(ln); 1572 LLE_WUNLOCK(ln);
1579 /* 1573 /*
1580 * If we have too many cache entries, initiate immediate 1574 * If we have too many cache entries, initiate immediate
1581 * purging for some entries. 1575 * purging for some entries.
1582 */ 1576 */
1583 nd6_gc_neighbors(ln->lle_tbl); 1577 nd6_gc_neighbors(ln->lle_tbl);
1584 ln = NULL; 1578 ln = NULL;
1585 1579
1586 break; 1580 break;
1587 1581
1588 case RTM_DELETE: 1582 case RTM_DELETE:
1589 if (ln == NULL) 1583 if (ln == NULL)
1590 break; 1584 break;
1591 /* leave from solicited node multicast for proxy ND */ 1585 /* leave from solicited node multicast for proxy ND */
1592 if ((rt->rt_flags & RTF_ANNOUNCE) != 0 && 1586 if ((rt->rt_flags & RTF_ANNOUNCE) != 0 &&
1593 (ifp->if_flags & IFF_MULTICAST) != 0) { 1587 (ifp->if_flags & IFF_MULTICAST) != 0) {
1594 struct in6_addr llsol; 1588 struct in6_addr llsol;

cvs diff -r1.69 -r1.70 src/sys/netinet6/nd6.h (switch to unified diff)

--- src/sys/netinet6/nd6.h 2015/12/07 06:19:13 1.69
+++ src/sys/netinet6/nd6.h 2016/04/01 05:11:38 1.70
@@ -1,459 +1,456 @@ @@ -1,459 +1,456 @@
1/* $NetBSD: nd6.h,v 1.69 2015/12/07 06:19:13 ozaki-r Exp $ */ 1/* $NetBSD: nd6.h,v 1.70 2016/04/01 05:11:38 ozaki-r Exp $ */
2/* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */ 2/* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 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#ifndef _NETINET6_ND6_H_ 33#ifndef _NETINET6_ND6_H_
34#define _NETINET6_ND6_H_ 34#define _NETINET6_ND6_H_
35 35
36#include <sys/queue.h> 36#include <sys/queue.h>
37#include <sys/callout.h> 37#include <sys/callout.h>
38 38
39#define ND6_LLINFO_PURGE -3 39#define ND6_LLINFO_PURGE -3
40#define ND6_LLINFO_NOSTATE -2 40#define ND6_LLINFO_NOSTATE -2
41/* 41/*
42 * We don't need the WAITDELETE state any more, but we keep the definition 42 * We don't need the WAITDELETE state any more, but we keep the definition
43 * in a comment line instead of removing it. This is necessary to avoid 43 * in a comment line instead of removing it. This is necessary to avoid
44 * unintentionally reusing the value for another purpose, which might 44 * unintentionally reusing the value for another purpose, which might
45 * affect backward compatibility with old applications. 45 * affect backward compatibility with old applications.
46 * (20000711 jinmei@kame.net) 46 * (20000711 jinmei@kame.net)
47 */ 47 */
48/* #define ND6_LLINFO_WAITDELETE -1 */ 48/* #define ND6_LLINFO_WAITDELETE -1 */
49#define ND6_LLINFO_INCOMPLETE 0 49#define ND6_LLINFO_INCOMPLETE 0
50#define ND6_LLINFO_REACHABLE 1 50#define ND6_LLINFO_REACHABLE 1
51#define ND6_LLINFO_STALE 2 51#define ND6_LLINFO_STALE 2
52#define ND6_LLINFO_DELAY 3 52#define ND6_LLINFO_DELAY 3
53#define ND6_LLINFO_PROBE 4 53#define ND6_LLINFO_PROBE 4
54 54
55#define ND6_IS_LLINFO_PROBREACH(n) ((n)->ln_state > ND6_LLINFO_INCOMPLETE) 55#define ND6_IS_LLINFO_PROBREACH(n) ((n)->ln_state > ND6_LLINFO_INCOMPLETE)
56#define ND6_LLINFO_PERMANENT(n) (((n)->ln_expire == 0) && ((n)->ln_state > ND6_LLINFO_INCOMPLETE)) 56#define ND6_LLINFO_PERMANENT(n) (((n)->ln_expire == 0) && ((n)->ln_state > ND6_LLINFO_INCOMPLETE))
57 57
58struct nd_ifinfo { 58struct nd_ifinfo {
59 u_int32_t linkmtu; /* LinkMTU */ 59 u_int32_t linkmtu; /* LinkMTU */
60 u_int32_t maxmtu; /* Upper bound of LinkMTU */ 60 u_int32_t maxmtu; /* Upper bound of LinkMTU */
61 u_int32_t basereachable; /* BaseReachableTime */ 61 u_int32_t basereachable; /* BaseReachableTime */
62 u_int32_t reachable; /* Reachable Time */ 62 u_int32_t reachable; /* Reachable Time */
63 u_int32_t retrans; /* Retrans Timer */ 63 u_int32_t retrans; /* Retrans Timer */
64 u_int32_t flags; /* Flags */ 64 u_int32_t flags; /* Flags */
65 int recalctm; /* BaseReacable re-calculation timer */ 65 int recalctm; /* BaseReacable re-calculation timer */
66 u_int8_t chlim; /* CurHopLimit */ 66 u_int8_t chlim; /* CurHopLimit */
67 u_int8_t initialized; /* Flag to see the entry is initialized */ 67 u_int8_t initialized; /* Flag to see the entry is initialized */
68 /* the following 3 members are for privacy extension for addrconf */ 68 /* the following 3 members are for privacy extension for addrconf */
69 u_int8_t randomseed0[8]; /* upper 64 bits of MD5 digest */ 69 u_int8_t randomseed0[8]; /* upper 64 bits of MD5 digest */
70 u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */ 70 u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */
71 u_int8_t randomid[8]; /* current random ID */ 71 u_int8_t randomid[8]; /* current random ID */
72}; 72};
73 73
74#define ND6_IFF_PERFORMNUD 0x01 74#define ND6_IFF_PERFORMNUD 0x01
75#define ND6_IFF_ACCEPT_RTADV 0x02 /* See "RTADV Key", below. */ 75#define ND6_IFF_ACCEPT_RTADV 0x02 /* See "RTADV Key", below. */
76#define ND6_IFF_PREFER_SOURCE 0x04 /* XXX: not related to ND. */ 76#define ND6_IFF_PREFER_SOURCE 0x04 /* XXX: not related to ND. */
77#define ND6_IFF_IFDISABLED 0x08 /* IPv6 operation is disabled due to 77#define ND6_IFF_IFDISABLED 0x08 /* IPv6 operation is disabled due to
78 * DAD failure. (XXX: not ND-specific) 78 * DAD failure. (XXX: not ND-specific)
79 */ 79 */
80#define ND6_IFF_OVERRIDE_RTADV 0x10 /* See "RTADV Key", below. */ 80#define ND6_IFF_OVERRIDE_RTADV 0x10 /* See "RTADV Key", below. */
81#define ND6_IFF_AUTO_LINKLOCAL 0x20 81#define ND6_IFF_AUTO_LINKLOCAL 0x20
82 82
83/* 83/*
84 * RTADV Key 84 * RTADV Key
85 * 85 *
86 * The flags ND6_IFF_ACCEPT_RTADV and ND6_IFF_OVERRIDE_RTADV form a 86 * The flags ND6_IFF_ACCEPT_RTADV and ND6_IFF_OVERRIDE_RTADV form a
87 * tri-state variable. (There are actually four different states, but 87 * tri-state variable. (There are actually four different states, but
88 * two of the states are functionally identical.) 88 * two of the states are functionally identical.)
89 * 89 *
90 * ND6_IFF_OVERRIDE_RTADV or 0: This interface does not accept 90 * ND6_IFF_OVERRIDE_RTADV or 0: This interface does not accept
91 * Router Advertisements. 91 * Router Advertisements.
92 * 92 *
93 * ND6_IFF_OVERRIDE_RTADV| 93 * ND6_IFF_OVERRIDE_RTADV|
94 * ND6_IFF_ACCEPT_RTADV: This interface accepts Router 94 * ND6_IFF_ACCEPT_RTADV: This interface accepts Router
95 * Advertisements regardless of the 95 * Advertisements regardless of the
96 * global setting, ip6_accept_rtadv. 96 * global setting, ip6_accept_rtadv.
97 * 97 *
98 * ND6_IFF_ACCEPT_RTADV: This interface follows the global setting, 98 * ND6_IFF_ACCEPT_RTADV: This interface follows the global setting,
99 * ip6_accept_rtadv. If ip6_accept_rtadv == 0, 99 * ip6_accept_rtadv. If ip6_accept_rtadv == 0,
100 * this interface does not accept Router 100 * this interface does not accept Router
101 * Advertisements. If ip6_accept_rtadv != 0, 101 * Advertisements. If ip6_accept_rtadv != 0,
102 * this interface does accept them. 102 * this interface does accept them.
103 */ 103 */
104 104
105#ifdef _KERNEL 105#ifdef _KERNEL
106#define ND_IFINFO(ifp) \ 106#define ND_IFINFO(ifp) \
107 (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->nd_ifinfo) 107 (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->nd_ifinfo)
108#define IN6_LINKMTU(ifp) \ 108#define IN6_LINKMTU(ifp) \
109 ((ND_IFINFO(ifp)->linkmtu && ND_IFINFO(ifp)->linkmtu < (ifp)->if_mtu) \ 109 ((ND_IFINFO(ifp)->linkmtu && ND_IFINFO(ifp)->linkmtu < (ifp)->if_mtu) \
110 ? ND_IFINFO(ifp)->linkmtu \ 110 ? ND_IFINFO(ifp)->linkmtu \
111 : ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < (ifp)->if_mtu) \ 111 : ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < (ifp)->if_mtu) \
112 ? ND_IFINFO(ifp)->maxmtu : (ifp)->if_mtu)) 112 ? ND_IFINFO(ifp)->maxmtu : (ifp)->if_mtu))
113#endif 113#endif
114 114
115struct in6_nbrinfo { 115struct in6_nbrinfo {
116 char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ 116 char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
117 struct in6_addr addr; /* IPv6 address of the neighbor */ 117 struct in6_addr addr; /* IPv6 address of the neighbor */
118 long asked; /* number of queries already sent for this addr */ 118 long asked; /* number of queries already sent for this addr */
119 int isrouter; /* if it acts as a router */ 119 int isrouter; /* if it acts as a router */
120 int state; /* reachability state */ 120 int state; /* reachability state */
121 int expire; /* lifetime for NDP state transition */ 121 int expire; /* lifetime for NDP state transition */
122}; 122};
123 123
124#define DRLSTSIZ 10 124#define DRLSTSIZ 10
125#define PRLSTSIZ 10 125#define PRLSTSIZ 10
126struct in6_drlist { 126struct in6_drlist {
127 char ifname[IFNAMSIZ]; 127 char ifname[IFNAMSIZ];
128 struct { 128 struct {
129 struct in6_addr rtaddr; 129 struct in6_addr rtaddr;
130 u_char flags; 130 u_char flags;
131 u_short rtlifetime; 131 u_short rtlifetime;
132 u_long expire; 132 u_long expire;
133 u_short if_index; 133 u_short if_index;
134 } defrouter[DRLSTSIZ]; 134 } defrouter[DRLSTSIZ];
135}; 135};
136 136
137struct in6_defrouter { 137struct in6_defrouter {
138 struct sockaddr_in6 rtaddr; 138 struct sockaddr_in6 rtaddr;
139 u_char flags; 139 u_char flags;
140 u_short rtlifetime; 140 u_short rtlifetime;
141 u_long expire; 141 u_long expire;
142 u_short if_index; 142 u_short if_index;
143}; 143};
144 144
145#ifdef _KERNEL 145#ifdef _KERNEL
146struct in6_oprlist { 146struct in6_oprlist {
147 char ifname[IFNAMSIZ]; 147 char ifname[IFNAMSIZ];
148 struct { 148 struct {
149 struct in6_addr prefix; 149 struct in6_addr prefix;
150 struct prf_ra raflags; 150 struct prf_ra raflags;
151 u_char prefixlen; 151 u_char prefixlen;
152 u_char origin; 152 u_char origin;
153 u_long vltime; 153 u_long vltime;
154 u_long pltime; 154 u_long pltime;
155 u_long expire; 155 u_long expire;
156 u_short if_index; 156 u_short if_index;
157 u_short advrtrs; /* number of advertisement routers */ 157 u_short advrtrs; /* number of advertisement routers */
158 struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */ 158 struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */
159 } prefix[PRLSTSIZ]; 159 } prefix[PRLSTSIZ];
160}; 160};
161#endif 161#endif
162 162
163struct in6_prlist { 163struct in6_prlist {
164 char ifname[IFNAMSIZ]; 164 char ifname[IFNAMSIZ];
165 struct { 165 struct {
166 struct in6_addr prefix; 166 struct in6_addr prefix;
167 struct prf_ra raflags; 167 struct prf_ra raflags;
168 u_char prefixlen; 168 u_char prefixlen;
169 u_char origin; 169 u_char origin;
170 u_int32_t vltime; 170 u_int32_t vltime;
171 u_int32_t pltime; 171 u_int32_t pltime;
172 time_t expire; 172 time_t expire;
173 u_short if_index; 173 u_short if_index;
174 u_short advrtrs; /* number of advertisement routers */ 174 u_short advrtrs; /* number of advertisement routers */
175 struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */ 175 struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */
176 } prefix[PRLSTSIZ]; 176 } prefix[PRLSTSIZ];
177}; 177};
178 178
179struct in6_prefix { 179struct in6_prefix {
180 struct sockaddr_in6 prefix; 180 struct sockaddr_in6 prefix;
181 struct prf_ra raflags; 181 struct prf_ra raflags;
182 u_char prefixlen; 182 u_char prefixlen;
183 u_char origin; 183 u_char origin;
184 u_int32_t vltime; 184 u_int32_t vltime;
185 u_int32_t pltime; 185 u_int32_t pltime;
186 time_t expire; 186 time_t expire;
187 u_int32_t flags; 187 u_int32_t flags;
188 int refcnt; 188 int refcnt;
189 u_short if_index; 189 u_short if_index;
190 u_short advrtrs; /* number of advertisement routers */ 190 u_short advrtrs; /* number of advertisement routers */
191 /* struct sockaddr_in6 advrtr[] */ 191 /* struct sockaddr_in6 advrtr[] */
192}; 192};
193 193
194#ifdef _KERNEL 194#ifdef _KERNEL
195struct in6_ondireq { 195struct in6_ondireq {
196 char ifname[IFNAMSIZ]; 196 char ifname[IFNAMSIZ];
197 struct { 197 struct {
198 u_int32_t linkmtu; /* LinkMTU */ 198 u_int32_t linkmtu; /* LinkMTU */
199 u_int32_t maxmtu; /* Upper bound of LinkMTU */ 199 u_int32_t maxmtu; /* Upper bound of LinkMTU */
200 u_int32_t basereachable; /* BaseReachableTime */ 200 u_int32_t basereachable; /* BaseReachableTime */
201 u_int32_t reachable; /* Reachable Time */ 201 u_int32_t reachable; /* Reachable Time */
202 u_int32_t retrans; /* Retrans Timer */ 202 u_int32_t retrans; /* Retrans Timer */
203 u_int32_t flags; /* Flags */ 203 u_int32_t flags; /* Flags */
204 int recalctm; /* BaseReacable re-calculation timer */ 204 int recalctm; /* BaseReacable re-calculation timer */
205 u_int8_t chlim; /* CurHopLimit */ 205 u_int8_t chlim; /* CurHopLimit */
206 u_int8_t receivedra; 206 u_int8_t receivedra;
207 } ndi; 207 } ndi;
208}; 208};
209#endif 209#endif
210 210
211struct in6_ndireq { 211struct in6_ndireq {
212 char ifname[IFNAMSIZ]; 212 char ifname[IFNAMSIZ];
213 struct nd_ifinfo ndi; 213 struct nd_ifinfo ndi;
214}; 214};
215 215
216struct in6_ndifreq { 216struct in6_ndifreq {
217 char ifname[IFNAMSIZ]; 217 char ifname[IFNAMSIZ];
218 u_long ifindex; 218 u_long ifindex;
219}; 219};
220 220
221/* Prefix status */ 221/* Prefix status */
222#define NDPRF_ONLINK 0x1 222#define NDPRF_ONLINK 0x1
223#define NDPRF_DETACHED 0x2 223#define NDPRF_DETACHED 0x2
224#define NDPRF_HOME 0x4 224#define NDPRF_HOME 0x4
225 225
226/* protocol constants */ 226/* protocol constants */
227#define MAX_RTR_SOLICITATION_DELAY 1 /* 1sec */ 227#define MAX_RTR_SOLICITATION_DELAY 1 /* 1sec */
228#define RTR_SOLICITATION_INTERVAL 4 /* 4sec */ 228#define RTR_SOLICITATION_INTERVAL 4 /* 4sec */
229#define MAX_RTR_SOLICITATIONS 3 229#define MAX_RTR_SOLICITATIONS 3
230 230
231#define ND6_INFINITE_LIFETIME ((u_int32_t)~0) 231#define ND6_INFINITE_LIFETIME ((u_int32_t)~0)
232 232
233#ifdef _KERNEL 233#ifdef _KERNEL
234/* node constants */ 234/* node constants */
235#define MAX_REACHABLE_TIME 3600000 /* msec */ 235#define MAX_REACHABLE_TIME 3600000 /* msec */
236#define REACHABLE_TIME 30000 /* msec */ 236#define REACHABLE_TIME 30000 /* msec */
237#define RETRANS_TIMER 1000 /* msec */ 237#define RETRANS_TIMER 1000 /* msec */
238#define MIN_RANDOM_FACTOR 512 /* 1024 * 0.5 */ 238#define MIN_RANDOM_FACTOR 512 /* 1024 * 0.5 */
239#define MAX_RANDOM_FACTOR 1536 /* 1024 * 1.5 */ 239#define MAX_RANDOM_FACTOR 1536 /* 1024 * 1.5 */
240#define DEF_TEMP_VALID_LIFETIME 604800 /* 1 week */ 240#define DEF_TEMP_VALID_LIFETIME 604800 /* 1 week */
241#define DEF_TEMP_PREFERRED_LIFETIME 86400 /* 1 day */ 241#define DEF_TEMP_PREFERRED_LIFETIME 86400 /* 1 day */
242#define TEMPADDR_REGEN_ADVANCE 5 /* sec */ 242#define TEMPADDR_REGEN_ADVANCE 5 /* sec */
243#define MAX_TEMP_DESYNC_FACTOR 600 /* 10 min */ 243#define MAX_TEMP_DESYNC_FACTOR 600 /* 10 min */
244#define ND_COMPUTE_RTIME(x) \ 244#define ND_COMPUTE_RTIME(x) \
245 (((MIN_RANDOM_FACTOR * (x >> 10)) + (cprng_fast32() & \ 245 (((MIN_RANDOM_FACTOR * (x >> 10)) + (cprng_fast32() & \
246 ((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000) 246 ((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000)
247 247
248TAILQ_HEAD(nd_drhead, nd_defrouter); 248TAILQ_HEAD(nd_drhead, nd_defrouter);
249struct nd_defrouter { 249struct nd_defrouter {
250 TAILQ_ENTRY(nd_defrouter) dr_entry; 250 TAILQ_ENTRY(nd_defrouter) dr_entry;
251 struct in6_addr rtaddr; 251 struct in6_addr rtaddr;
252 u_char flags; /* flags on RA message */ 252 u_char flags; /* flags on RA message */
253 u_short rtlifetime; 253 u_short rtlifetime;
254 u_long expire; 254 u_long expire;
255 struct ifnet *ifp; 255 struct ifnet *ifp;
256 int installed; /* is installed into kernel routing table */ 256 int installed; /* is installed into kernel routing table */
257}; 257};
258 258
259struct nd_prefixctl { 259struct nd_prefixctl {
260 struct ifnet *ndprc_ifp; 260 struct ifnet *ndprc_ifp;
261 261
262 /* prefix */ 262 /* prefix */
263 struct sockaddr_in6 ndprc_prefix; 263 struct sockaddr_in6 ndprc_prefix;
264 u_char ndprc_plen; 264 u_char ndprc_plen;
265 265
266 u_int32_t ndprc_vltime; /* advertised valid lifetime */ 266 u_int32_t ndprc_vltime; /* advertised valid lifetime */
267 u_int32_t ndprc_pltime; /* advertised preferred lifetime */ 267 u_int32_t ndprc_pltime; /* advertised preferred lifetime */
268 268
269 struct prf_ra ndprc_flags; 269 struct prf_ra ndprc_flags;
270}; 270};
271 271
272#define ndprc_raf ndprc_flags 272#define ndprc_raf ndprc_flags
273#define ndprc_raf_onlink ndprc_flags.onlink 273#define ndprc_raf_onlink ndprc_flags.onlink
274#define ndprc_raf_auto ndprc_flags.autonomous 274#define ndprc_raf_auto ndprc_flags.autonomous
275#define ndprc_raf_router ndprc_flags.router 275#define ndprc_raf_router ndprc_flags.router
276 276
277struct nd_prefix { 277struct nd_prefix {
278 struct ifnet *ndpr_ifp; 278 struct ifnet *ndpr_ifp;
279 LIST_ENTRY(nd_prefix) ndpr_entry; 279 LIST_ENTRY(nd_prefix) ndpr_entry;
280 struct sockaddr_in6 ndpr_prefix; /* prefix */ 280 struct sockaddr_in6 ndpr_prefix; /* prefix */
281 struct in6_addr ndpr_mask; /* netmask derived from the prefix */ 281 struct in6_addr ndpr_mask; /* netmask derived from the prefix */
282 282
283 u_int32_t ndpr_vltime; /* advertised valid lifetime */ 283 u_int32_t ndpr_vltime; /* advertised valid lifetime */
284 u_int32_t ndpr_pltime; /* advertised preferred lifetime */ 284 u_int32_t ndpr_pltime; /* advertised preferred lifetime */
285 285
286 time_t ndpr_expire; /* expiration time of the prefix */ 286 time_t ndpr_expire; /* expiration time of the prefix */
287 time_t ndpr_preferred; /* preferred time of the prefix */ 287 time_t ndpr_preferred; /* preferred time of the prefix */
288 time_t ndpr_lastupdate; /* reception time of last advertisement */ 288 time_t ndpr_lastupdate; /* reception time of last advertisement */
289 289
290 struct prf_ra ndpr_flags; 290 struct prf_ra ndpr_flags;
291 u_int32_t ndpr_stateflags; /* actual state flags */ 291 u_int32_t ndpr_stateflags; /* actual state flags */
292 /* list of routers that advertise the prefix: */ 292 /* list of routers that advertise the prefix: */
293 LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs; 293 LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs;
294 u_char ndpr_plen; 294 u_char ndpr_plen;
295 int ndpr_refcnt; /* reference couter from addresses */ 295 int ndpr_refcnt; /* reference couter from addresses */
296}; 296};
297 297
298#define ndpr_next ndpr_entry.le_next 298#define ndpr_next ndpr_entry.le_next
299 299
300#define ndpr_raf ndpr_flags 300#define ndpr_raf ndpr_flags
301#define ndpr_raf_onlink ndpr_flags.onlink 301#define ndpr_raf_onlink ndpr_flags.onlink
302#define ndpr_raf_auto ndpr_flags.autonomous 302#define ndpr_raf_auto ndpr_flags.autonomous
303#define ndpr_raf_router ndpr_flags.router 303#define ndpr_raf_router ndpr_flags.router
304 304
305/* 305/*
306 * Message format for use in obtaining information about prefixes 306 * Message format for use in obtaining information about prefixes
307 * from inet6 sysctl function 307 * from inet6 sysctl function
308 */ 308 */
309struct inet6_ndpr_msghdr { 309struct inet6_ndpr_msghdr {
310 u_short inpm_msglen; /* to skip over non-understood messages */ 310 u_short inpm_msglen; /* to skip over non-understood messages */
311 u_char inpm_version; /* future binary compatibility */ 311 u_char inpm_version; /* future binary compatibility */
312 u_char inpm_type; /* message type */ 312 u_char inpm_type; /* message type */
313 struct in6_addr inpm_prefix; 313 struct in6_addr inpm_prefix;
314 u_long prm_vltim; 314 u_long prm_vltim;
315 u_long prm_pltime; 315 u_long prm_pltime;
316 u_long prm_expire; 316 u_long prm_expire;
317 u_long prm_preferred; 317 u_long prm_preferred;
318 struct in6_prflags prm_flags; 318 struct in6_prflags prm_flags;
319 u_short prm_index; /* index for associated ifp */ 319 u_short prm_index; /* index for associated ifp */
320 u_char prm_plen; /* length of prefix in bits */ 320 u_char prm_plen; /* length of prefix in bits */
321}; 321};
322 322
323#define prm_raf_onlink prm_flags.prf_ra.onlink 323#define prm_raf_onlink prm_flags.prf_ra.onlink
324#define prm_raf_auto prm_flags.prf_ra.autonomous 324#define prm_raf_auto prm_flags.prf_ra.autonomous
325 325
326#define prm_statef_onlink prm_flags.prf_state.onlink 326#define prm_statef_onlink prm_flags.prf_state.onlink
327 327
328#define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid 328#define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid
329#define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd 329#define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd
330 330
331struct nd_pfxrouter { 331struct nd_pfxrouter {
332 LIST_ENTRY(nd_pfxrouter) pfr_entry; 332 LIST_ENTRY(nd_pfxrouter) pfr_entry;
333 struct nd_defrouter *router; 333 struct nd_defrouter *router;
334}; 334};
335 335
336LIST_HEAD(nd_prhead, nd_prefix); 336LIST_HEAD(nd_prhead, nd_prefix);
337 337
338#include <sys/mallocvar.h> 338#include <sys/mallocvar.h>
339MALLOC_DECLARE(M_IP6NDP); 339MALLOC_DECLARE(M_IP6NDP);
340 340
341/* nd6.c */ 341/* nd6.c */
342extern int nd6_prune; 342extern int nd6_prune;
343extern int nd6_delay; 343extern int nd6_delay;
344extern int nd6_umaxtries; 344extern int nd6_umaxtries;
345extern int nd6_mmaxtries; 345extern int nd6_mmaxtries;
346extern int nd6_useloopback; 346extern int nd6_useloopback;
347extern int nd6_maxnudhint; 347extern int nd6_maxnudhint;
348extern int nd6_gctimer; 348extern int nd6_gctimer;
349extern struct nd_drhead nd_defrouter; 349extern struct nd_drhead nd_defrouter;
350extern struct nd_prhead nd_prefix; 350extern struct nd_prhead nd_prefix;
351extern int nd6_debug; 351extern int nd6_debug;
352 352
353#define nd6log(x) do { if (nd6_debug) log x; } while (/*CONSTCOND*/ 0) 353#define nd6log(x) do { if (nd6_debug) log x; } while (/*CONSTCOND*/ 0)
354 354
355extern struct callout nd6_timer_ch; 
356 
357/* nd6_rtr.c */ 355/* nd6_rtr.c */
358extern int nd6_defifindex; 356extern int nd6_defifindex;
359extern int ip6_desync_factor; /* seconds */ 357extern int ip6_desync_factor; /* seconds */
360extern u_int32_t ip6_temp_preferred_lifetime; /* seconds */ 358extern u_int32_t ip6_temp_preferred_lifetime; /* seconds */
361extern u_int32_t ip6_temp_valid_lifetime; /* seconds */ 359extern u_int32_t ip6_temp_valid_lifetime; /* seconds */
362extern int ip6_temp_regen_advance; /* seconds */ 360extern int ip6_temp_regen_advance; /* seconds */
363extern int nd6_numroutes; 361extern int nd6_numroutes;
364 362
365union nd_opts { 363union nd_opts {
366 struct nd_opt_hdr *nd_opt_array[8]; 364 struct nd_opt_hdr *nd_opt_array[8];
367 struct { 365 struct {
368 struct nd_opt_hdr *zero; 366 struct nd_opt_hdr *zero;
369 struct nd_opt_hdr *src_lladdr; 367 struct nd_opt_hdr *src_lladdr;
370 struct nd_opt_hdr *tgt_lladdr; 368 struct nd_opt_hdr *tgt_lladdr;
371 struct nd_opt_prefix_info *pi_beg; /* multiple opts, start */ 369 struct nd_opt_prefix_info *pi_beg; /* multiple opts, start */
372 struct nd_opt_rd_hdr *rh; 370 struct nd_opt_rd_hdr *rh;
373 struct nd_opt_mtu *mtu; 371 struct nd_opt_mtu *mtu;
374 struct nd_opt_hdr *search; /* multiple opts */ 372 struct nd_opt_hdr *search; /* multiple opts */
375 struct nd_opt_hdr *last; /* multiple opts */ 373 struct nd_opt_hdr *last; /* multiple opts */
376 int done; 374 int done;
377 struct nd_opt_prefix_info *pi_end;/* multiple opts, end */ 375 struct nd_opt_prefix_info *pi_end;/* multiple opts, end */
378 } nd_opt_each; 376 } nd_opt_each;
379}; 377};
380#define nd_opts_src_lladdr nd_opt_each.src_lladdr 378#define nd_opts_src_lladdr nd_opt_each.src_lladdr
381#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr 379#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr
382#define nd_opts_pi nd_opt_each.pi_beg 380#define nd_opts_pi nd_opt_each.pi_beg
383#define nd_opts_pi_end nd_opt_each.pi_end 381#define nd_opts_pi_end nd_opt_each.pi_end
384#define nd_opts_rh nd_opt_each.rh 382#define nd_opts_rh nd_opt_each.rh
385#define nd_opts_mtu nd_opt_each.mtu 383#define nd_opts_mtu nd_opt_each.mtu
386#define nd_opts_search nd_opt_each.search 384#define nd_opts_search nd_opt_each.search
387#define nd_opts_last nd_opt_each.last 385#define nd_opts_last nd_opt_each.last
388#define nd_opts_done nd_opt_each.done 386#define nd_opts_done nd_opt_each.done
389 387
390#include <net/if_llatbl.h> 388#include <net/if_llatbl.h>
391 389
392/* XXX: need nd6_var.h?? */ 390/* XXX: need nd6_var.h?? */
393/* nd6.c */ 391/* nd6.c */
394void nd6_init(void); 392void nd6_init(void);
395struct nd_ifinfo *nd6_ifattach(struct ifnet *); 393struct nd_ifinfo *nd6_ifattach(struct ifnet *);
396void nd6_ifdetach(struct ifnet *, struct in6_ifextra *); 394void nd6_ifdetach(struct ifnet *, struct in6_ifextra *);
397int nd6_is_addr_neighbor(const struct sockaddr_in6 *, struct ifnet *); 395int nd6_is_addr_neighbor(const struct sockaddr_in6 *, struct ifnet *);
398void nd6_option_init(void *, int, union nd_opts *); 396void nd6_option_init(void *, int, union nd_opts *);
399struct nd_opt_hdr *nd6_option(union nd_opts *); 397struct nd_opt_hdr *nd6_option(union nd_opts *);
400int nd6_options(union nd_opts *); 398int nd6_options(union nd_opts *);
401struct rtentry *nd6_lookup(const struct in6_addr *, int, struct ifnet *); 399struct rtentry *nd6_lookup(const struct in6_addr *, int, struct ifnet *);
402void nd6_setmtu(struct ifnet *); 400void nd6_setmtu(struct ifnet *);
403void nd6_llinfo_settimer(struct llentry *, time_t); 401void nd6_llinfo_settimer(struct llentry *, time_t);
404void nd6_llinfo_settimer_locked(struct llentry *, time_t); 402void nd6_llinfo_settimer_locked(struct llentry *, time_t);
405void nd6_timer(void *); 
406void nd6_purge(struct ifnet *, struct in6_ifextra *); 403void nd6_purge(struct ifnet *, struct in6_ifextra *);
407void nd6_nud_hint(struct rtentry *); 404void nd6_nud_hint(struct rtentry *);
408int nd6_resolve(struct ifnet *, struct rtentry *, 405int nd6_resolve(struct ifnet *, struct rtentry *,
409 struct mbuf *, struct sockaddr *, u_char *); 406 struct mbuf *, struct sockaddr *, u_char *);
410void nd6_rtrequest(int, struct rtentry *, const struct rt_addrinfo *); 407void nd6_rtrequest(int, struct rtentry *, const struct rt_addrinfo *);
411int nd6_ioctl(u_long, void *, struct ifnet *); 408int nd6_ioctl(u_long, void *, struct ifnet *);
412void nd6_cache_lladdr(struct ifnet *, struct in6_addr *, 409void nd6_cache_lladdr(struct ifnet *, struct in6_addr *,
413 char *, int, int, int); 410 char *, int, int, int);
414int nd6_output(struct ifnet *, struct ifnet *, struct mbuf *, 411int nd6_output(struct ifnet *, struct ifnet *, struct mbuf *,
415 const struct sockaddr_in6 *, struct rtentry *); 412 const struct sockaddr_in6 *, struct rtentry *);
416int nd6_storelladdr(const struct ifnet *, const struct rtentry *, struct mbuf *, 413int nd6_storelladdr(const struct ifnet *, const struct rtentry *, struct mbuf *,
417 const struct sockaddr *, uint8_t *, size_t); 414 const struct sockaddr *, uint8_t *, size_t);
418int nd6_sysctl(int, void *, size_t *, void *, size_t); 415int nd6_sysctl(int, void *, size_t *, void *, size_t);
419int nd6_need_cache(struct ifnet *); 416int nd6_need_cache(struct ifnet *);
420void nd6_llinfo_release_pkts(struct llentry *, struct ifnet *, 417void nd6_llinfo_release_pkts(struct llentry *, struct ifnet *,
421 struct rtentry *); 418 struct rtentry *);
422 419
423/* nd6_nbr.c */ 420/* nd6_nbr.c */
424void nd6_na_input(struct mbuf *, int, int); 421void nd6_na_input(struct mbuf *, int, int);
425void nd6_na_output(struct ifnet *, const struct in6_addr *, 422void nd6_na_output(struct ifnet *, const struct in6_addr *,
426 const struct in6_addr *, u_long, int, const struct sockaddr *); 423 const struct in6_addr *, u_long, int, const struct sockaddr *);
427void nd6_ns_input(struct mbuf *, int, int); 424void nd6_ns_input(struct mbuf *, int, int);
428void nd6_ns_output(struct ifnet *, const struct in6_addr *, 425void nd6_ns_output(struct ifnet *, const struct in6_addr *,
429 const struct in6_addr *, struct in6_addr *, int); 426 const struct in6_addr *, struct in6_addr *, int);
430const void *nd6_ifptomac(const struct ifnet *); 427const void *nd6_ifptomac(const struct ifnet *);
431void nd6_dad_start(struct ifaddr *, int); 428void nd6_dad_start(struct ifaddr *, int);
432void nd6_dad_stop(struct ifaddr *); 429void nd6_dad_stop(struct ifaddr *);
433void nd6_dad_duplicated(struct ifaddr *); 430void nd6_dad_duplicated(struct ifaddr *);
434 431
435/* nd6_rtr.c */ 432/* nd6_rtr.c */
436void nd6_rs_input(struct mbuf *, int, int); 433void nd6_rs_input(struct mbuf *, int, int);
437void nd6_ra_input(struct mbuf *, int, int); 434void nd6_ra_input(struct mbuf *, int, int);
438void prelist_del(struct nd_prefix *); 435void prelist_del(struct nd_prefix *);
439void defrouter_addreq(struct nd_defrouter *); 436void defrouter_addreq(struct nd_defrouter *);
440void defrouter_reset(void); 437void defrouter_reset(void);
441void defrouter_select(void); 438void defrouter_select(void);
442void defrtrlist_del(struct nd_defrouter *, struct in6_ifextra *); 439void defrtrlist_del(struct nd_defrouter *, struct in6_ifextra *);
443void prelist_remove(struct nd_prefix *); 440void prelist_remove(struct nd_prefix *);
444int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *, 441int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *,
445 struct nd_prefix **); 442 struct nd_prefix **);
446int nd6_prefix_onlink(struct nd_prefix *); 443int nd6_prefix_onlink(struct nd_prefix *);
447int nd6_prefix_offlink(struct nd_prefix *); 444int nd6_prefix_offlink(struct nd_prefix *);
448void pfxlist_onlink_check(void); 445void pfxlist_onlink_check(void);
449struct nd_defrouter *defrouter_lookup(const struct in6_addr *, struct ifnet *); 446struct nd_defrouter *defrouter_lookup(const struct in6_addr *, struct ifnet *);
450struct nd_prefix *nd6_prefix_lookup(struct nd_prefixctl *); 447struct nd_prefix *nd6_prefix_lookup(struct nd_prefixctl *);
451int in6_ifdel(struct ifnet *, struct in6_addr *); 448int in6_ifdel(struct ifnet *, struct in6_addr *);
452void rt6_flush(struct in6_addr *, struct ifnet *); 449void rt6_flush(struct in6_addr *, struct ifnet *);
453int nd6_setdefaultiface(int); 450int nd6_setdefaultiface(int);
454int in6_tmpifadd(const struct in6_ifaddr *, int, int); 451int in6_tmpifadd(const struct in6_ifaddr *, int, int);
455bool nd6_accepts_rtadv(const struct nd_ifinfo *); 452bool nd6_accepts_rtadv(const struct nd_ifinfo *);
456 453
457#endif /* _KERNEL */ 454#endif /* _KERNEL */
458 455
459#endif /* !_NETINET6_ND6_H_ */ 456#endif /* !_NETINET6_ND6_H_ */