Skip to content

Commit 8c4083b

Browse files
jpirkodavem330
authored andcommitted
net: sched: add block bind/unbind notif. and extended block_get/put
Introduce new type of ndo_setup_tc message to propage binding/unbinding of a block to driver. Call this ndo whenever qdisc gets/puts a block. Alongside with this, there's need to propagate binder type from qdisc code down to the notifier. So introduce extended variants of block_get/put in order to pass this info. Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b65f164 commit 8c4083b

File tree

3 files changed

+94
-3
lines changed

3 files changed

+94
-3
lines changed

include/linux/netdevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,7 @@ enum tc_setup_type {
775775
TC_SETUP_CLSFLOWER,
776776
TC_SETUP_CLSMATCHALL,
777777
TC_SETUP_CLSBPF,
778+
TC_SETUP_BLOCK,
778779
};
779780

780781
/* These structures hold the attributes of xdp state that are being passed

include/net/pkt_cls.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,27 @@ struct tcf_walker {
1717
int register_tcf_proto_ops(struct tcf_proto_ops *ops);
1818
int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
1919

20+
enum tcf_block_binder_type {
21+
TCF_BLOCK_BINDER_TYPE_UNSPEC,
22+
};
23+
24+
struct tcf_block_ext_info {
25+
enum tcf_block_binder_type binder_type;
26+
};
27+
2028
#ifdef CONFIG_NET_CLS
2129
struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
2230
bool create);
2331
void tcf_chain_put(struct tcf_chain *chain);
2432
int tcf_block_get(struct tcf_block **p_block,
2533
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q);
34+
int tcf_block_get_ext(struct tcf_block **p_block,
35+
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
36+
struct tcf_block_ext_info *ei);
2637
void tcf_block_put(struct tcf_block *block);
38+
void tcf_block_put_ext(struct tcf_block *block,
39+
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
40+
struct tcf_block_ext_info *ei);
2741

2842
static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
2943
{
@@ -46,10 +60,25 @@ int tcf_block_get(struct tcf_block **p_block,
4660
return 0;
4761
}
4862

63+
static inline
64+
int tcf_block_get_ext(struct tcf_block **p_block,
65+
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
66+
struct tcf_block_ext_info *ei)
67+
{
68+
return 0;
69+
}
70+
4971
static inline void tcf_block_put(struct tcf_block *block)
5072
{
5173
}
5274

75+
static inline
76+
void tcf_block_put_ext(struct tcf_block *block,
77+
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
78+
struct tcf_block_ext_info *ei)
79+
{
80+
}
81+
5382
static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
5483
{
5584
return NULL;
@@ -434,6 +463,17 @@ tcf_match_indev(struct sk_buff *skb, int ifindex)
434463
int tc_setup_cb_call(struct tcf_exts *exts, enum tc_setup_type type,
435464
void *type_data, bool err_stop);
436465

466+
enum tc_block_command {
467+
TC_BLOCK_BIND,
468+
TC_BLOCK_UNBIND,
469+
};
470+
471+
struct tc_block_offload {
472+
enum tc_block_command command;
473+
enum tcf_block_binder_type binder_type;
474+
struct tcf_block *block;
475+
};
476+
437477
struct tc_cls_common_offload {
438478
u32 chain_index;
439479
__be16 protocol;

net/sched/cls_api.c

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,36 @@ tcf_chain_filter_chain_ptr_set(struct tcf_chain *chain,
240240
chain->p_filter_chain = p_filter_chain;
241241
}
242242

243-
int tcf_block_get(struct tcf_block **p_block,
244-
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q)
243+
static void tcf_block_offload_cmd(struct tcf_block *block, struct Qdisc *q,
244+
struct tcf_block_ext_info *ei,
245+
enum tc_block_command command)
246+
{
247+
struct net_device *dev = q->dev_queue->dev;
248+
struct tc_block_offload bo = {};
249+
250+
if (!tc_can_offload(dev))
251+
return;
252+
bo.command = command;
253+
bo.binder_type = ei->binder_type;
254+
bo.block = block;
255+
dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_BLOCK, &bo);
256+
}
257+
258+
static void tcf_block_offload_bind(struct tcf_block *block, struct Qdisc *q,
259+
struct tcf_block_ext_info *ei)
260+
{
261+
tcf_block_offload_cmd(block, q, ei, TC_BLOCK_BIND);
262+
}
263+
264+
static void tcf_block_offload_unbind(struct tcf_block *block, struct Qdisc *q,
265+
struct tcf_block_ext_info *ei)
266+
{
267+
tcf_block_offload_cmd(block, q, ei, TC_BLOCK_UNBIND);
268+
}
269+
270+
int tcf_block_get_ext(struct tcf_block **p_block,
271+
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
272+
struct tcf_block_ext_info *ei)
245273
{
246274
struct tcf_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
247275
struct tcf_chain *chain;
@@ -259,22 +287,36 @@ int tcf_block_get(struct tcf_block **p_block,
259287
tcf_chain_filter_chain_ptr_set(chain, p_filter_chain);
260288
block->net = qdisc_net(q);
261289
block->q = q;
290+
tcf_block_offload_bind(block, q, ei);
262291
*p_block = block;
263292
return 0;
264293

265294
err_chain_create:
266295
kfree(block);
267296
return err;
268297
}
298+
EXPORT_SYMBOL(tcf_block_get_ext);
299+
300+
int tcf_block_get(struct tcf_block **p_block,
301+
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q)
302+
{
303+
struct tcf_block_ext_info ei = {0, };
304+
305+
return tcf_block_get_ext(p_block, p_filter_chain, q, &ei);
306+
}
269307
EXPORT_SYMBOL(tcf_block_get);
270308

271-
void tcf_block_put(struct tcf_block *block)
309+
void tcf_block_put_ext(struct tcf_block *block,
310+
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
311+
struct tcf_block_ext_info *ei)
272312
{
273313
struct tcf_chain *chain, *tmp;
274314

275315
if (!block)
276316
return;
277317

318+
tcf_block_offload_unbind(block, q, ei);
319+
278320
/* XXX: Standalone actions are not allowed to jump to any chain, and
279321
* bound actions should be all removed after flushing. However,
280322
* filters are destroyed in RCU callbacks, we have to hold the chains
@@ -302,6 +344,14 @@ void tcf_block_put(struct tcf_block *block)
302344
tcf_chain_put(chain);
303345
kfree(block);
304346
}
347+
EXPORT_SYMBOL(tcf_block_put_ext);
348+
349+
void tcf_block_put(struct tcf_block *block)
350+
{
351+
struct tcf_block_ext_info ei = {0, };
352+
353+
tcf_block_put_ext(block, NULL, block->q, &ei);
354+
}
305355
EXPORT_SYMBOL(tcf_block_put);
306356

307357
/* Main classifier routine: scans classifier chain attached

0 commit comments

Comments
 (0)