diff -Naur orig/iproute2-2.6.11-050330/include/linux/pkt_sched.h new/iproute2-2.6.11-050330/include/linux/pkt_sched.h --- orig/iproute2-2.6.11-050330/include/linux/pkt_sched.h 2005-04-01 19:58:11.000000000 +0000 +++ new/iproute2-2.6.11-050330/include/linux/pkt_sched.h 2005-05-21 11:59:12.000000000 +0000 @@ -427,6 +427,7 @@ TCA_NETEM_UNSPEC, TCA_NETEM_CORR, TCA_NETEM_DELAY_DIST, + TCA_NETEM_REORDER, __TCA_NETEM_MAX, }; @@ -437,7 +438,7 @@ __u32 latency; /* added delay (us) */ __u32 limit; /* fifo limit (packets) */ __u32 loss; /* random packet loss (0=none ~0=100%) */ - __u32 gap; /* re-ordering gap (0 for delay all) */ + __u32 gap; /* re-ordering gap (0 for none) */ __u32 duplicate; /* random packet dup (0=none ~0=100%) */ __u32 jitter; /* random jitter in latency (us) */ }; @@ -449,6 +450,12 @@ __u32 dup_corr; /* duplicate correlation */ }; +struct tc_netem_reorder +{ + __u32 probability; + __u32 correlation; +}; + #define NETEM_DIST_SCALE 8192 #endif diff -Naur orig/iproute2-2.6.11-050330/tc/q_netem.c new/iproute2-2.6.11-050330/tc/q_netem.c --- orig/iproute2-2.6.11-050330/tc/q_netem.c 2005-04-01 19:58:11.000000000 +0000 +++ new/iproute2-2.6.11-050330/tc/q_netem.c 2005-05-21 10:58:33.000000000 +0000 @@ -33,6 +33,7 @@ " [ drop PERCENT [CORRELATION]] \n" \ " [ duplicate PERCENT [CORRELATION]]\n" \ " [ distribution {uniform|normal|pareto|paretonormal} ]\n" \ +" [ reorder PERCENT [CORRELATION]]\n" \ " [ gap PACKETS ]\n"); } @@ -127,11 +128,13 @@ struct rtattr *tail; struct tc_netem_qopt opt; struct tc_netem_corr cor; + struct tc_netem_reorder reorder; __s16 dist_data[MAXDIST]; memset(&opt, 0, sizeof(opt)); opt.limit = 1000; memset(&cor, 0, sizeof(cor)); + memset(&reorder, 0, sizeof(reorder)); while (argc > 0) { if (matches(*argv, "limit") == 0) { @@ -197,6 +200,19 @@ return -1; } } + } else if (matches(*argv, "reorder") == 0) { + NEXT_ARG(); + if (get_percent(&reorder.probability, *argv)) { + explain1("reorder"); + return -1; + } + if (NEXT_IS_NUMBER()) { + NEXT_ARG(); + if (get_percent(&reorder.correlation, *argv)) { + explain1("reorder"); + return -1; + } + } } else if (matches(*argv, "distribution") == 0) { NEXT_ARG(); dist_size = get_distribution(*argv, dist_data); @@ -217,6 +233,7 @@ addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt)); addattr_l(n, 1024, TCA_NETEM_CORR, &cor, sizeof(cor)); + addattr_l(n, 1024, TCA_NETEM_REORDER, &reorder, sizeof(reorder)); if (dist_size > 0) { addattr_l(n, 32768, TCA_NETEM_DELAY_DIST, @@ -229,7 +246,8 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) { const struct tc_netem_corr *cor = NULL; - struct tc_netem_qopt qopt; + const struct tc_netem_reorder *reorder = NULL; + struct tc_netem_qopt qopt; int len = RTA_PAYLOAD(opt) - sizeof(qopt); SPRINT_BUF(b1); @@ -252,6 +270,12 @@ return -1; cor = RTA_DATA(tb[TCA_NETEM_CORR]); } + + if (tb[TCA_NETEM_REORDER]) { + if (RTA_PAYLOAD(tb[TCA_NETEM_REORDER]) < sizeof(*reorder)) + return -1; + reorder = RTA_DATA(tb[TCA_NETEM_REORDER]); + } } fprintf(f, "limit %d", qopt.limit); @@ -279,6 +303,13 @@ fprintf(f, " %s", sprint_percent(cor->dup_corr, b1)); } + if (reorder && reorder->probability) { + fprintf(f, " reorder %s", + sprint_percent(reorder->probability, b1)); + if (reorder && reorder->correlation) + fprintf(f, " %s", sprint_percent(reorder->correlation, b1)); + } + if (qopt.gap) fprintf(f, " gap %lu", (unsigned long)qopt.gap);