aboutsummaryrefslogtreecommitdiffstats
path: root/net/key
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2008-11-25 20:58:07 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-25 20:58:07 -0500
commit3fa87a3210a24ae406c2ccd37a52585baeb21546 (patch)
treeb4fee69b1314d107659c7e2f22c00fa5a845fe68 /net/key
parent7c2776ee21a60e0d370538bd08b9ed82979f6e3a (diff)
netns PF_KEY: part 1
* netns boilerplate * keep per-netns socket list * keep per-netns number of sockets Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/key')
-rw-r--r--net/key/af_key.c88
1 files changed, 73 insertions, 15 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index ea7755ab7e6a..e80b26488bb3 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -27,6 +27,7 @@
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <net/net_namespace.h> 29#include <net/net_namespace.h>
30#include <net/netns/generic.h>
30#include <net/xfrm.h> 31#include <net/xfrm.h>
31 32
32#include <net/sock.h> 33#include <net/sock.h>
@@ -34,15 +35,16 @@
34#define _X2KEY(x) ((x) == XFRM_INF ? 0 : (x)) 35#define _X2KEY(x) ((x) == XFRM_INF ? 0 : (x))
35#define _KEY2X(x) ((x) == 0 ? XFRM_INF : (x)) 36#define _KEY2X(x) ((x) == 0 ? XFRM_INF : (x))
36 37
37 38static int pfkey_net_id;
38/* List of all pfkey sockets. */ 39struct netns_pfkey {
39static HLIST_HEAD(pfkey_table); 40 /* List of all pfkey sockets. */
41 struct hlist_head table;
42 atomic_t socks_nr;
43};
40static DECLARE_WAIT_QUEUE_HEAD(pfkey_table_wait); 44static DECLARE_WAIT_QUEUE_HEAD(pfkey_table_wait);
41static DEFINE_RWLOCK(pfkey_table_lock); 45static DEFINE_RWLOCK(pfkey_table_lock);
42static atomic_t pfkey_table_users = ATOMIC_INIT(0); 46static atomic_t pfkey_table_users = ATOMIC_INIT(0);
43 47
44static atomic_t pfkey_socks_nr = ATOMIC_INIT(0);
45
46struct pfkey_sock { 48struct pfkey_sock {
47 /* struct sock must be the first member of struct pfkey_sock */ 49 /* struct sock must be the first member of struct pfkey_sock */
48 struct sock sk; 50 struct sock sk;
@@ -89,6 +91,9 @@ static void pfkey_terminate_dump(struct pfkey_sock *pfk)
89 91
90static void pfkey_sock_destruct(struct sock *sk) 92static void pfkey_sock_destruct(struct sock *sk)
91{ 93{
94 struct net *net = sock_net(sk);
95 struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
96
92 pfkey_terminate_dump(pfkey_sk(sk)); 97 pfkey_terminate_dump(pfkey_sk(sk));
93 skb_queue_purge(&sk->sk_receive_queue); 98 skb_queue_purge(&sk->sk_receive_queue);
94 99
@@ -100,7 +105,7 @@ static void pfkey_sock_destruct(struct sock *sk)
100 WARN_ON(atomic_read(&sk->sk_rmem_alloc)); 105 WARN_ON(atomic_read(&sk->sk_rmem_alloc));
101 WARN_ON(atomic_read(&sk->sk_wmem_alloc)); 106 WARN_ON(atomic_read(&sk->sk_wmem_alloc));
102 107
103 atomic_dec(&pfkey_socks_nr); 108 atomic_dec(&net_pfkey->socks_nr);
104} 109}
105 110
106static void pfkey_table_grab(void) 111static void pfkey_table_grab(void)
@@ -151,8 +156,11 @@ static const struct proto_ops pfkey_ops;
151 156
152static void pfkey_insert(struct sock *sk) 157static void pfkey_insert(struct sock *sk)
153{ 158{
159 struct net *net = sock_net(sk);
160 struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
161
154 pfkey_table_grab(); 162 pfkey_table_grab();
155 sk_add_node(sk, &pfkey_table); 163 sk_add_node(sk, &net_pfkey->table);
156 pfkey_table_ungrab(); 164 pfkey_table_ungrab();
157} 165}
158 166
@@ -171,12 +179,10 @@ static struct proto key_proto = {
171 179
172static int pfkey_create(struct net *net, struct socket *sock, int protocol) 180static int pfkey_create(struct net *net, struct socket *sock, int protocol)
173{ 181{
182 struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
174 struct sock *sk; 183 struct sock *sk;
175 int err; 184 int err;
176 185
177 if (net != &init_net)
178 return -EAFNOSUPPORT;
179
180 if (!capable(CAP_NET_ADMIN)) 186 if (!capable(CAP_NET_ADMIN))
181 return -EPERM; 187 return -EPERM;
182 if (sock->type != SOCK_RAW) 188 if (sock->type != SOCK_RAW)
@@ -195,7 +201,7 @@ static int pfkey_create(struct net *net, struct socket *sock, int protocol)
195 sk->sk_family = PF_KEY; 201 sk->sk_family = PF_KEY;
196 sk->sk_destruct = pfkey_sock_destruct; 202 sk->sk_destruct = pfkey_sock_destruct;
197 203
198 atomic_inc(&pfkey_socks_nr); 204 atomic_inc(&net_pfkey->socks_nr);
199 205
200 pfkey_insert(sk); 206 pfkey_insert(sk);
201 207
@@ -257,6 +263,8 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
257static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, 263static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
258 int broadcast_flags, struct sock *one_sk) 264 int broadcast_flags, struct sock *one_sk)
259{ 265{
266 struct net *net = &init_net;
267 struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
260 struct sock *sk; 268 struct sock *sk;
261 struct hlist_node *node; 269 struct hlist_node *node;
262 struct sk_buff *skb2 = NULL; 270 struct sk_buff *skb2 = NULL;
@@ -269,7 +277,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
269 return -ENOMEM; 277 return -ENOMEM;
270 278
271 pfkey_lock_table(); 279 pfkey_lock_table();
272 sk_for_each(sk, node, &pfkey_table) { 280 sk_for_each(sk, node, &net_pfkey->table) {
273 struct pfkey_sock *pfk = pfkey_sk(sk); 281 struct pfkey_sock *pfk = pfkey_sk(sk);
274 int err2; 282 int err2;
275 283
@@ -2943,7 +2951,10 @@ static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c)
2943 2951
2944static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c) 2952static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c)
2945{ 2953{
2946 if (atomic_read(&pfkey_socks_nr) == 0) 2954 struct net *net = &init_net;
2955 struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
2956
2957 if (atomic_read(&net_pfkey->socks_nr) == 0)
2947 return 0; 2958 return 0;
2948 2959
2949 switch (c->event) { 2960 switch (c->event) {
@@ -3647,6 +3658,8 @@ static int pfkey_seq_show(struct seq_file *f, void *v)
3647 3658
3648static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos) 3659static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
3649{ 3660{
3661 struct net *net = &init_net;
3662 struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
3650 struct sock *s; 3663 struct sock *s;
3651 struct hlist_node *node; 3664 struct hlist_node *node;
3652 loff_t pos = *ppos; 3665 loff_t pos = *ppos;
@@ -3655,7 +3668,7 @@ static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
3655 if (pos == 0) 3668 if (pos == 0)
3656 return SEQ_START_TOKEN; 3669 return SEQ_START_TOKEN;
3657 3670
3658 sk_for_each(s, node, &pfkey_table) 3671 sk_for_each(s, node, &net_pfkey->table)
3659 if (pos-- == 1) 3672 if (pos-- == 1)
3660 return s; 3673 return s;
3661 3674
@@ -3664,9 +3677,12 @@ static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
3664 3677
3665static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos) 3678static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos)
3666{ 3679{
3680 struct net *net = &init_net;
3681 struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
3682
3667 ++*ppos; 3683 ++*ppos;
3668 return (v == SEQ_START_TOKEN) ? 3684 return (v == SEQ_START_TOKEN) ?
3669 sk_head(&pfkey_table) : 3685 sk_head(&net_pfkey->table) :
3670 sk_next((struct sock *)v); 3686 sk_next((struct sock *)v);
3671} 3687}
3672 3688
@@ -3731,8 +3747,45 @@ static struct xfrm_mgr pfkeyv2_mgr =
3731 .migrate = pfkey_send_migrate, 3747 .migrate = pfkey_send_migrate,
3732}; 3748};
3733 3749
3750static int __net_init pfkey_net_init(struct net *net)
3751{
3752 struct netns_pfkey *net_pfkey;
3753 int rv;
3754
3755 net_pfkey = kmalloc(sizeof(struct netns_pfkey), GFP_KERNEL);
3756 if (!net_pfkey) {
3757 rv = -ENOMEM;
3758 goto out_kmalloc;
3759 }
3760 INIT_HLIST_HEAD(&net_pfkey->table);
3761 atomic_set(&net_pfkey->socks_nr, 0);
3762 rv = net_assign_generic(net, pfkey_net_id, net_pfkey);
3763 if (rv < 0)
3764 goto out_assign;
3765 return 0;
3766
3767out_assign:
3768 kfree(net_pfkey);
3769out_kmalloc:
3770 return rv;
3771}
3772
3773static void __net_exit pfkey_net_exit(struct net *net)
3774{
3775 struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
3776
3777 BUG_ON(!hlist_empty(&net_pfkey->table));
3778 kfree(net_pfkey);
3779}
3780
3781static struct pernet_operations pfkey_net_ops = {
3782 .init = pfkey_net_init,
3783 .exit = pfkey_net_exit,
3784};
3785
3734static void __exit ipsec_pfkey_exit(void) 3786static void __exit ipsec_pfkey_exit(void)
3735{ 3787{
3788 unregister_pernet_gen_subsys(pfkey_net_id, &pfkey_net_ops);
3736 xfrm_unregister_km(&pfkeyv2_mgr); 3789 xfrm_unregister_km(&pfkeyv2_mgr);
3737 pfkey_exit_proc(); 3790 pfkey_exit_proc();
3738 sock_unregister(PF_KEY); 3791 sock_unregister(PF_KEY);
@@ -3755,8 +3808,13 @@ static int __init ipsec_pfkey_init(void)
3755 err = xfrm_register_km(&pfkeyv2_mgr); 3808 err = xfrm_register_km(&pfkeyv2_mgr);
3756 if (err != 0) 3809 if (err != 0)
3757 goto out_remove_proc_entry; 3810 goto out_remove_proc_entry;
3811 err = register_pernet_gen_subsys(&pfkey_net_id, &pfkey_net_ops);
3812 if (err != 0)
3813 goto out_xfrm_unregister_km;
3758out: 3814out:
3759 return err; 3815 return err;
3816out_xfrm_unregister_km:
3817 xfrm_unregister_km(&pfkeyv2_mgr);
3760out_remove_proc_entry: 3818out_remove_proc_entry:
3761 pfkey_exit_proc(); 3819 pfkey_exit_proc();
3762out_sock_unregister: 3820out_sock_unregister: