aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_state.c
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2008-11-25 20:31:51 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-25 20:31:51 -0500
commit5447c5e401c49aba0c36bb1066f2d25b152553b7 (patch)
tree5a5b4e0736368a70a266bd04075d174310aa5f80 /net/xfrm/xfrm_state.c
parent12604d8aaa38ac4e24299c9803fefdb301a16421 (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.c73
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
879struct xfrm_state * 880struct xfrm_state *
880xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 881xfrm_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)
972EXPORT_SYMBOL(xfrm_state_insert); 974EXPORT_SYMBOL(xfrm_state_insert);
973 975
974/* xfrm_state_lock is held */ 976/* xfrm_state_lock is held */
975static 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) 977static 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
1061static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq); 1063static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq);
1062 1064
1063int xfrm_state_add(struct xfrm_state *x) 1065int 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,
1390EXPORT_SYMBOL(xfrm_state_lookup_byaddr); 1393EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
1391 1394
1392struct xfrm_state * 1395struct xfrm_state *
1393xfrm_find_acq(u8 mode, u32 reqid, u8 proto, 1396xfrm_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
1447static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq) 1450static 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
1466struct xfrm_state *xfrm_find_acq_byseq(u32 seq) 1469struct 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}