lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 27 Nov 2007 00:50:51 +0900 (JST)
From:	Ryousei Takano <takano-ryousei@...t.go.jp>
To:	netdev@...r.kernel.org
Cc:	shemminger@...ux-foundation.org, kaber@...sh.net,
	dada1@...mosbay.com, t.kudoh@...t.go.jp
Subject: [PATCHv2 2/3] TC: PSPacer qdisc module

This patch includes the PSPacer (Precise Software Pacer) qdisc
tc part, which achieves precise transmission bandwidth control.
You can find more information at the project web page
(http://www.gridmpi.org/gridtcp.jsp).

Signed-off-by: Ryousei Takano <takano-ryousei@...t.go.jp>
---
 include/linux/pkt_sched.h |   38 +++++++++
 tc/Makefile               |    1 +
 tc/q_psp.c                |  199 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 238 insertions(+), 0 deletions(-)
 create mode 100644 tc/q_psp.c

diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 268c515..c708082 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -430,6 +430,44 @@ enum {
 
 #define TCA_ATM_MAX	(__TCA_ATM_MAX - 1)
 
+/* Precise Software Pacer section */
+
+#define TC_PSP_MAXDEPTH (8)
+
+typedef long long gapclock_t;
+
+enum {
+	MODE_NORMAL = 0,
+	MODE_STATIC = 1,
+};
+
+struct tc_psp_copt
+{
+	__u32	level;
+	__u32	mode;
+	__u32	rate;
+};
+
+struct tc_psp_qopt
+{
+	__u32	defcls;
+	__u32	rate;
+	__u32	direct_pkts;
+};
+
+struct tc_psp_xstats
+{
+	__u32	bytes;		/* gap packet statistics */
+	__u32	packets;
+};
+
+enum
+{
+	TCA_PSP_UNSPEC,
+	TCA_PSP_COPT,
+	TCA_PSP_QOPT,
+};
+
 /* Network emulator */
 
 enum
diff --git a/tc/Makefile b/tc/Makefile
index a715566..836df9d 100644
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -12,6 +12,7 @@ TCMODULES += q_prio.o
 TCMODULES += q_tbf.o
 TCMODULES += q_cbq.o
 TCMODULES += q_rr.o
+TCMODULES += q_psp.o
 TCMODULES += q_netem.o
 TCMODULES += f_rsvp.o
 TCMODULES += f_u32.o
diff --git a/tc/q_psp.c b/tc/q_psp.c
new file mode 100644
index 0000000..1806b66
--- /dev/null
+++ b/tc/q_psp.c
@@ -0,0 +1,199 @@
+/*
+ * q_psp.c		PSPacer: Precise Software Pacer
+ *
+ *		Copyright (C) 2004-2007 National Institute of Advanced
+ *		Industrial Science and Technology (AIST), Japan.
+ *
+ *		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:	Ryousei Takano, <takano-ryousei@...t.go.jp>
+ *
+ */
+
+#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: ... qdisc add ... psp [ default N ] [rate RATE]\n"
+" default  minor id of class to which unclassified packets are sent {0}\n"
+" rate     physical interface bandwidth\n\n"
+"... class add ... psp mode M [ rate MBPS ]\n"
+" mode     target rate estimation method (NORMAL=0 STATIC=1) {0}\n"
+" rate     rate allocated to this class\n");
+}
+
+static void explain1(char *arg)
+{
+	fprintf(stderr, "Illegal \"%s\"\n", arg);
+	explain();
+}
+
+
+static int psp_parse_opt(struct qdisc_util *qu, int argc, char **argv,
+			 struct nlmsghdr *n)
+{
+	struct tc_psp_qopt qopt;
+	struct rtattr *tail;
+	memset(&qopt, 0, sizeof(qopt));
+
+	while (argc > 0) {
+		if (matches(*argv, "rate") == 0) {
+			NEXT_ARG();
+			if (get_rate(&qopt.rate, *argv)) {
+				explain1("rate");
+				return -1;
+			}
+		} else if (matches(*argv, "default") == 0) {
+			NEXT_ARG();
+			if (get_u32(&qopt.defcls, *argv, 16)) {
+				explain1("default");
+				return -1;
+			}
+		} else if (matches(*argv, "help") == 0) {
+			explain();
+			return -1;
+		} else {
+			fprintf(stderr, "What is \"%s\"?\n", *argv);
+			explain();
+			return -1;
+		}
+		argc--;
+		argv++;
+	}
+
+	tail = NLMSG_TAIL(n);
+	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
+	addattr_l(n, 2024, TCA_OPTIONS, &qopt, NLMSG_ALIGN(sizeof(qopt)));
+	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
+	return 0;
+}
+
+static int psp_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
+{
+	struct rtattr *tb[TCA_PSP_QOPT+1];
+	struct tc_psp_copt *copt;
+	struct tc_psp_qopt *qopt;
+	SPRINT_BUF(b);
+
+	if (opt == NULL)
+		return 0;
+
+	memset(tb, 0, sizeof(tb));
+	parse_rtattr_nested(tb, TCA_PSP_QOPT, opt);
+
+	if (tb[TCA_PSP_COPT]) {
+		copt = RTA_DATA(tb[TCA_PSP_COPT]);
+		if (RTA_PAYLOAD(tb[TCA_PSP_COPT]) < sizeof(*copt))
+			return -1;
+		fprintf(f, "level %d ", (int)copt->level);
+		switch (copt->mode) {
+		case MODE_NORMAL:
+			fprintf(f, "mode NORMAL ");
+			break;
+		case MODE_STATIC:
+			fprintf(f, "mode STATIC (%s) ",
+				sprint_rate(copt->rate, b));
+			break;
+		}
+	}
+	if (tb[TCA_PSP_QOPT]) {
+		qopt = RTA_DATA(tb[TCA_PSP_QOPT]);
+		if (RTA_PAYLOAD(tb[TCA_PSP_QOPT])  < sizeof(*qopt))
+			return -1;
+		fprintf(f, "default %x max rate %s",
+			qopt->defcls, sprint_rate(qopt->rate, b));
+	}
+	return 0;
+}
+
+static int psp_print_xstats(struct qdisc_util *qu, FILE *f,
+			    struct rtattr *xstats)
+{
+	struct tc_psp_xstats *st;
+	if (xstats == NULL)
+		return 0;
+
+	if (RTA_PAYLOAD(xstats) < sizeof(*st))
+		return -1;
+
+	st = RTA_DATA(xstats);
+	fprintf(f, "  gap %u bytes %u pkts", st->bytes, st->packets);
+	return 0;
+}
+
+static int psp_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
+			       struct nlmsghdr *n)
+{
+	struct tc_psp_copt copt;
+	struct rtattr *tail;
+
+	memset(&copt, 0, sizeof(copt));
+	copt.mode = MODE_STATIC; /* default mode */
+
+	while (argc > 0) {
+		if (matches(*argv, "rate") == 0) {
+			NEXT_ARG();
+			if (get_rate(&copt.rate, *argv)) {
+				explain1("rate");
+				return -1;
+			}
+		} else if (matches(*argv, "mode") == 0) {
+			NEXT_ARG();
+			if (get_u32(&copt.mode, *argv, 10)) {
+				explain1("mode");
+				return -1;
+			}
+		} else if (matches(*argv, "help") == 0) {
+			explain();
+			return -1;
+		} else {
+			fprintf(stderr, "What is \"%s\"?\n", *argv);
+			explain();
+			return -1;
+		}
+		argc--; argv++;
+	}
+
+	if (copt.mode == MODE_NORMAL && copt.rate != 0) {
+		fprintf(stderr, "You can not set to \"rate\" parameter "
+			"in normal mode\n");
+		explain1("rate");
+		return -1;
+	} else if (copt.mode == MODE_STATIC && copt.rate == 0) {
+		fprintf(stderr, "You need set to \"rate\" parameter "
+			"in static target rate mode.\n");
+		explain1("rate");
+		return -1;
+	}
+
+	tail = NLMSG_TAIL(n);
+	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
+	addattr_l(n, 2024, TCA_PSP_COPT, &copt, sizeof(copt));
+	tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail;
+	return 0;
+}
+
+struct qdisc_util psp_qdisc_util = {
+	.id		= "psp",
+	.parse_qopt	= psp_parse_opt,
+	.print_qopt	= psp_print_opt,
+	.print_xstats	= psp_print_xstats,
+	.parse_copt	= psp_parse_class_opt,
+	.print_copt	= psp_print_opt
+};
+
-- 
1.5.3.4

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists