diff options
author | Maksym Glubokiy <maksym.glubokiy@plvision.eu> | 2022-06-27 12:50:18 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-06-29 14:02:37 +0100 |
commit | 702e70143291b09e6245deb8ab904d1c18ed4f47 (patch) | |
tree | 2b8784b632e98930861014fd183ec0abfc2dfe95 /drivers/net/ethernet/marvell/prestera/prestera_flow.c | |
parent | 04cfbc1d89d4cc73b5b328e3bacf24d43e9aa4b7 (diff) |
net: prestera: acl: add support for 'egress' rules
The following is now supported:
$ tc qdisc add PORT clsact
$ tc filter add dev PORT egress ...
Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/marvell/prestera/prestera_flow.c')
-rw-r--r-- | drivers/net/ethernet/marvell/prestera/prestera_flow.c | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flow.c b/drivers/net/ethernet/marvell/prestera/prestera_flow.c index 05c3ad98eba9..2262693bd5cf 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_flow.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_flow.c @@ -75,7 +75,9 @@ static void prestera_flow_block_destroy(void *cb_priv) } static struct prestera_flow_block * -prestera_flow_block_create(struct prestera_switch *sw, struct net *net) +prestera_flow_block_create(struct prestera_switch *sw, + struct net *net, + bool ingress) { struct prestera_flow_block *block; @@ -87,6 +89,7 @@ prestera_flow_block_create(struct prestera_switch *sw, struct net *net) INIT_LIST_HEAD(&block->template_list); block->net = net; block->sw = sw; + block->ingress = ingress; return block; } @@ -165,7 +168,8 @@ static int prestera_flow_block_unbind(struct prestera_flow_block *block, static struct prestera_flow_block * prestera_flow_block_get(struct prestera_switch *sw, struct flow_block_offload *f, - bool *register_block) + bool *register_block, + bool ingress) { struct prestera_flow_block *block; struct flow_block_cb *block_cb; @@ -173,7 +177,7 @@ prestera_flow_block_get(struct prestera_switch *sw, block_cb = flow_block_cb_lookup(f->block, prestera_flow_block_cb, sw); if (!block_cb) { - block = prestera_flow_block_create(sw, f->net); + block = prestera_flow_block_create(sw, f->net, ingress); if (!block) return ERR_PTR(-ENOMEM); @@ -209,7 +213,7 @@ static void prestera_flow_block_put(struct prestera_flow_block *block) } static int prestera_setup_flow_block_bind(struct prestera_port *port, - struct flow_block_offload *f) + struct flow_block_offload *f, bool ingress) { struct prestera_switch *sw = port->sw; struct prestera_flow_block *block; @@ -217,7 +221,7 @@ static int prestera_setup_flow_block_bind(struct prestera_port *port, bool register_block; int err; - block = prestera_flow_block_get(sw, f, ®ister_block); + block = prestera_flow_block_get(sw, f, ®ister_block, ingress); if (IS_ERR(block)) return PTR_ERR(block); @@ -232,7 +236,11 @@ static int prestera_setup_flow_block_bind(struct prestera_port *port, list_add_tail(&block_cb->driver_list, &prestera_block_cb_list); } - port->flow_block = block; + if (ingress) + port->ingress_flow_block = block; + else + port->egress_flow_block = block; + return 0; err_block_bind: @@ -242,7 +250,7 @@ err_block_bind: } static void prestera_setup_flow_block_unbind(struct prestera_port *port, - struct flow_block_offload *f) + struct flow_block_offload *f, bool ingress) { struct prestera_switch *sw = port->sw; struct prestera_flow_block *block; @@ -266,24 +274,38 @@ static void prestera_setup_flow_block_unbind(struct prestera_port *port, list_del(&block_cb->driver_list); } error: - port->flow_block = NULL; + if (ingress) + port->ingress_flow_block = NULL; + else + port->egress_flow_block = NULL; } -int prestera_flow_block_setup(struct prestera_port *port, - struct flow_block_offload *f) +static int prestera_setup_flow_block_clsact(struct prestera_port *port, + struct flow_block_offload *f, + bool ingress) { - if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - f->driver_block_list = &prestera_block_cb_list; switch (f->command) { case FLOW_BLOCK_BIND: - return prestera_setup_flow_block_bind(port, f); + return prestera_setup_flow_block_bind(port, f, ingress); case FLOW_BLOCK_UNBIND: - prestera_setup_flow_block_unbind(port, f); + prestera_setup_flow_block_unbind(port, f, ingress); return 0; default: return -EOPNOTSUPP; } } + +int prestera_flow_block_setup(struct prestera_port *port, + struct flow_block_offload *f) +{ + switch (f->binder_type) { + case FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS: + return prestera_setup_flow_block_clsact(port, f, true); + case FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS: + return prestera_setup_flow_block_clsact(port, f, false); + default: + return -EOPNOTSUPP; + } +} |