All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
To: Patrick McHardy <kaber@trash.net>
Cc: netdev@vger.kernel.org
Subject: [PATCH v4 2/2] [iproute2/tc] hfsc: add link layer overhead adaption
Date: Thu, 10 Jul 2008 22:34:54 +0300	[thread overview]
Message-ID: <20080710193454.19601.97736.stgit@fate.lan> (raw)
In-Reply-To: <20080710193448.19601.673.stgit@fate.lan>

Patch adds 'mpu', 'mtu', 'overhead' and 'linklayer' options to hfsc. These
options are used to create size table for sch_hfsc. Size table is only used
and passed to kernel if these options are used.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---

 include/linux/pkt_sched.h |    5 +
 tc/q_hfsc.c               |  155 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 155 insertions(+), 5 deletions(-)

diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 5bf1444..46db55d 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -303,6 +303,9 @@ struct tc_htb_xstats
 struct tc_hfsc_qopt
 {
 	__u16	defcls;		/* default class */
+	__u16	__reserved;
+	struct tc_sizespec szopts;
+	__u16	stab[512];
 };
 
 struct tc_service_curve
@@ -326,6 +329,8 @@ enum
 	TCA_HFSC_RSC,
 	TCA_HFSC_FSC,
 	TCA_HFSC_USC,
+	TCA_HFSC_SZOPTS,
+	TCA_HFSC_STAB,
 	__TCA_HFSC_MAX,
 };
 
diff --git a/tc/q_hfsc.c b/tc/q_hfsc.c
index b190c71..e8bff6e 100644
--- a/tc/q_hfsc.c
+++ b/tc/q_hfsc.c
@@ -12,6 +12,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stddef.h>
 #include <unistd.h>
 #include <syslog.h>
 #include <fcntl.h>
@@ -24,6 +25,9 @@
 #include "utils.h"
 #include "tc_util.h"
 
+#define endof(type, member) \
+	(offsetof(type, member) + sizeof(((type *)0)->member))
+
 static int hfsc_get_sc(int *, char ***, struct tc_service_curve *);
 
 
