initial import (Boeing r1752, NRL r878)

This commit is contained in:
ahrenholz 2013-08-29 14:21:13 +00:00
commit f8f46d28be
394 changed files with 99738 additions and 0 deletions

View file

@ -0,0 +1,49 @@
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));

View file

@ -0,0 +1,51 @@
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)

View file

@ -0,0 +1,351 @@
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

View file

@ -0,0 +1,516 @@
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