[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230705134329.102345-6-victor@mojatatu.com>
Date: Wed, 5 Jul 2023 10:43:29 -0300
From: Victor Nogueira <victor@...atatu.com>
To: netdev@...r.kernel.org
Cc: jhs@...atatu.com,
xiyou.wangcong@...il.com,
jiri@...nulli.us,
davem@...emloft.net,
edumazet@...gle.com,
kuba@...nel.org,
pabeni@...hat.com,
pctammela@...atatu.com,
simon.horman@...igine.com,
kernel@...atatu.com
Subject: [PATCH net v2 5/5] net: sched: cls_flower: Undo tcf_bind_filter if fl_set_key fails
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.
When checking for TCA_FLOWER_CLASSID attribute, the code is calling for
tcf_bind_fitler.
Fixes: 77b9900ef53a ("tc: introduce Flower classifier")
Signed-off-by: Victor Nogueira <victor@...atatu.com>
Acked-by: Jamal Hadi Salim <jhs@...atatu.com>
---
net/sched/cls_flower.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 56065cc5a661..644b0097e6ae 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -2169,7 +2169,7 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
struct nlattr *est,
struct fl_flow_tmplt *tmplt,
u32 flags, u32 fl_flags,
- struct netlink_ext_ack *extack)
+ bool *bound_to_filter, struct netlink_ext_ack *extack)
{
int err;
@@ -2185,18 +2185,20 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
tcf_bind_filter(tp, &f->res, base);
if (flags & TCA_ACT_FLAGS_NO_RTNL)
rtnl_unlock();
+ *bound_to_filter = true;
}
err = fl_set_key(net, tb, &f->key, &mask->key, extack);
if (err)
- return err;
+ goto unbind_filter;
fl_mask_update_range(mask);
fl_set_masked_key(&f->mkey, &f->key, mask);
if (!fl_mask_fits_tmplt(tmplt, mask)) {
NL_SET_ERR_MSG_MOD(extack, "Mask does not fit the template");
- return -EINVAL;
+ err = -EINVAL;
+ goto unbind_filter;
}
/* Enable tc skb extension if filter matches on data extracted from
@@ -2208,6 +2210,17 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
}
return 0;
+
+unbind_filter:
+ if (*bound_to_filter) {
+ if (flags & TCA_ACT_FLAGS_NO_RTNL)
+ rtnl_lock();
+ tcf_unbind_filter(tp, &f->res);
+ if (flags & TCA_ACT_FLAGS_NO_RTNL)
+ rtnl_unlock();
+ *bound_to_filter = false;
+ }
+ return err;
}
static int fl_ht_insert_unique(struct cls_fl_filter *fnew,
@@ -2241,6 +2254,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
struct cls_fl_head *head = fl_head_dereference(tp);
bool rtnl_held = !(flags & TCA_ACT_FLAGS_NO_RTNL);
struct cls_fl_filter *fold = *arg;
+ bool bound_to_filter = false;
struct cls_fl_filter *fnew;
struct fl_flow_mask *mask;
struct nlattr **tb;
@@ -2327,7 +2341,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE],
tp->chain->tmplt_priv, flags, fnew->flags,
- extack);
+ &bound_to_filter, extack);
if (err)
goto errout_idr;
@@ -2425,6 +2439,13 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
errout_mask:
fl_mask_put(head, fnew->mask);
errout_idr:
+ if (bound_to_filter) {
+ if (flags & TCA_ACT_FLAGS_NO_RTNL)
+ rtnl_lock();
+ tcf_unbind_filter(tp, &fnew->res);
+ if (flags & TCA_ACT_FLAGS_NO_RTNL)
+ rtnl_unlock();
+ }
if (!fold)
idr_remove(&head->handle_idr, fnew->handle);
__fl_put(fnew);
--
2.25.1
Powered by blists - more mailing lists