@@ -31,7 +35,13 @@ static void
 explain_qdisc(void)
 {
 	fprintf(stderr,
-		"Usage: ... hfsc [ default CLASSID ]\n"
+		"Usage: ... hfsc [ default CLASSID ] [ mtu BYTES] [ mpu BYTES ]\n"
+		"                [ overhead BYTES ] [ linklayer TYPE ]\n"
+		"\n"
+		" mtu       : max packet size we create rate map for {2047}\n"
+		" mpu       : minimum packet size used in rate computations\n"
+		" overhead  : per-packet size overhead used in rate computations\n"
+		" linklayer : adapting to a linklayer e.g. atm\n"
 		"\n"
 		" default: default class for unclassified packets\n"
 	);
@@ -42,6 +52,13 @@ explain_class(void)
 {
 	fprintf(stderr,
 		"Usage: ... hfsc [ [ rt SC ] [ ls SC ] | [ sc SC ] ] [ ul SC ]\n"
+		"                [ mtu BYTES] [ mpu BYTES ] [ overhead BYTES ]\n"
+		"                [ linklayer TYPE ]\n"
+		"\n"
+		" mtu       : max packet size we create rate map for {2047}\n"
+		" mpu       : minimum packet size used in rate computations\n"
+		" overhead  : per-packet size overhead used in rate computations\n"
+		" linklayer : adapting to a linklayer e.g. atm\n"
 		"\n"
 		"SC := [ [ m1 BPS ] [ d SEC ] m2 BPS\n"
 		"\n"
@@ -67,14 +84,86 @@ explain1(char *arg)
 }
 
 static int
+hfsc_parse_stab(int *argcp, char ***argvp, unsigned *mtup,
+		unsigned int *linklayerp, short *overheadp,
+		unsigned short *mpup)
+{
+	char **argv = *argvp;
+	int argc = *argcp;
+	int next = 0;
+
+	if (matches(*argv, "mtu") == 0) {
+		NEXT_ARG();
+		if (get_u32(mtup, *argv, 10)) {
+			explain1("mtu");
+			return -1;
+		}
+	} else if (matches(*argv, "mpu") == 0) {
+		NEXT_ARG();
+		if (get_u16(mpup, *argv, 10)) {
+			explain1("mpu");
+			return -1;
+		}
+	} else if (matches(*argv, "overhead") == 0) {
+		NEXT_ARG();
+		if (get_s16(overheadp, *argv, 10)) {
+			explain1("overhead");
+			return -1;
+		}
+	} else if (matches(*argv, "linklayer") == 0) {
+		NEXT_ARG();
+		if (get_linklayer(linklayerp, *argv)) {
+			explain1("linklayer");
+			return -1;
+		}
+	} else {
+		next = 1;
+	}
+
+	*argvp = argv;
+	*argcp = argc;
+	return next;
+}
+
+static int
+hfsc_create_stab(struct tc_sizespec *szoptsp, __u16 *stabp, unsigned mtu,
+			unsigned int linklayer, short overhead,
+			unsigned short mpu)
+{
+	/* Only use stab when needed, mtu only defines stab properties so
+	 * it is not checked here. */
+	if (linklayer != LINKLAYER_ETHERNET || mpu != 0 || overhead != 0) {
+		szoptsp->mpu = mpu;
+		szoptsp->overhead = overhead;
+		if (tc_calc_stable(szoptsp, stabp, -1, mtu, linklayer) < 0) {
+			fprintf(stderr, "HFSC: failed to calculate size table.\n");
+			return -1;
+		}
+		return 1;
+	}
+	return 0;
+}
+
+static int
 hfsc_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
 {
 	struct tc_hfsc_qopt qopt;
+	unsigned qopt_len;
+	unsigned mtu = 0;
+	unsigned int linklayer = LINKLAYER_ETHERNET; /* Assume ethernet */
+	short overhead = 0;
+	unsigned short mpu = 0;
+	int use_stab, next;
 
 	memset(&qopt, 0, sizeof(qopt));
 
 	while (argc > 0) {
-		if (matches(*argv, "default") == 0) {
+		next = hfsc_parse_stab(&argc, &argv, &mtu, &linklayer,
+					&overhead, &mpu);
+		if (next != 1) {
+			if (next < 0)
+				return next;
+		} else if (matches(*argv, "default") == 0) {
 			NEXT_ARG();
 			if (qopt.defcls != 0) {
 				fprintf(stderr, "HFSC: Double \"default\"\n");
@@ -95,7 +184,15 @@ hfsc_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
 		argc--, argv++;
 	}
 
-	addattr_l(n, 1024, TCA_OPTIONS, &qopt, sizeof(qopt));
+	use_stab = hfsc_create_stab(&qopt.szopts, qopt.stab, mtu, linklayer,
+				overhead, mpu);
+	if (use_stab < 0)
+		return use_stab;
+	qopt_len = (use_stab > 0) ? endof(struct tc_hfsc_qopt, stab) :
+					endof(struct tc_hfsc_qopt, defcls);
+
+	addattr_l(n, 2024, TCA_OPTIONS, &qopt, qopt_len);
+
 	return 0;
 }
 
@@ -103,16 +200,27 @@ static int
 hfsc_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
 {
 	struct tc_hfsc_qopt *qopt;
+	SPRINT_BUF(b1);
 
 	if (opt == NULL)
 		return 0;
-	if (RTA_PAYLOAD(opt) < sizeof(*qopt))
+	if (RTA_PAYLOAD(opt) < endof(struct tc_hfsc_qopt, defcls))
 		return -1;
 	qopt = RTA_DATA(opt);
 
 	if (qopt->defcls != 0)
 		fprintf(f, "default %x ", qopt->defcls);
 
+	if (show_details && RTA_PAYLOAD(opt) >=
+					endof(struct tc_hfsc_qopt, szopts)) {
+		if (qopt->szopts.mpu)
+			fprintf(f, "mpu %s ",
+				sprint_size(qopt->szopts.mpu, b1));
+		if (qopt->szopts.overhead)
+			fprintf(f, "overhead %s ",
+				sprint_size(qopt->szopts.overhead, b1));
+	}
+
 	return 0;
 }
 
@@ -145,14 +253,28 @@ hfsc_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
 	struct tc_service_curve rsc, fsc, usc;
 	int rsc_ok, fsc_ok, usc_ok;
 	struct rtattr *tail;
+	struct tc_sizespec szopts;
+	__u16 stab[512];
+	int use_stab, next;
+	unsigned mtu = 0;
+	unsigned int linklayer = LINKLAYER_ETHERNET; /* Assume ethernet */
+	short overhead = 0;
+	unsigned short mpu = 0;
 
 	memset(&rsc, 0, sizeof(rsc));
 	memset(&fsc, 0, sizeof(fsc));
 	memset(&usc, 0, sizeof(usc));
+	memset(&szopts, 0, sizeof(szopts));
+	memset(stab, 0, TCA_HFSC_STAB);
 	rsc_ok = fsc_ok = usc_ok = 0;
 
 	while (argc > 0) {
-		if (matches(*argv, "rt") == 0) {
+		next = hfsc_parse_stab(&argc, &argv, &mtu, &linklayer,
+					&overhead, &mpu);
+		if (next != 1) {
+			if (next < 0)
+				return next;
+		} else if (matches(*argv, "rt") == 0) {
 			NEXT_ARG();
 			if (hfsc_get_sc(&argc, &argv, &rsc) < 0) {
 				explain1("rt");
@@ -205,6 +327,10 @@ hfsc_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
 		return -1;
 	}
 
+	use_stab = hfsc_create_stab(&szopts, stab, mtu, linklayer, overhead, mpu);
+	if (use_stab < 0)
+		return use_stab;
+
 	tail = NLMSG_TAIL(n);
 
 	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
@@ -214,6 +340,10 @@ hfsc_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
 		addattr_l(n, 1024, TCA_HFSC_FSC, &fsc, sizeof(fsc));
 	if (usc_ok)
 		addattr_l(n, 1024, TCA_HFSC_USC, &usc, sizeof(usc));
+	if (use_stab) {
+		addattr_l(n, 2024, TCA_HFSC_SZOPTS, &szopts, sizeof(szopts));
+		addattr_l(n, 3024, TCA_HFSC_STAB, stab, TC_STAB_SIZE);
+	}
 
 	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
 	return 0;
@@ -235,6 +365,8 @@ hfsc_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
 {
 	struct rtattr *tb[TCA_HFSC_MAX+1];
 	struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL;
+	struct tc_sizespec *szopts = NULL;
+	SPRINT_BUF(b1);
 
 	if (opt == NULL)
 		return 0;
@@ -259,6 +391,12 @@ hfsc_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
 		else
 			usc = RTA_DATA(tb[TCA_HFSC_USC]);
 	}
+	if (tb[TCA_HFSC_SZOPTS]) {
+		if (RTA_PAYLOAD(tb[TCA_HFSC_SZOPTS]) < sizeof(*szopts))
+			fprintf(stderr, "HFSC: truncated rate options\n");
+		else
+			szopts = RTA_DATA(tb[TCA_HFSC_SZOPTS]);
+	}
 
 
 	if (rsc != NULL && fsc != NULL &&
@@ -273,6 +411,13 @@ hfsc_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
 	if (usc != NULL)
 		hfsc_print_sc(f, "ul", usc);
 
+	if (szopts != NULL && show_details) {
+		if (szopts->mpu)
+			fprintf(f, "mpu %s ", sprint_size(szopts->mpu, b1));
+		if (szopts->overhead)
+			fprintf(f, "overhead %s ", sprint_size(szopts->overhead, b1));
+	}
+
 	return 0;
 }
 


      reply	other threads:[~2008-07-10 19:34 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-10 19:34 [PATCH v4 1/2] [iproute2/tc] tc_core: add size table Jussi Kivilinna
2008-07-10 19:34 ` Jussi Kivilinna [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080710193454.19601.97736.stgit@fate.lan \
    --to=jussi.kivilinna@mbnet.fi \
    --cc=kaber@trash.net \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.