libnl 1.1.4
netem.c
1/*
2 * lib/route/sch/netem.c Network Emulator Qdisc
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation version 2.1
7 * of the License.
8 *
9 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
10 */
11
12/**
13 * @ingroup qdisc_api
14 * @defgroup netem Network Emulator
15 * @brief
16 *
17 * For further documentation see http://linux-net.osdl.org/index.php/Netem
18 * @{
19 */
20
21#include <netlink-local.h>
22#include <netlink-tc.h>
23#include <netlink/netlink.h>
24#include <netlink/utils.h>
25#include <netlink/route/qdisc.h>
26#include <netlink/route/qdisc-modules.h>
27#include <netlink/route/sch/netem.h>
28
29/** @cond SKIP */
30#define SCH_NETEM_ATTR_LATENCY 0x001
31#define SCH_NETEM_ATTR_LIMIT 0x002
32#define SCH_NETEM_ATTR_LOSS 0x004
33#define SCH_NETEM_ATTR_GAP 0x008
34#define SCH_NETEM_ATTR_DUPLICATE 0x010
35#define SCH_NETEM_ATTR_JITTER 0x020
36#define SCH_NETEM_ATTR_DELAY_CORR 0x040
37#define SCH_NETEM_ATTR_LOSS_CORR 0x080
38#define SCH_NETEM_ATTR_DUP_CORR 0x100
39#define SCH_NETEM_ATTR_RO_PROB 0x200
40#define SCH_NETEM_ATTR_RO_CORR 0x400
41/** @endcond */
42
43static inline struct rtnl_netem *netem_qdisc(struct rtnl_qdisc *qdisc)
44{
45 return (struct rtnl_netem *) qdisc->q_subdata;
46}
47
48static inline struct rtnl_netem *netem_alloc(struct rtnl_qdisc *qdisc)
49{
50 if (!qdisc->q_subdata)
51 qdisc->q_subdata = calloc(1, sizeof(struct rtnl_netem));
52
53 return netem_qdisc(qdisc);
54}
55
56static struct nla_policy netem_policy[TCA_NETEM_MAX+1] = {
57 [TCA_NETEM_CORR] = { .minlen = sizeof(struct tc_netem_corr) },
58 [TCA_NETEM_REORDER] = { .minlen = sizeof(struct tc_netem_reorder) },
59};
60
61static int netem_msg_parser(struct rtnl_qdisc *qdisc)
62{
63 int len, err = 0;
64 struct rtnl_netem *netem;
65 struct tc_netem_qopt *opts;
66
67 if (qdisc->q_opts->d_size < sizeof(*opts))
68 return nl_error(EINVAL, "Netem specific options size mismatch");
69
70 netem = netem_alloc(qdisc);
71 if (!netem)
72 return nl_errno(ENOMEM);
73
74 opts = (struct tc_netem_qopt *) qdisc->q_opts->d_data;
75 netem->qnm_latency = opts->latency;
76 netem->qnm_limit = opts->limit;
77 netem->qnm_loss = opts->loss;
78 netem->qnm_gap = opts->gap;
79 netem->qnm_duplicate = opts->duplicate;
80 netem->qnm_jitter = opts->jitter;
81
82 netem->qnm_mask = (SCH_NETEM_ATTR_LATENCY | SCH_NETEM_ATTR_LIMIT |
83 SCH_NETEM_ATTR_LOSS | SCH_NETEM_ATTR_GAP |
84 SCH_NETEM_ATTR_DUPLICATE | SCH_NETEM_ATTR_JITTER);
85
86 len = qdisc->q_opts->d_size - sizeof(*opts);
87
88 if (len > 0) {
89 struct nlattr *tb[TCA_NETEM_MAX+1];
90
91 err = nla_parse(tb, TCA_NETEM_MAX, (struct nlattr *)
92 qdisc->q_opts->d_data + sizeof(*opts),
93 len, netem_policy);
94 if (err < 0) {
95 free(netem);
96 return err;
97 }
98
99 if (tb[TCA_NETEM_CORR]) {
100 struct tc_netem_corr cor;
101
102 nla_memcpy(&cor, tb[TCA_NETEM_CORR], sizeof(cor));
103 netem->qnm_corr.nmc_delay = cor.delay_corr;
104 netem->qnm_corr.nmc_loss = cor.loss_corr;
105 netem->qnm_corr.nmc_duplicate = cor.dup_corr;
106
107 netem->qnm_mask |= (SCH_NETEM_ATTR_DELAY_CORR |
108 SCH_NETEM_ATTR_LOSS_CORR |
109 SCH_NETEM_ATTR_DELAY_CORR);
110 }
111
112 if (tb[TCA_NETEM_REORDER]) {
113 struct tc_netem_reorder ro;
114
115 nla_memcpy(&ro, tb[TCA_NETEM_REORDER], sizeof(ro));
116 netem->qnm_ro.nmro_probability = ro.probability;
117 netem->qnm_ro.nmro_correlation = ro.correlation;
118
119 netem->qnm_mask |= (SCH_NETEM_ATTR_RO_PROB |
120 SCH_NETEM_ATTR_RO_CORR);
121 }
122 }
123
124 return 0;
125}
126
127static void netem_free_data(struct rtnl_qdisc *qdisc)
128{
129 free(qdisc->q_subdata);
130}
131
132static int netem_dump_brief(struct rtnl_qdisc *qdisc, struct nl_dump_params *p,
133 int line)
134{
135 struct rtnl_netem *netem = netem_qdisc(qdisc);
136
137 if (netem)
138 dp_dump(p, "limit %d", netem->qnm_limit);
139
140 return line;
141}
142
143static int netem_dump_full(struct rtnl_qdisc *qdisc, struct nl_dump_params *p,
144 int line)
145{
146 return line;
147}
148
149static struct nl_msg *netem_get_opts(struct rtnl_qdisc *qdisc)
150{
151 return NULL;
152}
153
154/**
155 * @name Queue Limit
156 * @{
157 */
158
159/**
160 * Set limit of netem qdisc.
161 * @arg qdisc Netem qdisc to be modified.
162 * @arg limit New limit in bytes.
163 * @return 0 on success or a negative error code.
164 */
165int rtnl_netem_set_limit(struct rtnl_qdisc *qdisc, int limit)
166{
167 struct rtnl_netem *netem;
168
169 netem = netem_alloc(qdisc);
170 if (!netem)
171 return nl_errno(ENOMEM);
172
173 netem->qnm_limit = limit;
174 netem->qnm_mask |= SCH_NETEM_ATTR_LIMIT;
175
176 return 0;
177}
178
179/**
180 * Get limit of netem qdisc.
181 * @arg qdisc Netem qdisc.
182 * @return Limit in bytes or a negative error code.
183 */
184int rtnl_netem_get_limit(struct rtnl_qdisc *qdisc)
185{
186 struct rtnl_netem *netem;
187
188 netem = netem_qdisc(qdisc);
189 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_LIMIT))
190 return netem->qnm_limit;
191 else
192 return nl_errno(ENOENT);
193}
194
195/** @} */
196
197/**
198 * @name Packet Re-ordering
199 * @{
200 */
201
202/**
203 * Set re-ordering gap of netem qdisc.
204 * @arg qdisc Netem qdisc to be modified.
205 * @arg gap New gap in number of packets.
206 * @return 0 on success or a negative error code.
207 */
208int rtnl_netem_set_gap(struct rtnl_qdisc *qdisc, int gap)
209{
210 struct rtnl_netem *netem;
211
212 netem = netem_alloc(qdisc);
213 if (!netem)
214 return nl_errno(ENOMEM);
215
216 netem->qnm_gap = gap;
217 netem->qnm_mask |= SCH_NETEM_ATTR_GAP;
218
219 return 0;
220}
221
222/**
223 * Get re-ordering gap of netem qdisc.
224 * @arg qdisc Netem qdisc.
225 * @return Re-ordering gap in packets or a negative error code.
226 */
227int rtnl_netem_get_gap(struct rtnl_qdisc *qdisc)
228{
229 struct rtnl_netem *netem;
230
231 netem = netem_qdisc(qdisc);
232 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_GAP))
233 return netem->qnm_gap;
234 else
235 return nl_errno(ENOENT);
236}
237
238/**
239 * Set re-ordering probability of netem qdisc.
240 * @arg qdisc Netem qdisc to be modified.
241 * @arg prob New re-ordering probability.
242 * @return 0 on success or a negative error code.
243 */
244int rtnl_netem_set_reorder_probability(struct rtnl_qdisc *qdisc, int prob)
245{
246 struct rtnl_netem *netem;
247
248 netem = netem_alloc(qdisc);
249 if (!netem)
250 return nl_errno(ENOMEM);
251
252 netem->qnm_ro.nmro_probability = prob;
253 netem->qnm_mask |= SCH_NETEM_ATTR_RO_PROB;
254
255 return 0;
256}
257
258/**
259 * Get re-ordering probability of netem qdisc.
260 * @arg qdisc Netem qdisc.
261 * @return Re-ordering probability or a negative error code.
262 */
263int rtnl_netem_get_reorder_probability(struct rtnl_qdisc *qdisc)
264{
265 struct rtnl_netem *netem;
266
267 netem = netem_qdisc(qdisc);
268 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_RO_PROB))
269 return netem->qnm_ro.nmro_probability;
270 else
271 return nl_errno(ENOENT);
272}
273
274/**
275 * Set re-order correlation probability of netem qdisc.
276 * @arg qdisc Netem qdisc to be modified.
277 * @arg prob New re-ordering correlation probability.
278 * @return 0 on success or a negative error code.
279 */
280int rtnl_netem_set_reorder_correlation(struct rtnl_qdisc *qdisc, int prob)
281{
282 struct rtnl_netem *netem;
283
284 netem = netem_alloc(qdisc);
285 if (!netem)
286 return nl_errno(ENOMEM);
287
288 netem->qnm_ro.nmro_correlation = prob;
289 netem->qnm_mask |= SCH_NETEM_ATTR_RO_CORR;
290
291 return 0;
292}
293
294/**
295 * Get re-ordering correlation probability of netem qdisc.
296 * @arg qdisc Netem qdisc.
297 * @return Re-ordering correlation probability or a negative error code.
298 */
299int rtnl_netem_get_reorder_correlation(struct rtnl_qdisc *qdisc)
300{
301 struct rtnl_netem *netem;
302
303 netem = netem_qdisc(qdisc);
304 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_RO_CORR))
305 return netem->qnm_ro.nmro_correlation;
306 else
307 return nl_errno(ENOENT);
308}
309
310/** @} */
311
312/**
313 * @name Packet Loss
314 * @{
315 */
316
317/**
318 * Set packet loss probability of netem qdisc.
319 * @arg qdisc Netem qdisc to be modified.
320 * @arg prob New packet loss probability.
321 * @return 0 on success or a negative error code.
322 */
323int rtnl_netem_set_loss(struct rtnl_qdisc *qdisc, int prob)
324{
325 struct rtnl_netem *netem;
326
327 netem = netem_alloc(qdisc);
328 if (!netem)
329 return nl_errno(ENOMEM);
330
331 netem->qnm_loss = prob;
332 netem->qnm_mask |= SCH_NETEM_ATTR_LOSS;
333
334 return 0;
335}
336
337/**
338 * Get packet loss probability of netem qdisc.
339 * @arg qdisc Netem qdisc.
340 * @return Packet loss probability or a negative error code.
341 */
342int rtnl_netem_get_loss(struct rtnl_qdisc *qdisc)
343{
344 struct rtnl_netem *netem;
345
346 netem = netem_qdisc(qdisc);
347 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_LOSS))
348 return netem->qnm_loss;
349 else
350 return nl_errno(ENOENT);
351}
352
353/**
354 * Set packet loss correlation probability of netem qdisc.
355 * @arg qdisc Netem qdisc to be modified.
356 * @arg prob New packet loss correlation.
357 * @return 0 on success or a negative error code.
358 */
359int rtnl_netem_set_loss_correlation(struct rtnl_qdisc *qdisc, int prob)
360{
361 struct rtnl_netem *netem;
362
363 netem = netem_alloc(qdisc);
364 if (!netem)
365 return nl_errno(ENOMEM);
366
367 netem->qnm_corr.nmc_loss = prob;
368 netem->qnm_mask |= SCH_NETEM_ATTR_LOSS_CORR;
369
370 return 0;
371}
372
373/**
374 * Get packet loss correlation probability of netem qdisc.
375 * @arg qdisc Netem qdisc.
376 * @return Packet loss correlation probability or a negative error code.
377 */
378int rtnl_netem_get_loss_correlation(struct rtnl_qdisc *qdisc)
379{
380 struct rtnl_netem *netem;
381
382 netem = netem_qdisc(qdisc);
383 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_LOSS_CORR))
384 return netem->qnm_corr.nmc_loss;
385 else
386 return nl_errno(ENOENT);
387}
388
389/** @} */
390
391/**
392 * @name Packet Duplication
393 * @{
394 */
395
396/**
397 * Set packet duplication probability of netem qdisc.
398 * @arg qdisc Netem qdisc to be modified.
399 * @arg prob New packet duplication probability.
400 * @return 0 on success or a negative error code.
401 */
402int rtnl_netem_set_duplicate(struct rtnl_qdisc *qdisc, int prob)
403{
404 struct rtnl_netem *netem;
405
406 netem = netem_alloc(qdisc);
407 if (!netem)
408 return nl_errno(ENOMEM);
409
410 netem->qnm_duplicate = prob;
411 netem->qnm_mask |= SCH_NETEM_ATTR_DUPLICATE;
412
413 return 0;
414}
415
416/**
417 * Get packet duplication probability of netem qdisc.
418 * @arg qdisc Netem qdisc.
419 * @return Packet duplication probability or a negative error code.
420 */
421int rtnl_netem_get_duplicate(struct rtnl_qdisc *qdisc)
422{
423 struct rtnl_netem *netem;
424
425 netem = netem_qdisc(qdisc);
426 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_DUPLICATE))
427 return netem->qnm_duplicate;
428 else
429 return nl_errno(ENOENT);
430}
431
432/**
433 * Set packet duplication correlation probability of netem qdisc.
434 * @arg qdisc Netem qdisc to be modified.
435 * @arg prob New packet duplication correlation probability.
436 * @return 0 on sucess or a negative error code.
437 */
438int rtnl_netem_set_duplicate_correlation(struct rtnl_qdisc *qdisc, int prob)
439{
440 struct rtnl_netem *netem;
441
442 netem = netem_alloc(qdisc);
443 if (!netem)
444 return nl_errno(ENOMEM);
445
446 netem->qnm_corr.nmc_duplicate = prob;
447 netem->qnm_mask |= SCH_NETEM_ATTR_DUP_CORR;
448
449 return 0;
450}
451
452/**
453 * Get packet duplication correlation probability of netem qdisc.
454 * @arg qdisc Netem qdisc.
455 * @return Packet duplication correlation probability or a negative error code.
456 */
457int rtnl_netem_get_duplicate_correlation(struct rtnl_qdisc *qdisc)
458{
459 struct rtnl_netem *netem;
460
461 netem = netem_qdisc(qdisc);
462 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_DUP_CORR))
463 return netem->qnm_corr.nmc_duplicate;
464 else
465 return nl_errno(ENOENT);
466}
467
468/** @} */
469
470/**
471 * @name Packet Delay
472 * @{
473 */
474
475/**
476 * Set packet delay of netem qdisc.
477 * @arg qdisc Netem qdisc to be modified.
478 * @arg delay New packet delay in micro seconds.
479 * @return 0 on success or a negative error code.
480 */
481int rtnl_netem_set_delay(struct rtnl_qdisc *qdisc, int delay)
482{
483 struct rtnl_netem *netem;
484
485 netem = netem_alloc(qdisc);
486 if (!netem)
487 return nl_errno(ENOMEM);
488
489 netem->qnm_latency = nl_us2ticks(delay);
490 netem->qnm_mask |= SCH_NETEM_ATTR_LATENCY;
491
492 return 0;
493}
494
495/**
496 * Get packet delay of netem qdisc.
497 * @arg qdisc Netem qdisc.
498 * @return Packet delay in micro seconds or a negative error code.
499 */
500int rtnl_netem_get_delay(struct rtnl_qdisc *qdisc)
501{
502 struct rtnl_netem *netem;
503
504 netem = netem_qdisc(qdisc);
505 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_LATENCY))
506 return nl_ticks2us(netem->qnm_latency);
507 else
508 return nl_errno(ENOENT);
509}
510
511/**
512 * Set packet delay jitter of netem qdisc.
513 * @arg qdisc Netem qdisc to be modified.
514 * @arg jitter New packet delay jitter in micro seconds.
515 * @return 0 on success or a negative error code.
516 */
517int rtnl_netem_set_jitter(struct rtnl_qdisc *qdisc, int jitter)
518{
519 struct rtnl_netem *netem;
520
521 netem = netem_alloc(qdisc);
522 if (!netem)
523 return nl_errno(ENOMEM);
524
525 netem->qnm_jitter = nl_us2ticks(jitter);
526 netem->qnm_mask |= SCH_NETEM_ATTR_JITTER;
527
528 return 0;
529}
530
531/**
532 * Get packet delay jitter of netem qdisc.
533 * @arg qdisc Netem qdisc.
534 * @return Packet delay jitter in micro seconds or a negative error code.
535 */
536int rtnl_netem_get_jitter(struct rtnl_qdisc *qdisc)
537{
538 struct rtnl_netem *netem;
539
540 netem = netem_qdisc(qdisc);
541 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_JITTER))
542 return nl_ticks2us(netem->qnm_jitter);
543 else
544 return nl_errno(ENOENT);
545}
546
547/**
548 * Set packet delay correlation probability of netem qdisc.
549 * @arg qdisc Netem qdisc to be modified.
550 * @arg prob New packet delay correlation probability.
551 */
552int rtnl_netem_set_delay_correlation(struct rtnl_qdisc *qdisc, int prob)
553{
554 struct rtnl_netem *netem;
555
556 netem = netem_alloc(qdisc);
557 if (!netem)
558 return nl_errno(ENOMEM);
559
560 netem->qnm_corr.nmc_delay = prob;
561 netem->qnm_mask |= SCH_NETEM_ATTR_DELAY_CORR;
562
563 return 0;
564}
565
566/**
567 * Get packet delay correlation probability of netem qdisc.
568 * @arg qdisc Netem qdisc.
569 * @return Packet delay correlation probability or a negative error code.
570 */
571int rtnl_netem_get_delay_correlation(struct rtnl_qdisc *qdisc)
572{
573 struct rtnl_netem *netem;
574
575 netem = netem_qdisc(qdisc);
576 if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_DELAY_CORR))
577 return netem->qnm_corr.nmc_delay;
578 else
579 return nl_errno(ENOENT);
580}
581
582/** @} */
583
584static struct rtnl_qdisc_ops netem_ops = {
585 .qo_kind = "netem",
586 .qo_msg_parser = netem_msg_parser,
587 .qo_free_data = netem_free_data,
588 .qo_dump[NL_DUMP_BRIEF] = netem_dump_brief,
589 .qo_dump[NL_DUMP_FULL] = netem_dump_full,
590 .qo_get_opts = netem_get_opts,
591};
592
593static void __init netem_init(void)
594{
595 rtnl_qdisc_register(&netem_ops);
596}
597
598static void __exit netem_exit(void)
599{
600 rtnl_qdisc_unregister(&netem_ops);
601}
602
603/** @} */
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, struct nla_policy *policy)
Parse a stream of attributes into a tb buffer.
Definition: attr.c:262
int nla_memcpy(void *dest, struct nlattr *src, int count)
Copy a netlink attribute into another memory area.
Definition: attr.c:382
int rtnl_netem_get_duplicate(struct rtnl_qdisc *qdisc)
Get packet duplication probability of netem qdisc.
Definition: netem.c:421
int rtnl_netem_get_reorder_correlation(struct rtnl_qdisc *qdisc)
Get re-ordering correlation probability of netem qdisc.
Definition: netem.c:299
int rtnl_netem_get_delay_correlation(struct rtnl_qdisc *qdisc)
Get packet delay correlation probability of netem qdisc.
Definition: netem.c:571
int rtnl_netem_get_loss(struct rtnl_qdisc *qdisc)
Get packet loss probability of netem qdisc.
Definition: netem.c:342
int rtnl_netem_set_jitter(struct rtnl_qdisc *qdisc, int jitter)
Set packet delay jitter of netem qdisc.
Definition: netem.c:517
int rtnl_netem_set_duplicate_correlation(struct rtnl_qdisc *qdisc, int prob)
Set packet duplication correlation probability of netem qdisc.
Definition: netem.c:438
int rtnl_netem_set_delay(struct rtnl_qdisc *qdisc, int delay)
Set packet delay of netem qdisc.
Definition: netem.c:481
int rtnl_netem_set_duplicate(struct rtnl_qdisc *qdisc, int prob)
Set packet duplication probability of netem qdisc.
Definition: netem.c:402
int rtnl_netem_get_gap(struct rtnl_qdisc *qdisc)
Get re-ordering gap of netem qdisc.
Definition: netem.c:227
int rtnl_netem_get_reorder_probability(struct rtnl_qdisc *qdisc)
Get re-ordering probability of netem qdisc.
Definition: netem.c:263
int rtnl_netem_get_duplicate_correlation(struct rtnl_qdisc *qdisc)
Get packet duplication correlation probability of netem qdisc.
Definition: netem.c:457
int rtnl_netem_set_reorder_probability(struct rtnl_qdisc *qdisc, int prob)
Set re-ordering probability of netem qdisc.
Definition: netem.c:244
int rtnl_netem_set_delay_correlation(struct rtnl_qdisc *qdisc, int prob)
Set packet delay correlation probability of netem qdisc.
Definition: netem.c:552
int rtnl_netem_set_limit(struct rtnl_qdisc *qdisc, int limit)
Set limit of netem qdisc.
Definition: netem.c:165
int rtnl_netem_get_jitter(struct rtnl_qdisc *qdisc)
Get packet delay jitter of netem qdisc.
Definition: netem.c:536
int rtnl_netem_get_delay(struct rtnl_qdisc *qdisc)
Get packet delay of netem qdisc.
Definition: netem.c:500
int rtnl_netem_set_gap(struct rtnl_qdisc *qdisc, int gap)
Set re-ordering gap of netem qdisc.
Definition: netem.c:208
int rtnl_netem_set_loss_correlation(struct rtnl_qdisc *qdisc, int prob)
Set packet loss correlation probability of netem qdisc.
Definition: netem.c:359
int rtnl_netem_set_reorder_correlation(struct rtnl_qdisc *qdisc, int prob)
Set re-order correlation probability of netem qdisc.
Definition: netem.c:280
int rtnl_netem_get_loss_correlation(struct rtnl_qdisc *qdisc)
Get packet loss correlation probability of netem qdisc.
Definition: netem.c:378
int rtnl_netem_set_loss(struct rtnl_qdisc *qdisc, int prob)
Set packet loss probability of netem qdisc.
Definition: netem.c:323
int rtnl_netem_get_limit(struct rtnl_qdisc *qdisc)
Get limit of netem qdisc.
Definition: netem.c:184
int rtnl_qdisc_unregister(struct rtnl_qdisc_ops *qops)
Unregister a qdisc module.
Definition: qdisc_api.c:61
int rtnl_qdisc_register(struct rtnl_qdisc_ops *qops)
Register a qdisc module.
Definition: qdisc_api.c:40
uint32_t nl_ticks2us(uint32_t ticks)
Convert ticks to micro seconds.
Definition: utils.c:450
uint32_t nl_us2ticks(uint32_t us)
Convert micro seconds to ticks.
Definition: utils.c:439
@ NL_DUMP_FULL
Dump all attributes but no statistics.
Definition: types.h:23
@ NL_DUMP_BRIEF
Dump object in a brief one-liner.
Definition: types.h:22
Dumping parameters.
Definition: types.h:37
attribute validation policy
Definition: attr.h:73
uint16_t minlen
Minimal length of payload required to be available.
Definition: attr.h:78
Qdisc Operations.
Definition: qdisc-modules.h:26
char qo_kind[32]
Kind/Name of Qdisc.
Definition: qdisc-modules.h:30