1309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger/* 2309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger * q_netem.c NETEM. 3309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger * 4309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger * This program is free software; you can redistribute it and/or 5309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger * modify it under the terms of the GNU General Public License 6309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger * as published by the Free Software Foundation; either version 7309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger * 2 of the License, or (at your option) any later version. 8309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger * 959a935d2045b233539a2d0be00310d355a9e0ebdStephen Hemminger * Authors: Stephen Hemminger <shemminger@linux-foundation.org> 10309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger * 11309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger */ 12309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 13309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include <stdio.h> 14309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include <stdlib.h> 153c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger#include <math.h> 163c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger#include <ctype.h> 17309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include <unistd.h> 18309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include <syslog.h> 19309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include <fcntl.h> 20309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include <sys/socket.h> 21309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include <netinet/in.h> 22309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include <arpa/inet.h> 23309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include <string.h> 24b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger#include <errno.h> 25309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 26309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include "utils.h" 27309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger#include "tc_util.h" 28b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger#include "tc_common.h" 29309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 30309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemmingerstatic void explain(void) 31309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger{ 32ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger fprintf(stderr, 33b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger"Usage: ... netem [ limit PACKETS ] \n" \ 34ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger" [ delay TIME [ JITTER [CORRELATION]]]\n" \ 35ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger" [ distribution {uniform|normal|pareto|paretonormal} ]\n" \ 36a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger" [ corrupt PERCENT [CORRELATION]] \n" \ 37b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger" [ duplicate PERCENT [CORRELATION]]\n" \ 383c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger" [ loss random PERCENT [CORRELATION]]\n" \ 393c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger" [ loss state P13 [P31 [P32 [P23 P14]]]\n" \ 403c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger" [ loss gemodel PERCENT [R [1-H [1-K]]]\n" \ 411070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian" [ ecn ]\n" \ 426b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer" [ reorder PRECENT [CORRELATION] [ gap DISTANCE ]]\n" \ 436b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer" [ rate RATE [PACKETOVERHEAD] [CELLSIZE] [CELLOVERHEAD]]\n"); 44309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger} 45309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 46309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemmingerstatic void explain1(const char *arg) 47309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger{ 48309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger fprintf(stderr, "Illegal \"%s\"\n", arg); 49309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger} 50309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 513c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger/* Upper bound on size of distribution 52c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger * really (TCA_BUF_MAX - other headers) / sizeof (__s16) 53c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger */ 54c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger#define MAX_DIST (16*1024) 55c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger 563c7950af598beab378a291ee0540da438978a4b2Stephen Hemmingerstatic const double max_percent_value = 0xffffffff; 573c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 583c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger/* scaled value used to percent of maximum. */ 593c7950af598beab378a291ee0540da438978a4b2Stephen Hemmingerstatic void set_percent(__u32 *percent, double per) 603c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger{ 613c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger *percent = (unsigned) rint(per * max_percent_value); 623c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger} 633c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 643c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 653c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger/* Parse either a fraction '.3' or percent '30% 663c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger * return: 0 = ok, -1 = error, 1 = out of range 673c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger */ 683c7950af598beab378a291ee0540da438978a4b2Stephen Hemmingerstatic int parse_percent(double *val, const char *str) 693c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger{ 703c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger char *p; 713c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 723c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger *val = strtod(str, &p) / 100.; 733c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (*p && strcmp(p, "%") ) 743c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 753c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 763c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return 0; 773c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger} 783c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 793c7950af598beab378a291ee0540da438978a4b2Stephen Hemmingerstatic int get_percent(__u32 *percent, const char *str) 803c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger{ 813c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger double per; 823c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 833c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (parse_percent(&per, str)) 843c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 853c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 863c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger set_percent(percent, per); 873c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return 0; 883c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger} 893c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 90d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void print_percent(char *buf, int len, __u32 per) 913c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger{ 923c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger snprintf(buf, len, "%g%%", 100. * (double) per / max_percent_value); 933c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger} 943c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 95d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic char * sprint_percent(__u32 per, char *buf) 963c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger{ 973c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger print_percent(buf, SPRINT_BSIZE-1, per); 983c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return buf; 993c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger} 1003c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 1012e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger/* 1022e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger * Simplistic file parser for distrbution data. 1032e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger * Format is: 1042e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger * # comment line(s) 105c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger * data0 data1 ... 1062e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger */ 107c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemmingerstatic int get_distribution(const char *type, __s16 *data, int maxdata) 108b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger{ 109b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger FILE *f; 110b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger int n; 1112e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger long x; 1122e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger size_t len; 113fb9b1d0f6a9f355bceae435ea43f1c8f3635b2dfosdl.net!shemminger char *line = NULL; 1142e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger char name[128]; 115b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 116aa27f88c8444ad6a87ebb563d6ffacb4fe95d87cStephen Hemminger snprintf(name, sizeof(name), "%s/%s.dist", get_tc_lib(), type); 1172e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if ((f = fopen(name, "r")) == NULL) { 118ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger fprintf(stderr, "No distribution data for %s (%s: %s)\n", 1192e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger type, name, strerror(errno)); 120b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger return -1; 121b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 122ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger 123b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger n = 0; 1242e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger while (getline(&line, &len, f) != -1) { 1252e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger char *p, *endp; 1262e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (*line == '\n' || *line == '#') 127b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger continue; 128b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 1292e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger for (p = line; ; p = endp) { 1302e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger x = strtol(p, &endp, 0); 131ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger if (endp == p) 1322e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger break; 1332e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger 134c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger if (n >= maxdata) { 1352e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger fprintf(stderr, "%s: too much data\n", 1362e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger name); 1372e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger n = -1; 1382e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger goto error; 1392e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger } 140b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger data[n++] = x; 141b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 142b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 1432e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger error: 1442e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger free(line); 145b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger fclose(f); 146b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger return n; 147b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger} 148b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 1493c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger#define NEXT_IS_NUMBER() (NEXT_ARG_OK() && isdigit(argv[1][0])) 150e72ca3fbb0aeaa382e6a5a14dada38a56ffab160Johannes Naab#define NEXT_IS_SIGNED_NUMBER() \ 151e72ca3fbb0aeaa382e6a5a14dada38a56ffab160Johannes Naab (NEXT_ARG_OK() && (isdigit(argv[1][0]) || argv[1][0] == '-')) 152b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 153ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger/* Adjust for the fact that psched_ticks aren't always usecs 154b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger (based on kernel PSCHED_CLOCK configuration */ 155b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemmingerstatic int get_ticks(__u32 *ticks, const char *str) 156b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger{ 157b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger unsigned t; 158b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 1598f34caafbdbc8f87d228d577872591e138caadb1Patrick McHardy if(get_time(&t, str)) 160b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger return -1; 161ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger 1628f34caafbdbc8f87d228d577872591e138caadb1Patrick McHardy if (tc_core_time2big(t)) { 1638f34caafbdbc8f87d228d577872591e138caadb1Patrick McHardy fprintf(stderr, "Illegal %u time (too large)\n", t); 164fa56513034c839e444ab7ca986ddb178dece86c7Stephen Hemminger return -1; 165fa56513034c839e444ab7ca986ddb178dece86c7Stephen Hemminger } 166fa56513034c839e444ab7ca986ddb178dece86c7Stephen Hemminger 1678f34caafbdbc8f87d228d577872591e138caadb1Patrick McHardy *ticks = tc_core_time2tick(t); 168b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger return 0; 169b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger} 170b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 171ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemmingerstatic int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv, 172309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger struct nlmsghdr *n) 173309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger{ 174fcbd0165fcf6d0efdfb02220ac77342ce0c0e224Thomas Jarosch int dist_size = 0; 1752e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger struct rtattr *tail; 1763c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger struct tc_netem_qopt opt = { .limit = 1000 }; 1772e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger struct tc_netem_corr cor; 178ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger struct tc_netem_reorder reorder; 179a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger struct tc_netem_corrupt corrupt; 1803c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger struct tc_netem_gimodel gimodel; 1813c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger struct tc_netem_gemodel gemodel; 1826b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer struct tc_netem_rate rate; 183a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger __s16 *dist_data = NULL; 1843c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger __u16 loss_type = NETEM_LOSS_UNSPEC; 18540076f622e0aacb2b792d3ac1b5d12aa97c4da9cStephen Hemminger int present[__TCA_NETEM_MAX]; 186dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang __u64 rate64 = 0; 187309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 1882e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger memset(&cor, 0, sizeof(cor)); 189ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger memset(&reorder, 0, sizeof(reorder)); 190a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger memset(&corrupt, 0, sizeof(corrupt)); 1916b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer memset(&rate, 0, sizeof(rate)); 19240076f622e0aacb2b792d3ac1b5d12aa97c4da9cStephen Hemminger memset(present, 0, sizeof(present)); 193309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 1943c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger for( ; argc > 0; --argc, ++argv) { 195309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger if (matches(*argv, "limit") == 0) { 196309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger NEXT_ARG(); 1972e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (get_size(&opt.limit, *argv)) { 198309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger explain1("limit"); 199309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return -1; 200309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger } 201b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } else if (matches(*argv, "latency") == 0 || 202b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger matches(*argv, "delay") == 0) { 203309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger NEXT_ARG(); 2042e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (get_ticks(&opt.latency, *argv)) { 205309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger explain1("latency"); 206309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return -1; 207309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger } 208b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 209b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger if (NEXT_IS_NUMBER()) { 210b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger NEXT_ARG(); 2112e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (get_ticks(&opt.jitter, *argv)) { 212b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger explain1("latency"); 213b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger return -1; 214b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 215b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 216b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger if (NEXT_IS_NUMBER()) { 217b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger NEXT_ARG(); 21840076f622e0aacb2b792d3ac1b5d12aa97c4da9cStephen Hemminger ++present[TCA_NETEM_CORR]; 2193c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (get_percent(&cor.delay_corr, *argv)) { 220b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger explain1("latency"); 221b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger return -1; 222b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 223b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 224b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 225b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } else if (matches(*argv, "loss") == 0 || 226b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger matches(*argv, "drop") == 0) { 2273c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (opt.loss > 0 || loss_type != NETEM_LOSS_UNSPEC) { 2283c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("duplicate loss argument\n"); 229309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return -1; 230309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger } 2313c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 2323c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger NEXT_ARG(); 2333c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger /* Old (deprecated) random loss model syntax */ 2343c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (isdigit(argv[0][0])) 2353c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger goto random_loss_model; 2363c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 2373c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (!strcmp(*argv, "random")) { 238b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger NEXT_ARG(); 2393c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger random_loss_model: 2403c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (get_percent(&opt.loss, *argv)) { 2413c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("loss percent"); 2423c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 2433c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 2443c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (NEXT_IS_NUMBER()) { 2453c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger NEXT_ARG(); 2463c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger ++present[TCA_NETEM_CORR]; 2473c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (get_percent(&cor.loss_corr, *argv)) { 2483c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("loss correllation"); 2493c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 2503c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 2513c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 2523c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } else if (!strcmp(*argv, "state")) { 2533c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger double p13; 2543c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 2553c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger NEXT_ARG(); 2563c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (parse_percent(&p13, *argv)) { 2573c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("loss p13"); 2583c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 2593c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 2603c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 2613c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger /* set defaults */ 2623c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger set_percent(&gimodel.p13, p13); 2633c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger set_percent(&gimodel.p31, 1. - p13); 2643c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger set_percent(&gimodel.p32, 0); 2653c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger set_percent(&gimodel.p23, 1.); 2668f9672af7af74608278ab45546cf64d7bdfcd15fJay Vosburgh set_percent(&gimodel.p14, 0); 2673c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger loss_type = NETEM_LOSS_GI; 2683c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 2693c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (!NEXT_IS_NUMBER()) 2703c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger continue; 2713c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger NEXT_ARG(); 2723c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (get_percent(&gimodel.p31, *argv)) { 2733c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("loss p31"); 2743c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 2753c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 2763c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 2773c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (!NEXT_IS_NUMBER()) 2783c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger continue; 2793c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger NEXT_ARG(); 2803c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (get_percent(&gimodel.p32, *argv)) { 2813c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("loss p32"); 2823c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 2833c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 2843c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 2853c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (!NEXT_IS_NUMBER()) 2863c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger continue; 2873c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger NEXT_ARG(); 2883c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (get_percent(&gimodel.p23, *argv)) { 2893c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("loss p23"); 2903c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 2913c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 2928f9672af7af74608278ab45546cf64d7bdfcd15fJay Vosburgh if (!NEXT_IS_NUMBER()) 2938f9672af7af74608278ab45546cf64d7bdfcd15fJay Vosburgh continue; 2948f9672af7af74608278ab45546cf64d7bdfcd15fJay Vosburgh NEXT_ARG(); 2958f9672af7af74608278ab45546cf64d7bdfcd15fJay Vosburgh if (get_percent(&gimodel.p14, *argv)) { 2968f9672af7af74608278ab45546cf64d7bdfcd15fJay Vosburgh explain1("loss p14"); 2978f9672af7af74608278ab45546cf64d7bdfcd15fJay Vosburgh return -1; 2988f9672af7af74608278ab45546cf64d7bdfcd15fJay Vosburgh } 2993c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 3003c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } else if (!strcmp(*argv, "gemodel")) { 3013c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger NEXT_ARG(); 3023c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (get_percent(&gemodel.p, *argv)) { 3033c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("loss gemodel p"); 3043c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 3053c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 3063c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 3073c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger /* set defaults */ 3083c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger set_percent(&gemodel.r, 1.); 3093c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger set_percent(&gemodel.h, 0); 3103757185b29bba37943107ce49c21553054023f44Jay Vosburgh set_percent(&gemodel.k1, 0); 3113c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger loss_type = NETEM_LOSS_GE; 3123c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 3133c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (!NEXT_IS_NUMBER()) 3143c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger continue; 3153c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger NEXT_ARG(); 3163c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (get_percent(&gemodel.r, *argv)) { 3173c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("loss gemodel r"); 3183c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 3193c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 3203c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 3213c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (!NEXT_IS_NUMBER()) 3223c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger continue; 3233c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger NEXT_ARG(); 3243c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (get_percent(&gemodel.h, *argv)) { 3253c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("loss gemodel h"); 3263c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 3273c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 3283757185b29bba37943107ce49c21553054023f44Jay Vosburgh /* netem option is "1-h" but kernel 3293757185b29bba37943107ce49c21553054023f44Jay Vosburgh * expects "h". 3303757185b29bba37943107ce49c21553054023f44Jay Vosburgh */ 3313757185b29bba37943107ce49c21553054023f44Jay Vosburgh gemodel.h = max_percent_value - gemodel.h; 3323c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 3333c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (!NEXT_IS_NUMBER()) 3343c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger continue; 3353c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger NEXT_ARG(); 3363c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (get_percent(&gemodel.k1, *argv)) { 3373c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger explain1("loss gemodel k"); 338b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger return -1; 339b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 3403c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } else { 3413c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger fprintf(stderr, "Unknown loss parameter: %s\n", 3423c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger *argv); 3433c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 344b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 3451070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian } else if (matches(*argv, "ecn") == 0) { 3461070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian present[TCA_NETEM_ECN] = 1; 347ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger } else if (matches(*argv, "reorder") == 0) { 348ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger NEXT_ARG(); 34940076f622e0aacb2b792d3ac1b5d12aa97c4da9cStephen Hemminger present[TCA_NETEM_REORDER] = 1; 350ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger if (get_percent(&reorder.probability, *argv)) { 351ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger explain1("reorder"); 352ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger return -1; 353ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger } 354ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger if (NEXT_IS_NUMBER()) { 355ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger NEXT_ARG(); 35640076f622e0aacb2b792d3ac1b5d12aa97c4da9cStephen Hemminger ++present[TCA_NETEM_CORR]; 357ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger if (get_percent(&reorder.correlation, *argv)) { 358ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger explain1("reorder"); 359ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger return -1; 360ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger } 361ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger } 362a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger } else if (matches(*argv, "corrupt") == 0) { 363a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger NEXT_ARG(); 36440076f622e0aacb2b792d3ac1b5d12aa97c4da9cStephen Hemminger present[TCA_NETEM_CORRUPT] = 1; 365a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger if (get_percent(&corrupt.probability, *argv)) { 366a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger explain1("corrupt"); 367a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger return -1; 368a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger } 369a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger if (NEXT_IS_NUMBER()) { 370a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger NEXT_ARG(); 37140076f622e0aacb2b792d3ac1b5d12aa97c4da9cStephen Hemminger ++present[TCA_NETEM_CORR]; 372a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger if (get_percent(&corrupt.correlation, *argv)) { 373a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger explain1("corrupt"); 374a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger return -1; 375a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger } 376a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger } 377309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger } else if (matches(*argv, "gap") == 0) { 378309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger NEXT_ARG(); 3792e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (get_u32(&opt.gap, *argv, 0)) { 380309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger explain1("gap"); 381309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return -1; 382309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger } 383ffb79d06915fe3b1ee5d2e4e37c1db67c3c06cdfosdl.net!shemminger } else if (matches(*argv, "duplicate") == 0) { 384309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger NEXT_ARG(); 3852e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (get_percent(&opt.duplicate, *argv)) { 386ffb79d06915fe3b1ee5d2e4e37c1db67c3c06cdfosdl.net!shemminger explain1("duplicate"); 387309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return -1; 388309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger } 389b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger if (NEXT_IS_NUMBER()) { 390b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger NEXT_ARG(); 3912e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (get_percent(&cor.dup_corr, *argv)) { 392b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger explain1("duplicate"); 393b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger return -1; 394b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 395b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 396b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } else if (matches(*argv, "distribution") == 0) { 397309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger NEXT_ARG(); 398c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger dist_data = calloc(sizeof(dist_data[0]), MAX_DIST); 399c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger dist_size = get_distribution(*argv, dist_data, MAX_DIST); 400c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger if (dist_size <= 0) { 401c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger free(dist_data); 402309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return -1; 403c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger } 4046b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer } else if (matches(*argv, "rate") == 0) { 4056b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer ++present[TCA_NETEM_RATE]; 4066b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer NEXT_ARG(); 407dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang if (get_rate64(&rate64, *argv)) { 4086b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer explain1("rate"); 4096b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer return -1; 4106b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer } 411e72ca3fbb0aeaa382e6a5a14dada38a56ffab160Johannes Naab if (NEXT_IS_SIGNED_NUMBER()) { 4126b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer NEXT_ARG(); 4136b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer if (get_s32(&rate.packet_overhead, *argv, 0)) { 4146b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer explain1("rate"); 4156b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer return -1; 4166b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer } 4176b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer } 4186b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer if (NEXT_IS_NUMBER()) { 4196b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer NEXT_ARG(); 4206b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer if (get_u32(&rate.cell_size, *argv, 0)) { 4216b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer explain1("rate"); 4226b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer return -1; 4236b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer } 4246b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer } 425e72ca3fbb0aeaa382e6a5a14dada38a56ffab160Johannes Naab if (NEXT_IS_SIGNED_NUMBER()) { 4266b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer NEXT_ARG(); 4276b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer if (get_s32(&rate.cell_overhead, *argv, 0)) { 4286b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer explain1("rate"); 4296b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer return -1; 4306b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer } 4316b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer } 432309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger } else if (strcmp(*argv, "help") == 0) { 433309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger explain(); 434309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return -1; 435309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger } else { 436309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger fprintf(stderr, "What is \"%s\"?\n", *argv); 437309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger explain(); 438309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return -1; 439309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger } 440309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger } 441309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 4421a1d22a72284acf43f7aff5210db018076e66194n); tail = NLMSG_TAIL(n); 443025dc69a25f016c3035212517bae481dafbb2651osdl.net!shemminger 444ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger if (reorder.probability) { 445ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger if (opt.latency == 0) { 446ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger fprintf(stderr, "reordering not possible without specifying some delay\n"); 44714a1c164d12e32415acc44ef566fcf52ff4dd113Vijay Subramanian explain(); 44814a1c164d12e32415acc44ef566fcf52ff4dd113Vijay Subramanian return -1; 449ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger } 450ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger if (opt.gap == 0) 451ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger opt.gap = 1; 452ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger } else if (opt.gap > 0) { 453ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger fprintf(stderr, "gap specified without reorder probability\n"); 454ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger explain(); 455ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger return -1; 456ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger } 457ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger 4581070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian if (present[TCA_NETEM_ECN]) { 4591070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian if (opt.loss <= 0 && loss_type == NETEM_LOSS_UNSPEC) { 4601070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian fprintf(stderr, "ecn requested without loss model\n"); 4611070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian explain(); 4621070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian return -1; 4631070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian } 4641070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian } 4651070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian 466a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger if (dist_data && (opt.latency == 0 || opt.jitter == 0)) { 467ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger fprintf(stderr, "distribution specified but no latency and jitter values\n"); 468ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger explain(); 469ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger return -1; 470ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger } 471ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger 472c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger if (addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt)) < 0) 473a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger return -1; 4742e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger 47540076f622e0aacb2b792d3ac1b5d12aa97c4da9cStephen Hemminger if (present[TCA_NETEM_CORR] && 476c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger addattr_l(n, 1024, TCA_NETEM_CORR, &cor, sizeof(cor)) < 0) 477a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger return -1; 478a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger 4793c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (present[TCA_NETEM_REORDER] && 480c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger addattr_l(n, 1024, TCA_NETEM_REORDER, &reorder, sizeof(reorder)) < 0) 481e9bc3c40d0c96fff2236b404dc93de511ac1a301shemminger return -1; 482a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger 4831070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian if (present[TCA_NETEM_ECN] && 4841070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian addattr_l(n, 1024, TCA_NETEM_ECN, &present[TCA_NETEM_ECN], 4851070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian sizeof(present[TCA_NETEM_ECN])) < 0) 4861070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian return -1; 4871070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian 48840076f622e0aacb2b792d3ac1b5d12aa97c4da9cStephen Hemminger if (present[TCA_NETEM_CORRUPT] && 489c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger addattr_l(n, 1024, TCA_NETEM_CORRUPT, &corrupt, sizeof(corrupt)) < 0) 49040076f622e0aacb2b792d3ac1b5d12aa97c4da9cStephen Hemminger return -1; 491a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger 4923c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (loss_type != NETEM_LOSS_UNSPEC) { 4933c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger struct rtattr *start; 4943c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 4953c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger start = addattr_nest(n, 1024, TCA_NETEM_LOSS | NLA_F_NESTED); 4963c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (loss_type == NETEM_LOSS_GI) { 4973c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (addattr_l(n, 1024, NETEM_LOSS_GI, 4983c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger &gimodel, sizeof(gimodel)) < 0) 4993c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 5003c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } else if (loss_type == NETEM_LOSS_GE) { 5013c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (addattr_l(n, 1024, NETEM_LOSS_GE, 5023c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger &gemodel, sizeof(gemodel)) < 0) 5033c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 5043c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } else { 5053c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger fprintf(stderr, "loss in the weeds!\n"); 5063c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger return -1; 5073c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 5083d0b7439dfac96d93386295a4c961b89bd3d8463Stephen Hemminger 5093c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger addattr_nest_end(n, start); 5103c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 5113c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 512dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang if (present[TCA_NETEM_RATE]) { 513dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang if (rate64 >= (1ULL << 32)) { 514dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang if (addattr_l(n, 1024, 515dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang TCA_NETEM_RATE64, &rate64, sizeof(rate64)) < 0) 516dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang return -1; 517dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang rate.rate = ~0U; 518dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang } else { 519dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang rate.rate = rate64; 520dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang } 521dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang if (addattr_l(n, 1024, TCA_NETEM_RATE, &rate, sizeof(rate)) < 0) 522dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang return -1; 523dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang } 5246b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer 525a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger if (dist_data) { 526c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger if (addattr_l(n, MAX_DIST * sizeof(dist_data[0]), 527c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger TCA_NETEM_DELAY_DIST, 528c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger dist_data, dist_size * sizeof(dist_data[0])) < 0) 529a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger return -1; 530c1b81cb5fe92aa938e52071c89e1c8812f6d75e3Stephen Hemminger free(dist_data); 5312e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger } 5321a1d22a72284acf43f7aff5210db018076e66194void *) NLMSG_TAIL(n) - (void *) tail; tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 533b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger return 0; 534309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger} 535309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 536309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemmingerstatic int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) 537309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger{ 5382e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger const struct tc_netem_corr *cor = NULL; 539ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger const struct tc_netem_reorder *reorder = NULL; 540a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger const struct tc_netem_corrupt *corrupt = NULL; 5413c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger const struct tc_netem_gimodel *gimodel = NULL; 5423c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger const struct tc_netem_gemodel *gemodel = NULL; 5431070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian int *ecn = NULL; 5442e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger struct tc_netem_qopt qopt; 5456b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer const struct tc_netem_rate *rate = NULL; 5462e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger int len = RTA_PAYLOAD(opt) - sizeof(qopt); 547dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang __u64 rate64 = 0; 548309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger SPRINT_BUF(b1); 549309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 550309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger if (opt == NULL) 551309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return 0; 552309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 5532e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (len < 0) { 5542e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger fprintf(stderr, "options size error\n"); 555309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return -1; 556b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 5572e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger memcpy(&qopt, RTA_DATA(opt), sizeof(qopt)); 5582e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger 5592e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (len > 0) { 5601d2d1cb52255b01a764aa59cd17876cf87685f34net[shemminger]!shemminger struct rtattr *tb[TCA_NETEM_MAX+1]; 5612e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger parse_rtattr(tb, TCA_NETEM_MAX, RTA_DATA(opt) + sizeof(qopt), 5622e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger len); 563ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger 5642e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (tb[TCA_NETEM_CORR]) { 5652e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (RTA_PAYLOAD(tb[TCA_NETEM_CORR]) < sizeof(*cor)) 5662e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger return -1; 5672e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger cor = RTA_DATA(tb[TCA_NETEM_CORR]); 5682e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger } 569ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger if (tb[TCA_NETEM_REORDER]) { 570ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger if (RTA_PAYLOAD(tb[TCA_NETEM_REORDER]) < sizeof(*reorder)) 571ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger return -1; 572ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger reorder = RTA_DATA(tb[TCA_NETEM_REORDER]); 573ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger } 574a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger if (tb[TCA_NETEM_CORRUPT]) { 575a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger if (RTA_PAYLOAD(tb[TCA_NETEM_CORRUPT]) < sizeof(*corrupt)) 576a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger return -1; 577e9bc3c40d0c96fff2236b404dc93de511ac1a301shemminger corrupt = RTA_DATA(tb[TCA_NETEM_CORRUPT]); 578a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger } 5793c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (tb[TCA_NETEM_LOSS]) { 5803c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger struct rtattr *lb[NETEM_LOSS_MAX + 1]; 5813c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 5823c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger parse_rtattr_nested(lb, NETEM_LOSS_MAX, tb[TCA_NETEM_LOSS]); 5833c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (lb[NETEM_LOSS_GI]) 5848f9672af7af74608278ab45546cf64d7bdfcd15fJay Vosburgh gimodel = RTA_DATA(lb[NETEM_LOSS_GI]); 5853c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (lb[NETEM_LOSS_GE]) 5863c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger gemodel = RTA_DATA(lb[NETEM_LOSS_GE]); 5873d0b7439dfac96d93386295a4c961b89bd3d8463Stephen Hemminger } 5886b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer if (tb[TCA_NETEM_RATE]) { 5896b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer if (RTA_PAYLOAD(tb[TCA_NETEM_RATE]) < sizeof(*rate)) 5906b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer return -1; 5916b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer rate = RTA_DATA(tb[TCA_NETEM_RATE]); 5926b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer } 5931070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian if (tb[TCA_NETEM_ECN]) { 5941070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian if (RTA_PAYLOAD(tb[TCA_NETEM_ECN]) < sizeof(*ecn)) 5951070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian return -1; 5961070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian ecn = RTA_DATA(tb[TCA_NETEM_ECN]); 5971070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian } 598dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang if (tb[TCA_NETEM_RATE64]) { 599dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang if (RTA_PAYLOAD(tb[TCA_NETEM_RATE64]) < sizeof(rate64)) 600dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang return -1; 601dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang rate64 = rta_getattr_u64(tb[TCA_NETEM_RATE64]); 602dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang } 6032e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger } 604309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 6052e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger fprintf(f, "limit %d", qopt.limit); 60631fa60e00f6299328c4ae13a543c2e764b9379b7osdl.net!shemminger 6072e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (qopt.latency) { 6082e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger fprintf(f, " delay %s", sprint_ticks(qopt.latency, b1)); 609b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 6102e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (qopt.jitter) { 6112e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger fprintf(f, " %s", sprint_ticks(qopt.jitter, b1)); 6122e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (cor && cor->delay_corr) 6132e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger fprintf(f, " %s", sprint_percent(cor->delay_corr, b1)); 614b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 615b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 616b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 6172e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (qopt.loss) { 6182e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger fprintf(f, " loss %s", sprint_percent(qopt.loss, b1)); 6192e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (cor && cor->loss_corr) 6202e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger fprintf(f, " %s", sprint_percent(cor->loss_corr, b1)); 621b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 622b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 6233c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (gimodel) { 6243c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger fprintf(f, " loss state p13 %s", sprint_percent(gimodel->p13, b1)); 6253c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger fprintf(f, " p31 %s", sprint_percent(gimodel->p31, b1)); 6263c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger fprintf(f, " p32 %s", sprint_percent(gimodel->p32, b1)); 6273c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger fprintf(f, " p23 %s", sprint_percent(gimodel->p23, b1)); 6283c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger fprintf(f, " p14 %s", sprint_percent(gimodel->p14, b1)); 6293c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 6303c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 6313c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger if (gemodel) { 6323757185b29bba37943107ce49c21553054023f44Jay Vosburgh fprintf(f, " loss gemodel p %s", 6333c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger sprint_percent(gemodel->p, b1)); 6343c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger fprintf(f, " r %s", sprint_percent(gemodel->r, b1)); 6353757185b29bba37943107ce49c21553054023f44Jay Vosburgh fprintf(f, " 1-h %s", sprint_percent(max_percent_value - 6363757185b29bba37943107ce49c21553054023f44Jay Vosburgh gemodel->h, b1)); 6373c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger fprintf(f, " 1-k %s", sprint_percent(gemodel->k1, b1)); 6383c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger } 6393c7950af598beab378a291ee0540da438978a4b2Stephen Hemminger 6402e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (qopt.duplicate) { 641b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger fprintf(f, " duplicate %s", 6422e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger sprint_percent(qopt.duplicate, b1)); 6432e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (cor && cor->dup_corr) 6442e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger fprintf(f, " %s", sprint_percent(cor->dup_corr, b1)); 645b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger } 646ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger 647ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger if (reorder && reorder->probability) { 648ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger fprintf(f, " reorder %s", 649ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger sprint_percent(reorder->probability, b1)); 650ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger if (reorder->correlation) 651ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger fprintf(f, " %s", 652ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger sprint_percent(reorder->correlation, b1)); 653ea8fc1047d2b88ae1d123e3f79dbffbc2a3fa70cshemminger } 654b7be3d0cd2bd699c1bdaef960e7c7bf3ad5036d3osdl.net!shemminger 655a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger if (corrupt && corrupt->probability) { 656ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger fprintf(f, " corrupt %s", 657a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger sprint_percent(corrupt->probability, b1)); 658a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger if (corrupt->correlation) 659ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger fprintf(f, " %s", 660a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger sprint_percent(corrupt->correlation, b1)); 661a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger } 662a31a5d5904dd35d6a5839e66845f236e3284bb45shemminger 6636b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer if (rate && rate->rate) { 664dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang if (rate64) 665dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang fprintf(f, " rate %s", sprint_rate(rate64, b1)); 666dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang else 667dad2f72befc064d3ee8dea95b75b85c350cd2758Yang Yingliang fprintf(f, " rate %s", sprint_rate(rate->rate, b1)); 6686b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer if (rate->packet_overhead) 6696b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer fprintf(f, " packetoverhead %d", rate->packet_overhead); 6706b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer if (rate->cell_size) 6716b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer fprintf(f, " cellsize %u", rate->cell_size); 6726b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer if (rate->cell_overhead) 6736b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer fprintf(f, " celloverhead %d", rate->cell_overhead); 6746b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer } 6756b8dc4deea219d6c4392707bb647cc49cdc46da7Hagen Paul Pfeifer 6761070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian if (ecn) 6771070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian fprintf(f, " ecn "); 6781070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian 6792e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger if (qopt.gap) 6802e21655e39099e6a9645483bdeeebbd9e24e2345osdl.net!shemminger fprintf(f, " gap %lu", (unsigned long)qopt.gap); 681309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 6821070205dc042825dddcc30b478173f85c6b6a509Vijay Subramanian 683309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger return 0; 684309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger} 685309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger 68695812b56a5a66e7e9a21744cfe8bc0bb9791ea98net[shemminger]!kaberstruct qdisc_util netem_qdisc_util = { 68731fa60e00f6299328c4ae13a543c2e764b9379b7osdl.net!shemminger .id = "netem", 68831fa60e00f6299328c4ae13a543c2e764b9379b7osdl.net!shemminger .parse_qopt = netem_parse_opt, 68931fa60e00f6299328c4ae13a543c2e764b9379b7osdl.net!shemminger .print_qopt = netem_print_opt, 690309a4c90a5d4f648653de32807cd4146763913e9osdl.net!shemminger}; 691