1 From eab2fc822af38f31fd5f4e731b5d10b94904d919 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
3 Date: Thu, 14 Mar 2019 23:08:22 +0100
4 Subject: [PATCH] sch_cake: Interpret fwmark parameter as a bitmask
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
9 We initially interpreted the fwmark parameter as a flag that simply turned
10 on the feature, using the whole skb->mark field as the index into the CAKE
11 tin_order array. However, it is quite common for different applications to
12 use different parts of the mask field for their own purposes, each using a
15 Support this use of subsets of the mark by interpreting the TCA_CAKE_FWMARK
16 parameter as a bitmask to apply to the fwmark field when reading it. The
17 result will be right-shifted by the number of unset lower bits of the mask
18 before looking up the tin.
20 In the original commit message we also failed to credit Felix Resch with
21 originally suggesting the fwmark feature back in 2017; so the Suggested-By
22 in this commit covers the whole fwmark feature.
24 Fixes: 0b5c7efdfc6e ("sch_cake: Permit use of connmarks as tin classifiers")
25 Suggested-by: Felix Resch <fuller@beif.de>
26 Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
27 Signed-off-by: David S. Miller <davem@davemloft.net>
28 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
30 net/sched/sch_cake.c | 25 ++++++++++++-------------
31 1 file changed, 12 insertions(+), 13 deletions(-)
33 --- a/net/sched/sch_cake.c
34 +++ b/net/sched/sch_cake.c
35 @@ -211,6 +211,9 @@ struct cake_sched_data {
42 /* time_next = time_this + ((len * rate_ns) >> rate_shft) */
44 ktime_t time_next_packet;
45 @@ -258,8 +261,7 @@ enum {
46 CAKE_FLAG_AUTORATE_INGRESS = BIT(1),
47 CAKE_FLAG_INGRESS = BIT(2),
48 CAKE_FLAG_WASH = BIT(3),
49 - CAKE_FLAG_SPLIT_GSO = BIT(4),
50 - CAKE_FLAG_FWMARK = BIT(5)
51 + CAKE_FLAG_SPLIT_GSO = BIT(4)
54 /* COBALT operates the Codel and BLUE algorithms in parallel, in order to
55 @@ -1554,7 +1556,7 @@ static struct cake_tin_data *cake_select
58 struct cake_sched_data *q = qdisc_priv(sch);
63 /* Tin selection: Default to diffserv-based selection, allow overriding
64 @@ -1562,6 +1564,7 @@ static struct cake_tin_data *cake_select
66 dscp = cake_handle_diffserv(skb,
67 q->rate_flags & CAKE_FLAG_WASH);
68 + mark = (skb->mark & q->fwmark_mask) >> q->fwmark_shft;
70 if (q->tin_mode == CAKE_DIFFSERV_BESTEFFORT)
72 @@ -2178,6 +2181,7 @@ static const struct nla_policy cake_poli
73 [TCA_CAKE_MPU] = { .type = NLA_U32 },
74 [TCA_CAKE_INGRESS] = { .type = NLA_U32 },
75 [TCA_CAKE_ACK_FILTER] = { .type = NLA_U32 },
76 + [TCA_CAKE_FWMARK] = { .type = NLA_U32 },
79 static void cake_set_rate(struct cake_tin_data *b, u64 rate, u32 mtu,
80 @@ -2625,10 +2629,8 @@ static int cake_change(struct Qdisc *sch
83 if (tb[TCA_CAKE_FWMARK]) {
84 - if (!!nla_get_u32(tb[TCA_CAKE_FWMARK]))
85 - q->rate_flags |= CAKE_FLAG_FWMARK;
87 - q->rate_flags &= ~CAKE_FLAG_FWMARK;
88 + q->fwmark_mask = nla_get_u32(tb[TCA_CAKE_FWMARK]);
89 + q->fwmark_shft = q->fwmark_mask ? __ffs(q->fwmark_mask) : 0;
93 @@ -2790,8 +2792,7 @@ static int cake_dump(struct Qdisc *sch,
94 !!(q->rate_flags & CAKE_FLAG_SPLIT_GSO)))
97 - if (nla_put_u32(skb, TCA_CAKE_FWMARK,
98 - !!(q->rate_flags & CAKE_FLAG_FWMARK)))
99 + if (nla_put_u32(skb, TCA_CAKE_FWMARK, q->fwmark_mask))
100 goto nla_put_failure;
102 return nla_nest_end(skb, opts);