Skip to content

Commit a934579

Browse files
vbnogueiragregkh
authored andcommitted
net: sched: cls_u32: Undo tcf_bind_filter if u32_replace_hw_knode
[ Upstream commit 9cb36fa ] 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 <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> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent fa753f8 commit a934579

1 file changed

Lines changed: 30 additions & 11 deletions

File tree

net/sched/cls_u32.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,23 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
710710
[TCA_U32_FLAGS] = { .type = NLA_U32 },
711711
};
712712

713+
static void u32_unbind_filter(struct tcf_proto *tp, struct tc_u_knode *n,
714+
struct nlattr **tb)
715+
{
716+
if (tb[TCA_U32_CLASSID])
717+
tcf_unbind_filter(tp, &n->res);
718+
}
719+
720+
static void u32_bind_filter(struct tcf_proto *tp, struct tc_u_knode *n,
721+
unsigned long base, struct nlattr **tb)
722+
{
723+
if (tb[TCA_U32_CLASSID]) {
724+
n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]);
725+
tcf_bind_filter(tp, &n->res, base);
726+
}
727+
}
728+
713729
static int u32_set_parms(struct net *net, struct tcf_proto *tp,
714-
unsigned long base,
715730
struct tc_u_knode *n, struct nlattr **tb,
716731
struct nlattr *est, u32 flags, u32 fl_flags,
717732
struct netlink_ext_ack *extack)
@@ -758,10 +773,6 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp,
758773
if (ht_old)
759774
ht_old->refcnt--;
760775
}
761-
if (tb[TCA_U32_CLASSID]) {
762-
n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]);
763-
tcf_bind_filter(tp, &n->res, base);
764-
}
765776

766777
if (ifindex >= 0)
767778
n->ifindex = ifindex;
@@ -901,17 +912,20 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
901912
if (!new)
902913
return -ENOMEM;
903914

904-
err = u32_set_parms(net, tp, base, new, tb,
905-
tca[TCA_RATE], flags, new->flags,
906-
extack);
915+
err = u32_set_parms(net, tp, new, tb, tca[TCA_RATE],
916+
flags, new->flags, extack);
907917

908918
if (err) {
909919
__u32_destroy_key(new);
910920
return err;
911921
}
912922

923+
u32_bind_filter(tp, new, base, tb);
924+
913925
err = u32_replace_hw_knode(tp, new, flags, extack);
914926
if (err) {
927+
u32_unbind_filter(tp, new, tb);
928+
915929
__u32_destroy_key(new);
916930
return err;
917931
}
@@ -1072,15 +1086,18 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
10721086
}
10731087
#endif
10741088

1075-
err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE],
1089+
err = u32_set_parms(net, tp, n, tb, tca[TCA_RATE],
10761090
flags, n->flags, extack);
1091+
1092+
u32_bind_filter(tp, n, base, tb);
1093+
10771094
if (err == 0) {
10781095
struct tc_u_knode __rcu **ins;
10791096
struct tc_u_knode *pins;
10801097

10811098
err = u32_replace_hw_knode(tp, n, flags, extack);
10821099
if (err)
1083-
goto errhw;
1100+
goto errunbind;
10841101

10851102
if (!tc_in_hw(n->flags))
10861103
n->flags |= TCA_CLS_FLAGS_NOT_IN_HW;
@@ -1098,7 +1115,9 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
10981115
return 0;
10991116
}
11001117

1101-
errhw:
1118+
errunbind:
1119+
u32_unbind_filter(tp, n, tb);
1120+
11021121
#ifdef CONFIG_CLS_U32_MARK
11031122
free_percpu(n->pcpu_success);
11041123
#endif

0 commit comments

Comments
 (0)