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
        {


Reply via email to