Add mark/mask/exact parameters directly to __xfrm_state_lookup_byaddr(), reusing the SPI-keyed lookup's comparison. Use __xfrm_state_locate_exact()'s by-address branch UPDSA and xfrm_user_state_lookup()'s by-address branch (DELSA/GETSA for non-SPI-keyed lookups). Fixes: 3d6acfa7641f ("xfrm: SA lookups with mark") Signed-off-by: Antony Antony --- include/net/xfrm.h | 2 +- net/ipv6/xfrm6_input.c | 2 +- net/xfrm/xfrm_state.c | 21 +++++++++++---------- net/xfrm/xfrm_user.c | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index f6ed590cb2ff..ebe514376254 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1741,7 +1741,7 @@ struct xfrm_state *xfrm_input_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family); -struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark, +struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark, u32 mask, bool exact, const xfrm_address_t *daddr, const xfrm_address_t *saddr, u8 proto, diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 89d0443b5307..2dd347fece52 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -272,7 +272,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, break; } - x = xfrm_state_lookup_byaddr(net, skb->mark, dst, src, proto, AF_INET6); + x = xfrm_state_lookup_byaddr(net, skb->mark, 0, false, dst, src, proto, AF_INET6); if (!x) continue; diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index df761ce1c290..d78cfe481f75 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1274,11 +1274,12 @@ struct xfrm_state *xfrm_input_state_lookup(struct net *net, u32 mark, } EXPORT_SYMBOL(xfrm_input_state_lookup); -static struct xfrm_state *__xfrm_state_lookup_byaddr(const struct xfrm_hash_state_ptrs *state_ptrs, - u32 mark, - const xfrm_address_t *daddr, - const xfrm_address_t *saddr, - u8 proto, unsigned short family) +static struct xfrm_state * +__xfrm_state_lookup_byaddr(const struct xfrm_hash_state_ptrs *state_ptrs, + u32 mark, u32 mask, bool exact, + const xfrm_address_t *daddr, + const xfrm_address_t *saddr, + u8 proto, unsigned short family) { unsigned int h = __xfrm_src_hash(daddr, saddr, family, state_ptrs->hmask); struct xfrm_state *x; @@ -1290,7 +1291,7 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(const struct xfrm_hash_stat !xfrm_addr_equal(&x->props.saddr, saddr, family)) continue; - if ((mark & x->mark.m) != x->mark.v) + if (!xfrm_state_mark_matches(x, mark, mask, exact)) continue; if (!xfrm_state_hold_rcu(x)) continue; @@ -1313,7 +1314,7 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) return __xfrm_state_lookup(&state_ptrs, mark, 0, false, &x->id.daddr, x->id.spi, x->id.proto, family); else - return __xfrm_state_lookup_byaddr(&state_ptrs, mark, + return __xfrm_state_lookup_byaddr(&state_ptrs, mark, 0, false, &x->id.daddr, &x->props.saddr, x->id.proto, family); @@ -1334,7 +1335,7 @@ __xfrm_state_locate_exact(struct xfrm_state *x, int use_spi, int family) return __xfrm_state_lookup_exact(&state_ptrs, &x->mark, &x->id.daddr, x->id.spi, x->id.proto, family); else - return __xfrm_state_lookup_byaddr(&state_ptrs, x->mark.v & x->mark.m, + return __xfrm_state_lookup_byaddr(&state_ptrs, x->mark.v, x->mark.m, true, &x->id.daddr, &x->props.saddr, x->id.proto, family); @@ -2424,7 +2425,7 @@ xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32 EXPORT_SYMBOL(xfrm_state_lookup); struct xfrm_state * -xfrm_state_lookup_byaddr(struct net *net, u32 mark, +xfrm_state_lookup_byaddr(struct net *net, u32 mark, u32 mask, bool exact, const xfrm_address_t *daddr, const xfrm_address_t *saddr, u8 proto, unsigned short family) { @@ -2435,7 +2436,7 @@ xfrm_state_lookup_byaddr(struct net *net, u32 mark, xfrm_hash_ptrs_get(net, &state_ptrs); - x = __xfrm_state_lookup_byaddr(&state_ptrs, mark, daddr, saddr, proto, family); + x = __xfrm_state_lookup_byaddr(&state_ptrs, mark, mask, exact, daddr, saddr, proto, family); rcu_read_unlock(); return x; } diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b56fca666b89..11ec3b14a42f 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1105,7 +1105,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net, } err = -ESRCH; - x = xfrm_state_lookup_byaddr(net, m.v & m.m, + x = xfrm_state_lookup_byaddr(net, m.v, m.m, true, &p->daddr, saddr, p->proto, p->family); } -- 2.47.3