Skip to content

Commit b3d0e04

Browse files
vbnogueiradavem330
authored andcommitted
net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms
In case an error occurred after mall_set_parms executed successfully, we must undo the tcf_bind_filter call it issues. Fix that by calling tcf_unbind_filter in err_replace_hw_filter label. Fixes: ec2507d ("net/sched: cls_matchall: Fix error path") Signed-off-by: Victor Nogueira <[email protected]> Acked-by: Jamal Hadi Salim <[email protected]> Reviewed-by: Pedro Tammela <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0dd1805 commit b3d0e04

File tree

1 file changed

+12
-23
lines changed

1 file changed

+12
-23
lines changed

net/sched/cls_matchall.c

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -159,26 +159,6 @@ static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
159159
[TCA_MATCHALL_FLAGS] = { .type = NLA_U32 },
160160
};
161161

162-
static int mall_set_parms(struct net *net, struct tcf_proto *tp,
163-
struct cls_mall_head *head,
164-
unsigned long base, struct nlattr **tb,
165-
struct nlattr *est, u32 flags, u32 fl_flags,
166-
struct netlink_ext_ack *extack)
167-
{
168-
int err;
169-
170-
err = tcf_exts_validate_ex(net, tp, tb, est, &head->exts, flags,
171-
fl_flags, extack);
172-
if (err < 0)
173-
return err;
174-
175-
if (tb[TCA_MATCHALL_CLASSID]) {
176-
head->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]);
177-
tcf_bind_filter(tp, &head->res, base);
178-
}
179-
return 0;
180-
}
181-
182162
static int mall_change(struct net *net, struct sk_buff *in_skb,
183163
struct tcf_proto *tp, unsigned long base,
184164
u32 handle, struct nlattr **tca,
@@ -187,6 +167,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
187167
{
188168
struct cls_mall_head *head = rtnl_dereference(tp->root);
189169
struct nlattr *tb[TCA_MATCHALL_MAX + 1];
170+
bool bound_to_filter = false;
190171
struct cls_mall_head *new;
191172
u32 userflags = 0;
192173
int err;
@@ -226,11 +207,17 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
226207
goto err_alloc_percpu;
227208
}
228209

229-
err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE],
230-
flags, new->flags, extack);
231-
if (err)
210+
err = tcf_exts_validate_ex(net, tp, tb, tca[TCA_RATE],
211+
&new->exts, flags, new->flags, extack);
212+
if (err < 0)
232213
goto err_set_parms;
233214

215+
if (tb[TCA_MATCHALL_CLASSID]) {
216+
new->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]);
217+
tcf_bind_filter(tp, &new->res, base);
218+
bound_to_filter = true;
219+
}
220+
234221
if (!tc_skip_hw(new->flags)) {
235222
err = mall_replace_hw_filter(tp, new, (unsigned long)new,
236223
extack);
@@ -246,6 +233,8 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
246233
return 0;
247234

248235
err_replace_hw_filter:
236+
if (bound_to_filter)
237+
tcf_unbind_filter(tp, &new->res);
249238
err_set_parms:
250239
free_percpu(new->pf);
251240
err_alloc_percpu:

0 commit comments

Comments
 (0)