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 | |
| 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')
| -rw-r--r-- | net/xfrm/xfrm_input.c | 2 | ||||
| -rw-r--r-- | net/xfrm/xfrm_state.c | 34 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 12 |
3 files changed, 26 insertions, 22 deletions
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 75279402ccf4..c08a93e98a36 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
| @@ -151,7 +151,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
| 151 | goto drop; | 151 | goto drop; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | x = xfrm_state_lookup(daddr, spi, nexthdr, family); | 154 | x = xfrm_state_lookup(&init_net, daddr, spi, nexthdr, family); |
| 155 | if (x == NULL) { | 155 | if (x == NULL) { |
| 156 | XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); | 156 | XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); |
| 157 | xfrm_audit_state_notfound(skb, family, spi, seq); | 157 | xfrm_audit_state_notfound(skb, family, spi, seq); |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 5f4c5340ba30..afde47498cdc 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; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 49a7e897ba96..e02ef3361190 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -440,7 +440,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, | |||
| 440 | 440 | ||
| 441 | if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) { | 441 | if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) { |
| 442 | err = -ESRCH; | 442 | err = -ESRCH; |
| 443 | x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family); | 443 | x = xfrm_state_lookup(&init_net, &p->daddr, p->spi, p->proto, p->family); |
| 444 | } else { | 444 | } else { |
| 445 | xfrm_address_t *saddr = NULL; | 445 | xfrm_address_t *saddr = NULL; |
| 446 | 446 | ||
| @@ -451,8 +451,8 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, | |||
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | err = -ESRCH; | 453 | err = -ESRCH; |
| 454 | x = xfrm_state_lookup_byaddr(&p->daddr, saddr, p->proto, | 454 | x = xfrm_state_lookup_byaddr(&init_net, &p->daddr, saddr, |
| 455 | p->family); | 455 | p->proto, p->family); |
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | out: | 458 | out: |
| @@ -1468,7 +1468,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1468 | if (r_skb == NULL) | 1468 | if (r_skb == NULL) |
| 1469 | return -ENOMEM; | 1469 | return -ENOMEM; |
| 1470 | 1470 | ||
| 1471 | x = xfrm_state_lookup(&id->daddr, id->spi, id->proto, id->family); | 1471 | x = xfrm_state_lookup(&init_net, &id->daddr, id->spi, id->proto, id->family); |
| 1472 | if (x == NULL) { | 1472 | if (x == NULL) { |
| 1473 | kfree_skb(r_skb); | 1473 | kfree_skb(r_skb); |
| 1474 | return -ESRCH; | 1474 | return -ESRCH; |
| @@ -1509,7 +1509,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1509 | if (!(nlh->nlmsg_flags&NLM_F_REPLACE)) | 1509 | if (!(nlh->nlmsg_flags&NLM_F_REPLACE)) |
| 1510 | return err; | 1510 | return err; |
| 1511 | 1511 | ||
| 1512 | x = xfrm_state_lookup(&p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); | 1512 | x = xfrm_state_lookup(&init_net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); |
| 1513 | if (x == NULL) | 1513 | if (x == NULL) |
| 1514 | return -ESRCH; | 1514 | return -ESRCH; |
| 1515 | 1515 | ||
| @@ -1628,7 +1628,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1628 | struct xfrm_user_expire *ue = nlmsg_data(nlh); | 1628 | struct xfrm_user_expire *ue = nlmsg_data(nlh); |
| 1629 | struct xfrm_usersa_info *p = &ue->state; | 1629 | struct xfrm_usersa_info *p = &ue->state; |
| 1630 | 1630 | ||
| 1631 | x = xfrm_state_lookup(&p->id.daddr, p->id.spi, p->id.proto, p->family); | 1631 | x = xfrm_state_lookup(&init_net, &p->id.daddr, p->id.spi, p->id.proto, p->family); |
| 1632 | 1632 | ||
| 1633 | err = -ENOENT; | 1633 | err = -ENOENT; |
| 1634 | if (x == NULL) | 1634 | if (x == NULL) |
