Skip to content

Commit 9a74542

Browse files
committed
Merge branch 'net-tc-indirect-block-relay'
John Hurley says: ==================== Ensure egress un/bind are relayed with indirect blocks On register and unregister for indirect blocks, a command is called that sends a bind/unbind event to the registering driver. This command assumes that the bind to indirect block will be on ingress. However, drivers such as NFP have allowed binding to clsact qdiscs as well as ingress qdiscs from mainline Linux 5.2. A clsact qdisc binds to an ingress and an egress block. Rather than assuming that an indirect bind is always ingress, modify the function names to remove the ingress tag (patch 1). In cls_api, which is used by NFP to offload TC flower, generate bind/unbind message for both ingress and egress blocks on the event of indirectly registering/unregistering from that block. Doing so mimics the behaviour of both ingress and clsact qdiscs on initialise and destroy. This now ensures that drivers such as NFP receive the correct binder type for the indirect block registration. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents e0b6090 + 25a443f commit 9a74542

File tree

4 files changed

+65
-53
lines changed

4 files changed

+65
-53
lines changed

include/net/flow_offload.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -380,19 +380,18 @@ static inline void flow_block_init(struct flow_block *flow_block)
380380
typedef int flow_indr_block_bind_cb_t(struct net_device *dev, void *cb_priv,
381381
enum tc_setup_type type, void *type_data);
382382

383-
typedef void flow_indr_block_ing_cmd_t(struct net_device *dev,
384-
flow_indr_block_bind_cb_t *cb,
385-
void *cb_priv,
386-
enum flow_block_command command);
383+
typedef void flow_indr_block_cmd_t(struct net_device *dev,
384+
flow_indr_block_bind_cb_t *cb, void *cb_priv,
385+
enum flow_block_command command);
387386

