Skip to content

Commit b87f793

Browse files
yotamgidavem330
authored andcommitted
net/sched: Add match-all classifier hw offloading.
Following the work that have been done on offloading classifiers like u32 and flower, now the match-all classifier hw offloading is possible. if the interface supports tc offloading. To control the offloading, two tc flags have been introduced: skip_sw and skip_hw. Typical usage: tc filter add dev eth25 parent ffff: \ matchall skip_sw \ action mirred egress mirror \ dev eth27 Signed-off-by: Yotam Gigi <yotamg@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent bf3994d commit b87f793

File tree

4 files changed

+87
-3
lines changed

4 files changed

+87
-3
lines changed

include/linux/netdevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ enum {
787787
TC_SETUP_MQPRIO,
788788
TC_SETUP_CLSU32,
789789
TC_SETUP_CLSFLOWER,
790+
TC_SETUP_MATCHALL,
790791
};
791792

792793
struct tc_cls_u32_offload;
@@ -797,6 +798,7 @@ struct tc_to_netdev {
797798
u8 tc;
798799
struct tc_cls_u32_offload *cls_u32;
799800
struct tc_cls_flower_offload *cls_flower;
801+
struct tc_cls_matchall_offload *cls_mall;
800802
};
801803
};
802804

include/net/pkt_cls.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,4 +442,15 @@ struct tc_cls_flower_offload {
442442
struct tcf_exts *exts;
443443
};
444444

445+
enum tc_matchall_command {
446+
TC_CLSMATCHALL_REPLACE,
447+
TC_CLSMATCHALL_DESTROY,
448+
};
449+
450+
struct tc_cls_matchall_offload {
451+
enum tc_matchall_command command;
452+
struct tcf_exts *exts;
453+
unsigned long cookie;
454+
};
455+
445456
#endif

include/uapi/linux/pkt_cls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ enum {
439439
TCA_MATCHALL_UNSPEC,
440440
TCA_MATCHALL_CLASSID,
441441
TCA_MATCHALL_ACT,
442+
TCA_MATCHALL_FLAGS,
442443
__TCA_MATCHALL_MAX,
443444
};
444445

net/sched/cls_matchall.c

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct cls_mall_filter {
2121
struct tcf_result res;
2222
u32 handle;
2323
struct rcu_head rcu;
24+
u32 flags;
2425
};
2526

2627
struct cls_mall_head {
@@ -34,6 +35,9 @@ static int mall_classify(struct sk_buff *skb, const struct tcf_proto *tp,
3435
struct cls_mall_head *head = rcu_dereference_bh(tp->root);
3536
struct cls_mall_filter *f = head->filter;
3637

38+
if (tc_skip_sw(f->flags))
39+
return -1;
40+
3741
return tcf_exts_exec(skb, &f->exts, res);
3842
}
3943

@@ -55,18 +59,61 @@ static void mall_destroy_filter(struct rcu_head *head)
5559
struct cls_mall_filter *f = container_of(head, struct cls_mall_filter, rcu);
5660

5761
tcf_exts_destroy(&f->exts);
62+
5863
kfree(f);
5964
}
6065

