aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/net/xfrm.h7
-rw-r--r--net/core/pktgen.c3
-rw-r--r--net/key/af_key.c6
-rw-r--r--net/xfrm/xfrm_state.c73
-rw-r--r--net/xfrm/xfrm_user.c4
5 files changed, 49 insertions, 44 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 15136c5e2622..4cbd0557c698 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1315,7 +1315,8 @@ extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t
1315 struct flowi *fl, struct xfrm_tmpl *tmpl, 1315 struct flowi *fl, struct xfrm_tmpl *tmpl,
1316 struct xfrm_policy *pol, int *err, 1316 struct xfrm_policy *pol, int *err,
1317 unsigned short family); 1317 unsigned short family);
1318extern struct xfrm_state * xfrm_stateonly_find(xfrm_address_t *daddr, 1318extern struct xfrm_state * xfrm_stateonly_find(struct net *net,
1319 xfrm_address_t *daddr,
1319 xfrm_address_t *saddr, 1320 xfrm_address_t *saddr,
1320 unsigned short family, 1321 unsigned short family,
1321 u8 mode, u8 proto, u32 reqid); 1322 u8 mode, u8 proto, u32 reqid);
@@ -1361,7 +1362,7 @@ struct xfrmk_spdinfo {
1361 u32 spdhmcnt; 1362 u32 spdhmcnt;
1362}; 1363};
1363 1364
1364extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); 1365extern struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq);
1365extern int xfrm_state_delete(struct xfrm_state *x); 1366extern int xfrm_state_delete(struct xfrm_state *x);
1366extern int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info); 1367extern int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info);
1367extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si); 1368extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
@@ -1446,7 +1447,7 @@ struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
1446int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); 1447int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
1447u32 xfrm_get_acqseq(void); 1448u32 xfrm_get_acqseq(void);
1448extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); 1449extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
1449struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, 1450struct xfrm_state * xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto,
1450 xfrm_address_t *daddr, xfrm_address_t *saddr, 1451 xfrm_address_t *daddr, xfrm_address_t *saddr,
1451 int create, unsigned short family); 1452 int create, unsigned short family);
1452extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); 1453extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 15e0c2c7aacf..65498483325a 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2165,7 +2165,8 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
2165 struct xfrm_state *x = pkt_dev->flows[flow].x; 2165 struct xfrm_state *x = pkt_dev->flows[flow].x;
2166 if (!x) { 2166 if (!x) {
2167 /*slow path: we dont already have xfrm_state*/ 2167 /*slow path: we dont already have xfrm_state*/
2168 x = xfrm_stateonly_find((xfrm_address_t *)&pkt_dev->cur_daddr, 2168 x = xfrm_stateonly_find(&init_net,
2169 (xfrm_address_t *)&pkt_dev->cur_daddr,
2169 (xfrm_address_t *)&pkt_dev->cur_saddr, 2170 (xfrm_address_t *)&pkt_dev->cur_saddr,
2170 AF_INET, 2171 AF_INET,
2171 pkt_dev->ipsmode, 2172 pkt_dev->ipsmode,
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 449a5d03e283..4ef0827009e9 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1348,7 +1348,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1348 } 1348 }
1349 1349
1350 if (hdr->sadb_msg_seq) { 1350 if (hdr->sadb_msg_seq) {
1351 x = xfrm_find_acq_byseq(hdr->sadb_msg_seq); 1351 x = xfrm_find_acq_byseq(&init_net, hdr->sadb_msg_seq);
1352 if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) { 1352 if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) {
1353 xfrm_state_put(x); 1353 xfrm_state_put(x);
1354 x = NULL; 1354 x = NULL;
@@ -1356,7 +1356,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1356 } 1356 }
1357 1357
1358 if (!x) 1358 if (!x)
1359 x = xfrm_find_acq(mode, reqid, proto, xdaddr, xsaddr, 1, family); 1359 x = xfrm_find_acq(&init_net, mode, reqid, proto, xdaddr, xsaddr, 1, family);
1360 1360
1361 if (x == NULL) 1361 if (x == NULL)
1362 return -ENOENT; 1362 return -ENOENT;
@@ -1404,7 +1404,7 @@ 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) 1404 if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0)
1405 return 0; 1405 return 0;
1406 1406
1407 x = xfrm_find_acq_byseq(hdr->sadb_msg_seq); 1407 x = xfrm_find_acq_byseq(&init_net, hdr->sadb_msg_seq);
1408 if (x == NULL) 1408 if (x == NULL)
1409 return 0; 1409 return 0;
1410 1410
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}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index e02ef3361190..3d577440b673 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -837,7 +837,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
837 837
838 x = NULL; 838 x = NULL;
839 if (p->info.seq) { 839 if (p->info.seq) {
840 x = xfrm_find_acq_byseq(p->info.seq); 840 x = xfrm_find_acq_byseq(&init_net, p->info.seq);
841 if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) { 841 if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) {
842 xfrm_state_put(x); 842 xfrm_state_put(x);
843 x = NULL; 843 x = NULL;
@@ -845,7 +845,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
845 } 845 }
846 846
847 if (!x) 847 if (!x)
848 x = xfrm_find_acq(p->info.mode, p->info.reqid, 848 x = xfrm_find_acq(&init_net, p->info.mode, p->info.reqid,
849 p->info.id.proto, daddr, 849 p->info.id.proto, daddr,
850 &p->info.saddr, 1, 850 &p->info.saddr, 1,
851 family); 851 family);