[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190426003348.30745-8-pablo@netfilter.org>
Date: Fri, 26 Apr 2019 02:33:44 +0200
From: Pablo Neira Ayuso <pablo@...filter.org>
To: netfilter-devel@...r.kernel.org
Cc: davem@...emloft.net, netdev@...r.kernel.org, jiri@...lanox.com,
john.hurley@...ronome.com, jakub.kicinski@...ronome.com,
ogerlitz@...lanox.com
Subject: [PATCH net-next,RFC 7/9] net: use tcf_block_setup() infrastructure
This allows us to register / unregister tcf_block_cb objects from the
core. The idea is to allocate the tcf_block_cb object from the driver,
attach it to the tc_block_offload->cb_list, then the core registers
them.
Signed-off-by: Pablo Neira Ayuso <pablo@...filter.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 33 +++++++----
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 64 +++++++++++++---------
.../net/ethernet/netronome/nfp/flower/offload.c | 33 +++++++----
include/net/pkt_cls.h | 6 +-
net/dsa/slave.c | 15 ++++-
net/sched/cls_api.c | 35 ++++++++----
6 files changed, 124 insertions(+), 62 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index ee63a902c261..f09135b7a605 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -697,13 +697,21 @@ static int mlx5e_rep_indr_setup_block_cb(enum tc_setup_type type,
}
}
+static void mlx5e_rep_indr_tc_block_unbind(void *cb_priv)
+{
+ struct mlx5e_rep_indr_block_priv *indr_priv = cb_priv;
+
+ list_del(&indr_priv->list);
+ kfree(indr_priv);
+}
+
static int
mlx5e_rep_indr_setup_tc_block(struct net_device *netdev,
struct mlx5e_rep_priv *rpriv,
struct tc_block_offload *f)
{
struct mlx5e_rep_indr_block_priv *indr_priv;
- int err = 0;
+ struct tcf_block_cb *block_cb;
if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
return -EOPNOTSUPP;
@@ -723,26 +731,29 @@ mlx5e_rep_indr_setup_tc_block(struct net_device *netdev,
list_add(&indr_priv->list,
&rpriv->uplink_priv.tc_indr_block_priv_list);
- err = tcf_block_cb_register(f->block,
- mlx5e_rep_indr_setup_block_cb,
- indr_priv, indr_priv, f->extack);
- if (err) {
+ block_cb = tcf_block_cb_alloc(f->block->index,
+ mlx5e_rep_indr_setup_block_cb,
+ indr_priv, indr_priv,
+ mlx5e_rep_indr_tc_block_unbind);
+ if (!block_cb) {
list_del(&indr_priv->list);
kfree(indr_priv);
}
+ tcf_block_cb_list_add(block_cb, &f->cb_list);
- return err;
+ return 0;
case TC_BLOCK_UNBIND:
indr_priv = mlx5e_rep_indr_block_priv_lookup(rpriv, netdev);
if (!indr_priv)
return -ENOENT;
- tcf_block_cb_unregister(f->block,
- mlx5e_rep_indr_setup_block_cb,
- indr_priv);
- list_del(&indr_priv->list);
- kfree(indr_priv);
+ block_cb = tcf_block_cb_lookup(f->block->index,
+ mlx5e_rep_indr_setup_block_cb,
+ indr_priv);
+ if (!block_cb)
+ return -ENOENT;
+ tcf_block_cb_list_move(block_cb, &f->cb_list);
return 0;
default:
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index fc325f1213fb..c07fa0487b39 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -1514,25 +1514,34 @@ static int mlxsw_sp_setup_tc_block_cb_flower(enum tc_setup_type type,
}
}
+static void mlxsw_sp_tc_block_flower_release(void *cb_priv)
+{
+ struct mlxsw_sp_acl_block *acl_block = cb_priv;
+
+ mlxsw_sp_acl_block_destroy(acl_block);
+}
+
static int
mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port,
- struct tcf_block *block, bool ingress,
- struct netlink_ext_ack *extack)
+ struct tc_block_offload *f, bool ingress)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ struct net *net = dev_net(mlxsw_sp_port->dev);
struct mlxsw_sp_acl_block *acl_block;
struct tcf_block_cb *block_cb;
int err;
- block_cb = tcf_block_cb_lookup(block, mlxsw_sp_setup_tc_block_cb_flower,
+ block_cb = tcf_block_cb_lookup(f->block->index,
+ mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp);
if (!block_cb) {
- acl_block = mlxsw_sp_acl_block_create(mlxsw_sp, block->net);
+ acl_block = mlxsw_sp_acl_block_create(mlxsw_sp, net);
if (!acl_block)
return -ENOMEM;
- block_cb = __tcf_block_cb_register(block,
- mlxsw_sp_setup_tc_block_cb_flower,
- mlxsw_sp, acl_block, extack);
+ block_cb = tcf_block_cb_alloc(f->block->index,
+ mlxsw_sp_setup_tc_block_cb_flower,
+ mlxsw_sp, acl_block,
+ mlxsw_sp_tc_block_flower_release);
if (IS_ERR(block_cb)) {
err = PTR_ERR(block_cb);
goto err_cb_register;
@@ -1551,27 +1560,28 @@ mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port,
else
mlxsw_sp_port->eg_acl_block = acl_block;
+ tcf_block_cb_list_add(block_cb, &f->cb_list);
return 0;
err_block_bind:
if (!tcf_block_cb_decref(block_cb)) {
- __tcf_block_cb_unregister(block, block_cb);
err_cb_register:
- mlxsw_sp_acl_block_destroy(acl_block);
+ tcf_block_cb_free(block_cb);
}
return err;
}
static void
mlxsw_sp_setup_tc_block_flower_unbind(struct mlxsw_sp_port *mlxsw_sp_port,
- struct tcf_block *block, bool ingress)
+ struct tc_block_offload *f, bool ingress)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct mlxsw_sp_acl_block *acl_block;
struct tcf_block_cb *block_cb;
int err;
- block_cb = tcf_block_cb_lookup(block, mlxsw_sp_setup_tc_block_cb_flower,
+ block_cb = tcf_block_cb_lookup(f->block->index,
+ mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp);
if (!block_cb)
return;
@@ -1584,15 +1594,14 @@ mlxsw_sp_setup_tc_block_flower_unbind(struct mlxsw_sp_port *mlxsw_sp_port,
acl_block = tcf_block_cb_priv(block_cb);
err = mlxsw_sp_acl_block_unbind(mlxsw_sp, acl_block,
mlxsw_sp_port, ingress);
- if (!err && !tcf_block_cb_decref(block_cb)) {
- __tcf_block_cb_unregister(block, block_cb);
- mlxsw_sp_acl_block_destroy(acl_block);
- }
+ if (!err && !tcf_block_cb_decref(block_cb))
+ tcf_block_cb_list_move(block_cb, &f->cb_list);
}
static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
struct tc_block_offload *f)
{
+ struct tcf_block_cb *block_cb;
tc_setup_cb_t *cb;
bool ingress;
int err;
@@ -1609,22 +1618,27 @@ static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
switch (f->command) {
case TC_BLOCK_BIND:
- err = tcf_block_cb_register(f->block, cb, mlxsw_sp_port,
- mlxsw_sp_port, f->extack);
- if (err)
- return err;
- err = mlxsw_sp_setup_tc_block_flower_bind(mlxsw_sp_port,
- f->block, ingress,
- f->extack);
+ block_cb = tcf_block_cb_alloc(f->block->index, cb, mlxsw_sp_port,
+ mlxsw_sp_port, NULL);
+ if (!block_cb)
+ return -ENOMEM;
+ err = mlxsw_sp_setup_tc_block_flower_bind(mlxsw_sp_port, f,
+ ingress);
if (err) {
- tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port);
+ tcf_block_cb_free(block_cb);
return err;
}
+ tcf_block_cb_list_add(block_cb, &f->cb_list);
return 0;
case TC_BLOCK_UNBIND:
mlxsw_sp_setup_tc_block_flower_unbind(mlxsw_sp_port,
- f->block, ingress);
- tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port);
+ f, ingress);
+ block_cb = tcf_block_cb_lookup(f->block->index, cb,
+ mlxsw_sp_port);
+ if (!block_cb)
+ return -ENOENT;
+
+ tcf_block_cb_list_move(block_cb, &f->cb_list);
return 0;
default:
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index ba41252b1c14..d2bc36859952 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -1246,13 +1246,21 @@ static int nfp_flower_setup_indr_block_cb(enum tc_setup_type type,
}
}
+static void nfp_flower_setup_indr_tc_release(void *cb_priv)
+{
+ struct nfp_flower_indr_block_cb_priv *priv = cb_priv;
+
+ list_del(&priv->list);
+ kfree(priv);
+}
+
static int
nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
struct tc_block_offload *f)
{
struct nfp_flower_indr_block_cb_priv *cb_priv;
struct nfp_flower_priv *priv = app->priv;
- int err;
+ struct tcf_block_cb *block_cb;
if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS &&
!(f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS &&
@@ -1269,26 +1277,29 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
cb_priv->app = app;
list_add(&cb_priv->list, &priv->indr_block_cb_priv);
- err = tcf_block_cb_register(f->block,
- nfp_flower_setup_indr_block_cb,
- cb_priv, cb_priv, f->extack);
- if (err) {
+ block_cb = tcf_block_cb_alloc(f->block->index,
+ nfp_flower_setup_indr_block_cb,
+ cb_priv, cb_priv,
+ nfp_flower_setup_indr_tc_release);
+ if (!block_cb) {
list_del(&cb_priv->list);
kfree(cb_priv);
}
- return err;
+ tcf_block_cb_list_add(block_cb, &f->cb_list);
+ return 0;
case TC_BLOCK_UNBIND:
cb_priv = nfp_flower_indr_block_cb_priv_lookup(app, netdev);
if (!cb_priv)
return -ENOENT;
- tcf_block_cb_unregister(f->block,
- nfp_flower_setup_indr_block_cb,
- cb_priv);
- list_del(&cb_priv->list);
- kfree(cb_priv);
+ block_cb = tcf_block_cb_lookup(f->block->index,
+ nfp_flower_setup_indr_block_cb,
+ cb_priv);
+ if (!block_cb)
+ return -ENOENT;
+ tcf_block_cb_list_move(block_cb, &f->cb_list);
return 0;
default:
return -EOPNOTSUPP;
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 7a50f7bb6880..8f0486a00d70 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -71,7 +71,7 @@ static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
return block->q;
}
-struct tcf_block_cb *tcf_block_cb_alloc(tc_setup_cb_t *cb,
+struct tcf_block_cb *tcf_block_cb_alloc(u32 block_index, tc_setup_cb_t *cb,
void *cb_ident, void *cb_priv,
void (*release)(void *cb_priv));
void tcf_block_cb_free(struct tcf_block_cb *block_cb);
@@ -79,8 +79,8 @@ void tcf_block_cb_list_add(struct tcf_block_cb *block_cb, struct list_head *cb_l
void tcf_block_cb_list_move(struct tcf_block_cb *block_cb, struct list_head *cb_list);
void *tcf_block_cb_priv(struct tcf_block_cb *block_cb);
-struct tcf_block_cb *tcf_block_cb_lookup(struct tcf_block *block,
- tc_setup_cb_t *cb, void *cb_ident);
+struct tcf_block_cb *tcf_block_cb_lookup(u32 block_index, tc_setup_cb_t *cb,
+ void *cb_ident);
void tcf_block_cb_incref(struct tcf_block_cb *block_cb);
unsigned int tcf_block_cb_decref(struct tcf_block_cb *block_cb);
struct tcf_block_cb *__tcf_block_cb_register(struct tcf_block *block,
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index ce26dddc8270..7ef34cc2f574 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -902,6 +902,7 @@ static int dsa_slave_setup_tc_block_cb_eg(enum tc_setup_type type,
static int dsa_slave_setup_tc_block(struct net_device *dev,
struct tc_block_offload *f)
{
+ struct tcf_block_cb *block_cb;
tc_setup_cb_t *cb;
if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
@@ -913,9 +914,19 @@ static int dsa_slave_setup_tc_block(struct net_device *dev,
switch (f->command) {
case TC_BLOCK_BIND:
- return tcf_block_cb_register(f->block, cb, dev, dev, f->extack);
+ block_cb = tcf_block_cb_alloc(f->block->index, cb, dev, dev,
+ NULL);
+ if (!block_cb)
+ return -ENOMEM;
+
+ tcf_block_cb_list_add(block_cb, &f->cb_list);
+ return 0;
case TC_BLOCK_UNBIND:
- tcf_block_cb_unregister(f->block, cb, dev);
+ block_cb = tcf_block_cb_lookup(f->block->index, cb, dev);
+ if (!block_cb)
+ return -ENOENT;
+
+ tcf_block_cb_list_move(block_cb, &f->cb_list);
return 0;
default:
return -EOPNOTSUPP;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index a00463c8cfa9..f7f6f42d58d1 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -714,6 +714,7 @@ struct tcf_block_cb {
void (*release)(void *cb_priv);
void *cb_ident;
void *cb_priv;
+ u32 block_index;
unsigned int refcnt;
};
@@ -730,12 +731,14 @@ EXPORT_SYMBOL(tcf_block_cb_priv);
static LIST_HEAD(tcf_block_cb_list);
-struct tcf_block_cb *tcf_block_cb_lookup(struct tcf_block *block,
- tc_setup_cb_t *cb, void *cb_ident)
+struct tcf_block_cb *tcf_block_cb_lookup(u32 block_index, tc_setup_cb_t *cb,
+ void *cb_ident)
{ struct tcf_block_cb *block_cb;
- list_for_each_entry(block_cb, &block->cb_list, list)
- if (block_cb->cb == cb && block_cb->cb_ident == cb_ident)
+ list_for_each_entry(block_cb, &tcf_block_cb_list, list)
+ if (block_cb->block_index == block_index &&
+ block_cb->cb == cb &&
+ block_cb->cb_ident == cb_ident)
return block_cb;
return NULL;
}
@@ -753,7 +756,7 @@ unsigned int tcf_block_cb_decref(struct tcf_block_cb *block_cb)
}
EXPORT_SYMBOL(tcf_block_cb_decref);
-struct tcf_block_cb *tcf_block_cb_alloc(tc_setup_cb_t *cb,
+struct tcf_block_cb *tcf_block_cb_alloc(u32 block_index, tc_setup_cb_t *cb,
void *cb_ident, void *cb_priv,
void (*release)(void *cb_priv))
{
@@ -767,6 +770,7 @@ struct tcf_block_cb *tcf_block_cb_alloc(tc_setup_cb_t *cb,
block_cb->cb_ident = cb_ident;
block_cb->release = release;
block_cb->cb_priv = cb_priv;
+ block_cb->block_index = block_index;
return block_cb;
}
@@ -810,7 +814,7 @@ struct tcf_block_cb *__tcf_block_cb_register(struct tcf_block *block,
if (err)
return ERR_PTR(err);
- block_cb = tcf_block_cb_alloc(cb, cb_ident, cb_priv, NULL);
+ block_cb = tcf_block_cb_alloc(block->index, cb, cb_ident, cb_priv, NULL);
if (!block_cb)
return ERR_PTR(-ENOMEM);
@@ -847,7 +851,7 @@ void tcf_block_cb_unregister(struct tcf_block *block,
{
struct tcf_block_cb *block_cb;
- block_cb = tcf_block_cb_lookup(block, cb, cb_ident);
+ block_cb = tcf_block_cb_lookup(block->index, cb, cb_ident);
if (!block_cb)
return;
__tcf_block_cb_unregister(block, block_cb);
@@ -929,16 +933,27 @@ static int tcf_block_setup(struct tcf_block *block, struct tc_block_offload *bo)
int tcf_setup_block_offload(struct tc_block_offload *f, tc_setup_cb_t *cb,
void *cb_priv, bool ingress_only)
{
+ struct tcf_block_cb *block_cb;
+
if (ingress_only &&
f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
return -EOPNOTSUPP;
switch (f->command) {
case TC_BLOCK_BIND:
- return tcf_block_cb_register(f->block, cb, cb_priv, cb_priv,
- f->extack);
+ block_cb = tcf_block_cb_alloc(f->block->index, cb, cb_priv,
+ cb_priv, NULL);
+ if (!block_cb)
+ return -ENOMEM;
+
+ tcf_block_cb_list_add(block_cb, &f->cb_list);
+ return 0;
case TC_BLOCK_UNBIND:
- tcf_block_cb_unregister(f->block, cb, cb_priv);
+ block_cb = tcf_block_cb_lookup(f->block->index, cb, cb_priv);
+ if (!block_cb)
+ return -ENOENT;
+
+ tcf_block_cb_list_move(block_cb, &f->cb_list);
return 0;
default:
return -EOPNOTSUPP;
--
2.11.0
Powered by blists - more mailing lists