diff options
Diffstat (limited to 'net/sched/act_simple.c')
| -rw-r--r-- | net/sched/act_simple.c | 95 | 
1 files changed, 34 insertions, 61 deletions
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 97e84f3ee77..992c2317ce8 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -25,50 +25,31 @@  #include <net/tc_act/tc_defact.h>  #define SIMP_TAB_MASK     7 -static struct tcf_common *tcf_simp_ht[SIMP_TAB_MASK + 1]; -static u32 simp_idx_gen; -static DEFINE_RWLOCK(simp_lock); - -static struct tcf_hashinfo simp_hash_info = { -	.htab	=	tcf_simp_ht, -	.hmask	=	SIMP_TAB_MASK, -	.lock	=	&simp_lock, -};  #define SIMP_MAX_DATA	32 -static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res) +static int tcf_simp(struct sk_buff *skb, const struct tc_action *a, +		    struct tcf_result *res)  {  	struct tcf_defact *d = a->priv;  	spin_lock(&d->tcf_lock);  	d->tcf_tm.lastuse = jiffies; -	d->tcf_bstats.bytes += qdisc_pkt_len(skb); -	d->tcf_bstats.packets++; +	bstats_update(&d->tcf_bstats, skb);  	/* print policy string followed by _ then packet count  	 * Example if this was the 3rd packet and the string was "hello"  	 * then it would look like "hello_3" (without quotes) -	 **/ +	 */  	pr_info("simple: %s_%d\n",  	       (char *)d->tcfd_defdata, d->tcf_bstats.packets);  	spin_unlock(&d->tcf_lock);  	return d->tcf_action;  } -static int tcf_simp_release(struct tcf_defact *d, int bind) +static void tcf_simp_release(struct tc_action *a, int bind)  { -	int ret = 0; -	if (d) { -		if (bind) -			d->tcf_bindcnt--; -		d->tcf_refcnt--; -		if (d->tcf_bindcnt <= 0 && d->tcf_refcnt <= 0) { -			kfree(d->tcfd_defdata); -			tcf_hash_destroy(&d->common, &simp_hash_info); -			ret = 1; -		} -	} -	return ret; +	struct tcf_defact *d = to_defact(a); +	kfree(d->tcfd_defdata);  }  static int alloc_defdata(struct tcf_defact *d, char *defdata) @@ -95,13 +76,13 @@ static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {  	[TCA_DEF_DATA]	= { .type = NLA_STRING, .len = SIMP_MAX_DATA },  }; -static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, -			 struct tc_action *a, int ovr, int bind) +static int tcf_simp_init(struct net *net, struct nlattr *nla, +			 struct nlattr *est, struct tc_action *a, +			 int ovr, int bind)  {  	struct nlattr *tb[TCA_DEF_MAX + 1];  	struct tc_defact *parm;  	struct tcf_defact *d; -	struct tcf_common *pc;  	char *defdata;  	int ret = 0, err; @@ -121,46 +102,38 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,  	parm = nla_data(tb[TCA_DEF_PARMS]);  	defdata = nla_data(tb[TCA_DEF_DATA]); -	pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); -	if (!pc) { -		pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, -				     &simp_idx_gen, &simp_hash_info); -		if (IS_ERR(pc)) -		    return PTR_ERR(pc); +	if (!tcf_hash_check(parm->index, a, bind)) { +		ret = tcf_hash_create(parm->index, est, a, sizeof(*d), bind); +		if (ret) +			return ret; -		d = to_defact(pc); +		d = to_defact(a);  		ret = alloc_defdata(d, defdata);  		if (ret < 0) { -			kfree(pc); +			tcf_hash_cleanup(a, est);  			return ret;  		}  		d->tcf_action = parm->action;  		ret = ACT_P_CREATED;  	} else { -		d = to_defact(pc); -		if (!ovr) { -			tcf_simp_release(d, bind); +		d = to_defact(a); + +		if (bind) +			return 0; +		tcf_hash_release(a, bind); +		if (!ovr)  			return -EEXIST; -		} +  		reset_policy(d, defdata, parm);  	}  	if (ret == ACT_P_CREATED) -		tcf_hash_insert(pc, &simp_hash_info); +		tcf_hash_insert(a);  	return ret;  } -static inline int tcf_simp_cleanup(struct tc_action *a, int bind) -{ -	struct tcf_defact *d = a->priv; - -	if (d) -		return tcf_simp_release(d, bind); -	return 0; -} - -static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a, -				int bind, int ref) +static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a, +			 int bind, int ref)  {  	unsigned char *b = skb_tail_pointer(skb);  	struct tcf_defact *d = a->priv; @@ -172,12 +145,14 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,  	};  	struct tcf_t t; -	NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt); -	NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata); +	if (nla_put(skb, TCA_DEF_PARMS, sizeof(opt), &opt) || +	    nla_put_string(skb, TCA_DEF_DATA, d->tcfd_defdata)) +		goto nla_put_failure;  	t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);  	t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);  	t.expires = jiffies_to_clock_t(d->tcf_tm.expires); -	NLA_PUT(skb, TCA_DEF_TM, sizeof(t), &t); +	if (nla_put(skb, TCA_DEF_TM, sizeof(t), &t)) +		goto nla_put_failure;  	return skb->len;  nla_put_failure: @@ -187,15 +162,12 @@ nla_put_failure:  static struct tc_action_ops act_simp_ops = {  	.kind		=	"simple", -	.hinfo		=	&simp_hash_info,  	.type		=	TCA_ACT_SIMP, -	.capab		=	TCA_CAP_NONE,  	.owner		=	THIS_MODULE,  	.act		=	tcf_simp,  	.dump		=	tcf_simp_dump, -	.cleanup	=	tcf_simp_cleanup, +	.cleanup	=	tcf_simp_release,  	.init		=	tcf_simp_init, -	.walk		=	tcf_generic_walker,  };  MODULE_AUTHOR("Jamal Hadi Salim(2005)"); @@ -204,7 +176,8 @@ MODULE_LICENSE("GPL");  static int __init simp_init_module(void)  { -	int ret = tcf_register_action(&act_simp_ops); +	int ret; +	ret = tcf_register_action(&act_simp_ops, SIMP_TAB_MASK);  	if (!ret)  		pr_info("Simple TC action Loaded\n");  	return ret;  | 
