diff options
| author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:58:31 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:58:31 -0500 |
| commit | 07fb0f1799dcb6b3df527909811fd6704278842e (patch) | |
| tree | 65b14c59b1010b529bf087cbc6329a96d9e6e347 /net/key | |
| parent | 3fa87a3210a24ae406c2ccd37a52585baeb21546 (diff) | |
netns PF_KEY: part 2
* interaction with userspace -- take netns from userspace socket.
* in ->notify hook take netns either from SA or explicitly passed --
we don't know if SA/SPD flush is coming.
* stub policy migration with init_net for now.
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.c | 105 |
1 files changed, 60 insertions, 45 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c index e80b26488bb3..bb78ef972d1b 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -261,9 +261,9 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2, | |||
| 261 | #define BROADCAST_REGISTERED 2 | 261 | #define BROADCAST_REGISTERED 2 |
| 262 | #define BROADCAST_PROMISC_ONLY 4 | 262 | #define BROADCAST_PROMISC_ONLY 4 |
| 263 | static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, | 263 | static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, |
| 264 | int broadcast_flags, struct sock *one_sk) | 264 | int broadcast_flags, struct sock *one_sk, |
| 265 | struct net *net) | ||
| 265 | { | 266 | { |
| 266 | struct net *net = &init_net; | ||
| 267 | struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); | 267 | struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); |
| 268 | struct sock *sk; | 268 | struct sock *sk; |
| 269 | struct hlist_node *node; | 269 | struct hlist_node *node; |
| @@ -336,7 +336,7 @@ static int pfkey_do_dump(struct pfkey_sock *pfk) | |||
| 336 | hdr->sadb_msg_seq = 0; | 336 | hdr->sadb_msg_seq = 0; |
| 337 | hdr->sadb_msg_errno = rc; | 337 | hdr->sadb_msg_errno = rc; |
| 338 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, | 338 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, |
| 339 | &pfk->sk); | 339 | &pfk->sk, sock_net(&pfk->sk)); |
| 340 | pfk->dump.skb = NULL; | 340 | pfk->dump.skb = NULL; |
| 341 | } | 341 | } |
| 342 | 342 | ||
| @@ -375,7 +375,7 @@ static int pfkey_error(struct sadb_msg *orig, int err, struct sock *sk) | |||
| 375 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / | 375 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / |
| 376 | sizeof(uint64_t)); | 376 | sizeof(uint64_t)); |
| 377 | 377 | ||
| 378 | pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk); | 378 | pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk, sock_net(sk)); |
| 379 | 379 | ||
| 380 | return 0; | 380 | return 0; |
| 381 | } | 381 | } |
| @@ -653,7 +653,7 @@ int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, xfrm_address_t *xaddr) | |||
| 653 | xaddr); | 653 | xaddr); |
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | 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) |
| 657 | { | 657 | { |
| 658 | struct sadb_sa *sa; | 658 | struct sadb_sa *sa; |
| 659 | struct sadb_address *addr; | 659 | struct sadb_address *addr; |
| @@ -691,7 +691,7 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void ** | |||
| 691 | if (!xaddr) | 691 | if (!xaddr) |
| 692 | return NULL; | 692 | return NULL; |
| 693 | 693 | ||
| 694 | return xfrm_state_lookup(&init_net, xaddr, sa->sadb_sa_spi, proto, family); | 694 | return xfrm_state_lookup(net, xaddr, sa->sadb_sa_spi, proto, family); |
| 695 | } | 695 | } |
| 696 | 696 | ||
| 697 | #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) | 697 | #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) |
| @@ -1066,7 +1066,8 @@ static inline struct sk_buff *pfkey_xfrm_state2msg_expire(struct xfrm_state *x, | |||
| 1066 | return __pfkey_xfrm_state2msg(x, 0, hsc); | 1066 | return __pfkey_xfrm_state2msg(x, 0, hsc); |
| 1067 | } | 1067 | } |
| 1068 | 1068 | ||
| 1069 | 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, | ||
| 1070 | void **ext_hdrs) | 1071 | void **ext_hdrs) |
| 1071 | { | 1072 | { |
| 1072 | struct xfrm_state *x; | 1073 | struct xfrm_state *x; |
| @@ -1130,7 +1131,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, | |||
| 1130 | (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))) |
| 1131 | return ERR_PTR(-EINVAL); | 1132 | return ERR_PTR(-EINVAL); |
| 1132 | 1133 | ||
| 1133 | x = xfrm_state_alloc(&init_net); | 1134 | x = xfrm_state_alloc(net); |
| 1134 | if (x == NULL) | 1135 | if (x == NULL) |
| 1135 | return ERR_PTR(-ENOBUFS); | 1136 | return ERR_PTR(-ENOBUFS); |
| 1136 | 1137 | ||
| @@ -1306,6 +1307,7 @@ static int pfkey_reserved(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
| 1306 | 1307 | ||
| 1307 | 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) |
| 1308 | { | 1309 | { |
| 1310 | struct net *net = sock_net(sk); | ||
| 1309 | struct sk_buff *resp_skb; | 1311 | struct sk_buff *resp_skb; |
| 1310 | struct sadb_x_sa2 *sa2; | 1312 | struct sadb_x_sa2 *sa2; |
| 1311 | struct sadb_address *saddr, *daddr; | 1313 | struct sadb_address *saddr, *daddr; |
| @@ -1356,7 +1358,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 1356 | } | 1358 | } |
| 1357 | 1359 | ||
| 1358 | if (hdr->sadb_msg_seq) { | 1360 | if (hdr->sadb_msg_seq) { |
| 1359 | x = xfrm_find_acq_byseq(&init_net, hdr->sadb_msg_seq); | 1361 | x = xfrm_find_acq_byseq(net, hdr->sadb_msg_seq); |
| 1360 | if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) { | 1362 | if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) { |
| 1361 | xfrm_state_put(x); | 1363 | xfrm_state_put(x); |
| 1362 | x = NULL; | 1364 | x = NULL; |
| @@ -1364,7 +1366,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 1364 | } | 1366 | } |
| 1365 | 1367 | ||
| 1366 | if (!x) | 1368 | if (!x) |
| 1367 | x = xfrm_find_acq(&init_net, mode, reqid, proto, xdaddr, xsaddr, 1, family); | 1369 | x = xfrm_find_acq(net, mode, reqid, proto, xdaddr, xsaddr, 1, family); |
| 1368 | 1370 | ||
| 1369 | if (x == NULL) | 1371 | if (x == NULL) |
| 1370 | return -ENOENT; | 1372 | return -ENOENT; |
| @@ -1397,13 +1399,14 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 1397 | 1399 | ||
| 1398 | xfrm_state_put(x); | 1400 | xfrm_state_put(x); |
| 1399 | 1401 | ||
| 1400 | pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk); | 1402 | pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk, net); |
| 1401 | 1403 | ||
| 1402 | return 0; | 1404 | return 0; |
| 1403 | } | 1405 | } |
| 1404 | 1406 | ||
| 1405 | 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) |
| 1406 | { | 1408 | { |
| 1409 | struct net *net = sock_net(sk); | ||
| 1407 | struct xfrm_state *x; | 1410 | struct xfrm_state *x; |
| 1408 | 1411 | ||
| 1409 | if (hdr->sadb_msg_len != sizeof(struct sadb_msg)/8) | 1412 | if (hdr->sadb_msg_len != sizeof(struct sadb_msg)/8) |
| @@ -1412,14 +1415,14 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg * | |||
| 1412 | if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0) | 1415 | if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0) |
| 1413 | return 0; | 1416 | return 0; |
| 1414 | 1417 | ||
| 1415 | x = xfrm_find_acq_byseq(&init_net, hdr->sadb_msg_seq); | 1418 | x = xfrm_find_acq_byseq(net, hdr->sadb_msg_seq); |
| 1416 | if (x == NULL) | 1419 | if (x == NULL) |
| 1417 | return 0; | 1420 | return 0; |
| 1418 | 1421 | ||
| 1419 | spin_lock_bh(&x->lock); | 1422 | spin_lock_bh(&x->lock); |
| 1420 | if (x->km.state == XFRM_STATE_ACQ) { | 1423 | if (x->km.state == XFRM_STATE_ACQ) { |
| 1421 | x->km.state = XFRM_STATE_ERROR; | 1424 | x->km.state = XFRM_STATE_ERROR; |
| 1422 | wake_up(&init_net.xfrm.km_waitq); | 1425 | wake_up(&net->xfrm.km_waitq); |
| 1423 | } | 1426 | } |
| 1424 | spin_unlock_bh(&x->lock); | 1427 | spin_unlock_bh(&x->lock); |
| 1425 | xfrm_state_put(x); | 1428 | xfrm_state_put(x); |
| @@ -1484,18 +1487,19 @@ static int key_notify_sa(struct xfrm_state *x, struct km_event *c) | |||
| 1484 | hdr->sadb_msg_seq = c->seq; | 1487 | hdr->sadb_msg_seq = c->seq; |
| 1485 | hdr->sadb_msg_pid = c->pid; | 1488 | hdr->sadb_msg_pid = c->pid; |
| 1486 | 1489 | ||
| 1487 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); | 1490 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xs_net(x)); |
| 1488 | 1491 | ||
| 1489 | return 0; | 1492 | return 0; |
| 1490 | } | 1493 | } |
| 1491 | 1494 | ||
| 1492 | 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) |
| 1493 | { | 1496 | { |
| 1497 | struct net *net = sock_net(sk); | ||
| 1494 | struct xfrm_state *x; | 1498 | struct xfrm_state *x; |
| 1495 | int err; | 1499 | int err; |
| 1496 | struct km_event c; | 1500 | struct km_event c; |
| 1497 | 1501 | ||
| 1498 | x = pfkey_msg2xfrm_state(hdr, ext_hdrs); | 1502 | x = pfkey_msg2xfrm_state(net, hdr, ext_hdrs); |
| 1499 | if (IS_ERR(x)) | 1503 | if (IS_ERR(x)) |
| 1500 | return PTR_ERR(x); | 1504 | return PTR_ERR(x); |
| 1501 | 1505 | ||
| @@ -1529,6 +1533,7 @@ out: | |||
| 1529 | 1533 | ||
| 1530 | 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) |
| 1531 | { | 1535 | { |
| 1536 | struct net *net = sock_net(sk); | ||
| 1532 | struct xfrm_state *x; | 1537 | struct xfrm_state *x; |
| 1533 | struct km_event c; | 1538 | struct km_event c; |
| 1534 | int err; | 1539 | int err; |
| @@ -1538,7 +1543,7 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 1538 | ext_hdrs[SADB_EXT_ADDRESS_DST-1])) | 1543 | ext_hdrs[SADB_EXT_ADDRESS_DST-1])) |
| 1539 | return -EINVAL; | 1544 | return -EINVAL; |
| 1540 | 1545 | ||
| 1541 | x = pfkey_xfrm_state_lookup(hdr, ext_hdrs); | 1546 | x = pfkey_xfrm_state_lookup(net, hdr, ext_hdrs); |
| 1542 | if (x == NULL) | 1547 | if (x == NULL) |
| 1543 | return -ESRCH; | 1548 | return -ESRCH; |
| 1544 | 1549 | ||
| @@ -1570,6 +1575,7 @@ out: | |||
| 1570 | 1575 | ||
| 1571 | 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) |
| 1572 | { | 1577 | { |
| 1578 | struct net *net = sock_net(sk); | ||
| 1573 | __u8 proto; | 1579 | __u8 proto; |
| 1574 | struct sk_buff *out_skb; | 1580 | struct sk_buff *out_skb; |
| 1575 | struct sadb_msg *out_hdr; | 1581 | struct sadb_msg *out_hdr; |
| @@ -1580,7 +1586,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, | |||
| 1580 | ext_hdrs[SADB_EXT_ADDRESS_DST-1])) | 1586 | ext_hdrs[SADB_EXT_ADDRESS_DST-1])) |
| 1581 | return -EINVAL; | 1587 | return -EINVAL; |
| 1582 | 1588 | ||
| 1583 | x = pfkey_xfrm_state_lookup(hdr, ext_hdrs); | 1589 | x = pfkey_xfrm_state_lookup(net, hdr, ext_hdrs); |
| 1584 | if (x == NULL) | 1590 | if (x == NULL) |
| 1585 | return -ESRCH; | 1591 | return -ESRCH; |
| 1586 | 1592 | ||
| @@ -1598,7 +1604,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, | |||
| 1598 | out_hdr->sadb_msg_reserved = 0; | 1604 | out_hdr->sadb_msg_reserved = 0; |
| 1599 | out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; | 1605 | out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; |
| 1600 | out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; | 1606 | out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; |
| 1601 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk); | 1607 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk)); |
| 1602 | 1608 | ||
| 1603 | return 0; | 1609 | return 0; |
| 1604 | } | 1610 | } |
| @@ -1699,7 +1705,7 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
| 1699 | return -ENOBUFS; | 1705 | return -ENOBUFS; |
| 1700 | } | 1706 | } |
| 1701 | 1707 | ||
| 1702 | pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk); | 1708 | pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk, sock_net(sk)); |
| 1703 | 1709 | ||
| 1704 | return 0; | 1710 | return 0; |
| 1705 | } | 1711 | } |
| @@ -1721,13 +1727,14 @@ static int key_notify_sa_flush(struct km_event *c) | |||
| 1721 | hdr->sadb_msg_errno = (uint8_t) 0; | 1727 | hdr->sadb_msg_errno = (uint8_t) 0; |
| 1722 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); | 1728 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); |
| 1723 | 1729 | ||
| 1724 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); | 1730 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); |
| 1725 | 1731 | ||
| 1726 | return 0; | 1732 | return 0; |
| 1727 | } | 1733 | } |
| 1728 | 1734 | ||
| 1729 | 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) |
| 1730 | { | 1736 | { |
| 1737 | struct net *net = sock_net(sk); | ||
| 1731 | unsigned proto; | 1738 | unsigned proto; |
| 1732 | struct km_event c; | 1739 | struct km_event c; |
| 1733 | struct xfrm_audit audit_info; | 1740 | struct xfrm_audit audit_info; |
| @@ -1740,14 +1747,14 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
| 1740 | audit_info.loginuid = audit_get_loginuid(current); | 1747 | audit_info.loginuid = audit_get_loginuid(current); |
| 1741 | audit_info.sessionid = audit_get_sessionid(current); | 1748 | audit_info.sessionid = audit_get_sessionid(current); |
| 1742 | audit_info.secid = 0; | 1749 | audit_info.secid = 0; |
| 1743 | err = xfrm_state_flush(&init_net, proto, &audit_info); | 1750 | err = xfrm_state_flush(net, proto, &audit_info); |
| 1744 | if (err) | 1751 | if (err) |
| 1745 | return err; | 1752 | return err; |
| 1746 | c.data.proto = proto; | 1753 | c.data.proto = proto; |
| 1747 | c.seq = hdr->sadb_msg_seq; | 1754 | c.seq = hdr->sadb_msg_seq; |
| 1748 | c.pid = hdr->sadb_msg_pid; | 1755 | c.pid = hdr->sadb_msg_pid; |
| 1749 | c.event = XFRM_MSG_FLUSHSA; | 1756 | c.event = XFRM_MSG_FLUSHSA; |
| 1750 | c.net = &init_net; | 1757 | c.net = net; |
| 1751 | km_state_notify(NULL, &c); | 1758 | km_state_notify(NULL, &c); |
| 1752 | 1759 | ||
| 1753 | return 0; | 1760 | return 0; |
| @@ -1777,7 +1784,7 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr) | |||
| 1777 | 1784 | ||
| 1778 | if (pfk->dump.skb) | 1785 | if (pfk->dump.skb) |
| 1779 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, | 1786 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, |
| 1780 | &pfk->sk); | 1787 | &pfk->sk, sock_net(&pfk->sk)); |
| 1781 | pfk->dump.skb = out_skb; | 1788 | pfk->dump.skb = out_skb; |
| 1782 | 1789 | ||
| 1783 | return 0; | 1790 | return 0; |
| @@ -1785,7 +1792,8 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr) | |||
| 1785 | 1792 | ||
| 1786 | static int pfkey_dump_sa(struct pfkey_sock *pfk) | 1793 | static int pfkey_dump_sa(struct pfkey_sock *pfk) |
| 1787 | { | 1794 | { |
| 1788 | return xfrm_state_walk(&init_net, &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); | ||
| 1789 | } | 1797 | } |
| 1790 | 1798 | ||
| 1791 | static void pfkey_dump_sa_done(struct pfkey_sock *pfk) | 1799 | static void pfkey_dump_sa_done(struct pfkey_sock *pfk) |
| @@ -1826,7 +1834,7 @@ static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, struct sadb_msg * | |||
| 1826 | return -EINVAL; | 1834 | return -EINVAL; |
| 1827 | pfk->promisc = satype; | 1835 | pfk->promisc = satype; |
| 1828 | } | 1836 | } |
| 1829 | 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)); |
| 1830 | return 0; | 1838 | return 0; |
| 1831 | } | 1839 | } |
| 1832 | 1840 | ||
| @@ -1842,7 +1850,7 @@ static int check_reqid(struct xfrm_policy *xp, int dir, int count, void *ptr) | |||
| 1842 | return 0; | 1850 | return 0; |
| 1843 | } | 1851 | } |
| 1844 | 1852 | ||
| 1845 | static u32 gen_reqid(void) | 1853 | static u32 gen_reqid(struct net *net) |
| 1846 | { | 1854 | { |
| 1847 | struct xfrm_policy_walk walk; | 1855 | struct xfrm_policy_walk walk; |
| 1848 | u32 start; | 1856 | u32 start; |
| @@ -1855,7 +1863,7 @@ static u32 gen_reqid(void) | |||
| 1855 | if (reqid == 0) | 1863 | if (reqid == 0) |
| 1856 | reqid = IPSEC_MANUAL_REQID_MAX+1; | 1864 | reqid = IPSEC_MANUAL_REQID_MAX+1; |
| 1857 | xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN); | 1865 | xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN); |
| 1858 | rc = xfrm_policy_walk(&init_net, &walk, check_reqid, (void*)&reqid); | 1866 | rc = xfrm_policy_walk(net, &walk, check_reqid, (void*)&reqid); |
| 1859 | xfrm_policy_walk_done(&walk); | 1867 | xfrm_policy_walk_done(&walk); |
| 1860 | if (rc != -EEXIST) | 1868 | if (rc != -EEXIST) |
| 1861 | return reqid; | 1869 | return reqid; |
| @@ -1866,6 +1874,7 @@ static u32 gen_reqid(void) | |||
| 1866 | static int | 1874 | static int |
| 1867 | parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) | 1875 | parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) |
| 1868 | { | 1876 | { |
| 1877 | struct net *net = xp_net(xp); | ||
| 1869 | struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; | 1878 | struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; |
| 1870 | int mode; | 1879 | int mode; |
| 1871 | 1880 | ||
| @@ -1885,7 +1894,7 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) | |||
| 1885 | t->reqid = rq->sadb_x_ipsecrequest_reqid; | 1894 | t->reqid = rq->sadb_x_ipsecrequest_reqid; |
| 1886 | if (t->reqid > IPSEC_MANUAL_REQID_MAX) | 1895 | if (t->reqid > IPSEC_MANUAL_REQID_MAX) |
| 1887 | t->reqid = 0; | 1896 | t->reqid = 0; |
| 1888 | if (!t->reqid && !(t->reqid = gen_reqid())) | 1897 | if (!t->reqid && !(t->reqid = gen_reqid(net))) |
| 1889 | return -ENOBUFS; | 1898 | return -ENOBUFS; |
| 1890 | } | 1899 | } |
| 1891 | 1900 | ||
| @@ -2156,7 +2165,7 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c | |||
| 2156 | out_hdr->sadb_msg_errno = 0; | 2165 | out_hdr->sadb_msg_errno = 0; |
| 2157 | out_hdr->sadb_msg_seq = c->seq; | 2166 | out_hdr->sadb_msg_seq = c->seq; |
| 2158 | out_hdr->sadb_msg_pid = c->pid; | 2167 | out_hdr->sadb_msg_pid = c->pid; |
| 2159 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL); | 2168 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp)); |
| 2160 | out: | 2169 | out: |
| 2161 | return 0; | 2170 | return 0; |
| 2162 | 2171 | ||
| @@ -2164,6 +2173,7 @@ out: | |||
| 2164 | 2173 | ||
| 2165 | 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) |
| 2166 | { | 2175 | { |
| 2176 | struct net *net = sock_net(sk); | ||
| 2167 | int err = 0; | 2177 | int err = 0; |
| 2168 | struct sadb_lifetime *lifetime; | 2178 | struct sadb_lifetime *lifetime; |
| 2169 | struct sadb_address *sa; | 2179 | struct sadb_address *sa; |
| @@ -2183,7 +2193,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 2183 | 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) |
| 2184 | return -EINVAL; | 2194 | return -EINVAL; |
| 2185 | 2195 | ||
| 2186 | xp = xfrm_policy_alloc(&init_net, GFP_KERNEL); | 2196 | xp = xfrm_policy_alloc(net, GFP_KERNEL); |
| 2187 | if (xp == NULL) | 2197 | if (xp == NULL) |
| 2188 | return -ENOBUFS; | 2198 | return -ENOBUFS; |
| 2189 | 2199 | ||
| @@ -2284,6 +2294,7 @@ out: | |||
| 2284 | 2294 | ||
| 2285 | 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) |
| 2286 | { | 2296 | { |
| 2297 | struct net *net = sock_net(sk); | ||
| 2287 | int err; | 2298 | int err; |
| 2288 | struct sadb_address *sa; | 2299 | struct sadb_address *sa; |
| 2289 | struct sadb_x_policy *pol; | 2300 | struct sadb_x_policy *pol; |
| @@ -2333,7 +2344,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
| 2333 | return err; | 2344 | return err; |
| 2334 | } | 2345 | } |
| 2335 | 2346 | ||
| 2336 | xp = xfrm_policy_bysel_ctx(&init_net, XFRM_POLICY_TYPE_MAIN, | 2347 | xp = xfrm_policy_bysel_ctx(net, XFRM_POLICY_TYPE_MAIN, |
| 2337 | pol->sadb_x_policy_dir - 1, &sel, pol_ctx, | 2348 | pol->sadb_x_policy_dir - 1, &sel, pol_ctx, |
| 2338 | 1, &err); | 2349 | 1, &err); |
| 2339 | security_xfrm_policy_free(pol_ctx); | 2350 | security_xfrm_policy_free(pol_ctx); |
| @@ -2381,7 +2392,7 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, struct sadb | |||
| 2381 | out_hdr->sadb_msg_errno = 0; | 2392 | out_hdr->sadb_msg_errno = 0; |
| 2382 | out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; | 2393 | out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; |
| 2383 | out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; | 2394 | out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; |
| 2384 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk); | 2395 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, xp_net(xp)); |
| 2385 | err = 0; | 2396 | err = 0; |
| 2386 | 2397 | ||
| 2387 | out: | 2398 | out: |
| @@ -2566,6 +2577,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb, | |||
| 2566 | 2577 | ||
| 2567 | 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) |
| 2568 | { | 2579 | { |
| 2580 | struct net *net = sock_net(sk); | ||
| 2569 | unsigned int dir; | 2581 | unsigned int dir; |
| 2570 | int err = 0, delete; | 2582 | int err = 0, delete; |
| 2571 | struct sadb_x_policy *pol; | 2583 | struct sadb_x_policy *pol; |
| @@ -2580,7 +2592,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 2580 | return -EINVAL; | 2592 | return -EINVAL; |
| 2581 | 2593 | ||
| 2582 | delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2); | 2594 | delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2); |
| 2583 | xp = xfrm_policy_byid(&init_net, XFRM_POLICY_TYPE_MAIN, dir, | 2595 | xp = xfrm_policy_byid(net, XFRM_POLICY_TYPE_MAIN, dir, |
| 2584 | pol->sadb_x_policy_id, delete, &err); | 2596 | pol->sadb_x_policy_id, delete, &err); |
| 2585 | if (xp == NULL) | 2597 | if (xp == NULL) |
| 2586 | return -ENOENT; | 2598 | return -ENOENT; |
| @@ -2634,7 +2646,7 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) | |||
| 2634 | 2646 | ||
| 2635 | if (pfk->dump.skb) | 2647 | if (pfk->dump.skb) |
| 2636 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, | 2648 | pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, |
| 2637 | &pfk->sk); | 2649 | &pfk->sk, sock_net(&pfk->sk)); |
| 2638 | pfk->dump.skb = out_skb; | 2650 | pfk->dump.skb = out_skb; |
| 2639 | 2651 | ||
| 2640 | return 0; | 2652 | return 0; |
| @@ -2642,7 +2654,8 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) | |||
| 2642 | 2654 | ||
| 2643 | static int pfkey_dump_sp(struct pfkey_sock *pfk) | 2655 | static int pfkey_dump_sp(struct pfkey_sock *pfk) |
| 2644 | { | 2656 | { |
| 2645 | return xfrm_policy_walk(&init_net, &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); | ||
| 2646 | } | 2659 | } |
| 2647 | 2660 | ||
| 2648 | static void pfkey_dump_sp_done(struct pfkey_sock *pfk) | 2661 | static void pfkey_dump_sp_done(struct pfkey_sock *pfk) |
| @@ -2681,13 +2694,14 @@ static int key_notify_policy_flush(struct km_event *c) | |||
| 2681 | hdr->sadb_msg_version = PF_KEY_V2; | 2694 | hdr->sadb_msg_version = PF_KEY_V2; |
| 2682 | hdr->sadb_msg_errno = (uint8_t) 0; | 2695 | hdr->sadb_msg_errno = (uint8_t) 0; |
| 2683 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); | 2696 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); |
| 2684 | pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL); | 2697 | pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); |
| 2685 | return 0; | 2698 | return 0; |
| 2686 | 2699 | ||
| 2687 | } | 2700 | } |
| 2688 | 2701 | ||
| 2689 | 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) |
| 2690 | { | 2703 | { |
| 2704 | struct net *net = sock_net(sk); | ||
| 2691 | struct km_event c; | 2705 | struct km_event c; |
| 2692 | struct xfrm_audit audit_info; | 2706 | struct xfrm_audit audit_info; |
| 2693 | int err; | 2707 | int err; |
| @@ -2695,14 +2709,14 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
| 2695 | audit_info.loginuid = audit_get_loginuid(current); | 2709 | audit_info.loginuid = audit_get_loginuid(current); |
| 2696 | audit_info.sessionid = audit_get_sessionid(current); | 2710 | audit_info.sessionid = audit_get_sessionid(current); |
| 2697 | audit_info.secid = 0; | 2711 | audit_info.secid = 0; |
| 2698 | err = xfrm_policy_flush(&init_net, XFRM_POLICY_TYPE_MAIN, &audit_info); | 2712 | err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); |
| 2699 | if (err) | 2713 | if (err) |
| 2700 | return err; | 2714 | return err; |
| 2701 | c.data.type = XFRM_POLICY_TYPE_MAIN; | 2715 | c.data.type = XFRM_POLICY_TYPE_MAIN; |
| 2702 | c.event = XFRM_MSG_FLUSHPOLICY; | 2716 | c.event = XFRM_MSG_FLUSHPOLICY; |
| 2703 | c.pid = hdr->sadb_msg_pid; | 2717 | c.pid = hdr->sadb_msg_pid; |
| 2704 | c.seq = hdr->sadb_msg_seq; | 2718 | c.seq = hdr->sadb_msg_seq; |
| 2705 | c.net = &init_net; | 2719 | c.net = net; |
| 2706 | km_policy_notify(NULL, 0, &c); | 2720 | km_policy_notify(NULL, 0, &c); |
| 2707 | 2721 | ||
| 2708 | return 0; | 2722 | return 0; |
| @@ -2742,7 +2756,7 @@ static int pfkey_process(struct sock *sk, struct sk_buff *skb, struct sadb_msg * | |||
| 2742 | int err; | 2756 | int err; |
| 2743 | 2757 | ||
| 2744 | pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, | 2758 | pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, |
| 2745 | BROADCAST_PROMISC_ONLY, NULL); | 2759 | BROADCAST_PROMISC_ONLY, NULL, sock_net(sk)); |
| 2746 | 2760 | ||
| 2747 | memset(ext_hdrs, 0, sizeof(ext_hdrs)); | 2761 | memset(ext_hdrs, 0, sizeof(ext_hdrs)); |
| 2748 | err = parse_exthdrs(skb, hdr, ext_hdrs); | 2762 | err = parse_exthdrs(skb, hdr, ext_hdrs); |
| @@ -2945,13 +2959,13 @@ static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c) | |||
| 2945 | out_hdr->sadb_msg_seq = 0; | 2959 | out_hdr->sadb_msg_seq = 0; |
| 2946 | out_hdr->sadb_msg_pid = 0; | 2960 | out_hdr->sadb_msg_pid = 0; |
| 2947 | 2961 | ||
| 2948 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL); | 2962 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x)); |
| 2949 | return 0; | 2963 | return 0; |
| 2950 | } | 2964 | } |
| 2951 | 2965 | ||
| 2952 | 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) |
| 2953 | { | 2967 | { |
| 2954 | struct net *net = &init_net; | 2968 | struct net *net = x ? xs_net(x) : c->net; |
| 2955 | struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); | 2969 | struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); |
| 2956 | 2970 | ||
| 2957 | if (atomic_read(&net_pfkey->socks_nr) == 0) | 2971 | if (atomic_read(&net_pfkey->socks_nr) == 0) |
| @@ -3116,12 +3130,13 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
| 3116 | xfrm_ctx->ctx_len); | 3130 | xfrm_ctx->ctx_len); |
| 3117 | } | 3131 | } |
| 3118 | 3132 | ||
| 3119 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL); | 3133 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x)); |
| 3120 | } | 3134 | } |
| 3121 | 3135 | ||
| 3122 | 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, |
| 3123 | u8 *data, int len, int *dir) | 3137 | u8 *data, int len, int *dir) |
| 3124 | { | 3138 | { |
| 3139 | struct net *net = sock_net(sk); | ||
| 3125 | struct xfrm_policy *xp; | 3140 | struct xfrm_policy *xp; |
| 3126 | struct sadb_x_policy *pol = (struct sadb_x_policy*)data; | 3141 | struct sadb_x_policy *pol = (struct sadb_x_policy*)data; |
| 3127 | struct sadb_x_sec_ctx *sec_ctx; | 3142 | struct sadb_x_sec_ctx *sec_ctx; |
| @@ -3154,7 +3169,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, | |||
| 3154 | (!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)) |
| 3155 | return NULL; | 3170 | return NULL; |
| 3156 | 3171 | ||
| 3157 | xp = xfrm_policy_alloc(&init_net, GFP_ATOMIC); | 3172 | xp = xfrm_policy_alloc(net, GFP_ATOMIC); |
| 3158 | if (xp == NULL) { | 3173 | if (xp == NULL) { |
| 3159 | *dir = -ENOBUFS; | 3174 | *dir = -ENOBUFS; |
| 3160 | return NULL; | 3175 | return NULL; |
| @@ -3313,7 +3328,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | |||
| 3313 | n_port->sadb_x_nat_t_port_port = sport; | 3328 | n_port->sadb_x_nat_t_port_port = sport; |
| 3314 | n_port->sadb_x_nat_t_port_reserved = 0; | 3329 | n_port->sadb_x_nat_t_port_reserved = 0; |
| 3315 | 3330 | ||
| 3316 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL); | 3331 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x)); |
| 3317 | } | 3332 | } |
| 3318 | 3333 | ||
| 3319 | #ifdef CONFIG_NET_KEY_MIGRATE | 3334 | #ifdef CONFIG_NET_KEY_MIGRATE |
| @@ -3504,7 +3519,7 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | |||
| 3504 | } | 3519 | } |
| 3505 | 3520 | ||
| 3506 | /* broadcast migrate message to sockets */ | 3521 | /* broadcast migrate message to sockets */ |
| 3507 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); | 3522 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net); |
| 3508 | 3523 | ||
| 3509 | return 0; | 3524 | return 0; |
| 3510 | 3525 | ||
