diff mbox series

[SRU,Xenial,1/1] netfilter: allow logging from non-init namespaces

Message ID 39e23fdcc196851e3039ac7217c4a8447bb6bcef.1524585579.git.joseph.salisbury@canonical.com
State New
Headers show
Series netfilter: allow logging from non-init namespaces | expand

Commit Message

Joseph Salisbury April 27, 2018, 7:11 p.m. UTC
From: Michal Kubeček <mkubecek@suse.cz>

BugLink: http://bugs.launchpad.net/bugs/1766573

Commit 69b34fb996b2 ("netfilter: xt_LOG: add net namespace support for
xt_LOG") disabled logging packets using the LOG target from non-init
namespaces. The motivation was to prevent containers from flooding
kernel log of the host. The plan was to keep it that way until syslog
namespace implementation allows containers to log in a safe way.

However, the work on syslog namespace seems to have hit a dead end
somewhere in 2013 and there are users who want to use xt_LOG in all
network namespaces. This patch allows to do so by setting

  /proc/sys/net/netfilter/nf_log_all_netns

to a nonzero value. This sysctl is only accessible from init_net so that
one cannot switch the behaviour from inside a container.

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
(cherry picked from commit 2851940ffee313e0ff12540a8e11a8c54dea9c65)
Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com>
---
 Documentation/networking/netfilter-sysctl.txt | 10 ++++++++++
 include/net/netfilter/nf_log.h                |  3 +++
 net/bridge/netfilter/ebt_log.c                |  2 +-
 net/ipv4/netfilter/nf_log_arp.c               |  2 +-
 net/ipv4/netfilter/nf_log_ipv4.c              |  2 +-
 net/ipv6/netfilter/nf_log_ipv6.c              |  2 +-
 net/netfilter/nf_log.c                        | 24 ++++++++++++++++++++++++
 7 files changed, 41 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/networking/netfilter-sysctl.txt

Comments

Kleber Sacilotto de Souza May 8, 2018, 1:38 p.m. UTC | #1
On 04/27/18 21:11, Joseph Salisbury wrote:
> From: Michal Kubeček <mkubecek@suse.cz>
> 
> BugLink: http://bugs.launchpad.net/bugs/1766573
> 
> Commit 69b34fb996b2 ("netfilter: xt_LOG: add net namespace support for
> xt_LOG") disabled logging packets using the LOG target from non-init
> namespaces. The motivation was to prevent containers from flooding
> kernel log of the host. The plan was to keep it that way until syslog
> namespace implementation allows containers to log in a safe way.
> 
> However, the work on syslog namespace seems to have hit a dead end
> somewhere in 2013 and there are users who want to use xt_LOG in all
> network namespaces. This patch allows to do so by setting
> 
>   /proc/sys/net/netfilter/nf_log_all_netns
> 
> to a nonzero value. This sysctl is only accessible from init_net so that
> one cannot switch the behaviour from inside a container.
> 
> Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> (cherry picked from commit 2851940ffee313e0ff12540a8e11a8c54dea9c65)
> Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com>

Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>

> ---
>  Documentation/networking/netfilter-sysctl.txt | 10 ++++++++++
>  include/net/netfilter/nf_log.h                |  3 +++
>  net/bridge/netfilter/ebt_log.c                |  2 +-
>  net/ipv4/netfilter/nf_log_arp.c               |  2 +-
>  net/ipv4/netfilter/nf_log_ipv4.c              |  2 +-
>  net/ipv6/netfilter/nf_log_ipv6.c              |  2 +-
>  net/netfilter/nf_log.c                        | 24 ++++++++++++++++++++++++
>  7 files changed, 41 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/networking/netfilter-sysctl.txt
> 
> diff --git a/Documentation/networking/netfilter-sysctl.txt b/Documentation/networking/netfilter-sysctl.txt
> new file mode 100644
> index 0000000..55791e5
> --- /dev/null
> +++ b/Documentation/networking/netfilter-sysctl.txt
> @@ -0,0 +1,10 @@
> +/proc/sys/net/netfilter/* Variables:
> +
> +nf_log_all_netns - BOOLEAN
> +	0 - disabled (default)
> +	not 0 - enabled
> +
> +	By default, only init_net namespace can log packets into kernel log
> +	with LOG target; this aims to prevent containers from flooding host
> +	kernel log. If enabled, this target also works in other network
> +	namespaces. This variable is only accessible from init_net.
> diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
> index 57639fc..8c4b018 100644
> --- a/include/net/netfilter/nf_log.h
> +++ b/include/net/netfilter/nf_log.h
> @@ -49,6 +49,9 @@ struct nf_logger {
>  	struct module		*me;
>  };
>  
> +/* sysctl_nf_log_all_netns - allow LOG target in all network namespaces */
> +extern int sysctl_nf_log_all_netns;
> +
>  /* Function to register/unregister log function. */
>  int nf_log_register(u_int8_t pf, struct nf_logger *logger);
>  void nf_log_unregister(struct nf_logger *logger);
> diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
> index 0ad639a..0a2d0e3 100644
> --- a/net/bridge/netfilter/ebt_log.c
> +++ b/net/bridge/netfilter/ebt_log.c
> @@ -80,7 +80,7 @@ ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
>  	unsigned int bitmask;
>  
>  	/* FIXME: Disabled from containers until syslog ns is supported */
> -	if (!net_eq(net, &init_net))
> +	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
>  		return;
>  
>  	spin_lock_bh(&ebt_log_lock);
> diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c
> index e7ad950..39e1348 100644
> --- a/net/ipv4/netfilter/nf_log_arp.c
> +++ b/net/ipv4/netfilter/nf_log_arp.c
> @@ -87,7 +87,7 @@ static void nf_log_arp_packet(struct net *net, u_int8_t pf,
>  	struct nf_log_buf *m;
>  
>  	/* FIXME: Disabled from containers until syslog ns is supported */
> -	if (!net_eq(net, &init_net))
> +	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
>  		return;
>  
>  	m = nf_log_buf_open();
> diff --git a/net/ipv4/netfilter/nf_log_ipv4.c b/net/ipv4/netfilter/nf_log_ipv4.c
> index 076aadd..2b00831 100644
> --- a/net/ipv4/netfilter/nf_log_ipv4.c
> +++ b/net/ipv4/netfilter/nf_log_ipv4.c
> @@ -319,7 +319,7 @@ static void nf_log_ip_packet(struct net *net, u_int8_t pf,
>  	struct nf_log_buf *m;
>  
>  	/* FIXME: Disabled from containers until syslog ns is supported */
> -	if (!net_eq(net, &init_net))
> +	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
>  		return;
>  
>  	m = nf_log_buf_open();
> diff --git a/net/ipv6/netfilter/nf_log_ipv6.c b/net/ipv6/netfilter/nf_log_ipv6.c
> index 8dd8696..0496048 100644
> --- a/net/ipv6/netfilter/nf_log_ipv6.c
> +++ b/net/ipv6/netfilter/nf_log_ipv6.c
> @@ -351,7 +351,7 @@ static void nf_log_ip6_packet(struct net *net, u_int8_t pf,
>  	struct nf_log_buf *m;
>  
>  	/* FIXME: Disabled from containers until syslog ns is supported */
> -	if (!net_eq(net, &init_net))
> +	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
>  		return;
>  
>  	m = nf_log_buf_open();
> diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
> index 2c89f90..d84e11a 100644
> --- a/net/netfilter/nf_log.c
> +++ b/net/netfilter/nf_log.c
> @@ -16,6 +16,9 @@
>  #define NF_LOG_PREFIXLEN		128
>  #define NFLOGGER_NAME_LEN		64
>  
> +int sysctl_nf_log_all_netns __read_mostly;
> +EXPORT_SYMBOL(sysctl_nf_log_all_netns);
> +
>  static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly;
>  static DEFINE_MUTEX(nf_log_mutex);
>  
> @@ -392,6 +395,18 @@ static const struct file_operations nflog_file_ops = {
>  #ifdef CONFIG_SYSCTL
>  static char nf_log_sysctl_fnames[NFPROTO_NUMPROTO-NFPROTO_UNSPEC][3];
>  static struct ctl_table nf_log_sysctl_table[NFPROTO_NUMPROTO+1];
> +static struct ctl_table_header *nf_log_sysctl_fhdr;
> +
> +static struct ctl_table nf_log_sysctl_ftable[] = {
> +	{
> +		.procname	= "nf_log_all_netns",
> +		.data		= &sysctl_nf_log_all_netns,
> +		.maxlen		= sizeof(sysctl_nf_log_all_netns),
> +		.mode		= 0644,
> +		.proc_handler	= proc_dointvec,
> +	},
> +	{ }
> +};
>  
>  static int nf_log_proc_dostring(struct ctl_table *table, int write,
>  			 void __user *buffer, size_t *lenp, loff_t *ppos)
> @@ -460,6 +475,10 @@ static int netfilter_log_sysctl_init(struct net *net)
>  			nf_log_sysctl_table[i].extra1 =
>  				(void *)(unsigned long) i;
>  		}
> +		nf_log_sysctl_fhdr = register_net_sysctl(net, "net/netfilter",
> +							 nf_log_sysctl_ftable);
> +		if (!nf_log_sysctl_fhdr)
> +			goto err_freg;
>  	}
>  
>  	for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
> @@ -476,6 +495,9 @@ static int netfilter_log_sysctl_init(struct net *net)
>  err_reg:
>  	if (!net_eq(net, &init_net))
>  		kfree(table);
> +	else
> +		unregister_net_sysctl_table(nf_log_sysctl_fhdr);
> +err_freg:
>  err_alloc:
>  	return -ENOMEM;
>  }
> @@ -488,6 +510,8 @@ static void netfilter_log_sysctl_exit(struct net *net)
>  	unregister_net_sysctl_table(net->nf.nf_log_dir_header);
>  	if (!net_eq(net, &init_net))
>  		kfree(table);
> +	else
> +		unregister_net_sysctl_table(nf_log_sysctl_fhdr);
>  }
>  #else
>  static int netfilter_log_sysctl_init(struct net *net)
>
Stefan Bader May 23, 2018, 12:53 p.m. UTC | #2
On 27.04.2018 21:11, Joseph Salisbury wrote:
> From: Michal Kubeček <mkubecek@suse.cz>
> 
> BugLink: http://bugs.launchpad.net/bugs/1766573
> 
> Commit 69b34fb996b2 ("netfilter: xt_LOG: add net namespace support for
> xt_LOG") disabled logging packets using the LOG target from non-init
> namespaces. The motivation was to prevent containers from flooding
> kernel log of the host. The plan was to keep it that way until syslog
> namespace implementation allows containers to log in a safe way.
> 
> However, the work on syslog namespace seems to have hit a dead end
> somewhere in 2013 and there are users who want to use xt_LOG in all
> network namespaces. This patch allows to do so by setting
> 
>   /proc/sys/net/netfilter/nf_log_all_netns
> 
> to a nonzero value. This sysctl is only accessible from init_net so that
> one cannot switch the behaviour from inside a container.
> 
> Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> (cherry picked from commit 2851940ffee313e0ff12540a8e11a8c54dea9c65)
> Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>

> ---
>  Documentation/networking/netfilter-sysctl.txt | 10 ++++++++++
>  include/net/netfilter/nf_log.h                |  3 +++
>  net/bridge/netfilter/ebt_log.c                |  2 +-
>  net/ipv4/netfilter/nf_log_arp.c               |  2 +-
>  net/ipv4/netfilter/nf_log_ipv4.c              |  2 +-
>  net/ipv6/netfilter/nf_log_ipv6.c              |  2 +-
>  net/netfilter/nf_log.c                        | 24 ++++++++++++++++++++++++
>  7 files changed, 41 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/networking/netfilter-sysctl.txt
> 
> diff --git a/Documentation/networking/netfilter-sysctl.txt b/Documentation/networking/netfilter-sysctl.txt
> new file mode 100644
> index 0000000..55791e5
> --- /dev/null
> +++ b/Documentation/networking/netfilter-sysctl.txt
> @@ -0,0 +1,10 @@
> +/proc/sys/net/netfilter/* Variables:
> +
> +nf_log_all_netns - BOOLEAN
> +	0 - disabled (default)
> +	not 0 - enabled
> +
> +	By default, only init_net namespace can log packets into kernel log
> +	with LOG target; this aims to prevent containers from flooding host
> +	kernel log. If enabled, this target also works in other network
> +	namespaces. This variable is only accessible from init_net.
> diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
> index 57639fc..8c4b018 100644
> --- a/include/net/netfilter/nf_log.h
> +++ b/include/net/netfilter/nf_log.h
> @@ -49,6 +49,9 @@ struct nf_logger {
>  	struct module		*me;
>  };
>  
> +/* sysctl_nf_log_all_netns - allow LOG target in all network namespaces */
> +extern int sysctl_nf_log_all_netns;
> +
>  /* Function to register/unregister log function. */
>  int nf_log_register(u_int8_t pf, struct nf_logger *logger);
>  void nf_log_unregister(struct nf_logger *logger);
> diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
> index 0ad639a..0a2d0e3 100644
> --- a/net/bridge/netfilter/ebt_log.c
> +++ b/net/bridge/netfilter/ebt_log.c
> @@ -80,7 +80,7 @@ ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
>  	unsigned int bitmask;
>  
>  	/* FIXME: Disabled from containers until syslog ns is supported */
> -	if (!net_eq(net, &init_net))
> +	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
>  		return;
>  
>  	spin_lock_bh(&ebt_log_lock);
> diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c
> index e7ad950..39e1348 100644
> --- a/net/ipv4/netfilter/nf_log_arp.c
> +++ b/net/ipv4/netfilter/nf_log_arp.c
> @@ -87,7 +87,7 @@ static void nf_log_arp_packet(struct net *net, u_int8_t pf,
>  	struct nf_log_buf *m;
>  
>  	/* FIXME: Disabled from containers until syslog ns is supported */
> -	if (!net_eq(net, &init_net))
> +	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
>  		return;
>  
>  	m = nf_log_buf_open();
> diff --git a/net/ipv4/netfilter/nf_log_ipv4.c b/net/ipv4/netfilter/nf_log_ipv4.c
> index 076aadd..2b00831 100644
> --- a/net/ipv4/netfilter/nf_log_ipv4.c
> +++ b/net/ipv4/netfilter/nf_log_ipv4.c
> @@ -319,7 +319,7 @@ static void nf_log_ip_packet(struct net *net, u_int8_t pf,
>  	struct nf_log_buf *m;
>  
>  	/* FIXME: Disabled from containers until syslog ns is supported */
> -	if (!net_eq(net, &init_net))
> +	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
>  		return;
>  
>  	m = nf_log_buf_open();
> diff --git a/net/ipv6/netfilter/nf_log_ipv6.c b/net/ipv6/netfilter/nf_log_ipv6.c
> index 8dd8696..0496048 100644
> --- a/net/ipv6/netfilter/nf_log_ipv6.c
> +++ b/net/ipv6/netfilter/nf_log_ipv6.c
> @@ -351,7 +351,7 @@ static void nf_log_ip6_packet(struct net *net, u_int8_t pf,
>  	struct nf_log_buf *m;
>  
>  	/* FIXME: Disabled from containers until syslog ns is supported */
> -	if (!net_eq(net, &init_net))
> +	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
>  		return;
>  
>  	m = nf_log_buf_open();
> diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
> index 2c89f90..d84e11a 100644
> --- a/net/netfilter/nf_log.c
> +++ b/net/netfilter/nf_log.c
> @@ -16,6 +16,9 @@
>  #define NF_LOG_PREFIXLEN		128
>  #define NFLOGGER_NAME_LEN		64
>  
> +int sysctl_nf_log_all_netns __read_mostly;
> +EXPORT_SYMBOL(sysctl_nf_log_all_netns);
> +
>  static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly;
>  static DEFINE_MUTEX(nf_log_mutex);
>  
> @@ -392,6 +395,18 @@ static const struct file_operations nflog_file_ops = {
>  #ifdef CONFIG_SYSCTL
>  static char nf_log_sysctl_fnames[NFPROTO_NUMPROTO-NFPROTO_UNSPEC][3];
>  static struct ctl_table nf_log_sysctl_table[NFPROTO_NUMPROTO+1];
> +static struct ctl_table_header *nf_log_sysctl_fhdr;
> +
> +static struct ctl_table nf_log_sysctl_ftable[] = {
> +	{
> +		.procname	= "nf_log_all_netns",
> +		.data		= &sysctl_nf_log_all_netns,
> +		.maxlen		= sizeof(sysctl_nf_log_all_netns),
> +		.mode		= 0644,
> +		.proc_handler	= proc_dointvec,
> +	},
> +	{ }
> +};
>  
>  static int nf_log_proc_dostring(struct ctl_table *table, int write,
>  			 void __user *buffer, size_t *lenp, loff_t *ppos)
> @@ -460,6 +475,10 @@ static int netfilter_log_sysctl_init(struct net *net)
>  			nf_log_sysctl_table[i].extra1 =
>  				(void *)(unsigned long) i;
>  		}
> +		nf_log_sysctl_fhdr = register_net_sysctl(net, "net/netfilter",
> +							 nf_log_sysctl_ftable);
> +		if (!nf_log_sysctl_fhdr)
> +			goto err_freg;
>  	}
>  
>  	for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
> @@ -476,6 +495,9 @@ static int netfilter_log_sysctl_init(struct net *net)
>  err_reg:
>  	if (!net_eq(net, &init_net))
>  		kfree(table);
> +	else
> +		unregister_net_sysctl_table(nf_log_sysctl_fhdr);
> +err_freg:
>  err_alloc:
>  	return -ENOMEM;
>  }
> @@ -488,6 +510,8 @@ static void netfilter_log_sysctl_exit(struct net *net)
>  	unregister_net_sysctl_table(net->nf.nf_log_dir_header);
>  	if (!net_eq(net, &init_net))
>  		kfree(table);
> +	else
> +		unregister_net_sysctl_table(nf_log_sysctl_fhdr);
>  }
>  #else
>  static int netfilter_log_sysctl_init(struct net *net)
>
diff mbox series

Patch

diff --git a/Documentation/networking/netfilter-sysctl.txt b/Documentation/networking/netfilter-sysctl.txt
new file mode 100644
index 0000000..55791e5
--- /dev/null
+++ b/Documentation/networking/netfilter-sysctl.txt
@@ -0,0 +1,10 @@ 
+/proc/sys/net/netfilter/* Variables:
+
+nf_log_all_netns - BOOLEAN
+	0 - disabled (default)
+	not 0 - enabled
+
+	By default, only init_net namespace can log packets into kernel log
+	with LOG target; this aims to prevent containers from flooding host
+	kernel log. If enabled, this target also works in other network
+	namespaces. This variable is only accessible from init_net.
diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
index 57639fc..8c4b018 100644
--- a/include/net/netfilter/nf_log.h
+++ b/include/net/netfilter/nf_log.h
@@ -49,6 +49,9 @@  struct nf_logger {
 	struct module		*me;
 };
 
+/* sysctl_nf_log_all_netns - allow LOG target in all network namespaces */
+extern int sysctl_nf_log_all_netns;
+
 /* Function to register/unregister log function. */
 int nf_log_register(u_int8_t pf, struct nf_logger *logger);
 void nf_log_unregister(struct nf_logger *logger);
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 0ad639a..0a2d0e3 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -80,7 +80,7 @@  ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
 	unsigned int bitmask;
 
 	/* FIXME: Disabled from containers until syslog ns is supported */
-	if (!net_eq(net, &init_net))
+	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
 		return;
 
 	spin_lock_bh(&ebt_log_lock);
diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c
index e7ad950..39e1348 100644
--- a/net/ipv4/netfilter/nf_log_arp.c
+++ b/net/ipv4/netfilter/nf_log_arp.c
@@ -87,7 +87,7 @@  static void nf_log_arp_packet(struct net *net, u_int8_t pf,
 	struct nf_log_buf *m;
 
 	/* FIXME: Disabled from containers until syslog ns is supported */
-	if (!net_eq(net, &init_net))
+	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
 		return;
 
 	m = nf_log_buf_open();
diff --git a/net/ipv4/netfilter/nf_log_ipv4.c b/net/ipv4/netfilter/nf_log_ipv4.c
index 076aadd..2b00831 100644
--- a/net/ipv4/netfilter/nf_log_ipv4.c
+++ b/net/ipv4/netfilter/nf_log_ipv4.c
@@ -319,7 +319,7 @@  static void nf_log_ip_packet(struct net *net, u_int8_t pf,
 	struct nf_log_buf *m;
 
 	/* FIXME: Disabled from containers until syslog ns is supported */
-	if (!net_eq(net, &init_net))
+	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
 		return;
 
 	m = nf_log_buf_open();
diff --git a/net/ipv6/netfilter/nf_log_ipv6.c b/net/ipv6/netfilter/nf_log_ipv6.c
index 8dd8696..0496048 100644
--- a/net/ipv6/netfilter/nf_log_ipv6.c
+++ b/net/ipv6/netfilter/nf_log_ipv6.c
@@ -351,7 +351,7 @@  static void nf_log_ip6_packet(struct net *net, u_int8_t pf,
 	struct nf_log_buf *m;
 
 	/* FIXME: Disabled from containers until syslog ns is supported */
-	if (!net_eq(net, &init_net))
+	if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
 		return;
 
 	m = nf_log_buf_open();
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 2c89f90..d84e11a 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -16,6 +16,9 @@ 
 #define NF_LOG_PREFIXLEN		128
 #define NFLOGGER_NAME_LEN		64
 
+int sysctl_nf_log_all_netns __read_mostly;
+EXPORT_SYMBOL(sysctl_nf_log_all_netns);
+
 static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly;
 static DEFINE_MUTEX(nf_log_mutex);
 
@@ -392,6 +395,18 @@  static const struct file_operations nflog_file_ops = {
 #ifdef CONFIG_SYSCTL
 static char nf_log_sysctl_fnames[NFPROTO_NUMPROTO-NFPROTO_UNSPEC][3];
 static struct ctl_table nf_log_sysctl_table[NFPROTO_NUMPROTO+1];
+static struct ctl_table_header *nf_log_sysctl_fhdr;
+
+static struct ctl_table nf_log_sysctl_ftable[] = {
+	{
+		.procname	= "nf_log_all_netns",
+		.data		= &sysctl_nf_log_all_netns,
+		.maxlen		= sizeof(sysctl_nf_log_all_netns),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec,
+	},
+	{ }
+};
 
 static int nf_log_proc_dostring(struct ctl_table *table, int write,
 			 void __user *buffer, size_t *lenp, loff_t *ppos)
@@ -460,6 +475,10 @@  static int netfilter_log_sysctl_init(struct net *net)
 			nf_log_sysctl_table[i].extra1 =
 				(void *)(unsigned long) i;
 		}
+		nf_log_sysctl_fhdr = register_net_sysctl(net, "net/netfilter",
+							 nf_log_sysctl_ftable);
+		if (!nf_log_sysctl_fhdr)
+			goto err_freg;
 	}
 
 	for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
@@ -476,6 +495,9 @@  static int netfilter_log_sysctl_init(struct net *net)
 err_reg:
 	if (!net_eq(net, &init_net))
 		kfree(table);
+	else
+		unregister_net_sysctl_table(nf_log_sysctl_fhdr);
+err_freg:
 err_alloc:
 	return -ENOMEM;
 }
@@ -488,6 +510,8 @@  static void netfilter_log_sysctl_exit(struct net *net)
 	unregister_net_sysctl_table(net->nf.nf_log_dir_header);
 	if (!net_eq(net, &init_net))
 		kfree(table);
+	else
+		unregister_net_sysctl_table(nf_log_sysctl_fhdr);
 }
 #else
 static int netfilter_log_sysctl_init(struct net *net)