| 1 | /* |
| 2 | * Copyright (c) 2015-2021 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 | #ifndef _SKYWALK_OS_SKYWALK_PRIVATE_H |
| 29 | #define _SKYWALK_OS_SKYWALK_PRIVATE_H |
| 30 | |
| 31 | #if defined(PRIVATE) || defined(XNU_KERNEL_PRIVATE) |
| 32 | /* |
| 33 | * This file contains private interfaces for Skywalk, and should not |
| 34 | * be included by code external to xnu kernel or libsystem_kernel. |
| 35 | * The only exception to this is skywalk_cmds for the internal tools. |
| 36 | */ |
| 37 | |
| 38 | /* branch prediction helpers */ |
| 39 | #include <sys/cdefs.h> |
| 40 | #define SK_ALIGN64_CASSERT(type, field) \ |
| 41 | _CASSERT((__builtin_offsetof(type, field) % sizeof (uint64_t)) == 0) |
| 42 | |
| 43 | #if !defined(KERNEL) || defined(BSD_KERNEL_PRIVATE) |
| 44 | enum { |
| 45 | SK_FEATURE_SKYWALK = 1ULL << 0, |
| 46 | SK_FEATURE_DEVELOPMENT = 1ULL << 1, |
| 47 | SK_FEATURE_DEBUG = 1ULL << 2, |
| 48 | SK_FEATURE_NEXUS_FLOWSWITCH = 1ULL << 3, |
| 49 | SK_FEATURE_NEXUS_MONITOR = 1ULL << 4, |
| 50 | SK_FEATURE_NEXUS_NETIF = 1ULL << 5, |
| 51 | SK_FEATURE_NEXUS_USER_PIPE = 1ULL << 6, |
| 52 | SK_FEATURE_NEXUS_KERNEL_PIPE = 1ULL << 7, |
| 53 | SK_FEATURE_NEXUS_KERNEL_PIPE_LOOPBACK = 1ULL << 8, |
| 54 | SK_FEATURE_DEV_OR_DEBUG = 1ULL << 9, |
| 55 | SK_FEATURE_NETNS = 1ULL << 10, |
| 56 | SK_FEATURE_PROTONS = 1ULL << 11, |
| 57 | }; |
| 58 | #endif /* !KERNEL || BSD_KERNEL_PRIVATE */ |
| 59 | |
| 60 | /* valid flags for if_attach_nx */ |
| 61 | #define IF_ATTACH_NX_NETIF_COMPAT 0x01 /* create compat netif */ |
| 62 | #define IF_ATTACH_NX_FLOWSWITCH 0x02 /* enable flowswitch */ |
| 63 | #define IF_ATTACH_NX_FSW_TRANSPORT_NETAGENT 0x04 /* enable fsw TCP/UDP netagent */ |
| 64 | #define IF_ATTACH_NX_NETIF_NETAGENT 0x08 /* enable netif netagent */ |
| 65 | #define IF_ATTACH_NX_NETIF_ALL 0x10 /* don't restrict netif */ |
| 66 | #define IF_ATTACH_NX_FSW_IP_NETAGENT 0x20 /* enable fsw IP netagent */ |
| 67 | |
| 68 | /* |
| 69 | * Enabling Skywalk channel (user) networking stack fundamentally requires |
| 70 | * the presence of netif nexus attached to the interface. Native Skywalk |
| 71 | * drivers will come with a netif nexus; non-native drivers will require us |
| 72 | * to create a netif compat nexus, set through IF_ATTACH_NX_NETIF_COMPAT. |
| 73 | * |
| 74 | * The flowswitch nexus creation depends on the presence of netif nexus on |
| 75 | * the interface. Plumbing the flowswitch atop netif is required to connect |
| 76 | * the interface to the host (kernel) networking stack; this is the default |
| 77 | * behavior unless IF_ATTACH_NX_FLOWSWITCH is not set. |
| 78 | * |
| 79 | * To further allow for channel (user) networking stack, the netagent gets |
| 80 | * enabled on the flowswitch by default, unless opted out by clearing the |
| 81 | * IF_ATTACH_NX_FSW_TRANSPORT_NETAGENT flag. Note that |
| 82 | * IF_ATTACH_NX_FSW_TRANSPORT_NETAGENT cannot be changed after boot, and so has |
| 83 | * to be set by the if_attach_nx bootarg. |
| 84 | */ |
| 85 | #define SKYWALK_NETWORKING_ENABLED \ |
| 86 | (IF_ATTACH_NX_NETIF_COMPAT | IF_ATTACH_NX_FLOWSWITCH | \ |
| 87 | IF_ATTACH_NX_FSW_TRANSPORT_NETAGENT | IF_ATTACH_NX_FSW_IP_NETAGENT) |
| 88 | |
| 89 | /* |
| 90 | * To partially enable Skywalk to only let the host (kernel) stack to work, |
| 91 | * we set both IF_ATTACH_NX_NETIF_COMPAT and IF_ATTACH_NX_FLOWSWITCH flags, |
| 92 | * leaving IF_ATTACH_NX_FSW_*_NETAGENT unset. This enables netif and |
| 93 | * flowswitch flowswitch nexus on all eligible interfaces, except that channel |
| 94 | * (user) networking stack will be disabled. |
| 95 | */ |
| 96 | #define SKYWALK_NETWORKING_BSD_ONLY \ |
| 97 | (IF_ATTACH_NX_NETIF_COMPAT | IF_ATTACH_NX_FLOWSWITCH) |
| 98 | |
| 99 | /* |
| 100 | * macOS default configuration for enabling support for interpose filters, |
| 101 | * custom IP, custom ether type providers and user networking stack. |
| 102 | */ |
| 103 | #define SKYWALK_NETWORKING_MAC_OS \ |
| 104 | (SKYWALK_NETWORKING_BSD_ONLY | IF_ATTACH_NX_FSW_IP_NETAGENT | \ |
| 105 | IF_ATTACH_NX_NETIF_NETAGENT | IF_ATTACH_NX_FSW_TRANSPORT_NETAGENT) |
| 106 | |
| 107 | /* |
| 108 | * Disabling Skywalk networking is done by removing IF_ATTACH_NX_NETIF_COMPAT |
| 109 | * and IF_ATTACH_NX_FSW_*_NETAGENT flags, and leaving IF_ATTACH_NX_FLOWSWITCH |
| 110 | * set. This disables the compat netif instances and netagent, while still |
| 111 | * allowing flowswitch nexus creation for native Skywalk drivers, since |
| 112 | * otherwise they cease to function due to missing interaction with the host |
| 113 | * (kernel) stack. |
| 114 | */ |
| 115 | #define SKYWALK_NETWORKING_DISABLED IF_ATTACH_NX_FLOWSWITCH |
| 116 | |
| 117 | #if !XNU_TARGET_OS_OSX |
| 118 | #ifdef __LP64__ |
| 119 | #define IF_ATTACH_NX_DEFAULT SKYWALK_NETWORKING_ENABLED |
| 120 | #else /* !__LP64__ */ |
| 121 | #define IF_ATTACH_NX_DEFAULT SKYWALK_NETWORKING_DISABLED |
| 122 | #endif /* !__LP64__ */ |
| 123 | #else /* XNU_TARGET_OS_OSX */ |
| 124 | #define IF_ATTACH_NX_DEFAULT SKYWALK_NETWORKING_MAC_OS |
| 125 | #endif /* XNU_TARGET_OS_OSX */ |
| 126 | |
| 127 | #define SK_VERBOSE_SYSCTL "kern.skywalk.verbose" |
| 128 | /* |
| 129 | * Verbose flags. |
| 130 | * |
| 131 | * When adding new ones, consider the existing scheme based on the areas; |
| 132 | * try to "fill in the holes" first before extending the range. |
| 133 | */ |
| 134 | #define SK_VERB_FLAGS_TABLE(X) \ |
| 135 | X(SK_VERB_DEFAULT, 0) /* 0x0000000000000001 */ \ |
| 136 | X(SK_VERB_DUMP, 1) /* 0x0000000000000002 */ \ |
| 137 | X(SK_VERB_LOCKS, 2) /* 0x0000000000000004 */ \ |
| 138 | X(SK_VERB_REFCNT, 3) /* 0x0000000000000008 */ \ |
| 139 | X(SK_VERB_MEM, 4) /* 0x0000000000000010 */ \ |
| 140 | X(SK_VERB_MEM_ARENA, 5) /* 0x0000000000000020 */ \ |
| 141 | X(SK_VERB_MEM_CACHE, 6) /* 0x0000000000000040 */ \ |
| 142 | X(SK_VERB_MEM_REGION, 7) /* 0x0000000000000080 */ \ |
| 143 | X(SK_VERB_EVENTS, 8) /* 0x0000000000000100 */ \ |
| 144 | X(SK_VERB_SYNC, 9) /* 0x0000000000000200 */ \ |
| 145 | X(SK_VERB_NOTIFY, 10) /* 0x0000000000000400 */ \ |
| 146 | X(SK_VERB_INTR, 11) /* 0x0000000000000800 */ \ |
| 147 | X(SK_VERB_MONITOR, 12) /* 0x0000000000001000 */ \ |
| 148 | X(SK_VERB_DEV, 13) /* 0x0000000000002000 */ \ |
| 149 | X(SK_VERB_HOST, 14) /* 0x0000000000004000 */ \ |
| 150 | X(SK_VERB_USER, 15) /* 0x0000000000008000 */ \ |
| 151 | X(SK_VERB_RX, 16) /* 0x0000000000010000 */ \ |
| 152 | X(SK_VERB_TX, 17) /* 0x0000000000020000 */ \ |
| 153 | X(SK_VERB_LOOKUP, 18) /* 0x0000000000040000 */ \ |
| 154 | X(SK_VERB_RING, 19) /* 0x0000000000080000 */ \ |
| 155 | X(SK_VERB_NETIF, 20) /* 0x0000000000100000 */ \ |
| 156 | X(SK_VERB_NETIF_MIT, 21) /* 0x0000000000200000 */ \ |
| 157 | X(SK_VERB_IOSK, 22) /* 0x0000000000400000 */ \ |
| 158 | X(SK_VERB_CHANNEL, 23) /* 0x0000000000800000 */ \ |
| 159 | X(SK_VERB_AQM, 25) /* 0x0000000002000000 */ \ |
| 160 | X(SK_VERB_FSW, 24) /* 0x0000000001000000 */ \ |
| 161 | X(SK_VERB_FSW_DP, 26) /* 0x0000000004000000 */ \ |
| 162 | X(SK_VERB_LLINK, 27) /* 0x0000000008000000 */ \ |
| 163 | X(SK_VERB_FLOW, 28) /* 0x0000000010000000 */ \ |
| 164 | X(SK_VERB_FLOW_CLASSIFY, 29) /* 0x0000000020000000 */ \ |
| 165 | X(SK_VERB_FLOW_TRACK, 30) /* 0x0000000040000000 */ \ |
| 166 | X(SK_VERB_FLOW_ADVISORY, 31) /* 0x0000000080000000 */ \ |
| 167 | X(SK_VERB_FLOW_ROUTE, 32) /* 0x0000000100000000 */ \ |
| 168 | X(SK_VERB_FPD, 33) /* 0x0000000200000000 */ \ |
| 169 | X(__SK_VERB_34__, 34) /* 0x0000000400000000 */ \ |
| 170 | X(__SK_VERF_35__, 35) /* 0x0000000800000000 */ \ |
| 171 | X(SK_VERB_USER_PIPE, 36) /* 0x0000001000000000 */ \ |
| 172 | X(SK_VERB_NA, 37) /* 0x0000002000000000 */ \ |
| 173 | X(SK_VERB_KERNEL_PIPE, 38) /* 0x0000004000000000 */ \ |
| 174 | X(SK_VERB_NS_PROTO, 39) /* 0x0000008000000000 */ \ |
| 175 | X(SK_VERB_NS_TCP, 40) /* 0x0000010000000000 */ \ |
| 176 | X(SK_VERB_NS_UDP, 41) /* 0x0000020000000000 */ \ |
| 177 | X(SK_VERB_NS_IPV4, 42) /* 0x0000040000000000 */ \ |
| 178 | X(SK_VERB_NS_IPV6, 43) /* 0x0000080000000000 */ \ |
| 179 | X(SK_VERB_COPY, 44) /* 0x0000100000000000 */ \ |
| 180 | X(SK_VERB_COPY_MBUF, 45) /* 0x0000200000000000 */ \ |
| 181 | X(SK_VERB_MOVE, 46) /* 0x0000400000000000 */ \ |
| 182 | X(SK_VERB_MOVE_MBUF, 47) /* 0x0000800000000000 */ \ |
| 183 | X(SK_VERB_IP_FRAG, 48) /* 0x0001000000000000 */ \ |
| 184 | X(SK_VERB_ERROR_INJECT, 49) /* 0x0002000000000000 */ \ |
| 185 | X(SK_VERB_QOS, 50) /* 0x0004000000000000 */ \ |
| 186 | X(SK_VERB_NXPORT, 51) /* 0x0008000000000000 */ \ |
| 187 | X(SK_VERB_FILTER, 52) /* 0x0010000000000000 */ \ |
| 188 | X(SK_VERB_VP, 53) /* 0x0020000000000000 */ \ |
| 189 | X(SK_VERB_NETIF_POLL, 54) /* 0x0040000000000000 */ \ |
| 190 | X(SK_VERB_DROP, 55) /* 0x0080000000000000 */ \ |
| 191 | X(__SK_VERB_56__, 56) /* 0x0100000000000000 */ \ |
| 192 | X(__SK_VERB_57__, 57) /* 0x0200000000000000 */ \ |
| 193 | X(__SK_VERB_58__, 58) /* 0x0400000000000000 */ \ |
| 194 | X(__SK_VERB_59__, 59) /* 0x0800000000000000 */ \ |
| 195 | X(__SK_VERB_60__, 60) /* 0x1000000000000000 */ \ |
| 196 | X(__SK_VERB_61__, 61) /* 0x2000000000000000 */ \ |
| 197 | X(SK_VERB_PRIV, 62) /* 0x4000000000000000 */ \ |
| 198 | X(SK_VERB_ERROR, 63) /* 0x8000000000000000 */ |
| 199 | |
| 200 | #define EXPAND_TO_STRING(name, bitshift) #name, |
| 201 | #define EXPAND_TO_ENUMERATION(name, bitshift) name = (1ULL << bitshift), |
| 202 | |
| 203 | static const char *sk_verb_flags_string[] = { |
| 204 | SK_VERB_FLAGS_TABLE(EXPAND_TO_STRING) |
| 205 | }; |
| 206 | |
| 207 | enum SK_VERB_FLAGS { |
| 208 | SK_VERB_FLAGS_TABLE(EXPAND_TO_ENUMERATION) |
| 209 | }; |
| 210 | |
| 211 | #define SK_VERB_FLAGS_STRINGS_MAX \ |
| 212 | (sizeof (sk_verb_flags_string) / sizeof (sk_verb_flags_string[0])) |
| 213 | |
| 214 | #undef EXPAND_TO_STRING |
| 215 | #undef EXPAND_TO_ENUMERATION |
| 216 | |
| 217 | #ifdef KERNEL |
| 218 | #include <stdint.h> |
| 219 | #include <sys/types.h> |
| 220 | #include <sys/time.h> |
| 221 | #include <mach/vm_types.h> |
| 222 | #include <mach/vm_param.h> |
| 223 | #include <kern/cpu_number.h> |
| 224 | #include <pexpert/pexpert.h> |
| 225 | |
| 226 | #if (DEVELOPMENT || DEBUG) |
| 227 | #define SK_KVA(p) ((uint64_t)(p)) |
| 228 | #define SK_LOG 1 |
| 229 | #else |
| 230 | #define SK_KVA(p) ((uint64_t)VM_KERNEL_ADDRPERM(p)) |
| 231 | #define SK_LOG 0 |
| 232 | #endif /* !DEVELOPMENT && !DEBUG */ |
| 233 | |
| 234 | #if SK_LOG |
| 235 | #define SK_LOG_VAR(x) x |
| 236 | #else |
| 237 | #define SK_LOG_VAR(x) |
| 238 | #endif |
| 239 | |
| 240 | #define SK_INLINE_ATTRIBUTE __attribute__((always_inline)) |
| 241 | #define SK_NO_INLINE_ATTRIBUTE __attribute__((noinline)) |
| 242 | #define SK_LOG_ATTRIBUTE __attribute__((noinline, cold, not_tail_called)) |
| 243 | |
| 244 | #if SK_LOG |
| 245 | /* |
| 246 | * Because the compiler doesn't know about the %b format specifier, |
| 247 | * most warnings for _SK_D are disabled by pragma. |
| 248 | * |
| 249 | * XXX adi@apple.com: This means the compiler will not warn us about |
| 250 | * invalid parameters passed to kprintf(), so make sure to scrutinize |
| 251 | * any changes made to code using any logging macros defined below. |
| 252 | */ |
| 253 | |
| 254 | extern uint64_t sk_verbose; |
| 255 | #define _SK_D(_flag, _fmt, ...) do { \ |
| 256 | if (__improbable(((_flag) && (sk_verbose & (_flag)) == (_flag)) || \ |
| 257 | (_flag) == SK_VERB_ERROR)) { \ |
| 258 | _Pragma("clang diagnostic push") \ |
| 259 | _Pragma("clang diagnostic ignored \"-Wformat-invalid-specifier\"") \ |
| 260 | _Pragma("clang diagnostic ignored \"-Wformat-extra-args\"") \ |
| 261 | _Pragma("clang diagnostic ignored \"-Wformat\"") \ |
| 262 | kprintf("SK[%u]: %-30s " _fmt "\n", \ |
| 263 | cpu_number(), __FUNCTION__, ##__VA_ARGS__); \ |
| 264 | _Pragma("clang diagnostic pop") \ |
| 265 | } \ |
| 266 | } while (0) |
| 267 | |
| 268 | #define SK_DF(_flag, _fmt, ...) _SK_D((uint64_t)_flag, _fmt, ##__VA_ARGS__) |
| 269 | #define SK_D(_fmt, ...) SK_DF(SK_VERB_DEFAULT, _fmt, ##__VA_ARGS__) |
| 270 | #define SK_ERR(_fmt, ...) SK_DF(SK_VERB_ERROR, _fmt, ##__VA_ARGS__) |
| 271 | #define SK_DSC(_p, _fmt, ...) SK_ERR("%s(%d): " _fmt, \ |
| 272 | sk_proc_name_address(_p), sk_proc_pid(_p), ##__VA_ARGS__) |
| 273 | |
| 274 | /* rate limited, lps indicates how many per second */ |
| 275 | #define _SK_RD(_flag, _lps, _fmt, ...) do { \ |
| 276 | static int __t0, __now, __cnt; \ |
| 277 | __now = (int)_net_uptime; \ |
| 278 | if (__t0 != __now) { \ |
| 279 | __t0 = __now; \ |
| 280 | __cnt = 0; \ |
| 281 | } \ |
| 282 | if (__cnt++ < (_lps)) \ |
| 283 | SK_DF(_flag, _fmt, ##__VA_ARGS__); \ |
| 284 | } while (0) |
| 285 | |
| 286 | #define SK_RDF(_flag, _lps, _fmt, ...) \ |
| 287 | _SK_RD(_flag, _lps, _fmt, ##__VA_ARGS__) |
| 288 | #define SK_RD(_lps, _fmt, ...) \ |
| 289 | SK_RDF(SK_VERB_DEFAULT, _lps, _fmt, ##__VA_ARGS__) |
| 290 | #define SK_RDERR(_lps, _fmt, ...) \ |
| 291 | SK_RDF(SK_VERB_ERROR, _lps, _fmt, ##__VA_ARGS__) |
| 292 | #else /* !SK_LOG */ |
| 293 | #define SK_DF(_flag, _fmt, ...) do { ((void)0); } while (0) |
| 294 | #define SK_D(_fmt, ...) do { ((void)0); } while (0) |
| 295 | #define SK_ERR(_fmt, ...) do { ((void)0); } while (0) |
| 296 | #define SK_DSC(_p, _fmt, ...) do { ((void)0); } while (0) |
| 297 | #define SK_RDF(_flag, _lps, _fmt, ...) do { ((void)0); } while (0) |
| 298 | #define SK_RD(_lps, _fmt, ...) do { ((void)0); } while (0) |
| 299 | #define SK_RDERR(_lps, _fmt, ...) do { ((void)0); } while (0) |
| 300 | #endif /* ! SK_LOG */ |
| 301 | |
| 302 | #ifdef BSD_KERNEL_PRIVATE |
| 303 | #include <skywalk/core/skywalk_var.h> |
| 304 | #include <skywalk/lib/cuckoo_hashtable.h> |
| 305 | #include <skywalk/mem/skmem_var.h> |
| 306 | #include <skywalk/channel/os_channel_event.h> |
| 307 | #include <skywalk/channel/channel_var.h> |
| 308 | #include <skywalk/nexus/nexus_var.h> |
| 309 | #include <skywalk/packet/pbufpool_var.h> |
| 310 | #include <skywalk/packet/packet_var.h> |
| 311 | #endif /* BSD_KERNEL_PRIVATE */ |
| 312 | #endif /* KERNEL */ |
| 313 | #if !defined(KERNEL) || defined(BSD_KERNEL_PRIVATE) |
| 314 | #include <skywalk/skywalk_common.h> |
| 315 | #include <skywalk/os_nexus_private.h> |
| 316 | #include <skywalk/os_channel_private.h> |
| 317 | #include <skywalk/os_packet_private.h> |
| 318 | #include <skywalk/os_stats_private.h> |
| 319 | #endif /* !KERNEL || BSD_KERNEL_PRIVATE */ |
| 320 | #endif /* PRIVATE || XNU_KERNEL_PRIVATE */ |
| 321 | #endif /* _SKYWALK_OS_SKYWALK_PRIVATE_H */ |
| 322 | |