Commit 221df1ed authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by David S. Miller

netns xfrm: state lookup in netns

Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0e602451
...@@ -1323,8 +1323,8 @@ extern int xfrm_state_check_expire(struct xfrm_state *x); ...@@ -1323,8 +1323,8 @@ extern int xfrm_state_check_expire(struct xfrm_state *x);
extern void xfrm_state_insert(struct xfrm_state *x); extern void xfrm_state_insert(struct xfrm_state *x);
extern int xfrm_state_add(struct xfrm_state *x); extern int xfrm_state_add(struct xfrm_state *x);
extern int xfrm_state_update(struct xfrm_state *x); extern int xfrm_state_update(struct xfrm_state *x);
extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family); extern struct xfrm_state *xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family);
extern struct xfrm_state *xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family); extern struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family);
#ifdef CONFIG_XFRM_SUB_POLICY #ifdef CONFIG_XFRM_SUB_POLICY
extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src,
int n, unsigned short family); int n, unsigned short family);
......
...@@ -209,7 +209,7 @@ static void ah4_err(struct sk_buff *skb, u32 info) ...@@ -209,7 +209,7 @@ static void ah4_err(struct sk_buff *skb, u32 info)
icmp_hdr(skb)->code != ICMP_FRAG_NEEDED) icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
return; return;
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET); x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
if (!x) if (!x)
return; return;
printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n", printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n",
......
...@@ -421,7 +421,7 @@ static void esp4_err(struct sk_buff *skb, u32 info) ...@@ -421,7 +421,7 @@ static void esp4_err(struct sk_buff *skb, u32 info)
icmp_hdr(skb)->code != ICMP_FRAG_NEEDED) icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
return; return;
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET); x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
if (!x) if (!x)
return; return;
NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n", NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n",
......
...@@ -35,7 +35,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info) ...@@ -35,7 +35,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
return; return;
spi = htonl(ntohs(ipch->cpi)); spi = htonl(ntohs(ipch->cpi));
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr,
spi, IPPROTO_COMP, AF_INET); spi, IPPROTO_COMP, AF_INET);
if (!x) if (!x)
return; return;
...@@ -85,7 +85,7 @@ static int ipcomp_tunnel_attach(struct xfrm_state *x) ...@@ -85,7 +85,7 @@ static int ipcomp_tunnel_attach(struct xfrm_state *x)
int err = 0; int err = 0;
struct xfrm_state *t; struct xfrm_state *t;
t = xfrm_state_lookup((xfrm_address_t *)&x->id.daddr.a4, t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr.a4,
x->props.saddr.a4, IPPROTO_IPIP, AF_INET); x->props.saddr.a4, IPPROTO_IPIP, AF_INET);
if (!t) { if (!t) {
t = ipcomp_tunnel_create(x); t = ipcomp_tunnel_create(x);
......
...@@ -415,7 +415,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -415,7 +415,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
type != ICMPV6_PKT_TOOBIG) type != ICMPV6_PKT_TOOBIG)
return; return;
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6); x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
if (!x) if (!x)
return; return;
......
...@@ -364,7 +364,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -364,7 +364,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
type != ICMPV6_PKT_TOOBIG) type != ICMPV6_PKT_TOOBIG)
return; return;
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6); x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
if (!x) if (!x)
return; return;
printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n", printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n",
......
...@@ -63,7 +63,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -63,7 +63,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return; return;
spi = htonl(ntohs(ipcomph->cpi)); spi = htonl(ntohs(ipcomph->cpi));
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
if (!x) if (!x)
return; return;
...@@ -114,7 +114,7 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x) ...@@ -114,7 +114,7 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x)
spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr); spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr);
if (spi) if (spi)
t = xfrm_state_lookup((xfrm_address_t *)&x->id.daddr, t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr,
spi, IPPROTO_IPV6, AF_INET6); spi, IPPROTO_IPV6, AF_INET6);
if (!t) { if (!t) {
t = ipcomp6_tunnel_create(x); t = ipcomp6_tunnel_create(x);
......
...@@ -100,7 +100,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, ...@@ -100,7 +100,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
break; break;
} }
x = xfrm_state_lookup_byaddr(dst, src, proto, AF_INET6); x = xfrm_state_lookup_byaddr(&init_net, dst, src, proto, AF_INET6);
if (!x) if (!x)
continue; continue;
......
...@@ -683,7 +683,7 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void ** ...@@ -683,7 +683,7 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **
if (!xaddr) if (!xaddr)
return NULL; return NULL;
return xfrm_state_lookup(xaddr, sa->sadb_sa_spi, proto, family); return xfrm_state_lookup(&init_net, xaddr, sa->sadb_sa_spi, proto, family);
} }
#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
......
...@@ -151,7 +151,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) ...@@ -151,7 +151,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto drop; goto drop;
} }
x = xfrm_state_lookup(daddr, spi, nexthdr, family); x = xfrm_state_lookup(&init_net, daddr, spi, nexthdr, family);
if (x == NULL) { if (x == NULL) {
XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES);
xfrm_audit_state_notfound(skb, family, spi, seq); xfrm_audit_state_notfound(skb, family, spi, seq);
......
...@@ -670,13 +670,13 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl, ...@@ -670,13 +670,13 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
return 0; return 0;
} }
static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
{ {
unsigned int h = xfrm_spi_hash(&init_net, daddr, spi, proto, family); unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family);
struct xfrm_state *x; struct xfrm_state *x;
struct hlist_node *entry; struct hlist_node *entry;
hlist_for_each_entry(x, entry, init_net.xfrm.state_byspi+h, byspi) { hlist_for_each_entry(x, entry, net->xfrm.state_byspi+h, byspi) {
if (x->props.family != family || if (x->props.family != family ||
x->id.spi != spi || x->id.spi != spi ||
x->id.proto != proto) x->id.proto != proto)
...@@ -702,13 +702,13 @@ static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, ...@@ -702,13 +702,13 @@ static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi,
return NULL; return NULL;
} }
static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family) static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
{ {
unsigned int h = xfrm_src_hash(&init_net, daddr, saddr, family); unsigned int h = xfrm_src_hash(net, daddr, saddr, family);
struct xfrm_state *x; struct xfrm_state *x;
struct hlist_node *entry; struct hlist_node *entry;
hlist_for_each_entry(x, entry, init_net.xfrm.state_bysrc+h, bysrc) { hlist_for_each_entry(x, entry, net->xfrm.state_bysrc+h, bysrc) {
if (x->props.family != family || if (x->props.family != family ||
x->id.proto != proto) x->id.proto != proto)
continue; continue;
...@@ -740,11 +740,13 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm ...@@ -740,11 +740,13 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm
static inline struct xfrm_state * static inline struct xfrm_state *
__xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family)
{ {
struct net *net = xs_net(x);
if (use_spi) if (use_spi)
return __xfrm_state_lookup(&x->id.daddr, x->id.spi, return __xfrm_state_lookup(net, &x->id.daddr, x->id.spi,
x->id.proto, family); x->id.proto, family);
else else
return __xfrm_state_lookup_byaddr(&x->id.daddr, return __xfrm_state_lookup_byaddr(net, &x->id.daddr,
&x->props.saddr, &x->props.saddr,
x->id.proto, family); x->id.proto, family);
} }
...@@ -818,7 +820,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, ...@@ -818,7 +820,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
x = best; x = best;
if (!x && !error && !acquire_in_progress) { if (!x && !error && !acquire_in_progress) {
if (tmpl->id.spi && if (tmpl->id.spi &&
(x0 = __xfrm_state_lookup(daddr, tmpl->id.spi, (x0 = __xfrm_state_lookup(&init_net, daddr, tmpl->id.spi,
tmpl->id.proto, family)) != NULL) { tmpl->id.proto, family)) != NULL) {
to_put = x0; to_put = x0;
error = -EEXIST; error = -EEXIST;
...@@ -1361,26 +1363,27 @@ int xfrm_state_check_expire(struct xfrm_state *x) ...@@ -1361,26 +1363,27 @@ int xfrm_state_check_expire(struct xfrm_state *x)
EXPORT_SYMBOL(xfrm_state_check_expire); EXPORT_SYMBOL(xfrm_state_check_expire);
struct xfrm_state * struct xfrm_state *
xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto,
unsigned short family) unsigned short family)
{ {
struct xfrm_state *x; struct xfrm_state *x;
spin_lock_bh(&xfrm_state_lock); spin_lock_bh(&xfrm_state_lock);
x = __xfrm_state_lookup(daddr, spi, proto, family); x = __xfrm_state_lookup(net, daddr, spi, proto, family);
spin_unlock_bh(&xfrm_state_lock); spin_unlock_bh(&xfrm_state_lock);
return x; return x;
} }
EXPORT_SYMBOL(xfrm_state_lookup); EXPORT_SYMBOL(xfrm_state_lookup);
struct xfrm_state * struct xfrm_state *
xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, xfrm_state_lookup_byaddr(struct net *net,
xfrm_address_t *daddr, xfrm_address_t *saddr,
u8 proto, unsigned short family) u8 proto, unsigned short family)
{ {
struct xfrm_state *x; struct xfrm_state *x;
spin_lock_bh(&xfrm_state_lock); spin_lock_bh(&xfrm_state_lock);
x = __xfrm_state_lookup_byaddr(daddr, saddr, proto, family); x = __xfrm_state_lookup_byaddr(net, daddr, saddr, proto, family);
spin_unlock_bh(&xfrm_state_lock); spin_unlock_bh(&xfrm_state_lock);
return x; return x;
} }
...@@ -1486,6 +1489,7 @@ EXPORT_SYMBOL(xfrm_get_acqseq); ...@@ -1486,6 +1489,7 @@ EXPORT_SYMBOL(xfrm_get_acqseq);
int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
{ {
struct net *net = xs_net(x);
unsigned int h; unsigned int h;
struct xfrm_state *x0; struct xfrm_state *x0;
int err = -ENOENT; int err = -ENOENT;
...@@ -1503,7 +1507,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) ...@@ -1503,7 +1507,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
err = -ENOENT; err = -ENOENT;
if (minspi == maxspi) { if (minspi == maxspi) {
x0 = xfrm_state_lookup(&x->id.daddr, minspi, x->id.proto, x->props.family); x0 = xfrm_state_lookup(net, &x->id.daddr, minspi, x->id.proto, x->props.family);
if (x0) { if (x0) {
xfrm_state_put(x0); xfrm_state_put(x0);
goto unlock; goto unlock;
...@@ -1513,7 +1517,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) ...@@ -1513,7 +1517,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
u32 spi = 0; u32 spi = 0;
for (h=0; h<high-low+1; h++) { for (h=0; h<high-low+1; h++) {
spi = low + net_random()%(high-low+1); spi = low + net_random()%(high-low+1);
x0 = xfrm_state_lookup(&x->id.daddr, htonl(spi), x->id.proto, x->props.family); x0 = xfrm_state_lookup(net, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
if (x0 == NULL) { if (x0 == NULL) {
x->id.spi = htonl(spi); x->id.spi = htonl(spi);
break; break;
......
...@@ -440,7 +440,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, ...@@ -440,7 +440,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) { if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) {
err = -ESRCH; err = -ESRCH;
x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family); x = xfrm_state_lookup(&init_net, &p->daddr, p->spi, p->proto, p->family);
} else { } else {
xfrm_address_t *saddr = NULL; xfrm_address_t *saddr = NULL;
...@@ -451,8 +451,8 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, ...@@ -451,8 +451,8 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
} }
err = -ESRCH; err = -ESRCH;
x = xfrm_state_lookup_byaddr(&p->daddr, saddr, p->proto, x = xfrm_state_lookup_byaddr(&init_net, &p->daddr, saddr,
p->family); p->proto, p->family);
} }
out: out:
...@@ -1468,7 +1468,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -1468,7 +1468,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
if (r_skb == NULL) if (r_skb == NULL)
return -ENOMEM; return -ENOMEM;
x = xfrm_state_lookup(&id->daddr, id->spi, id->proto, id->family); x = xfrm_state_lookup(&init_net, &id->daddr, id->spi, id->proto, id->family);
if (x == NULL) { if (x == NULL) {
kfree_skb(r_skb); kfree_skb(r_skb);
return -ESRCH; return -ESRCH;
...@@ -1509,7 +1509,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -1509,7 +1509,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
if (!(nlh->nlmsg_flags&NLM_F_REPLACE)) if (!(nlh->nlmsg_flags&NLM_F_REPLACE))
return err; return err;
x = xfrm_state_lookup(&p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); x = xfrm_state_lookup(&init_net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);
if (x == NULL) if (x == NULL)
return -ESRCH; return -ESRCH;
...@@ -1628,7 +1628,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -1628,7 +1628,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
struct xfrm_user_expire *ue = nlmsg_data(nlh); struct xfrm_user_expire *ue = nlmsg_data(nlh);
struct xfrm_usersa_info *p = &ue->state; struct xfrm_usersa_info *p = &ue->state;
x = xfrm_state_lookup(&p->id.daddr, p->id.spi, p->id.proto, p->family); x = xfrm_state_lookup(&init_net, &p->id.daddr, p->id.spi, p->id.proto, p->family);
err = -ENOENT; err = -ENOENT;
if (x == NULL) if (x == NULL)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment