Commit d69151f9 authored by David Johnson's avatar David Johnson

This is the port of Kirk's (and others) linux endnodeshaping patches from

2.4 to 2.6.  PLR and delays (the two schedulers we need) seem to be working
nicely, but need more testing.  Note that the iptables patch isn't tested yet,
but it's the right one to apply...  There is still a locking bug in the PLR
sched, but it only affects stats dumping so we don't care at the moment.

The two imq patches are from the linux imq project, like the old ones.
parent 97d5918d
--- iptables-1.3.6.orig/extensions.orig/.IMQ-test6 Thu Jan 1 01:00:00 1970
+++ iptables-1.3.6/extensions/.IMQ-test6 Mon Jun 16 10:12:47 2003
@@ -0,0 +1,3 @@
+#!/bin/sh
+# True if IMQ target patch is applied.
+[ -f $KERNEL_DIR/net/ipv6/netfilter/ip6t_IMQ.c ] && echo IMQ
--- iptables-1.3.6.orig/extensions.orig/libip6t_IMQ.c Thu Jan 1 01:00:00 1970
+++ iptables-1.3.6/extensions/libip6t_IMQ.c Mon Jun 16 10:12:47 2003
@@ -0,0 +1,101 @@
+/* Shared library add-on to iptables to add IMQ target support. */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <ip6tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_IMQ.h>
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+ printf(
+"IMQ target v%s options:\n"
+" --todev <N> enqueue to imq<N>, defaults to 0\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+ { "todev", 1, 0, '1' },
+ { 0 }
+};
+
+/* Initialize the target. */
+static void
+init(struct ip6t_entry_target *t, unsigned int *nfcache)
+{
+ struct ip6t_imq_info *mr = (struct ip6t_imq_info*)t->data;
+
+ mr->todev = 0;
+ *nfcache |= NFC_UNKNOWN;
+}
+
+/* Function which parses command options; returns true if it
+ ate an option */
+static int
+parse(int c, char **argv, int invert, unsigned int *flags,
+ const struct ip6t_entry *entry,
+ struct ip6t_entry_target **target)
+{
+ struct ip6t_imq_info *mr = (struct ip6t_imq_info*)(*target)->data;
+
+ switch(c) {
+ case '1':
+ if (check_inverse(optarg, &invert, NULL, 0))
+ exit_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --todev");
+ mr->todev=atoi(optarg);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+static void
+final_check(unsigned int flags)
+{
+}
+
+/* Prints out the targinfo. */
+static void
+print(const struct ip6t_ip6 *ip,
+ const struct ip6t_entry_target *target,
+ int numeric)
+{
+ struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data;
+
+ printf("IMQ: todev %u ", mr->todev);
+}
+
+/* Saves the union ipt_targinfo in parsable form to stdout. */
+static void
+save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target)
+{
+ struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data;
+
+ printf("--todev %u", mr->todev);
+}
+
+static struct ip6tables_target imq = {
+ .next = NULL,
+ .name = "IMQ",
+ .version = IPTABLES_VERSION,
+ .size = IP6T_ALIGN(sizeof(struct ip6t_imq_info)),
+ .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_imq_info)),
+ .help = &help,
+ .init = &init,
+ .parse = &parse,
+ .final_check = &final_check,
+ .print = &print,
+ .save = &save,
+ .extra_opts = opts
+};
+
+static __attribute__((constructor)) void _init(void)
+{
+ register_target6(&imq);
+}
--- iptables-1.3.6.orig/extensions.orig/.IMQ-test Thu Jan 1 01:00:00 1970
+++ iptables-1.3.6/extensions/.IMQ-test Mon Jun 16 10:12:47 2003
@@ -0,0 +1,3 @@
+#!/bin/sh
+# True if IMQ target patch is applied.
+[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_IMQ.c ] && echo IMQ
--- iptables-1.3.6.orig/extensions.orig/libipt_IMQ.c Thu Jan 1 01:00:00 1970
+++ iptables-1.3.6/extensions/libipt_IMQ.c Mon Jun 16 10:12:47 2003
@@ -0,0 +1,101 @@
+/* Shared library add-on to iptables to add IMQ target support. */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_IMQ.h>
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+ printf(
+"IMQ target v%s options:\n"
+" --todev <N> enqueue to imq<N>, defaults to 0\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+ { "todev", 1, 0, '1' },
+ { 0 }
+};
+
+/* Initialize the target. */
+static void
+init(struct ipt_entry_target *t, unsigned int *nfcache)
+{
+ struct ipt_imq_info *mr = (struct ipt_imq_info*)t->data;
+
+ mr->todev = 0;
+ *nfcache |= NFC_UNKNOWN;
+}
+
+/* Function which parses command options; returns true if it
+ ate an option */
+static int
+parse(int c, char **argv, int invert, unsigned int *flags,
+ const struct ipt_entry *entry,
+ struct ipt_entry_target **target)
+{
+ struct ipt_imq_info *mr = (struct ipt_imq_info*)(*target)->data;
+
+ switch(c) {
+ case '1':
+ if (check_inverse(optarg, &invert, NULL, 0))
+ exit_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --todev");
+ mr->todev=atoi(optarg);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+static void
+final_check(unsigned int flags)
+{
+}
+
+/* Prints out the targinfo. */
+static void
+print(const struct ipt_ip *ip,
+ const struct ipt_entry_target *target,
+ int numeric)
+{
+ struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data;
+
+ printf("IMQ: todev %u ", mr->todev);
+}
+
+/* Saves the union ipt_targinfo in parsable form to stdout. */
+static void
+save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+{
+ struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data;
+
+ printf("--todev %u", mr->todev);
+}
+
+static struct iptables_target imq = {
+ .next = NULL,
+ .name = "IMQ",
+ .version = IPTABLES_VERSION,
+ .size = IPT_ALIGN(sizeof(struct ipt_imq_info)),
+ .userspacesize = IPT_ALIGN(sizeof(struct ipt_imq_info)),
+ .help = &help,
+ .init = &init,
+ .parse = &parse,
+ .final_check = &final_check,
+ .print = &print,
+ .save = &save,
+ .extra_opts = opts
+};
+
+static __attribute__((constructor)) void _init(void)
+{
+ register_target(&imq);
+}
diff -urN iproute-2.6.20-070313/Config iproute-2.6.20-070313-emulab/Config
--- iproute-2.6.20-070313/Config 2007-09-24 20:43:43.000000000 -0600
+++ iproute-2.6.20-070313-emulab/Config 2007-09-24 21:30:11.000000000 -0600
@@ -1 +1 @@
-# Generated config based on /usr/src/iproute-2.6.20-070313/include
+# Generated config based on /usr/src/linux-2.6.20-1.2944.fc6.emulab-1/include
diff -urN iproute-2.6.20-070313/Makefile iproute-2.6.20-070313-emulab/Makefile
--- iproute-2.6.20-070313/Makefile 2007-03-13 15:50:56.000000000 -0600
+++ iproute-2.6.20-070313-emulab/Makefile 2007-08-09 14:55:52.000000000 -0600
@@ -1,7 +1,8 @@
+KERNEL_INCLUDE=/usr/src/linux-2.6.20-1.2944.fc6.emulab-1/include
DESTDIR=
-SBINDIR=/usr/sbin
-CONFDIR=/etc/iproute2
-DOCDIR=/usr/share/doc/iproute2
+SBINDIR=/usr/local/sbin
+CONFDIR=/usr/local/etc/iproute2
+DOCDIR=/usr/local/share/doc/iproute2
MANDIR=/usr/share/man
# Path to db_185.h include
diff -urN iproute-2.6.20-070313/include/linux/pkt_sched.h iproute-2.6.20-070313-emulab/include/linux/pkt_sched.h
--- iproute-2.6.20-070313/include/linux/pkt_sched.h 2007-03-13 15:50:56.000000000 -0600
+++ iproute-2.6.20-070313-emulab/include/linux/pkt_sched.h 2007-08-09 15:50:25.000000000 -0600
@@ -90,6 +90,21 @@
__u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */
};
+/* PLR section */
+
+struct tc_plr_qopt
+{
+ __u32 plr; /* % drop rate (0-100) */
+};
+
+/* DELAY section */
+
+struct tc_delay_qopt
+{
+ __u32 delay_usec; /* # of usecs to delay */
+ __u8 reset_time; /* flag: reset time on dequeue, or not */
+};
+
/* PRIO section */
#define TCQ_PRIO_BANDS 16
diff -urN iproute-2.6.20-070313/tc/Makefile iproute-2.6.20-070313-emulab/tc/Makefile
--- iproute-2.6.20-070313/tc/Makefile 2007-03-13 15:50:56.000000000 -0600
+++ iproute-2.6.20-070313-emulab/tc/Makefile 2007-08-09 14:37:43.000000000 -0600
@@ -16,6 +16,8 @@
TCMODULES += f_route.o
TCMODULES += f_fw.o
TCMODULES += f_basic.o
+TCMODULES += q_delay.o
+TCMODULES += q_plr.o
TCMODULES += q_dsmark.o
TCMODULES += q_gred.o
TCMODULES += f_tcindex.o
diff -urN iproute-2.6.20-070313/tc/q_delay.c iproute-2.6.20-070313-emulab/tc/q_delay.c
--- iproute-2.6.20-070313/tc/q_delay.c 1969-12-31 17:00:00.000000000 -0700
+++ iproute-2.6.20-070313-emulab/tc/q_delay.c 2007-09-24 21:27:29.000000000 -0600
@@ -0,0 +1,131 @@
+/*
+ * q_delay.c Delay.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: David T. McWherter, <dtm@vramp.net>
+ * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include "utils.h"
+#include "tc_util.h"
+
+static void explain(void)
+{
+ fprintf(stderr, "Usage: ... delay <microseconds> [reset_time (0|1)]\n");
+}
+
+static void explain1(char *arg)
+{
+ fprintf(stderr, "Illegal \"%s\"\n", arg);
+}
+
+
+#define usage() return(-1)
+
+static int
+delay_parse_opt
+ (struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
+{
+ struct tc_delay_qopt opt;
+ char *end;
+
+ memset(&opt, 0, sizeof(opt));
+
+ if ( argc > 4 ) {
+ fprintf(stderr, "Too many arguments (seen: %d, expected: 2 or 4)\n",
+ argc);
+ return -1;
+ } else if ( argc < 2 ) {
+ fprintf(stderr, "Too few arguments (seen: %d, expected: 2 or 4)\n",
+ argc);
+ return -1;
+ } else {
+
+ while ( argc > 0 ) {
+ if (!strcmp(*argv, "usecs")) {
+ NEXT_ARG();
+ opt.delay_usec = strtoul(*argv,&end,0);
+ if (*end) {
+ explain1("microseconds");
+ return -1;
+ }
+ fprintf( stdout, "Usecs: %u\n", opt.delay_usec );
+ }
+ else if (!strcmp(*argv, "reset_time")) {
+ NEXT_ARG();
+ opt.reset_time = strtoul(*argv,&end,0);
+ if (*end) {
+ explain1("reset_time");
+ return -1;
+ }
+ fprintf( stdout, "reset_time: %u\n", opt.reset_time );
+ }
+ argc--;
+ argv++;
+ }
+ }
+
+ addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));
+
+ return 0;
+}
+
+static int
+delay_print_opt
+ (struct qdisc_util *qu, FILE *f, struct rtattr *opt)
+{
+ struct tc_delay_qopt *qopt;
+
+ if (opt == NULL)
+ return 0;
+
+ if ( RTA_PAYLOAD(opt) < sizeof(*qopt))
+ return -1;
+
+ qopt = RTA_DATA(opt);
+ fprintf( f, "delay { %u } reset_time { %u }",
+ qopt->delay_usec,
+ qopt->reset_time
+ );
+
+ return 0;
+}
+
+
+static int delay_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats)
+{
+ return 0;
+}
+
+
+static int
+delay_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
+ struct nlmsghdr *n)
+{
+ return 0;
+}
+
+
+struct qdisc_util delay_qdisc_util = {
+ .id = "delay",
+ .parse_qopt = delay_parse_opt,
+ .print_qopt = delay_print_opt,
+ .print_xstats = delay_print_xstats,
+
+ .parse_copt = delay_parse_class_opt,
+ .print_copt = delay_print_opt,
+};
diff -urN iproute-2.6.20-070313/tc/q_plr.c iproute-2.6.20-070313-emulab/tc/q_plr.c
--- iproute-2.6.20-070313/tc/q_plr.c 1969-12-31 17:00:00.000000000 -0700
+++ iproute-2.6.20-070313-emulab/tc/q_plr.c 2007-09-24 21:29:18.000000000 -0600
@@ -0,0 +1,115 @@
+/*
+ * q_plr.c packet loss qdisc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Kirk Webb, <kwebb@cs.utah.edu>
+ * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include "utils.h"
+#include "tc_util.h"
+
+static void explain(void)
+{
+ fprintf(stderr, "Usage: ... plr <rate (%% loss: 0-100)>\n");
+}
+
+static void explain1(char *arg)
+{
+ fprintf(stderr, "Illegal \"%s\"\n", arg);
+}
+
+
+#define usage() return(-1)
+
+static int
+plr_parse_opt
+ (struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
+{
+ struct tc_plr_qopt opt;
+ double plr_rate = 0;
+ char *p;
+
+ memset(&opt, 0, sizeof(opt));
+
+ if ( argc > 1 ) {
+ fprintf(stderr, "Too many arguments (seen: %d, expected: %d)\n",
+ argc, 1);
+ return -1;
+ } else if ( argc < 1 ) {
+ fprintf(stderr, "Too few arguments (seen: %d, expected: %d)\n",
+ argc, 1);
+ return -1;
+ } else if ( argc == 1 ) {
+ plr_rate = strtod(*argv, &p);
+ if (p == *argv || plr_rate < 0 || plr_rate > 1) {
+ explain1("fraction (range 0-1)");
+ return -1;
+ }
+ }
+
+ opt.plr = (unsigned int)(plr_rate*0xffffffffUL);
+ fprintf( stdout, "PLR: %u\n", opt.plr );
+
+ addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));
+
+ return 0;
+}
+
+static int
+plr_print_opt
+ (struct qdisc_util *qu, FILE *f, struct rtattr *opt)
+{
+ struct tc_plr_qopt *qopt;
+
+ if (opt == NULL)
+ return 0;
+
+ if ( RTA_PAYLOAD(opt) < sizeof(*qopt))
+ return -1;
+
+ qopt = RTA_DATA(opt);
+ fprintf( f, "PLR: %f",
+ qopt->plr / (double) 0xffffffff
+ );
+
+ return 0;
+}
+
+static int plr_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats)
+{
+ return 0;
+}
+
+static int
+plr_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
+ struct nlmsghdr *n)
+{
+ return 0;
+}
+
+
+
+struct qdisc_util plr_qdisc_util = {
+ .id = "plr",
+ .parse_qopt = plr_parse_opt,
+ .print_qopt = plr_print_opt,
+ .print_xstats = plr_print_xstats,
+
+ .parse_copt = plr_parse_class_opt,
+ .print_copt = plr_print_opt,
+};
diff -urN iproute-2.6.20-070313/tc/tc_qdisc.c iproute-2.6.20-070313-emulab/tc/tc_qdisc.c
--- iproute-2.6.20-070313/tc/tc_qdisc.c 2007-03-13 15:50:56.000000000 -0600
+++ iproute-2.6.20-070313-emulab/tc/tc_qdisc.c 2007-08-09 14:42:02.000000000 -0600
@@ -36,7 +36,7 @@
fprintf(stderr, "\n");
fprintf(stderr, " tc qdisc show [ dev STRING ] [ingress]\n");
fprintf(stderr, "Where:\n");
- fprintf(stderr, "QDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. }\n");
+ fprintf(stderr, "QDISC_KIND := { [p|b]fifo | delay | plr | tbf | prio | cbq | red | etc. }\n");
fprintf(stderr, "OPTIONS := ... try tc qdisc add <desired QDISC_KIND> help\n");
return -1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment