1 /* 2 * Copyright (c) 2017-2022 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 _SKYWALK_OS_SYSCTLS_H_ 30 #define _SKYWALK_OS_SYSCTLS_H_ 31 32 #if defined(PRIVATE) || defined(BSD_KERNEL_PRIVATE) 33 #include <stdint.h> 34 35 /* 36 * X (type, field, default_value) 37 * 38 * Note: When defining X, be sure to use '...' such that adding fields will 39 * not break building your project. See the use of SKMEM_SYSCTL_TCP_LIST 40 * to define struct skmem_sysctl below for an example. 41 */ 42 #define SKMEM_SYSCTL_TCP_LIST \ 43 X(int32_t, bg_target_qdelay, 40) \ 44 X(int32_t, bg_allowed_increase, 8) \ 45 X(int32_t, bg_tether_shift, 1) \ 46 X(uint32_t, bg_ss_fltsz, 2) \ 47 X(int32_t, use_newreno, 0) \ 48 X(int32_t, cubic_tcp_friendliness, 0) \ 49 X(int32_t, cubic_fast_convergence, 0) \ 50 X(int32_t, cubic_use_minrtt, 0) \ 51 X(int32_t, delayed_ack, 3) \ 52 X(int32_t, recvbg, 0) \ 53 X(int32_t, drop_synfin, 1) \ 54 X(int32_t, slowlink_wsize, 8192) \ 55 X(int32_t, maxseg_unacked, 8) \ 56 X(int32_t, rfc3465, 1) \ 57 X(int32_t, rfc3465_lim2, 1) \ 58 X(int32_t, recv_allowed_iaj, 5) \ 59 X(uint32_t, doautorcvbuf, 1) \ 60 X(uint32_t, autorcvbufmax, 2 * 1024 * 1024) \ 61 X(int32_t, rcvsspktcnt, 512) \ 62 X(int32_t, path_mtu_discovery, 1) \ 63 X(int32_t, local_slowstart_flightsize, 8) \ 64 X(uint32_t, ecn_setup_percentage, 50) \ 65 X(int32_t, ecn_initiate_out, 0) \ 66 X(int32_t, ecn_negotiate_in, 0) \ 67 X(int32_t, packetchain, 50) \ 68 X(int32_t, socket_unlocked_on_output, 1) \ 69 X(int32_t, min_iaj_win, 16) \ 70 X(int32_t, acc_iaj_react_limit, 200) \ 71 X(uint32_t, autosndbufinc, 8 * 1024) \ 72 X(uint32_t, autosndbufmax, 2 * 1024 * 1024) \ 73 X(uint32_t, rtt_recvbg, 1) \ 74 X(uint32_t, recv_throttle_minwin, 16 * 1024) \ 75 X(int32_t, enable_tlp, 1) \ 76 X(int32_t, sack, 1) \ 77 X(int32_t, sack_maxholes, 128) \ 78 X(int32_t, sack_globalmaxholes, 65536) \ 79 X(int32_t, mssdflt, 512) \ 80 X(int32_t, v6mssdflt, 1024) \ 81 X(int32_t, fastopen_backlog, 10) \ 82 X(int32_t, fastopen, 0x3) \ 83 X(int32_t, minmss, 216) \ 84 X(int32_t, icmp_may_rst, 1) \ 85 X(int32_t, rtt_min, 100) \ 86 X(int32_t, rexmt_slop, 200) \ 87 X(int32_t, randomize_ports, 0) \ 88 X(int32_t, win_scale_factor, 3) \ 89 X(int32_t, keepinit, 75 * 1000) \ 90 X(int32_t, keepidle, 120 * 60 * 1000) \ 91 X(int32_t, keepintvl, 75 * 1000) \ 92 X(int32_t, keepcnt, 8) \ 93 X(int32_t, msl, 15 * 1000) \ 94 X(uint32_t, max_persist_timeout, 0) \ 95 X(int32_t, always_keepalive, 0) \ 96 X(uint32_t, timer_fastmode_idlemax, 10) \ 97 X(int32_t, broken_peer_syn_rexmit_thres, 10) \ 98 X(int32_t, pmtud_blackhole_detection, 1) \ 99 X(uint32_t, pmtud_blackhole_mss, 1200) \ 100 X(int32_t, sendspace, 1448*256) \ 101 X(int32_t, recvspace, 1448*384) \ 102 X(uint32_t, microuptime_init, 0) \ 103 X(uint32_t, now_init, 0) \ 104 X(uint32_t, challengeack_limit, 10) \ 105 X(int32_t, do_rfc5961, 1) \ 106 X(int32_t, init_rtt_from_cache, 1) \ 107 X(uint32_t, autotunereorder, 1) \ 108 X(uint32_t, do_ack_compression, 1) \ 109 X(uint32_t, ack_compression_rate, 5) \ 110 X(int32_t, do_better_lr, 1) \ 111 X(int32_t, cubic_minor_fixes, 1) \ 112 X(int32_t, cubic_rfc_compliant, 1) \ 113 X(int32_t, aggressive_rcvwnd_inc, 1) \ 114 X(int32_t, ack_strategy, 1) \ 115 X(int32_t, flow_control_response, 1) \ 116 X(int32_t, randomize_timestamps, 1) \ 117 X(uint32_t, ledbat_plus_plus, 1) \ 118 X(uint32_t, use_ledbat, 0) \ 119 X(uint32_t, rledbat, 1) \ 120 X(uint32_t, use_min_curr_rtt, 1) \ 121 X(uint32_t, fin_timeout, 30) \ 122 X(uint32_t, accurate_ecn, 0) \ 123 X(int32_t, tso, 1) 124 125 #define SKMEM_SYSCTL_KERN_IPC_LIST \ 126 X(uint32_t, throttle_best_effort, 0) 127 128 #define SKMEM_SYSCTL_TCP_HAS_DEFAULT_VALUES 1 129 #define SKMEM_SYSCTL_TCP_HAS_INIT_TIME 1 130 #define SKMEM_SYSCTL_TCP_HAS_LEDBAT_PLUS_PLUS 1 131 #define SKMEM_SYSCTL_TCP_HAS_RLEDBAT 1 132 #define SKMEM_SYSCTL_TCP_HAS_FIN_TIMEOUT 1 133 #define SKMEM_SYSCTL_TCP_HAS_ACC_ECN 1 134 #define SKMEM_SYSCTL_TCP_HAS_ACC_ECN_OPTION 1 135 /* 136 * When adding a new type above, be sure to add a corresponding 137 * printf format below. Clients use NW_SYSCTL_PRI_##type 138 */ 139 #define NW_SYSCTL_PRI_int32_t PRIi32 140 #define NW_SYSCTL_PRI_uint32_t PRIu32 141 142 #define SKMEM_SYSCTL_VERSION 3 143 144 typedef struct skmem_sysctl { 145 uint32_t version; 146 struct { 147 #define X(type, field, ...) type field; 148 SKMEM_SYSCTL_TCP_LIST 149 #undef X 150 } tcp; 151 struct { 152 struct { 153 #define X(type, field, ...) type field; 154 SKMEM_SYSCTL_KERN_IPC_LIST 155 #undef X 156 } ipc; 157 } kern; 158 } skmem_sysctl; 159 160 /* 161 * Skywalk logical link information 162 * Output: Array of struct nx_llink_info entry (per logical link). 163 */ 164 #define SK_LLINK_LIST_SYSCTL "kern.skywalk.llink_list" 165 166 #ifdef KERNEL 167 /* 168 * SYSCTL_SKMEM is infrastructure for keeping a shared memory region 169 * in sync with a subset of syctl values in the networking stack. 170 */ 171 __BEGIN_DECLS 172 extern void skmem_sysctl_init(void); 173 extern void *skmem_get_sysctls_obj(size_t *); 174 extern int skmem_sysctl_handle_int(struct sysctl_oid *oidp, void *arg1, 175 int arg2, struct sysctl_req *req); 176 __END_DECLS 177 178 #define SYSCTL_SKMEM_UPDATE_FIELD(field, value) do { \ 179 skmem_sysctl *swptr = skmem_get_sysctls_obj(NULL); \ 180 if (swptr) { \ 181 swptr->field = value; \ 182 } \ 183 } while (0) 184 185 /* 186 * Danger - the void* cast below eliminates an alignment warning. 187 * In this case it should be safe because offset should be an offset in to 188 * the structure, so it should already be aligned. Nonetheless, there's 189 * still a check above to ensure offset is aligned properly. 190 */ 191 #define SYSCTL_SKMEM_UPDATE_AT_OFFSET(offset, value) do { \ 192 if (offset >= 0 && \ 193 offset + sizeof (typeof(value)) <= sizeof (skmem_sysctl)) { \ 194 skmem_sysctl *swptr = skmem_get_sysctls_obj(NULL); \ 195 void *offp = (u_int8_t *)swptr + offset; \ 196 if (swptr && \ 197 ((uintptr_t)offp) % _Alignof(typeof(value)) == 0) { \ 198 *(typeof(value)*)offp = (value); \ 199 } \ 200 } \ 201 } while (0) 202 203 #define SYSCTL_SKMEM_INT(parent, oid, sysctl_name, access, ptr, offset, descr) \ 204 SYSCTL_OID(parent, oid, sysctl_name, CTLTYPE_INT|access, \ 205 ptr, offset, skmem_sysctl_handle_int, "I", descr); \ 206 _Static_assert((__builtin_constant_p(ptr) || \ 207 sizeof (*(ptr)) == sizeof (int)), "invalid ptr"); \ 208 _Static_assert(offset % _Alignof(int) == 0, "invalid offset") 209 210 #define SYSCTL_SKMEM_TCP_INT(oid, sysctl_name, access, variable_type, \ 211 variable_name, initial_value, descr) \ 212 variable_type variable_name = initial_value; \ 213 SYSCTL_SKMEM_INT(_net_inet_tcp, oid, sysctl_name, access, \ 214 &variable_name, offsetof(skmem_sysctl, tcp.sysctl_name), descr) 215 216 #define SYSCTL_SKMEM_KERN_IPC_INT(oid, sysctl_name, access, variable_type, \ 217 variable_name, initial_value, descr) \ 218 variable_type variable_name = initial_value; \ 219 SYSCTL_SKMEM_INT(_kern_ipc, oid, sysctl_name, access, \ 220 &variable_name, offsetof(skmem_sysctl, kern.ipc.sysctl_name), descr) 221 #endif /* KERNEL */ 222 #endif /* PRIVATE || BSD_KERNEL_PRIVATE */ 223 #endif /* _SKYWALK_OS_SYSCTLS_H_ */ 224