xref: /OK3568_Linux_fs/kernel/net/xfrm/xfrm_input.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * xfrm_input.c
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Changes:
6*4882a593Smuzhiyun  * 	YOSHIFUJI Hideaki @USAGI
7*4882a593Smuzhiyun  * 		Split up af-specific portion
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <linux/bottom_half.h>
12*4882a593Smuzhiyun #include <linux/cache.h>
13*4882a593Smuzhiyun #include <linux/interrupt.h>
14*4882a593Smuzhiyun #include <linux/slab.h>
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/netdevice.h>
17*4882a593Smuzhiyun #include <linux/percpu.h>
18*4882a593Smuzhiyun #include <net/dst.h>
19*4882a593Smuzhiyun #include <net/ip.h>
20*4882a593Smuzhiyun #include <net/xfrm.h>
21*4882a593Smuzhiyun #include <net/ip_tunnels.h>
22*4882a593Smuzhiyun #include <net/ip6_tunnel.h>
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #include "xfrm_inout.h"
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun struct xfrm_trans_tasklet {
27*4882a593Smuzhiyun 	struct tasklet_struct tasklet;
28*4882a593Smuzhiyun 	struct sk_buff_head queue;
29*4882a593Smuzhiyun };
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun struct xfrm_trans_cb {
32*4882a593Smuzhiyun 	union {
33*4882a593Smuzhiyun 		struct inet_skb_parm	h4;
34*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_IPV6)
35*4882a593Smuzhiyun 		struct inet6_skb_parm	h6;
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun 	} header;
38*4882a593Smuzhiyun 	int (*finish)(struct net *net, struct sock *sk, struct sk_buff *skb);
39*4882a593Smuzhiyun 	struct net *net;
40*4882a593Smuzhiyun };
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #define XFRM_TRANS_SKB_CB(__skb) ((struct xfrm_trans_cb *)&((__skb)->cb[0]))
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun static DEFINE_SPINLOCK(xfrm_input_afinfo_lock);
45*4882a593Smuzhiyun static struct xfrm_input_afinfo const __rcu *xfrm_input_afinfo[2][AF_INET6 + 1];
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun static struct gro_cells gro_cells;
48*4882a593Smuzhiyun static struct net_device xfrm_napi_dev;
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun static DEFINE_PER_CPU(struct xfrm_trans_tasklet, xfrm_trans_tasklet);
51*4882a593Smuzhiyun 
xfrm_input_register_afinfo(const struct xfrm_input_afinfo * afinfo)52*4882a593Smuzhiyun int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun 	int err = 0;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	if (WARN_ON(afinfo->family > AF_INET6))
57*4882a593Smuzhiyun 		return -EAFNOSUPPORT;
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	spin_lock_bh(&xfrm_input_afinfo_lock);
60*4882a593Smuzhiyun 	if (unlikely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family]))
61*4882a593Smuzhiyun 		err = -EEXIST;
62*4882a593Smuzhiyun 	else
63*4882a593Smuzhiyun 		rcu_assign_pointer(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family], afinfo);
64*4882a593Smuzhiyun 	spin_unlock_bh(&xfrm_input_afinfo_lock);
65*4882a593Smuzhiyun 	return err;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun EXPORT_SYMBOL(xfrm_input_register_afinfo);
68*4882a593Smuzhiyun 
xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo * afinfo)69*4882a593Smuzhiyun int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun 	int err = 0;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	spin_lock_bh(&xfrm_input_afinfo_lock);
74*4882a593Smuzhiyun 	if (likely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family])) {
75*4882a593Smuzhiyun 		if (unlikely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family] != afinfo))
76*4882a593Smuzhiyun 			err = -EINVAL;
77*4882a593Smuzhiyun 		else
78*4882a593Smuzhiyun 			RCU_INIT_POINTER(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family], NULL);
79*4882a593Smuzhiyun 	}
80*4882a593Smuzhiyun 	spin_unlock_bh(&xfrm_input_afinfo_lock);
81*4882a593Smuzhiyun 	synchronize_rcu();
82*4882a593Smuzhiyun 	return err;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun EXPORT_SYMBOL(xfrm_input_unregister_afinfo);
85*4882a593Smuzhiyun 
xfrm_input_get_afinfo(u8 family,bool is_ipip)86*4882a593Smuzhiyun static const struct xfrm_input_afinfo *xfrm_input_get_afinfo(u8 family, bool is_ipip)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	const struct xfrm_input_afinfo *afinfo;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	if (WARN_ON_ONCE(family > AF_INET6))
91*4882a593Smuzhiyun 		return NULL;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	rcu_read_lock();
94*4882a593Smuzhiyun 	afinfo = rcu_dereference(xfrm_input_afinfo[is_ipip][family]);
95*4882a593Smuzhiyun 	if (unlikely(!afinfo))
96*4882a593Smuzhiyun 		rcu_read_unlock();
97*4882a593Smuzhiyun 	return afinfo;
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
xfrm_rcv_cb(struct sk_buff * skb,unsigned int family,u8 protocol,int err)100*4882a593Smuzhiyun static int xfrm_rcv_cb(struct sk_buff *skb, unsigned int family, u8 protocol,
101*4882a593Smuzhiyun 		       int err)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun 	bool is_ipip = (protocol == IPPROTO_IPIP || protocol == IPPROTO_IPV6);
104*4882a593Smuzhiyun 	const struct xfrm_input_afinfo *afinfo;
105*4882a593Smuzhiyun 	int ret;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	afinfo = xfrm_input_get_afinfo(family, is_ipip);
108*4882a593Smuzhiyun 	if (!afinfo)
109*4882a593Smuzhiyun 		return -EAFNOSUPPORT;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	ret = afinfo->callback(skb, protocol, err);
112*4882a593Smuzhiyun 	rcu_read_unlock();
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	return ret;
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun 
secpath_set(struct sk_buff * skb)117*4882a593Smuzhiyun struct sec_path *secpath_set(struct sk_buff *skb)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun 	struct sec_path *sp, *tmp = skb_ext_find(skb, SKB_EXT_SEC_PATH);
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	sp = skb_ext_add(skb, SKB_EXT_SEC_PATH);
122*4882a593Smuzhiyun 	if (!sp)
123*4882a593Smuzhiyun 		return NULL;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	if (tmp) /* reused existing one (was COW'd if needed) */
126*4882a593Smuzhiyun 		return sp;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	/* allocated new secpath */
129*4882a593Smuzhiyun 	memset(sp->ovec, 0, sizeof(sp->ovec));
130*4882a593Smuzhiyun 	sp->olen = 0;
131*4882a593Smuzhiyun 	sp->len = 0;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	return sp;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun EXPORT_SYMBOL(secpath_set);
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun /* Fetch spi and seq from ipsec header */
138*4882a593Smuzhiyun 
xfrm_parse_spi(struct sk_buff * skb,u8 nexthdr,__be32 * spi,__be32 * seq)139*4882a593Smuzhiyun int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	int offset, offset_seq;
142*4882a593Smuzhiyun 	int hlen;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	switch (nexthdr) {
145*4882a593Smuzhiyun 	case IPPROTO_AH:
146*4882a593Smuzhiyun 		hlen = sizeof(struct ip_auth_hdr);
147*4882a593Smuzhiyun 		offset = offsetof(struct ip_auth_hdr, spi);
148*4882a593Smuzhiyun 		offset_seq = offsetof(struct ip_auth_hdr, seq_no);
149*4882a593Smuzhiyun 		break;
150*4882a593Smuzhiyun 	case IPPROTO_ESP:
151*4882a593Smuzhiyun 		hlen = sizeof(struct ip_esp_hdr);
152*4882a593Smuzhiyun 		offset = offsetof(struct ip_esp_hdr, spi);
153*4882a593Smuzhiyun 		offset_seq = offsetof(struct ip_esp_hdr, seq_no);
154*4882a593Smuzhiyun 		break;
155*4882a593Smuzhiyun 	case IPPROTO_COMP:
156*4882a593Smuzhiyun 		if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr)))
157*4882a593Smuzhiyun 			return -EINVAL;
158*4882a593Smuzhiyun 		*spi = htonl(ntohs(*(__be16 *)(skb_transport_header(skb) + 2)));
159*4882a593Smuzhiyun 		*seq = 0;
160*4882a593Smuzhiyun 		return 0;
161*4882a593Smuzhiyun 	default:
162*4882a593Smuzhiyun 		return 1;
163*4882a593Smuzhiyun 	}
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	if (!pskb_may_pull(skb, hlen))
166*4882a593Smuzhiyun 		return -EINVAL;
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	*spi = *(__be32 *)(skb_transport_header(skb) + offset);
169*4882a593Smuzhiyun 	*seq = *(__be32 *)(skb_transport_header(skb) + offset_seq);
170*4882a593Smuzhiyun 	return 0;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun EXPORT_SYMBOL(xfrm_parse_spi);
173*4882a593Smuzhiyun 
xfrm4_remove_beet_encap(struct xfrm_state * x,struct sk_buff * skb)174*4882a593Smuzhiyun static int xfrm4_remove_beet_encap(struct xfrm_state *x, struct sk_buff *skb)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun 	struct iphdr *iph;
177*4882a593Smuzhiyun 	int optlen = 0;
178*4882a593Smuzhiyun 	int err = -EINVAL;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) {
181*4882a593Smuzhiyun 		struct ip_beet_phdr *ph;
182*4882a593Smuzhiyun 		int phlen;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 		if (!pskb_may_pull(skb, sizeof(*ph)))
185*4882a593Smuzhiyun 			goto out;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 		ph = (struct ip_beet_phdr *)skb->data;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 		phlen = sizeof(*ph) + ph->padlen;
190*4882a593Smuzhiyun 		optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen);
191*4882a593Smuzhiyun 		if (optlen < 0 || optlen & 3 || optlen > 250)
192*4882a593Smuzhiyun 			goto out;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 		XFRM_MODE_SKB_CB(skb)->protocol = ph->nexthdr;
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 		if (!pskb_may_pull(skb, phlen))
197*4882a593Smuzhiyun 			goto out;
198*4882a593Smuzhiyun 		__skb_pull(skb, phlen);
199*4882a593Smuzhiyun 	}
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	skb_push(skb, sizeof(*iph));
202*4882a593Smuzhiyun 	skb_reset_network_header(skb);
203*4882a593Smuzhiyun 	skb_mac_header_rebuild(skb);
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	xfrm4_beet_make_header(skb);
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	iph = ip_hdr(skb);
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	iph->ihl += optlen / 4;
210*4882a593Smuzhiyun 	iph->tot_len = htons(skb->len);
211*4882a593Smuzhiyun 	iph->daddr = x->sel.daddr.a4;
212*4882a593Smuzhiyun 	iph->saddr = x->sel.saddr.a4;
213*4882a593Smuzhiyun 	iph->check = 0;
214*4882a593Smuzhiyun 	iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
215*4882a593Smuzhiyun 	err = 0;
216*4882a593Smuzhiyun out:
217*4882a593Smuzhiyun 	return err;
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun 
ipip_ecn_decapsulate(struct sk_buff * skb)220*4882a593Smuzhiyun static void ipip_ecn_decapsulate(struct sk_buff *skb)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	struct iphdr *inner_iph = ipip_hdr(skb);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos))
225*4882a593Smuzhiyun 		IP_ECN_set_ce(inner_iph);
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun 
xfrm4_remove_tunnel_encap(struct xfrm_state * x,struct sk_buff * skb)228*4882a593Smuzhiyun static int xfrm4_remove_tunnel_encap(struct xfrm_state *x, struct sk_buff *skb)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	int err = -EINVAL;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP)
233*4882a593Smuzhiyun 		goto out;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
236*4882a593Smuzhiyun 		goto out;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	err = skb_unclone(skb, GFP_ATOMIC);
239*4882a593Smuzhiyun 	if (err)
240*4882a593Smuzhiyun 		goto out;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	if (x->props.flags & XFRM_STATE_DECAP_DSCP)
243*4882a593Smuzhiyun 		ipv4_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipip_hdr(skb));
244*4882a593Smuzhiyun 	if (!(x->props.flags & XFRM_STATE_NOECN))
245*4882a593Smuzhiyun 		ipip_ecn_decapsulate(skb);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	skb_reset_network_header(skb);
248*4882a593Smuzhiyun 	skb_mac_header_rebuild(skb);
249*4882a593Smuzhiyun 	if (skb->mac_len)
250*4882a593Smuzhiyun 		eth_hdr(skb)->h_proto = skb->protocol;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	err = 0;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun out:
255*4882a593Smuzhiyun 	return err;
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun 
ipip6_ecn_decapsulate(struct sk_buff * skb)258*4882a593Smuzhiyun static void ipip6_ecn_decapsulate(struct sk_buff *skb)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun 	struct ipv6hdr *inner_iph = ipipv6_hdr(skb);
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos))
263*4882a593Smuzhiyun 		IP6_ECN_set_ce(skb, inner_iph);
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun 
xfrm6_remove_tunnel_encap(struct xfrm_state * x,struct sk_buff * skb)266*4882a593Smuzhiyun static int xfrm6_remove_tunnel_encap(struct xfrm_state *x, struct sk_buff *skb)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun 	int err = -EINVAL;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
271*4882a593Smuzhiyun 		goto out;
272*4882a593Smuzhiyun 	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
273*4882a593Smuzhiyun 		goto out;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	err = skb_unclone(skb, GFP_ATOMIC);
276*4882a593Smuzhiyun 	if (err)
277*4882a593Smuzhiyun 		goto out;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	if (x->props.flags & XFRM_STATE_DECAP_DSCP)
280*4882a593Smuzhiyun 		ipv6_copy_dscp(ipv6_get_dsfield(ipv6_hdr(skb)),
281*4882a593Smuzhiyun 			       ipipv6_hdr(skb));
282*4882a593Smuzhiyun 	if (!(x->props.flags & XFRM_STATE_NOECN))
283*4882a593Smuzhiyun 		ipip6_ecn_decapsulate(skb);
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	skb_reset_network_header(skb);
286*4882a593Smuzhiyun 	skb_mac_header_rebuild(skb);
287*4882a593Smuzhiyun 	if (skb->mac_len)
288*4882a593Smuzhiyun 		eth_hdr(skb)->h_proto = skb->protocol;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	err = 0;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun out:
293*4882a593Smuzhiyun 	return err;
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun 
xfrm6_remove_beet_encap(struct xfrm_state * x,struct sk_buff * skb)296*4882a593Smuzhiyun static int xfrm6_remove_beet_encap(struct xfrm_state *x, struct sk_buff *skb)
297*4882a593Smuzhiyun {
298*4882a593Smuzhiyun 	struct ipv6hdr *ip6h;
299*4882a593Smuzhiyun 	int size = sizeof(struct ipv6hdr);
300*4882a593Smuzhiyun 	int err;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	err = skb_cow_head(skb, size + skb->mac_len);
303*4882a593Smuzhiyun 	if (err)
304*4882a593Smuzhiyun 		goto out;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	__skb_push(skb, size);
307*4882a593Smuzhiyun 	skb_reset_network_header(skb);
308*4882a593Smuzhiyun 	skb_mac_header_rebuild(skb);
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	xfrm6_beet_make_header(skb);
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	ip6h = ipv6_hdr(skb);
313*4882a593Smuzhiyun 	ip6h->payload_len = htons(skb->len - size);
314*4882a593Smuzhiyun 	ip6h->daddr = x->sel.daddr.in6;
315*4882a593Smuzhiyun 	ip6h->saddr = x->sel.saddr.in6;
316*4882a593Smuzhiyun 	err = 0;
317*4882a593Smuzhiyun out:
318*4882a593Smuzhiyun 	return err;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun /* Remove encapsulation header.
322*4882a593Smuzhiyun  *
323*4882a593Smuzhiyun  * The IP header will be moved over the top of the encapsulation
324*4882a593Smuzhiyun  * header.
325*4882a593Smuzhiyun  *
326*4882a593Smuzhiyun  * On entry, the transport header shall point to where the IP header
327*4882a593Smuzhiyun  * should be and the network header shall be set to where the IP
328*4882a593Smuzhiyun  * header currently is.  skb->data shall point to the start of the
329*4882a593Smuzhiyun  * payload.
330*4882a593Smuzhiyun  */
331*4882a593Smuzhiyun static int
xfrm_inner_mode_encap_remove(struct xfrm_state * x,const struct xfrm_mode * inner_mode,struct sk_buff * skb)332*4882a593Smuzhiyun xfrm_inner_mode_encap_remove(struct xfrm_state *x,
333*4882a593Smuzhiyun 			     const struct xfrm_mode *inner_mode,
334*4882a593Smuzhiyun 			     struct sk_buff *skb)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun 	switch (inner_mode->encap) {
337*4882a593Smuzhiyun 	case XFRM_MODE_BEET:
338*4882a593Smuzhiyun 		if (inner_mode->family == AF_INET)
339*4882a593Smuzhiyun 			return xfrm4_remove_beet_encap(x, skb);
340*4882a593Smuzhiyun 		if (inner_mode->family == AF_INET6)
341*4882a593Smuzhiyun 			return xfrm6_remove_beet_encap(x, skb);
342*4882a593Smuzhiyun 		break;
343*4882a593Smuzhiyun 	case XFRM_MODE_TUNNEL:
344*4882a593Smuzhiyun 		if (inner_mode->family == AF_INET)
345*4882a593Smuzhiyun 			return xfrm4_remove_tunnel_encap(x, skb);
346*4882a593Smuzhiyun 		if (inner_mode->family == AF_INET6)
347*4882a593Smuzhiyun 			return xfrm6_remove_tunnel_encap(x, skb);
348*4882a593Smuzhiyun 		break;
349*4882a593Smuzhiyun 	}
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	WARN_ON_ONCE(1);
352*4882a593Smuzhiyun 	return -EOPNOTSUPP;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun 
xfrm_prepare_input(struct xfrm_state * x,struct sk_buff * skb)355*4882a593Smuzhiyun static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
356*4882a593Smuzhiyun {
357*4882a593Smuzhiyun 	const struct xfrm_mode *inner_mode = &x->inner_mode;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	switch (x->outer_mode.family) {
360*4882a593Smuzhiyun 	case AF_INET:
361*4882a593Smuzhiyun 		xfrm4_extract_header(skb);
362*4882a593Smuzhiyun 		break;
363*4882a593Smuzhiyun 	case AF_INET6:
364*4882a593Smuzhiyun 		xfrm6_extract_header(skb);
365*4882a593Smuzhiyun 		break;
366*4882a593Smuzhiyun 	default:
367*4882a593Smuzhiyun 		WARN_ON_ONCE(1);
368*4882a593Smuzhiyun 		return -EAFNOSUPPORT;
369*4882a593Smuzhiyun 	}
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	if (x->sel.family == AF_UNSPEC) {
372*4882a593Smuzhiyun 		inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
373*4882a593Smuzhiyun 		if (!inner_mode)
374*4882a593Smuzhiyun 			return -EAFNOSUPPORT;
375*4882a593Smuzhiyun 	}
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	switch (inner_mode->family) {
378*4882a593Smuzhiyun 	case AF_INET:
379*4882a593Smuzhiyun 		skb->protocol = htons(ETH_P_IP);
380*4882a593Smuzhiyun 		break;
381*4882a593Smuzhiyun 	case AF_INET6:
382*4882a593Smuzhiyun 		skb->protocol = htons(ETH_P_IPV6);
383*4882a593Smuzhiyun 		break;
384*4882a593Smuzhiyun 	default:
385*4882a593Smuzhiyun 		WARN_ON_ONCE(1);
386*4882a593Smuzhiyun 		break;
387*4882a593Smuzhiyun 	}
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	return xfrm_inner_mode_encap_remove(x, inner_mode, skb);
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun /* Remove encapsulation header.
393*4882a593Smuzhiyun  *
394*4882a593Smuzhiyun  * The IP header will be moved over the top of the encapsulation header.
395*4882a593Smuzhiyun  *
396*4882a593Smuzhiyun  * On entry, skb_transport_header() shall point to where the IP header
397*4882a593Smuzhiyun  * should be and skb_network_header() shall be set to where the IP header
398*4882a593Smuzhiyun  * currently is.  skb->data shall point to the start of the payload.
399*4882a593Smuzhiyun  */
xfrm4_transport_input(struct xfrm_state * x,struct sk_buff * skb)400*4882a593Smuzhiyun static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun 	int ihl = skb->data - skb_transport_header(skb);
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	if (skb->transport_header != skb->network_header) {
405*4882a593Smuzhiyun 		memmove(skb_transport_header(skb),
406*4882a593Smuzhiyun 			skb_network_header(skb), ihl);
407*4882a593Smuzhiyun 		skb->network_header = skb->transport_header;
408*4882a593Smuzhiyun 	}
409*4882a593Smuzhiyun 	ip_hdr(skb)->tot_len = htons(skb->len + ihl);
410*4882a593Smuzhiyun 	skb_reset_transport_header(skb);
411*4882a593Smuzhiyun 	return 0;
412*4882a593Smuzhiyun }
413*4882a593Smuzhiyun 
xfrm6_transport_input(struct xfrm_state * x,struct sk_buff * skb)414*4882a593Smuzhiyun static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
415*4882a593Smuzhiyun {
416*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_IPV6)
417*4882a593Smuzhiyun 	int ihl = skb->data - skb_transport_header(skb);
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	if (skb->transport_header != skb->network_header) {
420*4882a593Smuzhiyun 		memmove(skb_transport_header(skb),
421*4882a593Smuzhiyun 			skb_network_header(skb), ihl);
422*4882a593Smuzhiyun 		skb->network_header = skb->transport_header;
423*4882a593Smuzhiyun 	}
424*4882a593Smuzhiyun 	ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -
425*4882a593Smuzhiyun 					   sizeof(struct ipv6hdr));
426*4882a593Smuzhiyun 	skb_reset_transport_header(skb);
427*4882a593Smuzhiyun 	return 0;
428*4882a593Smuzhiyun #else
429*4882a593Smuzhiyun 	WARN_ON_ONCE(1);
430*4882a593Smuzhiyun 	return -EAFNOSUPPORT;
431*4882a593Smuzhiyun #endif
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun 
xfrm_inner_mode_input(struct xfrm_state * x,const struct xfrm_mode * inner_mode,struct sk_buff * skb)434*4882a593Smuzhiyun static int xfrm_inner_mode_input(struct xfrm_state *x,
435*4882a593Smuzhiyun 				 const struct xfrm_mode *inner_mode,
436*4882a593Smuzhiyun 				 struct sk_buff *skb)
437*4882a593Smuzhiyun {
438*4882a593Smuzhiyun 	switch (inner_mode->encap) {
439*4882a593Smuzhiyun 	case XFRM_MODE_BEET:
440*4882a593Smuzhiyun 	case XFRM_MODE_TUNNEL:
441*4882a593Smuzhiyun 		return xfrm_prepare_input(x, skb);
442*4882a593Smuzhiyun 	case XFRM_MODE_TRANSPORT:
443*4882a593Smuzhiyun 		if (inner_mode->family == AF_INET)
444*4882a593Smuzhiyun 			return xfrm4_transport_input(x, skb);
445*4882a593Smuzhiyun 		if (inner_mode->family == AF_INET6)
446*4882a593Smuzhiyun 			return xfrm6_transport_input(x, skb);
447*4882a593Smuzhiyun 		break;
448*4882a593Smuzhiyun 	case XFRM_MODE_ROUTEOPTIMIZATION:
449*4882a593Smuzhiyun 		WARN_ON_ONCE(1);
450*4882a593Smuzhiyun 		break;
451*4882a593Smuzhiyun 	default:
452*4882a593Smuzhiyun 		WARN_ON_ONCE(1);
453*4882a593Smuzhiyun 		break;
454*4882a593Smuzhiyun 	}
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	return -EOPNOTSUPP;
457*4882a593Smuzhiyun }
458*4882a593Smuzhiyun 
xfrm_input(struct sk_buff * skb,int nexthdr,__be32 spi,int encap_type)459*4882a593Smuzhiyun int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun 	const struct xfrm_state_afinfo *afinfo;
462*4882a593Smuzhiyun 	struct net *net = dev_net(skb->dev);
463*4882a593Smuzhiyun 	const struct xfrm_mode *inner_mode;
464*4882a593Smuzhiyun 	int err;
465*4882a593Smuzhiyun 	__be32 seq;
466*4882a593Smuzhiyun 	__be32 seq_hi;
467*4882a593Smuzhiyun 	struct xfrm_state *x = NULL;
468*4882a593Smuzhiyun 	xfrm_address_t *daddr;
469*4882a593Smuzhiyun 	u32 mark = skb->mark;
470*4882a593Smuzhiyun 	unsigned int family = AF_UNSPEC;
471*4882a593Smuzhiyun 	int decaps = 0;
472*4882a593Smuzhiyun 	int async = 0;
473*4882a593Smuzhiyun 	bool xfrm_gro = false;
474*4882a593Smuzhiyun 	bool crypto_done = false;
475*4882a593Smuzhiyun 	struct xfrm_offload *xo = xfrm_offload(skb);
476*4882a593Smuzhiyun 	struct sec_path *sp;
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 	if (encap_type < 0) {
479*4882a593Smuzhiyun 		x = xfrm_input_state(skb);
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 		if (unlikely(x->km.state != XFRM_STATE_VALID)) {
482*4882a593Smuzhiyun 			if (x->km.state == XFRM_STATE_ACQ)
483*4882a593Smuzhiyun 				XFRM_INC_STATS(net, LINUX_MIB_XFRMACQUIREERROR);
484*4882a593Smuzhiyun 			else
485*4882a593Smuzhiyun 				XFRM_INC_STATS(net,
486*4882a593Smuzhiyun 					       LINUX_MIB_XFRMINSTATEINVALID);
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 			if (encap_type == -1)
489*4882a593Smuzhiyun 				dev_put(skb->dev);
490*4882a593Smuzhiyun 			goto drop;
491*4882a593Smuzhiyun 		}
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 		family = x->outer_mode.family;
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 		/* An encap_type of -1 indicates async resumption. */
496*4882a593Smuzhiyun 		if (encap_type == -1) {
497*4882a593Smuzhiyun 			async = 1;
498*4882a593Smuzhiyun 			seq = XFRM_SKB_CB(skb)->seq.input.low;
499*4882a593Smuzhiyun 			goto resume;
500*4882a593Smuzhiyun 		}
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 		/* encap_type < -1 indicates a GRO call. */
503*4882a593Smuzhiyun 		encap_type = 0;
504*4882a593Smuzhiyun 		seq = XFRM_SPI_SKB_CB(skb)->seq;
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun 		if (xo && (xo->flags & CRYPTO_DONE)) {
507*4882a593Smuzhiyun 			crypto_done = true;
508*4882a593Smuzhiyun 			family = XFRM_SPI_SKB_CB(skb)->family;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 			if (!(xo->status & CRYPTO_SUCCESS)) {
511*4882a593Smuzhiyun 				if (xo->status &
512*4882a593Smuzhiyun 				    (CRYPTO_TRANSPORT_AH_AUTH_FAILED |
513*4882a593Smuzhiyun 				     CRYPTO_TRANSPORT_ESP_AUTH_FAILED |
514*4882a593Smuzhiyun 				     CRYPTO_TUNNEL_AH_AUTH_FAILED |
515*4882a593Smuzhiyun 				     CRYPTO_TUNNEL_ESP_AUTH_FAILED)) {
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 					xfrm_audit_state_icvfail(x, skb,
518*4882a593Smuzhiyun 								 x->type->proto);
519*4882a593Smuzhiyun 					x->stats.integrity_failed++;
520*4882a593Smuzhiyun 					XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR);
521*4882a593Smuzhiyun 					goto drop;
522*4882a593Smuzhiyun 				}
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 				if (xo->status & CRYPTO_INVALID_PROTOCOL) {
525*4882a593Smuzhiyun 					XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR);
526*4882a593Smuzhiyun 					goto drop;
527*4882a593Smuzhiyun 				}
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 				XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
530*4882a593Smuzhiyun 				goto drop;
531*4882a593Smuzhiyun 			}
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun 			if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
534*4882a593Smuzhiyun 				XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
535*4882a593Smuzhiyun 				goto drop;
536*4882a593Smuzhiyun 			}
537*4882a593Smuzhiyun 		}
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 		goto lock;
540*4882a593Smuzhiyun 	}
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	family = XFRM_SPI_SKB_CB(skb)->family;
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	/* if tunnel is present override skb->mark value with tunnel i_key */
545*4882a593Smuzhiyun 	switch (family) {
546*4882a593Smuzhiyun 	case AF_INET:
547*4882a593Smuzhiyun 		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
548*4882a593Smuzhiyun 			mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key);
549*4882a593Smuzhiyun 		break;
550*4882a593Smuzhiyun 	case AF_INET6:
551*4882a593Smuzhiyun 		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
552*4882a593Smuzhiyun 			mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key);
553*4882a593Smuzhiyun 		break;
554*4882a593Smuzhiyun 	}
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	sp = secpath_set(skb);
557*4882a593Smuzhiyun 	if (!sp) {
558*4882a593Smuzhiyun 		XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
559*4882a593Smuzhiyun 		goto drop;
560*4882a593Smuzhiyun 	}
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 	seq = 0;
563*4882a593Smuzhiyun 	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
564*4882a593Smuzhiyun 		secpath_reset(skb);
565*4882a593Smuzhiyun 		XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
566*4882a593Smuzhiyun 		goto drop;
567*4882a593Smuzhiyun 	}
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	daddr = (xfrm_address_t *)(skb_network_header(skb) +
570*4882a593Smuzhiyun 				   XFRM_SPI_SKB_CB(skb)->daddroff);
571*4882a593Smuzhiyun 	do {
572*4882a593Smuzhiyun 		sp = skb_sec_path(skb);
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 		if (sp->len == XFRM_MAX_DEPTH) {
575*4882a593Smuzhiyun 			secpath_reset(skb);
576*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
577*4882a593Smuzhiyun 			goto drop;
578*4882a593Smuzhiyun 		}
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 		x = xfrm_state_lookup(net, mark, daddr, spi, nexthdr, family);
581*4882a593Smuzhiyun 		if (x == NULL) {
582*4882a593Smuzhiyun 			secpath_reset(skb);
583*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
584*4882a593Smuzhiyun 			xfrm_audit_state_notfound(skb, family, spi, seq);
585*4882a593Smuzhiyun 			goto drop;
586*4882a593Smuzhiyun 		}
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 		skb->mark = xfrm_smark_get(skb->mark, x);
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 		sp->xvec[sp->len++] = x;
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun 		skb_dst_force(skb);
593*4882a593Smuzhiyun 		if (!skb_dst(skb)) {
594*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
595*4882a593Smuzhiyun 			goto drop;
596*4882a593Smuzhiyun 		}
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun lock:
599*4882a593Smuzhiyun 		spin_lock(&x->lock);
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 		if (unlikely(x->km.state != XFRM_STATE_VALID)) {
602*4882a593Smuzhiyun 			if (x->km.state == XFRM_STATE_ACQ)
603*4882a593Smuzhiyun 				XFRM_INC_STATS(net, LINUX_MIB_XFRMACQUIREERROR);
604*4882a593Smuzhiyun 			else
605*4882a593Smuzhiyun 				XFRM_INC_STATS(net,
606*4882a593Smuzhiyun 					       LINUX_MIB_XFRMINSTATEINVALID);
607*4882a593Smuzhiyun 			goto drop_unlock;
608*4882a593Smuzhiyun 		}
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 		if ((x->encap ? x->encap->encap_type : 0) != encap_type) {
611*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH);
612*4882a593Smuzhiyun 			goto drop_unlock;
613*4882a593Smuzhiyun 		}
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun 		if (x->repl->check(x, skb, seq)) {
616*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
617*4882a593Smuzhiyun 			goto drop_unlock;
618*4882a593Smuzhiyun 		}
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun 		if (xfrm_state_check_expire(x)) {
621*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEEXPIRED);
622*4882a593Smuzhiyun 			goto drop_unlock;
623*4882a593Smuzhiyun 		}
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 		spin_unlock(&x->lock);
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 		if (xfrm_tunnel_check(skb, x, family)) {
628*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
629*4882a593Smuzhiyun 			goto drop;
630*4882a593Smuzhiyun 		}
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 		seq_hi = htonl(xfrm_replay_seqhi(x, seq));
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 		XFRM_SKB_CB(skb)->seq.input.low = seq;
635*4882a593Smuzhiyun 		XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 		dev_hold(skb->dev);
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun 		if (crypto_done)
640*4882a593Smuzhiyun 			nexthdr = x->type_offload->input_tail(x, skb);
641*4882a593Smuzhiyun 		else
642*4882a593Smuzhiyun 			nexthdr = x->type->input(x, skb);
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 		if (nexthdr == -EINPROGRESS)
645*4882a593Smuzhiyun 			return 0;
646*4882a593Smuzhiyun resume:
647*4882a593Smuzhiyun 		dev_put(skb->dev);
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 		spin_lock(&x->lock);
650*4882a593Smuzhiyun 		if (nexthdr < 0) {
651*4882a593Smuzhiyun 			if (nexthdr == -EBADMSG) {
652*4882a593Smuzhiyun 				xfrm_audit_state_icvfail(x, skb,
653*4882a593Smuzhiyun 							 x->type->proto);
654*4882a593Smuzhiyun 				x->stats.integrity_failed++;
655*4882a593Smuzhiyun 			}
656*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR);
657*4882a593Smuzhiyun 			goto drop_unlock;
658*4882a593Smuzhiyun 		}
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun 		/* only the first xfrm gets the encap type */
661*4882a593Smuzhiyun 		encap_type = 0;
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 		if (x->repl->recheck(x, skb, seq)) {
664*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
665*4882a593Smuzhiyun 			goto drop_unlock;
666*4882a593Smuzhiyun 		}
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun 		x->repl->advance(x, seq);
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 		x->curlft.bytes += skb->len;
671*4882a593Smuzhiyun 		x->curlft.packets++;
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun 		spin_unlock(&x->lock);
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 		XFRM_MODE_SKB_CB(skb)->protocol = nexthdr;
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 		inner_mode = &x->inner_mode;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 		if (x->sel.family == AF_UNSPEC) {
680*4882a593Smuzhiyun 			inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
681*4882a593Smuzhiyun 			if (inner_mode == NULL) {
682*4882a593Smuzhiyun 				XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
683*4882a593Smuzhiyun 				goto drop;
684*4882a593Smuzhiyun 			}
685*4882a593Smuzhiyun 		}
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun 		if (xfrm_inner_mode_input(x, inner_mode, skb)) {
688*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
689*4882a593Smuzhiyun 			goto drop;
690*4882a593Smuzhiyun 		}
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun 		if (x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL) {
693*4882a593Smuzhiyun 			decaps = 1;
694*4882a593Smuzhiyun 			break;
695*4882a593Smuzhiyun 		}
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 		/*
698*4882a593Smuzhiyun 		 * We need the inner address.  However, we only get here for
699*4882a593Smuzhiyun 		 * transport mode so the outer address is identical.
700*4882a593Smuzhiyun 		 */
701*4882a593Smuzhiyun 		daddr = &x->id.daddr;
702*4882a593Smuzhiyun 		family = x->outer_mode.family;
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 		err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
705*4882a593Smuzhiyun 		if (err < 0) {
706*4882a593Smuzhiyun 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
707*4882a593Smuzhiyun 			goto drop;
708*4882a593Smuzhiyun 		}
709*4882a593Smuzhiyun 		crypto_done = false;
710*4882a593Smuzhiyun 	} while (!err);
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun 	err = xfrm_rcv_cb(skb, family, x->type->proto, 0);
713*4882a593Smuzhiyun 	if (err)
714*4882a593Smuzhiyun 		goto drop;
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun 	nf_reset_ct(skb);
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	if (decaps) {
719*4882a593Smuzhiyun 		sp = skb_sec_path(skb);
720*4882a593Smuzhiyun 		if (sp)
721*4882a593Smuzhiyun 			sp->olen = 0;
722*4882a593Smuzhiyun 		skb_dst_drop(skb);
723*4882a593Smuzhiyun 		gro_cells_receive(&gro_cells, skb);
724*4882a593Smuzhiyun 		return 0;
725*4882a593Smuzhiyun 	} else {
726*4882a593Smuzhiyun 		xo = xfrm_offload(skb);
727*4882a593Smuzhiyun 		if (xo)
728*4882a593Smuzhiyun 			xfrm_gro = xo->flags & XFRM_GRO;
729*4882a593Smuzhiyun 
730*4882a593Smuzhiyun 		err = -EAFNOSUPPORT;
731*4882a593Smuzhiyun 		rcu_read_lock();
732*4882a593Smuzhiyun 		afinfo = xfrm_state_afinfo_get_rcu(x->inner_mode.family);
733*4882a593Smuzhiyun 		if (likely(afinfo))
734*4882a593Smuzhiyun 			err = afinfo->transport_finish(skb, xfrm_gro || async);
735*4882a593Smuzhiyun 		rcu_read_unlock();
736*4882a593Smuzhiyun 		if (xfrm_gro) {
737*4882a593Smuzhiyun 			sp = skb_sec_path(skb);
738*4882a593Smuzhiyun 			if (sp)
739*4882a593Smuzhiyun 				sp->olen = 0;
740*4882a593Smuzhiyun 			skb_dst_drop(skb);
741*4882a593Smuzhiyun 			gro_cells_receive(&gro_cells, skb);
742*4882a593Smuzhiyun 			return err;
743*4882a593Smuzhiyun 		}
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 		return err;
746*4882a593Smuzhiyun 	}
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun drop_unlock:
749*4882a593Smuzhiyun 	spin_unlock(&x->lock);
750*4882a593Smuzhiyun drop:
751*4882a593Smuzhiyun 	xfrm_rcv_cb(skb, family, x && x->type ? x->type->proto : nexthdr, -1);
752*4882a593Smuzhiyun 	kfree_skb(skb);
753*4882a593Smuzhiyun 	return 0;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun EXPORT_SYMBOL(xfrm_input);
756*4882a593Smuzhiyun 
xfrm_input_resume(struct sk_buff * skb,int nexthdr)757*4882a593Smuzhiyun int xfrm_input_resume(struct sk_buff *skb, int nexthdr)
758*4882a593Smuzhiyun {
759*4882a593Smuzhiyun 	return xfrm_input(skb, nexthdr, 0, -1);
760*4882a593Smuzhiyun }
761*4882a593Smuzhiyun EXPORT_SYMBOL(xfrm_input_resume);
762*4882a593Smuzhiyun 
xfrm_trans_reinject(unsigned long data)763*4882a593Smuzhiyun static void xfrm_trans_reinject(unsigned long data)
764*4882a593Smuzhiyun {
765*4882a593Smuzhiyun 	struct xfrm_trans_tasklet *trans = (void *)data;
766*4882a593Smuzhiyun 	struct sk_buff_head queue;
767*4882a593Smuzhiyun 	struct sk_buff *skb;
768*4882a593Smuzhiyun 
769*4882a593Smuzhiyun 	__skb_queue_head_init(&queue);
770*4882a593Smuzhiyun 	skb_queue_splice_init(&trans->queue, &queue);
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun 	while ((skb = __skb_dequeue(&queue)))
773*4882a593Smuzhiyun 		XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net,
774*4882a593Smuzhiyun 					       NULL, skb);
775*4882a593Smuzhiyun }
776*4882a593Smuzhiyun 
xfrm_trans_queue_net(struct net * net,struct sk_buff * skb,int (* finish)(struct net *,struct sock *,struct sk_buff *))777*4882a593Smuzhiyun int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
778*4882a593Smuzhiyun 			 int (*finish)(struct net *, struct sock *,
779*4882a593Smuzhiyun 				       struct sk_buff *))
780*4882a593Smuzhiyun {
781*4882a593Smuzhiyun 	struct xfrm_trans_tasklet *trans;
782*4882a593Smuzhiyun 
783*4882a593Smuzhiyun 	trans = this_cpu_ptr(&xfrm_trans_tasklet);
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	if (skb_queue_len(&trans->queue) >= READ_ONCE(netdev_max_backlog))
786*4882a593Smuzhiyun 		return -ENOBUFS;
787*4882a593Smuzhiyun 
788*4882a593Smuzhiyun 	BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb));
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun 	XFRM_TRANS_SKB_CB(skb)->finish = finish;
791*4882a593Smuzhiyun 	XFRM_TRANS_SKB_CB(skb)->net = net;
792*4882a593Smuzhiyun 	__skb_queue_tail(&trans->queue, skb);
793*4882a593Smuzhiyun 	tasklet_schedule(&trans->tasklet);
794*4882a593Smuzhiyun 	return 0;
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun EXPORT_SYMBOL(xfrm_trans_queue_net);
797*4882a593Smuzhiyun 
xfrm_trans_queue(struct sk_buff * skb,int (* finish)(struct net *,struct sock *,struct sk_buff *))798*4882a593Smuzhiyun int xfrm_trans_queue(struct sk_buff *skb,
799*4882a593Smuzhiyun 		     int (*finish)(struct net *, struct sock *,
800*4882a593Smuzhiyun 				   struct sk_buff *))
801*4882a593Smuzhiyun {
802*4882a593Smuzhiyun 	return xfrm_trans_queue_net(dev_net(skb->dev), skb, finish);
803*4882a593Smuzhiyun }
804*4882a593Smuzhiyun EXPORT_SYMBOL(xfrm_trans_queue);
805*4882a593Smuzhiyun 
xfrm_input_init(void)806*4882a593Smuzhiyun void __init xfrm_input_init(void)
807*4882a593Smuzhiyun {
808*4882a593Smuzhiyun 	int err;
809*4882a593Smuzhiyun 	int i;
810*4882a593Smuzhiyun 
811*4882a593Smuzhiyun 	init_dummy_netdev(&xfrm_napi_dev);
812*4882a593Smuzhiyun 	err = gro_cells_init(&gro_cells, &xfrm_napi_dev);
813*4882a593Smuzhiyun 	if (err)
814*4882a593Smuzhiyun 		gro_cells.cells = NULL;
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun 	for_each_possible_cpu(i) {
817*4882a593Smuzhiyun 		struct xfrm_trans_tasklet *trans;
818*4882a593Smuzhiyun 
819*4882a593Smuzhiyun 		trans = &per_cpu(xfrm_trans_tasklet, i);
820*4882a593Smuzhiyun 		__skb_queue_head_init(&trans->queue);
821*4882a593Smuzhiyun 		tasklet_init(&trans->tasklet, xfrm_trans_reinject,
822*4882a593Smuzhiyun 			     (unsigned long)trans);
823*4882a593Smuzhiyun 	}
824*4882a593Smuzhiyun }
825