1/* 2 * Copyright (c) 2011-2012 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#ifndef _NET_IF_LLREACH_H_ 30#define _NET_IF_LLREACH_H_ 31 32#ifdef PRIVATE 33#ifdef __cplusplus 34extern "C" { 35#endif 36 37#include <sys/types.h> 38 39/* 40 * Per-interface link-layer reachability information (private). 41 */ 42#define IF_LLREACHINFO_ADDRLEN 64 /* max ll addr len */ 43#define IF_LLREACHINFO_RESERVED2 16 /* more reserved bits */ 44 45struct if_llreach_info { 46 u_int32_t lri_refcnt; /* reference count */ 47 u_int32_t lri_ifindex; /* interface index */ 48 u_int64_t lri_expire; /* expiration (calendar) time */ 49 u_int32_t lri_probes; /* total # of probes */ 50 u_int16_t lri_reserved; /* for future use */ 51 u_int16_t lri_proto; /* ll proto */ 52 u_int8_t lri_addr[IF_LLREACHINFO_ADDRLEN]; /* ll addr */ 53 int32_t lri_rssi; /* received signal strength */ 54 int32_t lri_lqm; /* link quality metric */ 55 int32_t lri_npm; /* node proximity metric */ 56 u_int8_t lri_reserved2[IF_LLREACHINFO_RESERVED2]; 57}; 58 59#ifdef XNU_KERNEL_PRIVATE 60#include <sys/tree.h> 61#include <kern/locks.h> 62#include <net/ethernet.h> 63#include <netinet/in.h> 64#if INET6 65#include <netinet6/in6_var.h> 66#include <netinet6/nd6.h> 67#endif /* INET6 */ 68 69/* 70 * Link-layer reachability is based off node constants in RFC4861. 71 */ 72#if INET6 73#define LL_BASE_REACHABLE REACHABLE_TIME 74#else 75#define LL_BASE_REACHABLE 30000 /* msec */ 76#endif /* !INET6 */ 77 78/* 79 * Per-interface link-layer reachability. (Currently only for ARP/Ethernet.) 80 */ 81#define IF_LLREACH_MAXLEN ETHER_ADDR_LEN 82 83struct if_llreach { 84 decl_lck_mtx_data(, lr_lock); 85 RB_ENTRY(if_llreach) lr_link; /* RB tree links */ 86 struct ifnet *lr_ifp; /* back pointer to ifnet */ 87 u_int32_t lr_refcnt; /* reference count */ 88 u_int32_t lr_reqcnt; /* RB tree request count */ 89 u_int32_t lr_debug; /* see ifa_debug flags */ 90 u_int32_t lr_probes; /* number of probes so far */ 91 u_int64_t lr_basecal; /* base calendar time */ 92 u_int64_t lr_baseup; /* base uptime */ 93 u_int64_t lr_lastrcvd; /* last-heard-of timestamp */ 94 u_int32_t lr_basereachable; /* baseline time */ 95 u_int32_t lr_reachable; /* reachable time */ 96 struct lr_key_s { 97 u_int16_t proto; /* ll proto */ 98 u_int8_t addr[IF_LLREACH_MAXLEN]; /* ll addr */ 99 } lr_key; 100 int32_t lr_rssi; /* received signal strength */ 101 int32_t lr_lqm; /* link quality metric */ 102 int32_t lr_npm; /* node proximity metric */ 103}; 104 105RB_PROTOTYPE_SC_PREV(__private_extern__, ll_reach_tree, if_llreach, 106 ls_link, ifllr_cmp); 107 108#define IFLR_LOCK_ASSERT_HELD(_iflr) \ 109 lck_mtx_assert(&(_iflr)->lr_lock, LCK_MTX_ASSERT_OWNED) 110 111#define IFLR_LOCK_ASSERT_NOTHELD(_iflr) \ 112 lck_mtx_assert(&(_iflr)->lr_lock, LCK_MTX_ASSERT_NOTOWNED) 113 114#define IFLR_LOCK(_iflr) \ 115 lck_mtx_lock(&(_iflr)->lr_lock) 116 117#define IFLR_LOCK_SPIN(_iflr) \ 118 lck_mtx_lock_spin(&(_iflr)->lr_lock) 119 120#define IFLR_CONVERT_LOCK(_iflr) do { \ 121 IFLR_LOCK_ASSERT_HELD(_iflr); \ 122 lck_mtx_convert_spin(&(_iflr)->lr_lock); \ 123} while (0) 124 125#define IFLR_UNLOCK(_iflr) \ 126 lck_mtx_unlock(&(_iflr)->lr_lock) 127 128#define IFLR_ADDREF(_iflr) \ 129 iflr_addref(_iflr, 0) 130 131#define IFLR_ADDREF_LOCKED(_iflr) \ 132 iflr_addref(_iflr, 1) 133 134#define IFLR_REMREF(_iflr) \ 135 iflr_remref(_iflr) 136 137struct ifnet_llreach_info; /* forward declaration */ 138 139extern void ifnet_llreach_init(void); 140extern void ifnet_llreach_ifattach(struct ifnet *, boolean_t); 141extern void ifnet_llreach_ifdetach(struct ifnet *); 142extern struct if_llreach *ifnet_llreach_alloc(struct ifnet *, u_int16_t, void *, 143 unsigned int, u_int64_t); 144extern void ifnet_llreach_free(struct if_llreach *); 145extern int ifnet_llreach_reachable(struct if_llreach *); 146extern int ifnet_llreach_reachable_delta(struct if_llreach *, u_int64_t); 147extern void ifnet_llreach_set_reachable(struct ifnet *, u_int16_t, void *, 148 unsigned int); 149extern u_int64_t ifnet_llreach_up2calexp(struct if_llreach *, u_int64_t); 150extern u_int64_t ifnet_llreach_up2upexp(struct if_llreach *, u_int64_t); 151extern int ifnet_llreach_get_defrouter(struct ifnet *, int, 152 struct ifnet_llreach_info *); 153extern void ifnet_lr2ri(struct if_llreach *, struct rt_reach_info *); 154extern void ifnet_lr2iflri(struct if_llreach *, struct ifnet_llreach_info *); 155extern void ifnet_lr2lri(struct if_llreach *, struct if_llreach_info *); 156extern void iflr_addref(struct if_llreach *, int); 157extern void iflr_remref(struct if_llreach *); 158#endif /* XNU_KERNEL_PRIVATE */ 159 160#ifdef __cplusplus 161} 162#endif 163#endif /* PRIVATE */ 164#endif /* !_NET_IF_LLREACH_H_ */ 165