diff options
Diffstat (limited to 'net/sched/cls_fw.c')
| -rw-r--r-- | net/sched/cls_fw.c | 28 | 
1 files changed, 19 insertions, 9 deletions
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index f23a3b68bba6..9dc63d54e167 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -57,7 +57,7 @@ static u32 fw_hash(u32 handle)  }  static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp, -			  struct tcf_result *res) +		       struct tcf_result *res)  {  	struct fw_head *head = rcu_dereference_bh(tp->root);  	struct fw_filter *f; @@ -188,17 +188,20 @@ static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = {  static int  fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f, -	struct nlattr **tb, struct nlattr **tca, unsigned long base, bool ovr) +		struct nlattr **tb, struct nlattr **tca, unsigned long base, +		bool ovr)  {  	struct fw_head *head = rtnl_dereference(tp->root);  	struct tcf_exts e;  	u32 mask;  	int err; -	tcf_exts_init(&e, TCA_FW_ACT, TCA_FW_POLICE); -	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr); +	err = tcf_exts_init(&e, TCA_FW_ACT, TCA_FW_POLICE);  	if (err < 0)  		return err; +	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr); +	if (err < 0) +		goto errout;  	if (tb[TCA_FW_CLASSID]) {  		f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); @@ -235,9 +238,8 @@ errout:  static int fw_change(struct net *net, struct sk_buff *in_skb,  		     struct tcf_proto *tp, unsigned long base, -		     u32 handle, -		     struct nlattr **tca, -		     unsigned long *arg, bool ovr) +		     u32 handle, struct nlattr **tca, unsigned long *arg, +		     bool ovr)  {  	struct fw_head *head = rtnl_dereference(tp->root);  	struct fw_filter *f = (struct fw_filter *) *arg; @@ -270,10 +272,15 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,  #endif /* CONFIG_NET_CLS_IND */  		fnew->tp = f->tp; -		tcf_exts_init(&fnew->exts, TCA_FW_ACT, TCA_FW_POLICE); +		err = tcf_exts_init(&fnew->exts, TCA_FW_ACT, TCA_FW_POLICE); +		if (err < 0) { +			kfree(fnew); +			return err; +		}  		err = fw_change_attrs(net, tp, fnew, tb, tca, base, ovr);  		if (err < 0) { +			tcf_exts_destroy(&fnew->exts);  			kfree(fnew);  			return err;  		} @@ -313,7 +320,9 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,  	if (f == NULL)  		return -ENOBUFS; -	tcf_exts_init(&f->exts, TCA_FW_ACT, TCA_FW_POLICE); +	err = tcf_exts_init(&f->exts, TCA_FW_ACT, TCA_FW_POLICE); +	if (err < 0) +		goto errout;  	f->id = handle;  	f->tp = tp; @@ -328,6 +337,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,  	return 0;  errout: +	tcf_exts_destroy(&f->exts);  	kfree(f);  	return err;  }  |