* [PATCH net-next v4 0/5] net: sched: Fixes for classifiers
@ 2023-07-12 21:13 Victor Nogueira
2023-07-12 21:13 ` [PATCH net-next v4 1/5] net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms Victor Nogueira
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Victor Nogueira @ 2023-07-12 21:13 UTC (permalink / raw)
To: netdev
Cc: jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, simon.horman, kernel
Four different classifiers (bpf, u32, matchall, and flower) are
calling tcf_bind_filter in their callbacks, but arent't undoing it by
calling tcf_unbind_filter if their was an error after binding.
This patch set fixes all this by calling tcf_unbind_filter in such
cases.
This set also undoes a refcount decrement in cls_u32 when an update
fails under specific conditions which are described in patch #3.
v1 -> v2:
* Remove blank line after fixes tag
* Fix reverse xmas tree issues pointed out by Simon
v2 -> v3:
* Inline functions cls_bpf_set_parms and fl_set_parms to avoid adding
yet another parameter (and a return value at it) to them.
* Remove similar fixes for u32 and matchall, which will be sent soon,
once we find a way to do the fixes without adding a return parameter
to their set_parms functions.
v3 -> v4:
* Inline mall_set_parms to avoid adding yet another parameter.
* Remove set_flags parameter from u32_set_parms and create a separate
function for calling tcf_bind_filter and tcf_unbind_filter in case of
failure.
* Change cover letter title to also encompass refcnt fix for u32
Victor Nogueira (5):
net: sched: cls_matchall: Undo tcf_bind_filter in case of failure
after mall_set_parms
net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode
net: sched: cls_u32: Undo refcount decrement in case update failed
net: sched: cls_bpf: Undo tcf_bind_filter in case of an error
net: sched: cls_flower: Undo tcf_bind_filter if fl_set_key fails
net/sched/cls_bpf.c | 106 +++++++++++++++++++--------------------
net/sched/cls_flower.c | 105 +++++++++++++++++++-------------------
net/sched/cls_matchall.c | 35 +++++--------
net/sched/cls_u32.c | 48 ++++++++++++++----
4 files changed, 153 insertions(+), 141 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next v4 1/5] net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms
2023-07-12 21:13 [PATCH net-next v4 0/5] net: sched: Fixes for classifiers Victor Nogueira
@ 2023-07-12 21:13 ` Victor Nogueira
2023-07-13 9:17 ` Simon Horman
2023-07-12 21:13 ` [PATCH net-next v4 2/5] net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode fails Victor Nogueira
` (4 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Victor Nogueira @ 2023-07-12 21:13 UTC (permalink / raw)
To: netdev
Cc: jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, simon.horman, kernel
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: ec2507d2a306 ("net/sched: cls_matchall: Fix error path")
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
---
net/sched/cls_matchall.c | 35 ++++++++++++-----------------------
1 file changed, 12 insertions(+), 23 deletions(-)
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index fa3bbd187eb9..c4ed11df6254 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -159,26 +159,6 @@ static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
[TCA_MATCHALL_FLAGS] = { .type = NLA_U32 },
};
-static int mall_set_parms(struct net *net, struct tcf_proto *tp,
- struct cls_mall_head *head,
- unsigned long base, struct nlattr **tb,
- struct nlattr *est, u32 flags, u32 fl_flags,
- struct netlink_ext_ack *extack)
-{
- int err;
-
- err = tcf_exts_validate_ex(net, tp, tb, est, &head->exts, flags,
- fl_flags, extack);
- if (err < 0)
- return err;
-
- if (tb[TCA_MATCHALL_CLASSID]) {
- head->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]);
- tcf_bind_filter(tp, &head->res, base);
- }
- return 0;
-}
-
static int mall_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle, struct nlattr **tca,
@@ -187,6 +167,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
{
struct cls_mall_head *head = rtnl_dereference(tp->root);
struct nlattr *tb[TCA_MATCHALL_MAX + 1];
+ bool bound_to_filter = false;
struct cls_mall_head *new;
u32 userflags = 0;
int err;
@@ -226,11 +207,17 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
goto err_alloc_percpu;
}
- err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE],
- flags, new->flags, extack);
- if (err)
+ err = tcf_exts_validate_ex(net, tp, tb, tca[TCA_RATE],
+ &new->exts, flags, new->flags, extack);
+ if (err < 0)
goto err_set_parms;
+ if (tb[TCA_MATCHALL_CLASSID]) {
+ new->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]);
+ tcf_bind_filter(tp, &new->res, base);
+ bound_to_filter = true;
+ }
+
if (!tc_skip_hw(new->flags)) {
err = mall_replace_hw_filter(tp, new, (unsigned long)new,
extack);
@@ -246,6 +233,8 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
return 0;
err_replace_hw_filter:
+ if (bound_to_filter)
+ tcf_unbind_filter(tp, &new->res);
err_set_parms:
free_percpu(new->pf);
err_alloc_percpu:
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v4 2/5] net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode fails
2023-07-12 21:13 [PATCH net-next v4 0/5] net: sched: Fixes for classifiers Victor Nogueira
2023-07-12 21:13 ` [PATCH net-next v4 1/5] net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms Victor Nogueira
@ 2023-07-12 21:13 ` Victor Nogueira
2023-07-13 9:17 ` Simon Horman
2023-07-12 21:13 ` [PATCH net-next v4 3/5] net: sched: cls_u32: Undo refcount decrement in case update failed Victor Nogueira
` (3 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Victor Nogueira @ 2023-07-12 21:13 UTC (permalink / raw)
To: netdev
Cc: jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, simon.horman, kernel
When u32_replace_hw_knode fails, we need to undo the tcf_bind_filter
operation done at u32_set_parms.
Fixes: d34e3e181395 ("net: cls_u32: Add support for skip-sw flag to tc u32 classifier.")
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
---
net/sched/cls_u32.c | 41 ++++++++++++++++++++++++++++++-----------
1 file changed, 30 insertions(+), 11 deletions(-)
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index d15d50de7980..ed358466d042 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -712,8 +712,23 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
[TCA_U32_FLAGS] = { .type = NLA_U32 },
};
+static void u32_unbind_filter(struct tcf_proto *tp, struct tc_u_knode *n,
+ struct nlattr **tb)
+{
+ if (tb[TCA_U32_CLASSID])
+ tcf_unbind_filter(tp, &n->res);
+}
+
+static void u32_bind_filter(struct tcf_proto *tp, struct tc_u_knode *n,
+ unsigned long base, struct nlattr **tb)
+{
+ if (tb[TCA_U32_CLASSID]) {
+ n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]);
+ tcf_bind_filter(tp, &n->res, base);
+ }
+}
+
static int u32_set_parms(struct net *net, struct tcf_proto *tp,
- unsigned long base,
struct tc_u_knode *n, struct nlattr **tb,
struct nlattr *est, u32 flags, u32 fl_flags,
struct netlink_ext_ack *extack)
@@ -760,10 +775,6 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp,
if (ht_old)
ht_old->refcnt--;
}
- if (tb[TCA_U32_CLASSID]) {
- n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]);
- tcf_bind_filter(tp, &n->res, base);
- }
if (ifindex >= 0)
n->ifindex = ifindex;
@@ -903,17 +914,20 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
if (!new)
return -ENOMEM;
- err = u32_set_parms(net, tp, base, new, tb,
- tca[TCA_RATE], flags, new->flags,
- extack);
+ err = u32_set_parms(net, tp, new, tb, tca[TCA_RATE],
+ flags, new->flags, extack);
if (err) {
__u32_destroy_key(new);
return err;
}
+ u32_bind_filter(tp, new, base, tb);
+
err = u32_replace_hw_knode(tp, new, flags, extack);
if (err) {
+ u32_unbind_filter(tp, new, tb);
+
__u32_destroy_key(new);
return err;
}
@@ -1074,15 +1088,18 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
}
#endif
- err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE],
+ err = u32_set_parms(net, tp, n, tb, tca[TCA_RATE],
flags, n->flags, extack);
+
+ u32_bind_filter(tp, n, base, tb);
+
if (err == 0) {
struct tc_u_knode __rcu **ins;
struct tc_u_knode *pins;
err = u32_replace_hw_knode(tp, n, flags, extack);
if (err)
- goto errhw;
+ goto errunbind;
if (!tc_in_hw(n->flags))
n->flags |= TCA_CLS_FLAGS_NOT_IN_HW;
@@ -1100,7 +1117,9 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
return 0;
}
-errhw:
+errunbind:
+ u32_unbind_filter(tp, n, tb);
+
#ifdef CONFIG_CLS_U32_MARK
free_percpu(n->pcpu_success);
#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v4 3/5] net: sched: cls_u32: Undo refcount decrement in case update failed
2023-07-12 21:13 [PATCH net-next v4 0/5] net: sched: Fixes for classifiers Victor Nogueira
2023-07-12 21:13 ` [PATCH net-next v4 1/5] net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms Victor Nogueira
2023-07-12 21:13 ` [PATCH net-next v4 2/5] net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode fails Victor Nogueira
@ 2023-07-12 21:13 ` Victor Nogueira
2023-07-13 9:17 ` Simon Horman
2023-07-12 21:13 ` [PATCH net-next v4 4/5] net: sched: cls_bpf: Undo tcf_bind_filter in case of an error Victor Nogueira
` (2 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Victor Nogueira @ 2023-07-12 21:13 UTC (permalink / raw)
To: netdev
Cc: jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, simon.horman, kernel
In the case of an update, when TCA_U32_LINK is set, u32_set_parms will
decrement the refcount of the ht_down (struct tc_u_hnode) pointer
present in the older u32 filter which we are replacing. However, if
u32_replace_hw_knode errors out, the update command fails and that
ht_down pointer continues decremented. To fix that, when
u32_replace_hw_knode fails, check if ht_down's refcount was decremented
and undo the decrement.
Fixes: d34e3e181395 ("net: cls_u32: Add support for skip-sw flag to tc u32 classifier.")
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
---
net/sched/cls_u32.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index ed358466d042..5abf31e432ca 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -928,6 +928,13 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
if (err) {
u32_unbind_filter(tp, new, tb);
+ if (tb[TCA_U32_LINK]) {
+ struct tc_u_hnode *ht_old;
+
+ ht_old = rtnl_dereference(n->ht_down);
+ if (ht_old)
+ ht_old->refcnt++;
+ }
__u32_destroy_key(new);
return err;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v4 4/5] net: sched: cls_bpf: Undo tcf_bind_filter in case of an error
2023-07-12 21:13 [PATCH net-next v4 0/5] net: sched: Fixes for classifiers Victor Nogueira
` (2 preceding siblings ...)
2023-07-12 21:13 ` [PATCH net-next v4 3/5] net: sched: cls_u32: Undo refcount decrement in case update failed Victor Nogueira
@ 2023-07-12 21:13 ` Victor Nogueira
2023-07-13 9:18 ` Simon Horman
2023-07-12 21:13 ` [PATCH net-next v4 5/5] net: sched: cls_flower: " Victor Nogueira
2023-07-13 17:25 ` [PATCH net-next v4 0/5] net: sched: Fixes for classifiers Jakub Kicinski
5 siblings, 1 reply; 12+ messages in thread
From: Victor Nogueira @ 2023-07-12 21:13 UTC (permalink / raw)
To: netdev
Cc: jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, simon.horman, kernel
If cls_bpf_offload errors out, we must also undo tcf_bind_filter that
was done before the error.
Fix that by calling tcf_unbind_filter in errout_parms.
Fixes: eadb41489fd2 ("net: cls_bpf: add support for marking filters as hardware-only")
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
---
net/sched/cls_bpf.c | 99 +++++++++++++++++++++------------------------
1 file changed, 47 insertions(+), 52 deletions(-)
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index 466c26df853a..382c7a71f81f 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -406,56 +406,6 @@ static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog,
return 0;
}
-static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp,
- struct cls_bpf_prog *prog, unsigned long base,
- struct nlattr **tb, struct nlattr *est, u32 flags,
- struct netlink_ext_ack *extack)
-{
- bool is_bpf, is_ebpf, have_exts = false;
- u32 gen_flags = 0;
- int ret;
-
- is_bpf = tb[TCA_BPF_OPS_LEN] && tb[TCA_BPF_OPS];
- is_ebpf = tb[TCA_BPF_FD];
- if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf))
- return -EINVAL;
-
- ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, flags,
- extack);
- if (ret < 0)
- return ret;
-
- if (tb[TCA_BPF_FLAGS]) {
- u32 bpf_flags = nla_get_u32(tb[TCA_BPF_FLAGS]);
-
- if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT)
- return -EINVAL;
-
- have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT;
- }
- if (tb[TCA_BPF_FLAGS_GEN]) {
- gen_flags = nla_get_u32(tb[TCA_BPF_FLAGS_GEN]);
- if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS ||
- !tc_flags_valid(gen_flags))
- return -EINVAL;
- }
-
- prog->exts_integrated = have_exts;
- prog->gen_flags = gen_flags;
-
- ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog) :
- cls_bpf_prog_from_efd(tb, prog, gen_flags, tp);
- if (ret < 0)
- return ret;
-
- if (tb[TCA_BPF_CLASSID]) {
- prog->res.classid = nla_get_u32(tb[TCA_BPF_CLASSID]);
- tcf_bind_filter(tp, &prog->res, base);
- }
-
- return 0;
-}
-
static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle, struct nlattr **tca,
@@ -463,9 +413,12 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
struct netlink_ext_ack *extack)
{
struct cls_bpf_head *head = rtnl_dereference(tp->root);
+ bool is_bpf, is_ebpf, have_exts = false;
struct cls_bpf_prog *oldprog = *arg;
struct nlattr *tb[TCA_BPF_MAX + 1];
+ bool bound_to_filter = false;
struct cls_bpf_prog *prog;
+ u32 gen_flags = 0;
int ret;
if (tca[TCA_OPTIONS] == NULL)
@@ -504,11 +457,51 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
goto errout;
prog->handle = handle;
- ret = cls_bpf_set_parms(net, tp, prog, base, tb, tca[TCA_RATE], flags,
- extack);
+ is_bpf = tb[TCA_BPF_OPS_LEN] && tb[TCA_BPF_OPS];
+ is_ebpf = tb[TCA_BPF_FD];
+ if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf)) {
+ ret = -EINVAL;
+ goto errout_idr;
+ }
+
+ ret = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &prog->exts,
+ flags, extack);
+ if (ret < 0)
+ goto errout_idr;
+
+ if (tb[TCA_BPF_FLAGS]) {
+ u32 bpf_flags = nla_get_u32(tb[TCA_BPF_FLAGS]);
+
+ if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT) {
+ ret = -EINVAL;
+ goto errout_idr;
+ }
+
+ have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT;
+ }
+ if (tb[TCA_BPF_FLAGS_GEN]) {
+ gen_flags = nla_get_u32(tb[TCA_BPF_FLAGS_GEN]);
+ if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS ||
+ !tc_flags_valid(gen_flags)) {
+ ret = -EINVAL;
+ goto errout_idr;
+ }
+ }
+
+ prog->exts_integrated = have_exts;
+ prog->gen_flags = gen_flags;
+
+ ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog) :
+ cls_bpf_prog_from_efd(tb, prog, gen_flags, tp);
if (ret < 0)
goto errout_idr;
+ if (tb[TCA_BPF_CLASSID]) {
+ prog->res.classid = nla_get_u32(tb[TCA_BPF_CLASSID]);
+ tcf_bind_filter(tp, &prog->res, base);
+ bound_to_filter = true;
+ }
+
ret = cls_bpf_offload(tp, prog, oldprog, extack);
if (ret)
goto errout_parms;
@@ -530,6 +523,8 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
return 0;
errout_parms:
+ if (bound_to_filter)
+ tcf_unbind_filter(tp, &prog->res);
cls_bpf_free_parms(prog);
errout_idr:
if (!oldprog)
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v4 5/5] net: sched: cls_flower: Undo tcf_bind_filter in case of an error
2023-07-12 21:13 [PATCH net-next v4 0/5] net: sched: Fixes for classifiers Victor Nogueira
` (3 preceding siblings ...)
2023-07-12 21:13 ` [PATCH net-next v4 4/5] net: sched: cls_bpf: Undo tcf_bind_filter in case of an error Victor Nogueira
@ 2023-07-12 21:13 ` Victor Nogueira
2023-07-13 9:18 ` Simon Horman
2023-07-13 17:25 ` [PATCH net-next v4 0/5] net: sched: Fixes for classifiers Jakub Kicinski
5 siblings, 1 reply; 12+ messages in thread
From: Victor Nogueira @ 2023-07-12 21:13 UTC (permalink / raw)
To: netdev
Cc: jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, simon.horman, kernel
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: 77b9900ef53a ("tc: introduce Flower classifier")
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
---
net/sched/cls_flower.c | 99 ++++++++++++++++++++----------------------
1 file changed, 47 insertions(+), 52 deletions(-)
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index f2b0bc4142fe..8da9d039d964 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -2173,53 +2173,6 @@ static bool fl_needs_tc_skb_ext(const struct fl_flow_key *mask)
return mask->meta.l2_miss;
}
-static int fl_set_parms(struct net *net, struct tcf_proto *tp,
- struct cls_fl_filter *f, struct fl_flow_mask *mask,
- unsigned long base, struct nlattr **tb,
- struct nlattr *est,
- struct fl_flow_tmplt *tmplt,
- u32 flags, u32 fl_flags,
- struct netlink_ext_ack *extack)
-{
- int err;
-
- err = tcf_exts_validate_ex(net, tp, tb, est, &f->exts, flags,
- fl_flags, extack);
- if (err < 0)
- return err;
-
- if (tb[TCA_FLOWER_CLASSID]) {
- f->res.classid = nla_get_u32(tb[TCA_FLOWER_CLASSID]);
- if (flags & TCA_ACT_FLAGS_NO_RTNL)
- rtnl_lock();
- tcf_bind_filter(tp, &f->res, base);
- if (flags & TCA_ACT_FLAGS_NO_RTNL)
- rtnl_unlock();
- }
-
- err = fl_set_key(net, tb, &f->key, &mask->key, extack);
- if (err)
- return err;
-
- 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;
- }
-
- /* Enable tc skb extension if filter matches on data extracted from
- * this extension.
- */
- if (fl_needs_tc_skb_ext(&mask->key)) {
- f->needs_tc_skb_ext = 1;
- tc_skb_ext_tc_enable();
- }
-
- return 0;
-}
-
static int fl_ht_insert_unique(struct cls_fl_filter *fnew,
struct cls_fl_filter *fold,
bool *in_ht)
@@ -2251,6 +2204,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;
@@ -2335,15 +2289,46 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
if (err < 0)
goto errout_idr;
- err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE],
- tp->chain->tmplt_priv, flags, fnew->flags,
- extack);
- if (err)
+ err = tcf_exts_validate_ex(net, tp, tb, tca[TCA_RATE],
+ &fnew->exts, flags, fnew->flags,
+ extack);
+ if (err < 0)
goto errout_idr;
+ if (tb[TCA_FLOWER_CLASSID]) {
+ fnew->res.classid = nla_get_u32(tb[TCA_FLOWER_CLASSID]);
+ if (flags & TCA_ACT_FLAGS_NO_RTNL)
+ rtnl_lock();
+ tcf_bind_filter(tp, &fnew->res, base);
+ if (flags & TCA_ACT_FLAGS_NO_RTNL)
+ rtnl_unlock();
+ bound_to_filter = true;
+ }
+
+ err = fl_set_key(net, tb, &fnew->key, &mask->key, extack);
+ if (err)
+ goto unbind_filter;
+
+ fl_mask_update_range(mask);
+ fl_set_masked_key(&fnew->mkey, &fnew->key, mask);
+
+ if (!fl_mask_fits_tmplt(tp->chain->tmplt_priv, mask)) {
+ NL_SET_ERR_MSG_MOD(extack, "Mask does not fit the template");
+ err = -EINVAL;
+ goto unbind_filter;
+ }
+
+ /* Enable tc skb extension if filter matches on data extracted from
+ * this extension.
+ */
+ if (fl_needs_tc_skb_ext(&mask->key)) {
+ fnew->needs_tc_skb_ext = 1;
+ tc_skb_ext_tc_enable();
+ }
+
err = fl_check_assign_mask(head, fnew, fold, mask);
if (err)
- goto errout_idr;
+ goto unbind_filter;
err = fl_ht_insert_unique(fnew, fold, &in_ht);
if (err)
@@ -2434,6 +2419,16 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
fnew->mask->filter_ht_params);
errout_mask:
fl_mask_put(head, fnew->mask);
+
+unbind_filter:
+ 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();
+ }
+
errout_idr:
if (!fold)
idr_remove(&head->handle_idr, fnew->handle);
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v4 1/5] net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms
2023-07-12 21:13 ` [PATCH net-next v4 1/5] net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms Victor Nogueira
@ 2023-07-13 9:17 ` Simon Horman
0 siblings, 0 replies; 12+ messages in thread
From: Simon Horman @ 2023-07-13 9:17 UTC (permalink / raw)
To: Victor Nogueira
Cc: netdev, jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, kernel
On Wed, Jul 12, 2023 at 06:13:09PM -0300, Victor Nogueira wrote:
> 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: ec2507d2a306 ("net/sched: cls_matchall: Fix error path")
> Signed-off-by: Victor Nogueira <victor@mojatatu.com>
> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
> Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v4 2/5] net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode fails
2023-07-12 21:13 ` [PATCH net-next v4 2/5] net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode fails Victor Nogueira
@ 2023-07-13 9:17 ` Simon Horman
0 siblings, 0 replies; 12+ messages in thread
From: Simon Horman @ 2023-07-13 9:17 UTC (permalink / raw)
To: Victor Nogueira
Cc: netdev, jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, kernel
On Wed, Jul 12, 2023 at 06:13:10PM -0300, Victor Nogueira wrote:
> When u32_replace_hw_knode fails, we need to undo the tcf_bind_filter
> operation done at u32_set_parms.
>
> Fixes: d34e3e181395 ("net: cls_u32: Add support for skip-sw flag to tc u32 classifier.")
> Signed-off-by: Victor Nogueira <victor@mojatatu.com>
> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
> Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v4 3/5] net: sched: cls_u32: Undo refcount decrement in case update failed
2023-07-12 21:13 ` [PATCH net-next v4 3/5] net: sched: cls_u32: Undo refcount decrement in case update failed Victor Nogueira
@ 2023-07-13 9:17 ` Simon Horman
0 siblings, 0 replies; 12+ messages in thread
From: Simon Horman @ 2023-07-13 9:17 UTC (permalink / raw)
To: Victor Nogueira
Cc: netdev, jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, kernel
On Wed, Jul 12, 2023 at 06:13:11PM -0300, Victor Nogueira wrote:
> In the case of an update, when TCA_U32_LINK is set, u32_set_parms will
> decrement the refcount of the ht_down (struct tc_u_hnode) pointer
> present in the older u32 filter which we are replacing. However, if
> u32_replace_hw_knode errors out, the update command fails and that
> ht_down pointer continues decremented. To fix that, when
> u32_replace_hw_knode fails, check if ht_down's refcount was decremented
> and undo the decrement.
>
> Fixes: d34e3e181395 ("net: cls_u32: Add support for skip-sw flag to tc u32 classifier.")
> Signed-off-by: Victor Nogueira <victor@mojatatu.com>
> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
> Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v4 4/5] net: sched: cls_bpf: Undo tcf_bind_filter in case of an error
2023-07-12 21:13 ` [PATCH net-next v4 4/5] net: sched: cls_bpf: Undo tcf_bind_filter in case of an error Victor Nogueira
@ 2023-07-13 9:18 ` Simon Horman
0 siblings, 0 replies; 12+ messages in thread
From: Simon Horman @ 2023-07-13 9:18 UTC (permalink / raw)
To: Victor Nogueira
Cc: netdev, jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, kernel
On Wed, Jul 12, 2023 at 06:13:12PM -0300, Victor Nogueira wrote:
> If cls_bpf_offload errors out, we must also undo tcf_bind_filter that
> was done before the error.
>
> Fix that by calling tcf_unbind_filter in errout_parms.
>
> Fixes: eadb41489fd2 ("net: cls_bpf: add support for marking filters as hardware-only")
> Signed-off-by: Victor Nogueira <victor@mojatatu.com>
> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
> Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v4 5/5] net: sched: cls_flower: Undo tcf_bind_filter in case of an error
2023-07-12 21:13 ` [PATCH net-next v4 5/5] net: sched: cls_flower: " Victor Nogueira
@ 2023-07-13 9:18 ` Simon Horman
0 siblings, 0 replies; 12+ messages in thread
From: Simon Horman @ 2023-07-13 9:18 UTC (permalink / raw)
To: Victor Nogueira
Cc: netdev, jhs, xiyou.wangcong, jiri, davem, edumazet, kuba, pabeni,
pctammela, kernel
On Wed, Jul 12, 2023 at 06:13:13PM -0300, Victor Nogueira wrote:
> 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: 77b9900ef53a ("tc: introduce Flower classifier")
> Signed-off-by: Victor Nogueira <victor@mojatatu.com>
> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
> Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v4 0/5] net: sched: Fixes for classifiers
2023-07-12 21:13 [PATCH net-next v4 0/5] net: sched: Fixes for classifiers Victor Nogueira
` (4 preceding siblings ...)
2023-07-12 21:13 ` [PATCH net-next v4 5/5] net: sched: cls_flower: " Victor Nogueira
@ 2023-07-13 17:25 ` Jakub Kicinski
5 siblings, 0 replies; 12+ messages in thread
From: Jakub Kicinski @ 2023-07-13 17:25 UTC (permalink / raw)
To: Victor Nogueira
Cc: netdev, jhs, xiyou.wangcong, jiri, davem, edumazet, pabeni,
pctammela, simon.horman, kernel
On Wed, 12 Jul 2023 18:13:08 -0300 Victor Nogueira wrote:
> Four different classifiers (bpf, u32, matchall, and flower) are
> calling tcf_bind_filter in their callbacks, but arent't undoing it by
> calling tcf_unbind_filter if their was an error after binding.
>
> This patch set fixes all this by calling tcf_unbind_filter in such
> cases.
>
> This set also undoes a refcount decrement in cls_u32 when an update
> fails under specific conditions which are described in patch #3.
I haven't looked the code, and probably won't have the time until
the evening, so to save time - if these are fixes they will have to
be reposted against net, not net-next.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2023-07-13 17:25 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-12 21:13 [PATCH net-next v4 0/5] net: sched: Fixes for classifiers Victor Nogueira
2023-07-12 21:13 ` [PATCH net-next v4 1/5] net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms Victor Nogueira
2023-07-13 9:17 ` Simon Horman
2023-07-12 21:13 ` [PATCH net-next v4 2/5] net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode fails Victor Nogueira
2023-07-13 9:17 ` Simon Horman
2023-07-12 21:13 ` [PATCH net-next v4 3/5] net: sched: cls_u32: Undo refcount decrement in case update failed Victor Nogueira
2023-07-13 9:17 ` Simon Horman
2023-07-12 21:13 ` [PATCH net-next v4 4/5] net: sched: cls_bpf: Undo tcf_bind_filter in case of an error Victor Nogueira
2023-07-13 9:18 ` Simon Horman
2023-07-12 21:13 ` [PATCH net-next v4 5/5] net: sched: cls_flower: " Victor Nogueira
2023-07-13 9:18 ` Simon Horman
2023-07-13 17:25 ` [PATCH net-next v4 0/5] net: sched: Fixes for classifiers Jakub Kicinski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).