]> git.saurik.com Git - apple/xnu.git/blame - bsd/netinet6/nd6.h
xnu-1699.32.7.tar.gz
[apple/xnu.git] / bsd / netinet6 / nd6.h
CommitLineData
b0d623f7 1/*
6d2010ae 2 * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
b0d623f7
A
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
9bccf70c
A
29/* $FreeBSD: src/sys/netinet6/nd6.h,v 1.2.2.3 2001/08/13 01:10:49 simokawa Exp $ */
30/* $KAME: nd6.h,v 1.55 2001/04/27 15:09:49 itojun Exp $ */
1c79356b
A
31
32/*
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61#ifndef _NETINET6_ND6_H_
62#define _NETINET6_ND6_H_
9bccf70c 63#include <sys/appleapiopts.h>
1c79356b
A
64
65/* see net/route.h, or net/if_inarp.h */
66#ifndef RTF_ANNOUNCE
67#define RTF_ANNOUNCE RTF_PROTO2
68#endif
69
70#include <sys/queue.h>
71
6d2010ae 72#ifdef XNU_KERNEL_PRIVATE
b0d623f7
A
73#include <kern/locks.h>
74
1c79356b 75struct llinfo_nd6 {
b0d623f7
A
76 /*
77 * The following are protected by rnh_lock
78 */
1c79356b
A
79 struct llinfo_nd6 *ln_next;
80 struct llinfo_nd6 *ln_prev;
81 struct rtentry *ln_rt;
b0d623f7
A
82 /*
83 * The following are protected by rt_lock
84 */
1c79356b
A
85 struct mbuf *ln_hold; /* last packet until resolved/timeout */
86 long ln_asked; /* number of queries already sent for this addr */
b0d623f7 87 u_int32_t ln_expire; /* lifetime for NDP state transition */
1c79356b
A
88 short ln_state; /* reachability state */
89 short ln_router; /* 2^0: ND6 router bit */
9bccf70c 90 int ln_byhint; /* # of times we made it reachable by UL hint */
b0d623f7 91 u_int32_t ln_flags; /* flags; see below */
6d2010ae
A
92 struct if_llreach *ln_llreach; /* link-layer reachability record */
93 u_int64_t ln_lastused; /* last used timestamp */
1c79356b 94};
b0d623f7
A
95
96/* Values for ln_flags */
97#define ND6_LNF_TIMER_SKIP 0x1 /* modified by nd6_timer() */
98#define ND6_LNF_IN_USE 0x2 /* currently in llinfo_nd6 list */
6d2010ae 99#endif /* XNU_KERNEL_PRIVATE */
1c79356b 100
e2fac8b1 101#define ND6_LLINFO_PURGE -3
1c79356b 102#define ND6_LLINFO_NOSTATE -2
9bccf70c
A
103/*
104 * We don't need the WAITDELETE state any more, but we keep the definition
105 * in a comment line instead of removing it. This is necessary to avoid
106 * unintentionally reusing the value for another purpose, which might
107 * affect backward compatibility with old applications.
108 * (20000711 jinmei@kame.net)
109 */
110/* #define ND6_LLINFO_WAITDELETE -1 */
1c79356b
A
111#define ND6_LLINFO_INCOMPLETE 0
112#define ND6_LLINFO_REACHABLE 1
113#define ND6_LLINFO_STALE 2
114#define ND6_LLINFO_DELAY 3
115#define ND6_LLINFO_PROBE 4
116
6d2010ae 117#ifdef XNU_KERNEL_PRIVATE
1c79356b 118#define ND6_IS_LLINFO_PROBREACH(n) ((n)->ln_state > ND6_LLINFO_INCOMPLETE)
6d2010ae
A
119#define ND6_LLINFO_PERMANENT(n) (((n)->ln_expire == 0) && ((n)->ln_state > ND6_LLINFO_INCOMPLETE))
120#define ND6_IFF_PERFORMNUD 0x1
121#define ND6_IFF_ACCEPT_RTADV 0x2 /* APPLE: not used. Innterface specific router advertisments are
122 * handled with a specific ifnet flag: IFEF_ACCEPT_RTADVD
123 */
124#define ND6_IFF_PREFER_SOURCE 0x4 /* APPLE: NOT USED not related to ND. */
125#define ND6_IFF_IFDISABLED 0x8 /* IPv6 operation is disabled due to
126 * DAD failure. (XXX: not ND-specific)
127 */
128#define ND6_IFF_DONT_SET_IFROUTE 0x10 /* NOT USED */
129
130#endif /* XNU_KERNEL_PRIVATE */
131
132#if !defined(XNU_KERNEL_PRIVATE)
b0d623f7
A
133struct nd_ifinfo {
134#else
135/* For binary compatibility, this structure must not change */
136struct nd_ifinfo_compat {
6d2010ae 137#endif /* !XNU_KERNEL_PRIVATE */
b0d623f7
A
138 u_int32_t linkmtu; /* LinkMTU */
139 u_int32_t maxmtu; /* Upper bound of LinkMTU */
140 u_int32_t basereachable; /* BaseReachableTime */
141 u_int32_t reachable; /* Reachable Time */
142 u_int32_t retrans; /* Retrans Timer */
143 u_int32_t flags; /* Flags */
144 int recalctm; /* BaseReacable re-calculation timer */
145 u_int8_t chlim; /* CurHopLimit */
146 u_int8_t receivedra;
147 /* the following 3 members are for privacy extension for addrconf */
148 u_int8_t randomseed0[8]; /* upper 64 bits of MD5 digest */
149 u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */
150 u_int8_t randomid[8]; /* current random ID */
151};
1c79356b 152
6d2010ae 153#if defined(XNU_KERNEL_PRIVATE)
1c79356b
A
154struct nd_ifinfo {
155 u_int32_t linkmtu; /* LinkMTU */
156 u_int32_t maxmtu; /* Upper bound of LinkMTU */
157 u_int32_t basereachable; /* BaseReachableTime */
158 u_int32_t reachable; /* Reachable Time */
159 u_int32_t retrans; /* Retrans Timer */
160 u_int32_t flags; /* Flags */
161 int recalctm; /* BaseReacable re-calculation timer */
162 u_int8_t chlim; /* CurHopLimit */
6d2010ae 163 u_int8_t initialized; /* Flag to see the entry is initialized */
55e303ae 164 /* the following 3 members are for privacy extension for addrconf */
9bccf70c
A
165 u_int8_t randomseed0[8]; /* upper 64 bits of MD5 digest */
166 u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */
167 u_int8_t randomid[8]; /* current random ID */
e2fac8b1
A
168 /* keep track of routers and prefixes on this link */
169 int32_t nprefixes;
170 int32_t ndefrouters;
1c79356b 171};
6d2010ae 172#endif /* XNU_KERNEL_PRIVATE */
1c79356b
A
173
174#define ND6_IFF_PERFORMNUD 0x1
175
176struct in6_nbrinfo {
177 char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
178 struct in6_addr addr; /* IPv6 address of the neighbor */
179 long asked; /* number of queries already sent for this addr */
180 int isrouter; /* if it acts as a router */
181 int state; /* reachability state */
182 int expire; /* lifetime for NDP state transition */
183};
184
6d2010ae 185#if defined(XNU_KERNEL_PRIVATE)
b0d623f7
A
186struct in6_nbrinfo_32 {
187 char ifname[IFNAMSIZ];
188 struct in6_addr addr;
189 u_int32_t asked;
190 int isrouter;
191 int state;
192 int expire;
193};
194
195struct in6_nbrinfo_64 {
196 char ifname[IFNAMSIZ];
197 struct in6_addr addr;
198 long asked;
199 int isrouter __attribute__((aligned(8)));
200 int state;
201 int expire;
202} __attribute__((aligned(8)));
6d2010ae 203#endif /* XNU_KERNEL_PRIVATE */
b0d623f7 204
1c79356b
A
205#define DRLSTSIZ 10
206#define PRLSTSIZ 10
b0d623f7 207
1c79356b
A
208struct in6_drlist {
209 char ifname[IFNAMSIZ];
210 struct {
211 struct in6_addr rtaddr;
212 u_char flags;
213 u_short rtlifetime;
214 u_long expire;
215 u_short if_index;
216 } defrouter[DRLSTSIZ];
217};
218
6d2010ae 219#if defined(XNU_KERNEL_PRIVATE)
b0d623f7
A
220struct in6_drlist_32 {
221 char ifname[IFNAMSIZ];
222 struct {
223 struct in6_addr rtaddr;
224 u_char flags;
225 u_short rtlifetime;
226 u_int32_t expire;
227 u_short if_index;
228 } defrouter[DRLSTSIZ];
229};
230
231struct in6_drlist_64 {
232 char ifname[IFNAMSIZ];
233 struct {
234 struct in6_addr rtaddr;
235 u_char flags;
236 u_short rtlifetime;
237 u_long expire __attribute__((aligned(8)));
238 u_short if_index __attribute__((aligned(8)));
239 } defrouter[DRLSTSIZ] __attribute__((aligned(8)));
240};
6d2010ae
A
241#endif /* XNU_KERNEL_PRIVATE */
242
243/* valid values for stateflags */
244#define NDDRF_INSTALLED 0x1 /* installed in the routing table */
245#define NDDRF_IFSCOPE 0x2 /* installed as a scoped route */
246#define NDDRF_STATIC 0x4 /* for internal use only */
247#ifdef XNU_KERNEL_PRIVATE
248#define NDDRF_PROCESSED 0x10
249#endif
b0d623f7 250
9bccf70c
A
251struct in6_defrouter {
252 struct sockaddr_in6 rtaddr;
253 u_char flags;
6d2010ae 254 u_char stateflags;
9bccf70c
A
255 u_short rtlifetime;
256 u_long expire;
257 u_short if_index;
258};
259
6d2010ae 260#if defined(XNU_KERNEL_PRIVATE)
b0d623f7
A
261struct in6_defrouter_32 {
262 struct sockaddr_in6 rtaddr;
263 u_char flags;
6d2010ae 264 u_char stateflags;
b0d623f7
A
265 u_short rtlifetime;
266 u_int32_t expire;
267 u_short if_index;
268};
269
270struct in6_defrouter_64 {
271 struct sockaddr_in6 rtaddr;
272 u_char flags;
6d2010ae 273 u_char stateflags;
b0d623f7
A
274 u_short rtlifetime;
275 u_long expire __attribute__((aligned(8)));
276 u_short if_index __attribute__((aligned(8)));
277} __attribute__((aligned(8)));
6d2010ae 278#endif /* XNU_KERNEL_PRIVATE */
b0d623f7 279
1c79356b
A
280struct in6_prlist {
281 char ifname[IFNAMSIZ];
282 struct {
283 struct in6_addr prefix;
284 struct prf_ra raflags;
285 u_char prefixlen;
286 u_char origin;
287 u_long vltime;
288 u_long pltime;
289 u_long expire;
290 u_short if_index;
291 u_short advrtrs; /* number of advertisement routers */
292 struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */
293 } prefix[PRLSTSIZ];
294};
295
6d2010ae 296#if defined(XNU_KERNEL_PRIVATE)
b0d623f7
A
297struct in6_prlist_32 {
298 char ifname[IFNAMSIZ];
299 struct {
300 struct in6_addr prefix;
301 struct prf_ra raflags;
302 u_char prefixlen;
303 u_char origin;
304 u_int32_t vltime;
305 u_int32_t pltime;
306 u_int32_t expire;
307 u_short if_index;
308 u_short advrtrs;
309 struct in6_addr advrtr[DRLSTSIZ];
310 } prefix[PRLSTSIZ];
311};
312
313struct in6_prlist_64 {
314 char ifname[IFNAMSIZ];
315 struct {
316 struct in6_addr prefix;
317 struct prf_ra raflags;
318 u_char prefixlen;
319 u_char origin;
320 u_long vltime __attribute__((aligned(8)));
321 u_long pltime __attribute__((aligned(8)));
322 u_long expire __attribute__((aligned(8)));
323 u_short if_index;
324 u_short advrtrs;
325 u_int32_t pad;
326 struct in6_addr advrtr[DRLSTSIZ];
327 } prefix[PRLSTSIZ];
328};
6d2010ae 329#endif /* XNU_KERNEL_PRIVATE */
b0d623f7 330
9bccf70c
A
331struct in6_prefix {
332 struct sockaddr_in6 prefix;
333 struct prf_ra raflags;
334 u_char prefixlen;
335 u_char origin;
336 u_long vltime;
337 u_long pltime;
338 u_long expire;
339 u_int32_t flags;
340 int refcnt;
341 u_short if_index;
342 u_short advrtrs; /* number of advertisement routers */
343 /* struct sockaddr_in6 advrtr[] */
344};
345
6d2010ae 346#if defined(XNU_KERNEL_PRIVATE)
b0d623f7
A
347struct in6_prefix_32 {
348 struct sockaddr_in6 prefix;
349 struct prf_ra raflags;
350 u_char prefixlen;
351 u_char origin;
352 u_int32_t vltime;
353 u_int32_t pltime;
354 u_int32_t expire;
355 u_int32_t flags;
356 int refcnt;
357 u_short if_index;
6d2010ae 358 u_short advrtrs; /* number of advertisement routers */
b0d623f7
A
359 /* struct sockaddr_in6 advrtr[] */
360};
361
362struct in6_prefix_64 {
363 struct sockaddr_in6 prefix;
364 struct prf_ra raflags;
365 u_char prefixlen;
366 u_char origin;
367 u_long vltime __attribute__((aligned(8)));
368 u_long pltime __attribute__((aligned(8)));
369 u_long expire __attribute__((aligned(8)));
370 u_int32_t flags __attribute__((aligned(8)));
371 int refcnt;
372 u_short if_index;
373 u_short advrtrs;
374 /* struct sockaddr_in6 advrtr[] */
375};
6d2010ae 376#endif /* XNU_KERNEL_PRIVATE */
b0d623f7 377
9bccf70c
A
378struct in6_ondireq {
379 char ifname[IFNAMSIZ];
380 struct {
381 u_int32_t linkmtu; /* LinkMTU */
382 u_int32_t maxmtu; /* Upper bound of LinkMTU */
383 u_int32_t basereachable; /* BaseReachableTime */
384 u_int32_t reachable; /* Reachable Time */
385 u_int32_t retrans; /* Retrans Timer */
386 u_int32_t flags; /* Flags */
387 int recalctm; /* BaseReacable re-calculation timer */
388 u_int8_t chlim; /* CurHopLimit */
389 u_int8_t receivedra;
390 } ndi;
391};
392
6d2010ae 393#if !defined(XNU_KERNEL_PRIVATE)
1c79356b
A
394struct in6_ndireq {
395 char ifname[IFNAMSIZ];
396 struct nd_ifinfo ndi;
397};
b0d623f7
A
398#else
399struct in6_ndireq {
400 char ifname[IFNAMSIZ];
401 struct nd_ifinfo_compat ndi;
402};
6d2010ae 403#endif /* !XNU_KERNEL_PRIVATE */
1c79356b
A
404
405struct in6_ndifreq {
406 char ifname[IFNAMSIZ];
407 u_long ifindex;
408};
409
6d2010ae
A
410#define MAX_RTR_SOLICITATION_DELAY 1 /* 1sec */
411#define RTR_SOLICITATION_INTERVAL 4 /* 4sec */
412
413#if defined(XNU_KERNEL_PRIVATE)
b0d623f7
A
414struct in6_ndifreq_32 {
415 char ifname[IFNAMSIZ];
416 u_int32_t ifindex;
417};
418
419struct in6_ndifreq_64 {
420 char ifname[IFNAMSIZ];
421 u_long ifindex __attribute__((aligned(8)));
422};
6d2010ae 423#endif /* XNU_KERNEL_PRIVATE */
b0d623f7 424
9bccf70c
A
425/* Prefix status */
426#define NDPRF_ONLINK 0x1
427#define NDPRF_DETACHED 0x2
6d2010ae
A
428#define NDPRF_STATIC 0x100
429#define NDPRF_IFSCOPE 0x1000
430#ifdef XNU_KERNEL_PRIVATE
431#define NDPRF_PROCESSED 0x08000
432#endif
1c79356b
A
433
434/* protocol constants */
435#define MAX_RTR_SOLICITATION_DELAY 1 /*1sec*/
436#define RTR_SOLICITATION_INTERVAL 4 /*4sec*/
437#define MAX_RTR_SOLICITATIONS 3
438
439#define ND6_INFINITE_LIFETIME 0xffffffff
6d2010ae 440#define ND6_MAX_LIFETIME 0x7fffffff
1c79356b 441
6d2010ae 442#ifdef XNU_KERNEL_PRIVATE
b0d623f7
A
443/*
444 * Protects nd_ifinfo[]
445 */
446__private_extern__ lck_rw_t *nd_if_rwlock;
447
2d21ac55 448#define ND_IFINFO(ifp) \
b0d623f7
A
449 ((ifp)->if_index < nd_ifinfo_indexlim ? &nd_ifinfo[(ifp)->if_index] : NULL)
450
2d21ac55
A
451/*
452 * In a more readable form, we derive linkmtu based on:
453 *
454 * if (ND_IFINFO(ifp)->linkmtu && ND_IFINFO(ifp)->linkmtu < ifp->if_mtu)
455 * linkmtu = ND_IFINFO(ifp)->linkmtu;
456 * else if ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < ifp->if_mtu))
457 * linkmtu = ND_IFINFO(ifp)->maxmtu;
458 * else
459 * linkmtu = ifp->if_mtu;
460 */
461#define IN6_LINKMTU(ifp) \
b0d623f7 462 (ND_IFINFO(ifp) == NULL ? (ifp)->if_mtu : \
2d21ac55
A
463 ((ND_IFINFO(ifp)->linkmtu && \
464 ND_IFINFO(ifp)->linkmtu < (ifp)->if_mtu) ? ND_IFINFO(ifp)->linkmtu : \
465 ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < (ifp)->if_mtu) ? \
b0d623f7 466 ND_IFINFO(ifp)->maxmtu : (ifp)->if_mtu)))
2d21ac55 467
1c79356b
A
468/* node constants */
469#define MAX_REACHABLE_TIME 3600000 /* msec */
470#define REACHABLE_TIME 30000 /* msec */
471#define RETRANS_TIMER 1000 /* msec */
472#define MIN_RANDOM_FACTOR 512 /* 1024 * 0.5 */
473#define MAX_RANDOM_FACTOR 1536 /* 1024 * 1.5 */
9bccf70c
A
474#define DEF_TEMP_VALID_LIFETIME 604800 /* 1 week */
475#define DEF_TEMP_PREFERRED_LIFETIME 86400 /* 1 day */
476#define TEMPADDR_REGEN_ADVANCE 5 /* sec */
477#define MAX_TEMP_DESYNC_FACTOR 600 /* 10 min */
1c79356b
A
478#define ND_COMPUTE_RTIME(x) \
479 (((MIN_RANDOM_FACTOR * (x >> 10)) + (random() & \
480 ((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000)
1c79356b
A
481
482TAILQ_HEAD(nd_drhead, nd_defrouter);
483struct nd_defrouter {
6d2010ae
A
484 decl_lck_mtx_data(, nddr_lock);
485 uint32_t nddr_refcount;
486 uint32_t nddr_debug;
1c79356b 487 TAILQ_ENTRY(nd_defrouter) dr_entry;
6d2010ae
A
488 struct in6_addr rtaddr;
489 u_char flags; /* flags on RA message */
490 u_char stateflags;
491 u_short rtlifetime;
b0d623f7 492 u_int32_t expire;
6d2010ae
A
493 struct ifnet *ifp;
494 unsigned int genid;
495 int err;
496 void (*nddr_trace) /* callback fn for tracing refs */
497 (struct nd_defrouter *, int);
1c79356b
A
498};
499
6d2010ae
A
500#define NDDR_LOCK_ASSERT_HELD(_nddr) \
501 lck_mtx_assert(&(_nddr)->nddr_lock, LCK_MTX_ASSERT_OWNED)
502
503#define NDDR_LOCK_ASSERT_NOTHELD(_nddr) \
504 lck_mtx_assert(&(_nddr)->nddr_lock, LCK_MTX_ASSERT_NOTOWNED)
505
506#define NDDR_LOCK(_nddr) \
507 lck_mtx_lock(&(_nddr)->nddr_lock)
508
509#define NDDR_LOCK_SPIN(_nddr) \
510 lck_mtx_lock_spin(&(_nddr)->nddr_lock)
511
512#define NDDR_CONVERT_LOCK(_nddr) do { \
513 NDPR_LOCK_ASSERT_HELD(_nddr); \
514 lck_mtx_convert_spin(&(_nddr)->nddr_lock); \
515} while (0)
516
517#define NDDR_UNLOCK(_nddr) \
518 lck_mtx_unlock(&(_nddr)->nddr_lock)
519
520#define NDDR_ADDREF(_nddr) \
521 nddr_addref(_nddr, 0)
522
523#define NDDR_ADDREF_LOCKED(_nddr) \
524 nddr_addref(_nddr, 1)
525
526#define NDDR_REMREF(_nddr) do { \
527 (void) nddr_remref(_nddr, 0); \
528} while (0)
529
530#define NDDR_REMREF_LOCKED(_nddr) \
531 nddr_remref(_nddr, 1)
532
1c79356b 533struct nd_prefix {
6d2010ae
A
534 decl_lck_mtx_data(, ndpr_lock);
535 u_int32_t ndpr_refcount; /* reference count */
536 u_int32_t ndpr_debug; /* see ifa_debug flags */
1c79356b
A
537 struct ifnet *ndpr_ifp;
538 LIST_ENTRY(nd_prefix) ndpr_entry;
539 struct sockaddr_in6 ndpr_prefix; /* prefix */
540 struct in6_addr ndpr_mask; /* netmask derived from the prefix */
541 struct in6_addr ndpr_addr; /* address that is derived from the prefix */
542 u_int32_t ndpr_vltime; /* advertised valid lifetime */
543 u_int32_t ndpr_pltime; /* advertised preferred lifetime */
1c79356b 544 time_t ndpr_preferred; /* preferred time of the prefix */
6d2010ae
A
545 time_t ndpr_expire; /* expiration time of the prefix */
546 time_t ndpr_lastupdate; /* reception time of last advertisement */
1c79356b 547 struct prf_ra ndpr_flags;
9bccf70c 548 u_int32_t ndpr_stateflags; /* actual state flags */
1c79356b
A
549 /* list of routers that advertise the prefix: */
550 LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs;
551 u_char ndpr_plen;
6d2010ae
A
552 int ndpr_addrcnt; /* reference counter from addresses */
553 void (*ndpr_trace) /* callback fn for tracing refs */
554 (struct nd_prefix *, int);
1c79356b
A
555};
556
557#define ndpr_next ndpr_entry.le_next
558
559#define ndpr_raf ndpr_flags
560#define ndpr_raf_onlink ndpr_flags.onlink
561#define ndpr_raf_auto ndpr_flags.autonomous
6d2010ae 562#define ndpr_raf_router ndpr_flags.router
1c79356b
A
563/*
564 * We keep expired prefix for certain amount of time, for validation purposes.
565 * 1800s = MaxRtrAdvInterval
566 */
567#define NDPR_KEEP_EXPIRED (1800 * 2)
568
6d2010ae
A
569#define NDPR_LOCK_ASSERT_HELD(_ndpr) \
570 lck_mtx_assert(&(_ndpr)->ndpr_lock, LCK_MTX_ASSERT_OWNED)
571
572#define NDPR_LOCK_ASSERT_NOTHELD(_ndpr) \
573 lck_mtx_assert(&(_ndpr)->ndpr_lock, LCK_MTX_ASSERT_NOTOWNED)
574
575#define NDPR_LOCK(_ndpr) \
576 lck_mtx_lock(&(_ndpr)->ndpr_lock)
577
578#define NDPR_LOCK_SPIN(_ndpr) \
579 lck_mtx_lock_spin(&(_ndpr)->ndpr_lock)
580
581#define NDPR_CONVERT_LOCK(_ndpr) do { \
582 NDPR_LOCK_ASSERT_HELD(_ndpr); \
583 lck_mtx_convert_spin(&(_ndpr)->ndpr_lock); \
584} while (0)
585
586#define NDPR_UNLOCK(_ndpr) \
587 lck_mtx_unlock(&(_ndpr)->ndpr_lock)
588
589#define NDPR_ADDREF(_ndpr) \
590 ndpr_addref(_ndpr, 0)
591
592#define NDPR_ADDREF_LOCKED(_ndpr) \
593 ndpr_addref(_ndpr, 1)
594
595#define NDPR_REMREF(_ndpr) do { \
596 (void) ndpr_remref(_ndpr, 0); \
597} while (0)
598
599#define NDPR_REMREF_LOCKED(_ndpr) \
600 ndpr_remref(_ndpr, 1)
601
1c79356b
A
602/*
603 * Message format for use in obtaining information about prefixes
604 * from inet6 sysctl function
605 */
606struct inet6_ndpr_msghdr {
607 u_short inpm_msglen; /* to skip over non-understood messages */
55e303ae 608 u_char inpm_version; /* future binary compatibility */
1c79356b
A
609 u_char inpm_type; /* message type */
610 struct in6_addr inpm_prefix;
b0d623f7
A
611 u_int32_t prm_vltim;
612 u_int32_t prm_pltime;
613 u_int32_t prm_expire;
614 u_int32_t prm_preferred;
1c79356b
A
615 struct in6_prflags prm_flags;
616 u_short prm_index; /* index for associated ifp */
617 u_char prm_plen; /* length of prefix in bits */
618};
619
620#define prm_raf_onlink prm_flags.prf_ra.onlink
621#define prm_raf_auto prm_flags.prf_ra.autonomous
622
623#define prm_statef_onlink prm_flags.prf_state.onlink
624
625#define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid
626#define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd
627
628#define ifpr2ndpr(ifpr) ((struct nd_prefix *)(ifpr))
629#define ndpr2ifpr(ndpr) ((struct ifprefix *)(ndpr))
630
631struct nd_pfxrouter {
632 LIST_ENTRY(nd_pfxrouter) pfr_entry;
633#define pfr_next pfr_entry.le_next
634 struct nd_defrouter *router;
635};
636
637LIST_HEAD(nd_prhead, nd_prefix);
638
639/* nd6.c */
640extern int nd6_prune;
641extern int nd6_delay;
642extern int nd6_umaxtries;
643extern int nd6_mmaxtries;
644extern int nd6_useloopback;
6d2010ae 645extern int nd6_accept_6to4;
9bccf70c
A
646extern int nd6_maxnudhint;
647extern int nd6_gctimer;
1c79356b
A
648extern struct llinfo_nd6 llinfo_nd6;
649extern struct nd_ifinfo *nd_ifinfo;
650extern struct nd_drhead nd_defrouter;
651extern struct nd_prhead nd_prefix;
9bccf70c 652extern int nd6_debug;
b0d623f7 653extern size_t nd_ifinfo_indexlim;
6d2010ae 654extern int nd6_onlink_ns_rfc4861;
9bccf70c 655
6d2010ae
A
656#define nd6log(x) do { if (nd6_debug >= 1) log x; } while (0)
657#define nd6log2(x) do { if (nd6_debug >= 2) log x; } while (0)
1c79356b
A
658
659/* nd6_rtr.c */
1c79356b 660extern int nd6_defifindex;
9bccf70c 661extern int ip6_desync_factor; /* seconds */
6d2010ae 662/* ND6_INFINITE_LIFETIME does not apply to temporary addresses */
9bccf70c
A
663extern u_int32_t ip6_temp_preferred_lifetime; /* seconds */
664extern u_int32_t ip6_temp_valid_lifetime; /* seconds */
665extern int ip6_temp_regen_advance; /* seconds */
1c79356b
A
666
667union nd_opts {
6d2010ae 668 struct nd_opt_hdr *nd_opt_array[8]; /* max = target address list */
1c79356b
A
669 struct {
670 struct nd_opt_hdr *zero;
671 struct nd_opt_hdr *src_lladdr;
672 struct nd_opt_hdr *tgt_lladdr;
55e303ae 673 struct nd_opt_prefix_info *pi_beg; /* multiple opts, start */
1c79356b
A
674 struct nd_opt_rd_hdr *rh;
675 struct nd_opt_mtu *mtu;
1c79356b
A
676 struct nd_opt_hdr *search; /* multiple opts */
677 struct nd_opt_hdr *last; /* multiple opts */
678 int done;
679 struct nd_opt_prefix_info *pi_end;/* multiple opts, end */
680 } nd_opt_each;
681};
682#define nd_opts_src_lladdr nd_opt_each.src_lladdr
683#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr
684#define nd_opts_pi nd_opt_each.pi_beg
685#define nd_opts_pi_end nd_opt_each.pi_end
686#define nd_opts_rh nd_opt_each.rh
687#define nd_opts_mtu nd_opt_each.mtu
1c79356b
A
688#define nd_opts_search nd_opt_each.search
689#define nd_opts_last nd_opt_each.last
690#define nd_opts_done nd_opt_each.done
691
692/* XXX: need nd6_var.h?? */
693/* nd6.c */
b0d623f7
A
694extern void nd6_init(void);
695extern int nd6_ifattach(struct ifnet *);
696extern int nd6_is_addr_neighbor(struct sockaddr_in6 *, struct ifnet *, int);
697extern void nd6_option_init(void *, int, union nd_opts *);
698extern struct nd_opt_hdr *nd6_option(union nd_opts *);
699extern int nd6_options(union nd_opts *);
700extern struct rtentry *nd6_lookup(struct in6_addr *, int, struct ifnet *, int);
701extern void nd6_setmtu(struct ifnet *);
702extern void nd6_timer(void *);
703extern void nd6_purge(struct ifnet *);
704extern void nd6_free(struct rtentry *);
705extern void nd6_nud_hint(struct rtentry *, struct in6_addr *, int);
706extern int nd6_resolve(struct ifnet *, struct rtentry *,
707 struct mbuf *, struct sockaddr *, u_char *);
708extern void nd6_rtrequest(int, struct rtentry *, struct sockaddr *);
709extern int nd6_ioctl(u_long, caddr_t, struct ifnet *);
710extern void nd6_cache_lladdr(struct ifnet *, struct in6_addr *,
711 char *, int, int, int);
712extern int nd6_output(struct ifnet *, struct ifnet *, struct mbuf *,
6d2010ae 713 struct sockaddr_in6 *, struct rtentry *);
b0d623f7
A
714extern int nd6_storelladdr(struct ifnet *, struct rtentry *, struct mbuf *,
715 struct sockaddr *, u_char *);
716extern int nd6_need_cache(struct ifnet *);
d1ecb069 717extern void nd6_drain(void *);
1c79356b
A
718
719/* nd6_nbr.c */
6d2010ae 720extern void nd6_nbr_init(void);
b0d623f7
A
721extern void nd6_na_input(struct mbuf *, int, int);
722extern void nd6_na_output(struct ifnet *, const struct in6_addr *,
723 const struct in6_addr *, u_int32_t, int, struct sockaddr *);
724extern void nd6_ns_input(struct mbuf *, int, int);
725extern void nd6_ns_output(struct ifnet *, const struct in6_addr *,
6d2010ae 726 const struct in6_addr *, struct llinfo_nd6 *, int);
b0d623f7
A
727extern caddr_t nd6_ifptomac(struct ifnet *);
728extern void nd6_dad_start(struct ifaddr *, int *);
729extern void nd6_dad_stop(struct ifaddr *);
6d2010ae
A
730extern void nd6_dad_duplicated(struct ifaddr *, boolean_t);
731extern void nd6_llreach_alloc(struct rtentry *, struct ifnet *, void *,
732 unsigned int, boolean_t);
733extern void nd6_llreach_set_reachable(struct ifnet *, void *, unsigned int);
734extern void nd6_llreach_use(struct llinfo_nd6 *);
1c79356b
A
735
736/* nd6_rtr.c */
6d2010ae 737extern void nd6_rtr_init(void);
b0d623f7
A
738extern void nd6_rs_input(struct mbuf *, int, int);
739extern void nd6_ra_input(struct mbuf *, int, int);
740extern void prelist_del(struct nd_prefix *);
6d2010ae
A
741extern void defrouter_addreq(struct nd_defrouter *, boolean_t);
742extern void defrouter_delreq(struct nd_defrouter *);
743extern void defrouter_select(struct ifnet *);
744extern void defrouter_reset(void);
745extern int defrtrlist_ioctl(u_long, caddr_t);
746extern void defrtrlist_del(struct nd_defrouter *);
747extern int defrtrlist_add_static(struct nd_defrouter *);
748extern int defrtrlist_del_static(struct nd_defrouter *);
749extern void prelist_remove(struct nd_prefix *);
b0d623f7 750extern int prelist_update(struct nd_prefix *, struct nd_defrouter *,
6d2010ae 751 struct mbuf *, int);
b0d623f7 752extern int nd6_prelist_add(struct nd_prefix *, struct nd_defrouter *,
6d2010ae
A
753 struct nd_prefix **, boolean_t);
754extern int nd6_prefix_onlink(struct nd_prefix *);
755extern int nd6_prefix_onlink_scoped(struct nd_prefix *, unsigned int);
b0d623f7 756extern int nd6_prefix_offlink(struct nd_prefix *);
6d2010ae 757extern void pfxlist_onlink_check(void);
b0d623f7
A
758extern struct nd_defrouter *defrouter_lookup(struct in6_addr *, struct ifnet *);
759extern struct nd_prefix *nd6_prefix_lookup(struct nd_prefix *);
760extern int in6_init_prefix_ltimes(struct nd_prefix *ndpr);
761extern void rt6_flush(struct in6_addr *, struct ifnet *);
762extern int nd6_setdefaultiface(int);
763extern int in6_tmpifadd(const struct in6_ifaddr *, int, int);
6d2010ae
A
764extern void nddr_addref(struct nd_defrouter *, int);
765extern struct nd_defrouter *nddr_remref(struct nd_defrouter *, int);
766extern void ndpr_addref(struct nd_prefix *, int);
767extern struct nd_prefix *ndpr_remref(struct nd_prefix *, int);
768#endif /* XNU_KERNEL_PRIVATE */
91447636
A
769
770#ifdef KERNEL
771
772/*!
773 @function nd6_lookup_ipv6
774 @discussion This function will check the routing table for a cached
775 neighbor discovery entry or trigger an neighbor discovery query
776 to resolve the IPv6 address to a link-layer address.
b0d623f7 777
91447636
A
778 nd entries are stored in the routing table. This function will
779 lookup the IPv6 destination in the routing table. If the
780 destination requires forwarding to a gateway, the route of the
781 gateway will be looked up. The route entry is inspected to
782 determine if the link layer destination address is known. If
783 unknown, neighbor discovery will be used to resolve the entry.
784 @param interface The interface the packet is being sent on.
785 @param ip6_dest The IPv6 destination of the packet.
786 @param ll_dest On output, the link-layer destination.
787 @param ll_dest_len The length of the buffer for ll_dest.
788 @param hint Any routing hint passed down from the protocol.
789 @param packet The packet being transmitted.
790 @result May return an error such as EHOSTDOWN or ENETUNREACH. If
791 this function returns EJUSTRETURN, the packet has been queued
792 and will be sent when the address is resolved. If any other
793 value is returned, the caller is responsible for disposing of
794 the packet.
795 */
b0d623f7
A
796extern errno_t nd6_lookup_ipv6(ifnet_t interface,
797 const struct sockaddr_in6 *ip6_dest, struct sockaddr_dl *ll_dest,
798 size_t ll_dest_len, route_t hint, mbuf_t packet);
1c79356b 799
b0d623f7 800#endif /* KERNEL */
1c79356b 801#endif /* _NETINET6_ND6_H_ */