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 ? > raptor@unacs.bg 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 {