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