Commit e89a6804 authored by Lance Yang's avatar Lance Yang Committed by Pablo Neira Ayuso
Browse files

netfilter: load nf_log_syslog on enabling nf_conntrack_log_invalid



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: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarZi Li <zi.li@linux.dev>
Signed-off-by: default avatarLance Yang <lance.yang@linux.dev>
Acked-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent aa584016
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);

+25 −1
Original line number Diff line number Diff line
@@ -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>
@@ -555,6 +556,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 {
@@ -651,7 +675,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",
+26 −0
Original line number Diff line number Diff line
@@ -125,6 +125,32 @@ 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;

	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)
{