diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:31:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:31:51 -0500 |
commit | 5447c5e401c49aba0c36bb1066f2d25b152553b7 (patch) | |
tree | 5a5b4e0736368a70a266bd04075d174310aa5f80 /net/xfrm/xfrm_state.c | |
parent | 12604d8aaa38ac4e24299c9803fefdb301a16421 (diff) |
netns xfrm: finding states in netns
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_state.c')
-rw-r--r-- | net/xfrm/xfrm_state.c | 73 |
1 files changed, 38 insertions, 35 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index cd51e4e3d023..0d974fc9dd6c 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -765,6 +765,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
765 | struct xfrm_policy *pol, int *err, | 765 | struct xfrm_policy *pol, int *err, |
766 | unsigned short family) | 766 | unsigned short family) |
767 | { | 767 | { |
768 | struct net *net = xp_net(pol); | ||
768 | unsigned int h; | 769 | unsigned int h; |
769 | struct hlist_node *entry; | 770 | struct hlist_node *entry; |
770 | struct xfrm_state *x, *x0, *to_put; | 771 | struct xfrm_state *x, *x0, *to_put; |
@@ -775,8 +776,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
775 | to_put = NULL; | 776 | to_put = NULL; |
776 | 777 | ||
777 | spin_lock_bh(&xfrm_state_lock); | 778 | spin_lock_bh(&xfrm_state_lock); |
778 | h = xfrm_dst_hash(&init_net, daddr, saddr, tmpl->reqid, family); | 779 | h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, family); |
779 | hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) { | 780 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { |
780 | if (x->props.family == family && | 781 | if (x->props.family == family && |
781 | x->props.reqid == tmpl->reqid && | 782 | x->props.reqid == tmpl->reqid && |
782 | !(x->props.flags & XFRM_STATE_WILDRECV) && | 783 | !(x->props.flags & XFRM_STATE_WILDRECV) && |
@@ -820,13 +821,13 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
820 | x = best; | 821 | x = best; |
821 | if (!x && !error && !acquire_in_progress) { | 822 | if (!x && !error && !acquire_in_progress) { |
822 | if (tmpl->id.spi && | 823 | if (tmpl->id.spi && |
823 | (x0 = __xfrm_state_lookup(&init_net, daddr, tmpl->id.spi, | 824 | (x0 = __xfrm_state_lookup(net, daddr, tmpl->id.spi, |
824 | tmpl->id.proto, family)) != NULL) { | 825 | tmpl->id.proto, family)) != NULL) { |
825 | to_put = x0; | 826 | to_put = x0; |
826 | error = -EEXIST; | 827 | error = -EEXIST; |
827 | goto out; | 828 | goto out; |
828 | } | 829 | } |
829 | x = xfrm_state_alloc(&init_net); | 830 | x = xfrm_state_alloc(net); |
830 | if (x == NULL) { | 831 | if (x == NULL) { |
831 | error = -ENOMEM; | 832 | error = -ENOMEM; |
832 | goto out; | 833 | goto out; |
@@ -845,19 +846,19 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
845 | 846 | ||
846 | if (km_query(x, tmpl, pol) == 0) { | 847 | if (km_query(x, tmpl, pol) == 0) { |
847 | x->km.state = XFRM_STATE_ACQ; | 848 | x->km.state = XFRM_STATE_ACQ; |
848 | list_add(&x->km.all, &init_net.xfrm.state_all); | 849 | list_add(&x->km.all, &net->xfrm.state_all); |
849 | hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); | 850 | hlist_add_head(&x->bydst, net->xfrm.state_bydst+h); |
850 | h = xfrm_src_hash(&init_net, daddr, saddr, family); | 851 | h = xfrm_src_hash(net, daddr, saddr, family); |
851 | hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h); | 852 | hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); |
852 | if (x->id.spi) { | 853 | if (x->id.spi) { |
853 | h = xfrm_spi_hash(&init_net, &x->id.daddr, x->id.spi, x->id.proto, family); | 854 | h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, family); |
854 | hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h); | 855 | hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); |
855 | } | 856 | } |
856 | x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires; | 857 | x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires; |
857 | x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; | 858 | x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; |
858 | add_timer(&x->timer); | 859 | add_timer(&x->timer); |
859 | init_net.xfrm.state_num++; | 860 | net->xfrm.state_num++; |
860 | xfrm_hash_grow_check(&init_net, x->bydst.next != NULL); | 861 | xfrm_hash_grow_check(net, x->bydst.next != NULL); |
861 | } else { | 862 | } else { |
862 | x->km.state = XFRM_STATE_DEAD; | 863 | x->km.state = XFRM_STATE_DEAD; |
863 | to_put = x; | 864 | to_put = x; |
@@ -877,7 +878,8 @@ out: | |||
877 | } | 878 | } |
878 | 879 | ||
879 | struct xfrm_state * | 880 | struct xfrm_state * |
880 | xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | 881 | xfrm_stateonly_find(struct net *net, |
882 | xfrm_address_t *daddr, xfrm_address_t *saddr, | ||
881 | unsigned short family, u8 mode, u8 proto, u32 reqid) | 883 | unsigned short family, u8 mode, u8 proto, u32 reqid) |
882 | { | 884 | { |
883 | unsigned int h; | 885 | unsigned int h; |
@@ -885,8 +887,8 @@ xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
885 | struct hlist_node *entry; | 887 | struct hlist_node *entry; |
886 | 888 | ||
887 | spin_lock(&xfrm_state_lock); | 889 | spin_lock(&xfrm_state_lock); |
888 | h = xfrm_dst_hash(&init_net, daddr, saddr, reqid, family); | 890 | h = xfrm_dst_hash(net, daddr, saddr, reqid, family); |
889 | hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) { | 891 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { |
890 | if (x->props.family == family && | 892 | if (x->props.family == family && |
891 | x->props.reqid == reqid && | 893 | x->props.reqid == reqid && |
892 | !(x->props.flags & XFRM_STATE_WILDRECV) && | 894 | !(x->props.flags & XFRM_STATE_WILDRECV) && |
@@ -972,13 +974,13 @@ void xfrm_state_insert(struct xfrm_state *x) | |||
972 | EXPORT_SYMBOL(xfrm_state_insert); | 974 | EXPORT_SYMBOL(xfrm_state_insert); |
973 | 975 | ||
974 | /* xfrm_state_lock is held */ | 976 | /* xfrm_state_lock is held */ |
975 | static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create) | 977 | static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create) |
976 | { | 978 | { |
977 | unsigned int h = xfrm_dst_hash(&init_net, daddr, saddr, reqid, family); | 979 | unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family); |
978 | struct hlist_node *entry; | 980 | struct hlist_node *entry; |
979 | struct xfrm_state *x; | 981 | struct xfrm_state *x; |
980 | 982 | ||
981 | hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) { | 983 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { |
982 | if (x->props.reqid != reqid || | 984 | if (x->props.reqid != reqid || |
983 | x->props.mode != mode || | 985 | x->props.mode != mode || |
984 | x->props.family != family || | 986 | x->props.family != family || |
@@ -1010,7 +1012,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re | |||
1010 | if (!create) | 1012 | if (!create) |
1011 | return NULL; | 1013 | return NULL; |
1012 | 1014 | ||
1013 | x = xfrm_state_alloc(&init_net); | 1015 | x = xfrm_state_alloc(net); |
1014 | if (likely(x)) { | 1016 | if (likely(x)) { |
1015 | switch (family) { | 1017 | switch (family) { |
1016 | case AF_INET: | 1018 | case AF_INET: |
@@ -1045,23 +1047,24 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re | |||
1045 | xfrm_state_hold(x); | 1047 | xfrm_state_hold(x); |
1046 | x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; | 1048 | x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; |
1047 | add_timer(&x->timer); | 1049 | add_timer(&x->timer); |
1048 | list_add(&x->km.all, &init_net.xfrm.state_all); | 1050 | list_add(&x->km.all, &net->xfrm.state_all); |
1049 | hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); | 1051 | hlist_add_head(&x->bydst, net->xfrm.state_bydst+h); |
1050 | h = xfrm_src_hash(&init_net, daddr, saddr, family); | 1052 | h = xfrm_src_hash(net, daddr, saddr, family); |
1051 | hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h); | 1053 | hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); |
1052 | 1054 | ||
1053 | init_net.xfrm.state_num++; | 1055 | net->xfrm.state_num++; |
1054 | 1056 | ||
1055 | xfrm_hash_grow_check(&init_net, x->bydst.next != NULL); | 1057 | xfrm_hash_grow_check(net, x->bydst.next != NULL); |
1056 | } | 1058 | } |
1057 | 1059 | ||
1058 | return x; | 1060 | return x; |
1059 | } | 1061 | } |
1060 | 1062 | ||
1061 | static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq); | 1063 | static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq); |
1062 | 1064 | ||
1063 | int xfrm_state_add(struct xfrm_state *x) | 1065 | int xfrm_state_add(struct xfrm_state *x) |
1064 | { | 1066 | { |
1067 | struct net *net = xs_net(x); | ||
1065 | struct xfrm_state *x1, *to_put; | 1068 | struct xfrm_state *x1, *to_put; |
1066 | int family; | 1069 | int family; |
1067 | int err; | 1070 | int err; |
@@ -1082,7 +1085,7 @@ int xfrm_state_add(struct xfrm_state *x) | |||
1082 | } | 1085 | } |
1083 | 1086 | ||
1084 | if (use_spi && x->km.seq) { | 1087 | if (use_spi && x->km.seq) { |
1085 | x1 = __xfrm_find_acq_byseq(x->km.seq); | 1088 | x1 = __xfrm_find_acq_byseq(net, x->km.seq); |
1086 | if (x1 && ((x1->id.proto != x->id.proto) || | 1089 | if (x1 && ((x1->id.proto != x->id.proto) || |
1087 | xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) { | 1090 | xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) { |
1088 | to_put = x1; | 1091 | to_put = x1; |
@@ -1091,7 +1094,7 @@ int xfrm_state_add(struct xfrm_state *x) | |||
1091 | } | 1094 | } |
1092 | 1095 | ||
1093 | if (use_spi && !x1) | 1096 | if (use_spi && !x1) |
1094 | x1 = __find_acq_core(family, x->props.mode, x->props.reqid, | 1097 | x1 = __find_acq_core(net, family, x->props.mode, x->props.reqid, |
1095 | x->id.proto, | 1098 | x->id.proto, |
1096 | &x->id.daddr, &x->props.saddr, 0); | 1099 | &x->id.daddr, &x->props.saddr, 0); |
1097 | 1100 | ||
@@ -1390,14 +1393,14 @@ xfrm_state_lookup_byaddr(struct net *net, | |||
1390 | EXPORT_SYMBOL(xfrm_state_lookup_byaddr); | 1393 | EXPORT_SYMBOL(xfrm_state_lookup_byaddr); |
1391 | 1394 | ||
1392 | struct xfrm_state * | 1395 | struct xfrm_state * |
1393 | xfrm_find_acq(u8 mode, u32 reqid, u8 proto, | 1396 | xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto, |
1394 | xfrm_address_t *daddr, xfrm_address_t *saddr, | 1397 | xfrm_address_t *daddr, xfrm_address_t *saddr, |
1395 | int create, unsigned short family) | 1398 | int create, unsigned short family) |
1396 | { | 1399 | { |
1397 | struct xfrm_state *x; | 1400 | struct xfrm_state *x; |
1398 | 1401 | ||
1399 | spin_lock_bh(&xfrm_state_lock); | 1402 | spin_lock_bh(&xfrm_state_lock); |
1400 | x = __find_acq_core(family, mode, reqid, proto, daddr, saddr, create); | 1403 | x = __find_acq_core(net, family, mode, reqid, proto, daddr, saddr, create); |
1401 | spin_unlock_bh(&xfrm_state_lock); | 1404 | spin_unlock_bh(&xfrm_state_lock); |
1402 | 1405 | ||
1403 | return x; | 1406 | return x; |
@@ -1444,15 +1447,15 @@ EXPORT_SYMBOL(xfrm_state_sort); | |||
1444 | 1447 | ||
1445 | /* Silly enough, but I'm lazy to build resolution list */ | 1448 | /* Silly enough, but I'm lazy to build resolution list */ |
1446 | 1449 | ||
1447 | static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq) | 1450 | static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq) |
1448 | { | 1451 | { |
1449 | int i; | 1452 | int i; |
1450 | 1453 | ||
1451 | for (i = 0; i <= init_net.xfrm.state_hmask; i++) { | 1454 | for (i = 0; i <= net->xfrm.state_hmask; i++) { |
1452 | struct hlist_node *entry; | 1455 | struct hlist_node *entry; |
1453 | struct xfrm_state *x; | 1456 | struct xfrm_state *x; |
1454 | 1457 | ||
1455 | hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+i, bydst) { | 1458 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+i, bydst) { |
1456 | if (x->km.seq == seq && | 1459 | if (x->km.seq == seq && |
1457 | x->km.state == XFRM_STATE_ACQ) { | 1460 | x->km.state == XFRM_STATE_ACQ) { |
1458 | xfrm_state_hold(x); | 1461 | xfrm_state_hold(x); |
@@ -1463,12 +1466,12 @@ static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq) | |||
1463 | return NULL; | 1466 | return NULL; |
1464 | } | 1467 | } |
1465 | 1468 | ||
1466 | struct xfrm_state *xfrm_find_acq_byseq(u32 seq) | 1469 | struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq) |
1467 | { | 1470 | { |
1468 | struct xfrm_state *x; | 1471 | struct xfrm_state *x; |
1469 | 1472 | ||
1470 | spin_lock_bh(&xfrm_state_lock); | 1473 | spin_lock_bh(&xfrm_state_lock); |
1471 | x = __xfrm_find_acq_byseq(seq); | 1474 | x = __xfrm_find_acq_byseq(net, seq); |
1472 | spin_unlock_bh(&xfrm_state_lock); | 1475 | spin_unlock_bh(&xfrm_state_lock); |
1473 | return x; | 1476 | return x; |
1474 | } | 1477 | } |