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 X(int32_t, awdl_rtobase, 100)
125
126#define SKMEM_SYSCTL_KERN_IPC_LIST \
127 X(uint32_t, throttle_best_effort, 0)
128
129#define SKMEM_SYSCTL_TCP_HAS_DEFAULT_VALUES 1
130#define SKMEM_SYSCTL_TCP_HAS_INIT_TIME 1
131#define SKMEM_SYSCTL_TCP_HAS_LEDBAT_PLUS_PLUS 1
132#define SKMEM_SYSCTL_TCP_HAS_RLEDBAT 1
133#define SKMEM_SYSCTL_TCP_HAS_FIN_TIMEOUT 1
134#define SKMEM_SYSCTL_TCP_HAS_ACC_ECN 1
135#define SKMEM_SYSCTL_TCP_HAS_ACC_ECN_OPTION 1
136#define SKMEM_SYSCTL_TCP_HAS_AWDL_RTOBASE 1
137/*
138 * When adding a new type above, be sure to add a corresponding
139 * printf format below. Clients use NW_SYSCTL_PRI_##type
140 */
141#define NW_SYSCTL_PRI_int32_t PRIi32
142#define NW_SYSCTL_PRI_uint32_t PRIu32
143
144#define SKMEM_SYSCTL_VERSION 3
145
146typedef struct skmem_sysctl {
147 uint32_t version;
148 struct {
149#define X(type, field, ...) type field;
150 SKMEM_SYSCTL_TCP_LIST
151#undef X
152 } tcp;
153 struct {
154 struct {
155 #define X(type, field, ...) type field;
156 SKMEM_SYSCTL_KERN_IPC_LIST
157 #undef X
158 } ipc;
159 } kern;
160} skmem_sysctl;
161
162/*
163 * Skywalk logical link information
164 * Output: Array of struct nx_llink_info entry (per logical link).
165 */
166#define SK_LLINK_LIST_SYSCTL "kern.skywalk.llink_list"
167
168#ifdef KERNEL
169/*
170 * SYSCTL_SKMEM is infrastructure for keeping a shared memory region
171 * in sync with a subset of syctl values in the networking stack.
172 */
173__BEGIN_DECLS
174extern void skmem_sysctl_init(void);
175extern void *skmem_get_sysctls_obj(size_t *);
176extern int skmem_sysctl_handle_int(struct sysctl_oid *oidp, void *arg1,
177 int arg2, struct sysctl_req *req);
178__END_DECLS
179
180#define SYSCTL_SKMEM_UPDATE_FIELD(field, value) do { \
181 skmem_sysctl *swptr = skmem_get_sysctls_obj(NULL); \
182 if (swptr) { \
183 swptr->field = value; \
184 } \
185} while (0)
186
187/*
188 * Danger - the void* cast below eliminates an alignment warning.
189 * In this case it should be safe because offset should be an offset in to
190 * the structure, so it should already be aligned. Nonetheless, there's
191 * still a check above to ensure offset is aligned properly.
192 */
193#define SYSCTL_SKMEM_UPDATE_AT_OFFSET(offset, value) do { \
194 if (offset >= 0 && \
195 offset + sizeof (typeof(value)) <= sizeof (skmem_sysctl)) { \
196 skmem_sysctl *swptr = skmem_get_sysctls_obj(NULL); \
197 void *offp = (u_int8_t *)swptr + offset; \
198 if (swptr && \
199 ((uintptr_t)offp) % _Alignof(typeof(value)) == 0) { \
200 *(typeof(value)*)offp = (value); \
201 } \
202 } \
203} while (0)
204
205#define SYSCTL_SKMEM_INT(parent, oid, sysctl_name, access, ptr, offset, descr) \
206 SYSCTL_OID(parent, oid, sysctl_name, CTLTYPE_INT|access, \
207 ptr, offset, skmem_sysctl_handle_int, "I", descr); \
208 _Static_assert((__builtin_constant_p(ptr) || \
209 sizeof (*(ptr)) == sizeof (int)), "invalid ptr"); \
210 _Static_assert(offset % _Alignof(int) == 0, "invalid offset")
211
212#define SYSCTL_SKMEM_TCP_INT(oid, sysctl_name, access, variable_type, \
213 variable_name, initial_value, descr) \
214 variable_type variable_name = initial_value; \
215 SYSCTL_SKMEM_INT(_net_inet_tcp, oid, sysctl_name, access, \
216 &variable_name, offsetof(skmem_sysctl, tcp.sysctl_name), descr)
217
218#define SYSCTL_SKMEM_KERN_IPC_INT(oid, sysctl_name, access, variable_type, \
219 variable_name, initial_value, descr) \
220 variable_type variable_name = initial_value; \
221 SYSCTL_SKMEM_INT(_kern_ipc, oid, sysctl_name, access, \
222 &variable_name, offsetof(skmem_sysctl, kern.ipc.sysctl_name), descr)
223#endif /* KERNEL */
224#endif /* PRIVATE || BSD_KERNEL_PRIVATE */
225#endif /* _SKYWALK_OS_SYSCTLS_H_ */
226