1/* 2 * Copyright (c) 2000-2014 Apple Inc. All rights reserved. 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/* 29 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 30 * All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 3. Neither the name of the project nor the names of its contributors 41 * may be used to endorse or promote products derived from this software 42 * without specific prior written permission. 43 * 44 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 * SUCH DAMAGE. 55 */ 56 57#ifndef _NETINET6_ND6_H_ 58#define _NETINET6_ND6_H_ 59#include <sys/appleapiopts.h> 60 61/* see net/route.h, or net/if_inarp.h */ 62#ifndef RTF_ANNOUNCE 63#define RTF_ANNOUNCE RTF_PROTO2 64#endif 65 66#include <sys/queue.h> 67 68#ifdef BSD_KERNEL_PRIVATE 69#include <net/flowadv.h> 70#include <kern/locks.h> 71#include <sys/tree.h> 72 73struct llinfo_nd6 { 74 /* 75 * The following are protected by rnh_lock 76 */ 77 struct llinfo_nd6 *ln_next; 78 struct llinfo_nd6 *ln_prev; 79 struct rtentry *ln_rt; 80 /* 81 * The following are protected by rt_lock 82 */ 83 struct ifnet *ln_exclifp; /* excluded interface (prefix proxy) */ 84 struct mbuf *ln_hold; /* last packet until resolved/timeout */ 85 uint32_t ln_asked; /* # of queries already sent for this addr */ 86 short ln_state; /* reachability state */ 87 short ln_router; /* 2^0: ND6 router bit */ 88 u_int32_t ln_flags; /* flags; see below */ 89 u_int64_t ln_expire; /* lifetime for NDP state transition */ 90 u_int64_t ln_lastused; /* last used timestamp */ 91 struct if_llreach *ln_llreach; /* link-layer reachability record */ 92}; 93 94/* Values for ln_flags */ 95#define ND6_LNF_TIMER_SKIP 0x1 /* modified by nd6_timer() */ 96#define ND6_LNF_IN_USE 0x2 /* currently in llinfo_nd6 list */ 97#endif /* BSD_KERNEL_PRIVATE */ 98 99#define ND6_LLINFO_PURGE -3 100#define ND6_LLINFO_NOSTATE -2 101/* 102 * We don't need the WAITDELETE state any more, but we keep the definition 103 * in a comment line instead of removing it. This is necessary to avoid 104 * unintentionally reusing the value for another purpose, which might 105 * affect backward compatibility with old applications. 106 * (20000711 jinmei@kame.net) 107 */ 108/* #define ND6_LLINFO_WAITDELETE -1 */ 109#define ND6_LLINFO_INCOMPLETE 0 110#define ND6_LLINFO_REACHABLE 1 111#define ND6_LLINFO_STALE 2 112#define ND6_LLINFO_DELAY 3 113#define ND6_LLINFO_PROBE 4 114 115#ifdef BSD_KERNEL_PRIVATE 116#define ND6_IS_LLINFO_PROBREACH(n) ((n)->ln_state > ND6_LLINFO_INCOMPLETE) 117#define ND6_LLINFO_PERMANENT(n) \ 118 (((n)->ln_expire == 0) && ((n)->ln_state > ND6_LLINFO_INCOMPLETE)) 119 120#define ND6_EUI64_GBIT 0x01 121#define ND6_EUI64_UBIT 0x02 122 123#define ND6_EUI64_TO_IFID(in6) \ 124 do {(in6)->s6_addr[8] ^= ND6_EUI64_UBIT; } while (0) 125 126#define ND6_EUI64_GROUP(in6) ((in6)->s6_addr[8] & ND6_EUI64_GBIT) 127#define ND6_EUI64_INDIVIDUAL(in6) (!ND6_EUI64_GROUP(in6)) 128#define ND6_EUI64_LOCAL(in6) ((in6)->s6_addr[8] & ND6_EUI64_UBIT) 129#define ND6_EUI64_UNIVERSAL(in6) (!ND6_EUI64_LOCAL(in6)) 130#define ND6_IFID_LOCAL(in6) (!ND6_EUI64_LOCAL(in6)) 131#define ND6_IFID_UNIVERSAL(in6) (!ND6_EUI64_UNIVERSAL(in6)) 132#endif /* BSD_KERNEL_PRIVATE */ 133 134#if !defined(BSD_KERNEL_PRIVATE) 135struct nd_ifinfo { 136#else 137/* For binary compatibility, this structure must not change */ 138struct nd_ifinfo_compat { 139#endif /* !BSD_KERNEL_PRIVATE */ 140 u_int32_t linkmtu; /* LinkMTU */ 141 u_int32_t maxmtu; /* Upper bound of LinkMTU */ 142 u_int32_t basereachable; /* BaseReachableTime */ 143 u_int32_t reachable; /* Reachable Time */ 144 u_int32_t retrans; /* Retrans Timer */ 145 u_int32_t flags; /* Flags */ 146 int recalctm; /* BaseReacable re-calculation timer */ 147 u_int8_t chlim; /* CurHopLimit */ 148 u_int8_t receivedra; 149 /* the following 3 members are for privacy extension for addrconf */ 150 u_int8_t randomseed0[8]; /* upper 64 bits of SHA1 digest */ 151 u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */ 152 u_int8_t randomid[8]; /* current random ID */ 153}; 154 155#if defined(BSD_KERNEL_PRIVATE) 156struct nd_ifinfo { 157 decl_lck_mtx_data(, lock); 158 boolean_t initialized; /* Flag to see the entry is initialized */ 159 u_int32_t linkmtu; /* LinkMTU */ 160 u_int32_t maxmtu; /* Upper bound of LinkMTU */ 161 u_int32_t basereachable; /* BaseReachableTime */ 162 u_int32_t reachable; /* Reachable Time */ 163 u_int32_t retrans; /* Retrans Timer */ 164 u_int32_t flags; /* Flags */ 165 int recalctm; /* BaseReacable re-calculation timer */ 166 u_int8_t chlim; /* CurHopLimit */ 167 u_int8_t _pad[3]; 168 /* the following 3 members are for privacy extension for addrconf */ 169 u_int8_t randomseed0[8]; /* upper 64 bits of SHA1 digest */ 170 u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */ 171 u_int8_t randomid[8]; /* current random ID */ 172 /* keep track of routers and prefixes on this link */ 173 int32_t nprefixes; 174 int32_t ndefrouters; 175 struct in6_cga_modifier local_cga_modifier; 176}; 177#endif /* BSD_KERNEL_PRIVATE */ 178 179#define ND6_IFF_PERFORMNUD 0x1 180#if defined(PRIVATE) 181 182/* 183 * APPLE: not used. Interface specific router advertisements are handled with a 184 * specific ifnet flag: IFEF_ACCEPT_RTADVD 185 */ 186#define ND6_IFF_ACCEPT_RTADV 0x2 187 188/* APPLE: NOT USED not related to ND. */ 189#define ND6_IFF_PREFER_SOURCE 0x4 190 191/* IPv6 operation is disabled due to * DAD failure. (XXX: not ND-specific) */ 192#define ND6_IFF_IFDISABLED 0x8 193 194#define ND6_IFF_DONT_SET_IFROUTE 0x10 /* NOT USED */ 195#endif /* PRIVATE */ 196#define ND6_IFF_PROXY_PREFIXES 0x20 197#define ND6_IFF_IGNORE_NA 0x40 198#if defined(PRIVATE) 199#define ND6_IFF_INSECURE 0x80 200#endif 201#define ND6_IFF_REPLICATED 0x100 /* sleep proxy registered */ 202 203struct in6_nbrinfo { 204 char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ 205 struct in6_addr addr; /* IPv6 address of the neighbor */ 206 long asked; /* # of queries already sent for this addr */ 207 int isrouter; /* if it acts as a router */ 208 int state; /* reachability state */ 209 int expire; /* lifetime for NDP state transition */ 210}; 211 212#if defined(BSD_KERNEL_PRIVATE) 213struct in6_nbrinfo_32 { 214 char ifname[IFNAMSIZ]; 215 struct in6_addr addr; 216 u_int32_t asked; 217 int isrouter; 218 int state; 219 int expire; 220}; 221 222struct in6_nbrinfo_64 { 223 char ifname[IFNAMSIZ]; 224 struct in6_addr addr; 225 long asked; 226 int isrouter __attribute__((aligned(8))); 227 int state; 228 int expire; 229} __attribute__((aligned(8))); 230#endif /* BSD_KERNEL_PRIVATE */ 231 232#define DRLSTSIZ 10 233#define PRLSTSIZ 10 234 235struct in6_drlist { 236 char ifname[IFNAMSIZ]; 237 struct { 238 struct in6_addr rtaddr; 239 u_char flags; 240 u_short rtlifetime; 241 u_long expire; 242 u_short if_index; 243 } defrouter[DRLSTSIZ]; 244}; 245 246#if defined(BSD_KERNEL_PRIVATE) 247struct in6_drlist_32 { 248 char ifname[IFNAMSIZ]; 249 struct { 250 struct in6_addr rtaddr; 251 u_char flags; 252 u_short rtlifetime; 253 u_int32_t expire; 254 u_short if_index; 255 } defrouter[DRLSTSIZ]; 256}; 257 258struct in6_drlist_64 { 259 char ifname[IFNAMSIZ]; 260 struct { 261 struct in6_addr rtaddr; 262 u_char flags; 263 u_short rtlifetime; 264 u_long expire __attribute__((aligned(8))); 265 u_short if_index __attribute__((aligned(8))); 266 } defrouter[DRLSTSIZ] __attribute__((aligned(8))); 267}; 268#endif /* BSD_KERNEL_PRIVATE */ 269 270/* valid values for stateflags */ 271#define NDDRF_INSTALLED 0x1 /* installed in the routing table */ 272#define NDDRF_IFSCOPE 0x2 /* installed as a scoped route */ 273#define NDDRF_STATIC 0x4 /* for internal use only */ 274#ifdef BSD_KERNEL_PRIVATE 275#define NDDRF_PROCESSED 0x10 276#endif 277 278struct in6_defrouter { 279 struct sockaddr_in6 rtaddr; 280 u_char flags; 281 u_char stateflags; 282 u_short rtlifetime; 283 u_long expire; 284 u_short if_index; 285}; 286 287#if defined(BSD_KERNEL_PRIVATE) 288struct in6_defrouter_32 { 289 struct sockaddr_in6 rtaddr; 290 u_char flags; 291 u_char stateflags; 292 u_short rtlifetime; 293 u_int32_t expire; 294 u_short if_index; 295}; 296 297struct in6_defrouter_64 { 298 struct sockaddr_in6 rtaddr; 299 u_char flags; 300 u_char stateflags; 301 u_short rtlifetime; 302 u_long expire __attribute__((aligned(8))); 303 u_short if_index __attribute__((aligned(8))); 304} __attribute__((aligned(8))); 305#endif /* BSD_KERNEL_PRIVATE */ 306 307struct in6_prlist { 308 char ifname[IFNAMSIZ]; 309 struct { 310 struct in6_addr prefix; 311 struct prf_ra raflags; 312 u_char prefixlen; 313 u_char origin; 314 u_long vltime; 315 u_long pltime; 316 u_long expire; 317 u_short if_index; 318 u_short advrtrs; /* number of advertisement routers */ 319 struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */ 320 } prefix[PRLSTSIZ]; 321}; 322 323#if defined(BSD_KERNEL_PRIVATE) 324struct in6_prlist_32 { 325 char ifname[IFNAMSIZ]; 326 struct { 327 struct in6_addr prefix; 328 struct prf_ra raflags; 329 u_char prefixlen; 330 u_char origin; 331 u_int32_t vltime; 332 u_int32_t pltime; 333 u_int32_t expire; 334 u_short if_index; 335 u_short advrtrs; 336 struct in6_addr advrtr[DRLSTSIZ]; 337 } prefix[PRLSTSIZ]; 338}; 339 340struct in6_prlist_64 { 341 char ifname[IFNAMSIZ]; 342 struct { 343 struct in6_addr prefix; 344 struct prf_ra raflags; 345 u_char prefixlen; 346 u_char origin; 347 u_long vltime __attribute__((aligned(8))); 348 u_long pltime __attribute__((aligned(8))); 349 u_long expire __attribute__((aligned(8))); 350 u_short if_index; 351 u_short advrtrs; 352 u_int32_t pad; 353 struct in6_addr advrtr[DRLSTSIZ]; 354 } prefix[PRLSTSIZ]; 355}; 356#endif /* BSD_KERNEL_PRIVATE */ 357 358struct in6_prefix { 359 struct sockaddr_in6 prefix; 360 struct prf_ra raflags; 361 u_char prefixlen; 362 u_char origin; 363 u_long vltime; 364 u_long pltime; 365 u_long expire; 366 u_int32_t flags; 367 int refcnt; 368 u_short if_index; 369 u_short advrtrs; /* number of advertisement routers */ 370 /* struct sockaddr_in6 advrtr[] */ 371}; 372 373#if defined(BSD_KERNEL_PRIVATE) 374struct in6_prefix_32 { 375 struct sockaddr_in6 prefix; 376 struct prf_ra raflags; 377 u_char prefixlen; 378 u_char origin; 379 u_int32_t vltime; 380 u_int32_t pltime; 381 u_int32_t expire; 382 u_int32_t flags; 383 int refcnt; 384 u_short if_index; 385 u_short advrtrs; /* number of advertisement routers */ 386 /* struct sockaddr_in6 advrtr[] */ 387}; 388 389struct in6_prefix_64 { 390 struct sockaddr_in6 prefix; 391 struct prf_ra raflags; 392 u_char prefixlen; 393 u_char origin; 394 u_long vltime __attribute__((aligned(8))); 395 u_long pltime __attribute__((aligned(8))); 396 u_long expire __attribute__((aligned(8))); 397 u_int32_t flags __attribute__((aligned(8))); 398 int refcnt; 399 u_short if_index; 400 u_short advrtrs; 401 /* struct sockaddr_in6 advrtr[] */ 402}; 403#endif /* BSD_KERNEL_PRIVATE */ 404 405struct in6_ondireq { 406 char ifname[IFNAMSIZ]; 407 struct { 408 u_int32_t linkmtu; /* LinkMTU */ 409 u_int32_t maxmtu; /* Upper bound of LinkMTU */ 410 u_int32_t basereachable; /* BaseReachableTime */ 411 u_int32_t reachable; /* Reachable Time */ 412 u_int32_t retrans; /* Retrans Timer */ 413 u_int32_t flags; /* Flags */ 414 int recalctm; /* BaseReacable re-calculation timer */ 415 u_int8_t chlim; /* CurHopLimit */ 416 u_int8_t receivedra; 417 } ndi; 418}; 419 420#if !defined(BSD_KERNEL_PRIVATE) 421struct in6_ndireq { 422 char ifname[IFNAMSIZ]; 423 struct nd_ifinfo ndi; 424}; 425#else 426struct in6_ndireq { 427 char ifname[IFNAMSIZ]; 428 struct nd_ifinfo_compat ndi; 429}; 430#endif /* !BSD_KERNEL_PRIVATE */ 431 432struct in6_ndifreq { 433 char ifname[IFNAMSIZ]; 434 u_long ifindex; 435}; 436 437#define MAX_RTR_SOLICITATION_DELAY 1 /* 1sec */ 438#define RTR_SOLICITATION_INTERVAL 4 /* 4sec */ 439 440#if defined(BSD_KERNEL_PRIVATE) 441struct in6_ndifreq_32 { 442 char ifname[IFNAMSIZ]; 443 u_int32_t ifindex; 444}; 445 446struct in6_ndifreq_64 { 447 char ifname[IFNAMSIZ]; 448 u_long ifindex __attribute__((aligned(8))); 449}; 450#endif /* BSD_KERNEL_PRIVATE */ 451 452/* Prefix status */ 453#define NDPRF_ONLINK 0x1 454#define NDPRF_DETACHED 0x2 455#define NDPRF_STATIC 0x100 456#define NDPRF_IFSCOPE 0x1000 457#define NDPRF_PRPROXY 0x2000 458#ifdef BSD_KERNEL_PRIVATE 459#define NDPRF_PROCESSED_ONLINK 0x08000 460#define NDPRF_PROCESSED_SERVICE 0x10000 461#define NDPRF_DEFUNCT 0x20000 462#endif 463 464/* protocol constants */ 465#define MAX_RTR_SOLICITATION_DELAY 1 /* 1sec */ 466#define RTR_SOLICITATION_INTERVAL 4 /* 4sec */ 467#define MAX_RTR_SOLICITATIONS 3 468 469#define ND6_INFINITE_LIFETIME 0xffffffff 470#define ND6_MAX_LIFETIME 0x7fffffff 471 472#ifdef BSD_KERNEL_PRIVATE 473/* 474 * Protects nd_ifinfo[] 475 */ 476extern lck_rw_t *nd_if_rwlock; 477 478#define ND_IFINFO(ifp) \ 479 ((ifp)->if_index < nd_ifinfo_indexlim ? &nd_ifinfo[(ifp)->if_index] : \ 480 NULL) 481 482/* 483 * In a more readable form, we derive linkmtu based on: 484 * 485 * if (ifp == NULL) 486 * linkmtu = IPV6_MMTU 487 * else if (ND_IFINFO(ifp) == NULL || !ND_IFINFO(ifp)->initialized) 488 * linkmtu = ifp->if_mtu; 489 * else if (ND_IFINFO(ifp)->linkmtu && ND_IFINFO(ifp)->linkmtu < ifp->if_mtu) 490 * linkmtu = ND_IFINFO(ifp)->linkmtu; 491 * else if ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < ifp->if_mtu)) 492 * linkmtu = ND_IFINFO(ifp)->maxmtu; 493 * else 494 * linkmtu = ifp->if_mtu; 495 */ 496#define IN6_LINKMTU(ifp) \ 497 (ifp == NULL ? IPV6_MMTU : \ 498 (ND_IFINFO(ifp) == NULL || !ND_IFINFO(ifp)->initialized) ? \ 499 (ifp)->if_mtu : ((ND_IFINFO(ifp)->linkmtu && \ 500 ND_IFINFO(ifp)->linkmtu < (ifp)->if_mtu) ? ND_IFINFO(ifp)->linkmtu : \ 501 ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < (ifp)->if_mtu) ? \ 502 ND_IFINFO(ifp)->maxmtu : (ifp)->if_mtu))) 503 504/* node constants */ 505#define MAX_REACHABLE_TIME 3600000 /* msec */ 506#define REACHABLE_TIME 30000 /* msec */ 507#define RETRANS_TIMER 1000 /* msec */ 508#define MIN_RANDOM_FACTOR 512 /* 1024 * 0.5 */ 509#define MAX_RANDOM_FACTOR 1536 /* 1024 * 1.5 */ 510#define DEF_TEMP_VALID_LIFETIME 604800 /* 1 week */ 511#define DEF_TEMP_PREFERRED_LIFETIME 86400 /* 1 day */ 512#define TEMPADDR_REGEN_ADVANCE 5 /* sec */ 513#define MAX_TEMP_DESYNC_FACTOR 600 /* 10 min */ 514#define ND_COMPUTE_RTIME(x) \ 515 (((MIN_RANDOM_FACTOR * (x >> 10)) + (RandomULong() & \ 516 ((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000) 517 518TAILQ_HEAD(nd_drhead, nd_defrouter); 519struct nd_defrouter { 520 decl_lck_mtx_data(, nddr_lock); 521 TAILQ_ENTRY(nd_defrouter) dr_entry; 522 struct in6_addr rtaddr; 523 u_int32_t nddr_refcount; 524 u_int32_t nddr_debug; 525 u_int64_t expire; 526 u_int64_t base_calendartime; /* calendar time at creation */ 527 u_int64_t base_uptime; /* uptime at creation */ 528 u_char flags; /* flags on RA message */ 529 u_char stateflags; 530 u_short rtlifetime; 531 unsigned int genid; 532 int err; 533 struct ifnet *ifp; 534 void (*nddr_trace)(struct nd_defrouter *, int); /* trace callback fn */ 535}; 536 537#define NDDR_LOCK_ASSERT_HELD(_nddr) \ 538 lck_mtx_assert(&(_nddr)->nddr_lock, LCK_MTX_ASSERT_OWNED) 539 540#define NDDR_LOCK_ASSERT_NOTHELD(_nddr) \ 541 lck_mtx_assert(&(_nddr)->nddr_lock, LCK_MTX_ASSERT_NOTOWNED) 542 543#define NDDR_LOCK(_nddr) \ 544 lck_mtx_lock(&(_nddr)->nddr_lock) 545 546#define NDDR_LOCK_SPIN(_nddr) \ 547 lck_mtx_lock_spin(&(_nddr)->nddr_lock) 548 549#define NDDR_CONVERT_LOCK(_nddr) do { \ 550 NDPR_LOCK_ASSERT_HELD(_nddr); \ 551 lck_mtx_convert_spin(&(_nddr)->nddr_lock); \ 552} while (0) 553 554#define NDDR_UNLOCK(_nddr) \ 555 lck_mtx_unlock(&(_nddr)->nddr_lock) 556 557#define NDDR_ADDREF(_nddr) \ 558 nddr_addref(_nddr, 0) 559 560#define NDDR_ADDREF_LOCKED(_nddr) \ 561 nddr_addref(_nddr, 1) 562 563#define NDDR_REMREF(_nddr) do { \ 564 (void) nddr_remref(_nddr, 0); \ 565} while (0) 566 567#define NDDR_REMREF_LOCKED(_nddr) \ 568 nddr_remref(_nddr, 1) 569 570/* define struct prproxy_sols_tree */ 571RB_HEAD(prproxy_sols_tree, nd6_prproxy_soltgt); 572 573struct nd_prefix { 574 decl_lck_mtx_data(, ndpr_lock); 575 u_int32_t ndpr_refcount; /* reference count */ 576 u_int32_t ndpr_debug; /* see ifa_debug flags */ 577 struct ifnet *ndpr_ifp; 578 struct rtentry *ndpr_rt; 579 LIST_ENTRY(nd_prefix) ndpr_entry; 580 struct sockaddr_in6 ndpr_prefix; /* prefix */ 581 struct in6_addr ndpr_mask; /* netmask derived from the prefix */ 582 struct in6_addr ndpr_addr; /* address that is derived from the prefix */ 583 u_int32_t ndpr_vltime; /* advertised valid lifetime */ 584 u_int32_t ndpr_pltime; /* advertised preferred lifetime */ 585 u_int64_t ndpr_preferred; /* preferred time of the prefix */ 586 u_int64_t ndpr_expire; /* expiration time of the prefix */ 587 u_int64_t ndpr_lastupdate; /* rx time of last advertisement */ 588 u_int64_t ndpr_base_calendartime; /* calendar time at creation */ 589 u_int64_t ndpr_base_uptime; /* uptime at creation */ 590 struct prf_ra ndpr_flags; 591 unsigned int ndpr_genid; /* protects ndpr_advrtrs */ 592 u_int32_t ndpr_stateflags; /* actual state flags */ 593 /* list of routers that advertise the prefix: */ 594 LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs; 595 u_char ndpr_plen; 596 int ndpr_addrcnt; /* reference counter from addresses */ 597 u_int32_t ndpr_allmulti_cnt; /* total all-multi reqs */ 598 u_int32_t ndpr_prproxy_sols_cnt; /* total # of proxied NS */ 599 struct prproxy_sols_tree ndpr_prproxy_sols; /* tree of proxied NS */ 600 void (*ndpr_trace)(struct nd_prefix *, int); /* trace callback fn */ 601}; 602 603#define ndpr_next ndpr_entry.le_next 604 605#define ndpr_raf ndpr_flags 606#define ndpr_raf_onlink ndpr_flags.onlink 607#define ndpr_raf_auto ndpr_flags.autonomous 608#define ndpr_raf_router ndpr_flags.router 609/* 610 * We keep expired prefix for certain amount of time, for validation purposes. 611 * 1800s = MaxRtrAdvInterval 612 */ 613#define NDPR_KEEP_EXPIRED (1800 * 2) 614 615#define NDPR_LOCK_ASSERT_HELD(_ndpr) \ 616 lck_mtx_assert(&(_ndpr)->ndpr_lock, LCK_MTX_ASSERT_OWNED) 617 618#define NDPR_LOCK_ASSERT_NOTHELD(_ndpr) \ 619 lck_mtx_assert(&(_ndpr)->ndpr_lock, LCK_MTX_ASSERT_NOTOWNED) 620 621#define NDPR_LOCK(_ndpr) \ 622 lck_mtx_lock(&(_ndpr)->ndpr_lock) 623 624#define NDPR_LOCK_SPIN(_ndpr) \ 625 lck_mtx_lock_spin(&(_ndpr)->ndpr_lock) 626 627#define NDPR_CONVERT_LOCK(_ndpr) do { \ 628 NDPR_LOCK_ASSERT_HELD(_ndpr); \ 629 lck_mtx_convert_spin(&(_ndpr)->ndpr_lock); \ 630} while (0) 631 632#define NDPR_UNLOCK(_ndpr) \ 633 lck_mtx_unlock(&(_ndpr)->ndpr_lock) 634 635#define NDPR_ADDREF(_ndpr) \ 636 ndpr_addref(_ndpr, 0) 637 638#define NDPR_ADDREF_LOCKED(_ndpr) \ 639 ndpr_addref(_ndpr, 1) 640 641#define NDPR_REMREF(_ndpr) do { \ 642 (void) ndpr_remref(_ndpr, 0); \ 643} while (0) 644 645#define NDPR_REMREF_LOCKED(_ndpr) \ 646 ndpr_remref(_ndpr, 1) 647 648/* 649 * Message format for use in obtaining information about prefixes 650 * from inet6 sysctl function 651 */ 652struct inet6_ndpr_msghdr { 653 u_short inpm_msglen; /* to skip over non-understood messages */ 654 u_char inpm_version; /* future binary compatibility */ 655 u_char inpm_type; /* message type */ 656 struct in6_addr inpm_prefix; 657 u_int32_t prm_vltim; 658 u_int32_t prm_pltime; 659 u_int32_t prm_expire; 660 u_int32_t prm_preferred; 661 struct in6_prflags prm_flags; 662 u_short prm_index; /* index for associated ifp */ 663 u_char prm_plen; /* length of prefix in bits */ 664}; 665 666#define prm_raf_onlink prm_flags.prf_ra.onlink 667#define prm_raf_auto prm_flags.prf_ra.autonomous 668 669#define prm_statef_onlink prm_flags.prf_state.onlink 670 671#define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid 672#define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd 673 674#define ifpr2ndpr(ifpr) ((struct nd_prefix *)(ifpr)) 675#define ndpr2ifpr(ndpr) ((struct ifprefix *)(ndpr)) 676 677struct nd_pfxrouter { 678 LIST_ENTRY(nd_pfxrouter) pfr_entry; 679#define pfr_next pfr_entry.le_next 680 struct nd_defrouter *router; 681}; 682 683LIST_HEAD(nd_prhead, nd_prefix); 684 685struct nd_prefix_list { 686 struct nd_prefix_list *next; 687 struct nd_prefix pr; 688}; 689#endif /* BSD_KERNEL_PRIVATE */ 690 691#if defined(PRIVATE) 692/* ND6 kernel event subclass value */ 693#define KEV_ND6_SUBCLASS 7 694/* ND6 kernel event action type */ 695#define KEV_ND6_RA 1 696/* ND6 RA L2 source address length */ 697#define ND6_ROUTER_LL_SIZE 64 698 699struct nd6_ra_prefix { 700 struct sockaddr_in6 prefix; 701 struct prf_ra raflags; 702 u_int32_t prefixlen; 703 u_int32_t origin; 704 u_int64_t vltime; 705 u_int64_t pltime; 706 u_int64_t expire; 707 u_int32_t flags; 708 u_int32_t refcnt; 709 u_int32_t if_index; 710 u_int32_t pad; 711}; 712 713/* ND6 router advertisement valid bits */ 714#define KEV_ND6_DATA_VALID_MTU (0x1 << 0) 715#define KEV_ND6_DATA_VALID_PREFIX (0x1 << 1) 716 717struct kev_nd6_ra_data { 718 u_int8_t lladdr[ND6_ROUTER_LL_SIZE]; 719 u_int32_t lladdrlen; 720 u_int32_t mtu; 721 u_int32_t list_index; 722 u_int32_t list_length; 723 u_int32_t flags; 724 struct nd6_ra_prefix prefix; 725 u_int32_t pad; 726}; 727#endif /* PRIVATE */ 728 729#if defined(BSD_KERNEL_PRIVATE) 730/* nd6.c */ 731extern int nd6_prune; 732extern int nd6_prune_lazy; 733extern int nd6_delay; 734extern int nd6_umaxtries; 735extern int nd6_mmaxtries; 736extern int nd6_useloopback; 737extern int nd6_accept_6to4; 738extern int nd6_maxnudhint; 739extern int nd6_gctimer; 740extern struct llinfo_nd6 llinfo_nd6; 741extern struct nd_ifinfo *nd_ifinfo; 742extern struct nd_drhead nd_defrouter; 743extern struct nd_prhead nd_prefix; 744extern int nd6_debug; 745extern size_t nd_ifinfo_indexlim; 746extern int nd6_onlink_ns_rfc4861; 747extern int nd6_optimistic_dad; 748 749#define nd6log(x) do { if (nd6_debug >= 1) log x; } while (0) 750#define nd6log2(x) do { if (nd6_debug >= 2) log x; } while (0) 751 752#define ND6_OPTIMISTIC_DAD_LINKLOCAL (1 << 0) 753#define ND6_OPTIMISTIC_DAD_AUTOCONF (1 << 1) 754#define ND6_OPTIMISTIC_DAD_TEMPORARY (1 << 2) 755#define ND6_OPTIMISTIC_DAD_DYNAMIC (1 << 3) 756#define ND6_OPTIMISTIC_DAD_SECURED (1 << 4) 757#define ND6_OPTIMISTIC_DAD_MANUAL (1 << 5) 758 759/* nd6_rtr.c */ 760extern int nd6_defifindex; 761extern int ip6_desync_factor; /* seconds */ 762/* ND6_INFINITE_LIFETIME does not apply to temporary addresses */ 763extern u_int32_t ip6_temp_preferred_lifetime; /* seconds */ 764extern u_int32_t ip6_temp_valid_lifetime; /* seconds */ 765extern int ip6_temp_regen_advance; /* seconds */ 766 767union nd_opts { 768 struct nd_opt_hdr *nd_opt_array[8]; /* max = target address list */ 769 struct { 770 struct nd_opt_hdr *zero; 771 struct nd_opt_hdr *src_lladdr; 772 struct nd_opt_hdr *tgt_lladdr; 773 struct nd_opt_prefix_info *pi_beg; /* multiple opts, start */ 774 struct nd_opt_rd_hdr *rh; 775 struct nd_opt_mtu *mtu; 776 struct nd_opt_hdr *search; /* multiple opts */ 777 struct nd_opt_hdr *last; /* multiple opts */ 778 int done; 779 struct nd_opt_prefix_info *pi_end; /* multiple opts, end */ 780 } nd_opt_each; 781}; 782#define nd_opts_src_lladdr nd_opt_each.src_lladdr 783#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr 784#define nd_opts_pi nd_opt_each.pi_beg 785#define nd_opts_pi_end nd_opt_each.pi_end 786#define nd_opts_rh nd_opt_each.rh 787#define nd_opts_mtu nd_opt_each.mtu 788#define nd_opts_search nd_opt_each.search 789#define nd_opts_last nd_opt_each.last 790#define nd_opts_done nd_opt_each.done 791 792/* XXX: need nd6_var.h?? */ 793/* nd6.c */ 794extern int nd6_sched_timeout_want; 795extern void nd6_sched_timeout(struct timeval *, struct timeval *); 796extern void nd6_init(void); 797extern void nd6_ifreset(struct ifnet *); 798extern int nd6_ifattach(struct ifnet *); 799extern int nd6_is_addr_neighbor(struct sockaddr_in6 *, struct ifnet *, int); 800extern void nd6_option_init(void *, int, union nd_opts *); 801extern struct nd_opt_hdr *nd6_option(union nd_opts *); 802extern int nd6_options(union nd_opts *); 803extern struct rtentry *nd6_lookup(struct in6_addr *, int, struct ifnet *, int); 804extern void nd6_setmtu(struct ifnet *); 805extern void nd6_purge(struct ifnet *); 806extern void nd6_free(struct rtentry *); 807extern void nd6_nud_hint(struct rtentry *, struct in6_addr *, int); 808extern int nd6_resolve(struct ifnet *, struct rtentry *, 809 struct mbuf *, struct sockaddr *, u_char *); 810extern void nd6_rtrequest(int, struct rtentry *, struct sockaddr *); 811extern int nd6_ioctl(u_long, caddr_t, struct ifnet *); 812extern void nd6_cache_lladdr(struct ifnet *, struct in6_addr *, 813 char *, int, int, int); 814extern int nd6_output(struct ifnet *, struct ifnet *, struct mbuf *, 815 struct sockaddr_in6 *, struct rtentry *, struct flowadv *); 816extern int nd6_storelladdr(struct ifnet *, struct rtentry *, struct mbuf *, 817 struct sockaddr *, u_char *); 818extern int nd6_need_cache(struct ifnet *); 819extern void nd6_drain(void *); 820extern void nd6_post_msg(u_int32_t, struct nd_prefix_list *, u_int32_t, 821 u_int32_t, char *, u_int32_t); 822extern int nd6_setifinfo(struct ifnet *, u_int32_t, u_int32_t); 823extern void ln_setexpire(struct llinfo_nd6 *, uint64_t); 824 825/* nd6_nbr.c */ 826extern void nd6_nbr_init(void); 827extern void nd6_na_input(struct mbuf *, int, int); 828extern void nd6_na_output(struct ifnet *, const struct in6_addr *, 829 const struct in6_addr *, u_int32_t, int, struct sockaddr *); 830extern void nd6_ns_input(struct mbuf *, int, int); 831extern void nd6_ns_output(struct ifnet *, const struct in6_addr *, 832 const struct in6_addr *, struct llinfo_nd6 *, int); 833extern caddr_t nd6_ifptomac(struct ifnet *); 834extern void nd6_dad_start(struct ifaddr *, int *); 835extern void nd6_dad_stop(struct ifaddr *); 836extern void nd6_dad_duplicated(struct ifaddr *); 837extern void nd6_llreach_alloc(struct rtentry *, struct ifnet *, void *, 838 unsigned int, boolean_t); 839extern void nd6_llreach_set_reachable(struct ifnet *, void *, unsigned int); 840extern void nd6_llreach_use(struct llinfo_nd6 *); 841extern void nd6_alt_node_addr_decompose(struct ifnet *, struct sockaddr *, 842 struct sockaddr_dl *, struct sockaddr_in6 *); 843extern void nd6_alt_node_present(struct ifnet *, struct sockaddr_in6 *, 844 struct sockaddr_dl *, int32_t, int, int); 845extern void nd6_alt_node_absent(struct ifnet *, struct sockaddr_in6 *); 846 847/* nd6_rtr.c */ 848extern void nd6_rtr_init(void); 849extern void nd6_rs_input(struct mbuf *, int, int); 850extern void nd6_ra_input(struct mbuf *, int, int); 851extern void prelist_del(struct nd_prefix *); 852extern void defrouter_select(struct ifnet *); 853extern void defrouter_reset(void); 854extern int defrtrlist_ioctl(u_long, caddr_t); 855extern void defrtrlist_del(struct nd_defrouter *); 856extern int defrtrlist_add_static(struct nd_defrouter *); 857extern int defrtrlist_del_static(struct nd_defrouter *); 858extern void prelist_remove(struct nd_prefix *); 859extern int prelist_update(struct nd_prefix *, struct nd_defrouter *, 860 struct mbuf *, int); 861extern int nd6_prelist_add(struct nd_prefix *, struct nd_defrouter *, 862 struct nd_prefix **, boolean_t); 863extern int nd6_prefix_onlink(struct nd_prefix *); 864extern int nd6_prefix_onlink_scoped(struct nd_prefix *, unsigned int); 865extern int nd6_prefix_offlink(struct nd_prefix *); 866extern void pfxlist_onlink_check(void); 867extern struct nd_defrouter *defrouter_lookup(struct in6_addr *, struct ifnet *); 868extern struct nd_prefix *nd6_prefix_lookup(struct nd_prefix *); 869extern int in6_init_prefix_ltimes(struct nd_prefix *ndpr); 870extern void rt6_flush(struct in6_addr *, struct ifnet *); 871extern int nd6_setdefaultiface(int); 872extern int in6_tmpifadd(const struct in6_ifaddr *, int); 873extern void nddr_addref(struct nd_defrouter *, int); 874extern struct nd_defrouter *nddr_remref(struct nd_defrouter *, int); 875extern uint64_t nddr_getexpire(struct nd_defrouter *); 876extern void ndpr_addref(struct nd_prefix *, int); 877extern struct nd_prefix *ndpr_remref(struct nd_prefix *, int); 878extern uint64_t ndpr_getexpire(struct nd_prefix *); 879 880/* nd6_prproxy.c */ 881struct ip6_hdr; 882extern u_int32_t nd6_prproxy; 883extern void nd6_prproxy_init(void); 884extern int nd6_if_prproxy(struct ifnet *, boolean_t); 885extern void nd6_prproxy_prelist_update(struct nd_prefix *, struct nd_prefix *); 886extern boolean_t nd6_prproxy_ifaddr(struct in6_ifaddr *); 887extern void nd6_proxy_find_fwdroute(struct ifnet *, struct route_in6 *); 888extern boolean_t nd6_prproxy_isours(struct mbuf *, struct ip6_hdr *, 889 struct route_in6 *, unsigned int); 890extern void nd6_prproxy_ns_output(struct ifnet *, struct ifnet *, 891 struct in6_addr *, struct in6_addr *, struct llinfo_nd6 *); 892extern void nd6_prproxy_ns_input(struct ifnet *, struct in6_addr *, 893 char *, int, struct in6_addr *, struct in6_addr *); 894extern void nd6_prproxy_na_input(struct ifnet *, struct in6_addr *, 895 struct in6_addr *, struct in6_addr *, int); 896extern void nd6_prproxy_sols_reap(struct nd_prefix *); 897extern void nd6_prproxy_sols_prune(struct nd_prefix *, u_int32_t); 898extern int nd6_if_disable(struct ifnet *, boolean_t); 899#endif /* BSD_KERNEL_PRIVATE */ 900 901#ifdef KERNEL 902 903/* 904 * @function nd6_lookup_ipv6 905 * @discussion This function will check the routing table for a cached 906 * neighbor discovery entry or trigger an neighbor discovery query 907 * to resolve the IPv6 address to a link-layer address. 908 * nd entries are stored in the routing table. This function will 909 * lookup the IPv6 destination in the routing table. If the 910 * destination requires forwarding to a gateway, the route of the 911 * gateway will be looked up. The route entry is inspected to 912 * determine if the link layer destination address is known. If 913 * unknown, neighbor discovery will be used to resolve the entry. 914 * @param interface The interface the packet is being sent on. 915 * @param ip6_dest The IPv6 destination of the packet. 916 * @param ll_dest On output, the link-layer destination. 917 * @param ll_dest_len The length of the buffer for ll_dest. 918 * @param hint Any routing hint passed down from the protocol. 919 * @param packet The packet being transmitted. 920 * @result May return an error such as EHOSTDOWN or ENETUNREACH. If 921 * this function returns EJUSTRETURN, the packet has been queued 922 * and will be sent when the address is resolved. If any other 923 * value is returned, the caller is responsible for disposing of 924 * the packet. 925 */ 926extern errno_t nd6_lookup_ipv6(ifnet_t interface, 927 const struct sockaddr_in6 *ip6_dest, struct sockaddr_dl *ll_dest, 928 size_t ll_dest_len, route_t hint, mbuf_t packet); 929 930#endif /* KERNEL */ 931 932/* nd6_send.c */ 933#ifdef BSD_KERNEL_PRIVATE 934/* 935 * nd6_send_opmode 936 * 937 * value using CGA tx SEND rx SEND 938 * -------- --------- ------- ------- 939 * DISABLED NO NO NO 940 * QUIET YES NO NO 941 */ 942extern int nd6_send_opstate; 943 944#define ND6_SEND_OPMODE_DISABLED 0 945#define ND6_SEND_OPMODE_CGA_QUIET 1 946 947#endif /* BSD_KERNEL_PRIVATE */ 948#endif /* _NETINET6_ND6_H_ */ 949