Skip to content

Commit e7e3728

Browse files
mengxiang0811davem330
authored andcommitted
net:sched: add action inheritdsfield to skbedit
The new action inheritdsfield copies the field DS of IPv4 and IPv6 packets into skb->priority. This enables later classification of packets based on the DS field. v5: *Update the drop counter for TC_ACT_SHOT v4: *Not allow setting flags other than the expected ones. *Allow dumping the pure flags. v3: *Use optional flags, so that it won't break old versions of tc. *Allow users to set both SKBEDIT_F_PRIORITY and SKBEDIT_F_INHERITDSFIELD flags. v2: *Fix the style issue *Move the code from skbmod to skbedit Original idea by Jamal Hadi Salim <[email protected]> Signed-off-by: Qiaobin Fu <[email protected]> Reviewed-by: Michel Machado <[email protected]> Acked-by: Jamal Hadi Salim <[email protected]> Reviewed-by: Marcelo Ricardo Leitner <[email protected]> Acked-by: Davide Caratti <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f145b0a commit e7e3728

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

include/uapi/linux/tc_act/tc_skbedit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#define SKBEDIT_F_MARK 0x4
3131
#define SKBEDIT_F_PTYPE 0x8
3232
#define SKBEDIT_F_MASK 0x10
33+
#define SKBEDIT_F_INHERITDSFIELD 0x20
3334

3435
struct tc_skbedit {
3536
tc_gen;
@@ -45,6 +46,7 @@ enum {
4546
TCA_SKBEDIT_PAD,
4647
TCA_SKBEDIT_PTYPE,
4748
TCA_SKBEDIT_MASK,
49+
TCA_SKBEDIT_FLAGS,
4850
__TCA_SKBEDIT_MAX
4951
};
5052
#define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1)

net/sched/act_skbedit.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#include <linux/rtnetlink.h>
2424
#include <net/netlink.h>
2525
#include <net/pkt_sched.h>
26+
#include <net/ip.h>
27+
#include <net/ipv6.h>
28+
#include <net/dsfield.h>
2629

2730
#include <linux/tc_act/tc_skbedit.h>
2831
#include <net/tc_act/tc_skbedit.h>
@@ -41,6 +44,25 @@ static int tcf_skbedit(struct sk_buff *skb, const struct tc_action *a,
4144

4245
if (d->flags & SKBEDIT_F_PRIORITY)
4346
skb->priority = d->priority;
47+
if (d->flags & SKBEDIT_F_INHERITDSFIELD) {
48+
int wlen = skb_network_offset(skb);
49+
50+
switch (tc_skb_protocol(skb)) {
51+
case htons(ETH_P_IP):
52+
wlen += sizeof(struct iphdr);
53+
if (!pskb_may_pull(skb, wlen))
54+
goto err;
55+
skb->priority = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
56+
break;
57+
58+
case htons(ETH_P_IPV6):
59+
wlen += sizeof(struct ipv6hdr);
60+
if (!pskb_may_pull(skb, wlen))
61+
goto err;
62+
skb->priority = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
63+
break;
64+
}
65+
}
4466
if (d->flags & SKBEDIT_F_QUEUE_MAPPING &&
4567
skb->dev->real_num_tx_queues > d->queue_mapping)
4668
skb_set_queue_mapping(skb, d->queue_mapping);
@@ -53,6 +75,11 @@ static int tcf_skbedit(struct sk_buff *skb, const struct tc_action *a,
5375

5476
spin_unlock(&d->tcf_lock);
5577
return d->tcf_action;
78+
79+
err:
80+
d->tcf_qstats.drops++;
81+
spin_unlock(&d->tcf_lock);
82+
return TC_ACT_SHOT;
5683
}
5784

5885
static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {
@@ -62,6 +89,7 @@ static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {
6289
[TCA_SKBEDIT_MARK] = { .len = sizeof(u32) },
6390
[TCA_SKBEDIT_PTYPE] = { .len = sizeof(u16) },
6491
[TCA_SKBEDIT_MASK] = { .len = sizeof(u32) },
92+
[TCA_SKBEDIT_FLAGS] = { .len = sizeof(u64) },
6593
};
6694

6795
static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
@@ -114,6 +142,13 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
114142
mask = nla_data(tb[TCA_SKBEDIT_MASK]);
115143
}
116144

145+
if (tb[TCA_SKBEDIT_FLAGS] != NULL) {
146+
u64 *pure_flags = nla_data(tb[TCA_SKBEDIT_FLAGS]);
147+
148+
if (*pure_flags & SKBEDIT_F_INHERITDSFIELD)
149+
flags |= SKBEDIT_F_INHERITDSFIELD;
150+
}
151+
117152
parm = nla_data(tb[TCA_SKBEDIT_PARMS]);
118153

119154
exists = tcf_idr_check(tn, parm->index, a, bind);
@@ -178,6 +213,7 @@ static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
178213
.action = d->tcf_action,
179214
};
180215
struct tcf_t t;
216+
u64 pure_flags = 0;
181217

182218
if (nla_put(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt))
183219
goto nla_put_failure;
@@ -196,6 +232,11 @@ static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
196232
if ((d->flags & SKBEDIT_F_MASK) &&
197233
nla_put_u32(skb, TCA_SKBEDIT_MASK, d->mask))
198234
goto nla_put_failure;
235+
if (d->flags & SKBEDIT_F_INHERITDSFIELD)
236+
pure_flags |= SKBEDIT_F_INHERITDSFIELD;
237+
if (pure_flags != 0 &&
238+
nla_put(skb, TCA_SKBEDIT_FLAGS, sizeof(pure_flags), &pure_flags))
239+
goto nla_put_failure;
199240

200241
tcf_tm_dump(&t, &d->tcf_tm);
201242
if (nla_put_64bit(skb, TCA_SKBEDIT_TM, sizeof(t), &t, TCA_SKBEDIT_PAD))

0 commit comments

Comments
 (0)