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