summaryrefslogtreecommitdiffstats
path: root/sbin/ipfw/dummynet.c
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2009-06-08 14:32:29 +0000
committerluigi <luigi@FreeBSD.org>2009-06-08 14:32:29 +0000
commitbf5db0adae861610024694b3fc7c339e0f2cd621 (patch)
tree840b2805e4318857276c020c7f0604c97f1f151a /sbin/ipfw/dummynet.c
parent66aa1d7eeb5ce07985741f334e7e121ee058c568 (diff)
downloadFreeBSD-src-bf5db0adae861610024694b3fc7c339e0f2cd621.zip
FreeBSD-src-bf5db0adae861610024694b3fc7c339e0f2cd621.tar.gz
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
Diffstat (limited to 'sbin/ipfw/dummynet.c')
-rw-r--r--sbin/ipfw/dummynet.c86
1 files changed, 57 insertions, 29 deletions
diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c
index 5e86df6..9e8356e 100644
--- a/sbin/ipfw/dummynet.c
+++ b/sbin/ipfw/dummynet.c
@@ -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 @@ end_mask:
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 @@ end_mask:
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;
OpenPOWER on IntegriCloud