Skip to content

Commit ac177a3

Browse files
vbnogueiradavem330
authored andcommitted
net: sched: cls_flower: Undo tcf_bind_filter in case of an error
If TCA_FLOWER_CLASSID is specified in the netlink message, the code will call tcf_bind_filter. However, if any error occurs after that, the code should undo this by calling tcf_unbind_filter. Fixes: 77b9900 ("tc: introduce Flower classifier") 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 26a2219 commit ac177a3

File tree

1 file changed

+47
-52
lines changed

1 file changed

+47
-52
lines changed

net/sched/cls_flower.c

Lines changed: 47 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,53 +2173,6 @@ static bool fl_needs_tc_skb_ext(const struct fl_flow_key *mask)
21732173
return mask->meta.l2_miss;
21742174
}
21752175

2176-
static int fl_set_parms(struct net *net, struct tcf_proto *tp,
2177-
struct cls_fl_filter *f, struct fl_flow_mask *mask,
2178-
unsigned long base, struct nlattr **tb,
2179-
struct nlattr *est,
2180-
struct fl_flow_tmplt *tmplt,
2181-
u32 flags, u32 fl_flags,
2182-
struct netlink_ext_ack *extack)
2183-
{
2184-
int err;
2185-
2186-
err = tcf_exts_validate_ex(net, tp, tb, est, &f->exts, flags,
2187-
fl_flags, extack);
2188-
if (err < 0)
2189-
return err;
2190-
2191-
if (tb[TCA_FLOWER_CLASSID]) {
2192-
f->res.classid = nla_get_u32(tb[TCA_FLOWER_CLASSID]);
2193-
if (flags & TCA_ACT_FLAGS_NO_RTNL)
2194-
rtnl_lock();
2195-
tcf_bind_filter(tp, &f->res, base);
2196-
if (flags & TCA_ACT_FLAGS_NO_RTNL)
2197-
rtnl_unlock();
2198-
}
2199-
2200-
err = fl_set_key(net, tb, &f->key, &mask->key, extack);
2201-
if (err)
2202-
return err;
2203-
2204-
fl_mask_update_range(mask);
2205-
fl_set_masked_key(&f->mkey, &f->key, mask);
2206-
2207-
if (!fl_mask_fits_tmplt(tmplt, mask)) {
2208-
NL_SET_ERR_MSG_MOD(extack, "Mask does not fit the template");
2209-
return -EINVAL;
2210-
}
2211-
2212-
/* Enable tc skb extension if filter matches on data extracted from
2213-
* this extension.
2214-
*/
2215-
if (fl_needs_tc_skb_ext(&mask->key)) {
2216-
f->needs_tc_skb_ext = 1;
2217-
tc_skb_ext_tc_enable();
2218-
}
2219-
2220-
return 0;
2221-
}
2222-
22232176
static int fl_ht_insert_unique(struct cls_fl_filter *fnew,
22242177
struct cls_fl_filter *fold,
22252178
bool *in_ht)
@@ -2251,6 +2204,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
22512204
struct cls_fl_head *head = fl_head_dereference(tp);
22522205
bool rtnl_held = !(flags & TCA_ACT_FLAGS_NO_RTNL);
22532206
struct cls_fl_filter *fold = *arg;
2207+
bool bound_to_filter = false;
22542208
struct cls_fl_filter *fnew;
22552209
struct fl_flow_mask *mask;
22562210
struct nlattr **tb;
@@ -2335,15 +2289,46 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
23352289
if (err < 0)
23362290
goto errout_idr;
23372291

2338-
err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE],
2339-
tp->chain->tmplt_priv, flags, fnew->flags,
2340-
extack);
2341-
if (err)
2292+
err = tcf_exts_validate_ex(net, tp, tb, tca[TCA_RATE],
2293+
&fnew->exts, flags, fnew->flags,
2294+
extack);
2295+
if (err < 0)
23422296
goto errout_idr;
23432297

2298+
if (tb[TCA_FLOWER_CLASSID]) {
2299+
fnew->res.classid = nla_get_u32(tb[TCA_FLOWER_CLASSID]);
2300+
if (flags & TCA_ACT_FLAGS_NO_RTNL)
2301+
rtnl_lock();
2302+
tcf_bind_filter(tp, &fnew->res, base);
2303+
if (flags & TCA_ACT_FLAGS_NO_RTNL)
2304+
rtnl_unlock();
2305+
bound_to_filter = true;
2306+
}
2307+
2308+
err = fl_set_key(net, tb, &fnew->key, &mask->key, extack);
2309+
if (err)
2310+
goto unbind_filter;
2311+
2312+
fl_mask_update_range(mask);
2313+
fl_set_masked_key(&fnew->mkey, &fnew->key, mask);
2314+
2315+
if (!fl_mask_fits_tmplt(tp->chain->tmplt_priv, mask)) {
2316+
NL_SET_ERR_MSG_MOD(extack, "Mask does not fit the template");
2317+
err = -EINVAL;
2318+
goto unbind_filter;
2319+
}
2320+
2321+
/* Enable tc skb extension if filter matches on data extracted from
2322+
* this extension.
2323+
*/
2324+
if (fl_needs_tc_skb_ext(&mask->key)) {
2325+
fnew->needs_tc_skb_ext = 1;
2326+
tc_skb_ext_tc_enable();
2327+
}
2328+
23442329
err = fl_check_assign_mask(head, fnew, fold, mask);
23452330
if (err)
2346-
goto errout_idr;
2331+
goto unbind_filter;
23472332

23482333
err = fl_ht_insert_unique(fnew, fold, &in_ht);
23492334
if (err)
@@ -2434,6 +2419,16 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
24342419
fnew->mask->filter_ht_params);
24352420
errout_mask:
24362421
fl_mask_put(head, fnew->mask);
2422+
2423+
unbind_filter:
2424+
if (bound_to_filter) {
2425+
if (flags & TCA_ACT_FLAGS_NO_RTNL)
2426+
rtnl_lock();
2427+
tcf_unbind_filter(tp, &fnew->res);
2428+
if (flags & TCA_ACT_FLAGS_NO_RTNL)
2429+
rtnl_unlock();
2430+
}
2431+
24372432
errout_idr:
24382433
if (!fold)
24392434
idr_remove(&head->handle_idr, fnew->handle);

0 commit comments

Comments
 (0)