diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:38:20 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:38:20 -0500 |
commit | a6483b790f8efcd8db190c1c0ff93f9d9efe919a (patch) | |
tree | e05ba1d3e7014409a69d878bf9f24c5eb93365e4 | |
parent | bd235e3cfff617ff91677da553714051866ba55f (diff) |
netns xfrm: per-netns NETLINK_XFRM socket
Stub senders to init_net's one temporarily.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/netns/xfrm.h | 2 | ||||
-rw-r--r-- | include/net/xfrm.h | 7 | ||||
-rw-r--r-- | net/xfrm/xfrm_output.c | 3 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 7 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 108 |
5 files changed, 83 insertions, 44 deletions
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index c53d17357a49..09f3060e9d18 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h | |||
@@ -39,6 +39,8 @@ struct netns_xfrm { | |||
39 | struct xfrm_policy_hash policy_bydst[XFRM_POLICY_MAX * 2]; | 39 | struct xfrm_policy_hash policy_bydst[XFRM_POLICY_MAX * 2]; |
40 | unsigned int policy_count[XFRM_POLICY_MAX * 2]; | 40 | unsigned int policy_count[XFRM_POLICY_MAX * 2]; |
41 | struct work_struct policy_hash_work; | 41 | struct work_struct policy_hash_work; |
42 | |||
43 | struct sock *nlsk; | ||
42 | }; | 44 | }; |
43 | 45 | ||
44 | #endif | 46 | #endif |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index bd2515005ae2..e027179e8199 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -48,7 +48,6 @@ DECLARE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics); | |||
48 | #define XFRM_INC_STATS_USER(field) | 48 | #define XFRM_INC_STATS_USER(field) |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | extern struct sock *xfrm_nl; | ||
52 | extern u32 sysctl_xfrm_aevent_etime; | 51 | extern u32 sysctl_xfrm_aevent_etime; |
53 | extern u32 sysctl_xfrm_aevent_rseqth; | 52 | extern u32 sysctl_xfrm_aevent_rseqth; |
54 | extern int sysctl_xfrm_larval_drop; | 53 | extern int sysctl_xfrm_larval_drop; |
@@ -1516,18 +1515,20 @@ static inline int xfrm_policy_id2dir(u32 index) | |||
1516 | return index & 7; | 1515 | return index & 7; |
1517 | } | 1516 | } |
1518 | 1517 | ||
1519 | static inline int xfrm_aevent_is_on(void) | 1518 | #ifdef CONFIG_XFRM |
1519 | static inline int xfrm_aevent_is_on(struct net *net) | ||
1520 | { | 1520 | { |
1521 | struct sock *nlsk; | 1521 | struct sock *nlsk; |
1522 | int ret = 0; | 1522 | int ret = 0; |
1523 | 1523 | ||
1524 | rcu_read_lock(); | 1524 | rcu_read_lock(); |
1525 | nlsk = rcu_dereference(xfrm_nl); | 1525 | nlsk = rcu_dereference(net->xfrm.nlsk); |
1526 | if (nlsk) | 1526 | if (nlsk) |
1527 | ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS); | 1527 | ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS); |
1528 | rcu_read_unlock(); | 1528 | rcu_read_unlock(); |
1529 | return ret; | 1529 | return ret; |
1530 | } | 1530 | } |
1531 | #endif | ||
1531 | 1532 | ||
1532 | static inline int xfrm_alg_len(struct xfrm_algo *alg) | 1533 | static inline int xfrm_alg_len(struct xfrm_algo *alg) |
1533 | { | 1534 | { |
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index dc50f1e71f76..ba90e5e50ffc 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c | |||
@@ -41,6 +41,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) | |||
41 | { | 41 | { |
42 | struct dst_entry *dst = skb->dst; | 42 | struct dst_entry *dst = skb->dst; |
43 | struct xfrm_state *x = dst->xfrm; | 43 | struct xfrm_state *x = dst->xfrm; |
44 | struct net *net = xs_net(x); | ||
44 | 45 | ||
45 | if (err <= 0) | 46 | if (err <= 0) |
46 | goto resume; | 47 | goto resume; |
@@ -74,7 +75,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) | |||
74 | err = -EOVERFLOW; | 75 | err = -EOVERFLOW; |
75 | goto error; | 76 | goto error; |
76 | } | 77 | } |
77 | if (xfrm_aevent_is_on()) | 78 | if (xfrm_aevent_is_on(net)) |
78 | xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); | 79 | xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); |
79 | } | 80 | } |
80 | 81 | ||
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index ea340bbbcc64..21db37ab0a2f 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -24,9 +24,6 @@ | |||
24 | 24 | ||
25 | #include "xfrm_hash.h" | 25 | #include "xfrm_hash.h" |
26 | 26 | ||
27 | struct sock *xfrm_nl; | ||
28 | EXPORT_SYMBOL(xfrm_nl); | ||
29 | |||
30 | u32 sysctl_xfrm_aevent_etime __read_mostly = XFRM_AE_ETIME; | 27 | u32 sysctl_xfrm_aevent_etime __read_mostly = XFRM_AE_ETIME; |
31 | EXPORT_SYMBOL(sysctl_xfrm_aevent_etime); | 28 | EXPORT_SYMBOL(sysctl_xfrm_aevent_etime); |
32 | 29 | ||
@@ -1659,7 +1656,7 @@ static void xfrm_replay_timer_handler(unsigned long data) | |||
1659 | spin_lock(&x->lock); | 1656 | spin_lock(&x->lock); |
1660 | 1657 | ||
1661 | if (x->km.state == XFRM_STATE_VALID) { | 1658 | if (x->km.state == XFRM_STATE_VALID) { |
1662 | if (xfrm_aevent_is_on()) | 1659 | if (xfrm_aevent_is_on(xs_net(x))) |
1663 | xfrm_replay_notify(x, XFRM_REPLAY_TIMEOUT); | 1660 | xfrm_replay_notify(x, XFRM_REPLAY_TIMEOUT); |
1664 | else | 1661 | else |
1665 | x->xflags |= XFRM_TIME_DEFER; | 1662 | x->xflags |= XFRM_TIME_DEFER; |
@@ -1715,7 +1712,7 @@ void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq) | |||
1715 | x->replay.bitmap |= (1U << diff); | 1712 | x->replay.bitmap |= (1U << diff); |
1716 | } | 1713 | } |
1717 | 1714 | ||
1718 | if (xfrm_aevent_is_on()) | 1715 | if (xfrm_aevent_is_on(xs_net(x))) |
1719 | xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); | 1716 | xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); |
1720 | } | 1717 | } |
1721 | 1718 | ||
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index f6e02726cf1b..8b5b01dfb77a 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -703,6 +703,7 @@ nla_put_failure: | |||
703 | static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | 703 | static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, |
704 | struct nlattr **attrs) | 704 | struct nlattr **attrs) |
705 | { | 705 | { |
706 | struct net *net = sock_net(skb->sk); | ||
706 | struct sk_buff *r_skb; | 707 | struct sk_buff *r_skb; |
707 | u32 *flags = nlmsg_data(nlh); | 708 | u32 *flags = nlmsg_data(nlh); |
708 | u32 spid = NETLINK_CB(skb).pid; | 709 | u32 spid = NETLINK_CB(skb).pid; |
@@ -715,7 +716,7 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
715 | if (build_spdinfo(r_skb, spid, seq, *flags) < 0) | 716 | if (build_spdinfo(r_skb, spid, seq, *flags) < 0) |
716 | BUG(); | 717 | BUG(); |
717 | 718 | ||
718 | return nlmsg_unicast(xfrm_nl, r_skb, spid); | 719 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid); |
719 | } | 720 | } |
720 | 721 | ||
721 | static inline size_t xfrm_sadinfo_msgsize(void) | 722 | static inline size_t xfrm_sadinfo_msgsize(void) |
@@ -756,6 +757,7 @@ nla_put_failure: | |||
756 | static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | 757 | static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh, |
757 | struct nlattr **attrs) | 758 | struct nlattr **attrs) |
758 | { | 759 | { |
760 | struct net *net = sock_net(skb->sk); | ||
759 | struct sk_buff *r_skb; | 761 | struct sk_buff *r_skb; |
760 | u32 *flags = nlmsg_data(nlh); | 762 | u32 *flags = nlmsg_data(nlh); |
761 | u32 spid = NETLINK_CB(skb).pid; | 763 | u32 spid = NETLINK_CB(skb).pid; |
@@ -768,12 +770,13 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
768 | if (build_sadinfo(r_skb, spid, seq, *flags) < 0) | 770 | if (build_sadinfo(r_skb, spid, seq, *flags) < 0) |
769 | BUG(); | 771 | BUG(); |
770 | 772 | ||
771 | return nlmsg_unicast(xfrm_nl, r_skb, spid); | 773 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid); |
772 | } | 774 | } |
773 | 775 | ||
774 | static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | 776 | static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, |
775 | struct nlattr **attrs) | 777 | struct nlattr **attrs) |
776 | { | 778 | { |
779 | struct net *net = &init_net; | ||
777 | struct xfrm_usersa_id *p = nlmsg_data(nlh); | 780 | struct xfrm_usersa_id *p = nlmsg_data(nlh); |
778 | struct xfrm_state *x; | 781 | struct xfrm_state *x; |
779 | struct sk_buff *resp_skb; | 782 | struct sk_buff *resp_skb; |
@@ -787,7 +790,7 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
787 | if (IS_ERR(resp_skb)) { | 790 | if (IS_ERR(resp_skb)) { |
788 | err = PTR_ERR(resp_skb); | 791 | err = PTR_ERR(resp_skb); |
789 | } else { | 792 | } else { |
790 | err = nlmsg_unicast(xfrm_nl, resp_skb, NETLINK_CB(skb).pid); | 793 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).pid); |
791 | } | 794 | } |
792 | xfrm_state_put(x); | 795 | xfrm_state_put(x); |
793 | out_noput: | 796 | out_noput: |
@@ -820,6 +823,7 @@ static int verify_userspi_info(struct xfrm_userspi_info *p) | |||
820 | static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | 823 | static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, |
821 | struct nlattr **attrs) | 824 | struct nlattr **attrs) |
822 | { | 825 | { |
826 | struct net *net = &init_net; | ||
823 | struct xfrm_state *x; | 827 | struct xfrm_state *x; |
824 | struct xfrm_userspi_info *p; | 828 | struct xfrm_userspi_info *p; |
825 | struct sk_buff *resp_skb; | 829 | struct sk_buff *resp_skb; |
@@ -837,7 +841,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
837 | 841 | ||
838 | x = NULL; | 842 | x = NULL; |
839 | if (p->info.seq) { | 843 | if (p->info.seq) { |
840 | x = xfrm_find_acq_byseq(&init_net, p->info.seq); | 844 | x = xfrm_find_acq_byseq(net, p->info.seq); |
841 | if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) { | 845 | if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) { |
842 | xfrm_state_put(x); | 846 | xfrm_state_put(x); |
843 | x = NULL; | 847 | x = NULL; |
@@ -845,7 +849,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
845 | } | 849 | } |
846 | 850 | ||
847 | if (!x) | 851 | if (!x) |
848 | x = xfrm_find_acq(&init_net, p->info.mode, p->info.reqid, | 852 | x = xfrm_find_acq(net, p->info.mode, p->info.reqid, |
849 | p->info.id.proto, daddr, | 853 | p->info.id.proto, daddr, |
850 | &p->info.saddr, 1, | 854 | &p->info.saddr, 1, |
851 | family); | 855 | family); |
@@ -863,7 +867,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
863 | goto out; | 867 | goto out; |
864 | } | 868 | } |
865 | 869 | ||
866 | err = nlmsg_unicast(xfrm_nl, resp_skb, NETLINK_CB(skb).pid); | 870 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).pid); |
867 | 871 | ||
868 | out: | 872 | out: |
869 | xfrm_state_put(x); | 873 | xfrm_state_put(x); |
@@ -1311,6 +1315,7 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb, | |||
1311 | static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | 1315 | static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, |
1312 | struct nlattr **attrs) | 1316 | struct nlattr **attrs) |
1313 | { | 1317 | { |
1318 | struct net *net = &init_net; | ||
1314 | struct xfrm_policy *xp; | 1319 | struct xfrm_policy *xp; |
1315 | struct xfrm_userpolicy_id *p; | 1320 | struct xfrm_userpolicy_id *p; |
1316 | u8 type = XFRM_POLICY_TYPE_MAIN; | 1321 | u8 type = XFRM_POLICY_TYPE_MAIN; |
@@ -1330,7 +1335,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1330 | return err; | 1335 | return err; |
1331 | 1336 | ||
1332 | if (p->index) | 1337 | if (p->index) |
1333 | xp = xfrm_policy_byid(&init_net, type, p->dir, p->index, delete, &err); | 1338 | xp = xfrm_policy_byid(net, type, p->dir, p->index, delete, &err); |
1334 | else { | 1339 | else { |
1335 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; | 1340 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
1336 | struct xfrm_sec_ctx *ctx; | 1341 | struct xfrm_sec_ctx *ctx; |
@@ -1347,7 +1352,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1347 | if (err) | 1352 | if (err) |
1348 | return err; | 1353 | return err; |
1349 | } | 1354 | } |
1350 | xp = xfrm_policy_bysel_ctx(&init_net, type, p->dir, &p->sel, ctx, | 1355 | xp = xfrm_policy_bysel_ctx(net, type, p->dir, &p->sel, ctx, |
1351 | delete, &err); | 1356 | delete, &err); |
1352 | security_xfrm_policy_free(ctx); | 1357 | security_xfrm_policy_free(ctx); |
1353 | } | 1358 | } |
@@ -1361,7 +1366,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1361 | if (IS_ERR(resp_skb)) { | 1366 | if (IS_ERR(resp_skb)) { |
1362 | err = PTR_ERR(resp_skb); | 1367 | err = PTR_ERR(resp_skb); |
1363 | } else { | 1368 | } else { |
1364 | err = nlmsg_unicast(xfrm_nl, resp_skb, | 1369 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, |
1365 | NETLINK_CB(skb).pid); | 1370 | NETLINK_CB(skb).pid); |
1366 | } | 1371 | } |
1367 | } else { | 1372 | } else { |
@@ -1457,6 +1462,7 @@ nla_put_failure: | |||
1457 | static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | 1462 | static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, |
1458 | struct nlattr **attrs) | 1463 | struct nlattr **attrs) |
1459 | { | 1464 | { |
1465 | struct net *net = &init_net; | ||
1460 | struct xfrm_state *x; | 1466 | struct xfrm_state *x; |
1461 | struct sk_buff *r_skb; | 1467 | struct sk_buff *r_skb; |
1462 | int err; | 1468 | int err; |
@@ -1468,7 +1474,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1468 | if (r_skb == NULL) | 1474 | if (r_skb == NULL) |
1469 | return -ENOMEM; | 1475 | return -ENOMEM; |
1470 | 1476 | ||
1471 | x = xfrm_state_lookup(&init_net, &id->daddr, id->spi, id->proto, id->family); | 1477 | x = xfrm_state_lookup(net, &id->daddr, id->spi, id->proto, id->family); |
1472 | if (x == NULL) { | 1478 | if (x == NULL) { |
1473 | kfree_skb(r_skb); | 1479 | kfree_skb(r_skb); |
1474 | return -ESRCH; | 1480 | return -ESRCH; |
@@ -1486,7 +1492,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1486 | 1492 | ||
1487 | if (build_aevent(r_skb, x, &c) < 0) | 1493 | if (build_aevent(r_skb, x, &c) < 0) |
1488 | BUG(); | 1494 | BUG(); |
1489 | err = nlmsg_unicast(xfrm_nl, r_skb, NETLINK_CB(skb).pid); | 1495 | err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).pid); |
1490 | spin_unlock_bh(&x->lock); | 1496 | spin_unlock_bh(&x->lock); |
1491 | xfrm_state_put(x); | 1497 | xfrm_state_put(x); |
1492 | return err; | 1498 | return err; |
@@ -1869,6 +1875,7 @@ static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | |||
1869 | struct xfrm_migrate *m, int num_migrate, | 1875 | struct xfrm_migrate *m, int num_migrate, |
1870 | struct xfrm_kmaddress *k) | 1876 | struct xfrm_kmaddress *k) |
1871 | { | 1877 | { |
1878 | struct net *net = &init_net; | ||
1872 | struct sk_buff *skb; | 1879 | struct sk_buff *skb; |
1873 | 1880 | ||
1874 | skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k), GFP_ATOMIC); | 1881 | skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k), GFP_ATOMIC); |
@@ -1879,7 +1886,7 @@ static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | |||
1879 | if (build_migrate(skb, m, num_migrate, k, sel, dir, type) < 0) | 1886 | if (build_migrate(skb, m, num_migrate, k, sel, dir, type) < 0) |
1880 | BUG(); | 1887 | BUG(); |
1881 | 1888 | ||
1882 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC); | 1889 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC); |
1883 | } | 1890 | } |
1884 | #else | 1891 | #else |
1885 | static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | 1892 | static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, |
@@ -1968,6 +1975,7 @@ static struct xfrm_link { | |||
1968 | 1975 | ||
1969 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 1976 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
1970 | { | 1977 | { |
1978 | struct net *net = sock_net(skb->sk); | ||
1971 | struct nlattr *attrs[XFRMA_MAX+1]; | 1979 | struct nlattr *attrs[XFRMA_MAX+1]; |
1972 | struct xfrm_link *link; | 1980 | struct xfrm_link *link; |
1973 | int type, err; | 1981 | int type, err; |
@@ -1989,7 +1997,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1989 | if (link->dump == NULL) | 1997 | if (link->dump == NULL) |
1990 | return -EINVAL; | 1998 | return -EINVAL; |
1991 | 1999 | ||
1992 | return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, link->done); | 2000 | return netlink_dump_start(net->xfrm.nlsk, skb, nlh, link->dump, link->done); |
1993 | } | 2001 | } |
1994 | 2002 | ||
1995 | err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX, | 2003 | err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX, |
@@ -2033,6 +2041,7 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_eve | |||
2033 | 2041 | ||
2034 | static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) | 2042 | static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) |
2035 | { | 2043 | { |
2044 | struct net *net = &init_net; | ||
2036 | struct sk_buff *skb; | 2045 | struct sk_buff *skb; |
2037 | 2046 | ||
2038 | skb = nlmsg_new(xfrm_expire_msgsize(), GFP_ATOMIC); | 2047 | skb = nlmsg_new(xfrm_expire_msgsize(), GFP_ATOMIC); |
@@ -2042,11 +2051,12 @@ static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) | |||
2042 | if (build_expire(skb, x, c) < 0) | 2051 | if (build_expire(skb, x, c) < 0) |
2043 | BUG(); | 2052 | BUG(); |
2044 | 2053 | ||
2045 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); | 2054 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); |
2046 | } | 2055 | } |
2047 | 2056 | ||
2048 | static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c) | 2057 | static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c) |
2049 | { | 2058 | { |
2059 | struct net *net = &init_net; | ||
2050 | struct sk_buff *skb; | 2060 | struct sk_buff *skb; |
2051 | 2061 | ||
2052 | skb = nlmsg_new(xfrm_aevent_msgsize(), GFP_ATOMIC); | 2062 | skb = nlmsg_new(xfrm_aevent_msgsize(), GFP_ATOMIC); |
@@ -2056,11 +2066,12 @@ static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c) | |||
2056 | if (build_aevent(skb, x, c) < 0) | 2066 | if (build_aevent(skb, x, c) < 0) |
2057 | BUG(); | 2067 | BUG(); |
2058 | 2068 | ||
2059 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_AEVENTS, GFP_ATOMIC); | 2069 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_AEVENTS, GFP_ATOMIC); |
2060 | } | 2070 | } |
2061 | 2071 | ||
2062 | static int xfrm_notify_sa_flush(struct km_event *c) | 2072 | static int xfrm_notify_sa_flush(struct km_event *c) |
2063 | { | 2073 | { |
2074 | struct net *net = &init_net; | ||
2064 | struct xfrm_usersa_flush *p; | 2075 | struct xfrm_usersa_flush *p; |
2065 | struct nlmsghdr *nlh; | 2076 | struct nlmsghdr *nlh; |
2066 | struct sk_buff *skb; | 2077 | struct sk_buff *skb; |
@@ -2081,7 +2092,7 @@ static int xfrm_notify_sa_flush(struct km_event *c) | |||
2081 | 2092 | ||
2082 | nlmsg_end(skb, nlh); | 2093 | nlmsg_end(skb, nlh); |
2083 | 2094 | ||
2084 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); | 2095 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); |
2085 | } | 2096 | } |
2086 | 2097 | ||
2087 | static inline size_t xfrm_sa_len(struct xfrm_state *x) | 2098 | static inline size_t xfrm_sa_len(struct xfrm_state *x) |
@@ -2111,6 +2122,7 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x) | |||
2111 | 2122 | ||
2112 | static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) | 2123 | static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) |
2113 | { | 2124 | { |
2125 | struct net *net = &init_net; | ||
2114 | struct xfrm_usersa_info *p; | 2126 | struct xfrm_usersa_info *p; |
2115 | struct xfrm_usersa_id *id; | 2127 | struct xfrm_usersa_id *id; |
2116 | struct nlmsghdr *nlh; | 2128 | struct nlmsghdr *nlh; |
@@ -2155,7 +2167,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) | |||
2155 | 2167 | ||
2156 | nlmsg_end(skb, nlh); | 2168 | nlmsg_end(skb, nlh); |
2157 | 2169 | ||
2158 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); | 2170 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); |
2159 | 2171 | ||
2160 | nla_put_failure: | 2172 | nla_put_failure: |
2161 | /* Somebody screwed up with xfrm_sa_len! */ | 2173 | /* Somebody screwed up with xfrm_sa_len! */ |
@@ -2235,6 +2247,7 @@ nlmsg_failure: | |||
2235 | static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | 2247 | static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, |
2236 | struct xfrm_policy *xp, int dir) | 2248 | struct xfrm_policy *xp, int dir) |
2237 | { | 2249 | { |
2250 | struct net *net = xs_net(x); | ||
2238 | struct sk_buff *skb; | 2251 | struct sk_buff *skb; |
2239 | 2252 | ||
2240 | skb = nlmsg_new(xfrm_acquire_msgsize(x, xp), GFP_ATOMIC); | 2253 | skb = nlmsg_new(xfrm_acquire_msgsize(x, xp), GFP_ATOMIC); |
@@ -2244,7 +2257,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | |||
2244 | if (build_acquire(skb, x, xt, xp, dir) < 0) | 2257 | if (build_acquire(skb, x, xt, xp, dir) < 0) |
2245 | BUG(); | 2258 | BUG(); |
2246 | 2259 | ||
2247 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_ACQUIRE, GFP_ATOMIC); | 2260 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_ACQUIRE, GFP_ATOMIC); |
2248 | } | 2261 | } |
2249 | 2262 | ||
2250 | /* User gives us xfrm_user_policy_info followed by an array of 0 | 2263 | /* User gives us xfrm_user_policy_info followed by an array of 0 |
@@ -2344,6 +2357,7 @@ nlmsg_failure: | |||
2344 | 2357 | ||
2345 | static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c) | 2358 | static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c) |
2346 | { | 2359 | { |
2360 | struct net *net = &init_net; | ||
2347 | struct sk_buff *skb; | 2361 | struct sk_buff *skb; |
2348 | 2362 | ||
2349 | skb = nlmsg_new(xfrm_polexpire_msgsize(xp), GFP_ATOMIC); | 2363 | skb = nlmsg_new(xfrm_polexpire_msgsize(xp), GFP_ATOMIC); |
@@ -2353,11 +2367,12 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve | |||
2353 | if (build_polexpire(skb, xp, dir, c) < 0) | 2367 | if (build_polexpire(skb, xp, dir, c) < 0) |
2354 | BUG(); | 2368 | BUG(); |
2355 | 2369 | ||
2356 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); | 2370 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); |
2357 | } | 2371 | } |
2358 | 2372 | ||
2359 | static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c) | 2373 | static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c) |
2360 | { | 2374 | { |
2375 | struct net *net = &init_net; | ||
2361 | struct xfrm_userpolicy_info *p; | 2376 | struct xfrm_userpolicy_info *p; |
2362 | struct xfrm_userpolicy_id *id; | 2377 | struct xfrm_userpolicy_id *id; |
2363 | struct nlmsghdr *nlh; | 2378 | struct nlmsghdr *nlh; |
@@ -2408,7 +2423,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
2408 | 2423 | ||
2409 | nlmsg_end(skb, nlh); | 2424 | nlmsg_end(skb, nlh); |
2410 | 2425 | ||
2411 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); | 2426 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); |
2412 | 2427 | ||
2413 | nlmsg_failure: | 2428 | nlmsg_failure: |
2414 | kfree_skb(skb); | 2429 | kfree_skb(skb); |
@@ -2417,6 +2432,7 @@ nlmsg_failure: | |||
2417 | 2432 | ||
2418 | static int xfrm_notify_policy_flush(struct km_event *c) | 2433 | static int xfrm_notify_policy_flush(struct km_event *c) |
2419 | { | 2434 | { |
2435 | struct net *net = &init_net; | ||
2420 | struct nlmsghdr *nlh; | 2436 | struct nlmsghdr *nlh; |
2421 | struct sk_buff *skb; | 2437 | struct sk_buff *skb; |
2422 | 2438 | ||
@@ -2432,7 +2448,7 @@ static int xfrm_notify_policy_flush(struct km_event *c) | |||
2432 | 2448 | ||
2433 | nlmsg_end(skb, nlh); | 2449 | nlmsg_end(skb, nlh); |
2434 | 2450 | ||
2435 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); | 2451 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); |
2436 | 2452 | ||
2437 | nlmsg_failure: | 2453 | nlmsg_failure: |
2438 | kfree_skb(skb); | 2454 | kfree_skb(skb); |
@@ -2491,6 +2507,7 @@ nla_put_failure: | |||
2491 | static int xfrm_send_report(u8 proto, struct xfrm_selector *sel, | 2507 | static int xfrm_send_report(u8 proto, struct xfrm_selector *sel, |
2492 | xfrm_address_t *addr) | 2508 | xfrm_address_t *addr) |
2493 | { | 2509 | { |
2510 | struct net *net = &init_net; | ||
2494 | struct sk_buff *skb; | 2511 | struct sk_buff *skb; |
2495 | 2512 | ||
2496 | skb = nlmsg_new(xfrm_report_msgsize(), GFP_ATOMIC); | 2513 | skb = nlmsg_new(xfrm_report_msgsize(), GFP_ATOMIC); |
@@ -2500,7 +2517,7 @@ static int xfrm_send_report(u8 proto, struct xfrm_selector *sel, | |||
2500 | if (build_report(skb, proto, sel, addr) < 0) | 2517 | if (build_report(skb, proto, sel, addr) < 0) |
2501 | BUG(); | 2518 | BUG(); |
2502 | 2519 | ||
2503 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_REPORT, GFP_ATOMIC); | 2520 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_REPORT, GFP_ATOMIC); |
2504 | } | 2521 | } |
2505 | 2522 | ||
2506 | static inline size_t xfrm_mapping_msgsize(void) | 2523 | static inline size_t xfrm_mapping_msgsize(void) |
@@ -2536,6 +2553,7 @@ static int build_mapping(struct sk_buff *skb, struct xfrm_state *x, | |||
2536 | static int xfrm_send_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | 2553 | static int xfrm_send_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, |
2537 | __be16 sport) | 2554 | __be16 sport) |
2538 | { | 2555 | { |
2556 | struct net *net = xs_net(x); | ||
2539 | struct sk_buff *skb; | 2557 | struct sk_buff *skb; |
2540 | 2558 | ||
2541 | if (x->id.proto != IPPROTO_ESP) | 2559 | if (x->id.proto != IPPROTO_ESP) |
@@ -2551,7 +2569,7 @@ static int xfrm_send_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | |||
2551 | if (build_mapping(skb, x, ipaddr, sport) < 0) | 2569 | if (build_mapping(skb, x, ipaddr, sport) < 0) |
2552 | BUG(); | 2570 | BUG(); |
2553 | 2571 | ||
2554 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MAPPING, GFP_ATOMIC); | 2572 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_MAPPING, GFP_ATOMIC); |
2555 | } | 2573 | } |
2556 | 2574 | ||
2557 | static struct xfrm_mgr netlink_mgr = { | 2575 | static struct xfrm_mgr netlink_mgr = { |
@@ -2565,33 +2583,53 @@ static struct xfrm_mgr netlink_mgr = { | |||
2565 | .new_mapping = xfrm_send_mapping, | 2583 | .new_mapping = xfrm_send_mapping, |
2566 | }; | 2584 | }; |
2567 | 2585 | ||
2568 | static int __init xfrm_user_init(void) | 2586 | static int __net_init xfrm_user_net_init(struct net *net) |
2569 | { | 2587 | { |
2570 | struct sock *nlsk; | 2588 | struct sock *nlsk; |
2571 | 2589 | ||
2572 | printk(KERN_INFO "Initializing XFRM netlink socket\n"); | 2590 | nlsk = netlink_kernel_create(net, NETLINK_XFRM, XFRMNLGRP_MAX, |
2573 | |||
2574 | nlsk = netlink_kernel_create(&init_net, NETLINK_XFRM, XFRMNLGRP_MAX, | ||
2575 | xfrm_netlink_rcv, NULL, THIS_MODULE); | 2591 | xfrm_netlink_rcv, NULL, THIS_MODULE); |
2576 | if (nlsk == NULL) | 2592 | if (nlsk == NULL) |
2577 | return -ENOMEM; | 2593 | return -ENOMEM; |
2578 | rcu_assign_pointer(xfrm_nl, nlsk); | 2594 | rcu_assign_pointer(net->xfrm.nlsk, nlsk); |
2579 | |||
2580 | xfrm_register_km(&netlink_mgr); | ||
2581 | |||
2582 | return 0; | 2595 | return 0; |
2583 | } | 2596 | } |
2584 | 2597 | ||
2585 | static void __exit xfrm_user_exit(void) | 2598 | static void __net_exit xfrm_user_net_exit(struct net *net) |
2586 | { | 2599 | { |
2587 | struct sock *nlsk = xfrm_nl; | 2600 | struct sock *nlsk = net->xfrm.nlsk; |
2588 | 2601 | ||
2589 | xfrm_unregister_km(&netlink_mgr); | 2602 | rcu_assign_pointer(net->xfrm.nlsk, NULL); |
2590 | rcu_assign_pointer(xfrm_nl, NULL); | ||
2591 | synchronize_rcu(); | 2603 | synchronize_rcu(); |
2592 | netlink_kernel_release(nlsk); | 2604 | netlink_kernel_release(nlsk); |
2593 | } | 2605 | } |
2594 | 2606 | ||
2607 | static struct pernet_operations xfrm_user_net_ops = { | ||
2608 | .init = xfrm_user_net_init, | ||
2609 | .exit = xfrm_user_net_exit, | ||
2610 | }; | ||
2611 | |||
2612 | static int __init xfrm_user_init(void) | ||
2613 | { | ||
2614 | int rv; | ||
2615 | |||
2616 | printk(KERN_INFO "Initializing XFRM netlink socket\n"); | ||
2617 | |||
2618 | rv = register_pernet_subsys(&xfrm_user_net_ops); | ||
2619 | if (rv < 0) | ||
2620 | return rv; | ||
2621 | rv = xfrm_register_km(&netlink_mgr); | ||
2622 | if (rv < 0) | ||
2623 | unregister_pernet_subsys(&xfrm_user_net_ops); | ||
2624 | return rv; | ||
2625 | } | ||
2626 | |||
2627 | static void __exit xfrm_user_exit(void) | ||
2628 | { | ||
2629 | xfrm_unregister_km(&netlink_mgr); | ||
2630 | unregister_pernet_subsys(&xfrm_user_net_ops); | ||
2631 | } | ||
2632 | |||
2595 | module_init(xfrm_user_init); | 2633 | module_init(xfrm_user_init); |
2596 | module_exit(xfrm_user_exit); | 2634 | module_exit(xfrm_user_exit); |
2597 | MODULE_LICENSE("GPL"); | 2635 | MODULE_LICENSE("GPL"); |