* [PATCH net-next 01/16] netfilter: ctnetlink: support CTA_FILTER for flush
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-07 2:10 ` patchwork-bot+netdevbpf
2024-09-05 23:29 ` [PATCH net-next 02/16] netfilter: nft_counter: Use u64_stats_t for statistic Pablo Neira Ayuso
` (14 subsequent siblings)
15 siblings, 1 reply; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
From: Changliang Wu <changliang.wu@smartx.com>
From cb8aa9a, we can use kernel side filtering for dump, but
this capability is not available for flush.
This Patch allows advanced filter with CTA_FILTER for flush
Performace
1048576 ct flows in total, delete 50,000 flows by origin src ip
3.06s -> dump all, compare and delete
584ms -> directly flush with filter
Signed-off-by: Changliang Wu <changliang.wu@smartx.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_netlink.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 4cbf71d0786b..123e2e933e9b 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1579,9 +1579,6 @@ static int ctnetlink_flush_conntrack(struct net *net,
};
if (ctnetlink_needs_filter(family, cda)) {
- if (cda[CTA_FILTER])
- return -EOPNOTSUPP;
-
filter = ctnetlink_alloc_filter(cda, family);
if (IS_ERR(filter))
return PTR_ERR(filter);
@@ -1610,14 +1607,14 @@ static int ctnetlink_del_conntrack(struct sk_buff *skb,
if (err < 0)
return err;
- if (cda[CTA_TUPLE_ORIG])
+ if (cda[CTA_TUPLE_ORIG] && !cda[CTA_FILTER])
err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG,
family, &zone);
- else if (cda[CTA_TUPLE_REPLY])
+ else if (cda[CTA_TUPLE_REPLY] && !cda[CTA_FILTER])
err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY,
family, &zone);
else {
- u_int8_t u3 = info->nfmsg->version ? family : AF_UNSPEC;
+ u8 u3 = info->nfmsg->version || cda[CTA_FILTER] ? family : AF_UNSPEC;
return ctnetlink_flush_conntrack(info->net, cda,
NETLINK_CB(skb).portid,
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH net-next 01/16] netfilter: ctnetlink: support CTA_FILTER for flush
2024-09-05 23:29 ` [PATCH net-next 01/16] netfilter: ctnetlink: support CTA_FILTER for flush Pablo Neira Ayuso
@ 2024-09-07 2:10 ` patchwork-bot+netdevbpf
0 siblings, 0 replies; 19+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-09-07 2:10 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: netfilter-devel, davem, netdev, kuba, pabeni, edumazet, fw
Hello:
This series was applied to netdev/net-next.git (main)
by Pablo Neira Ayuso <pablo@netfilter.org>:
On Fri, 6 Sep 2024 01:29:05 +0200 you wrote:
> From: Changliang Wu <changliang.wu@smartx.com>
>
> From cb8aa9a, we can use kernel side filtering for dump, but
> this capability is not available for flush.
>
> This Patch allows advanced filter with CTA_FILTER for flush
>
> [...]
Here is the summary with links:
- [net-next,01/16] netfilter: ctnetlink: support CTA_FILTER for flush
https://git.kernel.org/netdev/net-next/c/1ef7f50ccc6e
- [net-next,02/16] netfilter: nft_counter: Use u64_stats_t for statistic.
https://git.kernel.org/netdev/net-next/c/4a1d3acd6ea8
- [net-next,03/16] netfilter: Use kmemdup_array instead of kmemdup for multiple allocation
https://git.kernel.org/netdev/net-next/c/20eb5e7cb78c
- [net-next,04/16] netfilter: conntrack: Convert to use ERR_CAST()
https://git.kernel.org/netdev/net-next/c/09c0d0aef56b
- [net-next,05/16] netfilter: nf_tables: drop unused 3rd argument from validate callback ops
https://git.kernel.org/netdev/net-next/c/eaf9b2c875ec
- [net-next,06/16] netfilter: nf_tables: Correct spelling in nf_tables.h
https://git.kernel.org/netdev/net-next/c/85dfb34bb7d2
- [net-next,07/16] netfilter: nf_tables: Add missing Kernel doc
https://git.kernel.org/netdev/net-next/c/c362646b6fc1
- [net-next,08/16] netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire
https://git.kernel.org/netdev/net-next/c/e0c47281723f
- [net-next,09/16] netfilter: nf_tables: reject element expiration with no timeout
https://git.kernel.org/netdev/net-next/c/d2dc429ecb4e
- [net-next,10/16] netfilter: nf_tables: reject expiration higher than timeout
https://git.kernel.org/netdev/net-next/c/c0f38a8c6017
- [net-next,11/16] netfilter: nf_tables: remove annotation to access set timeout while holding lock
https://git.kernel.org/netdev/net-next/c/15d8605c0cf4
- [net-next,12/16] netfilter: nft_dynset: annotate data-races around set timeout
https://git.kernel.org/netdev/net-next/c/c5ad8ed61fa8
- [net-next,13/16] netfilter: nf_tables: annotate data-races around element expiration
https://git.kernel.org/netdev/net-next/c/73d3c04b710f
- [net-next,14/16] netfilter: nf_tables: consolidate timeout extension for elements
https://git.kernel.org/netdev/net-next/c/4c5daea9af4f
- [net-next,15/16] netfilter: nf_tables: zero timeout means element never times out
https://git.kernel.org/netdev/net-next/c/8bfb74ae12fa
- [net-next,16/16] netfilter: nf_tables: set element timeout update support
https://git.kernel.org/netdev/net-next/c/4201f3938914
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next 02/16] netfilter: nft_counter: Use u64_stats_t for statistic.
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 01/16] netfilter: ctnetlink: support CTA_FILTER for flush Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 03/16] netfilter: Use kmemdup_array instead of kmemdup for multiple allocation Pablo Neira Ayuso
` (13 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
The nft_counter uses two s64 counters for statistics. Those two are
protected by a seqcount to ensure that the 64bit variable is always
properly seen during updates even on 32bit architectures where the store
is performed by two writes. A side effect is that the two counter (bytes
and packet) are written and read together in the same window.
This can be replaced with u64_stats_t. write_seqcount_begin()/ end() is
replaced with u64_stats_update_begin()/ end() and behaves the same way
as with seqcount_t on 32bit architectures. Additionally there is a
preempt_disable on PREEMPT_RT to ensure that a reader does not preempt a
writer.
On 64bit architectures the macros are removed and the reads happen
without any retries. This also means that the reader can observe one
counter (bytes) from before the update and the other counter (packets)
but that is okay since there is no requirement to have both counter from
the same update window.
Convert the statistic to u64_stats_t. There is one optimisation:
nft_counter_do_init() and nft_counter_clone() allocate a new per-CPU
counter and assign a value to it. During this assignment preemption is
disabled which is not needed because the counter is not yet exposed to
the system so there can not be another writer or reader. Therefore
disabling preemption is omitted and raw_cpu_ptr() is used to obtain a
pointer to a counter for the assignment.
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_counter.c | 90 +++++++++++++++++++------------------
1 file changed, 46 insertions(+), 44 deletions(-)
diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
index eab0dc66bee6..cc7325329496 100644
--- a/net/netfilter/nft_counter.c
+++ b/net/netfilter/nft_counter.c
@@ -8,7 +8,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/seqlock.h>
+#include <linux/u64_stats_sync.h>
#include <linux/netlink.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
@@ -17,6 +17,11 @@
#include <net/netfilter/nf_tables_offload.h>
struct nft_counter {
+ u64_stats_t bytes;
+ u64_stats_t packets;
+};
+
+struct nft_counter_tot {
s64 bytes;
s64 packets;
};
@@ -25,25 +30,24 @@ struct nft_counter_percpu_priv {
struct nft_counter __percpu *counter;
};
-static DEFINE_PER_CPU(seqcount_t, nft_counter_seq);
+static DEFINE_PER_CPU(struct u64_stats_sync, nft_counter_sync);
static inline void nft_counter_do_eval(struct nft_counter_percpu_priv *priv,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
+ struct u64_stats_sync *nft_sync;
struct nft_counter *this_cpu;
- seqcount_t *myseq;
local_bh_disable();
this_cpu = this_cpu_ptr(priv->counter);
- myseq = this_cpu_ptr(&nft_counter_seq);
-
- write_seqcount_begin(myseq);
+ nft_sync = this_cpu_ptr(&nft_counter_sync);
- this_cpu->bytes += pkt->skb->len;
- this_cpu->packets++;
+ u64_stats_update_begin(nft_sync);
+ u64_stats_add(&this_cpu->bytes, pkt->skb->len);
+ u64_stats_inc(&this_cpu->packets);
+ u64_stats_update_end(nft_sync);
- write_seqcount_end(myseq);
local_bh_enable();
}
@@ -66,17 +70,16 @@ static int nft_counter_do_init(const struct nlattr * const tb[],
if (cpu_stats == NULL)
return -ENOMEM;
- preempt_disable();
- this_cpu = this_cpu_ptr(cpu_stats);
+ this_cpu = raw_cpu_ptr(cpu_stats);
if (tb[NFTA_COUNTER_PACKETS]) {
- this_cpu->packets =
- be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS]));
+ u64_stats_set(&this_cpu->packets,
+ be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS])));
}
if (tb[NFTA_COUNTER_BYTES]) {
- this_cpu->bytes =
- be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES]));
+ u64_stats_set(&this_cpu->bytes,
+ be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES])));
}
- preempt_enable();
+
priv->counter = cpu_stats;
return 0;
}
@@ -104,40 +107,41 @@ static void nft_counter_obj_destroy(const struct nft_ctx *ctx,
}
static void nft_counter_reset(struct nft_counter_percpu_priv *priv,
- struct nft_counter *total)
+ struct nft_counter_tot *total)
{
+ struct u64_stats_sync *nft_sync;
struct nft_counter *this_cpu;
- seqcount_t *myseq;
local_bh_disable();
this_cpu = this_cpu_ptr(priv->counter);
- myseq = this_cpu_ptr(&nft_counter_seq);
+ nft_sync = this_cpu_ptr(&nft_counter_sync);
+
+ u64_stats_update_begin(nft_sync);
+ u64_stats_add(&this_cpu->packets, -total->packets);
+ u64_stats_add(&this_cpu->bytes, -total->bytes);
+ u64_stats_update_end(nft_sync);
- write_seqcount_begin(myseq);
- this_cpu->packets -= total->packets;
- this_cpu->bytes -= total->bytes;
- write_seqcount_end(myseq);
local_bh_enable();
}
static void nft_counter_fetch(struct nft_counter_percpu_priv *priv,
- struct nft_counter *total)
+ struct nft_counter_tot *total)
{
struct nft_counter *this_cpu;
- const seqcount_t *myseq;
u64 bytes, packets;
unsigned int seq;
int cpu;
memset(total, 0, sizeof(*total));
for_each_possible_cpu(cpu) {
- myseq = per_cpu_ptr(&nft_counter_seq, cpu);
+ struct u64_stats_sync *nft_sync = per_cpu_ptr(&nft_counter_sync, cpu);
+
this_cpu = per_cpu_ptr(priv->counter, cpu);
do {
- seq = read_seqcount_begin(myseq);
- bytes = this_cpu->bytes;
- packets = this_cpu->packets;
- } while (read_seqcount_retry(myseq, seq));
+ seq = u64_stats_fetch_begin(nft_sync);
+ bytes = u64_stats_read(&this_cpu->bytes);
+ packets = u64_stats_read(&this_cpu->packets);
+ } while (u64_stats_fetch_retry(nft_sync, seq));
total->bytes += bytes;
total->packets += packets;
@@ -148,7 +152,7 @@ static int nft_counter_do_dump(struct sk_buff *skb,
struct nft_counter_percpu_priv *priv,
bool reset)
{
- struct nft_counter total;
+ struct nft_counter_tot total;
nft_counter_fetch(priv, &total);
@@ -237,7 +241,7 @@ static int nft_counter_clone(struct nft_expr *dst, const struct nft_expr *src, g
struct nft_counter_percpu_priv *priv_clone = nft_expr_priv(dst);
struct nft_counter __percpu *cpu_stats;
struct nft_counter *this_cpu;
- struct nft_counter total;
+ struct nft_counter_tot total;
nft_counter_fetch(priv, &total);
@@ -245,11 +249,9 @@ static int nft_counter_clone(struct nft_expr *dst, const struct nft_expr *src, g
if (cpu_stats == NULL)
return -ENOMEM;
- preempt_disable();
- this_cpu = this_cpu_ptr(cpu_stats);
- this_cpu->packets = total.packets;
- this_cpu->bytes = total.bytes;
- preempt_enable();
+ this_cpu = raw_cpu_ptr(cpu_stats);
+ u64_stats_set(&this_cpu->packets, total.packets);
+ u64_stats_set(&this_cpu->bytes, total.bytes);
priv_clone->counter = cpu_stats;
return 0;
@@ -267,17 +269,17 @@ static void nft_counter_offload_stats(struct nft_expr *expr,
const struct flow_stats *stats)
{
struct nft_counter_percpu_priv *priv = nft_expr_priv(expr);
+ struct u64_stats_sync *nft_sync;
struct nft_counter *this_cpu;
- seqcount_t *myseq;
local_bh_disable();
this_cpu = this_cpu_ptr(priv->counter);
- myseq = this_cpu_ptr(&nft_counter_seq);
+ nft_sync = this_cpu_ptr(&nft_counter_sync);
- write_seqcount_begin(myseq);
- this_cpu->packets += stats->pkts;
- this_cpu->bytes += stats->bytes;
- write_seqcount_end(myseq);
+ u64_stats_update_begin(nft_sync);
+ u64_stats_add(&this_cpu->packets, stats->pkts);
+ u64_stats_add(&this_cpu->bytes, stats->bytes);
+ u64_stats_update_end(nft_sync);
local_bh_enable();
}
@@ -286,7 +288,7 @@ void nft_counter_init_seqcount(void)
int cpu;
for_each_possible_cpu(cpu)
- seqcount_init(per_cpu_ptr(&nft_counter_seq, cpu));
+ u64_stats_init(per_cpu_ptr(&nft_counter_sync, cpu));
}
struct nft_expr_type nft_counter_type;
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 03/16] netfilter: Use kmemdup_array instead of kmemdup for multiple allocation
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 01/16] netfilter: ctnetlink: support CTA_FILTER for flush Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 02/16] netfilter: nft_counter: Use u64_stats_t for statistic Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 04/16] netfilter: conntrack: Convert to use ERR_CAST() Pablo Neira Ayuso
` (12 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
From: Yan Zhen <yanzhen@vivo.com>
When we are allocating an array, using kmemdup_array() to take care about
multiplication and possible overflows.
Also it makes auditing the code easier.
Signed-off-by: Yan Zhen <yanzhen@vivo.com>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/bridge/netfilter/ebtables.c | 2 +-
net/ipv4/netfilter/arp_tables.c | 2 +-
net/ipv4/netfilter/ip_tables.c | 2 +-
net/ipv6/netfilter/ip6_tables.c | 2 +-
net/netfilter/nf_nat_core.c | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index cbd0e3586c3f..3e67d4aff419 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1256,7 +1256,7 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
goto free_unlock;
}
- ops = kmemdup(template_ops, sizeof(*ops) * num_ops, GFP_KERNEL);
+ ops = kmemdup_array(template_ops, num_ops, sizeof(*ops), GFP_KERNEL);
if (!ops) {
ret = -ENOMEM;
if (newinfo->nentries)
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 42c34e8952da..1cdd9c28ab2d 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1547,7 +1547,7 @@ int arpt_register_table(struct net *net,
goto out_free;
}
- ops = kmemdup(template_ops, sizeof(*ops) * num_ops, GFP_KERNEL);
+ ops = kmemdup_array(template_ops, num_ops, sizeof(*ops), GFP_KERNEL);
if (!ops) {
ret = -ENOMEM;
goto out_free;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 97e754ddc155..3d101613f27f 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1767,7 +1767,7 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
goto out_free;
}
- ops = kmemdup(template_ops, sizeof(*ops) * num_ops, GFP_KERNEL);
+ ops = kmemdup_array(template_ops, num_ops, sizeof(*ops), GFP_KERNEL);
if (!ops) {
ret = -ENOMEM;
goto out_free;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 131f7bb2110d..7d5602950ae7 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1773,7 +1773,7 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
goto out_free;
}
- ops = kmemdup(template_ops, sizeof(*ops) * num_ops, GFP_KERNEL);
+ ops = kmemdup_array(template_ops, num_ops, sizeof(*ops), GFP_KERNEL);
if (!ops) {
ret = -ENOMEM;
goto out_free;
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 016c816d91cb..6d8da6dddf99 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -1104,7 +1104,7 @@ int nf_nat_register_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops,
if (!nat_proto_net->nat_hook_ops) {
WARN_ON(nat_proto_net->users != 0);
- nat_ops = kmemdup(orig_nat_ops, sizeof(*orig_nat_ops) * ops_count, GFP_KERNEL);
+ nat_ops = kmemdup_array(orig_nat_ops, ops_count, sizeof(*orig_nat_ops), GFP_KERNEL);
if (!nat_ops) {
mutex_unlock(&nf_nat_proto_mutex);
return -ENOMEM;
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 04/16] netfilter: conntrack: Convert to use ERR_CAST()
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (2 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 03/16] netfilter: Use kmemdup_array instead of kmemdup for multiple allocation Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 05/16] netfilter: nf_tables: drop unused 3rd argument from validate callback ops Pablo Neira Ayuso
` (11 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
From: Shen Lichuan <shenlichuan@vivo.com>
Use the ERR_CAST macro to clearly indicate that this is a pointer
to an error value and that a type conversion was performed.
Signed-off-by: Shen Lichuan <shenlichuan@vivo.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 9384426ddc06..d3cb53b008f5 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1722,7 +1722,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
ct = __nf_conntrack_alloc(net, zone, tuple, &repl_tuple, GFP_ATOMIC,
hash);
if (IS_ERR(ct))
- return (struct nf_conntrack_tuple_hash *)ct;
+ return ERR_CAST(ct);
if (!nf_ct_add_synproxy(ct, tmpl)) {
nf_conntrack_free(ct);
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 05/16] netfilter: nf_tables: drop unused 3rd argument from validate callback ops
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (3 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 04/16] netfilter: conntrack: Convert to use ERR_CAST() Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 06/16] netfilter: nf_tables: Correct spelling in nf_tables.h Pablo Neira Ayuso
` (10 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
From: Florian Westphal <fw@strlen.de>
Since commit a654de8fdc18 ("netfilter: nf_tables: fix chain dependency validation")
the validate() callback no longer needs the return pointer argument.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 3 +--
include/net/netfilter/nft_fib.h | 4 +---
include/net/netfilter/nft_meta.h | 3 +--
include/net/netfilter/nft_reject.h | 3 +--
net/bridge/netfilter/nft_meta_bridge.c | 5 ++---
net/bridge/netfilter/nft_reject_bridge.c | 3 +--
net/netfilter/nf_tables_api.c | 3 +--
net/netfilter/nft_compat.c | 6 ++----
net/netfilter/nft_fib.c | 3 +--
net/netfilter/nft_flow_offload.c | 3 +--
net/netfilter/nft_fwd_netdev.c | 3 +--
net/netfilter/nft_immediate.c | 3 +--
net/netfilter/nft_lookup.c | 3 +--
net/netfilter/nft_masq.c | 3 +--
net/netfilter/nft_meta.c | 6 ++----
net/netfilter/nft_nat.c | 3 +--
net/netfilter/nft_osf.c | 3 +--
net/netfilter/nft_queue.c | 3 +--
net/netfilter/nft_redir.c | 3 +--
net/netfilter/nft_reject.c | 3 +--
net/netfilter/nft_reject_inet.c | 3 +--
net/netfilter/nft_reject_netdev.c | 3 +--
net/netfilter/nft_rt.c | 3 +--
net/netfilter/nft_socket.c | 3 +--
net/netfilter/nft_synproxy.c | 3 +--
net/netfilter/nft_tproxy.c | 3 +--
net/netfilter/nft_xfrm.c | 3 +--
27 files changed, 30 insertions(+), 60 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 1cc33d946d41..7cd60ea7cdee 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -961,8 +961,7 @@ struct nft_expr_ops {
const struct nft_expr *expr,
bool reset);
int (*validate)(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data);
+ const struct nft_expr *expr);
bool (*reduce)(struct nft_regs_track *track,
const struct nft_expr *expr);
bool (*gc)(struct net *net,
diff --git a/include/net/netfilter/nft_fib.h b/include/net/netfilter/nft_fib.h
index 167640b843ef..38cae7113de4 100644
--- a/include/net/netfilter/nft_fib.h
+++ b/include/net/netfilter/nft_fib.h
@@ -21,9 +21,7 @@ nft_fib_is_loopback(const struct sk_buff *skb, const struct net_device *in)
int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr, bool reset);
int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
const struct nlattr * const tb[]);
-int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
- const struct nft_data **data);
-
+int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr);
void nft_fib4_eval_type(const struct nft_expr *expr, struct nft_regs *regs,
const struct nft_pktinfo *pkt);
diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h
index ba1238f12a48..d602263590fe 100644
--- a/include/net/netfilter/nft_meta.h
+++ b/include/net/netfilter/nft_meta.h
@@ -41,8 +41,7 @@ void nft_meta_set_destroy(const struct nft_ctx *ctx,
const struct nft_expr *expr);
int nft_meta_set_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data);
+ const struct nft_expr *expr);
bool nft_meta_get_reduce(struct nft_regs_track *track,
const struct nft_expr *expr);
diff --git a/include/net/netfilter/nft_reject.h b/include/net/netfilter/nft_reject.h
index 6d9ba62efd75..19060212988a 100644
--- a/include/net/netfilter/nft_reject.h
+++ b/include/net/netfilter/nft_reject.h
@@ -15,8 +15,7 @@ struct nft_reject {
extern const struct nla_policy nft_reject_policy[];
int nft_reject_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data);
+ const struct nft_expr *expr);
int nft_reject_init(const struct nft_ctx *ctx,
const struct nft_expr *expr,
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index 4d8e15927217..d12a221366d6 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -168,8 +168,7 @@ static bool nft_meta_bridge_set_reduce(struct nft_regs_track *track,
}
static int nft_meta_bridge_set_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
struct nft_meta *priv = nft_expr_priv(expr);
unsigned int hooks;
@@ -179,7 +178,7 @@ static int nft_meta_bridge_set_validate(const struct nft_ctx *ctx,
hooks = 1 << NF_BR_PRE_ROUTING;
break;
default:
- return nft_meta_set_validate(ctx, expr, data);
+ return nft_meta_set_validate(ctx, expr);
}
return nft_chain_validate_hooks(ctx->chain, hooks);
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c
index 71b54fed7263..1cb5c16e97b7 100644
--- a/net/bridge/netfilter/nft_reject_bridge.c
+++ b/net/bridge/netfilter/nft_reject_bridge.c
@@ -170,8 +170,7 @@ static void nft_reject_bridge_eval(const struct nft_expr *expr,
}
static int nft_reject_bridge_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
return nft_chain_validate_hooks(ctx->chain, (1 << NF_BR_PRE_ROUTING) |
(1 << NF_BR_LOCAL_IN));
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 904f2e25b4a4..b6547fe22bd8 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3886,7 +3886,6 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r
int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
{
struct nft_expr *expr, *last;
- const struct nft_data *data;
struct nft_rule *rule;
int err;
@@ -3907,7 +3906,7 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
/* This may call nft_chain_validate() recursively,
* callers that do so must increment ctx->level.
*/
- err = expr->ops->validate(ctx, expr, &data);
+ err = expr->ops->validate(ctx, expr);
if (err < 0)
return err;
}
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index d3d11dede545..52cdfee17f73 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -350,8 +350,7 @@ static int nft_target_dump(struct sk_buff *skb,
}
static int nft_target_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
struct xt_target *target = expr->ops->data;
unsigned int hook_mask = 0;
@@ -611,8 +610,7 @@ static int nft_match_large_dump(struct sk_buff *skb,
}
static int nft_match_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
struct xt_match *match = expr->ops->data;
unsigned int hook_mask = 0;
diff --git a/net/netfilter/nft_fib.c b/net/netfilter/nft_fib.c
index b58f62195ff3..96e02a83c045 100644
--- a/net/netfilter/nft_fib.c
+++ b/net/netfilter/nft_fib.c
@@ -26,8 +26,7 @@ const struct nla_policy nft_fib_policy[NFTA_FIB_MAX + 1] = {
};
EXPORT_SYMBOL(nft_fib_policy);
-int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
- const struct nft_data **data)
+int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr)
{
const struct nft_fib *priv = nft_expr_priv(expr);
unsigned int hooks;
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index ab9576098701..9dcd1548df9d 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -380,8 +380,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
}
static int nft_flow_offload_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
unsigned int hook_mask = (1 << NF_INET_FORWARD);
diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c
index c83a794025f9..152a9fb4d23a 100644
--- a/net/netfilter/nft_fwd_netdev.c
+++ b/net/netfilter/nft_fwd_netdev.c
@@ -204,8 +204,7 @@ static int nft_fwd_neigh_dump(struct sk_buff *skb,
}
static int nft_fwd_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
return nft_chain_validate_hooks(ctx->chain, (1 << NF_NETDEV_INGRESS) |
(1 << NF_NETDEV_EGRESS));
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index ac2422c215e5..02ee5fb69871 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -244,8 +244,7 @@ static int nft_immediate_dump(struct sk_buff *skb,
}
static int nft_immediate_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **d)
+ const struct nft_expr *expr)
{
const struct nft_immediate_expr *priv = nft_expr_priv(expr);
struct nft_ctx *pctx = (struct nft_ctx *)ctx;
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index 580e4b1deb9b..63ef832b8aa7 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -206,8 +206,7 @@ static int nft_lookup_dump(struct sk_buff *skb,
}
static int nft_lookup_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **d)
+ const struct nft_expr *expr)
{
const struct nft_lookup *priv = nft_expr_priv(expr);
struct nft_set_iter iter;
diff --git a/net/netfilter/nft_masq.c b/net/netfilter/nft_masq.c
index cb43c72a8c2a..868bd4d73555 100644
--- a/net/netfilter/nft_masq.c
+++ b/net/netfilter/nft_masq.c
@@ -27,8 +27,7 @@ static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = {
};
static int nft_masq_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
int err;
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 0214ad1ced2f..8c8eb14d647b 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -581,8 +581,7 @@ static int nft_meta_get_validate_xfrm(const struct nft_ctx *ctx)
}
static int nft_meta_get_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
const struct nft_meta *priv = nft_expr_priv(expr);
@@ -600,8 +599,7 @@ static int nft_meta_get_validate(const struct nft_ctx *ctx,
}
int nft_meta_set_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
struct nft_meta *priv = nft_expr_priv(expr);
unsigned int hooks;
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index 983dd937fe02..6e21f72c5b57 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -137,8 +137,7 @@ static const struct nla_policy nft_nat_policy[NFTA_NAT_MAX + 1] = {
};
static int nft_nat_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
struct nft_nat *priv = nft_expr_priv(expr);
int err;
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index 7fec57ff736f..1c0b493ef0a9 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -108,8 +108,7 @@ static int nft_osf_dump(struct sk_buff *skb,
}
static int nft_osf_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
unsigned int hooks;
diff --git a/net/netfilter/nft_queue.c b/net/netfilter/nft_queue.c
index 44e6817e6e29..344fe311878f 100644
--- a/net/netfilter/nft_queue.c
+++ b/net/netfilter/nft_queue.c
@@ -69,8 +69,7 @@ static void nft_queue_sreg_eval(const struct nft_expr *expr,
}
static int nft_queue_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
static const unsigned int supported_hooks = ((1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_LOCAL_IN) |
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
index 6568cc264078..95eedad85c83 100644
--- a/net/netfilter/nft_redir.c
+++ b/net/netfilter/nft_redir.c
@@ -27,8 +27,7 @@ static const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX + 1] = {
};
static int nft_redir_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
int err;
diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c
index ed2e668474d6..196a92c7ea09 100644
--- a/net/netfilter/nft_reject.c
+++ b/net/netfilter/nft_reject.c
@@ -24,8 +24,7 @@ const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = {
EXPORT_SYMBOL_GPL(nft_reject_policy);
int nft_reject_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
return nft_chain_validate_hooks(ctx->chain,
(1 << NF_INET_LOCAL_IN) |
diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c
index 973fa31a9dd6..49020e67304a 100644
--- a/net/netfilter/nft_reject_inet.c
+++ b/net/netfilter/nft_reject_inet.c
@@ -61,8 +61,7 @@ static void nft_reject_inet_eval(const struct nft_expr *expr,
}
static int nft_reject_inet_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
return nft_chain_validate_hooks(ctx->chain,
(1 << NF_INET_LOCAL_IN) |
diff --git a/net/netfilter/nft_reject_netdev.c b/net/netfilter/nft_reject_netdev.c
index 7865cd8b11bb..2558ce1505d9 100644
--- a/net/netfilter/nft_reject_netdev.c
+++ b/net/netfilter/nft_reject_netdev.c
@@ -145,8 +145,7 @@ static void nft_reject_netdev_eval(const struct nft_expr *expr,
}
static int nft_reject_netdev_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
return nft_chain_validate_hooks(ctx->chain, (1 << NF_NETDEV_INGRESS));
}
diff --git a/net/netfilter/nft_rt.c b/net/netfilter/nft_rt.c
index 14d88394bcb7..dc50b9a5bd68 100644
--- a/net/netfilter/nft_rt.c
+++ b/net/netfilter/nft_rt.c
@@ -160,8 +160,7 @@ static int nft_rt_get_dump(struct sk_buff *skb,
return -1;
}
-static int nft_rt_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
- const struct nft_data **data)
+static int nft_rt_validate(const struct nft_ctx *ctx, const struct nft_expr *expr)
{
const struct nft_rt *priv = nft_expr_priv(expr);
unsigned int hooks;
diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c
index f30163e2ca62..947566dba1ea 100644
--- a/net/netfilter/nft_socket.c
+++ b/net/netfilter/nft_socket.c
@@ -239,8 +239,7 @@ static bool nft_socket_reduce(struct nft_regs_track *track,
}
static int nft_socket_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
if (ctx->family != NFPROTO_IPV4 &&
ctx->family != NFPROTO_IPV6 &&
diff --git a/net/netfilter/nft_synproxy.c b/net/netfilter/nft_synproxy.c
index 1d737f89dfc1..5d3e51825985 100644
--- a/net/netfilter/nft_synproxy.c
+++ b/net/netfilter/nft_synproxy.c
@@ -248,8 +248,7 @@ static void nft_synproxy_eval(const struct nft_expr *expr,
}
static int nft_synproxy_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
if (ctx->family != NFPROTO_IPV4 &&
ctx->family != NFPROTO_IPV6 &&
diff --git a/net/netfilter/nft_tproxy.c b/net/netfilter/nft_tproxy.c
index 1b691393d8b1..50481280abd2 100644
--- a/net/netfilter/nft_tproxy.c
+++ b/net/netfilter/nft_tproxy.c
@@ -313,8 +313,7 @@ static int nft_tproxy_dump(struct sk_buff *skb,
}
static int nft_tproxy_validate(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nft_data **data)
+ const struct nft_expr *expr)
{
if (ctx->family != NFPROTO_IPV4 &&
ctx->family != NFPROTO_IPV6 &&
diff --git a/net/netfilter/nft_xfrm.c b/net/netfilter/nft_xfrm.c
index 1c866757db55..8a07b46cc8fb 100644
--- a/net/netfilter/nft_xfrm.c
+++ b/net/netfilter/nft_xfrm.c
@@ -229,8 +229,7 @@ static int nft_xfrm_get_dump(struct sk_buff *skb,
return 0;
}
-static int nft_xfrm_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
- const struct nft_data **data)
+static int nft_xfrm_validate(const struct nft_ctx *ctx, const struct nft_expr *expr)
{
const struct nft_xfrm *priv = nft_expr_priv(expr);
unsigned int hooks;
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 06/16] netfilter: nf_tables: Correct spelling in nf_tables.h
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (4 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 05/16] netfilter: nf_tables: drop unused 3rd argument from validate callback ops Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 07/16] netfilter: nf_tables: Add missing Kernel doc Pablo Neira Ayuso
` (9 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
From: Simon Horman <horms@kernel.org>
Correct spelling in nf_tables.h.
As reported by codespell.
Signed-off-by: Simon Horman <horms@kernel.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 7cd60ea7cdee..02626ad17e99 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -687,7 +687,7 @@ void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set);
* @NFT_SET_EXT_TIMEOUT: element timeout
* @NFT_SET_EXT_EXPIRATION: element expiration time
* @NFT_SET_EXT_USERDATA: user data associated with the element
- * @NFT_SET_EXT_EXPRESSIONS: expressions assiciated with the element
+ * @NFT_SET_EXT_EXPRESSIONS: expressions associated with the element
* @NFT_SET_EXT_OBJREF: stateful object reference associated with element
* @NFT_SET_EXT_NUM: number of extension types
*/
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 07/16] netfilter: nf_tables: Add missing Kernel doc
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (5 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 06/16] netfilter: nf_tables: Correct spelling in nf_tables.h Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 08/16] netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire Pablo Neira Ayuso
` (8 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
From: Simon Horman <horms@kernel.org>
- Add missing documentation of struct field and enum items.
- Add missing documentation of function parameter.
Flagged by ./scripts/kernel-doc -none.
No functional change intended.
Compile tested only.
Signed-off-by: Simon Horman <horms@kernel.org>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 2 ++
include/net/netfilter/nf_tproxy.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 02626ad17e99..c302b396e1a7 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -209,6 +209,7 @@ static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
* @family: protocol family
* @level: depth of the chains
* @report: notify via unicast netlink message
+ * @reg_inited: bitmap of initialised registers
*/
struct nft_ctx {
struct net *net;
@@ -313,6 +314,7 @@ static inline void *nft_elem_priv_cast(const struct nft_elem_priv *priv)
/**
* enum nft_iter_type - nftables set iterator type
*
+ * @NFT_ITER_UNSPEC: unspecified, to catch errors
* @NFT_ITER_READ: read-only iteration over set elements
* @NFT_ITER_UPDATE: iteration under mutex to update set element state
*/
diff --git a/include/net/netfilter/nf_tproxy.h b/include/net/netfilter/nf_tproxy.h
index faa108b1ba67..5adf6fda11e8 100644
--- a/include/net/netfilter/nf_tproxy.h
+++ b/include/net/netfilter/nf_tproxy.h
@@ -36,6 +36,7 @@ __be32 nf_tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr);
/**
* nf_tproxy_handle_time_wait4 - handle IPv4 TCP TIME_WAIT reopen redirections
+ * @net: The network namespace.
* @skb: The skb being processed.
* @laddr: IPv4 address to redirect to or zero.
* @lport: TCP port to redirect to or zero.
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 08/16] netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (6 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 07/16] netfilter: nf_tables: Add missing Kernel doc Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 09/16] netfilter: nf_tables: reject element expiration with no timeout Pablo Neira Ayuso
` (7 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
Element timeout that is below CONFIG_HZ never expires because the
timeout extension is not allocated given that nf_msecs_to_jiffies64()
returns 0. Set timeout to the minimum value to honor timeout.
Fixes: 8e1102d5a159 ("netfilter: nf_tables: support timeouts larger than 23 days")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index b6547fe22bd8..b49fcd7148d3 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4593,7 +4593,7 @@ int nf_msecs_to_jiffies64(const struct nlattr *nla, u64 *result)
return -ERANGE;
ms *= NSEC_PER_MSEC;
- *result = nsecs_to_jiffies64(ms);
+ *result = nsecs_to_jiffies64(ms) ? : !!ms;
return 0;
}
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 09/16] netfilter: nf_tables: reject element expiration with no timeout
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (7 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 08/16] netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 10/16] netfilter: nf_tables: reject expiration higher than timeout Pablo Neira Ayuso
` (6 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
If element timeout is unset and set provides no default timeout, the
element expiration is silently ignored, reject this instead to let user
know this is unsupported.
Also prepare for supporting timeout that never expire, where zero
timeout and expiration must be also rejected.
Fixes: 8e1102d5a159 ("netfilter: nf_tables: support timeouts larger than 23 days")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index b49fcd7148d3..da75bc1de466 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6923,6 +6923,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
if (nla[NFTA_SET_ELEM_EXPIRATION] != NULL) {
if (!(set->flags & NFT_SET_TIMEOUT))
return -EINVAL;
+ if (timeout == 0)
+ return -EOPNOTSUPP;
+
err = nf_msecs_to_jiffies64(nla[NFTA_SET_ELEM_EXPIRATION],
&expiration);
if (err)
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 10/16] netfilter: nf_tables: reject expiration higher than timeout
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (8 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 09/16] netfilter: nf_tables: reject element expiration with no timeout Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 11/16] netfilter: nf_tables: remove annotation to access set timeout while holding lock Pablo Neira Ayuso
` (5 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
Report ERANGE to userspace if user specifies an expiration larger than
the timeout.
Fixes: 8e1102d5a159 ("netfilter: nf_tables: support timeouts larger than 23 days")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index da75bc1de466..6c0c6f8a08a8 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6930,6 +6930,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
&expiration);
if (err)
return err;
+
+ if (expiration > timeout)
+ return -ERANGE;
}
if (nla[NFTA_SET_ELEM_EXPR]) {
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 11/16] netfilter: nf_tables: remove annotation to access set timeout while holding lock
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (9 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 10/16] netfilter: nf_tables: reject expiration higher than timeout Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 12/16] netfilter: nft_dynset: annotate data-races around set timeout Pablo Neira Ayuso
` (4 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
Mutex is held when adding an element, no need for READ_ONCE, remove it.
Fixes: 123b99619cca ("netfilter: nf_tables: honor set timeout and garbage collection updates")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 6c0c6f8a08a8..571aa30918e9 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6916,7 +6916,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
return err;
} else if (set->flags & NFT_SET_TIMEOUT &&
!(flags & NFT_SET_ELEM_INTERVAL_END)) {
- timeout = READ_ONCE(set->timeout);
+ timeout = set->timeout;
}
expiration = 0;
@@ -7023,7 +7023,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
if (err < 0)
goto err_parse_key_end;
- if (timeout != READ_ONCE(set->timeout)) {
+ if (timeout != set->timeout) {
err = nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
if (err < 0)
goto err_parse_key_end;
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 12/16] netfilter: nft_dynset: annotate data-races around set timeout
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (10 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 11/16] netfilter: nf_tables: remove annotation to access set timeout while holding lock Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 13/16] netfilter: nf_tables: annotate data-races around element expiration Pablo Neira Ayuso
` (3 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
set timeout can be read locklessly while being updated from control
plane, add annotation.
Fixes: 123b99619cca ("netfilter: nf_tables: honor set timeout and garbage collection updates")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_dynset.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index 6920df754265..5812fd880b79 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -56,7 +56,7 @@ static struct nft_elem_priv *nft_dynset_new(struct nft_set *set,
if (!atomic_add_unless(&set->nelems, 1, set->size))
return NULL;
- timeout = priv->timeout ? : set->timeout;
+ timeout = priv->timeout ? : READ_ONCE(set->timeout);
elem_priv = nft_set_elem_init(set, &priv->tmpl,
®s->data[priv->sreg_key], NULL,
®s->data[priv->sreg_data],
@@ -95,7 +95,7 @@ void nft_dynset_eval(const struct nft_expr *expr,
expr, regs, &ext)) {
if (priv->op == NFT_DYNSET_OP_UPDATE &&
nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
- timeout = priv->timeout ? : set->timeout;
+ timeout = priv->timeout ? : READ_ONCE(set->timeout);
*nft_set_ext_expiration(ext) = get_jiffies_64() + timeout;
}
@@ -313,7 +313,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
nft_dynset_ext_add_expr(priv);
if (set->flags & NFT_SET_TIMEOUT) {
- if (timeout || set->timeout) {
+ if (timeout || READ_ONCE(set->timeout)) {
nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_TIMEOUT);
nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
}
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 13/16] netfilter: nf_tables: annotate data-races around element expiration
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (11 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 12/16] netfilter: nft_dynset: annotate data-races around set timeout Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 14/16] netfilter: nf_tables: consolidate timeout extension for elements Pablo Neira Ayuso
` (2 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
element expiration can be read-write locklessly, it can be written by
dynset and read from netlink dump, add annotation.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 2 +-
net/netfilter/nf_tables_api.c | 2 +-
net/netfilter/nft_dynset.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index c302b396e1a7..1528af3fe26f 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -835,7 +835,7 @@ static inline bool __nft_set_elem_expired(const struct nft_set_ext *ext,
u64 tstamp)
{
return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) &&
- time_after_eq64(tstamp, *nft_set_ext_expiration(ext));
+ time_after_eq64(tstamp, READ_ONCE(*nft_set_ext_expiration(ext)));
}
static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 571aa30918e9..77dce3d61ae6 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5827,7 +5827,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
u64 expires, now = get_jiffies_64();
- expires = *nft_set_ext_expiration(ext);
+ expires = READ_ONCE(*nft_set_ext_expiration(ext));
if (time_before64(now, expires))
expires -= now;
else
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index 5812fd880b79..ca4b52e68295 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -96,7 +96,7 @@ void nft_dynset_eval(const struct nft_expr *expr,
if (priv->op == NFT_DYNSET_OP_UPDATE &&
nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
timeout = priv->timeout ? : READ_ONCE(set->timeout);
- *nft_set_ext_expiration(ext) = get_jiffies_64() + timeout;
+ WRITE_ONCE(*nft_set_ext_expiration(ext), get_jiffies_64() + timeout);
}
nft_set_elem_update_expr(ext, regs, pkt);
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 14/16] netfilter: nf_tables: consolidate timeout extension for elements
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (12 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 13/16] netfilter: nf_tables: annotate data-races around element expiration Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 15/16] netfilter: nf_tables: zero timeout means element never times out Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 16/16] netfilter: nf_tables: set element timeout update support Pablo Neira Ayuso
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
Expiration and timeout are stored in separated set element extensions,
but they are tightly coupled. Consolidate them in a single extension to
simplify and prepare for set element updates.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 18 ++++++-------
net/netfilter/nf_tables_api.c | 43 ++++++++++++-------------------
net/netfilter/nft_dynset.c | 13 ++++------
3 files changed, 30 insertions(+), 44 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 1528af3fe26f..1e9b5e1659a1 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -687,7 +687,6 @@ void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set);
* @NFT_SET_EXT_DATA: mapping data
* @NFT_SET_EXT_FLAGS: element flags
* @NFT_SET_EXT_TIMEOUT: element timeout
- * @NFT_SET_EXT_EXPIRATION: element expiration time
* @NFT_SET_EXT_USERDATA: user data associated with the element
* @NFT_SET_EXT_EXPRESSIONS: expressions associated with the element
* @NFT_SET_EXT_OBJREF: stateful object reference associated with element
@@ -699,7 +698,6 @@ enum nft_set_extensions {
NFT_SET_EXT_DATA,
NFT_SET_EXT_FLAGS,
NFT_SET_EXT_TIMEOUT,
- NFT_SET_EXT_EXPIRATION,
NFT_SET_EXT_USERDATA,
NFT_SET_EXT_EXPRESSIONS,
NFT_SET_EXT_OBJREF,
@@ -811,14 +809,14 @@ static inline u8 *nft_set_ext_flags(const struct nft_set_ext *ext)
return nft_set_ext(ext, NFT_SET_EXT_FLAGS);
}
-static inline u64 *nft_set_ext_timeout(const struct nft_set_ext *ext)
-{
- return nft_set_ext(ext, NFT_SET_EXT_TIMEOUT);
-}
+struct nft_timeout {
+ u64 timeout;
+ u64 expiration;
+};
-static inline u64 *nft_set_ext_expiration(const struct nft_set_ext *ext)
+static inline struct nft_timeout *nft_set_ext_timeout(const struct nft_set_ext *ext)
{
- return nft_set_ext(ext, NFT_SET_EXT_EXPIRATION);
+ return nft_set_ext(ext, NFT_SET_EXT_TIMEOUT);
}
static inline struct nft_userdata *nft_set_ext_userdata(const struct nft_set_ext *ext)
@@ -834,8 +832,8 @@ static inline struct nft_set_elem_expr *nft_set_ext_expr(const struct nft_set_ex
static inline bool __nft_set_elem_expired(const struct nft_set_ext *ext,
u64 tstamp)
{
- return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) &&
- time_after_eq64(tstamp, READ_ONCE(*nft_set_ext_expiration(ext)));
+ return nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
+ time_after_eq64(tstamp, READ_ONCE(nft_set_ext_timeout(ext)->expiration));
}
static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 77dce3d61ae6..c295d6e6c1fb 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5694,12 +5694,8 @@ const struct nft_set_ext_type nft_set_ext_types[] = {
.align = __alignof__(u8),
},
[NFT_SET_EXT_TIMEOUT] = {
- .len = sizeof(u64),
- .align = __alignof__(u64),
- },
- [NFT_SET_EXT_EXPIRATION] = {
- .len = sizeof(u64),
- .align = __alignof__(u64),
+ .len = sizeof(struct nft_timeout),
+ .align = __alignof__(struct nft_timeout),
},
[NFT_SET_EXT_USERDATA] = {
.len = sizeof(struct nft_userdata),
@@ -5818,16 +5814,16 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
htonl(*nft_set_ext_flags(ext))))
goto nla_put_failure;
- if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
- nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
- nf_jiffies64_to_msecs(*nft_set_ext_timeout(ext)),
- NFTA_SET_ELEM_PAD))
- goto nla_put_failure;
-
- if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
+ if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) {
u64 expires, now = get_jiffies_64();
- expires = READ_ONCE(*nft_set_ext_expiration(ext));
+ if (nft_set_ext_timeout(ext)->timeout != READ_ONCE(set->timeout) &&
+ nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
+ nf_jiffies64_to_msecs(nft_set_ext_timeout(ext)->timeout),
+ NFTA_SET_ELEM_PAD))
+ goto nla_put_failure;
+
+ expires = READ_ONCE(nft_set_ext_timeout(ext)->expiration);
if (time_before64(now, expires))
expires -= now;
else
@@ -6499,13 +6495,14 @@ struct nft_elem_priv *nft_set_elem_init(const struct nft_set *set,
nft_set_ext_data(ext), data, set->dlen) < 0)
goto err_ext_check;
- if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
- *nft_set_ext_expiration(ext) = get_jiffies_64() + expiration;
+ if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) {
+ nft_set_ext_timeout(ext)->timeout = timeout;
+
if (expiration == 0)
- *nft_set_ext_expiration(ext) += timeout;
+ expiration = timeout;
+
+ nft_set_ext_timeout(ext)->expiration = get_jiffies_64() + expiration;
}
- if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
- *nft_set_ext_timeout(ext) = timeout;
return elem;
@@ -7019,15 +7016,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
}
if (timeout > 0) {
- err = nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
+ err = nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
if (err < 0)
goto err_parse_key_end;
-
- if (timeout != set->timeout) {
- err = nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
- if (err < 0)
- goto err_parse_key_end;
- }
}
if (num_exprs) {
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index ca4b52e68295..ed8d692bebe3 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -94,9 +94,9 @@ void nft_dynset_eval(const struct nft_expr *expr,
if (set->ops->update(set, ®s->data[priv->sreg_key], nft_dynset_new,
expr, regs, &ext)) {
if (priv->op == NFT_DYNSET_OP_UPDATE &&
- nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
+ nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) {
timeout = priv->timeout ? : READ_ONCE(set->timeout);
- WRITE_ONCE(*nft_set_ext_expiration(ext), get_jiffies_64() + timeout);
+ WRITE_ONCE(nft_set_ext_timeout(ext)->expiration, get_jiffies_64() + timeout);
}
nft_set_elem_update_expr(ext, regs, pkt);
@@ -312,12 +312,9 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
if (priv->num_exprs)
nft_dynset_ext_add_expr(priv);
- if (set->flags & NFT_SET_TIMEOUT) {
- if (timeout || READ_ONCE(set->timeout)) {
- nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_TIMEOUT);
- nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
- }
- }
+ if (set->flags & NFT_SET_TIMEOUT &&
+ (timeout || READ_ONCE(set->timeout)))
+ nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_TIMEOUT);
priv->timeout = timeout;
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 15/16] netfilter: nf_tables: zero timeout means element never times out
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (13 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 14/16] netfilter: nf_tables: consolidate timeout extension for elements Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
2024-09-05 23:29 ` [PATCH net-next 16/16] netfilter: nf_tables: set element timeout update support Pablo Neira Ayuso
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
This patch uses zero as timeout marker for those elements that never expire
when the element is created.
If userspace provides no timeout for an element, then the default set
timeout applies. However, if no default set timeout is specified and
timeout flag is set on, then timeout extension is allocated and timeout
is set to zero to allow for future updates.
Use of zero a never timeout marker has been suggested by Phil Sutter.
Note that, in older kernels, it is already possible to define elements
that never expire by declaring a set with the set timeout flag set on
and no global set timeout, in this case, new element with no explicit
timeout never expire do not allocate the timeout extension, hence, they
never expire. This approach makes it complicated to accomodate element
timeout update, because element extensions do not support reallocations.
Therefore, allocate the timeout extension and use the new marker for
this case, but do not expose it to userspace to retain backward
compatibility in the set listing.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 7 +++--
include/uapi/linux/netfilter/nf_tables.h | 2 +-
net/netfilter/nf_tables_api.c | 39 ++++++++++++++----------
net/netfilter/nft_dynset.c | 3 +-
4 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 1e9b5e1659a1..7511918dce6f 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -832,8 +832,11 @@ static inline struct nft_set_elem_expr *nft_set_ext_expr(const struct nft_set_ex
static inline bool __nft_set_elem_expired(const struct nft_set_ext *ext,
u64 tstamp)
{
- return nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
- time_after_eq64(tstamp, READ_ONCE(nft_set_ext_timeout(ext)->expiration));
+ if (!nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) ||
+ nft_set_ext_timeout(ext)->timeout == 0)
+ return false;
+
+ return time_after_eq64(tstamp, READ_ONCE(nft_set_ext_timeout(ext)->expiration));
}
static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 639894ed1b97..d6476ca5d7a6 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -436,7 +436,7 @@ enum nft_set_elem_flags {
* @NFTA_SET_ELEM_KEY: key value (NLA_NESTED: nft_data)
* @NFTA_SET_ELEM_DATA: data value of mapping (NLA_NESTED: nft_data_attributes)
* @NFTA_SET_ELEM_FLAGS: bitmask of nft_set_elem_flags (NLA_U32)
- * @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64)
+ * @NFTA_SET_ELEM_TIMEOUT: timeout value, zero means never times out (NLA_U64)
* @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64)
* @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY)
* @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c295d6e6c1fb..ed85b10edb32 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5815,24 +5815,31 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
goto nla_put_failure;
if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) {
- u64 expires, now = get_jiffies_64();
+ u64 timeout = nft_set_ext_timeout(ext)->timeout;
+ u64 set_timeout = READ_ONCE(set->timeout);
+ __be64 msecs = 0;
+
+ if (set_timeout != timeout) {
+ msecs = nf_jiffies64_to_msecs(timeout);
+ if (nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT, msecs,
+ NFTA_SET_ELEM_PAD))
+ goto nla_put_failure;
+ }
- if (nft_set_ext_timeout(ext)->timeout != READ_ONCE(set->timeout) &&
- nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
- nf_jiffies64_to_msecs(nft_set_ext_timeout(ext)->timeout),
- NFTA_SET_ELEM_PAD))
- goto nla_put_failure;
+ if (timeout > 0) {
+ u64 expires, now = get_jiffies_64();
- expires = READ_ONCE(nft_set_ext_timeout(ext)->expiration);
- if (time_before64(now, expires))
- expires -= now;
- else
- expires = 0;
+ expires = READ_ONCE(nft_set_ext_timeout(ext)->expiration);
+ if (time_before64(now, expires))
+ expires -= now;
+ else
+ expires = 0;
- if (nla_put_be64(skb, NFTA_SET_ELEM_EXPIRATION,
- nf_jiffies64_to_msecs(expires),
- NFTA_SET_ELEM_PAD))
- goto nla_put_failure;
+ if (nla_put_be64(skb, NFTA_SET_ELEM_EXPIRATION,
+ nf_jiffies64_to_msecs(expires),
+ NFTA_SET_ELEM_PAD))
+ goto nla_put_failure;
+ }
}
if (nft_set_ext_exists(ext, NFT_SET_EXT_USERDATA)) {
@@ -7015,7 +7022,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
goto err_parse_key_end;
}
- if (timeout > 0) {
+ if (set->flags & NFT_SET_TIMEOUT) {
err = nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
if (err < 0)
goto err_parse_key_end;
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index ed8d692bebe3..6a10305de24b 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -94,7 +94,8 @@ void nft_dynset_eval(const struct nft_expr *expr,
if (set->ops->update(set, ®s->data[priv->sreg_key], nft_dynset_new,
expr, regs, &ext)) {
if (priv->op == NFT_DYNSET_OP_UPDATE &&
- nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) {
+ nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
+ nft_set_ext_timeout(ext)->timeout != 0) {
timeout = priv->timeout ? : READ_ONCE(set->timeout);
WRITE_ONCE(nft_set_ext_timeout(ext)->expiration, get_jiffies_64() + timeout);
}
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next 16/16] netfilter: nf_tables: set element timeout update support
2024-09-05 23:29 [PATCH net-next 00/16] Netfilter updates for net-next Pablo Neira Ayuso
` (14 preceding siblings ...)
2024-09-05 23:29 ` [PATCH net-next 15/16] netfilter: nf_tables: zero timeout means element never times out Pablo Neira Ayuso
@ 2024-09-05 23:29 ` Pablo Neira Ayuso
15 siblings, 0 replies; 19+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-05 23:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, fw
Store new timeout and expiration in transaction object, use them to
update elements from .commit path. Otherwise, discard update if .abort
path is exercised.
Use update_flags in the transaction to note whether the timeout,
expiration, or both need to be updated.
Annotate access to timeout extension now that it can be updated while
lockless read access is possible.
Reject timeout updates on elements with no timeout extension.
Element transaction remains in the 96 bytes kmalloc slab on x86_64 after
this update.
This patch requires ("netfilter: nf_tables: use timestamp to check for
set element timeout") to make sure an element does not expire while
transaction is ongoing.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 16 ++++++++++-
net/netfilter/nf_tables_api.c | 47 ++++++++++++++++++++++++++++---
net/netfilter/nft_dynset.c | 2 +-
3 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 7511918dce6f..49708e7e1339 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -833,7 +833,7 @@ static inline bool __nft_set_elem_expired(const struct nft_set_ext *ext,
u64 tstamp)
{
if (!nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) ||
- nft_set_ext_timeout(ext)->timeout == 0)
+ READ_ONCE(nft_set_ext_timeout(ext)->timeout) == 0)
return false;
return time_after_eq64(tstamp, READ_ONCE(nft_set_ext_timeout(ext)->expiration));
@@ -1749,10 +1749,18 @@ struct nft_trans_table {
#define nft_trans_table_update(trans) \
nft_trans_container_table(trans)->update
+enum nft_trans_elem_flags {
+ NFT_TRANS_UPD_TIMEOUT = (1 << 0),
+ NFT_TRANS_UPD_EXPIRATION = (1 << 1),
+};
+
struct nft_trans_elem {
struct nft_trans nft_trans;
struct nft_set *set;
struct nft_elem_priv *elem_priv;
+ u64 timeout;
+ u64 expiration;
+ u8 update_flags;
bool bound;
};
@@ -1762,6 +1770,12 @@ struct nft_trans_elem {
nft_trans_container_elem(trans)->set
#define nft_trans_elem_priv(trans) \
nft_trans_container_elem(trans)->elem_priv
+#define nft_trans_elem_update_flags(trans) \
+ nft_trans_container_elem(trans)->update_flags
+#define nft_trans_elem_timeout(trans) \
+ nft_trans_container_elem(trans)->timeout
+#define nft_trans_elem_expiration(trans) \
+ nft_trans_container_elem(trans)->expiration
#define nft_trans_elem_set_bound(trans) \
nft_trans_container_elem(trans)->bound
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index ed85b10edb32..57259b5f3ef5 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5815,7 +5815,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
goto nla_put_failure;
if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) {
- u64 timeout = nft_set_ext_timeout(ext)->timeout;
+ u64 timeout = READ_ONCE(nft_set_ext_timeout(ext)->timeout);
u64 set_timeout = READ_ONCE(set->timeout);
__be64 msecs = 0;
@@ -6852,6 +6852,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
struct nft_data_desc desc;
enum nft_registers dreg;
struct nft_trans *trans;
+ u8 update_flags;
u64 expiration;
u64 timeout;
int err, i;
@@ -7163,8 +7164,30 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF) &&
*nft_set_ext_obj(ext) != *nft_set_ext_obj(ext2)))
goto err_element_clash;
- else if (!(nlmsg_flags & NLM_F_EXCL))
+ else if (!(nlmsg_flags & NLM_F_EXCL)) {
err = 0;
+ if (nft_set_ext_exists(ext2, NFT_SET_EXT_TIMEOUT)) {
+ update_flags = 0;
+ if (timeout != nft_set_ext_timeout(ext2)->timeout) {
+ nft_trans_elem_timeout(trans) = timeout;
+ if (expiration == 0)
+ expiration = timeout;
+
+ update_flags |= NFT_TRANS_UPD_TIMEOUT;
+ }
+ if (expiration) {
+ nft_trans_elem_expiration(trans) = expiration;
+ update_flags |= NFT_TRANS_UPD_EXPIRATION;
+ }
+
+ if (update_flags) {
+ nft_trans_elem_priv(trans) = elem_priv;
+ nft_trans_elem_update_flags(trans) = update_flags;
+ nft_trans_commit_list_add_tail(ctx->net, trans);
+ goto err_elem_free;
+ }
+ }
+ }
} else if (err == -ENOTEMPTY) {
/* ENOTEMPTY reports overlapping between this element
* and an existing one.
@@ -10489,7 +10512,22 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
case NFT_MSG_NEWSETELEM:
te = nft_trans_container_elem(trans);
- nft_setelem_activate(net, te->set, te->elem_priv);
+ if (te->update_flags) {
+ const struct nft_set_ext *ext =
+ nft_set_elem_ext(te->set, te->elem_priv);
+
+ if (te->update_flags & NFT_TRANS_UPD_TIMEOUT) {
+ WRITE_ONCE(nft_set_ext_timeout(ext)->timeout,
+ te->timeout);
+ }
+ if (te->update_flags & NFT_TRANS_UPD_EXPIRATION) {
+ WRITE_ONCE(nft_set_ext_timeout(ext)->expiration,
+ get_jiffies_64() + te->expiration);
+ }
+ } else {
+ nft_setelem_activate(net, te->set, te->elem_priv);
+ }
+
nf_tables_setelem_notify(&ctx, te->set,
te->elem_priv,
NFT_MSG_NEWSETELEM);
@@ -10789,7 +10827,8 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
nft_trans_destroy(trans);
break;
case NFT_MSG_NEWSETELEM:
- if (nft_trans_elem_set_bound(trans)) {
+ if (nft_trans_elem_update_flags(trans) ||
+ nft_trans_elem_set_bound(trans)) {
nft_trans_destroy(trans);
break;
}
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index 6a10305de24b..88922e0e8e83 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -95,7 +95,7 @@ void nft_dynset_eval(const struct nft_expr *expr,
expr, regs, &ext)) {
if (priv->op == NFT_DYNSET_OP_UPDATE &&
nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
- nft_set_ext_timeout(ext)->timeout != 0) {
+ READ_ONCE(nft_set_ext_timeout(ext)->timeout) != 0) {
timeout = priv->timeout ? : READ_ONCE(set->timeout);
WRITE_ONCE(nft_set_ext_timeout(ext)->expiration, get_jiffies_64() + timeout);
}
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread