Commit 5447c5e4 authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by David S. Miller

netns xfrm: finding states in netns

Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 12604d8a
...@@ -1315,7 +1315,8 @@ extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t ...@@ -1315,7 +1315,8 @@ extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t
struct flowi *fl, struct xfrm_tmpl *tmpl, struct flowi *fl, struct xfrm_tmpl *tmpl,
struct xfrm_policy *pol, int *err, struct xfrm_policy *pol, int *err,
unsigned short family); unsigned short family);
extern struct xfrm_state * xfrm_stateonly_find(xfrm_address_t *daddr, extern struct xfrm_state * xfrm_stateonly_find(struct net *net,
xfrm_address_t *daddr,
xfrm_address_t *saddr, xfrm_address_t *saddr,
unsigned short family, unsigned short family,
u8 mode, u8 proto, u32 reqid); u8 mode, u8 proto, u32 reqid);
...@@ -1361,7 +1362,7 @@ struct xfrmk_spdinfo { ...@@ -1361,7 +1362,7 @@ struct xfrmk_spdinfo {
u32 spdhmcnt; u32 spdhmcnt;
}; };
extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); extern struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq);
extern int xfrm_state_delete(struct xfrm_state *x); extern int xfrm_state_delete(struct xfrm_state *x);
extern int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info); extern int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info);
extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si); extern 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); ...@@ -1446,7 +1447,7 @@ struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
u32 xfrm_get_acqseq(void); u32 xfrm_get_acqseq(void);
extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, struct xfrm_state * xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto,
xfrm_address_t *daddr, xfrm_address_t *saddr, xfrm_address_t *daddr, xfrm_address_t *saddr,
int create, unsigned short family); int create, unsigned short family);
extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
......
...@@ -2165,7 +2165,8 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow) ...@@ -2165,7 +2165,8 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
struct xfrm_state *x = pkt_dev->flows[flow].x; struct xfrm_state *x = pkt_dev->flows[flow].x;
if (!x) { if (!x) {
/*slow path: we dont already have xfrm_state*/ /*slow path: we dont already have xfrm_state*/
x = xfrm_stateonly_find((xfrm_address_t *)&pkt_dev->cur_daddr, x = xfrm_stateonly_find(&init_net,
(xfrm_address_t *)&pkt_dev->cur_daddr,
(xfrm_address_t *)&pkt_dev->cur_saddr, (xfrm_address_t *)&pkt_dev->cur_saddr,
AF_INET, AF_INET,
pkt_dev->ipsmode, pkt_dev->ipsmode,
......
...@@ -1348,7 +1348,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h ...@@ -1348,7 +1348,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
} }
if (hdr->sadb_msg_seq) { if (hdr->sadb_msg_seq) {
x = xfrm_find_acq_byseq(hdr->sadb_msg_seq); x = xfrm_find_acq_byseq(&init_net, hdr->sadb_msg_seq);
if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) { if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) {
xfrm_state_put(x); xfrm_state_put(x);
x = NULL; x = NULL;
...@@ -1356,7 +1356,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h ...@@ -1356,7 +1356,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
} }
if (!x) if (!x)
x = xfrm_find_acq(mode, reqid, proto, xdaddr, xsaddr, 1, family); x = xfrm_find_acq(&init_net, mode, reqid, proto, xdaddr, xsaddr, 1, family);
if (x == NULL) if (x == NULL)
return -ENOENT; return -ENOENT;
...@@ -1404,7 +1404,7 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg * ...@@ -1404,7 +1404,7 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0) if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0)
return 0; return 0;
x = xfrm_find_acq_byseq(hdr->sadb_msg_seq); x = xfrm_find_acq_byseq(&init_net, hdr->sadb_msg_seq);
if (x == NULL) if (x == NULL)
return 0; return 0;
......
...@@ -765,6 +765,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, ...@@ -765,6 +765,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
struct xfrm_policy *pol, int *err, struct xfrm_policy *pol, int *err,
unsigned short family) unsigned short family)
{ {
struct net *net = xp_net(pol);
unsigned int h; unsigned int h;
struct hlist_node *entry; struct hlist_node *entry;
struct xfrm_state *x, *x0, *to_put; struct xfrm_state *x, *x0, *to_put;
...@@ -775,8 +776,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, ...@@ -775,8 +776,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
to_put = NULL; to_put = NULL;
spin_lock_bh(&xfrm_state_lock); spin_lock_bh(&xfrm_state_lock);
h = xfrm_dst_hash(&init_net, daddr, saddr, tmpl->reqid, family); h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, family);
hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) { hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
if (x->props.family == family && if (x->props.family == family &&
x->props.reqid == tmpl->reqid && x->props.reqid == tmpl->reqid &&
!(x->props.flags & XFRM_STATE_WILDRECV) && !(x->props.flags & XFRM_STATE_WILDRECV) &&
...@@ -820,13 +821,13 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, ...@@ -820,13 +821,13 @@ 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(&init_net, daddr, tmpl->id.spi, (x0 = __xfrm_state_lookup(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;
goto out; goto out;
} }
x = xfrm_state_alloc(&init_net); x = xfrm_state_alloc(net);
if (x == NULL) { if (x == NULL) {
error = -ENOMEM; error = -ENOMEM;
goto out; goto out;
...@@ -845,19 +846,19 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, ...@@ -845,19 +846,19 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
if (km_query(x, tmpl, pol) == 0) { if (km_query(x, tmpl, pol) == 0) {
x->km.state = XFRM_STATE_ACQ; x->km.state = XFRM_STATE_ACQ;
list_add(&x->km.all, &init_net.xfrm.state_all); list_add(&x->km.all, &net->xfrm.state_all);
hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); hlist_add_head(&x->bydst, net->xfrm.state_bydst+h);
h = xfrm_src_hash(&init_net, daddr, saddr, family); h = xfrm_src_hash(net, daddr, saddr, family);
hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h); hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h);
if (x->id.spi) { if (x->id.spi) {
h = xfrm_spi_hash(&init_net, &x->id.daddr, x->id.spi, x->id.proto, family); h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, family);
hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h); hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
} }
x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires; x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
add_timer(&x->timer); add_timer(&x->timer);
init_net.xfrm.state_num++; net->xfrm.state_num++;
xfrm_hash_grow_check(&init_net, x->bydst.next != NULL); xfrm_hash_grow_check(net, x->bydst.next != NULL);
} else { } else {
x->km.state = XFRM_STATE_DEAD; x->km.state = XFRM_STATE_DEAD;
to_put = x; to_put = x;
...@@ -877,7 +878,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, ...@@ -877,7 +878,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
} }
struct xfrm_state * struct xfrm_state *
xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr, xfrm_stateonly_find(struct net *net,
xfrm_address_t *daddr, xfrm_address_t *saddr,
unsigned short family, u8 mode, u8 proto, u32 reqid) unsigned short family, u8 mode, u8 proto, u32 reqid)
{ {
unsigned int h; unsigned int h;
...@@ -885,8 +887,8 @@ xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr, ...@@ -885,8 +887,8 @@ xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
struct hlist_node *entry; struct hlist_node *entry;
spin_lock(&xfrm_state_lock); spin_lock(&xfrm_state_lock);
h = xfrm_dst_hash(&init_net, daddr, saddr, reqid, family); h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) { hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
if (x->props.family == family && if (x->props.family == family &&
x->props.reqid == reqid && x->props.reqid == reqid &&
!(x->props.flags & XFRM_STATE_WILDRECV) && !(x->props.flags & XFRM_STATE_WILDRECV) &&
...@@ -972,13 +974,13 @@ void xfrm_state_insert(struct xfrm_state *x) ...@@ -972,13 +974,13 @@ void xfrm_state_insert(struct xfrm_state *x)
EXPORT_SYMBOL(xfrm_state_insert); EXPORT_SYMBOL(xfrm_state_insert);
/* xfrm_state_lock is held */ /* xfrm_state_lock is held */
static 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) static 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)
{ {
unsigned int h = xfrm_dst_hash(&init_net, daddr, saddr, reqid, family); unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
struct hlist_node *entry; struct hlist_node *entry;
struct xfrm_state *x; struct xfrm_state *x;
hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) { hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
if (x->props.reqid != reqid || if (x->props.reqid != reqid ||
x->props.mode != mode || x->props.mode != mode ||
x->props.family != family || x->props.family != family ||
...@@ -1010,7 +1012,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re ...@@ -1010,7 +1012,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
if (!create) if (!create)
return NULL; return NULL;
x = xfrm_state_alloc(&init_net); x = xfrm_state_alloc(net);
if (likely(x)) { if (likely(x)) {
switch (family) { switch (family) {
case AF_INET: case AF_INET:
...@@ -1045,23 +1047,24 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re ...@@ -1045,23 +1047,24 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
xfrm_state_hold(x); xfrm_state_hold(x);
x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
add_timer(&x->timer); add_timer(&x->timer);
list_add(&x->km.all, &init_net.xfrm.state_all); list_add(&x->km.all, &net->xfrm.state_all);
hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); hlist_add_head(&x->bydst, net->xfrm.state_bydst+h);
h = xfrm_src_hash(&init_net, daddr, saddr, family); h = xfrm_src_hash(net, daddr, saddr, family);
hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h); hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h);
init_net.xfrm.state_num++; net->xfrm.state_num++;
xfrm_hash_grow_check(&init_net, x->bydst.next != NULL); xfrm_hash_grow_check(net, x->bydst.next != NULL);
} }
return x; return x;
} }
static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq); static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq);
int xfrm_state_add(struct xfrm_state *x) int xfrm_state_add(struct xfrm_state *x)
{ {
struct net *net = xs_net(x);
struct xfrm_state *x1, *to_put; struct xfrm_state *x1, *to_put;
int family; int family;
int err; int err;
...@@ -1082,7 +1085,7 @@ int xfrm_state_add(struct xfrm_state *x) ...@@ -1082,7 +1085,7 @@ int xfrm_state_add(struct xfrm_state *x)
} }
if (use_spi && x->km.seq) { if (use_spi && x->km.seq) {
x1 = __xfrm_find_acq_byseq(x->km.seq); x1 = __xfrm_find_acq_byseq(net, x->km.seq);
if (x1 && ((x1->id.proto != x->id.proto) || if (x1 && ((x1->id.proto != x->id.proto) ||
xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) { xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) {
to_put = x1; to_put = x1;
...@@ -1091,7 +1094,7 @@ int xfrm_state_add(struct xfrm_state *x) ...@@ -1091,7 +1094,7 @@ int xfrm_state_add(struct xfrm_state *x)
} }
if (use_spi && !x1) if (use_spi && !x1)
x1 = __find_acq_core(family, x->props.mode, x->props.reqid, x1 = __find_acq_core(net, family, x->props.mode, x->props.reqid,
x->id.proto, x->id.proto,
&x->id.daddr, &x->props.saddr, 0); &x->id.daddr, &x->props.saddr, 0);
...@@ -1390,14 +1393,14 @@ xfrm_state_lookup_byaddr(struct net *net, ...@@ -1390,14 +1393,14 @@ xfrm_state_lookup_byaddr(struct net *net,
EXPORT_SYMBOL(xfrm_state_lookup_byaddr); EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
struct xfrm_state * struct xfrm_state *
xfrm_find_acq(u8 mode, u32 reqid, u8 proto, xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto,
xfrm_address_t *daddr, xfrm_address_t *saddr, xfrm_address_t *daddr, xfrm_address_t *saddr,
int create, unsigned short family) int create, unsigned short family)
{ {
struct xfrm_state *x; struct xfrm_state *x;
spin_lock_bh(&xfrm_state_lock); spin_lock_bh(&xfrm_state_lock);
x = __find_acq_core(family, mode, reqid, proto, daddr, saddr, create); x = __find_acq_core(net, family, mode, reqid, proto, daddr, saddr, create);
spin_unlock_bh(&xfrm_state_lock); spin_unlock_bh(&xfrm_state_lock);
return x; return x;
...@@ -1444,15 +1447,15 @@ EXPORT_SYMBOL(xfrm_state_sort); ...@@ -1444,15 +1447,15 @@ EXPORT_SYMBOL(xfrm_state_sort);
/* Silly enough, but I'm lazy to build resolution list */ /* Silly enough, but I'm lazy to build resolution list */
static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq) static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq)
{ {
int i; int i;
for (i = 0; i <= init_net.xfrm.state_hmask; i++) { for (i = 0; i <= net->xfrm.state_hmask; i++) {
struct hlist_node *entry; struct hlist_node *entry;
struct xfrm_state *x; struct xfrm_state *x;
hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+i, bydst) { hlist_for_each_entry(x, entry, net->xfrm.state_bydst+i, bydst) {
if (x->km.seq == seq && if (x->km.seq == seq &&
x->km.state == XFRM_STATE_ACQ) { x->km.state == XFRM_STATE_ACQ) {
xfrm_state_hold(x); xfrm_state_hold(x);
...@@ -1463,12 +1466,12 @@ static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq) ...@@ -1463,12 +1466,12 @@ static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq)
return NULL; return NULL;
} }
struct xfrm_state *xfrm_find_acq_byseq(u32 seq) struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq)
{ {
struct xfrm_state *x; struct xfrm_state *x;
spin_lock_bh(&xfrm_state_lock); spin_lock_bh(&xfrm_state_lock);
x = __xfrm_find_acq_byseq(seq); x = __xfrm_find_acq_byseq(net, seq);
spin_unlock_bh(&xfrm_state_lock); spin_unlock_bh(&xfrm_state_lock);
return x; return x;
} }
......
...@@ -837,7 +837,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -837,7 +837,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
x = NULL; x = NULL;
if (p->info.seq) { if (p->info.seq) {
x = xfrm_find_acq_byseq(p->info.seq); x = xfrm_find_acq_byseq(&init_net, p->info.seq);
if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) { if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) {
xfrm_state_put(x); xfrm_state_put(x);
x = NULL; x = NULL;
...@@ -845,7 +845,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -845,7 +845,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
} }
if (!x) if (!x)
x = xfrm_find_acq(p->info.mode, p->info.reqid, x = xfrm_find_acq(&init_net, p->info.mode, p->info.reqid,
p->info.id.proto, daddr, p->info.id.proto, daddr,
&p->info.saddr, 1, &p->info.saddr, 1,
family); family);
......
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