388-
struct flow_indr_block_ing_entry {
389-
flow_indr_block_ing_cmd_t *cb;
387+
struct flow_indr_block_entry {
388+
flow_indr_block_cmd_t *cb;
390389
struct list_head list;
391390
};
392391

393-
void flow_indr_add_block_ing_cb(struct flow_indr_block_ing_entry *entry);
392+
void flow_indr_add_block_cb(struct flow_indr_block_entry *entry);
394393

395-
void flow_indr_del_block_ing_cb(struct flow_indr_block_ing_entry *entry);
394+
void flow_indr_del_block_cb(struct flow_indr_block_entry *entry);
396395

397396
int __flow_indr_block_cb_register(struct net_device *dev, void *cb_priv,
398397
flow_indr_block_bind_cb_t *cb,

net/core/flow_offload.c

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ int flow_block_cb_setup_simple(struct flow_block_offload *f,
283283
}
284284
EXPORT_SYMBOL(flow_block_cb_setup_simple);
285285

286-
static LIST_HEAD(block_ing_cb_list);
286+
static LIST_HEAD(block_cb_list);
287287

288288
static struct rhashtable indr_setup_block_ht;
289289

@@ -391,20 +391,19 @@ static void flow_indr_block_cb_del(struct flow_indr_block_cb *indr_block_cb)
391391
kfree(indr_block_cb);
392392
}
393393

394-
static DEFINE_MUTEX(flow_indr_block_ing_cb_lock);
394+
static DEFINE_MUTEX(flow_indr_block_cb_lock);
395395

396-
static void flow_block_ing_cmd(struct net_device *dev,
397-
flow_indr_block_bind_cb_t *cb,
398-
void *cb_priv,
399-
enum flow_block_command command)
396+
static void flow_block_cmd(struct net_device *dev,
397+
flow_indr_block_bind_cb_t *cb, void *cb_priv,
398+
enum flow_block_command command)
400399
{
401-
struct flow_indr_block_ing_entry *entry;
400+
struct flow_indr_block_entry *entry;
402401

403-
mutex_lock(&flow_indr_block_ing_cb_lock);
404-
list_for_each_entry(entry, &block_ing_cb_list, list) {
402+
mutex_lock(&flow_indr_block_cb_lock);
403+
list_for_each_entry(entry, &block_cb_list, list) {
405404
entry->cb(dev, cb, cb_priv, command);
406405
}
407-
mutex_unlock(&flow_indr_block_ing_cb_lock);
406+
mutex_unlock(&flow_indr_block_cb_lock);
408407
}
409408

410409
int __flow_indr_block_cb_register(struct net_device *dev, void *cb_priv,
@@ -424,8 +423,8 @@ int __flow_indr_block_cb_register(struct net_device *dev, void *cb_priv,
424423
if (err)
425424
goto err_dev_put;
426425

427-
flow_block_ing_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv,
428-
FLOW_BLOCK_BIND);
426+
flow_block_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv,
427+
FLOW_BLOCK_BIND);
429428

430429
return 0;
431430

@@ -464,8 +463,8 @@ void __flow_indr_block_cb_unregister(struct net_device *dev,
464463
if (!indr_block_cb)
465464
return;
466465

467-
flow_block_ing_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv,
468-
FLOW_BLOCK_UNBIND);
466+
flow_block_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv,
467+
FLOW_BLOCK_UNBIND);
469468

470469
flow_indr_block_cb_del(indr_block_cb);
471470
flow_indr_block_dev_put(indr_dev);
@@ -499,21 +498,21 @@ void flow_indr_block_call(struct net_device *dev,
499498
}
500499
EXPORT_SYMBOL_GPL(flow_indr_block_call);
501500

502-
void flow_indr_add_block_ing_cb(struct flow_indr_block_ing_entry *entry)
501+
void flow_indr_add_block_cb(struct flow_indr_block_entry *entry)
503502
{
504-
mutex_lock(&flow_indr_block_ing_cb_lock);
505-
list_add_tail(&entry->list, &block_ing_cb_list);
506-
mutex_unlock(&flow_indr_block_ing_cb_lock);
503+
mutex_lock(&flow_indr_block_cb_lock);
504+
list_add_tail(&entry->list, &block_cb_list);
505+
mutex_unlock(&flow_indr_block_cb_lock);
507506
}
508-
EXPORT_SYMBOL_GPL(flow_indr_add_block_ing_cb);
507+
EXPORT_SYMBOL_GPL(flow_indr_add_block_cb);
509508

510-
void flow_indr_del_block_ing_cb(struct flow_indr_block_ing_entry *entry)
509+
void flow_indr_del_block_cb(struct flow_indr_block_entry *entry)
511510
{
512-
mutex_lock(&flow_indr_block_ing_cb_lock);
511+
mutex_lock(&flow_indr_block_cb_lock);
513512
list_del(&entry->list);
514-
mutex_unlock(&flow_indr_block_ing_cb_lock);
513+
mutex_unlock(&flow_indr_block_cb_lock);
515514
}
516-
EXPORT_SYMBOL_GPL(flow_indr_del_block_ing_cb);
515+
EXPORT_SYMBOL_GPL(flow_indr_del_block_cb);
517516

518517
static int __init init_flow_indr_rhashtable(void)
519518
{

net/netfilter/nf_tables_offload.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ static int nft_offload_netdev_event(struct notifier_block *this,
588588
return NOTIFY_DONE;
589589
}
590590

591-
static struct flow_indr_block_ing_entry block_ing_entry = {
591+
static struct flow_indr_block_entry block_ing_entry = {
592592
.cb = nft_indr_block_cb,
593593
.list = LIST_HEAD_INIT(block_ing_entry.list),
594594
};
@@ -605,13 +605,13 @@ int nft_offload_init(void)
605605
if (err < 0)
606606
return err;
607607

608-
flow_indr_add_block_ing_cb(&block_ing_entry);
608+
flow_indr_add_block_cb(&block_ing_entry);
609609

610610
return 0;
611611
}
612612

613613
void nft_offload_exit(void)
614614
{
615-
flow_indr_del_block_ing_cb(&block_ing_entry);
615+
flow_indr_del_block_cb(&block_ing_entry);
616616
unregister_netdevice_notifier(&nft_offload_netdev_notifier);
617617
}

net/sched/cls_api.c

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -626,15 +626,15 @@ static void tcf_chain_flush(struct tcf_chain *chain, bool rtnl_held)
626626
static int tcf_block_setup(struct tcf_block *block,
627627
struct flow_block_offload *bo);
628628

629-
static void tc_indr_block_ing_cmd(struct net_device *dev,
630-
struct tcf_block *block,
631-
flow_indr_block_bind_cb_t *cb,
632-
void *cb_priv,
633-
enum flow_block_command command)
629+
static void tc_indr_block_cmd(struct net_device *dev, struct tcf_block *block,
630+
flow_indr_block_bind_cb_t *cb, void *cb_priv,
631+
enum flow_block_command command, bool ingress)
634632
{
635633
struct flow_block_offload bo = {
636634
.command = command,
637-
.binder_type = FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS,
635+
.binder_type = ingress ?
636+
FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS :
637+
FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS,
638638
.net = dev_net(dev),
639639
.block_shared = tcf_block_non_null_shared(block),
640640
};
@@ -652,9 +652,10 @@ static void tc_indr_block_ing_cmd(struct net_device *dev,
652652
up_write(&block->cb_lock);
653653
}
654654

655-
static struct tcf_block *tc_dev_ingress_block(struct net_device *dev)
655+
static struct tcf_block *tc_dev_block(struct net_device *dev, bool ingress)
656656
{
657657
const struct Qdisc_class_ops *cops;
658+
const struct Qdisc_ops *ops;
658659
struct Qdisc *qdisc;
659660

660661
if (!dev_ingress_queue(dev))
@@ -664,24 +665,37 @@ static struct tcf_block *tc_dev_ingress_block(struct net_device *dev)
664665
if (!qdisc)
665666
return NULL;
666667

667-
cops = qdisc->ops->cl_ops;
668+
ops = qdisc->ops;
669+
if (!ops)
670+
return NULL;
671+
672+
if (!ingress && !strcmp("ingress", ops->id))
673+
return NULL;
674+
675+
cops = ops->cl_ops;
668676
if (!cops)
669677
return NULL;
670678

671679
if (!cops->tcf_block)
672680
return NULL;
673681

674-
return cops->tcf_block(qdisc, TC_H_MIN_INGRESS, NULL);
682+
return cops->tcf_block(qdisc,
683+
ingress ? TC_H_MIN_INGRESS : TC_H_MIN_EGRESS,
684+
NULL);
675685
}
676686

677-
static void tc_indr_block_get_and_ing_cmd(struct net_device *dev,
678-
flow_indr_block_bind_cb_t *cb,
679-
void *cb_priv,
680-
enum flow_block_command command)
687+
static void tc_indr_block_get_and_cmd(struct net_device *dev,
688+
flow_indr_block_bind_cb_t *cb,
689+
void *cb_priv,
690+
enum flow_block_command command)
681691
{
682-
struct tcf_block *block = tc_dev_ingress_block(dev);
692+
struct tcf_block *block;
693+
694+
block = tc_dev_block(dev, true);
695+
tc_indr_block_cmd(dev, block, cb, cb_priv, command, true);
683696

684-
tc_indr_block_ing_cmd(dev, block, cb, cb_priv, command);
697+
block = tc_dev_block(dev, false);
698+
tc_indr_block_cmd(dev, block, cb, cb_priv, command, false);
685699
}
686700

687701
static void tc_indr_block_call(struct tcf_block *block,
@@ -3626,9 +3640,9 @@ static struct pernet_operations tcf_net_ops = {
36263640
.size = sizeof(struct tcf_net),
36273641
};
36283642

3629-
static struct flow_indr_block_ing_entry block_ing_entry = {
3630-
.cb = tc_indr_block_get_and_ing_cmd,
3631-
.list = LIST_HEAD_INIT(block_ing_entry.list),
3643+
static struct flow_indr_block_entry block_entry = {
3644+
.cb = tc_indr_block_get_and_cmd,
3645+
.list = LIST_HEAD_INIT(block_entry.list),
36323646
};
36333647

36343648
static int __init tc_filter_init(void)
@@ -3643,7 +3657,7 @@ static int __init tc_filter_init(void)
36433657
if (err)
36443658
goto err_register_pernet_subsys;
36453659

3646-
flow_indr_add_block_ing_cb(&block_ing_entry);
3660+
flow_indr_add_block_cb(&block_entry);
36473661

36483662
rtnl_register(PF_UNSPEC, RTM_NEWTFILTER, tc_new_tfilter, NULL,
36493663
RTNL_FLAG_DOIT_UNLOCKED);

0 commit comments

Comments
 (0)