Skip to content

Commit

Permalink
net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode
Browse files Browse the repository at this point in the history
When u32_replace_hw_knode fails, we need to undo the tcf_bind_filter
operation done at u32_set_parms.

Fixes: d34e3e1 ("net: cls_u32: Add support for skip-sw flag to tc u32 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]>
  • Loading branch information
vbnogueira authored and davem330 committed Jul 17, 2023
1 parent b3d0e04 commit 9cb36fa
Showing 1 changed file with 30 additions and 11 deletions.
41 changes: 30 additions & 11 deletions net/sched/cls_u32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down

0 comments on commit 9cb36fa

Please sign in to comment.