]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/pktsched/pktsched_netem.c
xnu-6153.61.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 uint32_t limit; /* max size */
600 uint32_t size; /* current size */
601 struct heap_elem p[0];
602 };
603
604 static struct heap *heap_create(uint32_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(uint32_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 ENOMEM;
730 }
731
732 uint32_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 uint32_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 int
1121 netem_dequeue(struct netem *ne, pktsched_pkt_t *p,
1122 boolean_t *ppending)
1123 {
1124 int ret;
1125
1126 NETEM_MTX_LOCK(ne);
1127 netem_update_locked(ne);
1128 ret = netem_dequeue_internal_locked(ne, p, ppending);
1129 NETEM_MTX_UNLOCK(ne);
1130
1131 return ret;
1132 }
1133
1134 __attribute__((noreturn))
1135 static void
1136 netem_output_thread_cont(void *v, wait_result_t w)
1137 __attribute__((optnone))
1138 {
1139 struct netem *ne = v;
1140 boolean_t pending = FALSE;
1141 pktsched_pkt_t pkts[NETEM_MAX_BATCH_SIZE];
1142 uint32_t n_pkts = 0;
1143 int ret;
1144
1145 NETEM_MTX_LOCK(ne);
1146 ASSERT(!(ne->netem_flags & NETEMF_TERMINATED));
1147 ne->netem_flags |= NETEMF_RUNNING;
1148
1149 if (__improbable(w == THREAD_INTERRUPTED ||
1150 (ne->netem_flags & NETEMF_TERMINATING) != 0)) {
1151 ASSERT(!(ne->netem_flags & NETEMF_TERMINATED));
1152 ne->netem_flags &= ~(NETEMF_RUNNING | NETEMF_TERMINATING);
1153 ne->netem_flags |= NETEMF_TERMINATED;
1154
1155 netem_log(NETEM_LOG_INFO, "%s output thread terminated",
1156 ne->netem_name);
1157
1158 if (ne->netem_flags & NETEMF_TERMINATEBLOCK) {
1159 thread_wakeup((caddr_t)&ne->netem_output_thread);
1160 }
1161
1162 NETEM_MTX_UNLOCK(ne);
1163
1164 /* for the extra refcnt from kernel_thread_start() */
1165 thread_deallocate(current_thread());
1166 /* this is the end */
1167 thread_terminate(current_thread());
1168 /* NOTREACHED */
1169 __builtin_unreachable();
1170 }
1171
1172 ASSERT(ne->netem_output != NULL);
1173 netem_update_locked(ne);
1174 n_pkts = 0;
1175 for (;;) {
1176 ret = netem_dequeue_internal_locked(ne, &pkts[n_pkts],
1177 &pending);
1178 if (__probable(ret == 0 &&
1179 ++n_pkts < ne->netem_output_max_batch_size)) {
1180 continue;
1181 }
1182
1183 if (__probable(n_pkts != 0)) {
1184 NETEM_MTX_UNLOCK(ne);
1185 (void) ne->netem_output(ne->netem_output_handle,
1186 pkts, n_pkts);
1187 NETEM_MTX_LOCK(ne);
1188 n_pkts = 0;
1189 }
1190 if (ret != 0) {
1191 break;
1192 }
1193 }
1194
1195 uint64_t deadline = TIMEOUT_WAIT_FOREVER;
1196 if (pending) {
1197 clock_interval_to_deadline(1, NSEC_PER_MSEC, &deadline);
1198 }
1199 (void) assert_wait_deadline(&ne->netem_flags, THREAD_UNINT, deadline);
1200 ne->netem_flags &= ~NETEMF_RUNNING;
1201 NETEM_MTX_UNLOCK(ne);
1202 (void) thread_block_parameter(netem_output_thread_cont, ne);
1203 /* NOTREACHED */
1204 __builtin_unreachable();
1205 }
1206
1207 __attribute__((noreturn))
1208 static void
1209 netem_output_thread_func(void *v, wait_result_t w)
1210 {
1211 #pragma unused(w)
1212 struct netem *ne = v;
1213
1214 ASSERT(ne->netem_output_thread == current_thread());
1215 thread_set_thread_name(current_thread(), ne->netem_name);
1216
1217 NETEM_MTX_LOCK(ne);
1218 VERIFY(!(ne->netem_flags & NETEMF_RUNNING));
1219 (void) assert_wait(&ne->netem_flags, THREAD_UNINT);
1220 NETEM_MTX_UNLOCK(ne);
1221 thread_block_parameter(netem_output_thread_cont, ne);
1222 /* NOTREACHED */
1223 __builtin_unreachable();
1224 }
1225
1226 int
1227 netem_init(void)
1228 {
1229 ASSERT(!__netem_inited);
1230 __netem_inited = 1;
1231
1232 netem_lock_attr = lck_attr_alloc_init();
1233 netem_lock_group_attr = lck_grp_attr_alloc_init();
1234 netem_lock_group = lck_grp_alloc_init("pktsched_netem_lock",
1235 netem_lock_group_attr);
1236
1237 return 0;
1238 }
1239
1240 static struct netem *
1241 netem_create(const char *name, void *output_handle,
1242 int (*output)(void *handle, pktsched_pkt_t *pkts, uint32_t n_pkts),
1243 uint32_t output_max_batch_size)
1244 {
1245 struct netem *ne;
1246
1247 ne = _MALLOC(sizeof(struct netem), M_DEVBUF, M_WAITOK | M_ZERO);
1248
1249 lck_mtx_init(&ne->netem_lock, netem_lock_group, netem_lock_attr);
1250
1251 ne->netem_heap = heap_create(NETEM_HEAP_SIZE);
1252 ne->netem_flags = NETEMF_INITIALIZED;
1253 ne->netem_output_handle = output_handle;
1254 ne->netem_output = output;
1255 ne->netem_output_max_batch_size =
1256 MIN(output_max_batch_size, NETEM_MAX_BATCH_SIZE);
1257 ne->netem_output_thread = THREAD_NULL;
1258 if (output != NULL) {
1259 strlcpy(ne->netem_name, name, sizeof(ne->netem_name));
1260 if (kernel_thread_start(netem_output_thread_func, ne,
1261 &ne->netem_output_thread) != KERN_SUCCESS) {
1262 panic_plain("%s can't create thread", ne->netem_name);
1263 }
1264 }
1265
1266 return ne;
1267 }
1268
1269 void
1270 netem_destroy(struct netem *ne)
1271 {
1272 uint64_t f = (1 * NSEC_PER_MSEC); /* 1 ms */
1273 uint64_t s = (1000 * NSEC_PER_MSEC); /* 1 sec */
1274 uint32_t i = 0;
1275 int ret = 0;
1276 uint64_t key = 0;
1277 pktsched_pkt_t pkt;
1278
1279 ASSERT(ne != NULL);
1280
1281 if (ne->netem_output_thread != THREAD_NULL) {
1282 ASSERT(ne->netem_flags & NETEMF_INITIALIZED);
1283 /* signal thread to begin self-termination */
1284 NETEM_MTX_LOCK(ne);
1285 ne->netem_flags |= NETEMF_TERMINATING;
1286
1287 /* and wait for thread to terminate */
1288 while (!(ne->netem_flags & NETEMF_TERMINATED)) {
1289 uint64_t t = 0;
1290 nanoseconds_to_absolutetime((i++ == 0) ? f : s, &t);
1291 clock_absolutetime_interval_to_deadline(t, &t);
1292 ASSERT(t != 0);
1293
1294 ne->netem_flags |= NETEMF_TERMINATEBLOCK;
1295 if (!(ne->netem_flags & NETEMF_RUNNING)) {
1296 thread_wakeup((caddr_t)&ne->netem_flags);
1297 }
1298 (void) assert_wait_deadline(&ne->netem_output_thread,
1299 THREAD_UNINT, t);
1300 NETEM_MTX_UNLOCK(ne);
1301 (void) thread_block(THREAD_CONTINUE_NULL);
1302 NETEM_MTX_LOCK(ne);
1303 ne->netem_flags &= ~NETEMF_TERMINATEBLOCK;
1304 }
1305 ASSERT(ne->netem_flags & NETEMF_TERMINATED);
1306 NETEM_MTX_UNLOCK(ne);
1307 ne->netem_output_thread = THREAD_NULL;
1308 }
1309 ASSERT(ne->netem_output_thread == THREAD_NULL);
1310
1311 lck_mtx_destroy(&ne->netem_lock, netem_lock_group);
1312
1313 while ((ret = heap_extract(ne->netem_heap, &key, &pkt)) == 0) {
1314 pktsched_free_pkt(&pkt);
1315 }
1316 heap_destroy(ne->netem_heap);
1317
1318 _FREE(ne, M_DEVBUF);
1319 }
1320
1321 static int
1322 netem_check_params(const struct if_netem_params *p)
1323 {
1324 if (p->ifnetem_corruption_p > NETEM_PSCALE) {
1325 netem_log(NETEM_LOG_ERROR, "error: corruption_p %d > %d",
1326 p->ifnetem_corruption_p, NETEM_PSCALE);
1327 return EINVAL;
1328 }
1329
1330 if (p->ifnetem_duplication_p > NETEM_PSCALE) {
1331 netem_log(NETEM_LOG_ERROR, "error: duplication_p %d > %d",
1332 p->ifnetem_duplication_p, NETEM_PSCALE);
1333 return EINVAL;
1334 }
1335
1336 if (p->ifnetem_duplication_p > 0 &&
1337 p->ifnetem_latency_ms == 0) {
1338 /* we need to insert dup'ed packet with latency */
1339 netem_log(NETEM_LOG_ERROR,
1340 "error: duplication needs latency param");
1341 return EINVAL;
1342 }
1343
1344 if (p->ifnetem_latency_ms > 1000) {
1345 netem_log(NETEM_LOG_ERROR,
1346 "error: latency %d too big (> 1 sec)",
1347 p->ifnetem_latency_ms);
1348 return EINVAL;
1349 }
1350
1351 if (p->ifnetem_jitter_ms * 3 > p->ifnetem_latency_ms) {
1352 netem_log(NETEM_LOG_ERROR,
1353 "error: jitter %dms too big (latency %dms)",
1354 p->ifnetem_jitter_ms, p->ifnetem_latency_ms);
1355 return EINVAL;
1356 }
1357
1358 /* if gr_gl == 0 (no loss), other prob should all be zero */
1359 if (p->ifnetem_loss_p_gr_gl == 0 &&
1360 (p->ifnetem_loss_p_gr_bl != 0 ||
1361 p->ifnetem_loss_p_bl_br != 0 ||
1362 p->ifnetem_loss_p_bl_gr != 0 ||
1363 p->ifnetem_loss_p_br_bl != 0)) {
1364 netem_log(NETEM_LOG_ERROR,
1365 "error: loss params not all zero when p_gr_gl is zero");
1366 return EINVAL;
1367 }
1368
1369 /* check state machine transition prob integrity */
1370 if (p->ifnetem_loss_p_gr_gl > NETEM_PSCALE ||
1371 /* gr_gl = NETEM_PSCALE for total loss */
1372 p->ifnetem_loss_p_gr_bl > NETEM_PSCALE ||
1373 p->ifnetem_loss_p_bl_br > NETEM_PSCALE ||
1374 p->ifnetem_loss_p_bl_gr > NETEM_PSCALE ||
1375 p->ifnetem_loss_p_br_bl > NETEM_PSCALE ||
1376 p->ifnetem_loss_p_gr_gl + p->ifnetem_loss_p_gr_bl > NETEM_PSCALE ||
1377 p->ifnetem_loss_p_bl_br + p->ifnetem_loss_p_bl_gr > NETEM_PSCALE) {
1378 netem_log(NETEM_LOG_ERROR, "error: loss params too big");
1379 return EINVAL;
1380 }
1381
1382 if (p->ifnetem_reordering_p > NETEM_PSCALE) {
1383 netem_log(NETEM_LOG_ERROR, "error: reordering %d > %d",
1384 p->ifnetem_reordering_p, NETEM_PSCALE);
1385 return EINVAL;
1386 }
1387
1388 return 0;
1389 }
1390
1391 static void
1392 netem_set_params(struct netem *ne, const struct if_netem_params *p)
1393 {
1394 NETEM_MTX_LOCK(ne);
1395
1396 struct token_bucket *tb = &ne->netem_bandwidth_model;
1397 if (p->ifnetem_bandwidth_bps == 0) {
1398 tb->depth = 0;
1399 tb->rate = 0;
1400 tb->token = 0;
1401 tb->last = 0;
1402 } else {
1403 tb->depth = p->ifnetem_bandwidth_bps;
1404 tb->rate = p->ifnetem_bandwidth_bps;
1405 tb->token = p->ifnetem_bandwidth_bps / 2;
1406 tb->last = mach_absolute_time();
1407 }
1408
1409 struct corruption *corr = &ne->netem_corruption_model;
1410 corr->corruption_p = p->ifnetem_corruption_p;
1411
1412 struct duplication *dup = &ne->netem_duplication_model;
1413 dup->duplication_p = p->ifnetem_duplication_p;
1414
1415 struct latency *late = &ne->netem_latency_model;
1416 late->latency_ms = p->ifnetem_latency_ms;
1417 late->jitter_ms = p->ifnetem_jitter_ms;
1418
1419 struct loss *loss = &ne->netem_loss_model;
1420 loss->state = GAP_RX;
1421 loss->p_gr_gl = p->ifnetem_loss_p_gr_gl;
1422 loss->p_gr_bl = p->ifnetem_loss_p_gr_bl;
1423 loss->p_bl_gr = p->ifnetem_loss_p_bl_gr;
1424 loss->p_bl_br = p->ifnetem_loss_p_bl_br;
1425 loss->p_br_bl = p->ifnetem_loss_p_br_bl;
1426
1427 struct reordering *r = &ne->netem_reordering_model;
1428 r->reordering_p = p->ifnetem_reordering_p;
1429
1430 netem_log(NETEM_LOG_INFO, "success: bandwidth %d bps", tb->rate);
1431 netem_log(NETEM_LOG_INFO, "success: corruption %d\%",
1432 corr->corruption_p);
1433 netem_log(NETEM_LOG_INFO, "success: duplication %d\%",
1434 dup->duplication_p);
1435 netem_log(NETEM_LOG_INFO, "success: latency_ms %d jitter_ms %d",
1436 late->latency_ms, late->jitter_ms);
1437 netem_log(NETEM_LOG_INFO, "changed loss p_gr_gl %d p_gr_bl %d "
1438 "p_bl_gr %d p_bl_br %d p_br_bl %d", loss->p_gr_gl, loss->p_gr_bl,
1439 loss->p_bl_gr, loss->p_bl_br, loss->p_br_bl);
1440 netem_log(NETEM_LOG_DEBUG, "success: reordering %d\%",
1441 r->reordering_p);
1442
1443 NETEM_MTX_UNLOCK(ne);
1444 }
1445
1446 void
1447 netem_get_params(struct netem *ne, struct if_netem_params *p)
1448 {
1449 ASSERT(ne != NULL);
1450 NETEM_MTX_LOCK(ne);
1451
1452 struct token_bucket *tb = &ne->netem_bandwidth_model;
1453 p->ifnetem_bandwidth_bps = tb->depth;
1454
1455 struct corruption *corr = &ne->netem_corruption_model;
1456 p->ifnetem_corruption_p = corr->corruption_p;
1457
1458 struct duplication *dup = &ne->netem_duplication_model;
1459 p->ifnetem_duplication_p = dup->duplication_p;
1460
1461 struct latency *late = &ne->netem_latency_model;
1462 p->ifnetem_latency_ms = late->latency_ms;
1463 p->ifnetem_jitter_ms = late->jitter_ms;
1464
1465 struct loss *loss = &ne->netem_loss_model;
1466 p->ifnetem_loss_p_gr_gl = loss->p_gr_gl;
1467 p->ifnetem_loss_p_gr_bl = loss->p_gr_bl;
1468 p->ifnetem_loss_p_bl_gr = loss->p_bl_gr;
1469 p->ifnetem_loss_p_bl_br = loss->p_bl_br;
1470 p->ifnetem_loss_p_br_bl = loss->p_br_bl;
1471
1472 struct reordering *r = &ne->netem_reordering_model;
1473 p->ifnetem_reordering_p = r->reordering_p;
1474
1475 NETEM_MTX_UNLOCK(ne);
1476 }
1477
1478 int
1479 netem_config(struct netem **ne, const char *name,
1480 const struct if_netem_params *p, void *output_handle,
1481 int (*output_func)(void *handle, pktsched_pkt_t *pkts, uint32_t n_pkts),
1482 uint32_t output_max_batch_size)
1483 {
1484 struct netem *netem = NULL;
1485 boolean_t enable = TRUE;
1486 int ret = 0;
1487
1488 if (p == NULL || (
1489 p->ifnetem_bandwidth_bps == 0 &&
1490 p->ifnetem_corruption_p == 0 &&
1491 p->ifnetem_duplication_p == 0 &&
1492 p->ifnetem_latency_ms == 0 &&
1493 p->ifnetem_jitter_ms == 0 &&
1494 p->ifnetem_loss_p_gr_gl == 0 &&
1495 p->ifnetem_loss_p_gr_bl == 0 &&
1496 p->ifnetem_loss_p_bl_br == 0 &&
1497 p->ifnetem_loss_p_bl_gr == 0 &&
1498 p->ifnetem_loss_p_br_bl == 0 &&
1499 p->ifnetem_reordering_p == 0)) {
1500 enable = FALSE;
1501 }
1502
1503 ret = netem_check_params(p);
1504 if (ret != 0) {
1505 goto done;
1506 }
1507
1508 if (enable) {
1509 if (*ne == NULL) {
1510 netem_log(NETEM_LOG_INFO, "netem create %s", name);
1511 netem = netem_create(name, output_handle, output_func,
1512 output_max_batch_size);
1513 if (netem == NULL) {
1514 return ENOMEM;
1515 }
1516 atomic_set_ptr(ne, netem);
1517 }
1518 netem_set_params(*ne, p);
1519 } else {
1520 netem_log(NETEM_LOG_INFO, "netem disable %s", name);
1521 if (*ne != NULL) {
1522 netem = *ne;
1523 atomic_set_ptr(ne, NULL);
1524 netem_log(NETEM_LOG_INFO, "netem destroy %s", name);
1525 netem_destroy(netem);
1526 }
1527 ret = 0;
1528 }
1529
1530 done:
1531 netem_log(NETEM_LOG_INFO, "netem config ret %d", ret);
1532 return ret;
1533 }
1534
1535 #else /* !CONFIG_NETEM */
1536
1537 int
1538 netem_init(void)
1539 {
1540 return 0;
1541 }
1542
1543 int
1544 netem_config(struct netem **ne, const char *name,
1545 const struct if_netem_params *p, void *output_handle,
1546 int (*output_func)(void *handle, pktsched_pkt_t *pkts, uint32_t n_pkts),
1547 uint32_t output_max_batch_size)
1548 {
1549 #pragma unused(ne, name, p, output_handle, output_func, output_max_batch_size)
1550 printf("%s error %d: unavailable on this platform\n", __func__, ENOTSUP);
1551 return ENOTSUP;
1552 }
1553
1554 void
1555 __attribute__((noreturn))
1556 netem_get_params(struct netem *ne, struct if_netem_params *p)
1557 {
1558 #pragma unused(ne, p)
1559 panic("unexpected netem call");
1560 }
1561
1562 void
1563 __attribute__((noreturn))
1564 netem_destroy(struct netem *ne)
1565 {
1566 #pragma unused(ne)
1567 panic("unexpected netem call");
1568 }
1569
1570 int
1571 netem_enqueue(struct netem *ne, classq_pkt_t *p, boolean_t *pdrop)
1572 {
1573 #pragma unused(ne, p, pdrop)
1574 panic("unexpected netem call");
1575 return 0;
1576 }
1577
1578 int
1579 netem_dequeue(struct netem *ne, pktsched_pkt_t *p, boolean_t *ppending)
1580 {
1581 #pragma unused(ne, p, ppending)
1582 panic("unexpected netem call");
1583 return 0;
1584 }
1585 #endif /* !CONFIG_NETEM */