[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250526085902.36467-1-lance.yang@linux.dev>
Date: Mon, 26 May 2025 16:59:02 +0800
From: Lance Yang <ioworker0@...il.com>
To: fw@...len.de,
pablo@...filter.org
Cc: coreteam@...filter.org,
davem@...emloft.net,
edumazet@...gle.com,
horms@...nel.org,
kadlec@...filter.org,
kuba@...nel.org,
linux-kernel@...r.kernel.org,
netfilter-devel@...r.kernel.org,
pabeni@...hat.com,
zi.li@...ux.dev,
Lance Yang <lance.yang@...ux.dev>
Subject: [PATCH v2 1/1] netfilter: load nf_log_syslog on enabling nf_conntrack_log_invalid
From: Lance Yang <lance.yang@...ux.dev>
When no logger is registered, nf_conntrack_log_invalid fails to log invalid
packets, leaving users unaware of actual invalid traffic. Improve this by
loading nf_log_syslog, similar to how 'iptables -I FORWARD 1 -m conntrack
--ctstate INVALID -j LOG' triggers it.
Suggested-by: Florian Westphal <fw@...len.de>
Signed-off-by: Zi Li <zi.li@...ux.dev>
Signed-off-by: Lance Yang <lance.yang@...ux.dev>
---
v1 -> v2:
- Add a new, simpler helper (per Florian)
- Load the module only when no logger is registered (per Florian)
- https://lore.kernel.org/all/20250514053751.2271-1-lance.yang@linux.dev/
include/net/netfilter/nf_log.h | 3 +++
net/netfilter/nf_conntrack_standalone.c | 26 +++++++++++++++++++++++-
net/netfilter/nf_log.c | 27 +++++++++++++++++++++++++
3 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
index e55eedc84ed7..00506792a06d 100644
--- a/include/net/netfilter/nf_log.h
+++ b/include/net/netfilter/nf_log.h
@@ -59,6 +59,9 @@ extern int sysctl_nf_log_all_netns;
int nf_log_register(u_int8_t pf, struct nf_logger *logger);
void nf_log_unregister(struct nf_logger *logger);
+/* Check if any logger is registered for a given protocol family. */
+bool nf_log_is_registered(u_int8_t pf);
+
int nf_log_set(struct net *net, u_int8_t pf, const struct nf_logger *logger);
void nf_log_unset(struct net *net, const struct nf_logger *logger);
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 2f666751c7e7..cdc27424f84a 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -14,6 +14,7 @@
#include <linux/sysctl.h>
#endif
+#include <net/netfilter/nf_log.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
@@ -543,6 +544,29 @@ nf_conntrack_hash_sysctl(const struct ctl_table *table, int write,
return ret;
}
+static int
+nf_conntrack_log_invalid_sysctl(const struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ int ret, i;
+
+ ret = proc_dou8vec_minmax(table, write, buffer, lenp, ppos);
+ if (ret < 0 || !write)
+ return ret;
+
+ if (*(u8 *)table->data == 0)
+ return ret;
+
+ /* Load nf_log_syslog only if no logger is currently registered */
+ for (i = 0; i < NFPROTO_NUMPROTO; i++) {
+ if (nf_log_is_registered(i))
+ return ret;
+ }
+ request_module("%s", "nf_log_syslog");
+
+ return ret;
+}
+
static struct ctl_table_header *nf_ct_netfilter_header;
enum nf_ct_sysctl_index {
@@ -649,7 +673,7 @@ static struct ctl_table nf_ct_sysctl_table[] = {
.data = &init_net.ct.sysctl_log_invalid,
.maxlen = sizeof(u8),
.mode = 0644,
- .proc_handler = proc_dou8vec_minmax,
+ .proc_handler = nf_conntrack_log_invalid_sysctl,
},
[NF_SYSCTL_CT_EXPECT_MAX] = {
.procname = "nf_conntrack_expect_max",
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 6dd0de33eebd..c7dd5019a89d 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -125,6 +125,33 @@ void nf_log_unregister(struct nf_logger *logger)
}
EXPORT_SYMBOL(nf_log_unregister);
+/**
+ * nf_log_is_registered - Check if any logger is registered for a given
+ * protocol family.
+ *
+ * @pf: Protocol family
+ *
+ * Returns: true if at least one logger is active for @pf, false otherwise.
+ */
+bool nf_log_is_registered(u_int8_t pf)
+{
+ int i;
+
+ /* Out of bounds. */
+ if (pf >= NFPROTO_NUMPROTO) {
+ WARN_ON_ONCE(1);
+ return false;
+ }
+
+ for (i = 0; i < NF_LOG_TYPE_MAX; i++) {
+ if (rcu_access_pointer(loggers[pf][i]))
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(nf_log_is_registered);
+
int nf_log_bind_pf(struct net *net, u_int8_t pf,
const struct nf_logger *logger)
{
--
2.49.0
Powered by blists - more mailing lists