Permit the specification of bandwidth values within

"profile" files (bandwidth is mandatory when using a
profile, so it makes sense to have everything in one place).

Update the manpage accordingly.

Submitted by:	Marta Carbone
This commit is contained in:
Luigi Rizzo 2009-06-08 14:32:29 +00:00
parent ce3fa4d5cf
commit 7a459517da
2 changed files with 72 additions and 40 deletions

View File

@ -452,6 +452,7 @@ ipfw_delete_pipe(int pipe_or_queue, int i)
#define ED_TOK_NAME "name"
#define ED_TOK_DELAY "delay"
#define ED_TOK_PROB "prob"
#define ED_TOK_BW "bw"
#define ED_SEPARATORS " \t\n"
#define ED_MIN_SAMPLES_NO 2
@ -470,6 +471,50 @@ is_valid_number(const char *s)
return 1;
}
/*
* Take as input a string describing a bandwidth value
* and return the numeric bandwidth value.
* set clocking interface or bandwidth value
*/
void
read_bandwidth(char *arg, int *bandwidth, char *if_name, int namelen)
{
if (*bandwidth != -1)
warn("duplicate token, override bandwidth value!");
if (arg[0] >= 'a' && arg[0] <= 'z') {
if (namelen >= IFNAMSIZ)
warn("interface name truncated");
namelen--;
/* interface name */
strncpy(if_name, arg, namelen);
if_name[namelen] = '\0';
*bandwidth = 0;
} else { /* read bandwidth value */
int bw;
char *end = NULL;
bw = strtoul(arg, &end, 0);
if (*end == 'K' || *end == 'k') {
end++;
bw *= 1000;
} else if (*end == 'M') {
end++;
bw *= 1000000;
}
if ((*end == 'B' &&
_substrcmp2(end, "Bi", "Bit/s") != 0) ||
_substrcmp2(end, "by", "bytes") == 0)
bw *= 8;
if (bw < 0)
errx(EX_DATAERR, "bandwidth too large");
*bandwidth = bw;
if_name[0] = '\0';
}
}
struct point {
double prob;
double delay;
@ -550,6 +595,8 @@ load_extra_delays(const char *filename, struct dn_pipe *p)
errx(ED_EFMT("too many samples, maximum is %d"),
ED_MAX_SAMPLES_NO);
do_points = 0;
} else if (!strcasecmp(name, ED_TOK_BW)) {
read_bandwidth(arg, &p->bandwidth, p->if_name, sizeof(p->if_name));
} else if (!strcasecmp(name, ED_TOK_LOSS)) {
if (loss != -1.0)
errx(ED_EFMT("duplicated token: %s"), name);
@ -645,6 +692,7 @@ ipfw_config_pipe(int ac, char **av)
void *par = NULL;
memset(&p, 0, sizeof p);
p.bandwidth = -1;
av++; ac--;
/* Pipe number */
@ -848,32 +896,7 @@ ipfw_config_pipe(int ac, char **av)
NEED1("bw needs bandwidth or interface\n");
if (co.do_pipe != 1)
errx(EX_DATAERR, "bandwidth only valid for pipes");
/*
* set clocking interface or bandwidth value
*/
if (av[0][0] >= 'a' && av[0][0] <= 'z') {
int l = sizeof(p.if_name)-1;
/* interface name */
strncpy(p.if_name, av[0], l);
p.if_name[l] = '\0';
p.bandwidth = 0;
} else {
p.if_name[0] = '\0';
p.bandwidth = strtoul(av[0], &end, 0);
if (*end == 'K' || *end == 'k') {
end++;
p.bandwidth *= 1000;
} else if (*end == 'M') {
end++;
p.bandwidth *= 1000000;
}
if ((*end == 'B' &&
_substrcmp2(end, "Bi", "Bit/s") != 0) ||
_substrcmp2(end, "by", "bytes") == 0)
p.bandwidth *= 8;
if (p.bandwidth < 0)
errx(EX_DATAERR, "bandwidth too large");
}
read_bandwidth(av[0], &p.bandwidth, p.if_name, sizeof(p.if_name));
ac--; av++;
break;
@ -919,15 +942,20 @@ ipfw_config_pipe(int ac, char **av)
errx(EX_DATAERR, "pipe_nr must be > 0");
if (p.delay > 10000)
errx(EX_DATAERR, "delay must be < 10000");
if (p.samples_no > 0 && p.bandwidth == 0)
errx(EX_DATAERR,
"profile requires a bandwidth limit");
} else { /* co.do_pipe == 2, queue */
if (p.fs.parent_nr == 0)
errx(EX_DATAERR, "pipe must be > 0");
if (p.fs.weight >100)
errx(EX_DATAERR, "weight must be <= 100");
}
/* check for bandwidth value */
if (p.bandwidth == -1) {
p.bandwidth = 0;
if (p.samples_no > 0)
errx(EX_DATAERR, "profile requires a bandwidth limit");
}
if (p.fs.flags_fs & DN_QSIZE_IS_BYTES) {
size_t len;
long limit;

View File

@ -1973,22 +1973,26 @@ that represents its distribution.
The empirical curve may have both vertical and horizontal lines.
Vertical lines represent constant delay for a range of
probabilities.
Horizontal lines correspond to a discontinuty in the delay
Horizontal lines correspond to a discontinuity in the delay
distribution: the pipe will use the largest delay for a
given probability.
.Pp
The file format is the following, with whitespace acting as
a separator and '#' indicating the beginning a comment:
.Bl -tag -width indent
.It Cm name Ar identifier
optional name (listed by "ipfw pipe show")
to identify the delay distribution;
.It Cm bw Ar value
the bandwidth used for the pipe.
If not specified here, it must be present
explicitly as a configuration parameter for the pipe;
.It Cm loss-level Ar L
the probability above which packets are lost.
(0.0 <= L <= 1.0, default 1.0 i.e. no loss);
.It Cm samples Ar N
the number of samples used in the internal
representation (2..1024; default 100);
.It Cm loss-level Ar L
The probability above which packets are lost.
(0.0 <= L <= 1.0, default 1.0 i.e. no loss);
.It Cm name Ar identifier
Optional a name (listed by "ipfw pipe show")
to identify the distribution;
representation of the curve (2..1024; default 100);
.It Cm "delay prob" | "prob delay"
One of these two lines is mandatory and defines
the format of the following lines with data points.
@ -1997,9 +2001,9 @@ the format of the following lines with data points.
with either delay or probability first, according
to the chosen format.
The unit for delay is milliseconds.
Data points do not need to be ordered or equal to the number
specified in the "samples" line.
The
Data points do not need to be sorted.
Also, tne number of actual lines can be different
from the value of the "samples" parameter:
.Nm
utility will sort and interpolate
the curve as needed.