X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fsched%2Fgact.c;h=a811c89fef7fd105e98f2b2dadf1518ff3eb0847;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=5607f5e8cd8313addcc2509ef43ced5dd2d32982;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/net/sched/gact.c b/net/sched/gact.c index 5607f5e8c..a811c89fe 100644 --- a/net/sched/gact.c +++ b/net/sched/gact.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include #include @@ -38,175 +38,154 @@ /* use generic hash table */ #define MY_TAB_SIZE 16 #define MY_TAB_MASK 15 + static u32 idx_gen; static struct tcf_gact *tcf_gact_ht[MY_TAB_SIZE]; -static rwlock_t gact_lock = RW_LOCK_UNLOCKED; +static DEFINE_RWLOCK(gact_lock); /* ovewrride the defaults */ -#define tcf_st tcf_gact -#define tc_st tc_gact -#define tcf_t_lock gact_lock -#define tcf_ht tcf_gact_ht +#define tcf_st tcf_gact +#define tc_st tc_gact +#define tcf_t_lock gact_lock +#define tcf_ht tcf_gact_ht #define CONFIG_NET_ACT_INIT 1 #include #ifdef CONFIG_GACT_PROB -typedef int (*g_rand)(struct tcf_gact *p); -int -gact_net_rand(struct tcf_gact *p) { +static int gact_net_rand(struct tcf_gact *p) +{ if (net_random()%p->pval) return p->action; return p->paction; } -int -gact_determ(struct tcf_gact *p) { - if (p->stats.packets%p->pval) +static int gact_determ(struct tcf_gact *p) +{ + if (p->bstats.packets%p->pval) return p->action; return p->paction; } - -g_rand gact_rand[MAX_RAND]= { NULL,gact_net_rand, gact_determ}; - +typedef int (*g_rand)(struct tcf_gact *p); +static g_rand gact_rand[MAX_RAND]= { NULL, gact_net_rand, gact_determ }; #endif -int -tcf_gact_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,int ovr,int bind) + +static int tcf_gact_init(struct rtattr *rta, struct rtattr *est, + struct tc_action *a, int ovr, int bind) { struct rtattr *tb[TCA_GACT_MAX]; - struct tc_gact *parm = NULL; -#ifdef CONFIG_GACT_PROB - struct tc_gact_p *p_parm = NULL; -#endif - struct tcf_gact *p = NULL; + struct tc_gact *parm; + struct tcf_gact *p; int ret = 0; - int size = sizeof (*p); - - if (rtattr_parse(tb, TCA_GACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0) - return -1; - if (NULL == a || NULL == tb[TCA_GACT_PARMS - 1]) { - printk("BUG: tcf_gact_init called with NULL params\n"); - return -1; - } + if (rta == NULL || rtattr_parse_nested(tb, TCA_GACT_MAX, rta) < 0) + return -EINVAL; + if (tb[TCA_GACT_PARMS - 1] == NULL || + RTA_PAYLOAD(tb[TCA_GACT_PARMS - 1]) < sizeof(*parm)) + return -EINVAL; parm = RTA_DATA(tb[TCA_GACT_PARMS - 1]); + + if (tb[TCA_GACT_PROB-1] != NULL) #ifdef CONFIG_GACT_PROB - if (NULL != tb[TCA_GACT_PROB - 1]) { - p_parm = RTA_DATA(tb[TCA_GACT_PROB - 1]); - } + if (RTA_PAYLOAD(tb[TCA_GACT_PROB-1]) < sizeof(struct tc_gact_p)) + return -EINVAL; +#else + return -EOPNOTSUPP; #endif - p = tcf_hash_check(parm, a, ovr, bind); - - if (NULL == p) { - p = tcf_hash_create(parm,est,a,size,ovr, bind); - - if (NULL == p) { - return -1; - } else { - p->refcnt = 1; - ret = 1; - goto override; + p = tcf_hash_check(parm->index, a, ovr, bind); + if (p == NULL) { + p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind); + if (p == NULL) + return -ENOMEM; + ret = ACT_P_CREATED; + } else { + if (!ovr) { + tcf_hash_release(p, bind); + return -EEXIST; } } - if (ovr) { -override: - p->action = parm->action; + spin_lock_bh(&p->lock); + p->action = parm->action; #ifdef CONFIG_GACT_PROB - if (NULL != p_parm) { - p->paction = p_parm->paction; - p->pval = p_parm->pval; - p->ptype = p_parm->ptype; - } else { - p->paction = p->pval = p->ptype = 0; - } -#endif + if (tb[TCA_GACT_PROB-1] != NULL) { + struct tc_gact_p *p_parm = RTA_DATA(tb[TCA_GACT_PROB-1]); + p->paction = p_parm->paction; + p->pval = p_parm->pval; + p->ptype = p_parm->ptype; } - +#endif + spin_unlock_bh(&p->lock); + if (ret == ACT_P_CREATED) + tcf_hash_insert(p); return ret; } -int +static int tcf_gact_cleanup(struct tc_action *a, int bind) { - struct tcf_gact *p; - p = PRIV(a,gact); - if (NULL != p) + struct tcf_gact *p = PRIV(a, gact); + + if (p != NULL) return tcf_hash_release(p, bind); return 0; } -int +static int tcf_gact(struct sk_buff **pskb, struct tc_action *a) { - struct tcf_gact *p; + struct tcf_gact *p = PRIV(a, gact); struct sk_buff *skb = *pskb; int action = TC_ACT_SHOT; - p = PRIV(a,gact); - - if (NULL == p) { - if (net_ratelimit()) - printk("BUG: tcf_gact called with NULL params\n"); - return -1; - } - spin_lock(&p->lock); #ifdef CONFIG_GACT_PROB - if (p->ptype && NULL != gact_rand[p->ptype]) + if (p->ptype && gact_rand[p->ptype] != NULL) action = gact_rand[p->ptype](p); else action = p->action; #else action = p->action; #endif - p->stats.bytes += skb->len; - p->stats.packets++; - if (TC_ACT_SHOT == action) - p->stats.drops++; + p->bstats.bytes += skb->len; + p->bstats.packets++; + if (action == TC_ACT_SHOT) + p->qstats.drops++; p->tm.lastuse = jiffies; spin_unlock(&p->lock); return action; } -int +static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { unsigned char *b = skb->tail; struct tc_gact opt; -#ifdef CONFIG_GACT_PROB - struct tc_gact_p p_opt; -#endif - struct tcf_gact *p; + struct tcf_gact *p = PRIV(a, gact); struct tcf_t t; - p = PRIV(a,gact); - if (NULL == p) { - printk("BUG: tcf_gact_dump called with NULL params\n"); - goto rtattr_failure; - } - opt.index = p->index; opt.refcnt = p->refcnt - ref; opt.bindcnt = p->bindcnt - bind; opt.action = p->action; - RTA_PUT(skb, TCA_GACT_PARMS, sizeof (opt), &opt); + RTA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt); #ifdef CONFIG_GACT_PROB if (p->ptype) { + struct tc_gact_p p_opt; p_opt.paction = p->paction; p_opt.pval = p->pval; p_opt.ptype = p->ptype; - RTA_PUT(skb, TCA_GACT_PROB, sizeof (p_opt), &p_opt); - } + RTA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt); + } #endif - t.install = jiffies - p->tm.install; - t.lastuse = jiffies - p->tm.lastuse; - t.expires = p->tm.expires; - RTA_PUT(skb, TCA_GACT_TM, sizeof (t), &t); + t.install = jiffies_to_clock_t(jiffies - p->tm.install); + t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse); + t.expires = jiffies_to_clock_t(p->tm.expires); + RTA_PUT(skb, TCA_GACT_TM, sizeof(t), &t); return skb->len; rtattr_failure: @@ -214,25 +193,12 @@ tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) return -1; } -int -tcf_gact_stats(struct sk_buff *skb, struct tc_action *a) -{ - struct tcf_gact *p; - p = PRIV(a,gact); - if (NULL != p) - return qdisc_copy_stats(skb, &p->stats,p->stats_lock); - - return 1; -} - -struct tc_action_ops act_gact_ops = { - .next = NULL, +static struct tc_action_ops act_gact_ops = { .kind = "gact", .type = TCA_ACT_GACT, .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_gact, - .get_stats = tcf_gact_stats, .dump = tcf_gact_dump, .cleanup = tcf_gact_cleanup, .lookup = tcf_hash_search,