mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
xfrm: SA lookups signature with mark
pass mark to all SA lookups to prepare them for when we add code to have them search. Signed-off-by: Jamal Hadi Salim <[email protected]> Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
parent
bf825f81b4
commit
bd55775c8d
13 changed files with 84 additions and 55 deletions
|
|
@ -152,7 +152,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
|
|||
goto drop;
|
||||
}
|
||||
|
||||
x = xfrm_state_lookup(net, daddr, spi, nexthdr, family);
|
||||
x = xfrm_state_lookup(net, skb->mark, daddr, spi, nexthdr, family);
|
||||
if (x == NULL) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
|
||||
xfrm_audit_state_notfound(skb, family, spi, seq);
|
||||
|
|
|
|||
|
|
@ -669,7 +669,7 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
|
||||
static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
|
||||
{
|
||||
unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family);
|
||||
struct xfrm_state *x;
|
||||
|
|
@ -689,7 +689,7 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *d
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
|
||||
static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
|
||||
{
|
||||
unsigned int h = xfrm_src_hash(net, daddr, saddr, family);
|
||||
struct xfrm_state *x;
|
||||
|
|
@ -713,12 +713,14 @@ static inline struct xfrm_state *
|
|||
__xfrm_state_locate(struct xfrm_state *x, int use_spi, int family)
|
||||
{
|
||||
struct net *net = xs_net(x);
|
||||
u32 mark = x->mark.v & x->mark.m;
|
||||
|
||||
if (use_spi)
|
||||
return __xfrm_state_lookup(net, &x->id.daddr, x->id.spi,
|
||||
x->id.proto, family);
|
||||
return __xfrm_state_lookup(net, mark, &x->id.daddr,
|
||||
x->id.spi, x->id.proto, family);
|
||||
else
|
||||
return __xfrm_state_lookup_byaddr(net, &x->id.daddr,
|
||||
return __xfrm_state_lookup_byaddr(net, mark,
|
||||
&x->id.daddr,
|
||||
&x->props.saddr,
|
||||
x->id.proto, family);
|
||||
}
|
||||
|
|
@ -783,6 +785,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
|
|||
int acquire_in_progress = 0;
|
||||
int error = 0;
|
||||
struct xfrm_state *best = NULL;
|
||||
u32 mark = pol->mark.v & pol->mark.m;
|
||||
|
||||
to_put = NULL;
|
||||
|
||||
|
|
@ -819,7 +822,7 @@ found:
|
|||
x = best;
|
||||
if (!x && !error && !acquire_in_progress) {
|
||||
if (tmpl->id.spi &&
|
||||
(x0 = __xfrm_state_lookup(net, daddr, tmpl->id.spi,
|
||||
(x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi,
|
||||
tmpl->id.proto, family)) != NULL) {
|
||||
to_put = x0;
|
||||
error = -EEXIST;
|
||||
|
|
@ -833,6 +836,7 @@ found:
|
|||
/* Initialize temporary selector matching only
|
||||
* to current session. */
|
||||
xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family);
|
||||
memcpy(&x->mark, &pol->mark, sizeof(x->mark));
|
||||
|
||||
error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid);
|
||||
if (error) {
|
||||
|
|
@ -875,7 +879,7 @@ out:
|
|||
}
|
||||
|
||||
struct xfrm_state *
|
||||
xfrm_stateonly_find(struct net *net,
|
||||
xfrm_stateonly_find(struct net *net, u32 mark,
|
||||
xfrm_address_t *daddr, xfrm_address_t *saddr,
|
||||
unsigned short family, u8 mode, u8 proto, u32 reqid)
|
||||
{
|
||||
|
|
@ -971,7 +975,7 @@ void xfrm_state_insert(struct xfrm_state *x)
|
|||
EXPORT_SYMBOL(xfrm_state_insert);
|
||||
|
||||
/* xfrm_state_lock is held */
|
||||
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)
|
||||
static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m, 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(net, daddr, saddr, reqid, family);
|
||||
struct hlist_node *entry;
|
||||
|
|
@ -1026,6 +1030,8 @@ static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family
|
|||
x->props.family = family;
|
||||
x->props.mode = mode;
|
||||
x->props.reqid = reqid;
|
||||
x->mark.v = m->v;
|
||||
x->mark.m = m->m;
|
||||
x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires;
|
||||
xfrm_state_hold(x);
|
||||
tasklet_hrtimer_start(&x->mtimer, ktime_set(net->xfrm.sysctl_acq_expires, 0), HRTIMER_MODE_REL);
|
||||
|
|
@ -1042,7 +1048,7 @@ static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family
|
|||
return x;
|
||||
}
|
||||
|
||||
static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq);
|
||||
static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
|
||||
|
||||
int xfrm_state_add(struct xfrm_state *x)
|
||||
{
|
||||
|
|
@ -1050,6 +1056,7 @@ int xfrm_state_add(struct xfrm_state *x)
|
|||
struct xfrm_state *x1, *to_put;
|
||||
int family;
|
||||
int err;
|
||||
u32 mark = x->mark.v & x->mark.m;
|
||||
int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
|
||||
|
||||
family = x->props.family;
|
||||
|
|
@ -1067,7 +1074,7 @@ int xfrm_state_add(struct xfrm_state *x)
|
|||
}
|
||||
|
||||
if (use_spi && x->km.seq) {
|
||||
x1 = __xfrm_find_acq_byseq(net, x->km.seq);
|
||||
x1 = __xfrm_find_acq_byseq(net, mark, x->km.seq);
|
||||
if (x1 && ((x1->id.proto != x->id.proto) ||
|
||||
xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) {
|
||||
to_put = x1;
|
||||
|
|
@ -1076,8 +1083,8 @@ int xfrm_state_add(struct xfrm_state *x)
|
|||
}
|
||||
|
||||
if (use_spi && !x1)
|
||||
x1 = __find_acq_core(net, family, x->props.mode, x->props.reqid,
|
||||
x->id.proto,
|
||||
x1 = __find_acq_core(net, &x->mark, family, x->props.mode,
|
||||
x->props.reqid, x->id.proto,
|
||||
&x->id.daddr, &x->props.saddr, 0);
|
||||
|
||||
__xfrm_state_bump_genids(x);
|
||||
|
|
@ -1151,6 +1158,8 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
|
|||
goto error;
|
||||
}
|
||||
|
||||
memcpy(&x->mark, &orig->mark, sizeof(x->mark));
|
||||
|
||||
err = xfrm_init_state(x);
|
||||
if (err)
|
||||
goto error;
|
||||
|
|
@ -1342,41 +1351,41 @@ int xfrm_state_check_expire(struct xfrm_state *x)
|
|||
EXPORT_SYMBOL(xfrm_state_check_expire);
|
||||
|
||||
struct xfrm_state *
|
||||
xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto,
|
||||
unsigned short family)
|
||||
xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi,
|
||||
u8 proto, unsigned short family)
|
||||
{
|
||||
struct xfrm_state *x;
|
||||
|
||||
spin_lock_bh(&xfrm_state_lock);
|
||||
x = __xfrm_state_lookup(net, daddr, spi, proto, family);
|
||||
x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family);
|
||||
spin_unlock_bh(&xfrm_state_lock);
|
||||
return x;
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_state_lookup);
|
||||
|
||||
struct xfrm_state *
|
||||
xfrm_state_lookup_byaddr(struct net *net,
|
||||
xfrm_state_lookup_byaddr(struct net *net, u32 mark,
|
||||
xfrm_address_t *daddr, xfrm_address_t *saddr,
|
||||
u8 proto, unsigned short family)
|
||||
{
|
||||
struct xfrm_state *x;
|
||||
|
||||
spin_lock_bh(&xfrm_state_lock);
|
||||
x = __xfrm_state_lookup_byaddr(net, daddr, saddr, proto, family);
|
||||
x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family);
|
||||
spin_unlock_bh(&xfrm_state_lock);
|
||||
return x;
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
|
||||
|
||||
struct xfrm_state *
|
||||
xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto,
|
||||
xfrm_find_acq(struct net *net, struct xfrm_mark *mark, u8 mode, u32 reqid, u8 proto,
|
||||
xfrm_address_t *daddr, xfrm_address_t *saddr,
|
||||
int create, unsigned short family)
|
||||
{
|
||||
struct xfrm_state *x;
|
||||
|
||||
spin_lock_bh(&xfrm_state_lock);
|
||||
x = __find_acq_core(net, family, mode, reqid, proto, daddr, saddr, create);
|
||||
x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create);
|
||||
spin_unlock_bh(&xfrm_state_lock);
|
||||
|
||||
return x;
|
||||
|
|
@ -1423,7 +1432,7 @@ EXPORT_SYMBOL(xfrm_state_sort);
|
|||
|
||||
/* Silly enough, but I'm lazy to build resolution list */
|
||||
|
||||
static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq)
|
||||
static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -1442,12 +1451,12 @@ static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq)
|
||||
struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
|
||||
{
|
||||
struct xfrm_state *x;
|
||||
|
||||
spin_lock_bh(&xfrm_state_lock);
|
||||
x = __xfrm_find_acq_byseq(net, seq);
|
||||
x = __xfrm_find_acq_byseq(net, mark, seq);
|
||||
spin_unlock_bh(&xfrm_state_lock);
|
||||
return x;
|
||||
}
|
||||
|
|
@ -1474,6 +1483,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
|
|||
int err = -ENOENT;
|
||||
__be32 minspi = htonl(low);
|
||||
__be32 maxspi = htonl(high);
|
||||
u32 mark = x->mark.v & x->mark.m;
|
||||
|
||||
spin_lock_bh(&x->lock);
|
||||
if (x->km.state == XFRM_STATE_DEAD)
|
||||
|
|
@ -1486,7 +1496,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
|
|||
err = -ENOENT;
|
||||
|
||||
if (minspi == maxspi) {
|
||||
x0 = xfrm_state_lookup(net, &x->id.daddr, minspi, x->id.proto, x->props.family);
|
||||
x0 = xfrm_state_lookup(net, mark, &x->id.daddr, minspi, x->id.proto, x->props.family);
|
||||
if (x0) {
|
||||
xfrm_state_put(x0);
|
||||
goto unlock;
|
||||
|
|
@ -1496,7 +1506,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
|
|||
u32 spi = 0;
|
||||
for (h=0; h<high-low+1; h++) {
|
||||
spi = low + net_random()%(high-low+1);
|
||||
x0 = xfrm_state_lookup(net, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
|
||||
x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
|
||||
if (x0 == NULL) {
|
||||
x->id.spi = htonl(spi);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
#include <linux/in6.h>
|
||||
#endif
|
||||
|
||||
#define DUMMY_MARK 0
|
||||
static struct xfrm_mark dummy_mark = {0, 0};
|
||||
|
||||
static inline int aead_len(struct xfrm_algo_aead *alg)
|
||||
{
|
||||
return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
|
||||
|
|
@ -530,7 +533,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net,
|
|||
|
||||
if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) {
|
||||
err = -ESRCH;
|
||||
x = xfrm_state_lookup(net, &p->daddr, p->spi, p->proto, p->family);
|
||||
x = xfrm_state_lookup(net, DUMMY_MARK, &p->daddr, p->spi, p->proto, p->family);
|
||||
} else {
|
||||
xfrm_address_t *saddr = NULL;
|
||||
|
||||
|
|
@ -541,7 +544,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net,
|
|||
}
|
||||
|
||||
err = -ESRCH;
|
||||
x = xfrm_state_lookup_byaddr(net, &p->daddr, saddr,
|
||||
x = xfrm_state_lookup_byaddr(net, DUMMY_MARK, &p->daddr, saddr,
|
||||
p->proto, p->family);
|
||||
}
|
||||
|
||||
|
|
@ -958,7 +961,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
|
||||
x = NULL;
|
||||
if (p->info.seq) {
|
||||
x = xfrm_find_acq_byseq(net, p->info.seq);
|
||||
x = xfrm_find_acq_byseq(net, DUMMY_MARK, p->info.seq);
|
||||
if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) {
|
||||
xfrm_state_put(x);
|
||||
x = NULL;
|
||||
|
|
@ -966,7 +969,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
}
|
||||
|
||||
if (!x)
|
||||
x = xfrm_find_acq(net, p->info.mode, p->info.reqid,
|
||||
x = xfrm_find_acq(net, &dummy_mark, p->info.mode, p->info.reqid,
|
||||
p->info.id.proto, daddr,
|
||||
&p->info.saddr, 1,
|
||||
family);
|
||||
|
|
@ -1598,7 +1601,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
if (r_skb == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
x = xfrm_state_lookup(net, &id->daddr, id->spi, id->proto, id->family);
|
||||
x = xfrm_state_lookup(net, DUMMY_MARK, &id->daddr, id->spi, id->proto, id->family);
|
||||
if (x == NULL) {
|
||||
kfree_skb(r_skb);
|
||||
return -ESRCH;
|
||||
|
|
@ -1640,7 +1643,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
if (!(nlh->nlmsg_flags&NLM_F_REPLACE))
|
||||
return err;
|
||||
|
||||
x = xfrm_state_lookup(net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);
|
||||
x = xfrm_state_lookup(net, DUMMY_MARK, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);
|
||||
if (x == NULL)
|
||||
return -ESRCH;
|
||||
|
||||
|
|
@ -1767,7 +1770,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
struct xfrm_user_expire *ue = nlmsg_data(nlh);
|
||||
struct xfrm_usersa_info *p = &ue->state;
|
||||
|
||||
x = xfrm_state_lookup(net, &p->id.daddr, p->id.spi, p->id.proto, p->family);
|
||||
x = xfrm_state_lookup(net, DUMMY_MARK, &p->id.daddr, p->id.spi, p->id.proto, p->family);
|
||||
|
||||
err = -ENOENT;
|
||||
if (x == NULL)
|
||||
|
|
|
|||
Loading…
Reference in a new issue