Commit 2da4c187 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files


Steffen Klassert says:

====================
1) Fix packet receiving of standard IP tunnels when the xfrm_interface
   module is installed. From Xin Long.

2) Fix a race condition between spi allocating and hash list
   resizing. From zhuoliang zhang.
====================

Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents fea07a48 a779d913
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -64,14 +64,14 @@ static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
static struct xfrm_tunnel xfrm_tunnel_handler __read_mostly = {
	.handler	=	xfrm_tunnel_rcv,
	.err_handler	=	xfrm_tunnel_err,
	.priority	=	3,
	.priority	=	4,
};

#if IS_ENABLED(CONFIG_IPV6)
static struct xfrm_tunnel xfrm64_tunnel_handler __read_mostly = {
	.handler	=	xfrm_tunnel_rcv,
	.err_handler	=	xfrm_tunnel_err,
	.priority	=	2,
	.priority	=	3,
};
#endif

+2 −2
Original line number Diff line number Diff line
@@ -303,13 +303,13 @@ static const struct xfrm_type xfrm6_tunnel_type = {
static struct xfrm6_tunnel xfrm6_tunnel_handler __read_mostly = {
	.handler	= xfrm6_tunnel_rcv,
	.err_handler	= xfrm6_tunnel_err,
	.priority	= 2,
	.priority	= 3,
};

static struct xfrm6_tunnel xfrm46_tunnel_handler __read_mostly = {
	.handler	= xfrm6_tunnel_rcv,
	.err_handler	= xfrm6_tunnel_err,
	.priority	= 2,
	.priority	= 3,
};

static int __net_init xfrm6_tunnel_net_init(struct net *net)
+4 −4
Original line number Diff line number Diff line
@@ -803,14 +803,14 @@ static struct xfrm6_tunnel xfrmi_ipv6_handler __read_mostly = {
	.handler	=	xfrmi6_rcv_tunnel,
	.cb_handler	=	xfrmi_rcv_cb,
	.err_handler	=	xfrmi6_err,
	.priority	=	-1,
	.priority	=	2,
};

static struct xfrm6_tunnel xfrmi_ip6ip_handler __read_mostly = {
	.handler	=	xfrmi6_rcv_tunnel,
	.cb_handler	=	xfrmi_rcv_cb,
	.err_handler	=	xfrmi6_err,
	.priority	=	-1,
	.priority	=	2,
};
#endif

@@ -848,14 +848,14 @@ static struct xfrm_tunnel xfrmi_ipip_handler __read_mostly = {
	.handler	=	xfrmi4_rcv_tunnel,
	.cb_handler	=	xfrmi_rcv_cb,
	.err_handler	=	xfrmi4_err,
	.priority	=	-1,
	.priority	=	3,
};

static struct xfrm_tunnel xfrmi_ipip6_handler __read_mostly = {
	.handler	=	xfrmi4_rcv_tunnel,
	.cb_handler	=	xfrmi_rcv_cb,
	.err_handler	=	xfrmi4_err,
	.priority	=	-1,
	.priority	=	2,
};
#endif

+5 −3
Original line number Diff line number Diff line
@@ -2004,6 +2004,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
	int err = -ENOENT;
	__be32 minspi = htonl(low);
	__be32 maxspi = htonl(high);
	__be32 newspi = 0;
	u32 mark = x->mark.v & x->mark.m;

	spin_lock_bh(&x->lock);
@@ -2022,21 +2023,22 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
			xfrm_state_put(x0);
			goto unlock;
		}
		x->id.spi = minspi;
		newspi = minspi;
	} else {
		u32 spi = 0;
		for (h = 0; h < high-low+1; h++) {
			spi = low + prandom_u32()%(high-low+1);
			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);
				newspi = htonl(spi);
				break;
			}
			xfrm_state_put(x0);
		}
	}
	if (x->id.spi) {
	if (newspi) {
		spin_lock_bh(&net->xfrm.xfrm_state_lock);
		x->id.spi = newspi;
		h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
		hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h);
		spin_unlock_bh(&net->xfrm.xfrm_state_lock);