Author: luigi
Date: Mon Jun  8 14:32:29 2009
New Revision: 193715
URL: http://svn.freebsd.org/changeset/base/193715

Log:
  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

Modified:
  head/sbin/ipfw/dummynet.c
  head/sbin/ipfw/ipfw.8

Modified: head/sbin/ipfw/dummynet.c
==============================================================================
--- head/sbin/ipfw/dummynet.c   Mon Jun  8 13:34:45 2009        (r193714)
+++ head/sbin/ipfw/dummynet.c   Mon Jun  8 14:32:29 2009        (r193715)
@@ -452,6 +452,7 @@ ipfw_delete_pipe(int pipe_or_queue, int 
 #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, 
                            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;

Modified: head/sbin/ipfw/ipfw.8
==============================================================================
--- head/sbin/ipfw/ipfw.8       Mon Jun  8 13:34:45 2009        (r193714)
+++ head/sbin/ipfw/ipfw.8       Mon Jun  8 14:32:29 2009        (r193715)
@@ -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 samples Ar N
-the number of samples used in the internal
-representation (2..1024; default 100);
+.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.
+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;
+.It Cm samples Ar N
+the number of samples used in the internal
+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 d
 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.
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to