/*
- * Copyright (c) 2000-2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#ifndef _NETINET6_ND6_H_
#define _NETINET6_ND6_H_
#include <sys/appleapiopts.h>
+#include <net/net_kev.h>
/* see net/route.h, or net/if_inarp.h */
#ifndef RTF_ANNOUNCE
#include <net/flowadv.h>
#include <kern/locks.h>
#include <sys/tree.h>
+#include <netinet6/nd6_var.h>
struct llinfo_nd6 {
/*
#define ND6_LLINFO_PROBE 4
#ifdef BSD_KERNEL_PRIVATE
+
+#define ND6_CACHE_STATE_TRANSITION(ln, nstate) do {\
+ if (nd6_debug >= 1) {\
+ nd6log((LOG_INFO,\
+ "[%s:%d]: NDP cache entry changed from %s -> %s",\
+ __FILE__,\
+ __LINE__,\
+ ndcache_state2str((ln)->ln_state),\
+ ndcache_state2str(nstate)));\
+ if ((ln)->ln_rt)\
+ nd6log((LOG_INFO,\
+ " for address: %s.\n",\
+ ip6_sprintf(&SIN6(rt_key((ln)->ln_rt))->sin6_addr)));\
+ else\
+ nd6log((LOG_INFO, "\n"));\
+ }\
+ (ln)->ln_state = nstate;\
+} while(0)
+
#define ND6_IS_LLINFO_PROBREACH(n) ((n)->ln_state > ND6_LLINFO_INCOMPLETE)
#define ND6_LLINFO_PERMANENT(n) \
(((n)->ln_expire == 0) && ((n)->ln_state > ND6_LLINFO_INCOMPLETE))
struct nd_ifinfo {
#else
/* For binary compatibility, this structure must not change */
+/* NOTE: nd_ifinfo is defined in nd6_var.h */
struct nd_ifinfo_compat {
#endif /* !BSD_KERNEL_PRIVATE */
u_int32_t linkmtu; /* LinkMTU */
u_int8_t randomid[8]; /* current random ID */
};
-#if defined(BSD_KERNEL_PRIVATE)
-struct nd_ifinfo {
- decl_lck_mtx_data(, lock);
- boolean_t initialized; /* Flag to see the entry is initialized */
- u_int32_t linkmtu; /* LinkMTU */
- u_int32_t maxmtu; /* Upper bound of LinkMTU */
- u_int32_t basereachable; /* BaseReachableTime */
- u_int32_t reachable; /* Reachable Time */
- u_int32_t retrans; /* Retrans Timer */
- u_int32_t flags; /* Flags */
- int recalctm; /* BaseReacable re-calculation timer */
- u_int8_t chlim; /* CurHopLimit */
- u_int8_t _pad[3];
- /* the following 3 members are for privacy extension for addrconf */
- u_int8_t randomseed0[8]; /* upper 64 bits of SHA1 digest */
- u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */
- u_int8_t randomid[8]; /* current random ID */
- /* keep track of routers and prefixes on this link */
- int32_t nprefixes;
- int32_t ndefrouters;
- struct in6_cga_modifier local_cga_modifier;
-};
-#endif /* BSD_KERNEL_PRIVATE */
-
#define ND6_IFF_PERFORMNUD 0x1
#if defined(PRIVATE)
#define ND6_IFF_INSECURE 0x80
#endif
#define ND6_IFF_REPLICATED 0x100 /* sleep proxy registered */
+#define ND6_IFF_DAD 0x200 /* Perform DAD on the interface */
struct in6_nbrinfo {
char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
#define NDDRF_INSTALLED 0x1 /* installed in the routing table */
#define NDDRF_IFSCOPE 0x2 /* installed as a scoped route */
#define NDDRF_STATIC 0x4 /* for internal use only */
-#ifdef BSD_KERNEL_PRIVATE
-#define NDDRF_PROCESSED 0x10
-#endif
+#define NDDRF_MAPPED 0x8 /* Default router addr is mapped to a different one for routing */
struct in6_defrouter {
struct sockaddr_in6 rtaddr;
#define ND6_MAX_LIFETIME 0x7fffffff
#ifdef BSD_KERNEL_PRIVATE
-/*
- * Protects nd_ifinfo[]
- */
-extern lck_rw_t *nd_if_rwlock;
-
-#define ND_IFINFO(ifp) \
- ((ifp)->if_index < nd_ifinfo_indexlim ? &nd_ifinfo[(ifp)->if_index] : \
- NULL)
+#define ND_IFINFO(ifp) \
+ ((ifp == NULL) ? NULL : \
+ ((IN6_IFEXTRA(ifp) == NULL) ? NULL : \
+ (&IN6_IFEXTRA(ifp)->nd_ifinfo)))
/*
* In a more readable form, we derive linkmtu based on:
(((MIN_RANDOM_FACTOR * (x >> 10)) + (RandomULong() & \
((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000)
+/* prefix expiry times */
+#define ND6_PREFIX_EXPIRY_UNSPEC -1
+#define ND6_PREFIX_EXPIRY_NEVER 0
+
TAILQ_HEAD(nd_drhead, nd_defrouter);
struct nd_defrouter {
decl_lck_mtx_data(, nddr_lock);
u_char flags; /* flags on RA message */
u_char stateflags;
u_short rtlifetime;
- unsigned int genid;
int err;
struct ifnet *ifp;
+ struct in6_addr rtaddr_mapped; /* Mapped gateway address for routing */
void (*nddr_trace)(struct nd_defrouter *, int); /* trace callback fn */
};
#define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid
#define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd
-#define ifpr2ndpr(ifpr) ((struct nd_prefix *)(ifpr))
-#define ndpr2ifpr(ndpr) ((struct ifprefix *)(ndpr))
-
struct nd_pfxrouter {
LIST_ENTRY(nd_pfxrouter) pfr_entry;
#define pfr_next pfr_entry.le_next
#endif /* BSD_KERNEL_PRIVATE */
#if defined(PRIVATE)
-/* ND6 kernel event subclass value */
-#define KEV_ND6_SUBCLASS 7
-/* ND6 kernel event action type */
-#define KEV_ND6_RA 1
+struct kev_nd6_ndfailure {
+ struct net_event_data link_data;
+};
+
+struct kev_nd6_ndalive {
+ struct net_event_data link_data;
+};
+
/* ND6 RA L2 source address length */
#define ND6_ROUTER_LL_SIZE 64
struct nd6_ra_prefix prefix;
u_int32_t pad;
};
+
+struct nd6_lookup_ipv6_args {
+ char ifname[IFNAMSIZ];
+ struct sockaddr_in6 ip6_dest;
+ u_int32_t ll_dest_len;
+ union {
+ char buffer[256];
+ struct sockaddr_dl _sdl;
+ } ll_dest_;
+};
+#define ll_dest_sdl ll_dest_._sdl
+
#endif /* PRIVATE */
#if defined(BSD_KERNEL_PRIVATE)
extern int nd6_maxnudhint;
extern int nd6_gctimer;
extern struct llinfo_nd6 llinfo_nd6;
-extern struct nd_ifinfo *nd_ifinfo;
extern struct nd_drhead nd_defrouter;
extern struct nd_prhead nd_prefix;
extern int nd6_debug;
-extern size_t nd_ifinfo_indexlim;
extern int nd6_onlink_ns_rfc4861;
extern int nd6_optimistic_dad;
extern int ip6_temp_regen_advance; /* seconds */
union nd_opts {
- struct nd_opt_hdr *nd_opt_array[8]; /* max = target address list */
+ struct nd_opt_hdr *nd_opt_array[16]; /* max = target address list */
struct {
struct nd_opt_hdr *zero;
struct nd_opt_hdr *src_lladdr;
struct nd_opt_prefix_info *pi_beg; /* multiple opts, start */
struct nd_opt_rd_hdr *rh;
struct nd_opt_mtu *mtu;
+ struct nd_opt_hdr *__res6;
+ struct nd_opt_hdr *__res7;
+ struct nd_opt_hdr *__res8;
+ struct nd_opt_hdr *__res9;
+ struct nd_opt_hdr *__res10;
+ struct nd_opt_hdr *__res11;
+ struct nd_opt_hdr *__res12;
+ struct nd_opt_hdr *__res13;
+ struct nd_opt_nonce *nonce;
+ struct nd_opt_hdr *__res15;
struct nd_opt_hdr *search; /* multiple opts */
struct nd_opt_hdr *last; /* multiple opts */
int done;
#define nd_opts_pi_end nd_opt_each.pi_end
#define nd_opts_rh nd_opt_each.rh
#define nd_opts_mtu nd_opt_each.mtu
+#define nd_opts_nonce nd_opt_each.nonce
#define nd_opts_search nd_opt_each.search
#define nd_opts_last nd_opt_each.last
#define nd_opts_done nd_opt_each.done
extern int nd6_sched_timeout_want;
extern void nd6_sched_timeout(struct timeval *, struct timeval *);
extern void nd6_init(void);
-extern void nd6_ifreset(struct ifnet *);
-extern int nd6_ifattach(struct ifnet *);
+extern void nd6_ifreset(struct ifnet *ifp);
+extern void nd6_ifattach(struct ifnet *);
extern int nd6_is_addr_neighbor(struct sockaddr_in6 *, struct ifnet *, int);
extern void nd6_option_init(void *, int, union nd_opts *);
extern struct nd_opt_hdr *nd6_option(union nd_opts *);
extern int nd6_ioctl(u_long, caddr_t, struct ifnet *);
extern void nd6_cache_lladdr(struct ifnet *, struct in6_addr *,
char *, int, int, int);
+extern int nd6_output_list(struct ifnet *, struct ifnet *, struct mbuf *,
+ struct sockaddr_in6 *, struct rtentry *, struct flowadv *);
extern int nd6_output(struct ifnet *, struct ifnet *, struct mbuf *,
struct sockaddr_in6 *, struct rtentry *, struct flowadv *);
extern int nd6_storelladdr(struct ifnet *, struct rtentry *, struct mbuf *,
extern void nd6_post_msg(u_int32_t, struct nd_prefix_list *, u_int32_t,
u_int32_t, char *, u_int32_t);
extern int nd6_setifinfo(struct ifnet *, u_int32_t, u_int32_t);
+extern const char *ndcache_state2str(short);
extern void ln_setexpire(struct llinfo_nd6 *, uint64_t);
/* nd6_nbr.c */
const struct in6_addr *, u_int32_t, int, struct sockaddr *);
extern void nd6_ns_input(struct mbuf *, int, int);
extern void nd6_ns_output(struct ifnet *, const struct in6_addr *,
- const struct in6_addr *, struct llinfo_nd6 *, int);
+ const struct in6_addr *, struct llinfo_nd6 *, uint8_t *);
extern caddr_t nd6_ifptomac(struct ifnet *);
extern void nd6_dad_start(struct ifaddr *, int *);
extern void nd6_dad_stop(struct ifaddr *);
extern int nd6_prefix_offlink(struct nd_prefix *);
extern void pfxlist_onlink_check(void);
extern struct nd_defrouter *defrouter_lookup(struct in6_addr *, struct ifnet *);
-extern struct nd_prefix *nd6_prefix_lookup(struct nd_prefix *);
+extern struct nd_prefix *nd6_prefix_lookup(struct nd_prefix *, int);
extern int in6_init_prefix_ltimes(struct nd_prefix *ndpr);
extern void rt6_flush(struct in6_addr *, struct ifnet *);
extern int nd6_setdefaultiface(int);
extern void nd6_prproxy_ns_output(struct ifnet *, struct ifnet *,
struct in6_addr *, struct in6_addr *, struct llinfo_nd6 *);
extern void nd6_prproxy_ns_input(struct ifnet *, struct in6_addr *,
- char *, int, struct in6_addr *, struct in6_addr *);
+ char *, int, struct in6_addr *, struct in6_addr *, uint8_t *nonce);
extern void nd6_prproxy_na_input(struct ifnet *, struct in6_addr *,
struct in6_addr *, struct in6_addr *, int);
extern void nd6_prproxy_sols_reap(struct nd_prefix *);
extern void nd6_prproxy_sols_prune(struct nd_prefix *, u_int32_t);
extern int nd6_if_disable(struct ifnet *, boolean_t);
+void in6_ifaddr_set_dadprogress(struct in6_ifaddr *ia);
#endif /* BSD_KERNEL_PRIVATE */
#ifdef KERNEL