diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:30:50 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:30:50 -0500 |
commit | 221df1ed33c9284fc7a6f6e47ca7f8d5f3665d43 (patch) | |
tree | 1961ab9f9061b595e10449a24e7275d91f422de2 /net/xfrm/xfrm_state.c | |
parent | 0e6024519b4da2d9413b97be1de8122d5709ccc1 (diff) |
netns xfrm: state lookup 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 | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 5f4c5340ba3..afde47498cd 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -670,13 +670,13 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl, | |||
670 | return 0; | 670 | return 0; |
671 | } | 671 | } |
672 | 672 | ||
673 | static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) | 673 | static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) |
674 | { | 674 | { |
675 | unsigned int h = xfrm_spi_hash(&init_net, daddr, spi, proto, family); | 675 | unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family); |
676 | struct xfrm_state *x; | 676 | struct xfrm_state *x; |
677 | struct hlist_node *entry; | 677 | struct hlist_node *entry; |
678 | 678 | ||
679 | hlist_for_each_entry(x, entry, init_net.xfrm.state_byspi+h, byspi) { | 679 | hlist_for_each_entry(x, entry, net->xfrm.state_byspi+h, byspi) { |
680 | if (x->props.family != family || | 680 | if (x->props.family != family || |
681 | x->id.spi != spi || | 681 | x->id.spi != spi || |
682 | x->id.proto != proto) | 682 | x->id.proto != proto) |
@@ -702,13 +702,13 @@ static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, | |||
702 | return NULL; | 702 | return NULL; |
703 | } | 703 | } |
704 | 704 | ||
705 | static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family) | 705 | static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family) |
706 | { | 706 | { |
707 | unsigned int h = xfrm_src_hash(&init_net, daddr, saddr, family); | 707 | unsigned int h = xfrm_src_hash(net, daddr, saddr, family); |
708 | struct xfrm_state *x; | 708 | struct xfrm_state *x; |
709 | struct hlist_node *entry; | 709 | struct hlist_node *entry; |
710 | 710 | ||
711 | hlist_for_each_entry(x, entry, init_net.xfrm.state_bysrc+h, bysrc) { | 711 | hlist_for_each_entry(x, entry, net->xfrm.state_bysrc+h, bysrc) { |
712 | if (x->props.family != family || | 712 | if (x->props.family != family || |
713 | x->id.proto != proto) | 713 | x->id.proto != proto) |
714 | continue; | 714 | continue; |
@@ -740,11 +740,13 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm | |||
740 | static inline struct xfrm_state * | 740 | static inline struct xfrm_state * |
741 | __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) | 741 | __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) |
742 | { | 742 | { |
743 | struct net *net = xs_net(x); | ||
744 | |||
743 | if (use_spi) | 745 | if (use_spi) |
744 | return __xfrm_state_lookup(&x->id.daddr, x->id.spi, | 746 | return __xfrm_state_lookup(net, &x->id.daddr, x->id.spi, |
745 | x->id.proto, family); | 747 | x->id.proto, family); |
746 | else | 748 | else |
747 | return __xfrm_state_lookup_byaddr(&x->id.daddr, | 749 | return __xfrm_state_lookup_byaddr(net, &x->id.daddr, |
748 | &x->props.saddr, | 750 | &x->props.saddr, |
749 | x->id.proto, family); | 751 | x->id.proto, family); |
750 | } | 752 | } |
@@ -818,7 +820,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
818 | x = best; | 820 | x = best; |
819 | if (!x && !error && !acquire_in_progress) { | 821 | if (!x && !error && !acquire_in_progress) { |
820 | if (tmpl->id.spi && | 822 | if (tmpl->id.spi && |
821 | (x0 = __xfrm_state_lookup(daddr, tmpl->id.spi, | 823 | (x0 = __xfrm_state_lookup(&init_net, daddr, tmpl->id.spi, |
822 | tmpl->id.proto, family)) != NULL) { | 824 | tmpl->id.proto, family)) != NULL) { |
823 | to_put = x0; | 825 | to_put = x0; |
824 | error = -EEXIST; | 826 | error = -EEXIST; |
@@ -1361,26 +1363,27 @@ int xfrm_state_check_expire(struct xfrm_state *x) | |||
1361 | EXPORT_SYMBOL(xfrm_state_check_expire); | 1363 | EXPORT_SYMBOL(xfrm_state_check_expire); |
1362 | 1364 | ||
1363 | struct xfrm_state * | 1365 | struct xfrm_state * |
1364 | xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, | 1366 | xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, |
1365 | unsigned short family) | 1367 | unsigned short family) |
1366 | { | 1368 | { |
1367 | struct xfrm_state *x; | 1369 | struct xfrm_state *x; |
1368 | 1370 | ||
1369 | spin_lock_bh(&xfrm_state_lock); | 1371 | spin_lock_bh(&xfrm_state_lock); |
1370 | x = __xfrm_state_lookup(daddr, spi, proto, family); | 1372 | x = __xfrm_state_lookup(net, daddr, spi, proto, family); |
1371 | spin_unlock_bh(&xfrm_state_lock); | 1373 | spin_unlock_bh(&xfrm_state_lock); |
1372 | return x; | 1374 | return x; |
1373 | } | 1375 | } |
1374 | EXPORT_SYMBOL(xfrm_state_lookup); | 1376 | EXPORT_SYMBOL(xfrm_state_lookup); |
1375 | 1377 | ||
1376 | struct xfrm_state * | 1378 | struct xfrm_state * |
1377 | xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, | 1379 | xfrm_state_lookup_byaddr(struct net *net, |
1380 | xfrm_address_t *daddr, xfrm_address_t *saddr, | ||
1378 | u8 proto, unsigned short family) | 1381 | u8 proto, unsigned short family) |
1379 | { | 1382 | { |
1380 | struct xfrm_state *x; | 1383 | struct xfrm_state *x; |
1381 | 1384 | ||
1382 | spin_lock_bh(&xfrm_state_lock); | 1385 | spin_lock_bh(&xfrm_state_lock); |
1383 | x = __xfrm_state_lookup_byaddr(daddr, saddr, proto, family); | 1386 | x = __xfrm_state_lookup_byaddr(net, daddr, saddr, proto, family); |
1384 | spin_unlock_bh(&xfrm_state_lock); | 1387 | spin_unlock_bh(&xfrm_state_lock); |
1385 | return x; | 1388 | return x; |
1386 | } | 1389 | } |
@@ -1486,6 +1489,7 @@ EXPORT_SYMBOL(xfrm_get_acqseq); | |||
1486 | 1489 | ||
1487 | int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) | 1490 | int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) |
1488 | { | 1491 | { |
1492 | struct net *net = xs_net(x); | ||
1489 | unsigned int h; | 1493 | unsigned int h; |
1490 | struct xfrm_state *x0; | 1494 | struct xfrm_state *x0; |
1491 | int err = -ENOENT; | 1495 | int err = -ENOENT; |
@@ -1503,7 +1507,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) | |||
1503 | err = -ENOENT; | 1507 | err = -ENOENT; |
1504 | 1508 | ||
1505 | if (minspi == maxspi) { | 1509 | if (minspi == maxspi) { |
1506 | x0 = xfrm_state_lookup(&x->id.daddr, minspi, x->id.proto, x->props.family); | 1510 | x0 = xfrm_state_lookup(net, &x->id.daddr, minspi, x->id.proto, x->props.family); |
1507 | if (x0) { | 1511 | if (x0) { |
1508 | xfrm_state_put(x0); | 1512 | xfrm_state_put(x0); |
1509 | goto unlock; | 1513 | goto unlock; |
@@ -1513,7 +1517,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) | |||
1513 | u32 spi = 0; | 1517 | u32 spi = 0; |
1514 | for (h=0; h<high-low+1; h++) { | 1518 | for (h=0; h<high-low+1; h++) { |
1515 | spi = low + net_random()%(high-low+1); | 1519 | spi = low + net_random()%(high-low+1); |
1516 | x0 = xfrm_state_lookup(&x->id.daddr, htonl(spi), x->id.proto, x->props.family); | 1520 | x0 = xfrm_state_lookup(net, &x->id.daddr, htonl(spi), x->id.proto, x->props.family); |
1517 | if (x0 == NULL) { | 1521 | if (x0 == NULL) { |
1518 | x->id.spi = htonl(spi); | 1522 | x->id.spi = htonl(spi); |
1519 | break; | 1523 | break; |