From 8e64f6fe1fd7c7f52773a1ae10915b060fc008b8 Mon Sep 17 00:00:00 2001 From: "net[shemminger]!shemminger" Date: Mon, 30 Aug 2004 21:07:09 +0000 Subject: [PATCH] Import patch gact_iproute-2.6.8_patch (Logical change 1.74) --- configure | 9 ++ include/linux/tc_act/tc_gact.h | 36 +++++ m_gact.c | 266 +++++++++++++++++++++++++++++++++ tc/Makefile | 10 ++ 4 files changed, 321 insertions(+) diff --git a/configure b/configure index 7a8e6c2..097447b 100644 --- a/configure +++ b/configure @@ -26,3 +26,12 @@ else fi rm -f /tmp/atmtest.c /tmp/atmtest +# hack for now +echo "TC actions" + +if [ -e "tc/m_gact.c" ] +then + echo "TC_CONFIG_ACTION_GACT=y" >>Config + echo "TC_CONFIG_ACTION_PROB=y" >>Config +fi + diff --git a/include/linux/tc_act/tc_gact.h b/include/linux/tc_act/tc_gact.h index e69de29..ec770d3 100644 --- a/include/linux/tc_act/tc_gact.h +++ b/include/linux/tc_act/tc_gact.h @@ -0,0 +1,36 @@ +#ifndef __LINUX_TC_GACT_H +#define __LINUX_TC_GACT_H + +#include + +#define TCA_ACT_GACT 5 +struct tc_gact +{ + tc_gen; + +}; + +#ifdef CONFIG_GACT_PROB +struct tc_gact_p +{ +#define PGACT_NONE 0 +#define PGACT_NETRAND 1 +#define PGACT_DETERM 2 +#define MAX_RAND (PGACT_DETERM + 1 ) + __u16 ptype; + __u16 pval; + int paction; +}; +#endif + +enum +{ + TCA_GACT_UNSPEC, + TCA_GACT_TM, + TCA_GACT_PARMS, + TCA_GACT_PROB, + __TCA_GACT_MAX +}; +#define TCA_GACT_MAX (__TCA_GACT_MAX - 1) + +#endif diff --git a/m_gact.c b/m_gact.c index e69de29..4dc7b16 100644 --- a/m_gact.c +++ b/m_gact.c @@ -0,0 +1,266 @@ +/* + * m_gact.c generic actions module + * + * This program is free software; you can distribute 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: J Hadi Salim (hadi@cyberus.ca) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tc_util.h" +#include + +/* define to turn on probablity stuff */ + +#ifdef CONFIG_GACT_PROB +int prob_a2n(unsigned char *n) +{ + if (!strcmp(n,"none")) + return PGACT_NONE; + if (!strcmp(n,"netrand")) + return PGACT_NETRAND; + if (!strcmp(n,"determ")) + return PGACT_DETERM; + + return 0; +} + +char *prob_n2a(int p) +{ + if (p == PGACT_NONE) + return "none"; + if (p == PGACT_NETRAND) + return "netrand"; + if (p == PGACT_DETERM) + return "determ"; + return "none"; +} +#endif +static void +explain(void) +{ +#ifdef CONFIG_GACT_PROB + fprintf(stderr, "Usage: ... gact [RAND] [INDEX]\n"); + fprintf(stderr, + "Where: ACTION := reclassify | drop | continue | pass " + "RAND := random " + "RANDTYPE := netrand | determ" + "VAL : = value not exceeding 10000" + "INDEX := index value used" + "\n"); +#else + fprintf(stderr, "Usage: ... gact [INDEX]\n"); + fprintf(stderr, + "Where: ACTION := reclassify | drop | continue | pass " + "INDEX := index value used" + "\n"); +#endif +} + +#define usage() return(-1) + +int +get_act(char ***argv_p) +{ + char **argv = *argv_p; + + if (matches(*argv, "reclassify") == 0) { + return TC_ACT_RECLASSIFY; + } else if (matches(*argv, "drop") == 0 || matches(*argv, "shot") == 0) { + return TC_ACT_SHOT; + } else if (matches(*argv, "continue") == 0) { + return TC_ACT_UNSPEC; + } else if (matches(*argv, "pipe") == 0) { + return TC_ACT_PIPE; + } else if (matches(*argv, "pass") == 0 || matches(*argv, "ok") == 0) { + return TC_ACT_OK; + } else { + fprintf(stderr,"bad action type %s\n",*argv); + return -10; + } +} + +int +parse_gact(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) +{ + int argc = *argc_p; + char **argv = *argv_p; + int ok = 0; + int action = TC_POLICE_RECLASSIFY; + struct tc_gact p; +#ifdef CONFIG_GACT_PROB + int rd = 0; + struct tc_gact_p pp; +#endif + struct rtattr *tail; + + memset(&p, 0, sizeof (p)); + p.action = TC_POLICE_RECLASSIFY; + + if (argc < 0) + return -1; + + + if (matches(*argv, "gact") == 0) { + ok++; + } else { + action = get_act(&argv); + if (action != -10) { + p.action = action; + ok++; + } else { + explain(); + return action; + } + } + + if (ok) { + argc--; + argv++; + } + +#ifdef CONFIG_GACT_PROB + if (ok && argc > 0) { + if (matches(*argv, "random") == 0) { + rd = 1; + NEXT_ARG(); + if (matches(*argv, "netrand") == 0) { + NEXT_ARG(); + pp.ptype = PGACT_NETRAND; + } else if (matches(*argv, "determ") == 0) { + NEXT_ARG(); + pp.ptype = PGACT_DETERM; + } else { + fprintf(stderr, "Illegal \"random type\"\n"); + return -1; + } + + action = get_act(&argv); + if (action != -10) { /* FIXME */ + pp.paction = action; + } else { + explain(); + return -1; + } + argc--; + argv++; + if (get_u16(&pp.pval, *argv, 10)) { + fprintf(stderr, "Illegal probability val 0x%x\n",pp.pval); + return -1; + } + if (pp.pval > 10000) { + fprintf(stderr, "Illegal probability val 0x%x\n",pp.pval); + return -1; + } + argc--; + argv++; + } + } +#endif + + if (argc > 0) { + if (matches(*argv, "index") == 0) { + NEXT_ARG(); + if (get_u32(&p.index, *argv, 10)) { + fprintf(stderr, "Illegal \"index\"\n"); + return -1; + } + argc--; + argv++; + ok++; + } + } + + if (!ok) + return -1; + + tail = (struct rtattr *) (((void *) n) + NLMSG_ALIGN(n->nlmsg_len)); + addattr_l(n, MAX_MSG, tca_id, NULL, 0); + addattr_l(n, MAX_MSG, TCA_GACT_PARMS, &p, sizeof (p)); +#ifdef CONFIG_GACT_PROB + if (rd) { + addattr_l(n, MAX_MSG, TCA_GACT_PROB, &pp, sizeof (pp)); + } +#endif + tail->rta_len = + (((void *) n) + NLMSG_ALIGN(n->nlmsg_len)) - (void *) tail; + + *argc_p = argc; + *argv_p = argv; + return 0; +} + +int +print_gact(struct action_util *au,FILE * f, struct rtattr *arg) +{ + SPRINT_BUF(b1); +#ifdef CONFIG_GACT_PROB + SPRINT_BUF(b2); + struct tc_gact_p *pp = NULL; + struct tc_gact_p pp_dummy; +#endif + struct tc_gact *p = NULL; + struct rtattr *tb[TCA_GACT_MAX + 1]; + + if (arg == NULL) + return -1; + + memset(tb, 0, sizeof (tb)); + parse_rtattr(tb, TCA_GACT_MAX, RTA_DATA(arg), RTA_PAYLOAD(arg)); + + if (tb[TCA_GACT_PARMS] == NULL) { + fprintf(f, "[NULL gact parameters]"); + return -1; + } + p = RTA_DATA(tb[TCA_GACT_PARMS]); + + fprintf(f, "gact action %s", action_n2a(p->action, b1, sizeof (b1))); +#ifdef CONFIG_GACT_PROB + if (NULL != tb[TCA_GACT_PROB]) { + pp = RTA_DATA(tb[TCA_GACT_PROB]); + } else { + /* need to keep consistent output */ + memset(&pp_dummy, 0, sizeof (pp_dummy)); + pp = &pp_dummy; + } + fprintf(f, "\n\t random type %s %s val %d",prob_n2a(pp->ptype), action_n2a(pp->paction, b2, sizeof (b2)), pp->pval); +#endif + fprintf(f, "\n\t index %d ref %d bind %d",p->index, p->refcnt, p->bindcnt); + if (show_stats) { + if (tb[TCA_GACT_TM]) { + struct tcf_t *tm = RTA_DATA(tb[TCA_GACT_TM]); + print_tm(f,tm); + } + } + fprintf(f, "\n "); + return 0; +} + +int +gact_print_xstats(struct action_util *au, FILE *f, struct rtattr *xstats) +{ + return 0; +} + + +struct action_util gact_util = { + NULL, + "gact", + parse_gact, + print_gact, + gact_print_xstats, +}; diff --git a/tc/Makefile b/tc/Makefile index 4e9e683..c83c378 100644 --- a/tc/Makefile +++ b/tc/Makefile @@ -28,6 +28,14 @@ TCLIB += tc_red.o TCLIB += tc_cbq.o TCLIB += tc_estimator.o +ifeq ($(TC_CONFIG_ACTION_GACT),y) + TCMODULES += m_gact.o + CFLAGS += -DCONFIG_GACT +ifeq ($(TC_CONFIG_ACTION_PROB),y) + CFLAGS += -DCONFIG_GACT_PROB +endif +endif + TCSO := TCSO += q_netem.so ifeq ($(TC_CONFIG_ATM),y) @@ -37,6 +45,7 @@ endif NETEM_DIST := normal.dist pareto.dist paretonormal.dist LDLIBS += -L. -ltc -lm -ldl + LDFLAGS += -Wl,-export-dynamic %.so: %.c @@ -51,6 +60,7 @@ all: libtc.a tc $(TCSO) $(NETEM_DIST) tc: $(TCOBJ) $(LIBNETLINK) $(LIBUTIL) $(TCLIB) + libtc.a: $(TCLIB) $(AR) rcs $@ $(TCLIB) -- 2.39.2