lkml.org 
[lkml]   [2022]   [Jun]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.17 160/298] netfilter: nf_tables: delete flowtable hooks via transaction list
    Date
    From: Pablo Neira Ayuso <pablo@netfilter.org>

    [ Upstream commit b6d9014a3335194590abdd2a2471ef5147a67645 ]

    Remove inactive bool field in nft_hook object that was introduced in
    abadb2f865d7 ("netfilter: nf_tables: delete devices from flowtable").
    Move stale flowtable hooks to transaction list instead.

    Deleting twice the same device does not result in ENOENT.

    Fixes: abadb2f865d7 ("netfilter: nf_tables: delete devices from flowtable")
    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/net/netfilter/nf_tables.h | 1 -
    net/netfilter/nf_tables_api.c | 31 ++++++-------------------------
    2 files changed, 6 insertions(+), 26 deletions(-)

    diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
    index c4c0861deac1..c3fdd9f71c05 100644
    --- a/include/net/netfilter/nf_tables.h
    +++ b/include/net/netfilter/nf_tables.h
    @@ -1089,7 +1089,6 @@ struct nft_stats {

    struct nft_hook {
    struct list_head list;
    - bool inactive;
    struct nf_hook_ops ops;
    struct rcu_head rcu;
    };
    diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
    index 07c842b65f6d..a7ed8fe46af1 100644
    --- a/net/netfilter/nf_tables_api.c
    +++ b/net/netfilter/nf_tables_api.c
    @@ -1835,7 +1835,6 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net,
    goto err_hook_dev;
    }
    hook->ops.dev = dev;
    - hook->inactive = false;

    return hook;

    @@ -7533,6 +7532,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
    {
    const struct nlattr * const *nla = ctx->nla;
    struct nft_flowtable_hook flowtable_hook;
    + LIST_HEAD(flowtable_del_list);
    struct nft_hook *this, *hook;
    struct nft_trans *trans;
    int err;
    @@ -7548,7 +7548,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
    err = -ENOENT;
    goto err_flowtable_del_hook;
    }
    - hook->inactive = true;
    + list_move(&hook->list, &flowtable_del_list);
    }

    trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE,
    @@ -7561,6 +7561,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
    nft_trans_flowtable(trans) = flowtable;
    nft_trans_flowtable_update(trans) = true;
    INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
    + list_splice(&flowtable_del_list, &nft_trans_flowtable_hooks(trans));
    nft_flowtable_hook_release(&flowtable_hook);

    nft_trans_commit_list_add_tail(ctx->net, trans);
    @@ -7568,13 +7569,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
    return 0;

    err_flowtable_del_hook:
    - list_for_each_entry(this, &flowtable_hook.list, list) {
    - hook = nft_hook_list_find(&flowtable->hook_list, this);
    - if (!hook)
    - break;
    -
    - hook->inactive = false;
    - }
    + list_splice(&flowtable_del_list, &flowtable->hook_list);
    nft_flowtable_hook_release(&flowtable_hook);

    return err;
    @@ -8480,17 +8475,6 @@ void nft_chain_del(struct nft_chain *chain)
    list_del_rcu(&chain->list);
    }

    -static void nft_flowtable_hooks_del(struct nft_flowtable *flowtable,
    - struct list_head *hook_list)
    -{
    - struct nft_hook *hook, *next;
    -
    - list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) {
    - if (hook->inactive)
    - list_move(&hook->list, hook_list);
    - }
    -}
    -
    static void nf_tables_module_autoload_cleanup(struct net *net)
    {
    struct nftables_pernet *nft_net = nft_pernet(net);
    @@ -8835,8 +8819,6 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
    break;
    case NFT_MSG_DELFLOWTABLE:
    if (nft_trans_flowtable_update(trans)) {
    - nft_flowtable_hooks_del(nft_trans_flowtable(trans),
    - &nft_trans_flowtable_hooks(trans));
    nf_tables_flowtable_notify(&trans->ctx,
    nft_trans_flowtable(trans),
    &nft_trans_flowtable_hooks(trans),
    @@ -8917,7 +8899,6 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
    struct nftables_pernet *nft_net = nft_pernet(net);
    struct nft_trans *trans, *next;
    struct nft_trans_elem *te;
    - struct nft_hook *hook;

    if (action == NFNL_ABORT_VALIDATE &&
    nf_tables_validate(net) < 0)
    @@ -9048,8 +9029,8 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
    break;
    case NFT_MSG_DELFLOWTABLE:
    if (nft_trans_flowtable_update(trans)) {
    - list_for_each_entry(hook, &nft_trans_flowtable(trans)->hook_list, list)
    - hook->inactive = false;
    + list_splice(&nft_trans_flowtable_hooks(trans),
    + &nft_trans_flowtable(trans)->hook_list);
    } else {
    trans->ctx.table->use++;
    nft_clear(trans->ctx.net, nft_trans_flowtable(trans));
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-13 16:32    [W:4.539 / U:0.432 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site