1/*
2 * Copyright (c) 2018 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#include <kern/thread.h>
30#include <kern/sched_prim.h>
31#include <dev/random/randomdev.h>
32
33#include <net/if.h>
34#include <net/classq/classq.h>
35#include <net/pktsched/pktsched.h>
36#include <net/pktsched/pktsched_netem.h>
37
38#define NETEM_STUB \
39int \
40netem_config(__unused struct netem **ne, __unused const char *name, \
41 __unused struct ifnet *ifp, __unused const struct if_netem_params *p,\
42 __unused void *output_handle, __unused netem_output_func_t *output_func, \
43 __unused uint32_t output_max_batch_size) \
44{ \
45 printf("%s error: unavailable on this platform\n", __func__); \
46 return ENOTSUP; \
47} \
48\
49void \
50__attribute__((noreturn)) \
51netem_get_params(__unused struct netem *ne, \
52 __unused struct if_netem_params *p) \
53{ \
54 panic("unexpected netem call"); \
55} \
56\
57void \
58__attribute__((noreturn)) \
59netem_destroy(__unused struct netem *ne) \
60{ \
61 panic("unexpected netem call"); \
62} \
63\
64int \
65netem_enqueue(__unused struct netem *ne, __unused classq_pkt_t *p, \
66 __unused bool *pdrop) \
67{ \
68 panic("unexpected netem call"); \
69 return 0; \
70}
71
72#if SKYWALK
73
74#include <skywalk/os_skywalk_private.h>
75
76/*
77 * The NetEm pktsched is designed with time-to-send scheduler model, scheduling
78 * decision are made at enqueue time only and the dequeue happens in a fixed
79 * routine, which determines wheter to send the next packet based on it's
80 * Time-To-Send (TTS) property.
81 *
82 * ##Enqueue##
83 * The enqueue model looks at various parameters of the
84 * current NetEm settings and calculates the packet's TTS:
85 * 1. Bandwidth regulator
86 * TTS is spaced out into future time based on the (pkt_len/rate).
87 * 2. Latency
88 * which is linearly added on top of TTS.
89 * 3. Reorder
90 * is done by making non-monotonic TTS.
91 * 4. Loss recovery (applies to IOD and FPD only)
92 * by adding recovery interval on top of TTS.
93 *
94 * ##Dequeue##
95 * The dequeue model has only one parameter, the output thread wakeup interval,
96 * which controls the granularity of packet scheduling. The output thread is
97 * created if the NetEm is created with a output handler and function (thus
98 * NetEm managed dequeue model). The thread wakes up periodically based on the
99 * interval. Upon wakeup, it dequeues all packets whose TTS is older than now
100 * and sends them to output handler.
101 *
102 */
103
104#if __LP64__
105#define CONFIG_NETEM 1
106#else
107#define CONFIG_NETEM 0
108#endif
109
110#if CONFIG_NETEM
111
112#define NETEM_PSCALE IF_NETEM_PARAMS_PSCALE
113
114#define NETEM_LOG(_level, _fmt, ...) \
115 do { \
116 if (pktsched_verbose >= _level) { \
117 log(_level, "NETEM: %-30s "_fmt "\n", \
118 __FUNCTION__, ##__VA_ARGS__); \
119 } \
120 } while (0);
121
122SYSCTL_NODE(_net_pktsched, OID_AUTO, netem, CTLFLAG_RW | CTLFLAG_LOCKED, 0,
123 "netem");
124
125static unsigned int netem_output_ival_ms = 1;
126SYSCTL_UINT(_net_pktsched_netem, OID_AUTO, sched_output_ival_ms,
127 CTLFLAG_RW | CTLFLAG_LOCKED, &netem_output_ival_ms, 0,
128 "Netem packet output interval");
129
130#define NETEM_HEAP_SIZE_DEFAULT 2048
131static unsigned int netem_heap_size = NETEM_HEAP_SIZE_DEFAULT;
132SYSCTL_UINT(_net_pktsched_netem, OID_AUTO, heap_size,
133 CTLFLAG_RW | CTLFLAG_LOCKED, &netem_heap_size, 0,
134 "Netem heap size");
135
136extern kern_return_t thread_terminate(thread_t);
137
138static LCK_GRP_DECLARE(netem_lock_group, "pktsched_netem_lock");
139
140static const int32_t NORM_DIST_SCALE = 8192;
141/* normal distribution lookup table */
142static int32_t norm_dist_table[] =
143{
144 -32768, -28307, -26871, -25967, -25298, -24765, -24320, -23937,
145 -23600, -23298, -23025, -22776, -22546, -22333, -22133, -21946,
146 -21770, -21604, -21445, -21295, -21151, -21013, -20882, -20755,
147 -20633, -20516, -20403, -20293, -20187, -20084, -19984, -19887,
148 -19793, -19702, -19612, -19526, -19441, -19358, -19277, -19198,
149 -19121, -19045, -18971, -18899, -18828, -18758, -18690, -18623,
150 -18557, -18492, -18429, -18366, -18305, -18245, -18185, -18127,
151 -18070, -18013, -17957, -17902, -17848, -17794, -17741, -17690,
152 -17638, -17588, -17538, -17489, -17440, -17392, -17345, -17298,
153 -17252, -17206, -17160, -17116, -17071, -17028, -16984, -16942,
154 -16899, -16857, -16816, -16775, -16735, -16694, -16654, -16615,
155 -16576, -16538, -16499, -16461, -16424, -16386, -16350, -16313,
156 -16277, -16241, -16205, -16170, -16135, -16100, -16066, -16031,
157 -15998, -15964, -15931, -15897, -15865, -15832, -15800, -15768,
158 -15736, -15704, -15673, -15642, -15611, -15580, -15550, -15519,
159 -15489, -15460, -15430, -15401, -15371, -15342, -15313, -15285,
160 -15256, -15228, -15200, -15172, -15144, -15116, -15089, -15062,
161 -15035, -15008, -14981, -14954, -14928, -14902, -14875, -14850,
162 -14823, -14798, -14772, -14747, -14722, -14696, -14671, -14647,
163 -14622, -14597, -14573, -14549, -14524, -14500, -14476, -14453,
164 -14429, -14405, -14382, -14359, -14335, -14312, -14289, -14266,
165 -14243, -14221, -14198, -14176, -14153, -14131, -14109, -14087,
166 -14065, -14043, -14021, -14000, -13978, -13957, -13935, -13914,
167 -13893, -13872, -13851, -13830, -13809, -13788, -13768, -13747,
168 -13727, -13706, -13686, -13666, -13646, -13626, -13606, -13586,
169 -13566, -13547, -13527, -13507, -13488, -13468, -13449, -13430,
170 -13411, -13392, -13373, -13354, -13335, -13316, -13297, -13278,
171 -13260, -13242, -13223, -13204, -13186, -13168, -13150, -13131,
172 -13113, -13095, -13077, -13060, -13042, -13024, -13006, -12988,
173 -12971, -12954, -12936, -12918, -12901, -12884, -12867, -12850,
174 -12832, -12815, -12798, -12781, -12764, -12748, -12731, -12714,
175 -12697, -12681, -12664, -12648, -12631, -12615, -12598, -12582,
176 -12566, -12549, -12533, -12517, -12501, -12485, -12469, -12453,
177 -12437, -12422, -12406, -12390, -12374, -12358, -12343, -12327,
178 -12312, -12296, -12281, -12265, -12250, -12235, -12220, -12204,
179 -12189, -12174, -12159, -12144, -12129, -12114, -12099, -12084,
180 -12069, -12054, -12039, -12025, -12010, -11995, -11981, -11966,
181 -11952, -11937, -11923, -11908, -11894, -11879, -11865, -11851,
182 -11837, -11822, -11808, -11794, -11780, -11766, -11752, -11737,
183 -11724, -11710, -11696, -11682, -11668, -11654, -11640, -11627,
184 -11613, -11599, -11586, -11572, -11559, -11545, -11531, -11518,
185 -11504, -11491, -11478, -11464, -11451, -11438, -11425, -11411,
186 -11398, -11385, -11372, -11359, -11346, -11332, -11319, -11306,
187 -11293, -11280, -11268, -11255, -11242, -11229, -11216, -11203,
188 -11191, -11178, -11165, -11153, -11140, -11127, -11114, -11102,
189 -11090, -11077, -11065, -11052, -11040, -11027, -11015, -11002,
190 -10990, -10978, -10965, -10953, -10941, -10929, -10917, -10904,
191 -10892, -10880, -10868, -10856, -10844, -10832, -10820, -10808,
192 -10796, -10784, -10772, -10760, -10748, -10736, -10725, -10713,
193 -10701, -10689, -10677, -10666, -10654, -10643, -10631, -10619,
194 -10607, -10596, -10584, -10573, -10562, -10550, -10539, -10527,
195 -10516, -10504, -10493, -10481, -10470, -10459, -10447, -10436,
196 -10425, -10414, -10402, -10391, -10380, -10369, -10358, -10346,
197 -10335, -10324, -10313, -10302, -10291, -10280, -10269, -10258,
198 -10247, -10236, -10225, -10214, -10203, -10192, -10181, -10171,
199 -10160, -10149, -10138, -10127, -10117, -10106, -10095, -10085,
200 -10074, -10063, -10052, -10042, -10031, -10021, -10010, -10000,
201 -9989, -9978, -9968, -9957, -9947, -9936, -9926, -9916,
202 -9905, -9895, -9884, -9874, -9864, -9853, -9843, -9833,
203 -9822, -9812, -9802, -9791, -9781, -9771, -9761, -9751,
204 -9741, -9730, -9720, -9710, -9700, -9690, -9680, -9670,
205 -9660, -9650, -9640, -9630, -9619, -9610, -9600, -9590,
206 -9580, -9570, -9560, -9550, -9540, -9530, -9520, -9511,
207 -9501, -9491, -9481, -9472, -9462, -9452, -9442, -9432,
208 -9423, -9413, -9403, -9394, -9384, -9374, -9365, -9355,
209 -9345, -9336, -9326, -9317, -9307, -9298, -9288, -9278,
210 -9269, -9259, -9250, -9241, -9231, -9221, -9212, -9202,
211 -9193, -9184, -9175, -9165, -9156, -9146, -9137, -9128,
212 -9119, -9109, -9100, -9090, -9081, -9072, -9063, -9053,
213 -9044, -9035, -9026, -9017, -9008, -8998, -8989, -8980,
214 -8971, -8962, -8953, -8944, -8934, -8925, -8916, -8907,
215 -8898, -8889, -8880, -8871, -8862, -8853, -8844, -8835,
216 -8826, -8817, -8808, -8799, -8790, -8781, -8772, -8764,
217 -8755, -8746, -8737, -8728, -8719, -8711, -8702, -8693,
218 -8684, -8675, -8667, -8658, -8649, -8640, -8632, -8623,
219 -8614, -8605, -8597, -8588, -8579, -8570, -8562, -8553,
220 -8545, -8536, -8527, -8519, -8510, -8502, -8493, -8484,
221 -8476, -8467, -8459, -8450, -8442, -8433, -8425, -8416,
222 -8408, -8399, -8391, -8382, -8374, -8365, -8357, -8348,
223 -8340, -8332, -8323, -8315, -8306, -8298, -8290, -8281,
224 -8273, -8264, -8256, -8248, -8240, -8231, -8223, -8215,
225 -8206, -8198, -8190, -8182, -8174, -8165, -8157, -8149,
226 -8140, -8132, -8124, -8116, -8108, -8099, -8091, -8083,
227 -8075, -8067, -8059, -8051, -8042, -8034, -8027, -8018,
228 -8010, -8002, -7994, -7986, -7978, -7970, -7962, -7954,
229 -7946, -7938, -7930, -7922, -7913, -7906, -7897, -7890,
230 -7882, -7874, -7866, -7858, -7850, -7842, -7834, -7826,
231 -7818, -7810, -7802, -7795, -7787, -7779, -7771, -7763,
232 -7755, -7748, -7739, -7732, -7724, -7716, -7708, -7700,
233 -7693, -7685, -7677, -7669, -7662, -7654, -7646, -7638,
234 -7630, -7623, -7615, -7608, -7600, -7592, -7584, -7577,
235 -7569, -7561, -7553, -7546, -7538, -7530, -7523, -7515,
236 -7508, -7500, -7492, -7485, -7477, -7469, -7462, -7454,
237 -7447, -7439, -7432, -7424, -7417, -7409, -7401, -7394,
238 -7386, -7379, -7372, -7364, -7356, -7349, -7341, -7334,
239 -7327, -7319, -7311, -7304, -7297, -7289, -7281, -7274,
240 -7267, -7259, -7252, -7245, -7237, -7230, -7222, -7215,
241 -7208, -7200, -7193, -7186, -7178, -7171, -7163, -7156,
242 -7149, -7141, -7134, -7127, -7119, -7112, -7105, -7098,
243 -7090, -7083, -7075, -7068, -7061, -7054, -7046, -7039,
244 -7032, -7025, -7018, -7010, -7003, -6996, -6989, -6981,
245 -6974, -6967, -6960, -6953, -6946, -6938, -6931, -6924,
246 -6917, -6910, -6903, -6895, -6888, -6881, -6874, -6867,
247 -6860, -6853, -6845, -6838, -6831, -6824, -6817, -6810,
248 -6803, -6796, -6789, -6782, -6775, -6767, -6760, -6753,
249 -6747, -6740, -6732, -6725, -6718, -6711, -6704, -6697,
250 -6690, -6683, -6676, -6669, -6662, -6655, -6648, -6641,
251 -6634, -6627, -6620, -6613, -6607, -6600, -6593, -6586,
252 -6579, -6572, -6565, -6558, -6551, -6544, -6538, -6531,
253 -6524, -6517, -6510, -6503, -6496, -6489, -6482, -6476,
254 -6469, -6462, -6455, -6448, -6441, -6434, -6428, -6421,
255 -6414, -6407, -6400, -6394, -6387, -6380, -6373, -6366,
256 -6360, -6353, -6346, -6339, -6333, -6326, -6319, -6312,
257 -6306, -6299, -6292, -6286, -6279, -6272, -6265, -6259,
258 -6252, -6245, -6239, -6232, -6225, -6219, -6212, -6205,
259 -6198, -6192, -6185, -6178, -6172, -6165, -6158, -6152,
260 -6145, -6139, -6132, -6125, -6119, -6112, -6105, -6099,
261 -6092, -6085, -6079, -6072, -6066, -6059, -6053, -6046,
262 -6040, -6033, -6026, -6019, -6013, -6006, -6000, -5993,
263 -5987, -5980, -5974, -5967, -5961, -5954, -5948, -5941,
264 -5935, -5928, -5922, -5915, -5908, -5902, -5895, -5889,
265 -5883, -5876, -5870, -5863, -5857, -5850, -5844, -5837,
266 -5831, -5825, -5818, -5811, -5805, -5799, -5792, -5786,
267 -5779, -5773, -5766, -5760, -5754, -5747, -5741, -5734,
268 -5728, -5722, -5715, -5709, -5702, -5696, -5690, -5683,
269 -5677, -5671, -5664, -5658, -5651, -5645, -5639, -5632,
270 -5626, -5620, -5613, -5607, -5600, -5594, -5588, -5582,
271 -5575, -5569, -5563, -5556, -5550, -5544, -5537, -5531,
272 -5525, -5519, -5512, -5506, -5500, -5494, -5487, -5481,
273 -5475, -5468, -5462, -5456, -5450, -5443, -5437, -5431,
274 -5425, -5418, -5412, -5406, -5400, -5393, -5387, -5381,
275 -5375, -5369, -5362, -5356, -5350, -5344, -5337, -5331,
276 -5325, -5319, -5313, -5306, -5300, -5294, -5288, -5282,
277 -5276, -5270, -5263, -5257, -5251, -5245, -5239, -5233,
278 -5226, -5220, -5214, -5208, -5202, -5196, -5190, -5183,
279 -5177, -5171, -5165, -5159, -5153, -5147, -5140, -5135,
280 -5129, -5122, -5116, -5110, -5104, -5098, -5092, -5086,
281 -5080, -5074, -5068, -5061, -5055, -5050, -5043, -5037,
282 -5031, -5025, -5019, -5013, -5007, -5001, -4995, -4989,
283 -4983, -4977, -4971, -4965, -4959, -4953, -4947, -4941,
284 -4935, -4929, -4923, -4917, -4911, -4905, -4899, -4893,
285 -4887, -4881, -4875, -4869, -4863, -4857, -4851, -4845,
286 -4839, -4833, -4827, -4821, -4815, -4809, -4803, -4797,
287 -4791, -4785, -4779, -4773, -4767, -4762, -4755, -4750,
288 -4744, -4738, -4732, -4726, -4720, -4714, -4708, -4702,
289 -4696, -4690, -4685, -4678, -4673, -4667, -4661, -4655,
290 -4649, -4643, -4637, -4631, -4626, -4620, -4614, -4608,
291 -4602, -4596, -4590, -4585, -4579, -4573, -4567, -4561,
292 -4555, -4549, -4544, -4538, -4532, -4526, -4520, -4514,
293 -4508, -4503, -4497, -4491, -4485, -4479, -4474, -4468,
294 -4462, -4456, -4450, -4445, -4439, -4433, -4427, -4421,
295 -4415, -4410, -4404, -4398, -4392, -4386, -4381, -4375,
296 -4369, -4363, -4358, -4352, -4346, -4340, -4334, -4329,
297 -4323, -4317, -4311, -4306, -4300, -4294, -4289, -4283,
298 -4277, -4271, -4266, -4260, -4254, -4248, -4243, -4237,
299 -4231, -4225, -4220, -4214, -4208, -4202, -4197, -4191,
300 -4185, -4180, -4174, -4168, -4162, -4157, -4151, -4146,
301 -4140, -4134, -4128, -4123, -4117, -4111, -4105, -4100,
302 -4094, -4089, -4083, -4077, -4071, -4066, -4060, -4055,
303 -4049, -4043, -4037, -4032, -4026, -4021, -4015, -4009,
304 -4003, -3998, -3992, -3987, -3981, -3975, -3970, -3964,
305 -3958, -3953, -3947, -3942, -3936, -3930, -3925, -3919,
306 -3913, -3908, -3902, -3897, -3891, -3885, -3880, -3874,
307 -3869, -3863, -3857, -3852, -3846, -3840, -3835, -3829,
308 -3824, -3818, -3813, -3807, -3801, -3796, -3790, -3785,
309 -3779, -3774, -3768, -3762, -3757, -3751, -3746, -3740,
310 -3734, -3729, -3723, -3718, -3712, -3707, -3701, -3696,
311 -3690, -3684, -3679, -3673, -3668, -3662, -3657, -3651,
312 -3646, -3640, -3635, -3629, -3624, -3618, -3613, -3607,
313 -3602, -3596, -3591, -3585, -3579, -3574, -3568, -3563,
314 -3557, -3552, -3546, -3541, -3535, -3530, -3524, -3519,
315 -3514, -3508, -3502, -3497, -3491, -3486, -3480, -3475,
316 -3469, -3464, -3459, -3453, -3448, -3442, -3437, -3431,
317 -3425, -3420, -3415, -3409, -3404, -3398, -3393, -3387,
318 -3382, -3376, -3371, -3366, -3360, -3355, -3349, -3344,
319 -3338, -3333, -3328, -3322, -3317, -3311, -3305, -3300,
320 -3295, -3289, -3284, -3278, -3273, -3268, -3262, -3257,
321 -3251, -3246, -3240, -3235, -3230, -3224, -3219, -3213,
322 -3208, -3203, -3197, -3192, -3186, -3181, -3176, -3170,
323 -3165, -3159, -3154, -3149, -3143, -3138, -3132, -3127,
324 -3122, -3116, -3111, -3105, -3100, -3095, -3089, -3084,
325 -3079, -3073, -3068, -3062, -3057, -3052, -3046, -3041,
326 -3036, -3030, -3025, -3019, -3014, -3009, -3003, -2998,
327 -2993, -2987, -2982, -2977, -2971, -2966, -2961, -2955,
328 -2950, -2944, -2939, -2934, -2928, -2923, -2918, -2912,
329 -2907, -2902, -2896, -2891, -2886, -2880, -2875, -2870,
330 -2864, -2859, -2854, -2848, -2843, -2838, -2832, -2827,
331 -2822, -2816, -2811, -2806, -2800, -2795, -2790, -2784,
332 -2779, -2774, -2768, -2763, -2758, -2753, -2747, -2742,
333 -2737, -2732, -2726, -2721, -2716, -2710, -2705, -2700,
334 -2694, -2689, -2684, -2678, -2673, -2668, -2663, -2657,
335 -2652, -2647, -2642, -2636, -2631, -2626, -2620, -2615,
336 -2610, -2605, -2599, -2594, -2589, -2583, -2578, -2573,
337 -2568, -2562, -2557, -2552, -2546, -2542, -2536, -2531,
338 -2526, -2520, -2515, -2510, -2505, -2499, -2494, -2489,
339 -2483, -2478, -2473, -2468, -2463, -2457, -2452, -2447,
340 -2442, -2436, -2431, -2426, -2421, -2415, -2410, -2405,
341 -2400, -2395, -2389, -2384, -2379, -2374, -2368, -2363,
342 -2358, -2353, -2347, -2342, -2337, -2332, -2327, -2321,
343 -2316, -2311, -2306, -2300, -2295, -2290, -2285, -2279,
344 -2275, -2269, -2264, -2259, -2254, -2248, -2243, -2238,
345 -2233, -2227, -2222, -2217, -2212, -2207, -2202, -2196,
346 -2191, -2186, -2181, -2175, -2170, -2165, -2160, -2155,
347 -2150, -2144, -2139, -2134, -2129, -2124, -2118, -2113,
348 -2108, -2103, -2098, -2093, -2087, -2082, -2077, -2072,
349 -2067, -2062, -2056, -2051, -2046, -2041, -2036, -2030,
350 -2025, -2020, -2015, -2010, -2005, -2000, -1994, -1989,
351 -1984, -1979, -1974, -1969, -1963, -1958, -1953, -1948,
352 -1943, -1937, -1932, -1927, -1922, -1917, -1912, -1907,
353 -1901, -1896, -1891, -1886, -1881, -1876, -1871, -1865,
354 -1860, -1855, -1850, -1845, -1840, -1835, -1829, -1824,
355 -1819, -1814, -1809, -1804, -1799, -1794, -1788, -1783,
356 -1778, -1773, -1768, -1763, -1758, -1752, -1747, -1742,
357 -1737, -1732, -1727, -1722, -1717, -1711, -1706, -1701,
358 -1696, -1691, -1686, -1681, -1676, -1670, -1665, -1660,
359 -1655, -1650, -1645, -1640, -1635, -1629, -1624, -1619,
360 -1614, -1609, -1604, -1599, -1594, -1589, -1584, -1579,
361 -1573, -1568, -1563, -1558, -1553, -1548, -1543, -1538,
362 -1532, -1527, -1522, -1517, -1512, -1507, -1502, -1497,
363 -1492, -1486, -1482, -1477, -1471, -1466, -1461, -1456,
364 -1451, -1446, -1441, -1436, -1431, -1425, -1420, -1415,
365 -1410, -1405, -1400, -1395, -1390, -1385, -1380, -1375,
366 -1370, -1364, -1359, -1354, -1349, -1344, -1339, -1334,
367 -1329, -1324, -1319, -1314, -1309, -1303, -1298, -1294,
368 -1288, -1283, -1278, -1273, -1268, -1263, -1258, -1253,
369 -1248, -1243, -1237, -1232, -1228, -1222, -1217, -1212,
370 -1207, -1202, -1197, -1192, -1187, -1182, -1177, -1171,
371 -1167, -1162, -1156, -1151, -1146, -1141, -1136, -1131,
372 -1126, -1121, -1116, -1111, -1106, -1101, -1096, -1091,
373 -1085, -1081, -1076, -1070, -1065, -1060, -1055, -1050,
374 -1045, -1040, -1035, -1030, -1025, -1020, -1015, -1010,
375 -1005, -1000, -995, -990, -985, -979, -974, -970,
376 -964, -959, -954, -949, -944, -939, -934, -929,
377 -924, -919, -914, -909, -904, -899, -894, -889,
378 -884, -879, -874, -868, -863, -859, -853, -848,
379 -843, -838, -833, -828, -823, -818, -813, -808,
380 -803, -798, -793, -788, -783, -778, -773, -768,
381 -763, -758, -752, -748, -743, -738, -732, -727,
382 -723, -717, -712, -707, -702, -697, -692, -687,
383 -682, -677, -672, -667, -662, -657, -652, -647,
384 -642, -637, -632, -627, -622, -617, -612, -607,
385 -602, -597, -591, -587, -582, -577, -571, -566,
386 -562, -557, -551, -546, -541, -537, -531, -526,
387 -521, -516, -511, -506, -501, -496, -491, -486,
388 -481, -476, -471, -466, -461, -456, -451, -446,
389 -441, -436, -431, -426, -421, -416, -411, -406,
390 -401, -396, -391, -386, -381, -376, -371, -366,
391 -360, -356, -351, -346, -340, -335, -331, -326,
392 -320, -315, -310, -306, -300, -295, -290, -285,
393 -281, -275, -270, -265, -261, -255, -250, -245,
394 -240, -235, -230, -225, -220, -215, -210, -205,
395 -200, -195, -190, -185, -180, -175, -170, -165,
396 -160, -155, -150, -145, -140, -135, -130, -125,
397 -120, -115, -110, -105, -100, -95, -90, -85,
398 -80, -75, -70, -65, -60, -55, -50, -45,
399 -40, -35, -29, -25, -20, -15, -9, -5,
400 0, 5, 11, 16, 20, 25, 30, 36,
401 41, 45, 50, 56, 61, 66, 70, 76,
402 81, 86, 91, 96, 101, 106, 111, 116,
403 121, 126, 131, 136, 141, 146, 151, 156,
404 161, 166, 171, 176, 181, 186, 191, 196,
405 201, 206, 211, 216, 221, 226, 231, 236,
406 241, 246, 251, 256, 261, 266, 271, 276,
407 281, 286, 291, 296, 301, 306, 311, 316,
408 322, 326, 331, 336, 342, 347, 351, 356,
409 362, 367, 372, 376, 382, 387, 392, 396,
410 402, 407, 412, 417, 422, 427, 432, 437,
411 442, 447, 452, 457, 462, 467, 472, 477,
412 482, 487, 492, 497, 502, 507, 512, 517,
413 522, 527, 532, 537, 542, 547, 552, 557,
414 562, 567, 572, 578, 582, 587, 593, 598,
415 603, 607, 613, 618, 623, 628, 633, 638,
416 643, 648, 653, 658, 663, 668, 673, 678,
417 683, 688, 693, 698, 703, 708, 713, 718,
418 723, 728, 733, 739, 743, 748, 754, 759,
419 763, 768, 774, 779, 784, 789, 794, 799,
420 804, 809, 814, 819, 824, 829, 834, 839,
421 844, 849, 854, 859, 864, 869, 874, 879,
422 884, 890, 895, 899, 905, 910, 915, 920,
423 925, 930, 935, 940, 945, 950, 955, 960,
424 965, 970, 975, 980, 985, 990, 995, 1001,
425 1006, 1010, 1016, 1021, 1026, 1031, 1036, 1041,
426 1046, 1051, 1056, 1061, 1066, 1071, 1076, 1081,
427 1086, 1092, 1096, 1102, 1107, 1112, 1117, 1122,
428 1127, 1132, 1137, 1142, 1147, 1152, 1157, 1162,
429 1167, 1173, 1178, 1183, 1188, 1193, 1198, 1203,
430 1208, 1213, 1218, 1223, 1228, 1233, 1238, 1244,
431 1248, 1254, 1259, 1264, 1269, 1274, 1279, 1284,
432 1289, 1294, 1299, 1304, 1309, 1314, 1320, 1325,
433 1330, 1335, 1340, 1345, 1350, 1355, 1360, 1365,
434 1371, 1375, 1381, 1386, 1391, 1396, 1401, 1406,
435 1411, 1416, 1421, 1426, 1432, 1436, 1442, 1447,
436 1452, 1457, 1462, 1467, 1472, 1477, 1482, 1488,
437 1493, 1497, 1503, 1508, 1513, 1518, 1523, 1528,
438 1534, 1538, 1543, 1549, 1554, 1559, 1564, 1569,
439 1574, 1579, 1584, 1590, 1595, 1600, 1605, 1610,
440 1615, 1620, 1625, 1630, 1636, 1640, 1646, 1651,
441 1656, 1661, 1666, 1671, 1676, 1681, 1687, 1692,
442 1697, 1702, 1707, 1712, 1717, 1722, 1728, 1733,
443 1738, 1743, 1748, 1753, 1758, 1764, 1769, 1774,
444 1779, 1784, 1789, 1794, 1799, 1805, 1810, 1815,
445 1820, 1825, 1831, 1835, 1841, 1846, 1851, 1856,
446 1861, 1866, 1871, 1877, 1882, 1887, 1892, 1897,
447 1902, 1908, 1913, 1918, 1923, 1928, 1933, 1939,
448 1944, 1949, 1954, 1959, 1964, 1969, 1975, 1980,
449 1985, 1990, 1995, 2000, 2005, 2011, 2016, 2021,
450 2026, 2031, 2037, 2042, 2047, 2052, 2057, 2062,
451 2068, 2073, 2078, 2083, 2088, 2093, 2099, 2104,
452 2109, 2114, 2119, 2125, 2130, 2135, 2140, 2145,
453 2150, 2156, 2161, 2166, 2171, 2177, 2182, 2187,
454 2192, 2197, 2202, 2208, 2213, 2218, 2223, 2229,
455 2234, 2239, 2244, 2249, 2254, 2260, 2265, 2270,
456 2275, 2281, 2286, 2291, 2296, 2302, 2306, 2312,
457 2317, 2322, 2327, 2333, 2338, 2343, 2348, 2354,
458 2359, 2364, 2369, 2374, 2380, 2385, 2390, 2395,
459 2401, 2406, 2411, 2416, 2422, 2427, 2432, 2437,
460 2442, 2448, 2453, 2458, 2463, 2469, 2474, 2479,
461 2485, 2490, 2495, 2500, 2506, 2511, 2516, 2521,
462 2526, 2532, 2537, 2542, 2548, 2553, 2558, 2563,
463 2569, 2574, 2579, 2585, 2589, 2595, 2600, 2605,
464 2611, 2616, 2621, 2627, 2632, 2637, 2642, 2648,
465 2653, 2658, 2664, 2669, 2674, 2680, 2685, 2690,
466 2695, 2700, 2706, 2711, 2716, 2722, 2727, 2732,
467 2738, 2743, 2748, 2754, 2759, 2764, 2769, 2775,
468 2780, 2785, 2791, 2796, 2801, 2807, 2812, 2817,
469 2823, 2828, 2833, 2839, 2844, 2849, 2855, 2860,
470 2865, 2870, 2876, 2881, 2886, 2892, 2897, 2902,
471 2908, 2913, 2918, 2924, 2929, 2935, 2940, 2945,
472 2951, 2956, 2961, 2967, 2972, 2977, 2983, 2988,
473 2993, 2999, 3004, 3010, 3015, 3020, 3026, 3031,
474 3036, 3042, 3047, 3052, 3058, 3063, 3069, 3074,
475 3079, 3085, 3090, 3095, 3101, 3106, 3112, 3117,
476 3122, 3128, 3133, 3139, 3144, 3149, 3155, 3160,
477 3166, 3171, 3176, 3182, 3187, 3193, 3198, 3203,
478 3209, 3214, 3220, 3225, 3231, 3236, 3242, 3247,
479 3252, 3258, 3263, 3269, 3274, 3279, 3285, 3290,
480 3296, 3301, 3307, 3312, 3317, 3323, 3328, 3334,
481 3339, 3345, 3350, 3355, 3361, 3367, 3372, 3378,
482 3383, 3388, 3394, 3399, 3405, 3410, 3416, 3421,
483 3427, 3432, 3437, 3443, 3448, 3454, 3459, 3465,
484 3471, 3476, 3481, 3487, 3492, 3498, 3503, 3509,
485 3514, 3520, 3525, 3531, 3536, 3542, 3548, 3553,
486 3558, 3564, 3569, 3575, 3580, 3586, 3591, 3597,
487 3602, 3608, 3613, 3619, 3625, 3630, 3636, 3641,
488 3647, 3652, 3658, 3663, 3669, 3675, 3680, 3686,
489 3691, 3697, 3702, 3708, 3713, 3719, 3724, 3730,
490 3736, 3741, 3747, 3752, 3758, 3763, 3769, 3774,
491 3780, 3786, 3791, 3797, 3802, 3808, 3813, 3819,
492 3825, 3830, 3836, 3842, 3847, 3853, 3858, 3864,
493 3869, 3875, 3881, 3886, 3892, 3898, 3903, 3909,
494 3915, 3920, 3926, 3931, 3937, 3942, 3948, 3954,
495 3960, 3965, 3971, 3976, 3982, 3987, 3993, 3999,
496 4005, 4010, 4016, 4021, 4027, 4033, 4039, 4044,
497 4050, 4055, 4061, 4067, 4073, 4078, 4084, 4089,
498 4095, 4101, 4107, 4112, 4118, 4123, 4129, 4135,
499 4141, 4146, 4152, 4158, 4164, 4169, 4175, 4181,
500 4187, 4192, 4198, 4203, 4209, 4215, 4221, 4226,
501 4232, 4238, 4243, 4249, 4255, 4261, 4266, 4272,
502 4278, 4284, 4289, 4295, 4301, 4307, 4313, 4318,
503 4324, 4330, 4336, 4341, 4347, 4353, 4359, 4364,
504 4370, 4376, 4382, 4388, 4393, 4399, 4405, 4411,
505 4417, 4422, 4428, 4434, 4440, 4445, 4452, 4457,
506 4463, 4469, 4474, 4481, 4486, 4492, 4498, 4504,
507 4510, 4515, 4521, 4527, 4533, 4539, 4545, 4551,
508 4556, 4562, 4568, 4574, 4580, 4585, 4592, 4597,
509 4603, 4609, 4615, 4621, 4627, 4633, 4638, 4644,
510 4650, 4656, 4662, 4668, 4674, 4680, 4686, 4692,
511 4697, 4703, 4709, 4715, 4721, 4727, 4733, 4739,
512 4745, 4751, 4757, 4762, 4769, 4774, 4780, 4786,
513 4792, 4798, 4804, 4810, 4816, 4822, 4828, 4834,
514 4840, 4846, 4852, 4858, 4864, 4870, 4876, 4882,
515 4888, 4894, 4900, 4906, 4912, 4918, 4924, 4930,
516 4936, 4942, 4948, 4954, 4960, 4966, 4972, 4978,
517 4984, 4990, 4996, 5002, 5008, 5014, 5020, 5026,
518 5032, 5038, 5045, 5050, 5057, 5063, 5069, 5075,
519 5081, 5087, 5093, 5099, 5105, 5111, 5118, 5123,
520 5129, 5136, 5142, 5148, 5154, 5160, 5166, 5172,
521 5179, 5185, 5191, 5197, 5203, 5209, 5215, 5221,
522 5227, 5233, 5240, 5246, 5252, 5258, 5265, 5271,
523 5277, 5283, 5289, 5295, 5301, 5308, 5314, 5320,
524 5326, 5333, 5339, 5345, 5351, 5357, 5363, 5369,
525 5376, 5382, 5388, 5394, 5401, 5407, 5413, 5419,
526 5426, 5432, 5438, 5444, 5451, 5457, 5463, 5469,
527 5476, 5482, 5488, 5494, 5501, 5507, 5513, 5520,
528 5526, 5532, 5539, 5545, 5551, 5557, 5564, 5570,
529 5576, 5583, 5589, 5596, 5602, 5608, 5614, 5621,
530 5627, 5634, 5640, 5646, 5652, 5659, 5665, 5672,
531 5678, 5684, 5691, 5697, 5704, 5710, 5716, 5723,
532 5729, 5736, 5742, 5748, 5755, 5761, 5768, 5774,
533 5780, 5787, 5793, 5800, 5806, 5813, 5819, 5826,
534 5832, 5838, 5845, 5852, 5858, 5864, 5871, 5877,
535 5884, 5890, 5897, 5903, 5910, 5916, 5923, 5929,
536 5936, 5942, 5949, 5956, 5962, 5968, 5975, 5981,
537 5988, 5994, 6001, 6008, 6014, 6021, 6027, 6034,
538 6041, 6047, 6054, 6060, 6067, 6074, 6080, 6087,
539 6093, 6100, 6107, 6113, 6120, 6126, 6133, 6140,
540 6146, 6153, 6160, 6167, 6173, 6180, 6186, 6193,
541 6200, 6206, 6213, 6220, 6226, 6233, 6240, 6246,
542 6253, 6260, 6266, 6273, 6280, 6287, 6294, 6300,
543 6307, 6314, 6321, 6327, 6334, 6341, 6348, 6354,
544 6361, 6368, 6375, 6382, 6388, 6395, 6402, 6409,
545 6416, 6422, 6429, 6436, 6443, 6450, 6457, 6463,
546 6470, 6477, 6484, 6491, 6497, 6504, 6511, 6518,
547 6525, 6532, 6539, 6546, 6553, 6559, 6566, 6573,
548 6580, 6587, 6594, 6601, 6608, 6615, 6622, 6629,
549 6636, 6643, 6650, 6657, 6664, 6671, 6678, 6685,
550 6692, 6699, 6706, 6713, 6719, 6727, 6734, 6741,
551 6748, 6755, 6762, 6769, 6776, 6783, 6790, 6797,
552 6804, 6811, 6818, 6826, 6833, 6840, 6847, 6854,
553 6861, 6868, 6875, 6883, 6889, 6897, 6904, 6911,
554 6918, 6925, 6932, 6939, 6947, 6954, 6961, 6969,
555 6975, 6983, 6990, 6997, 7005, 7012, 7019, 7026,
556 7033, 7041, 7048, 7055, 7062, 7070, 7077, 7084,
557 7091, 7099, 7106, 7114, 7121, 7128, 7135, 7143,
558 7150, 7157, 7165, 7172, 7179, 7187, 7194, 7202,
559 7209, 7216, 7224, 7231, 7238, 7246, 7253, 7261,
560 7268, 7276, 7283, 7290, 7298, 7306, 7313, 7320,
561 7328, 7336, 7343, 7350, 7358, 7365, 7373, 7381,
562 7388, 7395, 7403, 7410, 7418, 7426, 7433, 7441,
563 7448, 7456, 7463, 7471, 7479, 7486, 7494, 7501,
564 7509, 7517, 7524, 7532, 7540, 7547, 7555, 7563,
565 7571, 7578, 7586, 7594, 7601, 7609, 7617, 7624,
566 7632, 7640, 7648, 7655, 7663, 7671, 7679, 7687,
567 7694, 7702, 7710, 7718, 7725, 7733, 7741, 7749,
568 7757, 7765, 7773, 7780, 7788, 7796, 7804, 7812,
569 7820, 7828, 7836, 7843, 7852, 7859, 7868, 7875,
570 7883, 7891, 7899, 7907, 7915, 7923, 7931, 7939,
571 7947, 7955, 7963, 7971, 7979, 7988, 7995, 8004,
572 8012, 8020, 8028, 8036, 8044, 8052, 8061, 8069,
573 8076, 8085, 8093, 8101, 8109, 8117, 8126, 8134,
574 8142, 8150, 8158, 8167, 8175, 8183, 8192, 8200,
575 8208, 8217, 8225, 8233, 8241, 8250, 8258, 8266,
576 8275, 8283, 8292, 8300, 8308, 8317, 8325, 8333,
577 8342, 8350, 8359, 8367, 8376, 8384, 8392, 8401,
578 8409, 8418, 8426, 8435, 8443, 8452, 8461, 8469,
579 8477, 8486, 8495, 8503, 8512, 8520, 8529, 8538,
580 8546, 8555, 8564, 8573, 8581, 8590, 8598, 8607,
581 8616, 8625, 8633, 8642, 8651, 8659, 8668, 8677,
582 8686, 8695, 8704, 8712, 8721, 8730, 8739, 8748,
583 8756, 8765, 8774, 8783, 8792, 8801, 8810, 8819,
584 8828, 8837, 8846, 8855, 8864, 8873, 8882, 8891,
585 8900, 8909, 8918, 8927, 8936, 8945, 8954, 8964,
586 8973, 8982, 8991, 9000, 9009, 9019, 9028, 9037,
587 9046, 9055, 9064, 9074, 9083, 9092, 9102, 9111,
588 9120, 9130, 9139, 9148, 9157, 9167, 9176, 9186,
589 9195, 9205, 9214, 9223, 9233, 9242, 9252, 9261,
590 9271, 9280, 9290, 9300, 9309, 9318, 9328, 9338,
591 9347, 9357, 9367, 9376, 9386, 9395, 9405, 9415,
592 9424, 9434, 9444, 9454, 9464, 9473, 9483, 9493,
593 9503, 9513, 9522, 9532, 9542, 9552, 9562, 9572,
594 9582, 9592, 9602, 9612, 9622, 9632, 9642, 9652,
595 9662, 9672, 9682, 9692, 9702, 9712, 9722, 9733,
596 9743, 9753, 9763, 9773, 9783, 9794, 9804, 9814,
597 9825, 9835, 9845, 9855, 9866, 9876, 9887, 9897,
598 9907, 9918, 9928, 9939, 9949, 9960, 9970, 9981,
599 9991, 10002, 10012, 10023, 10034, 10044, 10055, 10066,
600 10076, 10087, 10097, 10108, 10119, 10130, 10140, 10152,
601 10162, 10173, 10184, 10195, 10206, 10217, 10227, 10238,
602 10249, 10260, 10271, 10282, 10293, 10304, 10315, 10326,
603 10337, 10349, 10360, 10371, 10382, 10394, 10405, 10416,
604 10427, 10438, 10450, 10461, 10472, 10484, 10495, 10507,
605 10518, 10530, 10541, 10553, 10564, 10575, 10587, 10598,
606 10610, 10622, 10633, 10645, 10657, 10668, 10680, 10692,
607 10704, 10715, 10727, 10739, 10751, 10763, 10775, 10786,
608 10798, 10811, 10822, 10834, 10847, 10858, 10870, 10883,
609 10895, 10907, 10919, 10931, 10944, 10956, 10968, 10981,
610 10993, 11005, 11017, 11030, 11042, 11055, 11067, 11080,
611 11092, 11105, 11117, 11130, 11142, 11155, 11168, 11180,
612 11193, 11206, 11219, 11232, 11245, 11257, 11270, 11283,
613 11296, 11309, 11322, 11335, 11348, 11361, 11375, 11388,
614 11401, 11414, 11427, 11441, 11454, 11467, 11481, 11494,
615 11508, 11521, 11534, 11548, 11561, 11575, 11589, 11602,
616 11616, 11630, 11644, 11657, 11671, 11685, 11699, 11713,
617 11727, 11741, 11755, 11769, 11783, 11797, 11811, 11826,
618 11839, 11854, 11868, 11882, 11897, 11911, 11926, 11940,
619 11955, 11969, 11984, 11998, 12013, 12028, 12043, 12057,
620 12072, 12087, 12102, 12117, 12132, 12147, 12162, 12177,
621 12193, 12208, 12223, 12238, 12254, 12269, 12284, 12299,
622 12315, 12331, 12346, 12362, 12378, 12393, 12409, 12425,
623 12441, 12457, 12473, 12489, 12505, 12521, 12537, 12553,
624 12569, 12586, 12602, 12619, 12635, 12651, 12668, 12684,
625 12701, 12718, 12734, 12751, 12768, 12785, 12802, 12819,
626 12836, 12853, 12870, 12888, 12905, 12922, 12940, 12957,
627 12975, 12993, 13010, 13028, 13046, 13064, 13081, 13099,
628 13117, 13135, 13154, 13172, 13190, 13209, 13227, 13246,
629 13264, 13283, 13301, 13320, 13339, 13358, 13377, 13396,
630 13415, 13434, 13454, 13473, 13492, 13512, 13532, 13551,
631 13571, 13591, 13611, 13631, 13651, 13671, 13691, 13711,
632 13732, 13752, 13773, 13793, 13814, 13835, 13856, 13877,
633 13898, 13919, 13940, 13962, 13983, 14005, 14026, 14048,
634 14070, 14092, 14114, 14136, 14159, 14181, 14203, 14226,
635 14249, 14272, 14294, 14318, 14341, 14364, 14387, 14411,
636 14434, 14458, 14482, 14506, 14530, 14554, 14578, 14603,
637 14628, 14653, 14677, 14703, 14728, 14753, 14778, 14804,
638 14830, 14855, 14882, 14908, 14934, 14961, 14987, 15014,
639 15041, 15068, 15095, 15123, 15151, 15179, 15206, 15235,
640 15263, 15291, 15320, 15349, 15378, 15408, 15437, 15466,
641 15496, 15527, 15557, 15587, 15618, 15649, 15680, 15712,
642 15743, 15775, 15808, 15840, 15872, 15906, 15939, 15972,
643 16006, 16040, 16074, 16108, 16143, 16178, 16214, 16249,
644 16285, 16322, 16358, 16395, 16433, 16470, 16508, 16547,
645 16586, 16624, 16664, 16704, 16744, 16785, 16826, 16867,
646 16910, 16952, 16995, 17038, 17082, 17126, 17171, 17217,
647 17263, 17309, 17356, 17403, 17452, 17501, 17550, 17600,
648 17651, 17702, 17754, 17807, 17861, 17915, 17970, 18026,
649 18083, 18141, 18200, 18259, 18320, 18382, 18444, 18508,
650 18573, 18639, 18706, 18775, 18845, 18917, 18989, 19064,
651 19140, 19217, 19297, 19378, 19461, 19547, 19634, 19724,
652 19816, 19911, 20009, 20109, 20213, 20319, 20430, 20544,
653 20663, 20786, 20914, 21047, 21186, 21331, 21484, 21644,
654 21813, 21991, 22181, 22384, 22601, 22836, 23091, 23370,
655 23679, 24027, 24424, 24888, 25450, 26164, 27159, 28858,
656};
657#define NORM_DIST_TABLE_SIZE \
658 (sizeof (norm_dist_table) / sizeof (norm_dist_table[0]))
659
660static uint32_t
661norm_dist(uint32_t mean, uint32_t stdvar)
662{
663 int32_t ret, var;
664
665 ret = mean;
666 var = 0;
667 if (stdvar != 0) {
668 int32_t rand, x, t, s = stdvar;
669 read_frandom(buffer: &rand, numBytes: sizeof(rand));
670 t = norm_dist_table[rand % NORM_DIST_TABLE_SIZE];
671 x = (s % NORM_DIST_SCALE) * t;
672 if (x >= 0) {
673 x += NORM_DIST_SCALE / 2;
674 } else {
675 x -= NORM_DIST_SCALE / 2;
676 }
677 var = x / NORM_DIST_SCALE + (s * t / NORM_DIST_SCALE);
678 }
679
680 ret += var;
681 ret = MAX(ret, 0);
682
683 return ret;
684}
685
686struct heap_elem {
687 uint64_t key;
688 pktsched_pkt_t pkt;
689};
690
691struct heap {
692 size_t limit; /* max size */
693 size_t size; /* current size */
694 struct heap_elem p[0];
695};
696
697static struct heap *heap_create(size_t size);
698static int heap_insert(struct heap *h, uint64_t k, pktsched_pkt_t *p);
699static int heap_peek(struct heap *h, uint64_t *k, pktsched_pkt_t *p);
700static int heap_extract(struct heap *h, uint64_t *k, pktsched_pkt_t *p);
701
702typedef enum {
703 NETEM_MODEL_NULL = IF_NETEM_MODEL_NULL,
704 NETEM_MODEL_NLC = IF_NETEM_MODEL_NLC,
705} netem_model_t;
706
707typedef int (*netem_enqueue_fn_t)(struct netem *, classq_pkt_t *, bool *);
708
709struct netem {
710 decl_lck_mtx_data(, netem_lock);
711
712 /************************ Init Time Constants *************************/
713 char netem_name[MAXTHREADNAMESIZE];
714 uint32_t netem_flags;
715 struct ifnet *netem_ifp;
716 struct thread *netem_output_thread;
717
718 void *netem_output_handle;
719 int (*netem_output)(void *handle,
720 pktsched_pkt_t *pkts, uint32_t n_pkts);
721 uint32_t netem_output_max_batch_size;
722 uint32_t netem_output_ival_ms;
723
724 struct heap *netem_heap;
725
726 /*********************** Parameters variables *************************/
727 netem_model_t netem_model;
728 netem_enqueue_fn_t netem_enqueue;
729
730 /* bandwidth token bucket limit */
731#define TOKEN_INVALID UINT64_MAX
732 struct bandwidth {
733 uint64_t rate;
734 uint64_t prev_time_to_send;
735 } netem_bandwidth_model;
736
737 /* XXX (need correlated) naive corruption model */
738 struct corruption {
739 uint32_t corruption_p;
740 } netem_corruption_model;
741
742 /* naive duplication model */
743 struct duplication {
744 uint32_t duplication_p;
745 } netem_duplication_model;
746
747 /* latency (with jitter following random distribution) */
748 struct latency {
749 uint32_t latency_ms;
750 uint32_t jitter_ms;
751 uint64_t prev_time_to_send;
752 } netem_latency_model;
753
754 /* 4 state Markov packet loss model */
755 struct loss {
756 enum _4state_markov_packet_loss_state {
757 __NO_LOSS = 0,
758 GAP_RX = 1,
759 GAP_LOSS,
760 BURST_RX,
761 BURST_LOSS,
762 } state;
763
764 uint32_t p_gr_gl; /* P( gap_loss | gap_rx ) */
765 uint32_t p_gr_bl; /* P( burst_loss | gap_rx ) */
766 uint32_t p_bl_br; /* P( burst_rx | burst_loss ) */
767 uint32_t p_bl_gr; /* P( gap_rx | burst_loss ) */
768 uint32_t p_br_bl; /* P( burst_loss | burst_rx ) */
769
770 uint32_t recovery_ms; /* time to recovery from loss */
771 uint64_t recovery_window;/* time recovery will finish */
772 } netem_loss_model;
773
774 /*
775 * Reordering Model --
776 * randomly select packets and re-inject with additional delay
777 */
778 struct reordering {
779 uint32_t reordering_p;
780 uint32_t reordering_ms;
781 } netem_reordering_model;
782};
783
784#define NETEMF_INITIALIZED 0x00000001 /* has been initialized */
785#define NETEMF_RUNNING 0x00000002 /* thread is running */
786#define NETEMF_OUTPUT_IVAL_ONLY 0x00000004 /* output on intervals only */
787#define NETEMF_TERMINATEBLOCK 0x20000000 /* block waiting terminate */
788#define NETEMF_TERMINATING 0x40000000 /* thread is terminating */
789#define NETEMF_TERMINATED 0x80000000 /* thread is terminated */
790
791#define NETEM_MTX_LOCK(_ne) \
792 lck_mtx_lock(&(_ne)->netem_lock)
793#define NETEM_MTX_LOCK_ASSERT_HELD(_ne) \
794 LCK_MTX_ASSERT(&(_ne)->netem_lock, LCK_ASSERT_OWNED)
795#define NETEM_MTX_LOCK_ASSERT_NOTHELD(_ne) \
796 LCK_MTX_ASSERT(&(_ne)->netem_lock, LCK_ASSERT_NOTOWNED)
797#define NETEM_MTX_UNLOCK(_ne) \
798 lck_mtx_unlock(&(_ne)->netem_lock)
799#define NETEM_OUTPUT_IVAL_ONLY(_ne) \
800 ((_ne->netem_flags & NETEMF_OUTPUT_IVAL_ONLY) != 0)
801
802static struct heap *
803heap_create(size_t limit)
804{
805 struct heap *h = NULL;
806
807 // verify limit
808 h = kalloc_type(struct heap, struct heap_elem, limit, Z_WAITOK | Z_ZERO);
809 if (h == NULL) {
810 return NULL;
811 }
812
813 h->limit = limit;
814 h->size = 0;
815
816 return h;
817}
818
819static void
820heap_destroy(struct heap *h)
821{
822 ASSERT(h->size == 0);
823
824 kfree_type(struct heap, struct heap_elem, h->limit, h);
825}
826
827#define HEAP_FATHER(child) (((child) - 1) / 2)
828#define HEAP_SWAP(a, b, tmp) { tmp = a; a = b; b = tmp; }
829#define HEAP_LEFT(x) (2 * (x) + 1)
830
831static int
832heap_insert(struct heap *h, uint64_t key, pktsched_pkt_t *pkt)
833{
834 ASSERT(h != NULL);
835
836 if (h->size == h->limit) {
837 return ENOBUFS;
838 }
839
840 uint64_t child, parent;
841 if (pkt == NULL) {
842 child = key;
843 ASSERT(child < h->size);
844 } else {
845 child = h->size;
846 h->p[child].key = key;
847 h->p[child].pkt = *pkt;
848 h->size++;
849 }
850
851 while (child > 0) {
852 struct heap_elem tmp;
853 parent = HEAP_FATHER(child);
854 if (h->p[parent].key < h->p[child].key) {
855 break;
856 }
857 HEAP_SWAP(h->p[child], h->p[parent], tmp);
858 child = parent;
859 }
860
861 return 0;
862}
863
864static int
865heap_peek(struct heap *h, uint64_t *key, pktsched_pkt_t *pkt)
866{
867 if (h->size == 0) {
868 return ENOENT;
869 }
870
871 *key = h->p[0].key;
872 *pkt = h->p[0].pkt;
873 return 0;
874}
875
876static int
877heap_extract(struct heap *h, uint64_t *key, pktsched_pkt_t *pkt)
878{
879 uint64_t child, parent, max;
880
881 if (h->size == 0) {
882 return ENOENT;
883 }
884
885 *key = h->p[0].key;
886 *pkt = h->p[0].pkt;
887
888 /* re-heapify */
889 parent = 0;
890 child = HEAP_LEFT(parent); /* start from left child */
891 max = h->size - 1;
892 while (child <= max) {
893 if (child != max && h->p[child + 1].key < h->p[child].key) {
894 child = child + 1; /* right child */
895 }
896 h->p[parent] = h->p[child];
897 parent = child;
898 child = HEAP_LEFT(child); /* left child for next loop */
899 }
900
901 h->size--;
902 if (parent != max) {
903 /* Fill hole with last entry, bubble up reusing insert code */
904 h->p[parent] = h->p[max];
905 _PKTSCHED_PKT_INIT(&h->p[max].pkt);
906 heap_insert(h, key: parent, NULL); /* this one cannot fail */
907 }
908
909 return 0;
910}
911
912static void
913corruption_event(struct netem *ne, pktsched_pkt_t *pkt)
914{
915 struct corruption *corr = &ne->netem_corruption_model;
916 uint32_t rand;
917
918 if (corr->corruption_p == 0) {
919 return;
920 }
921
922 read_frandom(buffer: &rand, numBytes: sizeof(rand));
923 rand %= NETEM_PSCALE;
924
925 if (rand < corr->corruption_p) {
926 NETEM_LOG(LOG_DEBUG, "| corrupted");
927 pktsched_corrupt_packet(pkt);
928 }
929}
930
931static bool
932duplication_event(struct netem *ne)
933{
934 struct duplication *dup = &ne->netem_duplication_model;
935 uint32_t rand;
936
937 if (dup->duplication_p == 0) {
938 return false;
939 }
940
941 read_frandom(buffer: &rand, numBytes: sizeof(rand));
942 rand %= NETEM_PSCALE;
943
944 return rand < dup->duplication_p;
945}
946
947static bool
948reordering_event(struct netem *ne)
949{
950 struct reordering *reord = &ne->netem_reordering_model;
951 uint32_t rand;
952
953 if (reord->reordering_p != 0) {
954 read_frandom(buffer: &rand, numBytes: sizeof(rand));
955 rand %= NETEM_PSCALE;
956 return rand < reord->reordering_p;
957 } else {
958 return false;
959 }
960}
961
962static uint64_t
963latency_event(struct netem *ne, uint64_t now)
964{
965 struct reordering *reord = &ne->netem_reordering_model;
966 struct latency *l = &ne->netem_latency_model;
967 bool reorder = false;
968 int32_t delay_ms = 0;
969 uint64_t abs_time_to_send = now, abs_interval;
970
971 if (reordering_event(ne)) {
972 reorder = true;
973 delay_ms += reord->reordering_ms;
974 NETEM_LOG(LOG_DEBUG, "| reorder %dms behind",
975 reord->reordering_ms);
976 }
977
978 if (l->latency_ms != 0 || l->jitter_ms != 0) {
979 delay_ms += norm_dist(mean: l->latency_ms, stdvar: l->jitter_ms);
980 NETEM_LOG(LOG_DEBUG, "| total delay %dms", delay_ms);
981 clock_interval_to_absolutetime_interval(interval: delay_ms,
982 NSEC_PER_MSEC, result: &abs_interval);
983 abs_time_to_send += abs_interval;
984 }
985
986 if (l->prev_time_to_send != 0) {
987 /* make sure packet time to send is monotonic */
988 if (abs_time_to_send < l->prev_time_to_send) {
989 /* send this one immediately after previous packet */
990 abs_time_to_send = l->prev_time_to_send + 1;
991 }
992 }
993
994 if (!reorder) {
995 l->prev_time_to_send = abs_time_to_send;
996 }
997
998 return abs_time_to_send;
999}
1000
1001static bool
1002loss_event(struct netem *ne)
1003{
1004 struct loss *loss = &ne->netem_loss_model;
1005 uint32_t rand;
1006
1007 if (loss->state == __NO_LOSS) {
1008 return false;
1009 }
1010
1011 read_frandom(buffer: &rand, numBytes: sizeof(rand));
1012 rand %= NETEM_PSCALE;
1013
1014 switch (loss->state) {
1015 case GAP_RX:
1016 if (rand < loss->p_gr_gl) {
1017 loss->state = GAP_RX;
1018 return true;
1019 } else if (loss->p_gr_gl < rand &&
1020 rand < loss->p_gr_gl + loss->p_gr_bl) {
1021 loss->state = BURST_LOSS;
1022 return true;
1023 } else {
1024 loss->state = GAP_RX;
1025 return false;
1026 }
1027 case BURST_LOSS:
1028 if (rand < loss->p_bl_br) {
1029 loss->state = BURST_RX;
1030 return false;
1031 } else if (loss->p_bl_br < rand &&
1032 rand < loss->p_bl_br + loss->p_bl_gr) {
1033 loss->state = GAP_RX;
1034 return false;
1035 } else {
1036 loss->state = BURST_LOSS;
1037 return true;
1038 }
1039 case BURST_RX:
1040 if (rand < loss->p_br_bl) {
1041 loss->state = BURST_LOSS;
1042 return true;
1043 } else {
1044 loss->state = BURST_RX;
1045 return false;
1046 }
1047 case GAP_LOSS:
1048 /* This is instantaneous (stateless), should not be reached */
1049 default:
1050 VERIFY(0);
1051 break;
1052 }
1053
1054 /* not reached */
1055 VERIFY(0);
1056 return false;
1057}
1058
1059static uint64_t
1060rate_limiter(struct netem *ne, pktsched_pkt_t *pkt, uint64_t start_abs_time)
1061{
1062 struct bandwidth *bw = &ne->netem_bandwidth_model;
1063 uint32_t ipg_ns; /* inter-packet-gap */
1064 uint64_t abs_interval, abs_time_to_send;
1065
1066 if (bw->rate == UINT64_MAX) {
1067 return start_abs_time;
1068 }
1069
1070 if (bw->rate == 0) {
1071 return UINT64_MAX; /* INF to block traffic */
1072 }
1073
1074 ipg_ns = (pkt->pktsched_plen * 8 * NSEC_PER_SEC) / bw->rate;
1075 clock_interval_to_absolutetime_interval(interval: ipg_ns, scale_factor: 1, result: &abs_interval);
1076 start_abs_time = MAX(start_abs_time, bw->prev_time_to_send);
1077 abs_time_to_send = bw->prev_time_to_send = start_abs_time + abs_interval;
1078
1079 return abs_time_to_send;
1080}
1081
1082static int
1083nlc_enqueue(struct netem *ne, classq_pkt_t *p, bool *pdrop)
1084{
1085 int ret = 0;
1086 int pkt_count = 1;
1087 uint64_t now, abs_time_to_send;
1088 pktsched_pkt_t pkt;
1089
1090 pktsched_pkt_encap(&pkt, p);
1091
1092 ASSERT(ne != NULL);
1093 ASSERT(pdrop != NULL);
1094 NETEM_MTX_LOCK(ne);
1095
1096 now = mach_absolute_time();
1097
1098 NETEM_LOG(LOG_DEBUG, "┌ begin p %p len %u, now %llu", p->cp_mbuf,
1099 pkt.pktsched_plen, now);
1100
1101 abs_time_to_send = rate_limiter(ne, pkt: &pkt, start_abs_time: now);
1102 if (abs_time_to_send == UINT64_MAX) {
1103 NETEM_LOG(LOG_DEBUG, "| zero-bw blocked");
1104 goto done_no_output;
1105 }
1106
1107 if (loss_event(ne)) {
1108 NETEM_LOG(LOG_DEBUG, "| lost");
1109 goto done_no_output;
1110 }
1111
1112 if (duplication_event(ne)) {
1113 NETEM_LOG(LOG_DEBUG, "| dup'ed");
1114 pkt_count++;
1115 }
1116
1117 do {
1118 corruption_event(ne, pkt: &pkt);
1119
1120 abs_time_to_send = latency_event(ne, now: abs_time_to_send);
1121
1122 ret = heap_insert(h: ne->netem_heap, key: abs_time_to_send, pkt: &pkt);
1123 if (ret != 0) {
1124 NETEM_LOG(LOG_WARNING,
1125 "| heap_insert p %p err(%d), freeing pkt",
1126 p->cp_mbuf, ret);
1127 pktsched_free_pkt(&pkt);
1128 goto done;
1129 }
1130 NETEM_LOG(LOG_DEBUG, "| %p enqueued TTS %llu",
1131 pkt.pktsched_pkt_mbuf, abs_time_to_send);
1132 } while (--pkt_count > 0 &&
1133 __probable((ret = pktsched_clone_pkt(&pkt, &pkt)) == 0));
1134
1135done:
1136 if (__probable(ne->netem_output_thread != THREAD_NULL)) {
1137 if (!(ne->netem_flags & (NETEMF_RUNNING |
1138 NETEMF_TERMINATING | NETEMF_TERMINATED)) &&
1139 !NETEM_OUTPUT_IVAL_ONLY(ne)) {
1140 NETEM_LOG(LOG_DEBUG, "| wakeup output thread");
1141 (void) thread_wakeup((caddr_t)&ne->netem_flags);
1142 }
1143 }
1144
1145 NETEM_MTX_UNLOCK(ne);
1146 NETEM_LOG(LOG_DEBUG, "└ %p end", p->cp_mbuf);
1147 return ret;
1148
1149done_no_output:
1150 pktsched_free_pkt(&pkt);
1151 *pdrop = true;
1152 NETEM_MTX_UNLOCK(ne);
1153 NETEM_LOG(LOG_DEBUG, "└ %p end", p->cp_mbuf);
1154 return ret;
1155}
1156
1157
1158int
1159netem_enqueue(struct netem *ne, classq_pkt_t *p, bool *pdrop)
1160{
1161 return ne->netem_enqueue(ne, p, pdrop);
1162}
1163
1164static int
1165netem_dequeue_internal_locked(struct netem *ne, pktsched_pkt_t *pp,
1166 bool *more)
1167{
1168 int ret = 0;
1169 uint64_t time_to_send;
1170 pktsched_pkt_t pkt;
1171
1172 ASSERT(ne != NULL);
1173 NETEM_MTX_LOCK_ASSERT_HELD(ne);
1174
1175 NETEM_LOG(LOG_DEBUG, "┌ begin");
1176
1177 ret = heap_peek(h: ne->netem_heap, key: &time_to_send, pkt: &pkt);
1178 if (ret != 0) {
1179 NETEM_LOG(LOG_DEBUG, "| heap empty");
1180 ret = ENOENT;
1181 goto done;
1182 }
1183
1184 if (time_to_send > mach_absolute_time()) {
1185 NETEM_LOG(LOG_DEBUG,
1186 "| TTS not yet reached: %llu now %llu",
1187 time_to_send, mach_absolute_time());
1188 *more = true;
1189 ret = EAGAIN;
1190 goto done;
1191 }
1192
1193 ret = heap_extract(h: ne->netem_heap, key: &time_to_send, pkt: &pkt);
1194 ASSERT(ret == 0);
1195 *pp = pkt;
1196
1197done:
1198 NETEM_LOG(LOG_DEBUG, "└ end");
1199
1200 return ret;
1201}
1202
1203__attribute__((noreturn))
1204static void
1205netem_output_thread_cont(void *v, wait_result_t w)
1206{
1207 struct netem *ne = v;
1208 bool more = false;
1209 pktsched_pkt_t pkts[NETEM_MAX_BATCH_SIZE];
1210 uint32_t n_pkts = 0;
1211 int ret;
1212
1213 NETEM_MTX_LOCK(ne);
1214 ASSERT(!(ne->netem_flags & NETEMF_TERMINATED));
1215 ne->netem_flags |= NETEMF_RUNNING;
1216
1217 if (__improbable(w == THREAD_INTERRUPTED ||
1218 (ne->netem_flags & NETEMF_TERMINATING) != 0)) {
1219 ASSERT(!(ne->netem_flags & NETEMF_TERMINATED));
1220 ne->netem_flags &= ~(NETEMF_RUNNING | NETEMF_TERMINATING);
1221 ne->netem_flags |= NETEMF_TERMINATED;
1222
1223 NETEM_LOG(LOG_INFO, "%s output thread terminated",
1224 ne->netem_name);
1225
1226 if (ne->netem_flags & NETEMF_TERMINATEBLOCK) {
1227 thread_wakeup((caddr_t)&ne->netem_output_thread);
1228 }
1229
1230 NETEM_MTX_UNLOCK(ne);
1231
1232 /* for the extra refcnt from kernel_thread_start() */
1233 thread_deallocate(thread: current_thread());
1234 /* this is the end */
1235 thread_terminate(current_thread());
1236 /* NOTREACHED */
1237 __builtin_unreachable();
1238 }
1239
1240 ASSERT(ne->netem_output != NULL);
1241 n_pkts = 0;
1242 for (;;) {
1243 ret = netem_dequeue_internal_locked(ne, pp: &pkts[n_pkts],
1244 more: &more);
1245 if (__probable(ret == 0 &&
1246 ++n_pkts < ne->netem_output_max_batch_size)) {
1247 continue;
1248 }
1249
1250 if (__probable(n_pkts != 0)) {
1251 NETEM_MTX_UNLOCK(ne);
1252 (void) ne->netem_output(ne->netem_output_handle,
1253 pkts, n_pkts);
1254 NETEM_MTX_LOCK(ne);
1255 n_pkts = 0;
1256 }
1257 if (ret != 0) {
1258 break;
1259 }
1260 }
1261
1262 uint64_t deadline = TIMEOUT_WAIT_FOREVER;
1263 if (more || NETEM_OUTPUT_IVAL_ONLY(ne)) {
1264 uint32_t delay_ms = ne->netem_output_ival_ms;
1265 clock_interval_to_deadline(interval: delay_ms, NSEC_PER_MSEC, result: &deadline);
1266 }
1267 (void) assert_wait_deadline(event: &ne->netem_flags, THREAD_UNINT, deadline);
1268 ne->netem_flags &= ~NETEMF_RUNNING;
1269 NETEM_MTX_UNLOCK(ne);
1270 (void) thread_block_parameter(continuation: netem_output_thread_cont, parameter: ne);
1271 /* NOTREACHED */
1272 __builtin_unreachable();
1273}
1274
1275__attribute__((noreturn))
1276static void
1277netem_output_thread_func(void *v, wait_result_t w)
1278{
1279#pragma unused(w)
1280 struct netem *ne = v;
1281 uint64_t wakeup;
1282
1283 ASSERT(ne->netem_output_thread == current_thread());
1284 thread_set_thread_name(th: current_thread(), name: ne->netem_name);
1285
1286 NETEM_MTX_LOCK(ne);
1287 VERIFY(!(ne->netem_flags & NETEMF_RUNNING));
1288 clock_interval_to_deadline(interval: 1, NSEC_PER_MSEC, result: &wakeup);
1289 (void) assert_wait_deadline(event: &ne->netem_flags, THREAD_UNINT, deadline: wakeup);
1290 NETEM_MTX_UNLOCK(ne);
1291 thread_block_parameter(continuation: netem_output_thread_cont, parameter: ne);
1292 /* NOTREACHED */
1293 __builtin_unreachable();
1294}
1295
1296static struct netem *
1297netem_create(const char *name, struct ifnet *ifp, void *output_handle,
1298 netem_output_func_t output, uint32_t output_max_batch_size)
1299{
1300 struct netem *ne;
1301
1302 _CASSERT(IF_NETEM_MODEL_NULL == NETEM_MODEL_NULL);
1303 _CASSERT(IF_NETEM_MODEL_NLC == NETEM_MODEL_NLC);
1304
1305 ne = kalloc_type(struct netem, Z_WAITOK | Z_ZERO);
1306
1307 lck_mtx_init(lck: &ne->netem_lock, grp: &netem_lock_group, LCK_ATTR_NULL);
1308
1309 ne->netem_heap = heap_create(limit: netem_heap_size);
1310 ne->netem_flags = NETEMF_INITIALIZED;
1311 ne->netem_output_handle = output_handle;
1312 ne->netem_output = output;
1313 ne->netem_output_max_batch_size =
1314 MIN(output_max_batch_size, NETEM_MAX_BATCH_SIZE);
1315 ne->netem_output_thread = THREAD_NULL;
1316 ne->netem_ifp = ifp;
1317 if (output != NULL) {
1318 strlcpy(dst: ne->netem_name, src: name, n: sizeof(ne->netem_name));
1319 if (kernel_thread_start(continuation: netem_output_thread_func, parameter: ne,
1320 new_thread: &ne->netem_output_thread) != KERN_SUCCESS) {
1321 panic_plain("%s can't create thread", ne->netem_name);
1322 }
1323 }
1324
1325
1326 return ne;
1327}
1328
1329void
1330netem_destroy(struct netem *ne)
1331{
1332 uint64_t f = (1 * NSEC_PER_MSEC); /* 1 ms */
1333 uint64_t s = (1000 * NSEC_PER_MSEC); /* 1 sec */
1334 uint32_t i = 0;
1335 int ret = 0;
1336 uint64_t key = 0;
1337 pktsched_pkt_t pkt;
1338
1339 ASSERT(ne != NULL);
1340
1341 if (ne->netem_output_thread != THREAD_NULL) {
1342 ASSERT(ne->netem_flags & NETEMF_INITIALIZED);
1343 /* signal thread to begin self-termination */
1344 NETEM_MTX_LOCK(ne);
1345 ne->netem_flags |= NETEMF_TERMINATING;
1346
1347 /* and wait for thread to terminate */
1348 while (!(ne->netem_flags & NETEMF_TERMINATED)) {
1349 uint64_t t = 0;
1350 nanoseconds_to_absolutetime(nanoseconds: (i++ == 0) ? f : s, result: &t);
1351 clock_absolutetime_interval_to_deadline(abstime: t, result: &t);
1352 ASSERT(t != 0);
1353
1354 ne->netem_flags |= NETEMF_TERMINATEBLOCK;
1355 if (!(ne->netem_flags & NETEMF_RUNNING)) {
1356 thread_wakeup((caddr_t)&ne->netem_flags);
1357 }
1358 (void) assert_wait_deadline(event: &ne->netem_output_thread,
1359 THREAD_UNINT, deadline: t);
1360 NETEM_MTX_UNLOCK(ne);
1361 (void) thread_block(THREAD_CONTINUE_NULL);
1362 NETEM_MTX_LOCK(ne);
1363 ne->netem_flags &= ~NETEMF_TERMINATEBLOCK;
1364 }
1365 ASSERT(ne->netem_flags & NETEMF_TERMINATED);
1366 NETEM_MTX_UNLOCK(ne);
1367 ne->netem_output_thread = THREAD_NULL;
1368 }
1369 ASSERT(ne->netem_output_thread == THREAD_NULL);
1370
1371 lck_mtx_destroy(lck: &ne->netem_lock, grp: &netem_lock_group);
1372
1373 while ((ret = heap_extract(h: ne->netem_heap, key: &key, pkt: &pkt)) == 0) {
1374 pktsched_free_pkt(&pkt);
1375 }
1376 heap_destroy(h: ne->netem_heap);
1377
1378
1379 kfree_type(struct netem, ne);
1380}
1381
1382static int
1383netem_check_params(const struct if_netem_params *p)
1384{
1385 if (p->ifnetem_model != IF_NETEM_MODEL_NLC) {
1386 NETEM_LOG(LOG_ERR, "| error: invalid scheduler model %d",
1387 p->ifnetem_model);
1388 return EINVAL;
1389 }
1390
1391 if (p->ifnetem_corruption_p > NETEM_PSCALE) {
1392 NETEM_LOG(LOG_ERR, "| error: corruption_p %d > %d",
1393 p->ifnetem_corruption_p, NETEM_PSCALE);
1394 return EINVAL;
1395 }
1396
1397 if (p->ifnetem_duplication_p > NETEM_PSCALE) {
1398 NETEM_LOG(LOG_ERR, "| error: duplication_p %d > %d",
1399 p->ifnetem_duplication_p, NETEM_PSCALE);
1400 return EINVAL;
1401 }
1402
1403 if (p->ifnetem_duplication_p > 0 &&
1404 p->ifnetem_latency_ms == 0) {
1405 /* we need to insert dup'ed packet with latency */
1406 NETEM_LOG(LOG_ERR,
1407 "| error: duplication needs latency param");
1408 return EINVAL;
1409 }
1410
1411 if (p->ifnetem_latency_ms > 1000) {
1412 NETEM_LOG(LOG_ERR,
1413 "| error: latency %d too big (> 1 sec)",
1414 p->ifnetem_latency_ms);
1415 return EINVAL;
1416 }
1417
1418 if (p->ifnetem_jitter_ms * 3 > p->ifnetem_latency_ms) {
1419 NETEM_LOG(LOG_ERR,
1420 "| error: jitter %dms too big (latency %dms)",
1421 p->ifnetem_jitter_ms, p->ifnetem_latency_ms);
1422 return EINVAL;
1423 }
1424
1425 /* if gr_gl == 0 (no loss), other prob should all be zero */
1426 if (p->ifnetem_loss_p_gr_gl == 0 &&
1427 (p->ifnetem_loss_p_gr_bl != 0 ||
1428 p->ifnetem_loss_p_bl_br != 0 ||
1429 p->ifnetem_loss_p_bl_gr != 0 ||
1430 p->ifnetem_loss_p_br_bl != 0)) {
1431 NETEM_LOG(LOG_ERR,
1432 "| error: loss params not all zero when p_gr_gl is zero");
1433 return EINVAL;
1434 }
1435
1436 if (p->ifnetem_loss_recovery_ms > 1000) {
1437 NETEM_LOG(LOG_ERR,
1438 "| error: loss recovery %dms too big",
1439 p->ifnetem_loss_recovery_ms);
1440 }
1441
1442 /* check state machine transition prob integrity */
1443 if (p->ifnetem_loss_p_gr_gl > NETEM_PSCALE ||
1444 /* gr_gl = NETEM_PSCALE for total loss */
1445 p->ifnetem_loss_p_gr_bl > NETEM_PSCALE ||
1446 p->ifnetem_loss_p_bl_br > NETEM_PSCALE ||
1447 p->ifnetem_loss_p_bl_gr > NETEM_PSCALE ||
1448 p->ifnetem_loss_p_br_bl > NETEM_PSCALE ||
1449 p->ifnetem_loss_p_gr_gl + p->ifnetem_loss_p_gr_bl > NETEM_PSCALE ||
1450 p->ifnetem_loss_p_bl_br + p->ifnetem_loss_p_bl_gr > NETEM_PSCALE) {
1451 NETEM_LOG(LOG_ERR, "| error: loss params too big");
1452 return EINVAL;
1453 }
1454
1455 if (p->ifnetem_reordering_p > NETEM_PSCALE) {
1456 NETEM_LOG(LOG_ERR, "| error: reordering %d > %d",
1457 p->ifnetem_reordering_p, NETEM_PSCALE);
1458 return EINVAL;
1459 }
1460
1461 if (p->ifnetem_output_ival_ms > 1000) {
1462 NETEM_LOG(LOG_ERR,
1463 "| error: output interval %dms too big",
1464 p->ifnetem_output_ival_ms);
1465 return EINVAL;
1466 }
1467
1468 return 0;
1469}
1470
1471static char *
1472netem_model_str(netem_model_t model)
1473{
1474 switch (model) {
1475 case IF_NETEM_MODEL_NLC:
1476 return "Network link conditioner";
1477 default:
1478 return "unknown";
1479 }
1480}
1481
1482static void
1483netem_set_params(struct netem *ne, __unused struct ifnet *ifp,
1484 const struct if_netem_params *p)
1485{
1486 NETEM_MTX_LOCK(ne);
1487
1488 ne->netem_model = (netem_model_t)p->ifnetem_model;
1489 switch (ne->netem_model) {
1490 case NETEM_MODEL_NLC:
1491 ne->netem_enqueue = nlc_enqueue;
1492 break;
1493 default:
1494 ASSERT(0);
1495 __builtin_unreachable();
1496 }
1497
1498 struct bandwidth *bw = &ne->netem_bandwidth_model;
1499 bw->rate = p->ifnetem_bandwidth_bps;
1500
1501 struct corruption *corr = &ne->netem_corruption_model;
1502 corr->corruption_p = p->ifnetem_corruption_p;
1503
1504 struct duplication *dup = &ne->netem_duplication_model;
1505 dup->duplication_p = p->ifnetem_duplication_p;
1506
1507 struct latency *late = &ne->netem_latency_model;
1508 late->latency_ms = p->ifnetem_latency_ms;
1509 late->jitter_ms = p->ifnetem_jitter_ms;
1510
1511 struct loss *loss = &ne->netem_loss_model;
1512 loss->state = GAP_RX;
1513 loss->p_gr_gl = p->ifnetem_loss_p_gr_gl;
1514 loss->p_gr_bl = p->ifnetem_loss_p_gr_bl;
1515 loss->p_bl_gr = p->ifnetem_loss_p_bl_gr;
1516 loss->p_bl_br = p->ifnetem_loss_p_bl_br;
1517 loss->p_br_bl = p->ifnetem_loss_p_br_bl;
1518
1519 loss->recovery_ms = p->ifnetem_loss_recovery_ms;
1520
1521 struct reordering *r = &ne->netem_reordering_model;
1522 r->reordering_p = p->ifnetem_reordering_p;
1523
1524 if (p->ifnetem_output_ival_ms != 0) {
1525 ne->netem_output_ival_ms = p->ifnetem_output_ival_ms;
1526 ne->netem_flags |= NETEMF_OUTPUT_IVAL_ONLY;
1527 } else {
1528 ne->netem_output_ival_ms = netem_output_ival_ms;
1529 }
1530
1531 if (NETEM_OUTPUT_IVAL_ONLY(ne)) {
1532 if (__probable(ne->netem_output_thread != THREAD_NULL)) {
1533 if (!(ne->netem_flags & (NETEMF_RUNNING |
1534 NETEMF_TERMINATING | NETEMF_TERMINATED))) {
1535 NETEM_LOG(LOG_DEBUG, "| wakeup output thread");
1536 (void) thread_wakeup((caddr_t)&ne->netem_flags);
1537 }
1538 }
1539 }
1540
1541 NETEM_LOG(LOG_INFO, "| %s set_params success", ne->netem_name);
1542 NETEM_LOG(LOG_INFO, "| model %s", netem_model_str(ne->netem_model));
1543 NETEM_LOG(LOG_INFO, "| bandwidth %llu bps %s", bw->rate,
1544 bw->rate == UINT64_MAX ? "no limit" : "");
1545 NETEM_LOG(LOG_INFO, "| corruption %d%%",
1546 corr->corruption_p);
1547 NETEM_LOG(LOG_INFO, "| duplication %d%%",
1548 dup->duplication_p);
1549 NETEM_LOG(LOG_INFO, "| latency_ms %d jitter_ms %d",
1550 late->latency_ms, late->jitter_ms);
1551 NETEM_LOG(LOG_INFO, "| loss p_gr_gl %d%%", loss->p_gr_gl);
1552 NETEM_LOG(LOG_INFO, "| p_gr_bl %d%%", loss->p_gr_bl);
1553 NETEM_LOG(LOG_INFO, "| p_bl_gr %d%%", loss->p_bl_gr);
1554 NETEM_LOG(LOG_INFO, "| p_bl_br %d%%", loss->p_bl_br);
1555 NETEM_LOG(LOG_INFO, "| p_br_bl %d%%", loss->p_br_bl);
1556 NETEM_LOG(LOG_INFO, "| recovery_ms %dms", loss->recovery_ms);
1557 NETEM_LOG(LOG_INFO, "| reordering %d%% %d ms behind",
1558 r->reordering_p, r->reordering_ms);
1559 NETEM_LOG(LOG_INFO, "| output ival %d ms",
1560 ne->netem_output_ival_ms);
1561
1562 NETEM_MTX_UNLOCK(ne);
1563}
1564
1565void
1566netem_get_params(struct netem *ne, struct if_netem_params *p)
1567{
1568 ASSERT(ne != NULL);
1569 NETEM_MTX_LOCK(ne);
1570
1571 p->ifnetem_model = (if_netem_model_t)ne->netem_model;
1572
1573 struct bandwidth *bw = &ne->netem_bandwidth_model;
1574 p->ifnetem_bandwidth_bps = bw->rate;
1575
1576 struct corruption *corr = &ne->netem_corruption_model;
1577 p->ifnetem_corruption_p = corr->corruption_p;
1578
1579 struct duplication *dup = &ne->netem_duplication_model;
1580 p->ifnetem_duplication_p = dup->duplication_p;
1581
1582 struct latency *late = &ne->netem_latency_model;
1583 p->ifnetem_latency_ms = late->latency_ms;
1584 p->ifnetem_jitter_ms = late->jitter_ms;
1585
1586 struct loss *loss = &ne->netem_loss_model;
1587 p->ifnetem_loss_p_gr_gl = loss->p_gr_gl;
1588 p->ifnetem_loss_p_gr_bl = loss->p_gr_bl;
1589 p->ifnetem_loss_p_bl_gr = loss->p_bl_gr;
1590 p->ifnetem_loss_p_bl_br = loss->p_bl_br;
1591 p->ifnetem_loss_p_br_bl = loss->p_br_bl;
1592 p->ifnetem_loss_recovery_ms = loss->recovery_ms;
1593
1594 struct reordering *r = &ne->netem_reordering_model;
1595 p->ifnetem_reordering_p = r->reordering_p;
1596
1597 NETEM_MTX_UNLOCK(ne);
1598}
1599
1600int
1601netem_config(struct netem **ne, const char *name, struct ifnet *ifp,
1602 const struct if_netem_params *p, void *output_handle,
1603 netem_output_func_t *output_func, uint32_t output_max_batch_size)
1604{
1605 struct netem *netem = NULL;
1606 bool enable = true;
1607 int ret = 0;
1608
1609 NETEM_LOG(LOG_INFO, "┌ begin %s", name);
1610
1611 if (p == NULL || (
1612 p->ifnetem_model == IF_NETEM_MODEL_NULL &&
1613 p->ifnetem_bandwidth_bps == 0 &&
1614 p->ifnetem_corruption_p == 0 &&
1615 p->ifnetem_duplication_p == 0 &&
1616 p->ifnetem_latency_ms == 0 &&
1617 p->ifnetem_jitter_ms == 0 &&
1618 p->ifnetem_loss_p_gr_gl == 0 &&
1619 p->ifnetem_loss_p_gr_bl == 0 &&
1620 p->ifnetem_loss_p_bl_br == 0 &&
1621 p->ifnetem_loss_p_bl_gr == 0 &&
1622 p->ifnetem_loss_p_br_bl == 0 &&
1623 p->ifnetem_loss_recovery_ms == 0 &&
1624 p->ifnetem_reordering_p == 0 &&
1625 p->ifnetem_output_ival_ms == 0)) {
1626 enable = false;
1627 }
1628
1629 if (enable) {
1630 if (p->ifnetem_model == IF_NETEM_MODEL_NLC &&
1631 (ifp->if_xflags & IFXF_NO_TRAFFIC_SHAPING) != 0) {
1632 NETEM_LOG(LOG_INFO, "| netem no traffic shapping %s on %s", name, if_name(ifp));
1633 goto done;
1634 }
1635
1636 ret = netem_check_params(p);
1637 if (ret != 0) {
1638 goto done;
1639 }
1640
1641 if (*ne == NULL) {
1642 NETEM_LOG(LOG_INFO, "| netem create %s", name);
1643 netem = netem_create(name, ifp, output_handle,
1644 output: output_func, output_max_batch_size);
1645 if (netem == NULL) {
1646 ret = ENOMEM;
1647 goto done;
1648 }
1649 os_atomic_store(ne, netem, release);
1650 }
1651 netem_set_params(ne: *ne, ifp, p);
1652 } else {
1653 NETEM_LOG(LOG_INFO, "| netem disable %s", name);
1654 if (*ne != NULL) {
1655 netem = *ne;
1656 os_atomic_store(ne, NULL, release);
1657 NETEM_LOG(LOG_INFO, "| netem destroy %s", name);
1658 netem_destroy(ne: netem);
1659 }
1660 ret = 0;
1661 }
1662
1663done:
1664 NETEM_LOG(LOG_INFO, "└ ret %d", ret);
1665 return ret;
1666}
1667
1668#else /* !CONFIG_NETEM */
1669NETEM_STUB
1670#endif /* !CONFIG_NETEM */
1671#else /* !SKYWALK */
1672NETEM_STUB
1673#endif /* !SKYWALK */
1674