removed kernel patches and some minor cleanup to documentation in relation
This commit is contained in:
parent
3bfcdac630
commit
bffed34a47
32 changed files with 2 additions and 5777 deletions
|
@ -28,7 +28,7 @@ ACLOCAL_AMFLAGS = -I config
|
||||||
# extra files to include with distribution tarball
|
# extra files to include with distribution tarball
|
||||||
EXTRA_DIST = bootstrap.sh LICENSE \
|
EXTRA_DIST = bootstrap.sh LICENSE \
|
||||||
README.md ASSIGNMENT_OF_COPYRIGHT.pdf \
|
README.md ASSIGNMENT_OF_COPYRIGHT.pdf \
|
||||||
Changelog kernel \
|
Changelog \
|
||||||
python-prefix.py revision.sh \
|
python-prefix.py revision.sh \
|
||||||
.version .version.date \
|
.version .version.date \
|
||||||
packaging/deb/compat \
|
packaging/deb/compat \
|
||||||
|
@ -51,10 +51,6 @@ MAINTAINERCLEANFILES = \
|
||||||
.version \
|
.version \
|
||||||
.version.date
|
.version.date
|
||||||
|
|
||||||
# don't include svn dirs in source tarball
|
|
||||||
dist-hook:
|
|
||||||
rm -rf `find $(distdir)/kernel -name .svn`
|
|
||||||
|
|
||||||
# build a source RPM
|
# build a source RPM
|
||||||
.PHONY: rpm
|
.PHONY: rpm
|
||||||
rpm: dist
|
rpm: dist
|
||||||
|
|
|
@ -119,36 +119,6 @@ Installing from Packages on Ubuntu
|
||||||
|
|
||||||
First install the Ubuntu |UBUNTUVERSION| operating system.
|
First install the Ubuntu |UBUNTUVERSION| operating system.
|
||||||
|
|
||||||
.. tip::
|
|
||||||
With Debian or Ubuntu 14.04 (trusty) and newer, you can simply install
|
|
||||||
CORE using the following command::
|
|
||||||
|
|
||||||
sudo apt-get install core-network
|
|
||||||
|
|
||||||
Proceed to the "Install Quagga for routing." line below to install Quagga.
|
|
||||||
The other commands shown in this section apply to binary packages
|
|
||||||
downloaded from the CORE website instead of using the Debian/Ubuntu
|
|
||||||
repositories.
|
|
||||||
|
|
||||||
|
|
||||||
.. NOTE::
|
|
||||||
Linux package managers (e.g. `software-center`, `yum`) will take care
|
|
||||||
of installing the dependencies for you when you use the CORE packages.
|
|
||||||
You do not need to manually use these installation lines. You do need
|
|
||||||
to select which Quagga package to use.
|
|
||||||
|
|
||||||
|
|
||||||
* **Optional:** install the prerequisite packages (otherwise skip this
|
|
||||||
step and have the package manager install them for you.)
|
|
||||||
|
|
||||||
.. parsed-literal::
|
|
||||||
|
|
||||||
# make sure the system is up to date; you can also use synaptic or
|
|
||||||
# update-manager instead of apt-get update/dist-upgrade
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get dist-upgrade
|
|
||||||
sudo apt-get install |APTDEPS| |APTDEPS2|
|
|
||||||
|
|
||||||
* Install Quagga for routing. If you plan on working with wireless
|
* Install Quagga for routing. If you plan on working with wireless
|
||||||
networks, we recommend
|
networks, we recommend
|
||||||
installing
|
installing
|
||||||
|
|
|
@ -111,8 +111,7 @@ Linux network namespaces (also known as netns, LXC, or `Linux containers
|
||||||
<http://lxc.sourceforge.net/>`_) is the primary virtualization
|
<http://lxc.sourceforge.net/>`_) is the primary virtualization
|
||||||
technique used by CORE. LXC has been part of the mainline Linux kernel since
|
technique used by CORE. LXC has been part of the mainline Linux kernel since
|
||||||
2.6.24. Recent Linux distributions such as Fedora and Ubuntu have
|
2.6.24. Recent Linux distributions such as Fedora and Ubuntu have
|
||||||
namespaces-enabled kernels out of the box, so the kernel does not need to be
|
namespaces-enabled kernels out of the box.
|
||||||
patched or recompiled.
|
|
||||||
A namespace is created using the ``clone()`` system call. Each namespace has
|
A namespace is created using the ``clone()`` system call. Each namespace has
|
||||||
its own process environment and private network stack. Network namespaces
|
its own process environment and private network stack. Network namespaces
|
||||||
share the same filesystem in CORE.
|
share the same filesystem in CORE.
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
VERSION := 2.6.38
|
|
||||||
TARBALL := /usr/src/linux-source-$(VERSION).tar.bz2
|
|
||||||
|
|
||||||
SUBVERSION := -core
|
|
||||||
REVISION := 1.0
|
|
||||||
|
|
||||||
PATCHDIR := patches
|
|
||||||
PATCHES := $(sort $(wildcard $(PATCHDIR)/*.patch))
|
|
||||||
|
|
||||||
CONFIG := config.core
|
|
||||||
|
|
||||||
DEPDEBS := linux-source kernel-package po-debconf gettext
|
|
||||||
|
|
||||||
CONCURRENCY_LEVEL := 2
|
|
||||||
|
|
||||||
MAINTAINER ?= Tom Goff
|
|
||||||
EMAIL ?= thomas.goff@boeing.com
|
|
||||||
|
|
||||||
MAKEKPKGFLAGS := --initrd --rootcmd fakeroot --us --uc \
|
|
||||||
--append-to-version $(SUBVERSION) --revision $(REVISION)
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
build: debcheck defaultconfig patch
|
|
||||||
export CONCURRENCY_LEVEL="$(CONCURRENCY_LEVEL)" \
|
|
||||||
KPKG_MAINTAINER="$(MAINTAINER)" KPKG_EMAIL="$(EMAIL)"; \
|
|
||||||
cd linux-source-$(VERSION) && \
|
|
||||||
if [ -f ../$(CONFIG) ]; then \
|
|
||||||
cat ../$(CONFIG) >> .config; \
|
|
||||||
fi && \
|
|
||||||
fakeroot make-kpkg $(MAKEKPKGFLAGS) binary-arch
|
|
||||||
|
|
||||||
.PHONY: debcheck
|
|
||||||
debcheck:
|
|
||||||
for d in $(DEPDEBS); do \
|
|
||||||
if ! dpkg-query -s $$d > /dev/null 2>&1; then \
|
|
||||||
echo ERROR: build dependency not installed: $$d >&2; \
|
|
||||||
exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
|
|
||||||
.PHONY: defaultconfig
|
|
||||||
defaultconfig: linux-source-$(VERSION)
|
|
||||||
export KPKG_MAINTAINER="$(MAINTAINER)" KPKG_EMAIL="$(EMAIL)"; \
|
|
||||||
cd linux-source-$(VERSION) && make-kpkg $(MAKEKPKGFLAGS) configure
|
|
||||||
|
|
||||||
.PHONY: patch
|
|
||||||
patch: linux-source-$(VERSION) patch-stamp
|
|
||||||
patch-stamp: $(PATCHES)
|
|
||||||
for p in $^; do \
|
|
||||||
if ! patch -d linux-source-$(VERSION) -p1 < $$p; then \
|
|
||||||
echo ERROR: applying patch failed: $$p >&2; \
|
|
||||||
exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
touch patch-stamp
|
|
||||||
|
|
||||||
linux-source-$(VERSION): $(TARBALL)
|
|
||||||
tar -xjf $^
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -rf linux-source-$(VERSION) patch-stamp
|
|
|
@ -1,9 +0,0 @@
|
||||||
Author: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
|
|
||||||
The Makefile is basically a wrapper around the make-kpkg command that
|
|
||||||
simplifies building kernel packages. Running make will do some basic
|
|
||||||
dependency checks then build architecture appropriate kernel packages that
|
|
||||||
include changes from the patches directory. The nfnetlink patch is what
|
|
||||||
virtualizes the netfilter queue mechanism; the flow-cache patch allows using
|
|
||||||
IPsec between network namespaces; the ifindex patch virtualizes network
|
|
||||||
interface index numbers.
|
|
|
@ -1 +0,0 @@
|
||||||
CONFIG_XFRM_STATISTICS=y
|
|
|
@ -1,31 +0,0 @@
|
||||||
Only use the flow cache for the initial network namespace.
|
|
||||||
|
|
||||||
The flow cache is not per netns and its entries do not include what
|
|
||||||
namespace they are valid for. This causes problems when transformed
|
|
||||||
traffic is sent between namespaces.
|
|
||||||
---
|
|
||||||
net/core/flow.c | 4 ++++
|
|
||||||
1 files changed, 4 insertions(+), 0 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/net/core/flow.c b/net/core/flow.c
|
|
||||||
index 127c8a7..890510f 100644
|
|
||||||
--- a/net/core/flow.c
|
|
||||||
+++ b/net/core/flow.c
|
|
||||||
@@ -24,6 +24,7 @@
|
|
||||||
#include <net/flow.h>
|
|
||||||
#include <asm/atomic.h>
|
|
||||||
#include <linux/security.h>
|
|
||||||
+#include <net/net_namespace.h>
|
|
||||||
|
|
||||||
struct flow_cache_entry {
|
|
||||||
union {
|
|
||||||
@@ -227,6 +228,9 @@ flow_cache_lookup(struct net *net, struct flowi *key, u16 family, u8 dir,
|
|
||||||
if (!fcp->hash_table)
|
|
||||||
goto nocache;
|
|
||||||
|
|
||||||
+ if (!net_eq(net, &init_net))
|
|
||||||
+ goto nocache;
|
|
||||||
+
|
|
||||||
if (fcp->hash_rnd_recalc)
|
|
||||||
flow_new_hash_rnd(fc, fcp);
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
Make network device ifindex sequential per network namespace.
|
|
||||||
|
|
||||||
---
|
|
||||||
include/net/net_namespace.h | 2 ++
|
|
||||||
net/core/dev.c | 13 ++++++-------
|
|
||||||
2 files changed, 8 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index 1bf812b..6ee0db4 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -57,6 +57,8 @@ struct net {
|
|
||||||
struct sock *rtnl; /* rtnetlink socket */
|
|
||||||
struct sock *genl_sock;
|
|
||||||
|
|
||||||
+ int ifindex;
|
|
||||||
+
|
|
||||||
struct list_head dev_base_head;
|
|
||||||
struct hlist_head *dev_name_head;
|
|
||||||
struct hlist_head *dev_index_head;
|
|
||||||
diff --git a/net/core/dev.c b/net/core/dev.c
|
|
||||||
index 6561021..764a190 100644
|
|
||||||
--- a/net/core/dev.c
|
|
||||||
+++ b/net/core/dev.c
|
|
||||||
@@ -4975,12 +4975,11 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
|
|
||||||
*/
|
|
||||||
static int dev_new_index(struct net *net)
|
|
||||||
{
|
|
||||||
- static int ifindex;
|
|
||||||
for (;;) {
|
|
||||||
- if (++ifindex <= 0)
|
|
||||||
- ifindex = 1;
|
|
||||||
- if (!__dev_get_by_index(net, ifindex))
|
|
||||||
- return ifindex;
|
|
||||||
+ if (++net->ifindex <= 0)
|
|
||||||
+ net->ifindex = 1;
|
|
||||||
+ if (!__dev_get_by_index(net, net->ifindex))
|
|
||||||
+ return net->ifindex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -5918,8 +5917,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
|
|
||||||
/* Actually switch the network namespace */
|
|
||||||
dev_net_set(dev, net);
|
|
||||||
|
|
||||||
- /* If there is an ifindex conflict assign a new one */
|
|
||||||
- if (__dev_get_by_index(net, dev->ifindex)) {
|
|
||||||
+ /* Assign a new ifindex */
|
|
||||||
+ {
|
|
||||||
int iflink = (dev->iflink == dev->ifindex);
|
|
||||||
dev->ifindex = dev_new_index(net);
|
|
||||||
if (iflink)
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,62 +0,0 @@
|
||||||
VERSION := 3.0.0
|
|
||||||
TARBALL := /usr/src/linux-source-$(VERSION).tar.bz2
|
|
||||||
|
|
||||||
SUBVERSION := -core
|
|
||||||
REVISION := 1.0
|
|
||||||
|
|
||||||
PATCHDIR := patches
|
|
||||||
PATCHES := $(sort $(wildcard $(PATCHDIR)/*.patch))
|
|
||||||
|
|
||||||
CONFIG := config.core
|
|
||||||
|
|
||||||
DEPDEBS := linux-source kernel-package po-debconf gettext
|
|
||||||
|
|
||||||
CONCURRENCY_LEVEL := 8
|
|
||||||
|
|
||||||
MAINTAINER ?= Tom Goff
|
|
||||||
EMAIL ?= thomas.goff@boeing.com
|
|
||||||
|
|
||||||
MAKEKPKGFLAGS := --initrd --rootcmd fakeroot --us --uc \
|
|
||||||
--append-to-version $(SUBVERSION) --revision $(REVISION)
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
build: debcheck defaultconfig patch
|
|
||||||
export CONCURRENCY_LEVEL="$(CONCURRENCY_LEVEL)" \
|
|
||||||
KPKG_MAINTAINER="$(MAINTAINER)" KPKG_EMAIL="$(EMAIL)"; \
|
|
||||||
cd linux-source-$(VERSION) && \
|
|
||||||
if [ -f ../$(CONFIG) ]; then \
|
|
||||||
cat ../$(CONFIG) >> .config; \
|
|
||||||
fi && \
|
|
||||||
fakeroot make-kpkg $(MAKEKPKGFLAGS) binary-arch
|
|
||||||
|
|
||||||
.PHONY: debcheck
|
|
||||||
debcheck:
|
|
||||||
for d in $(DEPDEBS); do \
|
|
||||||
if ! dpkg-query -s $$d > /dev/null 2>&1; then \
|
|
||||||
echo ERROR: build dependency not installed: $$d >&2; \
|
|
||||||
exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
|
|
||||||
.PHONY: defaultconfig
|
|
||||||
defaultconfig: linux-source-$(VERSION)
|
|
||||||
export KPKG_MAINTAINER="$(MAINTAINER)" KPKG_EMAIL="$(EMAIL)"; \
|
|
||||||
cd linux-source-$(VERSION) && make-kpkg $(MAKEKPKGFLAGS) configure
|
|
||||||
|
|
||||||
.PHONY: patch
|
|
||||||
patch: linux-source-$(VERSION) patch-stamp
|
|
||||||
patch-stamp: $(PATCHES)
|
|
||||||
for p in $^; do \
|
|
||||||
if ! patch -d linux-source-$(VERSION) -p1 < $$p; then \
|
|
||||||
echo ERROR: applying patch failed: $$p >&2; \
|
|
||||||
exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
touch patch-stamp
|
|
||||||
|
|
||||||
linux-source-$(VERSION): $(TARBALL)
|
|
||||||
tar -xjf $^
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -rf linux-source-$(VERSION) patch-stamp
|
|
|
@ -1,9 +0,0 @@
|
||||||
Author: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
|
|
||||||
The Makefile is basically a wrapper around the make-kpkg command that
|
|
||||||
simplifies building kernel packages. Running make will do some basic
|
|
||||||
dependency checks then build architecture appropriate kernel packages that
|
|
||||||
include changes from the patches directory. The nfnetlink patch is what
|
|
||||||
virtualizes the netfilter queue mechanism; the flow-cache patch allows using
|
|
||||||
IPsec between network namespaces; the ifindex patch virtualizes network
|
|
||||||
interface index numbers.
|
|
|
@ -1 +0,0 @@
|
||||||
CONFIG_XFRM_STATISTICS=y
|
|
|
@ -1,49 +0,0 @@
|
||||||
commit 0542b69e2c57fc9668ce6a03155bea6e1f557901
|
|
||||||
Author: dpward <david.ward@ll.mit.edu>
|
|
||||||
Date: Wed Aug 31 06:05:27 2011 +0000
|
|
||||||
|
|
||||||
net: Make flow cache namespace-aware
|
|
||||||
|
|
||||||
flow_cache_lookup will return a cached object (or null pointer) that the
|
|
||||||
resolver (i.e. xfrm_policy_lookup) previously found for another namespace
|
|
||||||
using the same key/family/dir. Instead, make the namespace part of what
|
|
||||||
identifies entries in the cache.
|
|
||||||
|
|
||||||
As before, flow_entry_valid will return 0 for entries where the namespace
|
|
||||||
has been deleted, and they will be removed from the cache the next time
|
|
||||||
flow_cache_gc_task is run.
|
|
||||||
|
|
||||||
Reported-by: Andrew Dickinson <whydna@whydna.net>
|
|
||||||
Signed-off-by: David Ward <david.ward@ll.mit.edu>
|
|
||||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
||||||
|
|
||||||
diff --git a/net/core/flow.c b/net/core/flow.c
|
|
||||||
index bf32c33..47b6d26 100644
|
|
||||||
--- a/net/core/flow.c
|
|
||||||
+++ b/net/core/flow.c
|
|
||||||
@@ -30,6 +30,7 @@ struct flow_cache_entry {
|
|
||||||
struct hlist_node hlist;
|
|
||||||
struct list_head gc_list;
|
|
||||||
} u;
|
|
||||||
+ struct net *net;
|
|
||||||
u16 family;
|
|
||||||
u8 dir;
|
|
||||||
u32 genid;
|
|
||||||
@@ -232,7 +233,8 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir,
|
|
||||||
|
|
||||||
hash = flow_hash_code(fc, fcp, key);
|
|
||||||
hlist_for_each_entry(tfle, entry, &fcp->hash_table[hash], u.hlist) {
|
|
||||||
- if (tfle->family == family &&
|
|
||||||
+ if (tfle->net == net &&
|
|
||||||
+ tfle->family == family &&
|
|
||||||
tfle->dir == dir &&
|
|
||||||
flow_key_compare(key, &tfle->key) == 0) {
|
|
||||||
fle = tfle;
|
|
||||||
@@ -246,6 +248,7 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir,
|
|
||||||
|
|
||||||
fle = kmem_cache_alloc(flow_cachep, GFP_ATOMIC);
|
|
||||||
if (fle) {
|
|
||||||
+ fle->net = net;
|
|
||||||
fle->family = family;
|
|
||||||
fle->dir = dir;
|
|
||||||
memcpy(&fle->key, key, sizeof(*key));
|
|
|
@ -1,51 +0,0 @@
|
||||||
commit 7da7dfcb787d77929c15d5b7127c816ee16f1ede
|
|
||||||
Author: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Fri Dec 16 17:39:00 2011 -0800
|
|
||||||
|
|
||||||
Make network device ifindex sequential per network namespace.
|
|
||||||
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index 3bb6fa0..2fd53da 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -62,6 +62,8 @@ struct net {
|
|
||||||
struct sock *rtnl; /* rtnetlink socket */
|
|
||||||
struct sock *genl_sock;
|
|
||||||
|
|
||||||
+ int ifindex;
|
|
||||||
+
|
|
||||||
struct list_head dev_base_head;
|
|
||||||
struct hlist_head *dev_name_head;
|
|
||||||
struct hlist_head *dev_index_head;
|
|
||||||
diff --git a/net/core/dev.c b/net/core/dev.c
|
|
||||||
index 6ba50a1..ba95aa5 100644
|
|
||||||
--- a/net/core/dev.c
|
|
||||||
+++ b/net/core/dev.c
|
|
||||||
@@ -5260,12 +5260,11 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
|
|
||||||
*/
|
|
||||||
static int dev_new_index(struct net *net)
|
|
||||||
{
|
|
||||||
- static int ifindex;
|
|
||||||
for (;;) {
|
|
||||||
- if (++ifindex <= 0)
|
|
||||||
- ifindex = 1;
|
|
||||||
- if (!__dev_get_by_index(net, ifindex))
|
|
||||||
- return ifindex;
|
|
||||||
+ if (++net->ifindex <= 0)
|
|
||||||
+ net->ifindex = 1;
|
|
||||||
+ if (!__dev_get_by_index(net, net->ifindex))
|
|
||||||
+ return net->ifindex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -6277,8 +6276,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
|
|
||||||
/* Actually switch the network namespace */
|
|
||||||
dev_net_set(dev, net);
|
|
||||||
|
|
||||||
- /* If there is an ifindex conflict assign a new one */
|
|
||||||
- if (__dev_get_by_index(net, dev->ifindex)) {
|
|
||||||
+ /* Assign a new ifindex */
|
|
||||||
+ {
|
|
||||||
int iflink = (dev->iflink == dev->ifindex);
|
|
||||||
dev->ifindex = dev_new_index(net);
|
|
||||||
if (iflink)
|
|
|
@ -1,351 +0,0 @@
|
||||||
From 4b819adab7892f61a96bab1e36e5d9a74018432b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Tue, 3 Jan 2012 14:39:04 -0800
|
|
||||||
Subject: [PATCH 1/2] netfilter: Make the /proc/net/netfilter directory per
|
|
||||||
netns.
|
|
||||||
|
|
||||||
This allows subsystems to create per-netns entries.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
include/linux/netfilter.h | 5 ----
|
|
||||||
include/net/net_namespace.h | 3 ++
|
|
||||||
net/netfilter/core.c | 35 +++++++++++++++++++++++-------
|
|
||||||
net/netfilter/nf_log.c | 33 +++++++++++++++++++++++++---
|
|
||||||
net/netfilter/nf_queue.c | 31 +++++++++++++++++++++++---
|
|
||||||
net/netfilter/nfnetlink_log.c | 44 ++++++++++++++++++++++++++-----------
|
|
||||||
net/netfilter/nfnetlink_queue.c | 45 ++++++++++++++++++++++++++------------
|
|
||||||
7 files changed, 148 insertions(+), 48 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
|
|
||||||
index 857f502..b4e02fb 100644
|
|
||||||
--- a/include/linux/netfilter.h
|
|
||||||
+++ b/include/linux/netfilter.h
|
|
||||||
@@ -340,11 +340,6 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-#include <linux/proc_fs.h>
|
|
||||||
-extern struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
#else /* !CONFIG_NETFILTER */
|
|
||||||
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
|
|
||||||
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index 3bb6fa0..cf126ef 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -84,6 +84,9 @@ struct net {
|
|
||||||
struct netns_dccp dccp;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NETFILTER
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
+#endif
|
|
||||||
struct netns_xt xt;
|
|
||||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
|
||||||
struct netns_ct ct;
|
|
||||||
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
|
|
||||||
index afca6c7..9d9b103 100644
|
|
||||||
--- a/net/netfilter/core.c
|
|
||||||
+++ b/net/netfilter/core.c
|
|
||||||
@@ -255,25 +255,44 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct)
|
|
||||||
EXPORT_SYMBOL(nf_conntrack_destroy);
|
|
||||||
#endif /* CONFIG_NF_CONNTRACK */
|
|
||||||
|
|
||||||
+static int __net_init netfilter_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
-struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
-EXPORT_SYMBOL(proc_net_netfilter);
|
|
||||||
+ net->proc_net_netfilter = proc_net_mkdir(net, "netfilter",
|
|
||||||
+ net->proc_net);
|
|
||||||
+ if (!net->proc_net_netfilter) {
|
|
||||||
+ pr_err("%s: cannot create netfilter proc entry\n", __func__);
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+ }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit netfilter_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ proc_net_remove(net, "netfilter");
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_net_ops = {
|
|
||||||
+ .init = netfilter_net_init,
|
|
||||||
+ .exit = netfilter_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
void __init netfilter_init(void)
|
|
||||||
{
|
|
||||||
int i, h;
|
|
||||||
+
|
|
||||||
+ if (register_pernet_subsys(&netfilter_net_ops))
|
|
||||||
+ panic("%s: failed to register per netns operations", __func__);
|
|
||||||
+
|
|
||||||
for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) {
|
|
||||||
for (h = 0; h < NF_MAX_HOOKS; h++)
|
|
||||||
INIT_LIST_HEAD(&nf_hooks[i][h]);
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- proc_net_netfilter = proc_mkdir("netfilter", init_net.proc_net);
|
|
||||||
- if (!proc_net_netfilter)
|
|
||||||
- panic("cannot create netfilter proc entry");
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
if (netfilter_queue_init() < 0)
|
|
||||||
panic("cannot initialize nf_queue");
|
|
||||||
if (netfilter_log_init() < 0)
|
|
||||||
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
|
|
||||||
index ce0c406..ccc15d6 100644
|
|
||||||
--- a/net/netfilter/nf_log.c
|
|
||||||
+++ b/net/netfilter/nf_log.c
|
|
||||||
@@ -297,14 +297,39 @@ static __init int netfilter_log_sysctl_init(void)
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_SYSCTL */
|
|
||||||
|
|
||||||
-int __init netfilter_log_init(void)
|
|
||||||
+static int __net_init netfilter_log_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
- int i, r;
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nf_log", S_IRUGO,
|
|
||||||
- proc_net_netfilter, &nflog_file_ops))
|
|
||||||
- return -1;
|
|
||||||
+ net->proc_net_netfilter, &nflog_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit netfilter_log_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nf_log", net->proc_net_netfilter);
|
|
||||||
#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_log_net_ops = {
|
|
||||||
+ .init = netfilter_log_net_init,
|
|
||||||
+ .exit = netfilter_log_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+int __init netfilter_log_init(void)
|
|
||||||
+{
|
|
||||||
+ int i, r;
|
|
||||||
+
|
|
||||||
+ r = register_pernet_subsys(&netfilter_log_net_ops);
|
|
||||||
+ if (r) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return r;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Errors will trigger panic, unroll on error is unnecessary. */
|
|
||||||
r = netfilter_log_sysctl_init();
|
|
||||||
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
|
|
||||||
index 99ffd28..ecb84a3 100644
|
|
||||||
--- a/net/netfilter/nf_queue.c
|
|
||||||
+++ b/net/netfilter/nf_queue.c
|
|
||||||
@@ -383,14 +383,37 @@ static const struct file_operations nfqueue_file_ops = {
|
|
||||||
};
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
-
|
|
||||||
-int __init netfilter_queue_init(void)
|
|
||||||
+static int __net_init netfilter_queue_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nf_queue", S_IRUGO,
|
|
||||||
- proc_net_netfilter, &nfqueue_file_ops))
|
|
||||||
- return -1;
|
|
||||||
+ net->proc_net_netfilter, &nfqueue_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
#endif
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void __net_exit netfilter_queue_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nf_queue", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_queue_net_ops = {
|
|
||||||
+ .init = netfilter_queue_net_init,
|
|
||||||
+ .exit = netfilter_queue_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+int __init netfilter_queue_init(void)
|
|
||||||
+{
|
|
||||||
+ int err;
|
|
||||||
+
|
|
||||||
+ err = register_pernet_subsys(&netfilter_queue_net_ops);
|
|
||||||
+ if (err)
|
|
||||||
+ pr_err("%s: cannot initialize per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+
|
|
||||||
+ return err;
|
|
||||||
+}
|
|
||||||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
|
|
||||||
index 66b2c54..e4c3c1e 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_log.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_log.c
|
|
||||||
@@ -950,9 +950,39 @@ static const struct file_operations nful_file_ops = {
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
+static int __net_init nfnetlink_log_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ if (!proc_create("nfnetlink_log", 0440,
|
|
||||||
+ net->proc_net_netfilter, &nful_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit nfnetlink_log_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nfnetlink_log", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations nfnetlink_log_net_ops = {
|
|
||||||
+ .init = nfnetlink_log_net_init,
|
|
||||||
+ .exit = nfnetlink_log_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __init nfnetlink_log_init(void)
|
|
||||||
{
|
|
||||||
- int i, status = -ENOMEM;
|
|
||||||
+ int i, status;
|
|
||||||
+
|
|
||||||
+ status = register_pernet_subsys(&nfnetlink_log_net_ops);
|
|
||||||
+ if (status) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return status;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
@@ -975,17 +1005,8 @@ static int __init nfnetlink_log_init(void)
|
|
||||||
goto cleanup_subsys;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- if (!proc_create("nfnetlink_log", 0440,
|
|
||||||
- proc_net_netfilter, &nful_file_ops))
|
|
||||||
- goto cleanup_logger;
|
|
||||||
-#endif
|
|
||||||
return status;
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-cleanup_logger:
|
|
||||||
- nf_log_unregister(&nfulnl_logger);
|
|
||||||
-#endif
|
|
||||||
cleanup_subsys:
|
|
||||||
nfnetlink_subsys_unregister(&nfulnl_subsys);
|
|
||||||
cleanup_netlink_notifier:
|
|
||||||
@@ -996,9 +1017,6 @@ cleanup_netlink_notifier:
|
|
||||||
static void __exit nfnetlink_log_fini(void)
|
|
||||||
{
|
|
||||||
nf_log_unregister(&nfulnl_logger);
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- remove_proc_entry("nfnetlink_log", proc_net_netfilter);
|
|
||||||
-#endif
|
|
||||||
nfnetlink_subsys_unregister(&nfulnl_subsys);
|
|
||||||
netlink_unregister_notifier(&nfulnl_rtnl_notifier);
|
|
||||||
}
|
|
||||||
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
|
|
||||||
index a80b0cb..b615da5 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_queue.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_queue.c
|
|
||||||
@@ -974,9 +974,39 @@ static const struct file_operations nfqnl_file_ops = {
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
+static int __net_init nfnetlink_queue_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
+ net->proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit nfnetlink_queue_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nfnetlink_queue", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations nfnetlink_queue_net_ops = {
|
|
||||||
+ .init = nfnetlink_queue_net_init,
|
|
||||||
+ .exit = nfnetlink_queue_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __init nfnetlink_queue_init(void)
|
|
||||||
{
|
|
||||||
- int i, status = -ENOMEM;
|
|
||||||
+ int i, status;
|
|
||||||
+
|
|
||||||
+ status = register_pernet_subsys(&nfnetlink_queue_net_ops);
|
|
||||||
+ if (status) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return status;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
@@ -988,19 +1018,9 @@ static int __init nfnetlink_queue_init(void)
|
|
||||||
goto cleanup_netlink_notifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
- proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
- goto cleanup_subsys;
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
register_netdevice_notifier(&nfqnl_dev_notifier);
|
|
||||||
return status;
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-cleanup_subsys:
|
|
||||||
- nfnetlink_subsys_unregister(&nfqnl_subsys);
|
|
||||||
-#endif
|
|
||||||
cleanup_netlink_notifier:
|
|
||||||
netlink_unregister_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
return status;
|
|
||||||
@@ -1010,9 +1030,6 @@ static void __exit nfnetlink_queue_fini(void)
|
|
||||||
{
|
|
||||||
nf_unregister_queue_handlers(&nfqh);
|
|
||||||
unregister_netdevice_notifier(&nfqnl_dev_notifier);
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- remove_proc_entry("nfnetlink_queue", proc_net_netfilter);
|
|
||||||
-#endif
|
|
||||||
nfnetlink_subsys_unregister(&nfqnl_subsys);
|
|
||||||
netlink_unregister_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
|
@ -1,516 +0,0 @@
|
||||||
From dd504f32d24e9f239d429204c43a5c500c9853c6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Tue, 3 Jan 2012 15:52:32 -0800
|
|
||||||
Subject: [PATCH 2/2] netfilter: nfnetlink_queue: Add netns support.
|
|
||||||
|
|
||||||
Make nfnetlink_queue network namespace aware including a per-netns
|
|
||||||
/proc/net/netfilter/nfnetlink_queue file.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
include/net/net_namespace.h | 6 ++
|
|
||||||
include/net/netfilter/nf_queue.h | 3 +-
|
|
||||||
include/net/netns/nfqnl.h | 14 ++++
|
|
||||||
net/ipv4/netfilter/ip_queue.c | 6 ++-
|
|
||||||
net/ipv6/netfilter/ip6_queue.c | 6 ++-
|
|
||||||
net/netfilter/nf_queue.c | 12 +++-
|
|
||||||
net/netfilter/nfnetlink_queue.c | 138 +++++++++++++++++++-------------------
|
|
||||||
7 files changed, 112 insertions(+), 73 deletions(-)
|
|
||||||
create mode 100644 include/net/netns/nfqnl.h
|
|
||||||
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index cf126ef..4b6f04a 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -21,6 +21,9 @@
|
|
||||||
#include <net/netns/conntrack.h>
|
|
||||||
#endif
|
|
||||||
#include <net/netns/xfrm.h>
|
|
||||||
+#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
|
||||||
+#include <net/netns/nfqnl.h>
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
struct proc_dir_entry;
|
|
||||||
struct net_device;
|
|
||||||
@@ -93,6 +96,9 @@ struct net {
|
|
||||||
#endif
|
|
||||||
struct sock *nfnl;
|
|
||||||
struct sock *nfnl_stash;
|
|
||||||
+#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
|
||||||
+ struct netns_nfqnl nfqnl;
|
|
||||||
+#endif
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_WEXT_CORE
|
|
||||||
struct sk_buff_head wext_nlevents;
|
|
||||||
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
|
|
||||||
index 252fd10..3e5bde8 100644
|
|
||||||
--- a/include/net/netfilter/nf_queue.h
|
|
||||||
+++ b/include/net/netfilter/nf_queue.h
|
|
||||||
@@ -19,7 +19,8 @@ struct nf_queue_entry {
|
|
||||||
|
|
||||||
/* Packet queuing */
|
|
||||||
struct nf_queue_handler {
|
|
||||||
- int (*outfn)(struct nf_queue_entry *entry,
|
|
||||||
+ int (*outfn)(struct net *net,
|
|
||||||
+ struct nf_queue_entry *entry,
|
|
||||||
unsigned int queuenum);
|
|
||||||
char *name;
|
|
||||||
};
|
|
||||||
diff --git a/include/net/netns/nfqnl.h b/include/net/netns/nfqnl.h
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..0fe7fbe
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/include/net/netns/nfqnl.h
|
|
||||||
@@ -0,0 +1,14 @@
|
|
||||||
+#ifndef __NETNS_NFQNL_H
|
|
||||||
+#define __NETNS_NFQNL_H
|
|
||||||
+
|
|
||||||
+#include <linux/spinlock.h>
|
|
||||||
+#include <linux/list.h>
|
|
||||||
+
|
|
||||||
+#define NFQNL_INSTANCE_BUCKETS 16
|
|
||||||
+
|
|
||||||
+struct netns_nfqnl {
|
|
||||||
+ spinlock_t instances_lock;
|
|
||||||
+ struct hlist_head instance_table[NFQNL_INSTANCE_BUCKETS];
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+#endif /* __NETNS_NFQNL_H */
|
|
||||||
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
|
|
||||||
index e59aabd..f3c43e5 100644
|
|
||||||
--- a/net/ipv4/netfilter/ip_queue.c
|
|
||||||
+++ b/net/ipv4/netfilter/ip_queue.c
|
|
||||||
@@ -225,7 +225,8 @@ nlmsg_failure:
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
+ipq_enqueue_packet(struct net *net, struct nf_queue_entry *entry,
|
|
||||||
+ unsigned int queuenum)
|
|
||||||
{
|
|
||||||
int status = -EINVAL;
|
|
||||||
struct sk_buff *nskb;
|
|
||||||
@@ -239,6 +240,9 @@ ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
|
|
||||||
spin_lock_bh(&queue_lock);
|
|
||||||
|
|
||||||
+ if (!net_eq(net, &init_net))
|
|
||||||
+ goto err_out_free_nskb;
|
|
||||||
+
|
|
||||||
if (!peer_pid)
|
|
||||||
goto err_out_free_nskb;
|
|
||||||
|
|
||||||
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
|
|
||||||
index e63c397..322c511 100644
|
|
||||||
--- a/net/ipv6/netfilter/ip6_queue.c
|
|
||||||
+++ b/net/ipv6/netfilter/ip6_queue.c
|
|
||||||
@@ -225,7 +225,8 @@ nlmsg_failure:
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
+ipq_enqueue_packet(struct net *net, struct nf_queue_entry *entry,
|
|
||||||
+ unsigned int queuenum)
|
|
||||||
{
|
|
||||||
int status = -EINVAL;
|
|
||||||
struct sk_buff *nskb;
|
|
||||||
@@ -239,6 +240,9 @@ ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
|
|
||||||
spin_lock_bh(&queue_lock);
|
|
||||||
|
|
||||||
+ if (!net_eq(net, &init_net))
|
|
||||||
+ goto err_out_free_nskb;
|
|
||||||
+
|
|
||||||
if (!peer_pid)
|
|
||||||
goto err_out_free_nskb;
|
|
||||||
|
|
||||||
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
|
|
||||||
index ecb84a3..9490bd5 100644
|
|
||||||
--- a/net/netfilter/nf_queue.c
|
|
||||||
+++ b/net/netfilter/nf_queue.c
|
|
||||||
@@ -133,6 +133,16 @@ static int __nf_queue(struct sk_buff *skb,
|
|
||||||
#endif
|
|
||||||
const struct nf_afinfo *afinfo;
|
|
||||||
const struct nf_queue_handler *qh;
|
|
||||||
+ struct net *net;
|
|
||||||
+
|
|
||||||
+ if (indev)
|
|
||||||
+ net = dev_net(indev);
|
|
||||||
+ else if (skb->sk)
|
|
||||||
+ net = sock_net(skb->sk);
|
|
||||||
+ else if (outdev)
|
|
||||||
+ net = dev_net(outdev);
|
|
||||||
+ else
|
|
||||||
+ return status;
|
|
||||||
|
|
||||||
/* QUEUE == DROP if no one is waiting, to be safe. */
|
|
||||||
rcu_read_lock();
|
|
||||||
@@ -185,7 +195,7 @@ static int __nf_queue(struct sk_buff *skb,
|
|
||||||
#endif
|
|
||||||
skb_dst_force(skb);
|
|
||||||
afinfo->saveroute(skb, entry);
|
|
||||||
- status = qh->outfn(entry, queuenum);
|
|
||||||
+ status = qh->outfn(net, entry, queuenum);
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
|
|
||||||
index b615da5..48ea6f4 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_queue.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_queue.c
|
|
||||||
@@ -64,24 +64,19 @@ struct nfqnl_instance {
|
|
||||||
|
|
||||||
typedef int (*nfqnl_cmpfn)(struct nf_queue_entry *, unsigned long);
|
|
||||||
|
|
||||||
-static DEFINE_SPINLOCK(instances_lock);
|
|
||||||
-
|
|
||||||
-#define INSTANCE_BUCKETS 16
|
|
||||||
-static struct hlist_head instance_table[INSTANCE_BUCKETS] __read_mostly;
|
|
||||||
-
|
|
||||||
static inline u_int8_t instance_hashfn(u_int16_t queue_num)
|
|
||||||
{
|
|
||||||
- return ((queue_num >> 8) | queue_num) % INSTANCE_BUCKETS;
|
|
||||||
+ return ((queue_num >> 8) | queue_num) % NFQNL_INSTANCE_BUCKETS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nfqnl_instance *
|
|
||||||
-instance_lookup(u_int16_t queue_num)
|
|
||||||
+instance_lookup(struct net *net, u_int16_t queue_num)
|
|
||||||
{
|
|
||||||
struct hlist_head *head;
|
|
||||||
struct hlist_node *pos;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
|
|
||||||
- head = &instance_table[instance_hashfn(queue_num)];
|
|
||||||
+ head = &net->nfqnl.instance_table[instance_hashfn(queue_num)];
|
|
||||||
hlist_for_each_entry_rcu(inst, pos, head, hlist) {
|
|
||||||
if (inst->queue_num == queue_num)
|
|
||||||
return inst;
|
|
||||||
@@ -90,14 +85,14 @@ instance_lookup(u_int16_t queue_num)
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nfqnl_instance *
|
|
||||||
-instance_create(u_int16_t queue_num, int pid)
|
|
||||||
+instance_create(struct net *net, u_int16_t queue_num, int pid)
|
|
||||||
{
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
unsigned int h;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- if (instance_lookup(queue_num)) {
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
+ if (instance_lookup(net, queue_num)) {
|
|
||||||
err = -EEXIST;
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
@@ -122,16 +117,16 @@ instance_create(u_int16_t queue_num, int pid)
|
|
||||||
}
|
|
||||||
|
|
||||||
h = instance_hashfn(queue_num);
|
|
||||||
- hlist_add_head_rcu(&inst->hlist, &instance_table[h]);
|
|
||||||
+ hlist_add_head_rcu(&inst->hlist, &net->nfqnl.instance_table[h]);
|
|
||||||
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
|
|
||||||
return inst;
|
|
||||||
|
|
||||||
out_free:
|
|
||||||
kfree(inst);
|
|
||||||
out_unlock:
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
return ERR_PTR(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -157,11 +152,11 @@ __instance_destroy(struct nfqnl_instance *inst)
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
-instance_destroy(struct nfqnl_instance *inst)
|
|
||||||
+instance_destroy(struct net *net, struct nfqnl_instance *inst)
|
|
||||||
{
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
__instance_destroy(inst);
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
@@ -390,7 +385,8 @@ nla_put_failure:
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
+nfqnl_enqueue_packet(struct net *net, struct nf_queue_entry *entry,
|
|
||||||
+ unsigned int queuenum)
|
|
||||||
{
|
|
||||||
struct sk_buff *nskb;
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
@@ -398,7 +394,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
__be32 *packet_id_ptr;
|
|
||||||
|
|
||||||
/* rcu_read_lock()ed by nf_hook_slow() */
|
|
||||||
- queue = instance_lookup(queuenum);
|
|
||||||
+ queue = instance_lookup(net, queuenum);
|
|
||||||
if (!queue) {
|
|
||||||
err = -ESRCH;
|
|
||||||
goto err_out;
|
|
||||||
@@ -432,7 +428,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
*packet_id_ptr = htonl(entry->id);
|
|
||||||
|
|
||||||
/* nfnetlink_unicast will either free the nskb or add it to a socket */
|
|
||||||
- err = nfnetlink_unicast(nskb, &init_net, queue->peer_pid, MSG_DONTWAIT);
|
|
||||||
+ err = nfnetlink_unicast(nskb, net, queue->peer_pid, MSG_DONTWAIT);
|
|
||||||
if (err < 0) {
|
|
||||||
queue->queue_user_dropped++;
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -541,16 +537,16 @@ dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
|
|
||||||
/* drop all packets with either indev or outdev == ifindex from all queue
|
|
||||||
* instances */
|
|
||||||
static void
|
|
||||||
-nfqnl_dev_drop(int ifindex)
|
|
||||||
+nfqnl_dev_drop(struct net *net, int ifindex)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++) {
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++) {
|
|
||||||
struct hlist_node *tmp;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
- struct hlist_head *head = &instance_table[i];
|
|
||||||
+ struct hlist_head *head = &net->nfqnl.instance_table[i];
|
|
||||||
|
|
||||||
hlist_for_each_entry_rcu(inst, tmp, head, hlist)
|
|
||||||
nfqnl_flush(inst, dev_cmp, ifindex);
|
|
||||||
@@ -567,12 +563,9 @@ nfqnl_rcv_dev_event(struct notifier_block *this,
|
|
||||||
{
|
|
||||||
struct net_device *dev = ptr;
|
|
||||||
|
|
||||||
- if (!net_eq(dev_net(dev), &init_net))
|
|
||||||
- return NOTIFY_DONE;
|
|
||||||
-
|
|
||||||
/* Drop any packets associated with the downed device */
|
|
||||||
if (event == NETDEV_DOWN)
|
|
||||||
- nfqnl_dev_drop(dev->ifindex);
|
|
||||||
+ nfqnl_dev_drop(dev_net(dev), dev->ifindex);
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -590,19 +583,19 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* destroy all instances for this pid */
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++) {
|
|
||||||
+ spin_lock(&n->net->nfqnl.instances_lock);
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++) {
|
|
||||||
struct hlist_node *tmp, *t2;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
- struct hlist_head *head = &instance_table[i];
|
|
||||||
+ struct hlist_head *head =
|
|
||||||
+ &n->net->nfqnl.instance_table[i];
|
|
||||||
|
|
||||||
hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
|
|
||||||
- if ((n->net == &init_net) &&
|
|
||||||
- (n->pid == inst->peer_pid))
|
|
||||||
+ if (n->pid == inst->peer_pid)
|
|
||||||
__instance_destroy(inst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&n->net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
@@ -715,9 +710,10 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
unsigned int verdict;
|
|
||||||
struct nf_queue_entry *entry;
|
|
||||||
int err;
|
|
||||||
+ struct net *net = sock_net(ctnl);
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (!queue) {
|
|
||||||
err = -ENODEV;
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -774,6 +770,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
struct nfqnl_msg_config_cmd *cmd = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
+ struct net *net = sock_net(ctnl);
|
|
||||||
|
|
||||||
if (nfqa[NFQA_CFG_CMD]) {
|
|
||||||
cmd = nla_data(nfqa[NFQA_CFG_CMD]);
|
|
||||||
@@ -790,7 +787,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
}
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (queue && queue->peer_pid != NETLINK_CB(skb).pid) {
|
|
||||||
ret = -EPERM;
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -803,7 +800,8 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
ret = -EBUSY;
|
|
||||||
goto err_out_unlock;
|
|
||||||
}
|
|
||||||
- queue = instance_create(queue_num, NETLINK_CB(skb).pid);
|
|
||||||
+ queue = instance_create(net, queue_num,
|
|
||||||
+ NETLINK_CB(skb).pid);
|
|
||||||
if (IS_ERR(queue)) {
|
|
||||||
ret = PTR_ERR(queue);
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -814,7 +812,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto err_out_unlock;
|
|
||||||
}
|
|
||||||
- instance_destroy(queue);
|
|
||||||
+ instance_destroy(net, queue);
|
|
||||||
break;
|
|
||||||
case NFQNL_CFG_CMD_PF_BIND:
|
|
||||||
case NFQNL_CFG_CMD_PF_UNBIND:
|
|
||||||
@@ -878,65 +876,64 @@ static const struct nfnetlink_subsystem nfqnl_subsys = {
|
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
struct iter_state {
|
|
||||||
+ struct seq_net_private p;
|
|
||||||
unsigned int bucket;
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct hlist_node *get_first(struct seq_file *seq)
|
|
||||||
+static struct hlist_node *get_first(struct net *net, struct iter_state *st)
|
|
||||||
{
|
|
||||||
- struct iter_state *st = seq->private;
|
|
||||||
-
|
|
||||||
if (!st)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) {
|
|
||||||
- if (!hlist_empty(&instance_table[st->bucket]))
|
|
||||||
- return instance_table[st->bucket].first;
|
|
||||||
+ for (st->bucket = 0; st->bucket < NFQNL_INSTANCE_BUCKETS; st->bucket++) {
|
|
||||||
+ if (!hlist_empty(&net->nfqnl.instance_table[st->bucket]))
|
|
||||||
+ return net->nfqnl.instance_table[st->bucket].first;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct hlist_node *get_next(struct seq_file *seq, struct hlist_node *h)
|
|
||||||
+static struct hlist_node *get_next(struct net *net, struct iter_state *st,
|
|
||||||
+ struct hlist_node *h)
|
|
||||||
{
|
|
||||||
- struct iter_state *st = seq->private;
|
|
||||||
-
|
|
||||||
h = h->next;
|
|
||||||
while (!h) {
|
|
||||||
- if (++st->bucket >= INSTANCE_BUCKETS)
|
|
||||||
+ if (++st->bucket >= NFQNL_INSTANCE_BUCKETS)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- h = instance_table[st->bucket].first;
|
|
||||||
+ h = net->nfqnl.instance_table[st->bucket].first;
|
|
||||||
}
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct hlist_node *get_idx(struct seq_file *seq, loff_t pos)
|
|
||||||
+static struct hlist_node *get_idx(struct net *net, struct iter_state *st,
|
|
||||||
+ loff_t pos)
|
|
||||||
{
|
|
||||||
struct hlist_node *head;
|
|
||||||
- head = get_first(seq);
|
|
||||||
+ head = get_first(net, st);
|
|
||||||
|
|
||||||
if (head)
|
|
||||||
- while (pos && (head = get_next(seq, head)))
|
|
||||||
+ while (pos && (head = get_next(net, st, head)))
|
|
||||||
pos--;
|
|
||||||
return pos ? NULL : head;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *seq_start(struct seq_file *seq, loff_t *pos)
|
|
||||||
- __acquires(instances_lock)
|
|
||||||
{
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- return get_idx(seq, *pos);
|
|
||||||
+ struct net *net = seq_file_net(seq);
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
+ return get_idx(net, seq->private, *pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
|
|
||||||
{
|
|
||||||
(*pos)++;
|
|
||||||
- return get_next(s, v);
|
|
||||||
+ return get_next(seq_file_net(s), s->private, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void seq_stop(struct seq_file *s, void *v)
|
|
||||||
- __releases(instances_lock)
|
|
||||||
{
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ struct net *net = seq_file_net(s);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int seq_show(struct seq_file *s, void *v)
|
|
||||||
@@ -960,8 +957,8 @@ static const struct seq_operations nfqnl_seq_ops = {
|
|
||||||
|
|
||||||
static int nfqnl_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
- return seq_open_private(file, &nfqnl_seq_ops,
|
|
||||||
- sizeof(struct iter_state));
|
|
||||||
+ return seq_open_net(inode, file, &nfqnl_seq_ops,
|
|
||||||
+ sizeof(struct iter_state));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations nfqnl_file_ops = {
|
|
||||||
@@ -969,13 +966,19 @@ static const struct file_operations nfqnl_file_ops = {
|
|
||||||
.open = nfqnl_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
- .release = seq_release_private,
|
|
||||||
+ .release = seq_release_net,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
static int __net_init nfnetlink_queue_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ spin_lock_init(&net->nfqnl.instances_lock);
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++)
|
|
||||||
+ INIT_HLIST_HEAD(&net->nfqnl.instance_table[i]);
|
|
||||||
+
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
net->proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
@@ -999,7 +1002,7 @@ static struct pernet_operations nfnetlink_queue_net_ops = {
|
|
||||||
|
|
||||||
static int __init nfnetlink_queue_init(void)
|
|
||||||
{
|
|
||||||
- int i, status;
|
|
||||||
+ int status;
|
|
||||||
|
|
||||||
status = register_pernet_subsys(&nfnetlink_queue_net_ops);
|
|
||||||
if (status) {
|
|
||||||
@@ -1008,9 +1011,6 @@ static int __init nfnetlink_queue_init(void)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
- INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
-
|
|
||||||
netlink_register_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
status = nfnetlink_subsys_register(&nfqnl_subsys);
|
|
||||||
if (status < 0) {
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
VERSION := 3.2.0
|
|
||||||
TARBALL := /usr/src/linux-source-$(VERSION).tar.bz2
|
|
||||||
|
|
||||||
SUBVERSION := -core
|
|
||||||
REVISION := 1.0
|
|
||||||
|
|
||||||
PATCHDIR := patches
|
|
||||||
PATCHES := $(sort $(wildcard $(PATCHDIR)/*.patch))
|
|
||||||
|
|
||||||
CONFIG := config.core
|
|
||||||
|
|
||||||
DEPDEBS := linux-source kernel-package po-debconf gettext
|
|
||||||
|
|
||||||
CONCURRENCY_LEVEL := 8
|
|
||||||
|
|
||||||
MAINTAINER ?= Tom Goff
|
|
||||||
EMAIL ?= thomas.goff@boeing.com
|
|
||||||
|
|
||||||
MAKEKPKGFLAGS := --initrd --rootcmd fakeroot --us --uc \
|
|
||||||
--append-to-version $(SUBVERSION) --revision $(REVISION)
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
build: debcheck defaultconfig patch
|
|
||||||
export CONCURRENCY_LEVEL="$(CONCURRENCY_LEVEL)" \
|
|
||||||
KPKG_MAINTAINER="$(MAINTAINER)" KPKG_EMAIL="$(EMAIL)"; \
|
|
||||||
cd linux-source-$(VERSION) && \
|
|
||||||
if [ -f ../$(CONFIG) ]; then \
|
|
||||||
cat ../$(CONFIG) >> .config; \
|
|
||||||
fi && \
|
|
||||||
fakeroot make-kpkg $(MAKEKPKGFLAGS) binary-arch
|
|
||||||
|
|
||||||
.PHONY: debcheck
|
|
||||||
debcheck:
|
|
||||||
for d in $(DEPDEBS); do \
|
|
||||||
if ! dpkg-query -s $$d > /dev/null 2>&1; then \
|
|
||||||
echo ERROR: build dependency not installed: $$d >&2; \
|
|
||||||
exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
|
|
||||||
.PHONY: defaultconfig
|
|
||||||
defaultconfig: linux-source-$(VERSION)
|
|
||||||
export KPKG_MAINTAINER="$(MAINTAINER)" KPKG_EMAIL="$(EMAIL)"; \
|
|
||||||
cd linux-source-$(VERSION) && make-kpkg $(MAKEKPKGFLAGS) configure
|
|
||||||
|
|
||||||
.PHONY: patch
|
|
||||||
patch: linux-source-$(VERSION) patch-stamp
|
|
||||||
patch-stamp: $(PATCHES)
|
|
||||||
for p in $^; do \
|
|
||||||
if ! patch -d linux-source-$(VERSION) -p1 < $$p; then \
|
|
||||||
echo ERROR: applying patch failed: $$p >&2; \
|
|
||||||
exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
touch patch-stamp
|
|
||||||
|
|
||||||
linux-source-$(VERSION): $(TARBALL)
|
|
||||||
tar -xjf $^
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -rf linux-source-$(VERSION) patch-stamp
|
|
|
@ -1,8 +0,0 @@
|
||||||
Author: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
|
|
||||||
The Makefile is basically a wrapper around the make-kpkg command that
|
|
||||||
simplifies building kernel packages. Running make will do some basic
|
|
||||||
dependency checks then build architecture appropriate kernel packages that
|
|
||||||
include changes from the patches directory. The nfnetlink patch is what
|
|
||||||
virtualizes the netfilter queue mechanism;
|
|
||||||
the ifindex patch virtualizes network interface index numbers.
|
|
|
@ -1 +0,0 @@
|
||||||
CONFIG_XFRM_STATISTICS=y
|
|
|
@ -1,60 +0,0 @@
|
||||||
From 918e253ebaa3d28c54ff64b596a0afc8779d106a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Fri, 27 Jul 2012 00:02:50 -0700
|
|
||||||
Subject: [PATCH] Make network device ifindex sequential per network
|
|
||||||
namespace.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
include/net/net_namespace.h | 2 ++
|
|
||||||
net/core/dev.c | 13 ++++++-------
|
|
||||||
2 files changed, 8 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index 4b6f04a..266e747 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -65,6 +65,8 @@ struct net {
|
|
||||||
struct sock *rtnl; /* rtnetlink socket */
|
|
||||||
struct sock *genl_sock;
|
|
||||||
|
|
||||||
+ int ifindex;
|
|
||||||
+
|
|
||||||
struct list_head dev_base_head;
|
|
||||||
struct hlist_head *dev_name_head;
|
|
||||||
struct hlist_head *dev_index_head;
|
|
||||||
diff --git a/net/core/dev.c b/net/core/dev.c
|
|
||||||
index 1cbddc9..d7f5711 100644
|
|
||||||
--- a/net/core/dev.c
|
|
||||||
+++ b/net/core/dev.c
|
|
||||||
@@ -5236,12 +5236,11 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
|
|
||||||
*/
|
|
||||||
static int dev_new_index(struct net *net)
|
|
||||||
{
|
|
||||||
- static int ifindex;
|
|
||||||
for (;;) {
|
|
||||||
- if (++ifindex <= 0)
|
|
||||||
- ifindex = 1;
|
|
||||||
- if (!__dev_get_by_index(net, ifindex))
|
|
||||||
- return ifindex;
|
|
||||||
+ if (++net->ifindex <= 0)
|
|
||||||
+ net->ifindex = 1;
|
|
||||||
+ if (!__dev_get_by_index(net, net->ifindex))
|
|
||||||
+ return net->ifindex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -6253,8 +6252,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
|
|
||||||
/* Actually switch the network namespace */
|
|
||||||
dev_net_set(dev, net);
|
|
||||||
|
|
||||||
- /* If there is an ifindex conflict assign a new one */
|
|
||||||
- if (__dev_get_by_index(net, dev->ifindex)) {
|
|
||||||
+ /* Assign a new ifindex */
|
|
||||||
+ {
|
|
||||||
int iflink = (dev->iflink == dev->ifindex);
|
|
||||||
dev->ifindex = dev_new_index(net);
|
|
||||||
if (iflink)
|
|
||||||
--
|
|
||||||
1.7.9.5
|
|
||||||
|
|
|
@ -1,351 +0,0 @@
|
||||||
From 67765faf27ec646bcc008bd34d12e48a7466dcdd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Thu, 26 Jul 2012 23:57:06 -0700
|
|
||||||
Subject: [PATCH 1/2] netfilter: Make the /proc/net/netfilter directory per
|
|
||||||
netns.
|
|
||||||
|
|
||||||
This allows subsystems to create per-netns entries.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
include/linux/netfilter.h | 5 -----
|
|
||||||
include/net/net_namespace.h | 3 +++
|
|
||||||
net/netfilter/core.c | 35 +++++++++++++++++++++++-------
|
|
||||||
net/netfilter/nf_log.c | 33 ++++++++++++++++++++++++----
|
|
||||||
net/netfilter/nf_queue.c | 31 +++++++++++++++++++++++----
|
|
||||||
net/netfilter/nfnetlink_log.c | 44 +++++++++++++++++++++++++++-----------
|
|
||||||
net/netfilter/nfnetlink_queue.c | 45 +++++++++++++++++++++++++++------------
|
|
||||||
7 files changed, 148 insertions(+), 48 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
|
|
||||||
index 857f502..b4e02fb 100644
|
|
||||||
--- a/include/linux/netfilter.h
|
|
||||||
+++ b/include/linux/netfilter.h
|
|
||||||
@@ -340,11 +340,6 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-#include <linux/proc_fs.h>
|
|
||||||
-extern struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
#else /* !CONFIG_NETFILTER */
|
|
||||||
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
|
|
||||||
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index 3bb6fa0..cf126ef 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -84,6 +84,9 @@ struct net {
|
|
||||||
struct netns_dccp dccp;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NETFILTER
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
+#endif
|
|
||||||
struct netns_xt xt;
|
|
||||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
|
||||||
struct netns_ct ct;
|
|
||||||
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
|
|
||||||
index afca6c7..9d9b103 100644
|
|
||||||
--- a/net/netfilter/core.c
|
|
||||||
+++ b/net/netfilter/core.c
|
|
||||||
@@ -255,25 +255,44 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct)
|
|
||||||
EXPORT_SYMBOL(nf_conntrack_destroy);
|
|
||||||
#endif /* CONFIG_NF_CONNTRACK */
|
|
||||||
|
|
||||||
+static int __net_init netfilter_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
-struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
-EXPORT_SYMBOL(proc_net_netfilter);
|
|
||||||
+ net->proc_net_netfilter = proc_net_mkdir(net, "netfilter",
|
|
||||||
+ net->proc_net);
|
|
||||||
+ if (!net->proc_net_netfilter) {
|
|
||||||
+ pr_err("%s: cannot create netfilter proc entry\n", __func__);
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+ }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit netfilter_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ proc_net_remove(net, "netfilter");
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_net_ops = {
|
|
||||||
+ .init = netfilter_net_init,
|
|
||||||
+ .exit = netfilter_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
void __init netfilter_init(void)
|
|
||||||
{
|
|
||||||
int i, h;
|
|
||||||
+
|
|
||||||
+ if (register_pernet_subsys(&netfilter_net_ops))
|
|
||||||
+ panic("%s: failed to register per netns operations", __func__);
|
|
||||||
+
|
|
||||||
for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) {
|
|
||||||
for (h = 0; h < NF_MAX_HOOKS; h++)
|
|
||||||
INIT_LIST_HEAD(&nf_hooks[i][h]);
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- proc_net_netfilter = proc_mkdir("netfilter", init_net.proc_net);
|
|
||||||
- if (!proc_net_netfilter)
|
|
||||||
- panic("cannot create netfilter proc entry");
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
if (netfilter_queue_init() < 0)
|
|
||||||
panic("cannot initialize nf_queue");
|
|
||||||
if (netfilter_log_init() < 0)
|
|
||||||
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
|
|
||||||
index 957374a..c546ad7 100644
|
|
||||||
--- a/net/netfilter/nf_log.c
|
|
||||||
+++ b/net/netfilter/nf_log.c
|
|
||||||
@@ -297,14 +297,39 @@ static __init int netfilter_log_sysctl_init(void)
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_SYSCTL */
|
|
||||||
|
|
||||||
-int __init netfilter_log_init(void)
|
|
||||||
+static int __net_init netfilter_log_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
- int i, r;
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nf_log", S_IRUGO,
|
|
||||||
- proc_net_netfilter, &nflog_file_ops))
|
|
||||||
- return -1;
|
|
||||||
+ net->proc_net_netfilter, &nflog_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit netfilter_log_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nf_log", net->proc_net_netfilter);
|
|
||||||
#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_log_net_ops = {
|
|
||||||
+ .init = netfilter_log_net_init,
|
|
||||||
+ .exit = netfilter_log_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+int __init netfilter_log_init(void)
|
|
||||||
+{
|
|
||||||
+ int i, r;
|
|
||||||
+
|
|
||||||
+ r = register_pernet_subsys(&netfilter_log_net_ops);
|
|
||||||
+ if (r) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return r;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Errors will trigger panic, unroll on error is unnecessary. */
|
|
||||||
r = netfilter_log_sysctl_init();
|
|
||||||
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
|
|
||||||
index b3a7db6..470ec3a 100644
|
|
||||||
--- a/net/netfilter/nf_queue.c
|
|
||||||
+++ b/net/netfilter/nf_queue.c
|
|
||||||
@@ -383,14 +383,37 @@ static const struct file_operations nfqueue_file_ops = {
|
|
||||||
};
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
-
|
|
||||||
-int __init netfilter_queue_init(void)
|
|
||||||
+static int __net_init netfilter_queue_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nf_queue", S_IRUGO,
|
|
||||||
- proc_net_netfilter, &nfqueue_file_ops))
|
|
||||||
- return -1;
|
|
||||||
+ net->proc_net_netfilter, &nfqueue_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
#endif
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void __net_exit netfilter_queue_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nf_queue", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_queue_net_ops = {
|
|
||||||
+ .init = netfilter_queue_net_init,
|
|
||||||
+ .exit = netfilter_queue_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+int __init netfilter_queue_init(void)
|
|
||||||
+{
|
|
||||||
+ int err;
|
|
||||||
+
|
|
||||||
+ err = register_pernet_subsys(&netfilter_queue_net_ops);
|
|
||||||
+ if (err)
|
|
||||||
+ pr_err("%s: cannot initialize per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+
|
|
||||||
+ return err;
|
|
||||||
+}
|
|
||||||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
|
|
||||||
index 66b2c54..e4c3c1e 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_log.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_log.c
|
|
||||||
@@ -950,9 +950,39 @@ static const struct file_operations nful_file_ops = {
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
+static int __net_init nfnetlink_log_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ if (!proc_create("nfnetlink_log", 0440,
|
|
||||||
+ net->proc_net_netfilter, &nful_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit nfnetlink_log_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nfnetlink_log", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations nfnetlink_log_net_ops = {
|
|
||||||
+ .init = nfnetlink_log_net_init,
|
|
||||||
+ .exit = nfnetlink_log_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __init nfnetlink_log_init(void)
|
|
||||||
{
|
|
||||||
- int i, status = -ENOMEM;
|
|
||||||
+ int i, status;
|
|
||||||
+
|
|
||||||
+ status = register_pernet_subsys(&nfnetlink_log_net_ops);
|
|
||||||
+ if (status) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return status;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
@@ -975,17 +1005,8 @@ static int __init nfnetlink_log_init(void)
|
|
||||||
goto cleanup_subsys;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- if (!proc_create("nfnetlink_log", 0440,
|
|
||||||
- proc_net_netfilter, &nful_file_ops))
|
|
||||||
- goto cleanup_logger;
|
|
||||||
-#endif
|
|
||||||
return status;
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-cleanup_logger:
|
|
||||||
- nf_log_unregister(&nfulnl_logger);
|
|
||||||
-#endif
|
|
||||||
cleanup_subsys:
|
|
||||||
nfnetlink_subsys_unregister(&nfulnl_subsys);
|
|
||||||
cleanup_netlink_notifier:
|
|
||||||
@@ -996,9 +1017,6 @@ cleanup_netlink_notifier:
|
|
||||||
static void __exit nfnetlink_log_fini(void)
|
|
||||||
{
|
|
||||||
nf_log_unregister(&nfulnl_logger);
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- remove_proc_entry("nfnetlink_log", proc_net_netfilter);
|
|
||||||
-#endif
|
|
||||||
nfnetlink_subsys_unregister(&nfulnl_subsys);
|
|
||||||
netlink_unregister_notifier(&nfulnl_rtnl_notifier);
|
|
||||||
}
|
|
||||||
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
|
|
||||||
index a80b0cb..b615da5 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_queue.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_queue.c
|
|
||||||
@@ -974,9 +974,39 @@ static const struct file_operations nfqnl_file_ops = {
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
+static int __net_init nfnetlink_queue_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
+ net->proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit nfnetlink_queue_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nfnetlink_queue", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations nfnetlink_queue_net_ops = {
|
|
||||||
+ .init = nfnetlink_queue_net_init,
|
|
||||||
+ .exit = nfnetlink_queue_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __init nfnetlink_queue_init(void)
|
|
||||||
{
|
|
||||||
- int i, status = -ENOMEM;
|
|
||||||
+ int i, status;
|
|
||||||
+
|
|
||||||
+ status = register_pernet_subsys(&nfnetlink_queue_net_ops);
|
|
||||||
+ if (status) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return status;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
@@ -988,19 +1018,9 @@ static int __init nfnetlink_queue_init(void)
|
|
||||||
goto cleanup_netlink_notifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
- proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
- goto cleanup_subsys;
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
register_netdevice_notifier(&nfqnl_dev_notifier);
|
|
||||||
return status;
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-cleanup_subsys:
|
|
||||||
- nfnetlink_subsys_unregister(&nfqnl_subsys);
|
|
||||||
-#endif
|
|
||||||
cleanup_netlink_notifier:
|
|
||||||
netlink_unregister_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
return status;
|
|
||||||
@@ -1010,9 +1030,6 @@ static void __exit nfnetlink_queue_fini(void)
|
|
||||||
{
|
|
||||||
nf_unregister_queue_handlers(&nfqh);
|
|
||||||
unregister_netdevice_notifier(&nfqnl_dev_notifier);
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- remove_proc_entry("nfnetlink_queue", proc_net_netfilter);
|
|
||||||
-#endif
|
|
||||||
nfnetlink_subsys_unregister(&nfqnl_subsys);
|
|
||||||
netlink_unregister_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
|
|
||||||
--
|
|
||||||
1.7.9.5
|
|
||||||
|
|
|
@ -1,544 +0,0 @@
|
||||||
From f8179877a37f37631d831de6381f22fd643b4ea0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Thu, 26 Jul 2012 23:58:38 -0700
|
|
||||||
Subject: [PATCH 2/2] netfilter: nfnetlink_queue: Add netns support.
|
|
||||||
|
|
||||||
Make nfnetlink_queue network namespace aware including a per-netns
|
|
||||||
/proc/net/netfilter/nfnetlink_queue file.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
include/net/net_namespace.h | 6 ++
|
|
||||||
include/net/netfilter/nf_queue.h | 3 +-
|
|
||||||
include/net/netns/nfqnl.h | 14 ++++
|
|
||||||
net/ipv4/netfilter/ip_queue.c | 6 +-
|
|
||||||
net/ipv6/netfilter/ip6_queue.c | 6 +-
|
|
||||||
net/netfilter/nf_queue.c | 12 +++-
|
|
||||||
net/netfilter/nfnetlink_queue.c | 136 +++++++++++++++++++-------------------
|
|
||||||
7 files changed, 111 insertions(+), 72 deletions(-)
|
|
||||||
create mode 100644 include/net/netns/nfqnl.h
|
|
||||||
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index cf126ef..4b6f04a 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -21,6 +21,9 @@
|
|
||||||
#include <net/netns/conntrack.h>
|
|
||||||
#endif
|
|
||||||
#include <net/netns/xfrm.h>
|
|
||||||
+#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
|
||||||
+#include <net/netns/nfqnl.h>
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
struct proc_dir_entry;
|
|
||||||
struct net_device;
|
|
||||||
@@ -93,6 +96,9 @@ struct net {
|
|
||||||
#endif
|
|
||||||
struct sock *nfnl;
|
|
||||||
struct sock *nfnl_stash;
|
|
||||||
+#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
|
||||||
+ struct netns_nfqnl nfqnl;
|
|
||||||
+#endif
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_WEXT_CORE
|
|
||||||
struct sk_buff_head wext_nlevents;
|
|
||||||
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
|
|
||||||
index 252fd10..3e5bde8 100644
|
|
||||||
--- a/include/net/netfilter/nf_queue.h
|
|
||||||
+++ b/include/net/netfilter/nf_queue.h
|
|
||||||
@@ -19,7 +19,8 @@ struct nf_queue_entry {
|
|
||||||
|
|
||||||
/* Packet queuing */
|
|
||||||
struct nf_queue_handler {
|
|
||||||
- int (*outfn)(struct nf_queue_entry *entry,
|
|
||||||
+ int (*outfn)(struct net *net,
|
|
||||||
+ struct nf_queue_entry *entry,
|
|
||||||
unsigned int queuenum);
|
|
||||||
char *name;
|
|
||||||
};
|
|
||||||
diff --git a/include/net/netns/nfqnl.h b/include/net/netns/nfqnl.h
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..0fe7fbe
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/include/net/netns/nfqnl.h
|
|
||||||
@@ -0,0 +1,14 @@
|
|
||||||
+#ifndef __NETNS_NFQNL_H
|
|
||||||
+#define __NETNS_NFQNL_H
|
|
||||||
+
|
|
||||||
+#include <linux/spinlock.h>
|
|
||||||
+#include <linux/list.h>
|
|
||||||
+
|
|
||||||
+#define NFQNL_INSTANCE_BUCKETS 16
|
|
||||||
+
|
|
||||||
+struct netns_nfqnl {
|
|
||||||
+ spinlock_t instances_lock;
|
|
||||||
+ struct hlist_head instance_table[NFQNL_INSTANCE_BUCKETS];
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+#endif /* __NETNS_NFQNL_H */
|
|
||||||
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
|
|
||||||
index e59aabd..f3c43e5 100644
|
|
||||||
--- a/net/ipv4/netfilter/ip_queue.c
|
|
||||||
+++ b/net/ipv4/netfilter/ip_queue.c
|
|
||||||
@@ -225,7 +225,8 @@ nlmsg_failure:
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
+ipq_enqueue_packet(struct net *net, struct nf_queue_entry *entry,
|
|
||||||
+ unsigned int queuenum)
|
|
||||||
{
|
|
||||||
int status = -EINVAL;
|
|
||||||
struct sk_buff *nskb;
|
|
||||||
@@ -239,6 +240,9 @@ ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
|
|
||||||
spin_lock_bh(&queue_lock);
|
|
||||||
|
|
||||||
+ if (!net_eq(net, &init_net))
|
|
||||||
+ goto err_out_free_nskb;
|
|
||||||
+
|
|
||||||
if (!peer_pid)
|
|
||||||
goto err_out_free_nskb;
|
|
||||||
|
|
||||||
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
|
|
||||||
index e63c397..322c511 100644
|
|
||||||
--- a/net/ipv6/netfilter/ip6_queue.c
|
|
||||||
+++ b/net/ipv6/netfilter/ip6_queue.c
|
|
||||||
@@ -225,7 +225,8 @@ nlmsg_failure:
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
+ipq_enqueue_packet(struct net *net, struct nf_queue_entry *entry,
|
|
||||||
+ unsigned int queuenum)
|
|
||||||
{
|
|
||||||
int status = -EINVAL;
|
|
||||||
struct sk_buff *nskb;
|
|
||||||
@@ -239,6 +240,9 @@ ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
|
|
||||||
spin_lock_bh(&queue_lock);
|
|
||||||
|
|
||||||
+ if (!net_eq(net, &init_net))
|
|
||||||
+ goto err_out_free_nskb;
|
|
||||||
+
|
|
||||||
if (!peer_pid)
|
|
||||||
goto err_out_free_nskb;
|
|
||||||
|
|
||||||
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
|
|
||||||
index 470ec3a..6894ecc 100644
|
|
||||||
--- a/net/netfilter/nf_queue.c
|
|
||||||
+++ b/net/netfilter/nf_queue.c
|
|
||||||
@@ -133,6 +133,16 @@ static int __nf_queue(struct sk_buff *skb,
|
|
||||||
#endif
|
|
||||||
const struct nf_afinfo *afinfo;
|
|
||||||
const struct nf_queue_handler *qh;
|
|
||||||
+ struct net *net;
|
|
||||||
+
|
|
||||||
+ if (indev)
|
|
||||||
+ net = dev_net(indev);
|
|
||||||
+ else if (skb->sk)
|
|
||||||
+ net = sock_net(skb->sk);
|
|
||||||
+ else if (outdev)
|
|
||||||
+ net = dev_net(outdev);
|
|
||||||
+ else
|
|
||||||
+ return status;
|
|
||||||
|
|
||||||
/* QUEUE == DROP if no one is waiting, to be safe. */
|
|
||||||
rcu_read_lock();
|
|
||||||
@@ -185,7 +195,7 @@ static int __nf_queue(struct sk_buff *skb,
|
|
||||||
#endif
|
|
||||||
skb_dst_force(skb);
|
|
||||||
afinfo->saveroute(skb, entry);
|
|
||||||
- status = qh->outfn(entry, queuenum);
|
|
||||||
+ status = qh->outfn(net, entry, queuenum);
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
|
|
||||||
index b615da5..11725a0 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_queue.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_queue.c
|
|
||||||
@@ -64,24 +64,19 @@ struct nfqnl_instance {
|
|
||||||
|
|
||||||
typedef int (*nfqnl_cmpfn)(struct nf_queue_entry *, unsigned long);
|
|
||||||
|
|
||||||
-static DEFINE_SPINLOCK(instances_lock);
|
|
||||||
-
|
|
||||||
-#define INSTANCE_BUCKETS 16
|
|
||||||
-static struct hlist_head instance_table[INSTANCE_BUCKETS] __read_mostly;
|
|
||||||
-
|
|
||||||
static inline u_int8_t instance_hashfn(u_int16_t queue_num)
|
|
||||||
{
|
|
||||||
- return ((queue_num >> 8) | queue_num) % INSTANCE_BUCKETS;
|
|
||||||
+ return ((queue_num >> 8) | queue_num) % NFQNL_INSTANCE_BUCKETS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nfqnl_instance *
|
|
||||||
-instance_lookup(u_int16_t queue_num)
|
|
||||||
+instance_lookup(struct net *net, u_int16_t queue_num)
|
|
||||||
{
|
|
||||||
struct hlist_head *head;
|
|
||||||
struct hlist_node *pos;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
|
|
||||||
- head = &instance_table[instance_hashfn(queue_num)];
|
|
||||||
+ head = &net->nfqnl.instance_table[instance_hashfn(queue_num)];
|
|
||||||
hlist_for_each_entry_rcu(inst, pos, head, hlist) {
|
|
||||||
if (inst->queue_num == queue_num)
|
|
||||||
return inst;
|
|
||||||
@@ -90,14 +85,14 @@ instance_lookup(u_int16_t queue_num)
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nfqnl_instance *
|
|
||||||
-instance_create(u_int16_t queue_num, int pid)
|
|
||||||
+instance_create(struct net *net, u_int16_t queue_num, int pid)
|
|
||||||
{
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
unsigned int h;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- if (instance_lookup(queue_num)) {
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
+ if (instance_lookup(net, queue_num)) {
|
|
||||||
err = -EEXIST;
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
@@ -122,16 +117,16 @@ instance_create(u_int16_t queue_num, int pid)
|
|
||||||
}
|
|
||||||
|
|
||||||
h = instance_hashfn(queue_num);
|
|
||||||
- hlist_add_head_rcu(&inst->hlist, &instance_table[h]);
|
|
||||||
+ hlist_add_head_rcu(&inst->hlist, &net->nfqnl.instance_table[h]);
|
|
||||||
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
|
|
||||||
return inst;
|
|
||||||
|
|
||||||
out_free:
|
|
||||||
kfree(inst);
|
|
||||||
out_unlock:
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
return ERR_PTR(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -157,11 +152,11 @@ __instance_destroy(struct nfqnl_instance *inst)
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
-instance_destroy(struct nfqnl_instance *inst)
|
|
||||||
+instance_destroy(struct net *net, struct nfqnl_instance *inst)
|
|
||||||
{
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
__instance_destroy(inst);
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
@@ -390,7 +385,8 @@ nla_put_failure:
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
+nfqnl_enqueue_packet(struct net *net, struct nf_queue_entry *entry,
|
|
||||||
+ unsigned int queuenum)
|
|
||||||
{
|
|
||||||
struct sk_buff *nskb;
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
@@ -398,7 +394,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
__be32 *packet_id_ptr;
|
|
||||||
|
|
||||||
/* rcu_read_lock()ed by nf_hook_slow() */
|
|
||||||
- queue = instance_lookup(queuenum);
|
|
||||||
+ queue = instance_lookup(net, queuenum);
|
|
||||||
if (!queue) {
|
|
||||||
err = -ESRCH;
|
|
||||||
goto err_out;
|
|
||||||
@@ -432,7 +428,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
*packet_id_ptr = htonl(entry->id);
|
|
||||||
|
|
||||||
/* nfnetlink_unicast will either free the nskb or add it to a socket */
|
|
||||||
- err = nfnetlink_unicast(nskb, &init_net, queue->peer_pid, MSG_DONTWAIT);
|
|
||||||
+ err = nfnetlink_unicast(nskb, net, queue->peer_pid, MSG_DONTWAIT);
|
|
||||||
if (err < 0) {
|
|
||||||
queue->queue_user_dropped++;
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -541,16 +537,16 @@ dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
|
|
||||||
/* drop all packets with either indev or outdev == ifindex from all queue
|
|
||||||
* instances */
|
|
||||||
static void
|
|
||||||
-nfqnl_dev_drop(int ifindex)
|
|
||||||
+nfqnl_dev_drop(struct net *net, int ifindex)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++) {
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++) {
|
|
||||||
struct hlist_node *tmp;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
- struct hlist_head *head = &instance_table[i];
|
|
||||||
+ struct hlist_head *head = &net->nfqnl.instance_table[i];
|
|
||||||
|
|
||||||
hlist_for_each_entry_rcu(inst, tmp, head, hlist)
|
|
||||||
nfqnl_flush(inst, dev_cmp, ifindex);
|
|
||||||
@@ -567,12 +563,9 @@ nfqnl_rcv_dev_event(struct notifier_block *this,
|
|
||||||
{
|
|
||||||
struct net_device *dev = ptr;
|
|
||||||
|
|
||||||
- if (!net_eq(dev_net(dev), &init_net))
|
|
||||||
- return NOTIFY_DONE;
|
|
||||||
-
|
|
||||||
/* Drop any packets associated with the downed device */
|
|
||||||
if (event == NETDEV_DOWN)
|
|
||||||
- nfqnl_dev_drop(dev->ifindex);
|
|
||||||
+ nfqnl_dev_drop(dev_net(dev), dev->ifindex);
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -590,19 +583,19 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* destroy all instances for this pid */
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++) {
|
|
||||||
+ spin_lock(&n->net->nfqnl.instances_lock);
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++) {
|
|
||||||
struct hlist_node *tmp, *t2;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
- struct hlist_head *head = &instance_table[i];
|
|
||||||
+ struct hlist_head *head =
|
|
||||||
+ &n->net->nfqnl.instance_table[i];
|
|
||||||
|
|
||||||
hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
|
|
||||||
- if ((n->net == &init_net) &&
|
|
||||||
- (n->pid == inst->peer_pid))
|
|
||||||
+ if (n->pid == inst->peer_pid)
|
|
||||||
__instance_destroy(inst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&n->net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
@@ -622,11 +615,12 @@ static const struct nla_policy nfqa_verdict_batch_policy[NFQA_MAX+1] = {
|
|
||||||
[NFQA_MARK] = { .type = NLA_U32 },
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct nfqnl_instance *verdict_instance_lookup(u16 queue_num, int nlpid)
|
|
||||||
+static struct nfqnl_instance *verdict_instance_lookup(struct net *net,
|
|
||||||
+ u16 queue_num, int nlpid)
|
|
||||||
{
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (!queue)
|
|
||||||
return ERR_PTR(-ENODEV);
|
|
||||||
|
|
||||||
@@ -670,7 +664,8 @@ nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
LIST_HEAD(batch_list);
|
|
||||||
u16 queue_num = ntohs(nfmsg->res_id);
|
|
||||||
|
|
||||||
- queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid);
|
|
||||||
+ queue = verdict_instance_lookup(sock_net(ctnl), queue_num,
|
|
||||||
+ NETLINK_CB(skb).pid);
|
|
||||||
if (IS_ERR(queue))
|
|
||||||
return PTR_ERR(queue);
|
|
||||||
|
|
||||||
@@ -715,11 +710,12 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
unsigned int verdict;
|
|
||||||
struct nf_queue_entry *entry;
|
|
||||||
+ struct net *net = sock_net(ctnl);
|
|
||||||
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (!queue)
|
|
||||||
|
|
||||||
- queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid);
|
|
||||||
+ queue = verdict_instance_lookup(net, queue_num, NETLINK_CB(skb).pid);
|
|
||||||
if (IS_ERR(queue))
|
|
||||||
return PTR_ERR(queue);
|
|
||||||
|
|
||||||
@@ -774,6 +770,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
struct nfqnl_msg_config_cmd *cmd = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
+ struct net *net = sock_net(ctnl);
|
|
||||||
|
|
||||||
if (nfqa[NFQA_CFG_CMD]) {
|
|
||||||
cmd = nla_data(nfqa[NFQA_CFG_CMD]);
|
|
||||||
@@ -790,7 +787,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
}
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (queue && queue->peer_pid != NETLINK_CB(skb).pid) {
|
|
||||||
ret = -EPERM;
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -803,7 +800,8 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
ret = -EBUSY;
|
|
||||||
goto err_out_unlock;
|
|
||||||
}
|
|
||||||
- queue = instance_create(queue_num, NETLINK_CB(skb).pid);
|
|
||||||
+ queue = instance_create(net, queue_num,
|
|
||||||
+ NETLINK_CB(skb).pid);
|
|
||||||
if (IS_ERR(queue)) {
|
|
||||||
ret = PTR_ERR(queue);
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -814,7 +812,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto err_out_unlock;
|
|
||||||
}
|
|
||||||
- instance_destroy(queue);
|
|
||||||
+ instance_destroy(net, queue);
|
|
||||||
break;
|
|
||||||
case NFQNL_CFG_CMD_PF_BIND:
|
|
||||||
case NFQNL_CFG_CMD_PF_UNBIND:
|
|
||||||
@@ -878,65 +876,64 @@ static const struct nfnetlink_subsystem nfqnl_subsys = {
|
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
struct iter_state {
|
|
||||||
+ struct seq_net_private p;
|
|
||||||
unsigned int bucket;
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct hlist_node *get_first(struct seq_file *seq)
|
|
||||||
+static struct hlist_node *get_first(struct net *net, struct iter_state *st)
|
|
||||||
{
|
|
||||||
- struct iter_state *st = seq->private;
|
|
||||||
-
|
|
||||||
if (!st)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) {
|
|
||||||
- if (!hlist_empty(&instance_table[st->bucket]))
|
|
||||||
- return instance_table[st->bucket].first;
|
|
||||||
+ for (st->bucket = 0; st->bucket < NFQNL_INSTANCE_BUCKETS; st->bucket++) {
|
|
||||||
+ if (!hlist_empty(&net->nfqnl.instance_table[st->bucket]))
|
|
||||||
+ return net->nfqnl.instance_table[st->bucket].first;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct hlist_node *get_next(struct seq_file *seq, struct hlist_node *h)
|
|
||||||
+static struct hlist_node *get_next(struct net *net, struct iter_state *st,
|
|
||||||
+ struct hlist_node *h)
|
|
||||||
{
|
|
||||||
- struct iter_state *st = seq->private;
|
|
||||||
-
|
|
||||||
h = h->next;
|
|
||||||
while (!h) {
|
|
||||||
- if (++st->bucket >= INSTANCE_BUCKETS)
|
|
||||||
+ if (++st->bucket >= NFQNL_INSTANCE_BUCKETS)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- h = instance_table[st->bucket].first;
|
|
||||||
+ h = net->nfqnl.instance_table[st->bucket].first;
|
|
||||||
}
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct hlist_node *get_idx(struct seq_file *seq, loff_t pos)
|
|
||||||
+static struct hlist_node *get_idx(struct net *net, struct iter_state *st,
|
|
||||||
+ loff_t pos)
|
|
||||||
{
|
|
||||||
struct hlist_node *head;
|
|
||||||
- head = get_first(seq);
|
|
||||||
+ head = get_first(net, st);
|
|
||||||
|
|
||||||
if (head)
|
|
||||||
- while (pos && (head = get_next(seq, head)))
|
|
||||||
+ while (pos && (head = get_next(net, st, head)))
|
|
||||||
pos--;
|
|
||||||
return pos ? NULL : head;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *seq_start(struct seq_file *seq, loff_t *pos)
|
|
||||||
- __acquires(instances_lock)
|
|
||||||
{
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- return get_idx(seq, *pos);
|
|
||||||
+ struct net *net = seq_file_net(seq);
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
+ return get_idx(net, seq->private, *pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
|
|
||||||
{
|
|
||||||
(*pos)++;
|
|
||||||
- return get_next(s, v);
|
|
||||||
+ return get_next(seq_file_net(s), s->private, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void seq_stop(struct seq_file *s, void *v)
|
|
||||||
- __releases(instances_lock)
|
|
||||||
{
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ struct net *net = seq_file_net(s);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int seq_show(struct seq_file *s, void *v)
|
|
||||||
@@ -960,8 +957,8 @@ static const struct seq_operations nfqnl_seq_ops = {
|
|
||||||
|
|
||||||
static int nfqnl_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
- return seq_open_private(file, &nfqnl_seq_ops,
|
|
||||||
- sizeof(struct iter_state));
|
|
||||||
+ return seq_open_net(inode, file, &nfqnl_seq_ops,
|
|
||||||
+ sizeof(struct iter_state));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations nfqnl_file_ops = {
|
|
||||||
@@ -969,13 +966,19 @@ static const struct file_operations nfqnl_file_ops = {
|
|
||||||
.open = nfqnl_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
- .release = seq_release_private,
|
|
||||||
+ .release = seq_release_net,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
static int __net_init nfnetlink_queue_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ spin_lock_init(&net->nfqnl.instances_lock);
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++)
|
|
||||||
+ INIT_HLIST_HEAD(&net->nfqnl.instance_table[i]);
|
|
||||||
+
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
net->proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
@@ -999,7 +1002,7 @@ static struct pernet_operations nfnetlink_queue_net_ops = {
|
|
||||||
|
|
||||||
static int __init nfnetlink_queue_init(void)
|
|
||||||
{
|
|
||||||
- int i, status;
|
|
||||||
+ int status;
|
|
||||||
|
|
||||||
status = register_pernet_subsys(&nfnetlink_queue_net_ops);
|
|
||||||
if (status) {
|
|
||||||
@@ -1008,9 +1011,6 @@ static int __init nfnetlink_queue_init(void)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
- INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
-
|
|
||||||
netlink_register_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
status = nfnetlink_subsys_register(&nfqnl_subsys);
|
|
||||||
if (status < 0) {
|
|
||||||
--
|
|
||||||
1.7.9.5
|
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
VERSION := $(shell dpkg -l linux-source 2> /dev/null | \
|
|
||||||
awk '/^i/ {match($$3, "[0-9]+[.][0-9]+[.][0-9]+"); if (RSTART) print substr($$3, RSTART, RLENGTH)}')
|
|
||||||
TARBALL := /usr/src/linux-source-$(VERSION).tar.bz2
|
|
||||||
|
|
||||||
SUBVERSION := -core
|
|
||||||
REVISION := 1.0
|
|
||||||
|
|
||||||
PATCHDIR := patches
|
|
||||||
PATCHES := $(sort $(wildcard $(PATCHDIR)/*.patch))
|
|
||||||
|
|
||||||
CONFIG := config.core
|
|
||||||
|
|
||||||
DEPDEBS := linux-source kernel-package po-debconf gettext
|
|
||||||
|
|
||||||
CONCURRENCY_LEVEL := $(shell lscpu 2> /dev/null | \
|
|
||||||
awk '/^CPU\(s\)/ {print $$2}')
|
|
||||||
ifeq ($(strip $(CONCURRENCY_LEVEL)),)
|
|
||||||
CONCURRENCY_LEVEL := 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
MAINTAINER ?= $(shell id -nu)
|
|
||||||
EMAIL ?= $(MAINTAINER)@$(shell hostname -f)
|
|
||||||
|
|
||||||
MAKEKPKGFLAGS := --initrd --rootcmd fakeroot --us --uc \
|
|
||||||
--append-to-version $(SUBVERSION) --revision $(REVISION)
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
build: debcheck defaultconfig patch
|
|
||||||
export CONCURRENCY_LEVEL="$(CONCURRENCY_LEVEL)" \
|
|
||||||
KPKG_MAINTAINER="$(MAINTAINER)" KPKG_EMAIL="$(EMAIL)"; \
|
|
||||||
cd linux-source-$(VERSION) && \
|
|
||||||
if [ -f ../$(CONFIG) ]; then \
|
|
||||||
cat ../$(CONFIG) >> .config; \
|
|
||||||
fi && \
|
|
||||||
fakeroot make-kpkg $(MAKEKPKGFLAGS) binary-arch
|
|
||||||
|
|
||||||
.PHONY: debcheck
|
|
||||||
debcheck:
|
|
||||||
for d in $(DEPDEBS); do \
|
|
||||||
if ! dpkg-query -s $$d > /dev/null 2>&1; then \
|
|
||||||
echo ERROR: build dependency not installed: $$d >&2; \
|
|
||||||
exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
|
|
||||||
.PHONY: defaultconfig
|
|
||||||
defaultconfig: linux-source-$(VERSION)
|
|
||||||
export KPKG_MAINTAINER="$(MAINTAINER)" KPKG_EMAIL="$(EMAIL)"; \
|
|
||||||
cd linux-source-$(VERSION) && make-kpkg $(MAKEKPKGFLAGS) configure
|
|
||||||
|
|
||||||
.PHONY: patch
|
|
||||||
patch: linux-source-$(VERSION) patch-stamp
|
|
||||||
patch-stamp: $(PATCHES)
|
|
||||||
for p in $^; do \
|
|
||||||
if ! patch -d linux-source-$(VERSION) -p1 < $$p; then \
|
|
||||||
echo ERROR: applying patch failed: $$p >&2; \
|
|
||||||
exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
touch patch-stamp
|
|
||||||
|
|
||||||
.PHONY: source
|
|
||||||
source: linux-source-$(VERSION)
|
|
||||||
|
|
||||||
linux-source-$(VERSION): $(TARBALL)
|
|
||||||
tar -xjf $^
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -rf linux-source-$(VERSION) patch-stamp
|
|
|
@ -1 +0,0 @@
|
||||||
CONFIG_XFRM_STATISTICS=y
|
|
|
@ -1,60 +0,0 @@
|
||||||
From e98f08306dd0dc854d93339730a8603638173e23 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Fri, 27 Jul 2012 00:02:50 -0700
|
|
||||||
Subject: [PATCH] Make network device ifindex sequential per network
|
|
||||||
namespace.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
include/net/net_namespace.h | 2 ++
|
|
||||||
net/core/dev.c | 13 ++++++-------
|
|
||||||
2 files changed, 8 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index ac9195e..1b9c99a 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -62,6 +62,8 @@ struct net {
|
|
||||||
struct sock *rtnl; /* rtnetlink socket */
|
|
||||||
struct sock *genl_sock;
|
|
||||||
|
|
||||||
+ int ifindex;
|
|
||||||
+
|
|
||||||
struct list_head dev_base_head;
|
|
||||||
struct hlist_head *dev_name_head;
|
|
||||||
struct hlist_head *dev_index_head;
|
|
||||||
diff --git a/net/core/dev.c b/net/core/dev.c
|
|
||||||
index 3ad746b..7bec156 100644
|
|
||||||
--- a/net/core/dev.c
|
|
||||||
+++ b/net/core/dev.c
|
|
||||||
@@ -5168,12 +5168,11 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
|
|
||||||
*/
|
|
||||||
static int dev_new_index(struct net *net)
|
|
||||||
{
|
|
||||||
- static int ifindex;
|
|
||||||
for (;;) {
|
|
||||||
- if (++ifindex <= 0)
|
|
||||||
- ifindex = 1;
|
|
||||||
- if (!__dev_get_by_index(net, ifindex))
|
|
||||||
- return ifindex;
|
|
||||||
+ if (++net->ifindex <= 0)
|
|
||||||
+ net->ifindex = 1;
|
|
||||||
+ if (!__dev_get_by_index(net, net->ifindex))
|
|
||||||
+ return net->ifindex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -6182,8 +6181,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
|
|
||||||
/* Actually switch the network namespace */
|
|
||||||
dev_net_set(dev, net);
|
|
||||||
|
|
||||||
- /* If there is an ifindex conflict assign a new one */
|
|
||||||
- if (__dev_get_by_index(net, dev->ifindex)) {
|
|
||||||
+ /* Assign a new ifindex */
|
|
||||||
+ {
|
|
||||||
int iflink = (dev->iflink == dev->ifindex);
|
|
||||||
dev->ifindex = dev_new_index(net);
|
|
||||||
if (iflink)
|
|
||||||
--
|
|
||||||
1.7.10.4
|
|
||||||
|
|
|
@ -1,351 +0,0 @@
|
||||||
From 5af499895ded68e1d42510df30be2004b4b778bf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Thu, 26 Jul 2012 23:57:06 -0700
|
|
||||||
Subject: [PATCH 1/2] netfilter: Make the /proc/net/netfilter directory per
|
|
||||||
netns.
|
|
||||||
|
|
||||||
This allows subsystems to create per-netns entries.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
include/linux/netfilter.h | 5 -----
|
|
||||||
include/net/net_namespace.h | 3 +++
|
|
||||||
net/netfilter/core.c | 35 +++++++++++++++++++++++-------
|
|
||||||
net/netfilter/nf_log.c | 33 ++++++++++++++++++++++++----
|
|
||||||
net/netfilter/nf_queue.c | 31 +++++++++++++++++++++++----
|
|
||||||
net/netfilter/nfnetlink_log.c | 44 +++++++++++++++++++++++++++-----------
|
|
||||||
net/netfilter/nfnetlink_queue.c | 45 +++++++++++++++++++++++++++------------
|
|
||||||
7 files changed, 148 insertions(+), 48 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
|
|
||||||
index ff9c84c..e28a566 100644
|
|
||||||
--- a/include/linux/netfilter.h
|
|
||||||
+++ b/include/linux/netfilter.h
|
|
||||||
@@ -350,11 +350,6 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-#include <linux/proc_fs.h>
|
|
||||||
-extern struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
#else /* !CONFIG_NETFILTER */
|
|
||||||
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
|
|
||||||
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index 1b9c99a..449fc8e 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -86,6 +86,9 @@ struct net {
|
|
||||||
struct netns_dccp dccp;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NETFILTER
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
+#endif
|
|
||||||
struct netns_xt xt;
|
|
||||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
|
||||||
struct netns_ct ct;
|
|
||||||
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
|
|
||||||
index e19f365..c7c9f39 100644
|
|
||||||
--- a/net/netfilter/core.c
|
|
||||||
+++ b/net/netfilter/core.c
|
|
||||||
@@ -266,25 +266,44 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct)
|
|
||||||
EXPORT_SYMBOL(nf_conntrack_destroy);
|
|
||||||
#endif /* CONFIG_NF_CONNTRACK */
|
|
||||||
|
|
||||||
+static int __net_init netfilter_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ net->proc_net_netfilter = proc_net_mkdir(net, "netfilter",
|
|
||||||
+ net->proc_net);
|
|
||||||
+ if (!net->proc_net_netfilter) {
|
|
||||||
+ pr_err("%s: cannot create netfilter proc entry\n", __func__);
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit netfilter_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
-struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
-EXPORT_SYMBOL(proc_net_netfilter);
|
|
||||||
+ proc_net_remove(net, "netfilter");
|
|
||||||
#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_net_ops = {
|
|
||||||
+ .init = netfilter_net_init,
|
|
||||||
+ .exit = netfilter_net_exit,
|
|
||||||
+};
|
|
||||||
|
|
||||||
void __init netfilter_init(void)
|
|
||||||
{
|
|
||||||
int i, h;
|
|
||||||
+
|
|
||||||
+ if (register_pernet_subsys(&netfilter_net_ops))
|
|
||||||
+ panic("%s: failed to register per netns operations", __func__);
|
|
||||||
+
|
|
||||||
for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) {
|
|
||||||
for (h = 0; h < NF_MAX_HOOKS; h++)
|
|
||||||
INIT_LIST_HEAD(&nf_hooks[i][h]);
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- proc_net_netfilter = proc_mkdir("netfilter", init_net.proc_net);
|
|
||||||
- if (!proc_net_netfilter)
|
|
||||||
- panic("cannot create netfilter proc entry");
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
if (netfilter_queue_init() < 0)
|
|
||||||
panic("cannot initialize nf_queue");
|
|
||||||
if (netfilter_log_init() < 0)
|
|
||||||
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
|
|
||||||
index 703fb26..4507932 100644
|
|
||||||
--- a/net/netfilter/nf_log.c
|
|
||||||
+++ b/net/netfilter/nf_log.c
|
|
||||||
@@ -290,14 +290,39 @@ static __init int netfilter_log_sysctl_init(void)
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_SYSCTL */
|
|
||||||
|
|
||||||
-int __init netfilter_log_init(void)
|
|
||||||
+static int __net_init netfilter_log_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
- int i, r;
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nf_log", S_IRUGO,
|
|
||||||
- proc_net_netfilter, &nflog_file_ops))
|
|
||||||
- return -1;
|
|
||||||
+ net->proc_net_netfilter, &nflog_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit netfilter_log_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nf_log", net->proc_net_netfilter);
|
|
||||||
#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_log_net_ops = {
|
|
||||||
+ .init = netfilter_log_net_init,
|
|
||||||
+ .exit = netfilter_log_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+int __init netfilter_log_init(void)
|
|
||||||
+{
|
|
||||||
+ int i, r;
|
|
||||||
+
|
|
||||||
+ r = register_pernet_subsys(&netfilter_log_net_ops);
|
|
||||||
+ if (r) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return r;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Errors will trigger panic, unroll on error is unnecessary. */
|
|
||||||
r = netfilter_log_sysctl_init();
|
|
||||||
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
|
|
||||||
index ce60cf0..288c6f5 100644
|
|
||||||
--- a/net/netfilter/nf_queue.c
|
|
||||||
+++ b/net/netfilter/nf_queue.c
|
|
||||||
@@ -407,14 +407,37 @@ static const struct file_operations nfqueue_file_ops = {
|
|
||||||
};
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
-
|
|
||||||
-int __init netfilter_queue_init(void)
|
|
||||||
+static int __net_init netfilter_queue_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nf_queue", S_IRUGO,
|
|
||||||
- proc_net_netfilter, &nfqueue_file_ops))
|
|
||||||
- return -1;
|
|
||||||
+ net->proc_net_netfilter, &nfqueue_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
#endif
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void __net_exit netfilter_queue_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nf_queue", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_queue_net_ops = {
|
|
||||||
+ .init = netfilter_queue_net_init,
|
|
||||||
+ .exit = netfilter_queue_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+int __init netfilter_queue_init(void)
|
|
||||||
+{
|
|
||||||
+ int err;
|
|
||||||
+
|
|
||||||
+ err = register_pernet_subsys(&netfilter_queue_net_ops);
|
|
||||||
+ if (err)
|
|
||||||
+ pr_err("%s: cannot initialize per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+
|
|
||||||
+ return err;
|
|
||||||
+}
|
|
||||||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
|
|
||||||
index bbc1d91..e5c1731 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_log.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_log.c
|
|
||||||
@@ -966,9 +966,39 @@ static const struct file_operations nful_file_ops = {
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
+static int __net_init nfnetlink_log_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ if (!proc_create("nfnetlink_log", 0440,
|
|
||||||
+ net->proc_net_netfilter, &nful_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit nfnetlink_log_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nfnetlink_log", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations nfnetlink_log_net_ops = {
|
|
||||||
+ .init = nfnetlink_log_net_init,
|
|
||||||
+ .exit = nfnetlink_log_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __init nfnetlink_log_init(void)
|
|
||||||
{
|
|
||||||
- int i, status = -ENOMEM;
|
|
||||||
+ int i, status;
|
|
||||||
+
|
|
||||||
+ status = register_pernet_subsys(&nfnetlink_log_net_ops);
|
|
||||||
+ if (status) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return status;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
@@ -991,17 +1021,8 @@ static int __init nfnetlink_log_init(void)
|
|
||||||
goto cleanup_subsys;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- if (!proc_create("nfnetlink_log", 0440,
|
|
||||||
- proc_net_netfilter, &nful_file_ops))
|
|
||||||
- goto cleanup_logger;
|
|
||||||
-#endif
|
|
||||||
return status;
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-cleanup_logger:
|
|
||||||
- nf_log_unregister(&nfulnl_logger);
|
|
||||||
-#endif
|
|
||||||
cleanup_subsys:
|
|
||||||
nfnetlink_subsys_unregister(&nfulnl_subsys);
|
|
||||||
cleanup_netlink_notifier:
|
|
||||||
@@ -1012,9 +1033,6 @@ cleanup_netlink_notifier:
|
|
||||||
static void __exit nfnetlink_log_fini(void)
|
|
||||||
{
|
|
||||||
nf_log_unregister(&nfulnl_logger);
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- remove_proc_entry("nfnetlink_log", proc_net_netfilter);
|
|
||||||
-#endif
|
|
||||||
nfnetlink_subsys_unregister(&nfulnl_subsys);
|
|
||||||
netlink_unregister_notifier(&nfulnl_rtnl_notifier);
|
|
||||||
}
|
|
||||||
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
|
|
||||||
index 4162437..add33dc 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_queue.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_queue.c
|
|
||||||
@@ -982,9 +982,39 @@ static const struct file_operations nfqnl_file_ops = {
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
+static int __net_init nfnetlink_queue_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
+ net->proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit nfnetlink_queue_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nfnetlink_queue", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations nfnetlink_queue_net_ops = {
|
|
||||||
+ .init = nfnetlink_queue_net_init,
|
|
||||||
+ .exit = nfnetlink_queue_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __init nfnetlink_queue_init(void)
|
|
||||||
{
|
|
||||||
- int i, status = -ENOMEM;
|
|
||||||
+ int i, status;
|
|
||||||
+
|
|
||||||
+ status = register_pernet_subsys(&nfnetlink_queue_net_ops);
|
|
||||||
+ if (status) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return status;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
@@ -996,19 +1026,9 @@ static int __init nfnetlink_queue_init(void)
|
|
||||||
goto cleanup_netlink_notifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
- proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
- goto cleanup_subsys;
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
register_netdevice_notifier(&nfqnl_dev_notifier);
|
|
||||||
return status;
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-cleanup_subsys:
|
|
||||||
- nfnetlink_subsys_unregister(&nfqnl_subsys);
|
|
||||||
-#endif
|
|
||||||
cleanup_netlink_notifier:
|
|
||||||
netlink_unregister_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
return status;
|
|
||||||
@@ -1018,9 +1038,6 @@ static void __exit nfnetlink_queue_fini(void)
|
|
||||||
{
|
|
||||||
nf_unregister_queue_handlers(&nfqh);
|
|
||||||
unregister_netdevice_notifier(&nfqnl_dev_notifier);
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- remove_proc_entry("nfnetlink_queue", proc_net_netfilter);
|
|
||||||
-#endif
|
|
||||||
nfnetlink_subsys_unregister(&nfqnl_subsys);
|
|
||||||
netlink_unregister_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
|
|
||||||
--
|
|
||||||
1.7.10.4
|
|
||||||
|
|
|
@ -1,494 +0,0 @@
|
||||||
From 1ede1963c84e15359d4b5bf7fb01587d90bcf1d4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Thu, 26 Jul 2012 23:58:38 -0700
|
|
||||||
Subject: [PATCH 2/2] netfilter: nfnetlink_queue: Add netns support.
|
|
||||||
|
|
||||||
Make nfnetlink_queue network namespace aware including a per-netns
|
|
||||||
/proc/net/netfilter/nfnetlink_queue file.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
include/net/net_namespace.h | 6 ++
|
|
||||||
include/net/netfilter/nf_queue.h | 3 +-
|
|
||||||
include/net/netns/nfqnl.h | 14 ++++
|
|
||||||
net/netfilter/nf_queue.c | 12 +++-
|
|
||||||
net/netfilter/nfnetlink_queue.c | 136 +++++++++++++++++++-------------------
|
|
||||||
5 files changed, 101 insertions(+), 70 deletions(-)
|
|
||||||
create mode 100644 include/net/netns/nfqnl.h
|
|
||||||
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index 449fc8e..c4229f1 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -21,6 +21,9 @@
|
|
||||||
#include <net/netns/conntrack.h>
|
|
||||||
#endif
|
|
||||||
#include <net/netns/xfrm.h>
|
|
||||||
+#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
|
||||||
+#include <net/netns/nfqnl.h>
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
struct proc_dir_entry;
|
|
||||||
struct net_device;
|
|
||||||
@@ -95,6 +98,9 @@ struct net {
|
|
||||||
#endif
|
|
||||||
struct sock *nfnl;
|
|
||||||
struct sock *nfnl_stash;
|
|
||||||
+#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
|
||||||
+ struct netns_nfqnl nfqnl;
|
|
||||||
+#endif
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_WEXT_CORE
|
|
||||||
struct sk_buff_head wext_nlevents;
|
|
||||||
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
|
|
||||||
index 252fd10..3e5bde8 100644
|
|
||||||
--- a/include/net/netfilter/nf_queue.h
|
|
||||||
+++ b/include/net/netfilter/nf_queue.h
|
|
||||||
@@ -19,7 +19,8 @@ struct nf_queue_entry {
|
|
||||||
|
|
||||||
/* Packet queuing */
|
|
||||||
struct nf_queue_handler {
|
|
||||||
- int (*outfn)(struct nf_queue_entry *entry,
|
|
||||||
+ int (*outfn)(struct net *net,
|
|
||||||
+ struct nf_queue_entry *entry,
|
|
||||||
unsigned int queuenum);
|
|
||||||
char *name;
|
|
||||||
};
|
|
||||||
diff --git a/include/net/netns/nfqnl.h b/include/net/netns/nfqnl.h
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..0fe7fbe
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/include/net/netns/nfqnl.h
|
|
||||||
@@ -0,0 +1,14 @@
|
|
||||||
+#ifndef __NETNS_NFQNL_H
|
|
||||||
+#define __NETNS_NFQNL_H
|
|
||||||
+
|
|
||||||
+#include <linux/spinlock.h>
|
|
||||||
+#include <linux/list.h>
|
|
||||||
+
|
|
||||||
+#define NFQNL_INSTANCE_BUCKETS 16
|
|
||||||
+
|
|
||||||
+struct netns_nfqnl {
|
|
||||||
+ spinlock_t instances_lock;
|
|
||||||
+ struct hlist_head instance_table[NFQNL_INSTANCE_BUCKETS];
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+#endif /* __NETNS_NFQNL_H */
|
|
||||||
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
|
|
||||||
index 288c6f5..3cb8733 100644
|
|
||||||
--- a/net/netfilter/nf_queue.c
|
|
||||||
+++ b/net/netfilter/nf_queue.c
|
|
||||||
@@ -133,6 +133,16 @@ static int __nf_queue(struct sk_buff *skb,
|
|
||||||
#endif
|
|
||||||
const struct nf_afinfo *afinfo;
|
|
||||||
const struct nf_queue_handler *qh;
|
|
||||||
+ struct net *net;
|
|
||||||
+
|
|
||||||
+ if (indev)
|
|
||||||
+ net = dev_net(indev);
|
|
||||||
+ else if (skb->sk)
|
|
||||||
+ net = sock_net(skb->sk);
|
|
||||||
+ else if (outdev)
|
|
||||||
+ net = dev_net(outdev);
|
|
||||||
+ else
|
|
||||||
+ return status;
|
|
||||||
|
|
||||||
/* QUEUE == DROP if no one is waiting, to be safe. */
|
|
||||||
rcu_read_lock();
|
|
||||||
@@ -185,7 +195,7 @@ static int __nf_queue(struct sk_buff *skb,
|
|
||||||
#endif
|
|
||||||
skb_dst_force(skb);
|
|
||||||
afinfo->saveroute(skb, entry);
|
|
||||||
- status = qh->outfn(entry, queuenum);
|
|
||||||
+ status = qh->outfn(net, entry, queuenum);
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
|
|
||||||
index add33dc..43c50bb 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_queue.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_queue.c
|
|
||||||
@@ -64,24 +64,19 @@ struct nfqnl_instance {
|
|
||||||
|
|
||||||
typedef int (*nfqnl_cmpfn)(struct nf_queue_entry *, unsigned long);
|
|
||||||
|
|
||||||
-static DEFINE_SPINLOCK(instances_lock);
|
|
||||||
-
|
|
||||||
-#define INSTANCE_BUCKETS 16
|
|
||||||
-static struct hlist_head instance_table[INSTANCE_BUCKETS] __read_mostly;
|
|
||||||
-
|
|
||||||
static inline u_int8_t instance_hashfn(u_int16_t queue_num)
|
|
||||||
{
|
|
||||||
- return ((queue_num >> 8) | queue_num) % INSTANCE_BUCKETS;
|
|
||||||
+ return ((queue_num >> 8) | queue_num) % NFQNL_INSTANCE_BUCKETS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nfqnl_instance *
|
|
||||||
-instance_lookup(u_int16_t queue_num)
|
|
||||||
+instance_lookup(struct net *net, u_int16_t queue_num)
|
|
||||||
{
|
|
||||||
struct hlist_head *head;
|
|
||||||
struct hlist_node *pos;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
|
|
||||||
- head = &instance_table[instance_hashfn(queue_num)];
|
|
||||||
+ head = &net->nfqnl.instance_table[instance_hashfn(queue_num)];
|
|
||||||
hlist_for_each_entry_rcu(inst, pos, head, hlist) {
|
|
||||||
if (inst->queue_num == queue_num)
|
|
||||||
return inst;
|
|
||||||
@@ -90,14 +85,14 @@ instance_lookup(u_int16_t queue_num)
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nfqnl_instance *
|
|
||||||
-instance_create(u_int16_t queue_num, int pid)
|
|
||||||
+instance_create(struct net *net, u_int16_t queue_num, int pid)
|
|
||||||
{
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
unsigned int h;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- if (instance_lookup(queue_num)) {
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
+ if (instance_lookup(net, queue_num)) {
|
|
||||||
err = -EEXIST;
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
@@ -122,16 +117,16 @@ instance_create(u_int16_t queue_num, int pid)
|
|
||||||
}
|
|
||||||
|
|
||||||
h = instance_hashfn(queue_num);
|
|
||||||
- hlist_add_head_rcu(&inst->hlist, &instance_table[h]);
|
|
||||||
+ hlist_add_head_rcu(&inst->hlist, &net->nfqnl.instance_table[h]);
|
|
||||||
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
|
|
||||||
return inst;
|
|
||||||
|
|
||||||
out_free:
|
|
||||||
kfree(inst);
|
|
||||||
out_unlock:
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
return ERR_PTR(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -157,11 +152,11 @@ __instance_destroy(struct nfqnl_instance *inst)
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
-instance_destroy(struct nfqnl_instance *inst)
|
|
||||||
+instance_destroy(struct net *net, struct nfqnl_instance *inst)
|
|
||||||
{
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
__instance_destroy(inst);
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
@@ -400,7 +395,8 @@ nla_put_failure:
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
+nfqnl_enqueue_packet(struct net *net, struct nf_queue_entry *entry,
|
|
||||||
+ unsigned int queuenum)
|
|
||||||
{
|
|
||||||
struct sk_buff *nskb;
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
@@ -408,7 +404,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
__be32 *packet_id_ptr;
|
|
||||||
|
|
||||||
/* rcu_read_lock()ed by nf_hook_slow() */
|
|
||||||
- queue = instance_lookup(queuenum);
|
|
||||||
+ queue = instance_lookup(net, queuenum);
|
|
||||||
if (!queue) {
|
|
||||||
err = -ESRCH;
|
|
||||||
goto err_out;
|
|
||||||
@@ -440,7 +436,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
*packet_id_ptr = htonl(entry->id);
|
|
||||||
|
|
||||||
/* nfnetlink_unicast will either free the nskb or add it to a socket */
|
|
||||||
- err = nfnetlink_unicast(nskb, &init_net, queue->peer_pid, MSG_DONTWAIT);
|
|
||||||
+ err = nfnetlink_unicast(nskb, net, queue->peer_pid, MSG_DONTWAIT);
|
|
||||||
if (err < 0) {
|
|
||||||
queue->queue_user_dropped++;
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -549,16 +545,16 @@ dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
|
|
||||||
/* drop all packets with either indev or outdev == ifindex from all queue
|
|
||||||
* instances */
|
|
||||||
static void
|
|
||||||
-nfqnl_dev_drop(int ifindex)
|
|
||||||
+nfqnl_dev_drop(struct net *net, int ifindex)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++) {
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++) {
|
|
||||||
struct hlist_node *tmp;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
- struct hlist_head *head = &instance_table[i];
|
|
||||||
+ struct hlist_head *head = &net->nfqnl.instance_table[i];
|
|
||||||
|
|
||||||
hlist_for_each_entry_rcu(inst, tmp, head, hlist)
|
|
||||||
nfqnl_flush(inst, dev_cmp, ifindex);
|
|
||||||
@@ -575,12 +571,9 @@ nfqnl_rcv_dev_event(struct notifier_block *this,
|
|
||||||
{
|
|
||||||
struct net_device *dev = ptr;
|
|
||||||
|
|
||||||
- if (!net_eq(dev_net(dev), &init_net))
|
|
||||||
- return NOTIFY_DONE;
|
|
||||||
-
|
|
||||||
/* Drop any packets associated with the downed device */
|
|
||||||
if (event == NETDEV_DOWN)
|
|
||||||
- nfqnl_dev_drop(dev->ifindex);
|
|
||||||
+ nfqnl_dev_drop(dev_net(dev), dev->ifindex);
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -598,19 +591,19 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* destroy all instances for this pid */
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++) {
|
|
||||||
+ spin_lock(&n->net->nfqnl.instances_lock);
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++) {
|
|
||||||
struct hlist_node *tmp, *t2;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
- struct hlist_head *head = &instance_table[i];
|
|
||||||
+ struct hlist_head *head =
|
|
||||||
+ &n->net->nfqnl.instance_table[i];
|
|
||||||
|
|
||||||
hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
|
|
||||||
- if ((n->net == &init_net) &&
|
|
||||||
- (n->pid == inst->peer_pid))
|
|
||||||
+ if (n->pid == inst->peer_pid)
|
|
||||||
__instance_destroy(inst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&n->net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
@@ -630,11 +623,12 @@ static const struct nla_policy nfqa_verdict_batch_policy[NFQA_MAX+1] = {
|
|
||||||
[NFQA_MARK] = { .type = NLA_U32 },
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct nfqnl_instance *verdict_instance_lookup(u16 queue_num, int nlpid)
|
|
||||||
+static struct nfqnl_instance *verdict_instance_lookup(struct net *net,
|
|
||||||
+ u16 queue_num, int nlpid)
|
|
||||||
{
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (!queue)
|
|
||||||
return ERR_PTR(-ENODEV);
|
|
||||||
|
|
||||||
@@ -678,7 +672,8 @@ nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
LIST_HEAD(batch_list);
|
|
||||||
u16 queue_num = ntohs(nfmsg->res_id);
|
|
||||||
|
|
||||||
- queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid);
|
|
||||||
+ queue = verdict_instance_lookup(sock_net(ctnl), queue_num,
|
|
||||||
+ NETLINK_CB(skb).pid);
|
|
||||||
if (IS_ERR(queue))
|
|
||||||
return PTR_ERR(queue);
|
|
||||||
|
|
||||||
@@ -723,11 +718,12 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
unsigned int verdict;
|
|
||||||
struct nf_queue_entry *entry;
|
|
||||||
+ struct net *net = sock_net(ctnl);
|
|
||||||
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (!queue)
|
|
||||||
|
|
||||||
- queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid);
|
|
||||||
+ queue = verdict_instance_lookup(net, queue_num, NETLINK_CB(skb).pid);
|
|
||||||
if (IS_ERR(queue))
|
|
||||||
return PTR_ERR(queue);
|
|
||||||
|
|
||||||
@@ -782,6 +778,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
struct nfqnl_msg_config_cmd *cmd = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
+ struct net *net = sock_net(ctnl);
|
|
||||||
|
|
||||||
if (nfqa[NFQA_CFG_CMD]) {
|
|
||||||
cmd = nla_data(nfqa[NFQA_CFG_CMD]);
|
|
||||||
@@ -798,7 +795,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
}
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (queue && queue->peer_pid != NETLINK_CB(skb).pid) {
|
|
||||||
ret = -EPERM;
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -811,7 +808,8 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
ret = -EBUSY;
|
|
||||||
goto err_out_unlock;
|
|
||||||
}
|
|
||||||
- queue = instance_create(queue_num, NETLINK_CB(skb).pid);
|
|
||||||
+ queue = instance_create(net, queue_num,
|
|
||||||
+ NETLINK_CB(skb).pid);
|
|
||||||
if (IS_ERR(queue)) {
|
|
||||||
ret = PTR_ERR(queue);
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -822,7 +820,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto err_out_unlock;
|
|
||||||
}
|
|
||||||
- instance_destroy(queue);
|
|
||||||
+ instance_destroy(net, queue);
|
|
||||||
break;
|
|
||||||
case NFQNL_CFG_CMD_PF_BIND:
|
|
||||||
case NFQNL_CFG_CMD_PF_UNBIND:
|
|
||||||
@@ -886,65 +884,64 @@ static const struct nfnetlink_subsystem nfqnl_subsys = {
|
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
struct iter_state {
|
|
||||||
+ struct seq_net_private p;
|
|
||||||
unsigned int bucket;
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct hlist_node *get_first(struct seq_file *seq)
|
|
||||||
+static struct hlist_node *get_first(struct net *net, struct iter_state *st)
|
|
||||||
{
|
|
||||||
- struct iter_state *st = seq->private;
|
|
||||||
-
|
|
||||||
if (!st)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) {
|
|
||||||
- if (!hlist_empty(&instance_table[st->bucket]))
|
|
||||||
- return instance_table[st->bucket].first;
|
|
||||||
+ for (st->bucket = 0; st->bucket < NFQNL_INSTANCE_BUCKETS; st->bucket++) {
|
|
||||||
+ if (!hlist_empty(&net->nfqnl.instance_table[st->bucket]))
|
|
||||||
+ return net->nfqnl.instance_table[st->bucket].first;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct hlist_node *get_next(struct seq_file *seq, struct hlist_node *h)
|
|
||||||
+static struct hlist_node *get_next(struct net *net, struct iter_state *st,
|
|
||||||
+ struct hlist_node *h)
|
|
||||||
{
|
|
||||||
- struct iter_state *st = seq->private;
|
|
||||||
-
|
|
||||||
h = h->next;
|
|
||||||
while (!h) {
|
|
||||||
- if (++st->bucket >= INSTANCE_BUCKETS)
|
|
||||||
+ if (++st->bucket >= NFQNL_INSTANCE_BUCKETS)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- h = instance_table[st->bucket].first;
|
|
||||||
+ h = net->nfqnl.instance_table[st->bucket].first;
|
|
||||||
}
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct hlist_node *get_idx(struct seq_file *seq, loff_t pos)
|
|
||||||
+static struct hlist_node *get_idx(struct net *net, struct iter_state *st,
|
|
||||||
+ loff_t pos)
|
|
||||||
{
|
|
||||||
struct hlist_node *head;
|
|
||||||
- head = get_first(seq);
|
|
||||||
+ head = get_first(net, st);
|
|
||||||
|
|
||||||
if (head)
|
|
||||||
- while (pos && (head = get_next(seq, head)))
|
|
||||||
+ while (pos && (head = get_next(net, st, head)))
|
|
||||||
pos--;
|
|
||||||
return pos ? NULL : head;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *seq_start(struct seq_file *seq, loff_t *pos)
|
|
||||||
- __acquires(instances_lock)
|
|
||||||
{
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- return get_idx(seq, *pos);
|
|
||||||
+ struct net *net = seq_file_net(seq);
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
+ return get_idx(net, seq->private, *pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
|
|
||||||
{
|
|
||||||
(*pos)++;
|
|
||||||
- return get_next(s, v);
|
|
||||||
+ return get_next(seq_file_net(s), s->private, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void seq_stop(struct seq_file *s, void *v)
|
|
||||||
- __releases(instances_lock)
|
|
||||||
{
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ struct net *net = seq_file_net(s);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int seq_show(struct seq_file *s, void *v)
|
|
||||||
@@ -968,8 +965,8 @@ static const struct seq_operations nfqnl_seq_ops = {
|
|
||||||
|
|
||||||
static int nfqnl_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
- return seq_open_private(file, &nfqnl_seq_ops,
|
|
||||||
- sizeof(struct iter_state));
|
|
||||||
+ return seq_open_net(inode, file, &nfqnl_seq_ops,
|
|
||||||
+ sizeof(struct iter_state));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations nfqnl_file_ops = {
|
|
||||||
@@ -977,13 +974,19 @@ static const struct file_operations nfqnl_file_ops = {
|
|
||||||
.open = nfqnl_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
- .release = seq_release_private,
|
|
||||||
+ .release = seq_release_net,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
static int __net_init nfnetlink_queue_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ spin_lock_init(&net->nfqnl.instances_lock);
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++)
|
|
||||||
+ INIT_HLIST_HEAD(&net->nfqnl.instance_table[i]);
|
|
||||||
+
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
net->proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
@@ -1007,7 +1010,7 @@ static struct pernet_operations nfnetlink_queue_net_ops = {
|
|
||||||
|
|
||||||
static int __init nfnetlink_queue_init(void)
|
|
||||||
{
|
|
||||||
- int i, status;
|
|
||||||
+ int status;
|
|
||||||
|
|
||||||
status = register_pernet_subsys(&nfnetlink_queue_net_ops);
|
|
||||||
if (status) {
|
|
||||||
@@ -1016,9 +1019,6 @@ static int __init nfnetlink_queue_init(void)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
- INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
-
|
|
||||||
netlink_register_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
status = nfnetlink_subsys_register(&nfqnl_subsys);
|
|
||||||
if (status < 0) {
|
|
||||||
--
|
|
||||||
1.7.10.4
|
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
VERSION := $(shell dpkg -l linux-source 2> /dev/null | \
|
|
||||||
awk '/^i/ {match($$3, "[0-9]+[.][0-9]+[.][0-9]+"); if (RSTART) print substr($$3, RSTART, RLENGTH)}')
|
|
||||||
TARBALL := /usr/src/linux-source-$(VERSION).tar.bz2
|
|
||||||
|
|
||||||
SUBVERSION := -core
|
|
||||||
REVISION := 1.0
|
|
||||||
|
|
||||||
PATCHDIR := patches
|
|
||||||
PATCHES := $(sort $(wildcard $(PATCHDIR)/*.patch))
|
|
||||||
|
|
||||||
CONFIG := config.core
|
|
||||||
|
|
||||||
DEPDEBS := linux-source kernel-package po-debconf gettext
|
|
||||||
|
|
||||||
CONCURRENCY_LEVEL := $(shell lscpu 2> /dev/null | \
|
|
||||||
awk '/^CPU\(s\)/ {print $$2}')
|
|
||||||
ifeq ($(strip $(CONCURRENCY_LEVEL)),)
|
|
||||||
CONCURRENCY_LEVEL := 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
MAINTAINER ?= $(shell id -nu)
|
|
||||||
EMAIL ?= $(MAINTAINER)@$(shell hostname -f)
|
|
||||||
|
|
||||||
MAKEKPKGFLAGS := --initrd --rootcmd fakeroot --us --uc \
|
|
||||||
--append-to-version $(SUBVERSION) --revision $(REVISION)
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
build: debcheck defaultconfig patch
|
|
||||||
export CONCURRENCY_LEVEL="$(CONCURRENCY_LEVEL)" \
|
|
||||||
KPKG_MAINTAINER="$(MAINTAINER)" KPKG_EMAIL="$(EMAIL)"; \
|
|
||||||
cd linux-source-$(VERSION) && \
|
|
||||||
if [ -f ../$(CONFIG) ]; then \
|
|
||||||
cat ../$(CONFIG) >> .config; \
|
|
||||||
fi && \
|
|
||||||
fakeroot make-kpkg $(MAKEKPKGFLAGS) binary-arch
|
|
||||||
|
|
||||||
.PHONY: debcheck
|
|
||||||
debcheck:
|
|
||||||
for d in $(DEPDEBS); do \
|
|
||||||
if ! dpkg-query -s $$d > /dev/null 2>&1; then \
|
|
||||||
echo ERROR: build dependency not installed: $$d >&2; \
|
|
||||||
exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
|
|
||||||
.PHONY: defaultconfig
|
|
||||||
defaultconfig: linux-source-$(VERSION)
|
|
||||||
export KPKG_MAINTAINER="$(MAINTAINER)" KPKG_EMAIL="$(EMAIL)"; \
|
|
||||||
cd linux-source-$(VERSION) && make-kpkg $(MAKEKPKGFLAGS) configure
|
|
||||||
|
|
||||||
.PHONY: patch
|
|
||||||
patch: linux-source-$(VERSION) patch-stamp
|
|
||||||
patch-stamp: $(PATCHES)
|
|
||||||
for p in $^; do \
|
|
||||||
if ! patch -d linux-source-$(VERSION) -p1 < $$p; then \
|
|
||||||
echo ERROR: applying patch failed: $$p >&2; \
|
|
||||||
exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
touch patch-stamp
|
|
||||||
|
|
||||||
.PHONY: source
|
|
||||||
source: linux-source-$(VERSION)
|
|
||||||
|
|
||||||
linux-source-$(VERSION): $(TARBALL)
|
|
||||||
tar -xjf $^
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -rf linux-source-$(VERSION) patch-stamp
|
|
|
@ -1 +0,0 @@
|
||||||
CONFIG_XFRM_STATISTICS=y
|
|
|
@ -1,29 +0,0 @@
|
||||||
From 1d992600b0f1962d0478df2083b76b1ceba50517 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Mon, 3 Jun 2013 18:29:42 -0700
|
|
||||||
Subject: [PATCH 1/3] Make network device ifindex sequential per network
|
|
||||||
namespace.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
net/core/dev.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/net/core/dev.c b/net/core/dev.c
|
|
||||||
index d592214..4b8da6e 100644
|
|
||||||
--- a/net/core/dev.c
|
|
||||||
+++ b/net/core/dev.c
|
|
||||||
@@ -6455,8 +6455,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
|
|
||||||
/* Actually switch the network namespace */
|
|
||||||
dev_net_set(dev, net);
|
|
||||||
|
|
||||||
- /* If there is an ifindex conflict assign a new one */
|
|
||||||
- if (__dev_get_by_index(net, dev->ifindex)) {
|
|
||||||
+ /* Assign a new ifindex */
|
|
||||||
+ {
|
|
||||||
int iflink = (dev->iflink == dev->ifindex);
|
|
||||||
dev->ifindex = dev_new_index(net);
|
|
||||||
if (iflink)
|
|
||||||
--
|
|
||||||
1.8.1.2
|
|
||||||
|
|
|
@ -1,307 +0,0 @@
|
||||||
From 433bc9e01b6a50db276c0b0d9dcd8bfcc2bc42f8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Mon, 3 Jun 2013 18:30:31 -0700
|
|
||||||
Subject: [PATCH 2/3] netfilter: Make the /proc/net/netfilter directory per
|
|
||||||
netns.
|
|
||||||
|
|
||||||
This allows subsystems to create per-netns entries.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
include/linux/netfilter.h | 5 ----
|
|
||||||
include/net/net_namespace.h | 3 +++
|
|
||||||
net/netfilter/core.c | 35 ++++++++++++++++++++-------
|
|
||||||
net/netfilter/nf_log.c | 33 ++++++++++++++++++++++----
|
|
||||||
net/netfilter/nfnetlink_log.c | 46 ++++++++++++++++++++++++------------
|
|
||||||
net/netfilter/nfnetlink_queue_core.c | 45 ++++++++++++++++++++++++-----------
|
|
||||||
6 files changed, 121 insertions(+), 46 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
|
|
||||||
index ee14284..0060fde 100644
|
|
||||||
--- a/include/linux/netfilter.h
|
|
||||||
+++ b/include/linux/netfilter.h
|
|
||||||
@@ -289,11 +289,6 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-#include <linux/proc_fs.h>
|
|
||||||
-extern struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
#else /* !CONFIG_NETFILTER */
|
|
||||||
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
|
|
||||||
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index de644bc..96b2242 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -94,6 +94,9 @@ struct net {
|
|
||||||
struct netns_dccp dccp;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NETFILTER
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
+#endif
|
|
||||||
struct netns_xt xt;
|
|
||||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
|
||||||
struct netns_ct ct;
|
|
||||||
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
|
|
||||||
index a9c488b..00e356d 100644
|
|
||||||
--- a/net/netfilter/core.c
|
|
||||||
+++ b/net/netfilter/core.c
|
|
||||||
@@ -276,25 +276,44 @@ void (*nf_nat_decode_session_hook)(struct sk_buff *, struct flowi *);
|
|
||||||
EXPORT_SYMBOL(nf_nat_decode_session_hook);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+static int __net_init netfilter_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ net->proc_net_netfilter = proc_net_mkdir(net, "netfilter",
|
|
||||||
+ net->proc_net);
|
|
||||||
+ if (!net->proc_net_netfilter) {
|
|
||||||
+ pr_err("%s: cannot create netfilter proc entry\n", __func__);
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit netfilter_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
-struct proc_dir_entry *proc_net_netfilter;
|
|
||||||
-EXPORT_SYMBOL(proc_net_netfilter);
|
|
||||||
+ proc_net_remove(net, "netfilter");
|
|
||||||
#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_net_ops = {
|
|
||||||
+ .init = netfilter_net_init,
|
|
||||||
+ .exit = netfilter_net_exit,
|
|
||||||
+};
|
|
||||||
|
|
||||||
void __init netfilter_init(void)
|
|
||||||
{
|
|
||||||
int i, h;
|
|
||||||
+
|
|
||||||
+ if (register_pernet_subsys(&netfilter_net_ops))
|
|
||||||
+ panic("%s: failed to register per netns operations", __func__);
|
|
||||||
+
|
|
||||||
for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) {
|
|
||||||
for (h = 0; h < NF_MAX_HOOKS; h++)
|
|
||||||
INIT_LIST_HEAD(&nf_hooks[i][h]);
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- proc_net_netfilter = proc_mkdir("netfilter", init_net.proc_net);
|
|
||||||
- if (!proc_net_netfilter)
|
|
||||||
- panic("cannot create netfilter proc entry");
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
if (netfilter_log_init() < 0)
|
|
||||||
panic("cannot initialize nf_log");
|
|
||||||
}
|
|
||||||
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
|
|
||||||
index 9e31269..5f33072 100644
|
|
||||||
--- a/net/netfilter/nf_log.c
|
|
||||||
+++ b/net/netfilter/nf_log.c
|
|
||||||
@@ -290,14 +290,39 @@ static __init int netfilter_log_sysctl_init(void)
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_SYSCTL */
|
|
||||||
|
|
||||||
-int __init netfilter_log_init(void)
|
|
||||||
+static int __net_init netfilter_log_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
- int i, r;
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nf_log", S_IRUGO,
|
|
||||||
- proc_net_netfilter, &nflog_file_ops))
|
|
||||||
- return -1;
|
|
||||||
+ net->proc_net_netfilter, &nflog_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit netfilter_log_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nf_log", net->proc_net_netfilter);
|
|
||||||
#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations netfilter_log_net_ops = {
|
|
||||||
+ .init = netfilter_log_net_init,
|
|
||||||
+ .exit = netfilter_log_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+int __init netfilter_log_init(void)
|
|
||||||
+{
|
|
||||||
+ int i, r;
|
|
||||||
+
|
|
||||||
+ r = register_pernet_subsys(&netfilter_log_net_ops);
|
|
||||||
+ if (r) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return r;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Errors will trigger panic, unroll on error is unnecessary. */
|
|
||||||
r = netfilter_log_sysctl_init();
|
|
||||||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
|
|
||||||
index 92fd8ec..9571c43 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_log.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_log.c
|
|
||||||
@@ -986,9 +986,39 @@ static const struct file_operations nful_file_ops = {
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
+static int __net_init nfnetlink_log_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ if (!proc_create("nfnetlink_log", 0440,
|
|
||||||
+ net->proc_net_netfilter, &nful_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit nfnetlink_log_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nfnetlink_log", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations nfnetlink_log_net_ops = {
|
|
||||||
+ .init = nfnetlink_log_net_init,
|
|
||||||
+ .exit = nfnetlink_log_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __init nfnetlink_log_init(void)
|
|
||||||
{
|
|
||||||
- int i, status = -ENOMEM;
|
|
||||||
+ int i, status;
|
|
||||||
+
|
|
||||||
+ status = register_pernet_subsys(&nfnetlink_log_net_ops);
|
|
||||||
+ if (status) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return status;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
@@ -1011,19 +1041,8 @@ static int __init nfnetlink_log_init(void)
|
|
||||||
goto cleanup_subsys;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- if (!proc_create("nfnetlink_log", 0440,
|
|
||||||
- proc_net_netfilter, &nful_file_ops)) {
|
|
||||||
- status = -ENOMEM;
|
|
||||||
- goto cleanup_logger;
|
|
||||||
- }
|
|
||||||
-#endif
|
|
||||||
return status;
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-cleanup_logger:
|
|
||||||
- nf_log_unregister(&nfulnl_logger);
|
|
||||||
-#endif
|
|
||||||
cleanup_subsys:
|
|
||||||
nfnetlink_subsys_unregister(&nfulnl_subsys);
|
|
||||||
cleanup_netlink_notifier:
|
|
||||||
@@ -1034,9 +1053,6 @@ cleanup_netlink_notifier:
|
|
||||||
static void __exit nfnetlink_log_fini(void)
|
|
||||||
{
|
|
||||||
nf_log_unregister(&nfulnl_logger);
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- remove_proc_entry("nfnetlink_log", proc_net_netfilter);
|
|
||||||
-#endif
|
|
||||||
nfnetlink_subsys_unregister(&nfulnl_subsys);
|
|
||||||
netlink_unregister_notifier(&nfulnl_rtnl_notifier);
|
|
||||||
}
|
|
||||||
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
|
|
||||||
index 3158d87..8f2d9bb 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_queue_core.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_queue_core.c
|
|
||||||
@@ -1048,9 +1048,39 @@ static const struct file_operations nfqnl_file_ops = {
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
+static int __net_init nfnetlink_queue_net_init(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
+ net->proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __net_exit nfnetlink_queue_net_exit(struct net *net)
|
|
||||||
+{
|
|
||||||
+#ifdef CONFIG_PROC_FS
|
|
||||||
+ remove_proc_entry("nfnetlink_queue", net->proc_net_netfilter);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct pernet_operations nfnetlink_queue_net_ops = {
|
|
||||||
+ .init = nfnetlink_queue_net_init,
|
|
||||||
+ .exit = nfnetlink_queue_net_exit,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __init nfnetlink_queue_init(void)
|
|
||||||
{
|
|
||||||
- int i, status = -ENOMEM;
|
|
||||||
+ int i, status;
|
|
||||||
+
|
|
||||||
+ status = register_pernet_subsys(&nfnetlink_queue_net_ops);
|
|
||||||
+ if (status) {
|
|
||||||
+ pr_err("%s: failed to register per netns operations\n",
|
|
||||||
+ __func__);
|
|
||||||
+ return status;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
@@ -1062,20 +1092,10 @@ static int __init nfnetlink_queue_init(void)
|
|
||||||
goto cleanup_netlink_notifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
- proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
- goto cleanup_subsys;
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
register_netdevice_notifier(&nfqnl_dev_notifier);
|
|
||||||
nf_register_queue_handler(&nfqh);
|
|
||||||
return status;
|
|
||||||
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
-cleanup_subsys:
|
|
||||||
- nfnetlink_subsys_unregister(&nfqnl_subsys);
|
|
||||||
-#endif
|
|
||||||
cleanup_netlink_notifier:
|
|
||||||
netlink_unregister_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
return status;
|
|
||||||
@@ -1085,9 +1105,6 @@ static void __exit nfnetlink_queue_fini(void)
|
|
||||||
{
|
|
||||||
nf_unregister_queue_handler();
|
|
||||||
unregister_netdevice_notifier(&nfqnl_dev_notifier);
|
|
||||||
-#ifdef CONFIG_PROC_FS
|
|
||||||
- remove_proc_entry("nfnetlink_queue", proc_net_netfilter);
|
|
||||||
-#endif
|
|
||||||
nfnetlink_subsys_unregister(&nfqnl_subsys);
|
|
||||||
netlink_unregister_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
|
|
||||||
--
|
|
||||||
1.8.1.2
|
|
||||||
|
|
|
@ -1,475 +0,0 @@
|
||||||
From 3d1c0bfef9d6ca43050e7a9077b46e0139ee1e1f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
Date: Mon, 3 Jun 2013 18:31:29 -0700
|
|
||||||
Subject: [PATCH 3/3] netfilter: nfnetlink_queue: Add netns support.
|
|
||||||
|
|
||||||
Make nfnetlink_queue network namespace aware including a per-netns
|
|
||||||
/proc/net/netfilter/nfnetlink_queue file.
|
|
||||||
|
|
||||||
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
|
|
||||||
---
|
|
||||||
include/net/net_namespace.h | 6 ++
|
|
||||||
include/net/netfilter/nf_queue.h | 3 +-
|
|
||||||
net/netfilter/nf_queue.c | 12 ++-
|
|
||||||
net/netfilter/nfnetlink_queue_core.c | 137 ++++++++++++++++++-----------------
|
|
||||||
4 files changed, 88 insertions(+), 70 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
|
|
||||||
index 96b2242..1af155b 100644
|
|
||||||
--- a/include/net/net_namespace.h
|
|
||||||
+++ b/include/net/net_namespace.h
|
|
||||||
@@ -22,6 +22,9 @@
|
|
||||||
#include <net/netns/conntrack.h>
|
|
||||||
#endif
|
|
||||||
#include <net/netns/xfrm.h>
|
|
||||||
+#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
|
||||||
+#include <net/netns/nfqnl.h>
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
struct user_namespace;
|
|
||||||
struct proc_dir_entry;
|
|
||||||
@@ -106,6 +109,9 @@ struct net {
|
|
||||||
#endif
|
|
||||||
struct sock *nfnl;
|
|
||||||
struct sock *nfnl_stash;
|
|
||||||
+#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
|
||||||
+ struct netns_nfqnl nfqnl;
|
|
||||||
+#endif
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_WEXT_CORE
|
|
||||||
struct sk_buff_head wext_nlevents;
|
|
||||||
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
|
|
||||||
index fb1c0be..484453d 100644
|
|
||||||
--- a/include/net/netfilter/nf_queue.h
|
|
||||||
+++ b/include/net/netfilter/nf_queue.h
|
|
||||||
@@ -19,7 +19,8 @@ struct nf_queue_entry {
|
|
||||||
|
|
||||||
/* Packet queuing */
|
|
||||||
struct nf_queue_handler {
|
|
||||||
- int (*outfn)(struct nf_queue_entry *entry,
|
|
||||||
+ int (*outfn)(struct net *net,
|
|
||||||
+ struct nf_queue_entry *entry,
|
|
||||||
unsigned int queuenum);
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
|
|
||||||
index d812c12..0d69be9 100644
|
|
||||||
--- a/net/netfilter/nf_queue.c
|
|
||||||
+++ b/net/netfilter/nf_queue.c
|
|
||||||
@@ -81,6 +81,16 @@ static int __nf_queue(struct sk_buff *skb,
|
|
||||||
#endif
|
|
||||||
const struct nf_afinfo *afinfo;
|
|
||||||
const struct nf_queue_handler *qh;
|
|
||||||
+ struct net *net;
|
|
||||||
+
|
|
||||||
+ if (indev)
|
|
||||||
+ net = dev_net(indev);
|
|
||||||
+ else if (skb->sk)
|
|
||||||
+ net = sock_net(skb->sk);
|
|
||||||
+ else if (outdev)
|
|
||||||
+ net = dev_net(outdev);
|
|
||||||
+ else
|
|
||||||
+ return status;
|
|
||||||
|
|
||||||
/* QUEUE == DROP if no one is waiting, to be safe. */
|
|
||||||
rcu_read_lock();
|
|
||||||
@@ -133,7 +143,7 @@ static int __nf_queue(struct sk_buff *skb,
|
|
||||||
#endif
|
|
||||||
skb_dst_force(skb);
|
|
||||||
afinfo->saveroute(skb, entry);
|
|
||||||
- status = qh->outfn(entry, queuenum);
|
|
||||||
+ status = qh->outfn(net, entry, queuenum);
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
|
|
||||||
index 8f2d9bb..1e0a830 100644
|
|
||||||
--- a/net/netfilter/nfnetlink_queue_core.c
|
|
||||||
+++ b/net/netfilter/nfnetlink_queue_core.c
|
|
||||||
@@ -66,24 +66,19 @@ struct nfqnl_instance {
|
|
||||||
|
|
||||||
typedef int (*nfqnl_cmpfn)(struct nf_queue_entry *, unsigned long);
|
|
||||||
|
|
||||||
-static DEFINE_SPINLOCK(instances_lock);
|
|
||||||
-
|
|
||||||
-#define INSTANCE_BUCKETS 16
|
|
||||||
-static struct hlist_head instance_table[INSTANCE_BUCKETS] __read_mostly;
|
|
||||||
-
|
|
||||||
static inline u_int8_t instance_hashfn(u_int16_t queue_num)
|
|
||||||
{
|
|
||||||
- return ((queue_num >> 8) | queue_num) % INSTANCE_BUCKETS;
|
|
||||||
+ return ((queue_num >> 8) | queue_num) % NFQNL_INSTANCE_BUCKETS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nfqnl_instance *
|
|
||||||
-instance_lookup(u_int16_t queue_num)
|
|
||||||
+instance_lookup(struct net *net, u_int16_t queue_num)
|
|
||||||
{
|
|
||||||
struct hlist_head *head;
|
|
||||||
struct hlist_node *pos;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
|
|
||||||
- head = &instance_table[instance_hashfn(queue_num)];
|
|
||||||
+ head = &net->nfqnl.instance_table[instance_hashfn(queue_num)];
|
|
||||||
hlist_for_each_entry_rcu(inst, pos, head, hlist) {
|
|
||||||
if (inst->queue_num == queue_num)
|
|
||||||
return inst;
|
|
||||||
@@ -92,14 +87,14 @@ instance_lookup(u_int16_t queue_num)
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nfqnl_instance *
|
|
||||||
-instance_create(u_int16_t queue_num, int portid)
|
|
||||||
+instance_create(struct net *net, u_int16_t queue_num, int portid)
|
|
||||||
{
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
unsigned int h;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- if (instance_lookup(queue_num)) {
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
+ if (instance_lookup(net, queue_num)) {
|
|
||||||
err = -EEXIST;
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
@@ -124,16 +119,16 @@ instance_create(u_int16_t queue_num, int portid)
|
|
||||||
}
|
|
||||||
|
|
||||||
h = instance_hashfn(queue_num);
|
|
||||||
- hlist_add_head_rcu(&inst->hlist, &instance_table[h]);
|
|
||||||
+ hlist_add_head_rcu(&inst->hlist, &net->nfqnl.instance_table[h]);
|
|
||||||
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
|
|
||||||
return inst;
|
|
||||||
|
|
||||||
out_free:
|
|
||||||
kfree(inst);
|
|
||||||
out_unlock:
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
return ERR_PTR(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -159,11 +154,11 @@ __instance_destroy(struct nfqnl_instance *inst)
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
-instance_destroy(struct nfqnl_instance *inst)
|
|
||||||
+instance_destroy(struct net *net, struct nfqnl_instance *inst)
|
|
||||||
{
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
__instance_destroy(inst);
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
@@ -417,7 +412,8 @@ nla_put_failure:
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
+nfqnl_enqueue_packet(struct net *net, struct nf_queue_entry *entry,
|
|
||||||
+ unsigned int queuenum)
|
|
||||||
{
|
|
||||||
struct sk_buff *nskb;
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
@@ -426,7 +422,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
int failopen = 0;
|
|
||||||
|
|
||||||
/* rcu_read_lock()ed by nf_hook_slow() */
|
|
||||||
- queue = instance_lookup(queuenum);
|
|
||||||
+ queue = instance_lookup(net, queuenum);
|
|
||||||
if (!queue) {
|
|
||||||
err = -ESRCH;
|
|
||||||
goto err_out;
|
|
||||||
@@ -463,7 +459,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
|
||||||
*packet_id_ptr = htonl(entry->id);
|
|
||||||
|
|
||||||
/* nfnetlink_unicast will either free the nskb or add it to a socket */
|
|
||||||
- err = nfnetlink_unicast(nskb, &init_net, queue->peer_portid, MSG_DONTWAIT);
|
|
||||||
+ err = nfnetlink_unicast(nskb, net, queue->peer_portid, MSG_DONTWAIT);
|
|
||||||
if (err < 0) {
|
|
||||||
queue->queue_user_dropped++;
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -576,16 +572,16 @@ dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
|
|
||||||
/* drop all packets with either indev or outdev == ifindex from all queue
|
|
||||||
* instances */
|
|
||||||
static void
|
|
||||||
-nfqnl_dev_drop(int ifindex)
|
|
||||||
+nfqnl_dev_drop(struct net *net, int ifindex)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++) {
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++) {
|
|
||||||
struct hlist_node *tmp;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
- struct hlist_head *head = &instance_table[i];
|
|
||||||
+ struct hlist_head *head = &net->nfqnl.instance_table[i];
|
|
||||||
|
|
||||||
hlist_for_each_entry_rcu(inst, tmp, head, hlist)
|
|
||||||
nfqnl_flush(inst, dev_cmp, ifindex);
|
|
||||||
@@ -602,12 +598,9 @@ nfqnl_rcv_dev_event(struct notifier_block *this,
|
|
||||||
{
|
|
||||||
struct net_device *dev = ptr;
|
|
||||||
|
|
||||||
- if (!net_eq(dev_net(dev), &init_net))
|
|
||||||
- return NOTIFY_DONE;
|
|
||||||
-
|
|
||||||
/* Drop any packets associated with the downed device */
|
|
||||||
if (event == NETDEV_DOWN)
|
|
||||||
- nfqnl_dev_drop(dev->ifindex);
|
|
||||||
+ nfqnl_dev_drop(dev_net(dev), dev->ifindex);
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -625,19 +618,19 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* destroy all instances for this portid */
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++) {
|
|
||||||
+ spin_lock(&n->net->nfqnl.instances_lock);
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++) {
|
|
||||||
struct hlist_node *tmp, *t2;
|
|
||||||
struct nfqnl_instance *inst;
|
|
||||||
- struct hlist_head *head = &instance_table[i];
|
|
||||||
+ struct hlist_head *head =
|
|
||||||
+ &n->net->nfqnl.instance_table[i];
|
|
||||||
|
|
||||||
hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
|
|
||||||
- if ((n->net == &init_net) &&
|
|
||||||
- (n->portid == inst->peer_portid))
|
|
||||||
+ if (n->portid == inst->peer_portid)
|
|
||||||
__instance_destroy(inst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ spin_unlock(&n->net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
@@ -658,11 +651,13 @@ static const struct nla_policy nfqa_verdict_batch_policy[NFQA_MAX+1] = {
|
|
||||||
[NFQA_MARK] = { .type = NLA_U32 },
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct nfqnl_instance *verdict_instance_lookup(u16 queue_num, int nlportid)
|
|
||||||
+static struct nfqnl_instance *verdict_instance_lookup(struct net *net,
|
|
||||||
+ u16 queue_num,
|
|
||||||
+ int nlportid)
|
|
||||||
{
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (!queue)
|
|
||||||
return ERR_PTR(-ENODEV);
|
|
||||||
|
|
||||||
@@ -706,7 +701,8 @@ nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
LIST_HEAD(batch_list);
|
|
||||||
u16 queue_num = ntohs(nfmsg->res_id);
|
|
||||||
|
|
||||||
- queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).portid);
|
|
||||||
+ queue = verdict_instance_lookup(sock_net(ctnl), queue_num,
|
|
||||||
+ NETLINK_CB(skb).portid);
|
|
||||||
if (IS_ERR(queue))
|
|
||||||
return PTR_ERR(queue);
|
|
||||||
|
|
||||||
@@ -751,13 +747,14 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
unsigned int verdict;
|
|
||||||
struct nf_queue_entry *entry;
|
|
||||||
+ struct net *net = sock_net(ctnl);
|
|
||||||
enum ip_conntrack_info uninitialized_var(ctinfo);
|
|
||||||
struct nf_conn *ct = NULL;
|
|
||||||
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (!queue)
|
|
||||||
|
|
||||||
- queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).portid);
|
|
||||||
+ queue = verdict_instance_lookup(net, queue_num, NETLINK_CB(skb).portid);
|
|
||||||
if (IS_ERR(queue))
|
|
||||||
return PTR_ERR(queue);
|
|
||||||
|
|
||||||
@@ -822,6 +819,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
struct nfqnl_instance *queue;
|
|
||||||
struct nfqnl_msg_config_cmd *cmd = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
+ struct net *net = sock_net(ctnl);
|
|
||||||
|
|
||||||
if (nfqa[NFQA_CFG_CMD]) {
|
|
||||||
cmd = nla_data(nfqa[NFQA_CFG_CMD]);
|
|
||||||
@@ -834,7 +832,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
}
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
- queue = instance_lookup(queue_num);
|
|
||||||
+ queue = instance_lookup(net, queue_num);
|
|
||||||
if (queue && queue->peer_portid != NETLINK_CB(skb).portid) {
|
|
||||||
ret = -EPERM;
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -847,7 +845,8 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
ret = -EBUSY;
|
|
||||||
goto err_out_unlock;
|
|
||||||
}
|
|
||||||
- queue = instance_create(queue_num, NETLINK_CB(skb).portid);
|
|
||||||
+ queue = instance_create(net, queue_num,
|
|
||||||
+ NETLINK_CB(skb).portid);
|
|
||||||
if (IS_ERR(queue)) {
|
|
||||||
ret = PTR_ERR(queue);
|
|
||||||
goto err_out_unlock;
|
|
||||||
@@ -858,7 +857,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto err_out_unlock;
|
|
||||||
}
|
|
||||||
- instance_destroy(queue);
|
|
||||||
+ instance_destroy(net, queue);
|
|
||||||
break;
|
|
||||||
case NFQNL_CFG_CMD_PF_BIND:
|
|
||||||
case NFQNL_CFG_CMD_PF_UNBIND:
|
|
||||||
@@ -952,65 +951,64 @@ static const struct nfnetlink_subsystem nfqnl_subsys = {
|
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
struct iter_state {
|
|
||||||
+ struct seq_net_private p;
|
|
||||||
unsigned int bucket;
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct hlist_node *get_first(struct seq_file *seq)
|
|
||||||
+static struct hlist_node *get_first(struct net *net, struct iter_state *st)
|
|
||||||
{
|
|
||||||
- struct iter_state *st = seq->private;
|
|
||||||
-
|
|
||||||
if (!st)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) {
|
|
||||||
- if (!hlist_empty(&instance_table[st->bucket]))
|
|
||||||
- return instance_table[st->bucket].first;
|
|
||||||
+ for (st->bucket = 0; st->bucket < NFQNL_INSTANCE_BUCKETS; st->bucket++) {
|
|
||||||
+ if (!hlist_empty(&net->nfqnl.instance_table[st->bucket]))
|
|
||||||
+ return net->nfqnl.instance_table[st->bucket].first;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct hlist_node *get_next(struct seq_file *seq, struct hlist_node *h)
|
|
||||||
+static struct hlist_node *get_next(struct net *net, struct iter_state *st,
|
|
||||||
+ struct hlist_node *h)
|
|
||||||
{
|
|
||||||
- struct iter_state *st = seq->private;
|
|
||||||
-
|
|
||||||
h = h->next;
|
|
||||||
while (!h) {
|
|
||||||
- if (++st->bucket >= INSTANCE_BUCKETS)
|
|
||||||
+ if (++st->bucket >= NFQNL_INSTANCE_BUCKETS)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- h = instance_table[st->bucket].first;
|
|
||||||
+ h = net->nfqnl.instance_table[st->bucket].first;
|
|
||||||
}
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct hlist_node *get_idx(struct seq_file *seq, loff_t pos)
|
|
||||||
+static struct hlist_node *get_idx(struct net *net, struct iter_state *st,
|
|
||||||
+ loff_t pos)
|
|
||||||
{
|
|
||||||
struct hlist_node *head;
|
|
||||||
- head = get_first(seq);
|
|
||||||
+ head = get_first(net, st);
|
|
||||||
|
|
||||||
if (head)
|
|
||||||
- while (pos && (head = get_next(seq, head)))
|
|
||||||
+ while (pos && (head = get_next(net, st, head)))
|
|
||||||
pos--;
|
|
||||||
return pos ? NULL : head;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *seq_start(struct seq_file *seq, loff_t *pos)
|
|
||||||
- __acquires(instances_lock)
|
|
||||||
{
|
|
||||||
- spin_lock(&instances_lock);
|
|
||||||
- return get_idx(seq, *pos);
|
|
||||||
+ struct net *net = seq_file_net(seq);
|
|
||||||
+ spin_lock(&net->nfqnl.instances_lock);
|
|
||||||
+ return get_idx(net, seq->private, *pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
|
|
||||||
{
|
|
||||||
(*pos)++;
|
|
||||||
- return get_next(s, v);
|
|
||||||
+ return get_next(seq_file_net(s), s->private, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void seq_stop(struct seq_file *s, void *v)
|
|
||||||
- __releases(instances_lock)
|
|
||||||
{
|
|
||||||
- spin_unlock(&instances_lock);
|
|
||||||
+ struct net *net = seq_file_net(s);
|
|
||||||
+ spin_unlock(&net->nfqnl.instances_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int seq_show(struct seq_file *s, void *v)
|
|
||||||
@@ -1034,8 +1032,8 @@ static const struct seq_operations nfqnl_seq_ops = {
|
|
||||||
|
|
||||||
static int nfqnl_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
- return seq_open_private(file, &nfqnl_seq_ops,
|
|
||||||
- sizeof(struct iter_state));
|
|
||||||
+ return seq_open_net(inode, file, &nfqnl_seq_ops,
|
|
||||||
+ sizeof(struct iter_state));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations nfqnl_file_ops = {
|
|
||||||
@@ -1043,13 +1041,19 @@ static const struct file_operations nfqnl_file_ops = {
|
|
||||||
.open = nfqnl_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
- .release = seq_release_private,
|
|
||||||
+ .release = seq_release_net,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* PROC_FS */
|
|
||||||
|
|
||||||
static int __net_init nfnetlink_queue_net_init(struct net *net)
|
|
||||||
{
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ spin_lock_init(&net->nfqnl.instances_lock);
|
|
||||||
+ for (i = 0; i < NFQNL_INSTANCE_BUCKETS; i++)
|
|
||||||
+ INIT_HLIST_HEAD(&net->nfqnl.instance_table[i]);
|
|
||||||
+
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
if (!proc_create("nfnetlink_queue", 0440,
|
|
||||||
net->proc_net_netfilter, &nfqnl_file_ops))
|
|
||||||
@@ -1073,7 +1077,7 @@ static struct pernet_operations nfnetlink_queue_net_ops = {
|
|
||||||
|
|
||||||
static int __init nfnetlink_queue_init(void)
|
|
||||||
{
|
|
||||||
- int i, status;
|
|
||||||
+ int status;
|
|
||||||
|
|
||||||
status = register_pernet_subsys(&nfnetlink_queue_net_ops);
|
|
||||||
if (status) {
|
|
||||||
@@ -1082,9 +1086,6 @@ static int __init nfnetlink_queue_init(void)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
- for (i = 0; i < INSTANCE_BUCKETS; i++)
|
|
||||||
- INIT_HLIST_HEAD(&instance_table[i]);
|
|
||||||
-
|
|
||||||
netlink_register_notifier(&nfqnl_rtnl_notifier);
|
|
||||||
status = nfnetlink_subsys_register(&nfqnl_subsys);
|
|
||||||
if (status < 0) {
|
|
||||||
--
|
|
||||||
1.8.1.2
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue