started with the distribution table stuff

This commit is contained in:
Steffen Vogel 2015-07-20 16:57:44 +02:00
parent fc996c3197
commit 87f0ab1a92
3 changed files with 82 additions and 39 deletions

View file

@ -1,12 +1,14 @@
TARGETS = netem mark.so
OBJS = main.o probe.o emulate.o timing.o hist.o utils.o ts.o tc.o tcp.o
OBJS = main.o probe.o emulate.o timing.o hist.o utils.o ts.o tc.o tcp.o dist.o
CC = gcc
CFLAGS = -g -lrt -std=c99 -Wall
CFLAGS += -I/usr/local/include/libnl3
CFLAGS += -I/usr/include/libnl3
CFLAGS += -I./libnl/include
LDLIBS = -lnl-3 -lnl-route-3 -lm
@ -22,9 +24,5 @@ mark.so: mark.c
clean:
rm -f $(TARGETS)
rm -f *.o *~
make -C libnl clean
libnl:
make -C libnl
.PHONY: all clean libnl

62
dist.c
View file

@ -9,6 +9,14 @@
* @license GPLv3
*********************************************************************************/
#include <stdio.h>
#include <error.h>
#include <string.h>
#include <netlink-private/types.h>
#include <netlink/route/qdisc.h>
#include <netlink/route/tc.h>
/**
* Set the delay distribution. Latency/jitter must be set before applying.
* @arg qdisc Netem qdisc.
@ -100,21 +108,25 @@ static short * inverttable(int *table, int inversesize, int tablesize, int cumul
short *inverse;
double findex, fvalue;
inverse = (short *)malloc(inversesize*sizeof(short));
for (i=0; i < inversesize; ++i) {
inverse = (short *) malloc(inversesize * sizeof(short));
for (i=0; i < inversesize; ++i)
inverse[i] = MINSHORT;
}
for (i=0; i < tablesize; ++i) {
findex = ((double)i/(double)DISTTABLEGRANULARITY) - DISTTABLEDOMAIN;
fvalue = (double)table[i]/(double)cumulative;
inverseindex = (int)rint(fvalue*inversesize);
inversevalue = (int)rint(findex*TABLEFACTOR);
if (inversevalue <= MINSHORT) inversevalue = MINSHORT+1;
if (inversevalue > MAXSHORT) inversevalue = MAXSHORT;
if (inversevalue <= MINSHORT)
inversevalue = MINSHORT+1;
if (inversevalue > MAXSHORT)
inversevalue = MAXSHORT;
inverse[inverseindex] = inversevalue;
}
return inverse;
return inverse;
}
/* Run simple linear interpolation over the table to fill in missing entries */
@ -123,19 +135,45 @@ static void interpolatetable(short *table, int limit)
int i, j, last, lasti = -1;
last = MINSHORT;
for (i=0; i < limit; ++i) {
if (table[i] == MINSHORT) {
for (j=i; j < limit; ++j)
for (j=i; j < limit; ++j) {
if (table[j] != MINSHORT)
break;
if (j < limit) {
table[i] = last + (i-lasti)*(table[j]-last)/(j-lasti);
} else {
table[i] = last + (i-lasti)*(MAXSHORT-last)/(limit-lasti);
}
} else {
if (j < limit)
table[i] = last + (i-lasti)*(table[j]-last)/(j-lasti);
else
table[i] = last + (i-lasti)*(MAXSHORT-last)/(limit-lasti);
}
else {
last = table[i];
lasti = i;
}
}
}
int dist_generate(int argc, char *argv[])
{
return 0;
}
int dist_load(int argc, char *argv[])
{
return 0;
}
int dist(int argc, char *argv[])
{
char *subcmd = argv[0];
if (argc != 1)
error(-1, 0, "Missing sub-command");
if (!strcmp(subcmd, "generate"))
return dist_generate(argc-1, argv+1);
else if (!strcmp(subcmd, "load"))
return dist_load(argc-1, argv+1);
}

51
main.c
View file

@ -44,28 +44,31 @@ void quit(int sig, siginfo_t *si, void *ptr)
int main(int argc, char *argv[])
{
if (argc < 2) {
printf("usage: %s CMD [OPTIONS]\n", argv[0]);
printf(" CMD can be one of:\n");
printf(" probe IP PORT\n");
printf(" emulate\n");
printf("\n");
printf(" OPTIONS:\n");
printf(" -m --mark N apply emulation only to packet buffers with mark N\n");
printf(" -M --mask N an optional mask for the fw mark\n");
printf(" -i --interval N update the emulation parameters every N seconds\n");
printf(" -r --rate rate limit used for measurements and updates of network emulation\n");
printf(" -l --limit how many probes should we sent\n");
printf(" -d --dev network interface\n");
printf("\n");
printf("netem util %s (built on %s %s)\n",
VERSION, __DATE__, __TIME__);
printf(" Copyright 2015, Steffen Vogel <post@steffenvogel.de>\n");
printf( "usage: %s CMD [OPTIONS]\n"
" CMD can be one of:\n\n"
" probe IP PORT Start TCP SYN+ACK RTT probes and write measurements data to STDOUT\n"
" live Read measurement data from STDIN and configure Kernel (tc-netem(8)) on-the-fly.\n"
" This mode only uses the mean and standard deviation of of the previous samples\n"
" to configure the netem qdisc. This can be used to interactively replicate a network link.\n"
"\n"
" dist generate Read measurement data from STDIN and write distribution file to STDOUT (see /usr/lib/tc/*.dist)\n"
" dist load Read measurement data from STDIN and configure Kernel (tc-netem(8))\n"
" These modes generate an inverse cumulated probability function (CDF) from the previously\n"
" recorded measurements. This iCDF can either be used by tc(8) or 'netem table'\n"
"\n"
" OPTIONS:\n\n"
" -m --mark N apply emulation only to packet buffers with mark N\n"
" -M --mask N an optional mask for the fw mark\n"
" -i --interval N update the emulation parameters every N seconds\n"
" -r --rate rate limit used for measurements and updates of network emulation\n"
" -l --limit how many probes should we sent\n"
" -d --dev network interface\n"
"\n"
"netem util %s (built on %s %s)\n"
" Copyright 2015, Steffen Vogel <post@steffenvogel.de>\n", argv[0], VERSION, __DATE__, __TIME__);
exit(EXIT_FAILURE);
}
char *cmd = argv[1];
}
/* Setup signals */
struct sigaction sa_quit = {
@ -121,11 +124,15 @@ check:
if (optarg == endptr)
error(-1, 0, "Failed to parse parse option argument '-%c %s'", c, optarg);
}
char *cmd = argv[1];
if (!strcmp(cmd, "probe"))
if (!strcmp(cmd, "probe"))
return probe(argc-optind-1, argv+optind+1);
else if (!strcmp(cmd, "emulate"))
else if (!strcmp(cmd, "live"))
return emulate(argc-optind-1, argv+optind+1);
else if (!strcmp(cmd, "dist"))
return dist(argc-optind-1, argv+optind+1);
else
error(-1, 0, "Unknown command: %s", cmd);