Here it is.
- Jacob
On Mon, Jul 15, 2002 at 08:22:25AM +0000, devik wrote:
> Hi Jacob,
>
> please can you post the htb tcng patch to LARTC list ?
> [EMAIL PROTECTED] would test it in real environment ...
>
> thanks, devik
>
Index: Makefile
===================================================================
RCS file: /export/cvsroot/tcng/Makefile,v
retrieving revision 1.124
diff -u -r1.124 Makefile
--- Makefile 26 May 2002 06:27:52 -0000 1.124
+++ Makefile 6 Jun 2002 01:46:47 -0000
@@ -50,6 +50,7 @@
tcc/sprintf.h tcc/sprintf.c \
tcc/device.h tcc/device.c \
tcc/qdisc.h tcc/qdisc.c tcc/qdisc_common.h tcc/q_ingress.c tcc/q_cbq.c \
+ tcc/q_htb.c \
tcc/q_dsmark.c tcc/q_fifo.c tcc/q_gred.c tcc/q_prio.c tcc/q_red.c \
tcc/q_sfq.c tcc/q_tbf.c tcc/csp.c \
tcc/filter.h tcc/filter.c tcc/filter_common.h tcc/f_if.c tcc/f_fw.c \
Index: VERSION
===================================================================
RCS file: /export/cvsroot/tcng/VERSION,v
retrieving revision 1.127
diff -u -r1.127 VERSION
--- VERSION 31 May 2002 12:26:35 -0000 1.127
+++ VERSION 6 Jun 2002 23:15:54 -0000
@@ -1 +1 @@
-8r
+8s
Index: tcc/Makefile
===================================================================
RCS file: /export/cvsroot/tcng/tcc/Makefile,v
retrieving revision 1.22
diff -u -r1.22 Makefile
--- tcc/Makefile 17 May 2002 04:42:25 -0000 1.22
+++ tcc/Makefile 6 Jun 2002 01:43:29 -0000
@@ -13,6 +13,7 @@
OBJS=lex.yy.o y.tab.o tcc.o util.o error.o var.o data.o param.o device.o \
registry.o u128.o sprintf.o \
qdisc.o q_ingress.o q_cbq.o q_dsmark.o q_fifo.o q_gred.o q_prio.o \
+ q_htb.o \
q_red.o q_sfq.o q_tbf.o csp.o \
filter.o f_if.o f_fw.o f_route.o f_rsvp.o f_tcindex.o \
police.o tc.o op.o field.o named.o \
Index: tcc/Parameters
===================================================================
RCS file: /export/cvsroot/tcng/tcc/Parameters,v
retrieving revision 1.3
diff -u -r1.3 Parameters
--- tcc/Parameters 26 Jan 2002 19:31:40 -0000 1.3
+++ tcc/Parameters 27 Jun 2002 19:11:19 -0000
@@ -7,6 +7,8 @@
bandwidth rate
bounded flag
burst size
+cburst size
+ceil rate
default flag
default_index unum
dport unum
@@ -42,6 +44,7 @@
protocol unum
quantum size
rate rate
+r2q unum
set_tc_index flag
shift unum
skip size
Index: tcc/if_u32.c
===================================================================
RCS file: /export/cvsroot/tcng/tcc/if_u32.c,v
retrieving revision 1.11
diff -u -r1.11 if_u32.c
--- tcc/if_u32.c 21 May 2002 06:44:39 -0000 1.11
+++ tcc/if_u32.c 8 Jun 2002 00:17:25 -0000
@@ -941,7 +941,9 @@
tc_pragma(filter->params);
for (i = 0; i < 2; i++) {
+// to uncover everything
if (!i) {
+ // first time
d = data_clone(qdisc->if_expr);
d = op_binary(&op_logical_or,d,data_decision(dr_continue,NULL));
}
Index: tcc/q_htb.c
===================================================================
RCS file: tcc/q_htb.c
diff -N tcc/q_htb.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tcc/q_htb.c 27 Jun 2002 19:42:35 -0000
@@ -0,0 +1,314 @@
+/*
+ * q_htb.c - Hierachical Token Bucket Queuing qdisc
+
+ *
+ * Written 2002 by Jacob Teplitsky
+ * Copyright 2002 Bivio Networks.
+ */
+
+
+#include <stddef.h>
+
+#include "tcdefs.h"
+#include "util.h"
+#include "error.h"
+#include "data.h"
+#include "param.h"
+#include "tree.h"
+#include "field.h"
+#include "op.h"
+#include "tc.h"
+#include "ext.h"
+#include "filter.h"
+#include "qdisc_common.h"
+#include "qdisc.h"
+
+
+/* ------------------------------- Checking -------------------------------- */
+
+
+#define __DEFAULT_PRM(f) f(burst) f(ceil) f(cburst) f(prio) f(quantum) f(rate)
+#define __DEFAULT_PRM_REQ(f) f(rate)
+
+static void htb_check_classes(CLASS **classes,DEFAULT_ARGS,int depth, int
+*got_default)
+{
+ CLASS *class;
+
+ if (!*classes) return;
+ sort_classes(classes);
+ if (depth == TC_HTB_MAXLEVEL)
+ lerrorf((*classes)->location,
+ "can't nest HTB classes deeper than %d levels",TC_HTB_MAXLEVEL);
+ for (class = *classes; class; class = class->next) {
+ DEFAULT_DECL_SAVED;
+
+ param_get(class->params,class->location);
+ DEFAULT_GET;
+ if (class->number != 0) {
+ DEFAULT_CHECK(class->location);
+ }
+ DEFAULT_SAVE;
+ if (class->number != 0) {
+ if (!prm_rate.v) lerror(class->location,"rate must be non-zero");
+ }
+ if (prm_ceil.present && prm_ceil.v < prm_rate.v)
+ lerrorf(class->location,"\"ceil\" (%lu) > \"rate\" (%lu)",
+ (unsigned long) prm_ceil.v,(unsigned long) prm_rate.v);
+ if (prm_prio.present && prm_prio.v > TC_HTB_MAXPRIO)
+ lerrorf(class->location,"\"prio\" (%lu) > %d",
+ (unsigned long) prm_prio.v,TC_HTB_MAXPRIO);
+ if (prm_default.present) {
+ if (*got_default) {
+ lerror(class->location,
+ "more than one class marked as \"default\"");
+ }
+ *got_default = 1;
+ }
+
+ htb_check_classes(&class->child,DEFAULT_PASS_SAVED,depth+1, got_default);
+ check_qdisc(class->qdisc);
+ check_filters(class->filters);
+ }
+}
+
+static void create_root_class(QDISC *qdisc)
+{
+ CLASS *classes,*root,*class;
+ int zero = 0;
+
+ if (recurse_class(qdisc->classes,count_class_ids,&zero)) return;
+ classes = qdisc->classes;
+ qdisc->classes = NULL;
+ root = require_class(qdisc,0);
+ root->child = classes;
+ for (class = classes; class; class = class->next)
+ class->parent.class = root;
+ /*
+ * Root class inherits all parameters from qdisc, and gets prm_rate from
+ * prm_bandwidth.
+ */
+}
+
+static void check_root_class(QDISC *qdisc)
+{
+ if (!qdisc->classes || qdisc->classes->next)
+ lerror(qdisc->classes ? qdisc->classes->location :
+ qdisc->classes->next->location,
+ "HTB must have exactly one root class");
+ if (qdisc->classes->number) /* hard to trigger :-) */
+ lerrorf(qdisc->classes->location,
+ "HTB root class must have number 0, not %lu\n",
+ (unsigned long) qdisc->classes->number);
+ if (qdisc->filters && qdisc->classes->filters)
+ lerror(qdisc->filters->location,"please specify filters either at HTB "
+ "qdisc or at root class");
+ if (qdisc->classes->filters) {
+ qdisc->filters = qdisc->classes->filters;
+ qdisc->classes->filters = NULL;
+ }
+}
+
+
+static void htb_check(QDISC *qdisc)
+{
+ int got_default = 0;
+
+ curr_id = 1;
+ (void) recurse_class(qdisc->classes,assign_class_id,qdisc->classes);
+ create_root_class(qdisc);
+ param_get(qdisc->params,qdisc->location);
+ check_root_class(qdisc); /* must be after param_get */
+ htb_check_classes(&qdisc->classes,DEFAULT_PASS,0, &got_default);
+ if (!got_default) {
+ lerror(qdisc->location,
+ "htb requires one class to be marked as \"default\"");
+ }
+ check_filters(qdisc->filters);
+}
+
+
+/* ------------------------ Default classification ------------------------- */
+static CLASS *htb_get_default_class(CLASS *classes)
+{
+ CLASS *class, *rt;
+
+ if (!classes) return (NULL);
+ for (class = classes; class; class = class->next) {
+ param_get(class->params,class->location);
+ if (prm_default.present) {
+ return (class);
+ }
+ rt = htb_get_default_class(class->child);
+ if (rt) {
+ return rt;
+ }
+ }
+ return NULL;
+}
+
+static void htb_use_default(DATA *d,DATA dfl,const CLASS *class)
+{
+ if (!d->op) {
+ if (d->type == dt_decision && d->u.decision.result == dr_class &&
+ d->u.decision.class == class)
+ *d = data_clone(dfl);
+ return;
+ }
+ htb_use_default(&d->op->a,dfl,class);
+ htb_use_default(&d->op->b,dfl,class);
+ htb_use_default(&d->op->c,dfl,class);
+}
+
+static void htb_push_defaults(DATA *d,PARAM *params,QDISC *qdisc,
+ CLASS *classes,CLASS *this_class)
+{
+ CLASS *class;
+
+ for (class = classes; class; class = class->next)
+ htb_push_defaults(d,class->params,qdisc,class->child,class);
+}
+
+static void htb_default_class(DATA *d,QDISC *qdisc)
+{
+ /*
+ * This is the only place where the root class becomes visible.
+ * This may confuse external programs quite badly.
+ */
+ CLASS *class;
+
+ class = htb_get_default_class(qdisc->classes);
+ append_default(d,data_decision(dr_class, class));
+}
+
+
+/* -------------------------------- Dump tc -------------------------------- */
+
+
+
+static void htb_dump_classes_tc(CLASS *classes,DEFAULT_ARGS)
+{
+ CLASS *class;
+
+ if (!classes) return;
+ for (class = classes; class; class = class->next) {
+ DEFAULT_DECL_SAVED;
+
+ param_get(class->params,class->location);
+ DEFAULT_GET;
+ DEFAULT_CHECK(class->location);
+ DEFAULT_SAVE;
+ tc_pragma(class->params);
+ tc_class_add(class);
+ tc_add_rate("rate",prm_rate.v);
+ if (prm_ceil.present) tc_add_rate("ceil",prm_ceil.v);
+ if (prm_burst.present) tc_add_size("burst",prm_burst.v);
+ if (prm_cburst.present) tc_add_size("cburst",prm_cburst.v);
+ if (prm_prio.present) tc_add_unum("prio",prm_prio.v);
+ tc_nl();
+ dump_qdisc(class->qdisc);
+ htb_dump_classes_tc(class->child,DEFAULT_PASS_SAVED);
+ dump_filters(class->filters);
+ }
+}
+
+
+static void htb_dump_tc(QDISC *qdisc)
+{
+ DEFAULT_DECL;
+ CLASS *class;
+
+ tc_pragma(qdisc->params);
+ tc_qdisc_add(qdisc);
+ class = htb_get_default_class(qdisc->classes);
+ param_get(qdisc->params,qdisc->location);
+ tc_add_unum("default", class->number);
+ if (prm_r2q.present) tc_add_unum("r2q",prm_r2q.v);
+ DEFAULT_SET;
+
+ param_get(qdisc->classes->params,qdisc->classes->location);
+ DEFAULT_GET;
+ tc_nl();
+ htb_dump_classes_tc(qdisc->classes->child,DEFAULT_PASS);
+ dump_qdisc(qdisc->classes->qdisc);
+ dump_filters(qdisc->filters);
+}
+
+
+/* ----------------------------- Dump external ----------------------------- */
+
+
+static void htb_dump_classes_ext(FILE *file,CLASS *classes)
+{
+ const PARAM_DSC *hide[] = {
+ NULL
+ };
+ const CLASS *class;
+
+ for (class = classes; class; class = class->next) {
+ param_push();
+ class_param_load(class);
+ ext_dump_class(file,class,hide,NULL);
+ htb_dump_classes_ext(file,class->child);
+ param_pop();
+ }
+}
+
+
+static void htb_dump_ext(FILE *file,QDISC *qdisc)
+{
+ const PARAM_DSC *hide[] = {
+ NULL
+ };
+
+ qdisc_param_load(qdisc);
+ ext_dump_qdisc(file,qdisc,hide,NULL);
+ htb_dump_classes_ext(file,qdisc->classes);
+}
+
+
+/* ------------------------------ Descriptors ------------------------------ */
+
+
+static const PARAM_DSC *htb_qdisc_req[] = {
+ NULL
+};
+
+static const PARAM_DSC *htb_qdisc_opt[] = {
+ &prm_pragma, /* list */
+ &prm_r2q,
+ DEFAULT_LIST /* NB: no trailing comma */
+ NULL
+};
+
+static const PARAM_DSC *htb_class_req[] = {
+ NULL
+};
+
+static const PARAM_DSC *htb_class_opt[] = {
+ &prm_default, /* flag */
+ &prm_pragma, /* list */
+ DEFAULT_LIST /* NB: no trailing comma */
+ NULL
+};
+
+static PARAM_DEF htb_qdisc = {
+ .required = htb_qdisc_req,
+ .optional = htb_qdisc_opt,
+};
+
+static PARAM_DEF htb_class = {
+ .required = htb_class_req,
+ .optional = htb_class_opt,
+};
+
+QDISC_DSC htb_dsc = {
+ .name = "htb",
+ .flags = QDISC_HAS_CLASSES | QDISC_HAS_FILTERS | QDISC_HAS_DEFAULT |
+ QDISC_CHILD_QDISCS,
+ .qdisc_param = &htb_qdisc,
+ .class_param = &htb_class,
+ .check = &htb_check,
+ .default_class = &htb_default_class,
+ .dump_tc = &htb_dump_tc,
+ .dump_ext = &htb_dump_ext,
+};
Index: tcc/qdisc.h
===================================================================
RCS file: /export/cvsroot/tcng/tcc/qdisc.h,v
retrieving revision 1.4
diff -u -r1.4 qdisc.h
--- tcc/qdisc.h 12 Mar 2002 13:46:41 -0000 1.4
+++ tcc/qdisc.h 6 Jun 2002 01:42:25 -0000
@@ -23,6 +23,7 @@
extern QDISC_DSC red_dsc;
extern QDISC_DSC sfq_dsc;
extern QDISC_DSC tbf_dsc;
+extern QDISC_DSC htb_dsc;
void assign_qdisc_ids(QDISC *root);
Index: tcc/tcdefs.h
===================================================================
RCS file: /export/cvsroot/tcng/tcc/tcdefs.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 tcdefs.h
--- tcc/tcdefs.h 16 Jul 2001 09:26:06 -0000 1.1.1.1
+++ tcc/tcdefs.h 6 Jun 2002 03:46:09 -0000
@@ -15,6 +15,8 @@
#ifndef TCDEFS_H
#define TCDEFS_H
+#define TC_HTB_MAXLEVEL 8
+#define TC_HTB_MAXPRIO 8
/* From linux/include/linux/pkt_sched.h */
#define TC_CBQ_MAXLEVEL 8
Index: tcc/tcng.l
===================================================================
RCS file: /export/cvsroot/tcng/tcc/tcng.l,v
retrieving revision 1.24
diff -u -r1.24 tcng.l
--- tcc/tcng.l 17 May 2002 04:42:25 -0000 1.24
+++ tcc/tcng.l 27 Jun 2002 19:15:57 -0000
@@ -92,6 +92,8 @@
bands return TOK_BANDS;
bounded return TOK_BOUNDED;
burst return TOK_BURST;
+cburst return TOK_CBURST;
+ceil return TOK_CEIL;
default return TOK_DEFAULT;
default_index return TOK_DEFAULT_INDEX;
dport return TOK_DPORT;
@@ -104,6 +106,7 @@
fromif return TOK_FROMIF;
grio return TOK_GRIO;
hash return TOK_HASH;
+htb return TOK_HTB;
isolated return TOK_ISOLATED;
indices return TOK_INDICES;
ipproto return TOK_IPPROTO;
@@ -125,6 +128,7 @@
protocol return TOK_PROTOCOL;
quantum return TOK_QUANTUM;
rate return TOK_RATE;
+r2q return TOK_R2Q;
set_tc_index return TOK_SET_TC_INDEX;
shift return TOK_SHIFT;
skip return TOK_SKIP;
Index: tcc/tcng.y
===================================================================
RCS file: /export/cvsroot/tcng/tcc/tcng.y,v
retrieving revision 1.52
diff -u -r1.52 tcng.y
--- tcc/tcng.y 17 May 2002 04:42:25 -0000 1.52
+++ tcc/tcng.y 27 Jun 2002 19:44:14 -0000
@@ -265,11 +265,11 @@
%token TOK_PASS TOK_RECLASSIFY TOK_CONTINUE TOK_FIELD TOK_TAG
%token TOK_FIELD_ROOT
%token TOK_CONFORM TOK_COUNT TOK_PRECOND TOK_DROP TOK_IF_ANCHOR
-%token TOK_CBQ TOK_DSMARK TOK_FIFO TOK_GRED TOK_PRIO TOK_RED TOK_SFQ
+%token TOK_CBQ TOK_DSMARK TOK_FIFO TOK_GRED TOK_PRIO TOK_RED TOK_SFQ TOK_HTB
%token TOK_TBF TOK_INGRESS TOK_EGRESS
%token TOK_FW TOK_ROUTE TOK_RSVP TOK_TCINDEX
%token TOK_AH TOK_ALLOT TOK_AVPKT TOK_BANDS TOK_BANDWIDTH TOK_BOUNDED
-%token TOK_BURST
+%token TOK_BURST TOK_CBURST TOK_CEIL
%token TOK_DEFAULT TOK_DEFAULT_INDEX TOK_DPORT TOK_DST
%token TOK_ECN TOK_ESP TOK_EWMA TOK_FALL_THROUGH
%token TOK_FROM TOK_FROMIF TOK_GRIO TOK_HASH
@@ -1366,6 +1366,10 @@
{
$$ = &tbf_dsc;
}
+ | TOK_HTB
+ {
+ $$ = &htb_dsc;
+ }
;
opt_qdisc_or_class_body:
@@ -1564,6 +1568,14 @@
$$ = param_make(&prm_burst,$2);
/* check against expected psched_mtu */
}
+ | TOK_CBURST constant_expression
+ {
+ $$ = param_make(&prm_cburst,$2);
+ }
+ | TOK_CEIL constant_expression
+ {
+ $$ = param_make(&prm_ceil,$2);
+ }
| TOK_DEFAULT
{
$$ = param_make(&prm_default,data_unum(1));
@@ -1700,7 +1712,7 @@
| TOK_PRIO constant_expression
{
$$ = param_make(&prm_prio,$2);
- NONZERO($$);
+ // NONZERO($$); jacobt add check in prio and cbq
}
| TOK_PRIOMAP forward_class_list
{
@@ -1724,6 +1736,10 @@
{
$$ = param_make(&prm_rate,$2);
/* NONZERO($$); @@@ policer may have zero rate */
+ }
+ | TOK_R2Q constant_expression
+ {
+ $$ = param_make(&prm_r2q,$2);
}
| TOK_SET_TC_INDEX
{