diff options
Diffstat (limited to 'net/key/af_key.c')
-rw-r--r-- | net/key/af_key.c | 217 |
1 files changed, 146 insertions, 71 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c index 5b22e011653b..f8bd8df5e257 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 | 38 | static int pfkey_net_id; | |
38 | /* List of all pfkey sockets. */ | 39 | struct netns_pfkey { |
39 | static HLIST_HEAD(pfkey_table); | 40 | /* List of all pfkey sockets. */ |
41 | struct hlist_head table; | ||
42 | atomic_t socks_nr; | ||
43 | }; | ||
40 | static DECLARE_WAIT_QUEUE_HEAD(pfkey_table_wait); | 44 | static DECLARE_WAIT_QUEUE_HEAD(pfkey_table_wait); |
41 | static DEFINE_RWLOCK(pfkey_table_lock); | 45 | static DEFINE_RWLOCK(pfkey_table_lock); |
42 | static atomic_t pfkey_table_users = ATOMIC_INIT(0); | 46 | static atomic_t pfkey_table_users = ATOMIC_INIT(0); |
43 | 47 | ||
44 | static atomic_t pfkey_socks_nr = ATOMIC_INIT(0); | ||
45 | |||
46 | struct pfkey_sock { | 48 | struct 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 | ||
90 | static void pfkey_sock_destruct(struct sock *sk) | 92 | static 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 | ||
106 | static void pfkey_table_grab(void) | 111 | static void pfkey_table_grab(void) |
@@ -151,8 +156,11 @@ static const struct proto_ops pfkey_ops; | |||
151 | 156 | ||
152 | static void pfkey_insert(struct sock *sk) | 157 | static 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 | ||
172 | static int pfkey_create(struct net *net, struct socket *sock, int protocol) | 180 | static 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 | ||
@@ -255,8 +261,10 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2, | |||
255 | #define BROADCAST_REGISTERED 2 | 261 | #define BROADCAST_REGISTERED 2 |
256 | #define BROADCAST_PROMISC_ONLY 4 | 262 | #define BROADCAST_PROMISC_ONLY 4 |
257 | static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, | 263 | static 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, |
265 | struct net *net) | ||
259 | { | 266 | { |
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 | ||
@@ -328,7 +336,7 @@ static int pfkey_do_dump(struct pfkey_sock *pfk) | |||
328 | hdr->sadb_msg_seq = 0; | 336 | hdr->sadb_msg_seq = 0; |
329 | hdr->sadb_msg_errno = rc; | 337 | hdr->sadb_msg_errno = rc; |
330 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, | 338 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, |
331 | &pfk->sk); | 339 | &pfk->sk, sock_net(&pfk->sk)); |
332 | pfk->dump.skb = NULL; | 340 | pfk->dump.skb = NULL; |
333 | } | 341 | } |
334 | 342 | ||
@@ -367,7 +375,7 @@ static int pfkey_error(struct sadb_msg *orig, int err, struct sock *sk) | |||
367 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / | 375 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / |
368 | sizeof(uint64_t)); | 376 | sizeof(uint64_t)); |
369 | 377 | ||
370 | pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk); | 378 | pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk, sock_net(sk)); |
371 | 379 | ||
372 | return 0; | 380 | return 0; |
373 | } | 381 | } |
@@ -645,7 +653,7 @@ int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, xfrm_address_t *xaddr) | |||
645 | xaddr); | 653 | xaddr); |
646 | } | 654 | } |
647 | 655 | ||
648 | static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs) | 656 | static struct xfrm_state *pfkey_xfrm_state_lookup(struct net *net, struct sadb_msg *hdr, void **ext_hdrs) |
649 | { | 657 | { |
650 | struct sadb_sa *sa; | 658 | struct sadb_sa *sa; |
651 | struct sadb_address *addr; | 659 | struct sadb_address *addr; |
@@ -683,7 +691,7 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void ** | |||
683 | if (!xaddr) | 691 | if (!xaddr) |
684 | return NULL; | 692 | return NULL; |
685 | 693 | ||
686 | return xfrm_state_lookup(xaddr, sa->sadb_sa_spi, proto, family); | 694 | return xfrm_state_lookup(net, xaddr, sa->sadb_sa_spi, proto, family); |
687 | } | 695 | } |
688 | 696 | ||
689 | #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) | 697 | #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) |
@@ -1058,7 +1066,8 @@ static inline struct sk_buff *pfkey_xfrm_state2msg_expire(struct xfrm_state *x, | |||
1058 | return __pfkey_xfrm_state2msg(x, 0, hsc); | 1066 | return __pfkey_xfrm_state2msg(x, 0, hsc); |
1059 | } | 1067 | } |
1060 | 1068 | ||
1061 | static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, | 1069 | static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net, |
1070 | struct sadb_msg *hdr, | ||
1062 | void **ext_hdrs) | 1071 | void **ext_hdrs) |
1063 | { | 1072 | { |
1064 | struct xfrm_state *x; | 1073 | struct xfrm_state *x; |
@@ -1122,7 +1131,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, | |||
1122 | (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) | 1131 | (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) |
1123 | return ERR_PTR(-EINVAL); | 1132 | return ERR_PTR(-EINVAL); |
1124 | 1133 | ||
1125 | x = xfrm_state_alloc(); | 1134 | x = xfrm_state_alloc(net); |
1126 | if (x == NULL) | 1135 | if (x == NULL) |
1127 | return ERR_PTR(-ENOBUFS); | 1136 | return ERR_PTR(-ENOBUFS); |
1128 | 1137 | ||
@@ -1298,6 +1307,7 @@ static int pfkey_reserved(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
1298 | 1307 | ||
1299 | static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 1308 | static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
1300 | { | 1309 | { |
1310 | struct net *net = sock_net(sk); | ||
1301 | struct sk_buff *resp_skb; | 1311 | struct sk_buff *resp_skb; |
1302 | struct sadb_x_sa2 *sa2; | 1312 | struct sadb_x_sa2 *sa2; |
1303 | struct sadb_address *saddr, *daddr; | 1313 | struct sadb_address *saddr, *daddr; |
@@ -1348,7 +1358,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
1348 | } | 1358 | } |
1349 | 1359 | ||
1350 | if (hdr->sadb_msg_seq) { | 1360 | if (hdr->sadb_msg_seq) { |
1351 | x = xfrm_find_acq_byseq(hdr->sadb_msg_seq); | 1361 | x = xfrm_find_acq_byseq(net, hdr->sadb_msg_seq); |
1352 | if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) { | 1362 | if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) { |
1353 | xfrm_state_put(x); | 1363 | xfrm_state_put(x); |
1354 | x = NULL; | 1364 | x = NULL; |
@@ -1356,7 +1366,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
1356 | } | 1366 | } |
1357 | 1367 | ||
1358 | if (!x) | 1368 | if (!x) |
1359 | x = xfrm_find_acq(mode, reqid, proto, xdaddr, xsaddr, 1, family); | 1369 | x = xfrm_find_acq(net, mode, reqid, proto, xdaddr, xsaddr, 1, family); |
1360 | 1370 | ||
1361 | if (x == NULL) | 1371 | if (x == NULL) |
1362 | return -ENOENT; | 1372 | return -ENOENT; |
@@ -1389,13 +1399,14 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
1389 | 1399 | ||
1390 | xfrm_state_put(x); | 1400 | xfrm_state_put(x); |
1391 | 1401 | ||
1392 | pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk); | 1402 | pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk, net); |
1393 | 1403 | ||
1394 | return 0; | 1404 | return 0; |
1395 | } | 1405 | } |
1396 | 1406 | ||
1397 | static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 1407 | static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
1398 | { | 1408 | { |
1409 | struct net *net = sock_net(sk); | ||
1399 | struct xfrm_state *x; | 1410 | struct xfrm_state *x; |
1400 | 1411 | ||
1401 | if (hdr->sadb_msg_len != sizeof(struct sadb_msg)/8) | 1412 | if (hdr->sadb_msg_len != sizeof(struct sadb_msg)/8) |
@@ -1404,14 +1415,14 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg * | |||
1404 | if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0) | 1415 | if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0) |
1405 | return 0; | 1416 | return 0; |
1406 | 1417 | ||
1407 | x = xfrm_find_acq_byseq(hdr->sadb_msg_seq); | 1418 | x = xfrm_find_acq_byseq(net, hdr->sadb_msg_seq); |
1408 | if (x == NULL) | 1419 | if (x == NULL) |
1409 | return 0; | 1420 | return 0; |
1410 | 1421 | ||
1411 | spin_lock_bh(&x->lock); | 1422 | spin_lock_bh(&x->lock); |
1412 | if (x->km.state == XFRM_STATE_ACQ) { | 1423 | if (x->km.state == XFRM_STATE_ACQ) { |
1413 | x->km.state = XFRM_STATE_ERROR; | 1424 | x->km.state = XFRM_STATE_ERROR; |
1414 | wake_up(&km_waitq); | 1425 | wake_up(&net->xfrm.km_waitq); |
1415 | } | 1426 | } |
1416 | spin_unlock_bh(&x->lock); | 1427 | spin_unlock_bh(&x->lock); |
1417 | xfrm_state_put(x); | 1428 | xfrm_state_put(x); |
@@ -1476,18 +1487,19 @@ static int key_notify_sa(struct xfrm_state *x, struct km_event *c) | |||
1476 | hdr->sadb_msg_seq = c->seq; | 1487 | hdr->sadb_msg_seq = c->seq; |
1477 | hdr->sadb_msg_pid = c->pid; | 1488 | hdr->sadb_msg_pid = c->pid; |
1478 | 1489 | ||
1479 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); | 1490 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xs_net(x)); |
1480 | 1491 | ||
1481 | return 0; | 1492 | return 0; |
1482 | } | 1493 | } |
1483 | 1494 | ||
1484 | static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 1495 | static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
1485 | { | 1496 | { |
1497 | struct net *net = sock_net(sk); | ||
1486 | struct xfrm_state *x; | 1498 | struct xfrm_state *x; |
1487 | int err; | 1499 | int err; |
1488 | struct km_event c; | 1500 | struct km_event c; |
1489 | 1501 | ||
1490 | x = pfkey_msg2xfrm_state(hdr, ext_hdrs); | 1502 | x = pfkey_msg2xfrm_state(net, hdr, ext_hdrs); |
1491 | if (IS_ERR(x)) | 1503 | if (IS_ERR(x)) |
1492 | return PTR_ERR(x); | 1504 | return PTR_ERR(x); |
1493 | 1505 | ||
@@ -1521,6 +1533,7 @@ out: | |||
1521 | 1533 | ||
1522 | static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 1534 | static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
1523 | { | 1535 | { |
1536 | struct net *net = sock_net(sk); | ||
1524 | struct xfrm_state *x; | 1537 | struct xfrm_state *x; |
1525 | struct km_event c; | 1538 | struct km_event c; |
1526 | int err; | 1539 | int err; |
@@ -1530,7 +1543,7 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
1530 | ext_hdrs[SADB_EXT_ADDRESS_DST-1])) | 1543 | ext_hdrs[SADB_EXT_ADDRESS_DST-1])) |
1531 | return -EINVAL; | 1544 | return -EINVAL; |
1532 | 1545 | ||
1533 | x = pfkey_xfrm_state_lookup(hdr, ext_hdrs); | 1546 | x = pfkey_xfrm_state_lookup(net, hdr, ext_hdrs); |
1534 | if (x == NULL) | 1547 | if (x == NULL) |
1535 | return -ESRCH; | 1548 | return -ESRCH; |
1536 | 1549 | ||
@@ -1562,6 +1575,7 @@ out: | |||
1562 | 1575 | ||
1563 | static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 1576 | static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
1564 | { | 1577 | { |
1578 | struct net *net = sock_net(sk); | ||
1565 | __u8 proto; | 1579 | __u8 proto; |
1566 | struct sk_buff *out_skb; | 1580 | struct sk_buff *out_skb; |
1567 | struct sadb_msg *out_hdr; | 1581 | struct sadb_msg *out_hdr; |
@@ -1572,7 +1586,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, | |||
1572 | ext_hdrs[SADB_EXT_ADDRESS_DST-1])) | 1586 | ext_hdrs[SADB_EXT_ADDRESS_DST-1])) |
1573 | return -EINVAL; | 1587 | return -EINVAL; |
1574 | 1588 | ||
1575 | x = pfkey_xfrm_state_lookup(hdr, ext_hdrs); | 1589 | x = pfkey_xfrm_state_lookup(net, hdr, ext_hdrs); |
1576 | if (x == NULL) | 1590 | if (x == NULL) |
1577 | return -ESRCH; | 1591 | return -ESRCH; |
1578 | 1592 | ||
@@ -1590,7 +1604,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, | |||
1590 | out_hdr->sadb_msg_reserved = 0; | 1604 | out_hdr->sadb_msg_reserved = 0; |
1591 | out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; | 1605 | out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; |
1592 | out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; | 1606 | out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; |
1593 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk); | 1607 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk)); |
1594 | 1608 | ||
1595 | return 0; | 1609 | return 0; |
1596 | } | 1610 | } |
@@ -1691,7 +1705,7 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
1691 | return -ENOBUFS; | 1705 | return -ENOBUFS; |
1692 | } | 1706 | } |
1693 | 1707 | ||
1694 | pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk); | 1708 | pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk, sock_net(sk)); |
1695 | 1709 | ||
1696 | return 0; | 1710 | return 0; |
1697 | } | 1711 | } |
@@ -1713,13 +1727,14 @@ static int key_notify_sa_flush(struct km_event *c) | |||
1713 | hdr->sadb_msg_errno = (uint8_t) 0; | 1727 | hdr->sadb_msg_errno = (uint8_t) 0; |
1714 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); | 1728 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); |
1715 | 1729 | ||
1716 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); | 1730 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); |
1717 | 1731 | ||
1718 | return 0; | 1732 | return 0; |
1719 | } | 1733 | } |
1720 | 1734 | ||
1721 | static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 1735 | static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
1722 | { | 1736 | { |
1737 | struct net *net = sock_net(sk); | ||
1723 | unsigned proto; | 1738 | unsigned proto; |
1724 | struct km_event c; | 1739 | struct km_event c; |
1725 | struct xfrm_audit audit_info; | 1740 | struct xfrm_audit audit_info; |
@@ -1732,13 +1747,14 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
1732 | audit_info.loginuid = audit_get_loginuid(current); | 1747 | audit_info.loginuid = audit_get_loginuid(current); |
1733 | audit_info.sessionid = audit_get_sessionid(current); | 1748 | audit_info.sessionid = audit_get_sessionid(current); |
1734 | audit_info.secid = 0; | 1749 | audit_info.secid = 0; |
1735 | err = xfrm_state_flush(proto, &audit_info); | 1750 | err = xfrm_state_flush(net, proto, &audit_info); |
1736 | if (err) | 1751 | if (err) |
1737 | return err; | 1752 | return err; |
1738 | c.data.proto = proto; | 1753 | c.data.proto = proto; |
1739 | c.seq = hdr->sadb_msg_seq; | 1754 | c.seq = hdr->sadb_msg_seq; |
1740 | c.pid = hdr->sadb_msg_pid; | 1755 | c.pid = hdr->sadb_msg_pid; |
1741 | c.event = XFRM_MSG_FLUSHSA; | 1756 | c.event = XFRM_MSG_FLUSHSA; |
1757 | c.net = net; | ||
1742 | km_state_notify(NULL, &c); | 1758 | km_state_notify(NULL, &c); |
1743 | 1759 | ||
1744 | return 0; | 1760 | return 0; |
@@ -1768,7 +1784,7 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr) | |||
1768 | 1784 | ||
1769 | if (pfk->dump.skb) | 1785 | if (pfk->dump.skb) |
1770 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, | 1786 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, |
1771 | &pfk->sk); | 1787 | &pfk->sk, sock_net(&pfk->sk)); |
1772 | pfk->dump.skb = out_skb; | 1788 | pfk->dump.skb = out_skb; |
1773 | 1789 | ||
1774 | return 0; | 1790 | return 0; |
@@ -1776,7 +1792,8 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr) | |||
1776 | 1792 | ||
1777 | static int pfkey_dump_sa(struct pfkey_sock *pfk) | 1793 | static int pfkey_dump_sa(struct pfkey_sock *pfk) |
1778 | { | 1794 | { |
1779 | return xfrm_state_walk(&pfk->dump.u.state, dump_sa, (void *) pfk); | 1795 | struct net *net = sock_net(&pfk->sk); |
1796 | return xfrm_state_walk(net, &pfk->dump.u.state, dump_sa, (void *) pfk); | ||
1780 | } | 1797 | } |
1781 | 1798 | ||
1782 | static void pfkey_dump_sa_done(struct pfkey_sock *pfk) | 1799 | static void pfkey_dump_sa_done(struct pfkey_sock *pfk) |
@@ -1817,7 +1834,7 @@ static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, struct sadb_msg * | |||
1817 | return -EINVAL; | 1834 | return -EINVAL; |
1818 | pfk->promisc = satype; | 1835 | pfk->promisc = satype; |
1819 | } | 1836 | } |
1820 | pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, BROADCAST_ALL, NULL); | 1837 | pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, BROADCAST_ALL, NULL, sock_net(sk)); |
1821 | return 0; | 1838 | return 0; |
1822 | } | 1839 | } |
1823 | 1840 | ||
@@ -1833,7 +1850,7 @@ static int check_reqid(struct xfrm_policy *xp, int dir, int count, void *ptr) | |||
1833 | return 0; | 1850 | return 0; |
1834 | } | 1851 | } |
1835 | 1852 | ||
1836 | static u32 gen_reqid(void) | 1853 | static u32 gen_reqid(struct net *net) |
1837 | { | 1854 | { |
1838 | struct xfrm_policy_walk walk; | 1855 | struct xfrm_policy_walk walk; |
1839 | u32 start; | 1856 | u32 start; |
@@ -1846,7 +1863,7 @@ static u32 gen_reqid(void) | |||
1846 | if (reqid == 0) | 1863 | if (reqid == 0) |
1847 | reqid = IPSEC_MANUAL_REQID_MAX+1; | 1864 | reqid = IPSEC_MANUAL_REQID_MAX+1; |
1848 | xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN); | 1865 | xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN); |
1849 | rc = xfrm_policy_walk(&walk, check_reqid, (void*)&reqid); | 1866 | rc = xfrm_policy_walk(net, &walk, check_reqid, (void*)&reqid); |
1850 | xfrm_policy_walk_done(&walk); | 1867 | xfrm_policy_walk_done(&walk); |
1851 | if (rc != -EEXIST) | 1868 | if (rc != -EEXIST) |
1852 | return reqid; | 1869 | return reqid; |
@@ -1857,6 +1874,7 @@ static u32 gen_reqid(void) | |||
1857 | static int | 1874 | static int |
1858 | parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) | 1875 | parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) |
1859 | { | 1876 | { |
1877 | struct net *net = xp_net(xp); | ||
1860 | struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; | 1878 | struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; |
1861 | int mode; | 1879 | int mode; |
1862 | 1880 | ||
@@ -1876,7 +1894,7 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) | |||
1876 | t->reqid = rq->sadb_x_ipsecrequest_reqid; | 1894 | t->reqid = rq->sadb_x_ipsecrequest_reqid; |
1877 | if (t->reqid > IPSEC_MANUAL_REQID_MAX) | 1895 | if (t->reqid > IPSEC_MANUAL_REQID_MAX) |
1878 | t->reqid = 0; | 1896 | t->reqid = 0; |
1879 | if (!t->reqid && !(t->reqid = gen_reqid())) | 1897 | if (!t->reqid && !(t->reqid = gen_reqid(net))) |
1880 | return -ENOBUFS; | 1898 | return -ENOBUFS; |
1881 | } | 1899 | } |
1882 | 1900 | ||
@@ -2147,7 +2165,7 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c | |||
2147 | out_hdr->sadb_msg_errno = 0; | 2165 | out_hdr->sadb_msg_errno = 0; |
2148 | out_hdr->sadb_msg_seq = c->seq; | 2166 | out_hdr->sadb_msg_seq = c->seq; |
2149 | out_hdr->sadb_msg_pid = c->pid; | 2167 | out_hdr->sadb_msg_pid = c->pid; |
2150 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL); | 2168 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp)); |
2151 | out: | 2169 | out: |
2152 | return 0; | 2170 | return 0; |
2153 | 2171 | ||
@@ -2155,6 +2173,7 @@ out: | |||
2155 | 2173 | ||
2156 | static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 2174 | static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
2157 | { | 2175 | { |
2176 | struct net *net = sock_net(sk); | ||
2158 | int err = 0; | 2177 | int err = 0; |
2159 | struct sadb_lifetime *lifetime; | 2178 | struct sadb_lifetime *lifetime; |
2160 | struct sadb_address *sa; | 2179 | struct sadb_address *sa; |
@@ -2174,7 +2193,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2174 | if (!pol->sadb_x_policy_dir || pol->sadb_x_policy_dir >= IPSEC_DIR_MAX) | 2193 | if (!pol->sadb_x_policy_dir || pol->sadb_x_policy_dir >= IPSEC_DIR_MAX) |
2175 | return -EINVAL; | 2194 | return -EINVAL; |
2176 | 2195 | ||
2177 | xp = xfrm_policy_alloc(GFP_KERNEL); | 2196 | xp = xfrm_policy_alloc(net, GFP_KERNEL); |
2178 | if (xp == NULL) | 2197 | if (xp == NULL) |
2179 | return -ENOBUFS; | 2198 | return -ENOBUFS; |
2180 | 2199 | ||
@@ -2275,6 +2294,7 @@ out: | |||
2275 | 2294 | ||
2276 | static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 2295 | static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
2277 | { | 2296 | { |
2297 | struct net *net = sock_net(sk); | ||
2278 | int err; | 2298 | int err; |
2279 | struct sadb_address *sa; | 2299 | struct sadb_address *sa; |
2280 | struct sadb_x_policy *pol; | 2300 | struct sadb_x_policy *pol; |
@@ -2324,7 +2344,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2324 | return err; | 2344 | return err; |
2325 | } | 2345 | } |
2326 | 2346 | ||
2327 | xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, | 2347 | xp = xfrm_policy_bysel_ctx(net, XFRM_POLICY_TYPE_MAIN, |
2328 | pol->sadb_x_policy_dir - 1, &sel, pol_ctx, | 2348 | pol->sadb_x_policy_dir - 1, &sel, pol_ctx, |
2329 | 1, &err); | 2349 | 1, &err); |
2330 | security_xfrm_policy_free(pol_ctx); | 2350 | security_xfrm_policy_free(pol_ctx); |
@@ -2372,7 +2392,7 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, struct sadb | |||
2372 | out_hdr->sadb_msg_errno = 0; | 2392 | out_hdr->sadb_msg_errno = 0; |
2373 | out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; | 2393 | out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; |
2374 | out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; | 2394 | out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; |
2375 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk); | 2395 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, xp_net(xp)); |
2376 | err = 0; | 2396 | err = 0; |
2377 | 2397 | ||
2378 | out: | 2398 | out: |
@@ -2557,6 +2577,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb, | |||
2557 | 2577 | ||
2558 | static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 2578 | static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
2559 | { | 2579 | { |
2580 | struct net *net = sock_net(sk); | ||
2560 | unsigned int dir; | 2581 | unsigned int dir; |
2561 | int err = 0, delete; | 2582 | int err = 0, delete; |
2562 | struct sadb_x_policy *pol; | 2583 | struct sadb_x_policy *pol; |
@@ -2571,8 +2592,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2571 | return -EINVAL; | 2592 | return -EINVAL; |
2572 | 2593 | ||
2573 | delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2); | 2594 | delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2); |
2574 | xp = xfrm_policy_byid(XFRM_POLICY_TYPE_MAIN, dir, pol->sadb_x_policy_id, | 2595 | xp = xfrm_policy_byid(net, XFRM_POLICY_TYPE_MAIN, dir, |
2575 | delete, &err); | 2596 | pol->sadb_x_policy_id, delete, &err); |
2576 | if (xp == NULL) | 2597 | if (xp == NULL) |
2577 | return -ENOENT; | 2598 | return -ENOENT; |
2578 | 2599 | ||
@@ -2625,7 +2646,7 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) | |||
2625 | 2646 | ||
2626 | if (pfk->dump.skb) | 2647 | if (pfk->dump.skb) |
2627 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, | 2648 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, |
2628 | &pfk->sk); | 2649 | &pfk->sk, sock_net(&pfk->sk)); |
2629 | pfk->dump.skb = out_skb; | 2650 | pfk->dump.skb = out_skb; |
2630 | 2651 | ||
2631 | return 0; | 2652 | return 0; |
@@ -2633,7 +2654,8 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) | |||
2633 | 2654 | ||
2634 | static int pfkey_dump_sp(struct pfkey_sock *pfk) | 2655 | static int pfkey_dump_sp(struct pfkey_sock *pfk) |
2635 | { | 2656 | { |
2636 | return xfrm_policy_walk(&pfk->dump.u.policy, dump_sp, (void *) pfk); | 2657 | struct net *net = sock_net(&pfk->sk); |
2658 | return xfrm_policy_walk(net, &pfk->dump.u.policy, dump_sp, (void *) pfk); | ||
2637 | } | 2659 | } |
2638 | 2660 | ||
2639 | static void pfkey_dump_sp_done(struct pfkey_sock *pfk) | 2661 | static void pfkey_dump_sp_done(struct pfkey_sock *pfk) |
@@ -2672,13 +2694,14 @@ static int key_notify_policy_flush(struct km_event *c) | |||
2672 | hdr->sadb_msg_version = PF_KEY_V2; | 2694 | hdr->sadb_msg_version = PF_KEY_V2; |
2673 | hdr->sadb_msg_errno = (uint8_t) 0; | 2695 | hdr->sadb_msg_errno = (uint8_t) 0; |
2674 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); | 2696 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); |
2675 | pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL); | 2697 | pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); |
2676 | return 0; | 2698 | return 0; |
2677 | 2699 | ||
2678 | } | 2700 | } |
2679 | 2701 | ||
2680 | static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 2702 | static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
2681 | { | 2703 | { |
2704 | struct net *net = sock_net(sk); | ||
2682 | struct km_event c; | 2705 | struct km_event c; |
2683 | struct xfrm_audit audit_info; | 2706 | struct xfrm_audit audit_info; |
2684 | int err; | 2707 | int err; |
@@ -2686,13 +2709,14 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2686 | audit_info.loginuid = audit_get_loginuid(current); | 2709 | audit_info.loginuid = audit_get_loginuid(current); |
2687 | audit_info.sessionid = audit_get_sessionid(current); | 2710 | audit_info.sessionid = audit_get_sessionid(current); |
2688 | audit_info.secid = 0; | 2711 | audit_info.secid = 0; |
2689 | err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); | 2712 | err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); |
2690 | if (err) | 2713 | if (err) |
2691 | return err; | 2714 | return err; |
2692 | c.data.type = XFRM_POLICY_TYPE_MAIN; | 2715 | c.data.type = XFRM_POLICY_TYPE_MAIN; |
2693 | c.event = XFRM_MSG_FLUSHPOLICY; | 2716 | c.event = XFRM_MSG_FLUSHPOLICY; |
2694 | c.pid = hdr->sadb_msg_pid; | 2717 | c.pid = hdr->sadb_msg_pid; |
2695 | c.seq = hdr->sadb_msg_seq; | 2718 | c.seq = hdr->sadb_msg_seq; |
2719 | c.net = net; | ||
2696 | km_policy_notify(NULL, 0, &c); | 2720 | km_policy_notify(NULL, 0, &c); |
2697 | 2721 | ||
2698 | return 0; | 2722 | return 0; |
@@ -2732,7 +2756,7 @@ static int pfkey_process(struct sock *sk, struct sk_buff *skb, struct sadb_msg * | |||
2732 | int err; | 2756 | int err; |
2733 | 2757 | ||
2734 | pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, | 2758 | pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, |
2735 | BROADCAST_PROMISC_ONLY, NULL); | 2759 | BROADCAST_PROMISC_ONLY, NULL, sock_net(sk)); |
2736 | 2760 | ||
2737 | memset(ext_hdrs, 0, sizeof(ext_hdrs)); | 2761 | memset(ext_hdrs, 0, sizeof(ext_hdrs)); |
2738 | err = parse_exthdrs(skb, hdr, ext_hdrs); | 2762 | err = parse_exthdrs(skb, hdr, ext_hdrs); |
@@ -2935,13 +2959,16 @@ static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c) | |||
2935 | out_hdr->sadb_msg_seq = 0; | 2959 | out_hdr->sadb_msg_seq = 0; |
2936 | out_hdr->sadb_msg_pid = 0; | 2960 | out_hdr->sadb_msg_pid = 0; |
2937 | 2961 | ||
2938 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL); | 2962 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x)); |
2939 | return 0; | 2963 | return 0; |
2940 | } | 2964 | } |
2941 | 2965 | ||
2942 | static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c) | 2966 | static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c) |
2943 | { | 2967 | { |
2944 | if (atomic_read(&pfkey_socks_nr) == 0) | 2968 | struct net *net = x ? xs_net(x) : c->net; |
2969 | struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); | ||
2970 | |||
2971 | if (atomic_read(&net_pfkey->socks_nr) == 0) | ||
2945 | return 0; | 2972 | return 0; |
2946 | 2973 | ||
2947 | switch (c->event) { | 2974 | switch (c->event) { |
@@ -3103,12 +3130,13 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
3103 | xfrm_ctx->ctx_len); | 3130 | xfrm_ctx->ctx_len); |
3104 | } | 3131 | } |
3105 | 3132 | ||
3106 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL); | 3133 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x)); |
3107 | } | 3134 | } |
3108 | 3135 | ||
3109 | static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, | 3136 | static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, |
3110 | u8 *data, int len, int *dir) | 3137 | u8 *data, int len, int *dir) |
3111 | { | 3138 | { |
3139 | struct net *net = sock_net(sk); | ||
3112 | struct xfrm_policy *xp; | 3140 | struct xfrm_policy *xp; |
3113 | struct sadb_x_policy *pol = (struct sadb_x_policy*)data; | 3141 | struct sadb_x_policy *pol = (struct sadb_x_policy*)data; |
3114 | struct sadb_x_sec_ctx *sec_ctx; | 3142 | struct sadb_x_sec_ctx *sec_ctx; |
@@ -3141,7 +3169,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, | |||
3141 | (!pol->sadb_x_policy_dir || pol->sadb_x_policy_dir > IPSEC_DIR_OUTBOUND)) | 3169 | (!pol->sadb_x_policy_dir || pol->sadb_x_policy_dir > IPSEC_DIR_OUTBOUND)) |
3142 | return NULL; | 3170 | return NULL; |
3143 | 3171 | ||
3144 | xp = xfrm_policy_alloc(GFP_ATOMIC); | 3172 | xp = xfrm_policy_alloc(net, GFP_ATOMIC); |
3145 | if (xp == NULL) { | 3173 | if (xp == NULL) { |
3146 | *dir = -ENOBUFS; | 3174 | *dir = -ENOBUFS; |
3147 | return NULL; | 3175 | return NULL; |
@@ -3300,7 +3328,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | |||
3300 | n_port->sadb_x_nat_t_port_port = sport; | 3328 | n_port->sadb_x_nat_t_port_port = sport; |
3301 | n_port->sadb_x_nat_t_port_reserved = 0; | 3329 | n_port->sadb_x_nat_t_port_reserved = 0; |
3302 | 3330 | ||
3303 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL); | 3331 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x)); |
3304 | } | 3332 | } |
3305 | 3333 | ||
3306 | #ifdef CONFIG_NET_KEY_MIGRATE | 3334 | #ifdef CONFIG_NET_KEY_MIGRATE |
@@ -3491,7 +3519,7 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | |||
3491 | } | 3519 | } |
3492 | 3520 | ||
3493 | /* broadcast migrate message to sockets */ | 3521 | /* broadcast migrate message to sockets */ |
3494 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); | 3522 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net); |
3495 | 3523 | ||
3496 | return 0; | 3524 | return 0; |
3497 | 3525 | ||
@@ -3645,6 +3673,8 @@ static int pfkey_seq_show(struct seq_file *f, void *v) | |||
3645 | 3673 | ||
3646 | static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos) | 3674 | static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos) |
3647 | { | 3675 | { |
3676 | struct net *net = seq_file_net(f); | ||
3677 | struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); | ||
3648 | struct sock *s; | 3678 | struct sock *s; |
3649 | struct hlist_node *node; | 3679 | struct hlist_node *node; |
3650 | loff_t pos = *ppos; | 3680 | loff_t pos = *ppos; |
@@ -3653,7 +3683,7 @@ static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos) | |||
3653 | if (pos == 0) | 3683 | if (pos == 0) |
3654 | return SEQ_START_TOKEN; | 3684 | return SEQ_START_TOKEN; |
3655 | 3685 | ||
3656 | sk_for_each(s, node, &pfkey_table) | 3686 | sk_for_each(s, node, &net_pfkey->table) |
3657 | if (pos-- == 1) | 3687 | if (pos-- == 1) |
3658 | return s; | 3688 | return s; |
3659 | 3689 | ||
@@ -3662,9 +3692,12 @@ static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos) | |||
3662 | 3692 | ||
3663 | static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos) | 3693 | static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos) |
3664 | { | 3694 | { |
3695 | struct net *net = seq_file_net(f); | ||
3696 | struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); | ||
3697 | |||
3665 | ++*ppos; | 3698 | ++*ppos; |
3666 | return (v == SEQ_START_TOKEN) ? | 3699 | return (v == SEQ_START_TOKEN) ? |
3667 | sk_head(&pfkey_table) : | 3700 | sk_head(&net_pfkey->table) : |
3668 | sk_next((struct sock *)v); | 3701 | sk_next((struct sock *)v); |
3669 | } | 3702 | } |
3670 | 3703 | ||
@@ -3682,38 +3715,39 @@ static struct seq_operations pfkey_seq_ops = { | |||
3682 | 3715 | ||
3683 | static int pfkey_seq_open(struct inode *inode, struct file *file) | 3716 | static int pfkey_seq_open(struct inode *inode, struct file *file) |
3684 | { | 3717 | { |
3685 | return seq_open(file, &pfkey_seq_ops); | 3718 | return seq_open_net(inode, file, &pfkey_seq_ops, |
3719 | sizeof(struct seq_net_private)); | ||
3686 | } | 3720 | } |
3687 | 3721 | ||
3688 | static struct file_operations pfkey_proc_ops = { | 3722 | static struct file_operations pfkey_proc_ops = { |
3689 | .open = pfkey_seq_open, | 3723 | .open = pfkey_seq_open, |
3690 | .read = seq_read, | 3724 | .read = seq_read, |
3691 | .llseek = seq_lseek, | 3725 | .llseek = seq_lseek, |
3692 | .release = seq_release, | 3726 | .release = seq_release_net, |
3693 | }; | 3727 | }; |
3694 | 3728 | ||
3695 | static int pfkey_init_proc(void) | 3729 | static int __net_init pfkey_init_proc(struct net *net) |
3696 | { | 3730 | { |
3697 | struct proc_dir_entry *e; | 3731 | struct proc_dir_entry *e; |
3698 | 3732 | ||
3699 | e = proc_net_fops_create(&init_net, "pfkey", 0, &pfkey_proc_ops); | 3733 | e = proc_net_fops_create(net, "pfkey", 0, &pfkey_proc_ops); |
3700 | if (e == NULL) | 3734 | if (e == NULL) |
3701 | return -ENOMEM; | 3735 | return -ENOMEM; |
3702 | 3736 | ||
3703 | return 0; | 3737 | return 0; |
3704 | } | 3738 | } |
3705 | 3739 | ||
3706 | static void pfkey_exit_proc(void) | 3740 | static void pfkey_exit_proc(struct net *net) |
3707 | { | 3741 | { |
3708 | proc_net_remove(&init_net, "pfkey"); | 3742 | proc_net_remove(net, "pfkey"); |
3709 | } | 3743 | } |
3710 | #else | 3744 | #else |
3711 | static inline int pfkey_init_proc(void) | 3745 | static int __net_init pfkey_init_proc(struct net *net) |
3712 | { | 3746 | { |
3713 | return 0; | 3747 | return 0; |
3714 | } | 3748 | } |
3715 | 3749 | ||
3716 | static inline void pfkey_exit_proc(void) | 3750 | static void pfkey_exit_proc(struct net *net) |
3717 | { | 3751 | { |
3718 | } | 3752 | } |
3719 | #endif | 3753 | #endif |
@@ -3729,10 +3763,51 @@ static struct xfrm_mgr pfkeyv2_mgr = | |||
3729 | .migrate = pfkey_send_migrate, | 3763 | .migrate = pfkey_send_migrate, |
3730 | }; | 3764 | }; |
3731 | 3765 | ||
3766 | static int __net_init pfkey_net_init(struct net *net) | ||
3767 | { | ||
3768 | struct netns_pfkey *net_pfkey; | ||
3769 | int rv; | ||
3770 | |||
3771 | net_pfkey = kmalloc(sizeof(struct netns_pfkey), GFP_KERNEL); | ||
3772 | if (!net_pfkey) { | ||
3773 | rv = -ENOMEM; | ||
3774 | goto out_kmalloc; | ||
3775 | } | ||
3776 | INIT_HLIST_HEAD(&net_pfkey->table); | ||
3777 | atomic_set(&net_pfkey->socks_nr, 0); | ||
3778 | rv = net_assign_generic(net, pfkey_net_id, net_pfkey); | ||
3779 | if (rv < 0) | ||
3780 | goto out_assign; | ||
3781 | rv = pfkey_init_proc(net); | ||
3782 | if (rv < 0) | ||
3783 | goto out_proc; | ||
3784 | return 0; | ||
3785 | |||
3786 | out_proc: | ||
3787 | out_assign: | ||
3788 | kfree(net_pfkey); | ||
3789 | out_kmalloc: | ||
3790 | return rv; | ||
3791 | } | ||
3792 | |||
3793 | static void __net_exit pfkey_net_exit(struct net *net) | ||
3794 | { | ||
3795 | struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); | ||
3796 | |||
3797 | pfkey_exit_proc(net); | ||
3798 | BUG_ON(!hlist_empty(&net_pfkey->table)); | ||
3799 | kfree(net_pfkey); | ||
3800 | } | ||
3801 | |||
3802 | static struct pernet_operations pfkey_net_ops = { | ||
3803 | .init = pfkey_net_init, | ||
3804 | .exit = pfkey_net_exit, | ||
3805 | }; | ||
3806 | |||
3732 | static void __exit ipsec_pfkey_exit(void) | 3807 | static void __exit ipsec_pfkey_exit(void) |
3733 | { | 3808 | { |
3809 | unregister_pernet_gen_subsys(pfkey_net_id, &pfkey_net_ops); | ||
3734 | xfrm_unregister_km(&pfkeyv2_mgr); | 3810 | xfrm_unregister_km(&pfkeyv2_mgr); |
3735 | pfkey_exit_proc(); | ||
3736 | sock_unregister(PF_KEY); | 3811 | sock_unregister(PF_KEY); |
3737 | proto_unregister(&key_proto); | 3812 | proto_unregister(&key_proto); |
3738 | } | 3813 | } |
@@ -3747,16 +3822,16 @@ static int __init ipsec_pfkey_init(void) | |||
3747 | err = sock_register(&pfkey_family_ops); | 3822 | err = sock_register(&pfkey_family_ops); |
3748 | if (err != 0) | 3823 | if (err != 0) |
3749 | goto out_unregister_key_proto; | 3824 | goto out_unregister_key_proto; |
3750 | err = pfkey_init_proc(); | 3825 | err = xfrm_register_km(&pfkeyv2_mgr); |
3751 | if (err != 0) | 3826 | if (err != 0) |
3752 | goto out_sock_unregister; | 3827 | goto out_sock_unregister; |
3753 | err = xfrm_register_km(&pfkeyv2_mgr); | 3828 | err = register_pernet_gen_subsys(&pfkey_net_id, &pfkey_net_ops); |
3754 | if (err != 0) | 3829 | if (err != 0) |
3755 | goto out_remove_proc_entry; | 3830 | goto out_xfrm_unregister_km; |
3756 | out: | 3831 | out: |
3757 | return err; | 3832 | return err; |
3758 | out_remove_proc_entry: | 3833 | out_xfrm_unregister_km: |
3759 | pfkey_exit_proc(); | 3834 | xfrm_unregister_km(&pfkeyv2_mgr); |
3760 | out_sock_unregister: | 3835 | out_sock_unregister: |
3761 | sock_unregister(PF_KEY); | 3836 | sock_unregister(PF_KEY); |
3762 | out_unregister_key_proto: | 3837 | out_unregister_key_proto: |