66+
static int mall_replace_hw_filter(struct tcf_proto *tp,
67+
struct cls_mall_filter *f,
68+
unsigned long cookie)
69+
{
70+
struct net_device *dev = tp->q->dev_queue->dev;
71+
struct tc_to_netdev offload;
72+
struct tc_cls_matchall_offload mall_offload = {0};
73+
74+
offload.type = TC_SETUP_MATCHALL;
75+
offload.cls_mall = &mall_offload;
76+
offload.cls_mall->command = TC_CLSMATCHALL_REPLACE;
77+
offload.cls_mall->exts = &f->exts;
78+
offload.cls_mall->cookie = cookie;
79+
80+
return dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol,
81+
&offload);
82+
}
83+
84+
static void mall_destroy_hw_filter(struct tcf_proto *tp,
85+
struct cls_mall_filter *f,
86+
unsigned long cookie)
87+
{
88+
struct net_device *dev = tp->q->dev_queue->dev;
89+
struct tc_to_netdev offload;
90+
struct tc_cls_matchall_offload mall_offload = {0};
91+
92+
offload.type = TC_SETUP_MATCHALL;
93+
offload.cls_mall = &mall_offload;
94+
offload.cls_mall->command = TC_CLSMATCHALL_DESTROY;
95+
offload.cls_mall->exts = NULL;
96+
offload.cls_mall->cookie = cookie;
97+
98+
dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol,
99+
&offload);
100+
}
101+
61102
static bool mall_destroy(struct tcf_proto *tp, bool force)
62103
{
63104
struct cls_mall_head *head = rtnl_dereference(tp->root);
105+
struct net_device *dev = tp->q->dev_queue->dev;
106+
struct cls_mall_filter *f = head->filter;
64107

65-
if (!force && head->filter)
108+
if (!force && f)
66109
return false;
67110

68-
if (head->filter)
69-
call_rcu(&head->filter->rcu, mall_destroy_filter);
111+
if (f) {
112+
if (tc_should_offload(dev, tp, f->flags))
113+
mall_destroy_hw_filter(tp, f, (unsigned long) f);
114+
115+
call_rcu(&f->rcu, mall_destroy_filter);
116+
}
70117
RCU_INIT_POINTER(tp->root, NULL);
71118
kfree_rcu(head, rcu);
72119
return true;
@@ -117,8 +164,10 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
117164
{
118165
struct cls_mall_head *head = rtnl_dereference(tp->root);
119166
struct cls_mall_filter *fold = (struct cls_mall_filter *) *arg;
167+
struct net_device *dev = tp->q->dev_queue->dev;
120168
struct cls_mall_filter *f;
121169
struct nlattr *tb[TCA_MATCHALL_MAX + 1];
170+
u32 flags = 0;
122171
int err;
123172

124173
if (!tca[TCA_OPTIONS])
@@ -135,6 +184,12 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
135184
if (err < 0)
136185
return err;
137186

187+
if (tb[TCA_MATCHALL_FLAGS]) {
188+
flags = nla_get_u32(tb[TCA_MATCHALL_FLAGS]);
189+
if (!tc_flags_valid(flags))
190+
return -EINVAL;
191+
}
192+
138193
f = kzalloc(sizeof(*f), GFP_KERNEL);
139194
if (!f)
140195
return -ENOBUFS;
@@ -144,11 +199,22 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
144199
if (!handle)
145200
handle = 1;
146201
f->handle = handle;
202+
f->flags = flags;
147203

148204
err = mall_set_parms(net, tp, f, base, tb, tca[TCA_RATE], ovr);
149205
if (err)
150206
goto errout;
151207

208+
if (tc_should_offload(dev, tp, flags)) {
209+
err = mall_replace_hw_filter(tp, f, (unsigned long) f);
210+
if (err) {
211+
if (tc_skip_sw(flags))
212+
goto errout;
213+
else
214+
err = 0;
215+
}
216+
}
217+
152218
*arg = (unsigned long) f;
153219
rcu_assign_pointer(head->filter, f);
154220

@@ -163,6 +229,10 @@ static int mall_delete(struct tcf_proto *tp, unsigned long arg)
163229
{
164230
struct cls_mall_head *head = rtnl_dereference(tp->root);
165231
struct cls_mall_filter *f = (struct cls_mall_filter *) arg;
232+
struct net_device *dev = tp->q->dev_queue->dev;
233+
234+
if (tc_should_offload(dev, tp, f->flags))
235+
mall_destroy_hw_filter(tp, f, (unsigned long) f);
166236

167237
RCU_INIT_POINTER(head->filter, NULL);
168238
tcf_unbind_filter(tp, &f->res);

0 commit comments

Comments
 (0)