1a9643ea8Slogwang /* $OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $ */
2a9643ea8Slogwang /*-
3a9643ea8Slogwang * The authors of this code are John Ioannidis ([email protected]),
4a9643ea8Slogwang * Angelos D. Keromytis ([email protected]) and
5a9643ea8Slogwang * Niels Provos ([email protected]).
6a9643ea8Slogwang *
7a9643ea8Slogwang * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
8a9643ea8Slogwang * in November 1995.
9a9643ea8Slogwang *
10a9643ea8Slogwang * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
11a9643ea8Slogwang * by Angelos D. Keromytis.
12a9643ea8Slogwang *
13a9643ea8Slogwang * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
14a9643ea8Slogwang * and Niels Provos.
15a9643ea8Slogwang *
16a9643ea8Slogwang * Additional features in 1999 by Angelos D. Keromytis.
17a9643ea8Slogwang *
18a9643ea8Slogwang * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
19a9643ea8Slogwang * Angelos D. Keromytis and Niels Provos.
20a9643ea8Slogwang * Copyright (c) 2001, Angelos D. Keromytis.
21*22ce4affSfengbojiang * Copyright (c) 2016 Andrey V. Elsukov <[email protected]>
22a9643ea8Slogwang *
23a9643ea8Slogwang * Permission to use, copy, and modify this software with or without fee
24a9643ea8Slogwang * is hereby granted, provided that this entire notice is included in
25a9643ea8Slogwang * all copies of any software which is or includes a copy or
26a9643ea8Slogwang * modification of this software.
27a9643ea8Slogwang * You may use this code under the GNU public license if you so wish. Please
28a9643ea8Slogwang * contribute changes back to the authors under this freer than GPL license
29a9643ea8Slogwang * so that we may further the use of strong encryption without limitations to
30a9643ea8Slogwang * all.
31a9643ea8Slogwang *
32a9643ea8Slogwang * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
33a9643ea8Slogwang * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
34a9643ea8Slogwang * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
35a9643ea8Slogwang * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
36a9643ea8Slogwang * PURPOSE.
37a9643ea8Slogwang */
38a9643ea8Slogwang
39a9643ea8Slogwang /*
40a9643ea8Slogwang * IPsec input processing.
41a9643ea8Slogwang */
42a9643ea8Slogwang
43*22ce4affSfengbojiang #include <sys/cdefs.h>
44*22ce4affSfengbojiang __FBSDID("$FreeBSD$");
45*22ce4affSfengbojiang
46a9643ea8Slogwang #include "opt_inet.h"
47a9643ea8Slogwang #include "opt_inet6.h"
48a9643ea8Slogwang #include "opt_ipsec.h"
49a9643ea8Slogwang
50a9643ea8Slogwang #include <sys/param.h>
51a9643ea8Slogwang #include <sys/systm.h>
52a9643ea8Slogwang #include <sys/malloc.h>
53a9643ea8Slogwang #include <sys/mbuf.h>
54a9643ea8Slogwang #include <sys/domain.h>
55a9643ea8Slogwang #include <sys/protosw.h>
56a9643ea8Slogwang #include <sys/socket.h>
57a9643ea8Slogwang #include <sys/errno.h>
58a9643ea8Slogwang #include <sys/hhook.h>
59a9643ea8Slogwang #include <sys/syslog.h>
60a9643ea8Slogwang
61a9643ea8Slogwang #include <net/if.h>
62a9643ea8Slogwang #include <net/if_var.h>
63a9643ea8Slogwang #include <net/if_enc.h>
64a9643ea8Slogwang #include <net/netisr.h>
65a9643ea8Slogwang #include <net/vnet.h>
66a9643ea8Slogwang
67a9643ea8Slogwang #include <netinet/in.h>
68a9643ea8Slogwang #include <netinet/in_systm.h>
69a9643ea8Slogwang #include <netinet/ip.h>
70a9643ea8Slogwang #include <netinet/ip_var.h>
71a9643ea8Slogwang #include <netinet/in_var.h>
72a9643ea8Slogwang
73a9643ea8Slogwang #include <netinet/ip6.h>
74a9643ea8Slogwang #ifdef INET6
75a9643ea8Slogwang #include <netinet6/ip6_var.h>
76a9643ea8Slogwang #endif
77a9643ea8Slogwang #include <netinet/in_pcb.h>
78a9643ea8Slogwang #ifdef INET6
79a9643ea8Slogwang #include <netinet/icmp6.h>
80a9643ea8Slogwang #endif
81a9643ea8Slogwang
82a9643ea8Slogwang #include <netipsec/ipsec.h>
83a9643ea8Slogwang #ifdef INET6
84a9643ea8Slogwang #include <netipsec/ipsec6.h>
85a9643ea8Slogwang #endif
86a9643ea8Slogwang #include <netipsec/ah_var.h>
87a9643ea8Slogwang #include <netipsec/esp.h>
88a9643ea8Slogwang #include <netipsec/esp_var.h>
89a9643ea8Slogwang #include <netipsec/ipcomp_var.h>
90a9643ea8Slogwang
91a9643ea8Slogwang #include <netipsec/key.h>
92a9643ea8Slogwang #include <netipsec/keydb.h>
93*22ce4affSfengbojiang #include <netipsec/key_debug.h>
94a9643ea8Slogwang
95a9643ea8Slogwang #include <netipsec/xform.h>
96a9643ea8Slogwang #include <netinet6/ip6protosw.h>
97a9643ea8Slogwang
98a9643ea8Slogwang #include <machine/in_cksum.h>
99a9643ea8Slogwang #include <machine/stdarg.h>
100a9643ea8Slogwang
101a9643ea8Slogwang #define IPSEC_ISTAT(proto, name) do { \
102a9643ea8Slogwang if ((proto) == IPPROTO_ESP) \
103a9643ea8Slogwang ESPSTAT_INC(esps_##name); \
104a9643ea8Slogwang else if ((proto) == IPPROTO_AH) \
105a9643ea8Slogwang AHSTAT_INC(ahs_##name); \
106a9643ea8Slogwang else \
107a9643ea8Slogwang IPCOMPSTAT_INC(ipcomps_##name); \
108a9643ea8Slogwang } while (0)
109a9643ea8Slogwang
110a9643ea8Slogwang /*
111a9643ea8Slogwang * ipsec_common_input gets called when an IPsec-protected packet
112a9643ea8Slogwang * is received by IPv4 or IPv6. Its job is to find the right SA
113a9643ea8Slogwang * and call the appropriate transform. The transform callback
114a9643ea8Slogwang * takes care of further processing (like ingress filtering).
115a9643ea8Slogwang */
116*22ce4affSfengbojiang static int
ipsec_common_input(struct mbuf * m,int skip,int protoff,int af,int sproto)117a9643ea8Slogwang ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
118a9643ea8Slogwang {
119*22ce4affSfengbojiang IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
120a9643ea8Slogwang union sockaddr_union dst_address;
121a9643ea8Slogwang struct secasvar *sav;
122*22ce4affSfengbojiang uint32_t spi;
123a9643ea8Slogwang int error;
124a9643ea8Slogwang
125a9643ea8Slogwang IPSEC_ISTAT(sproto, input);
126a9643ea8Slogwang
127a9643ea8Slogwang IPSEC_ASSERT(m != NULL, ("null packet"));
128a9643ea8Slogwang
129a9643ea8Slogwang IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
130a9643ea8Slogwang sproto == IPPROTO_IPCOMP,
131a9643ea8Slogwang ("unexpected security protocol %u", sproto));
132a9643ea8Slogwang
133a9643ea8Slogwang if ((sproto == IPPROTO_ESP && !V_esp_enable) ||
134a9643ea8Slogwang (sproto == IPPROTO_AH && !V_ah_enable) ||
135a9643ea8Slogwang (sproto == IPPROTO_IPCOMP && !V_ipcomp_enable)) {
136a9643ea8Slogwang m_freem(m);
137a9643ea8Slogwang IPSEC_ISTAT(sproto, pdrops);
138a9643ea8Slogwang return EOPNOTSUPP;
139a9643ea8Slogwang }
140a9643ea8Slogwang
141a9643ea8Slogwang if (m->m_pkthdr.len - skip < 2 * sizeof (u_int32_t)) {
142a9643ea8Slogwang m_freem(m);
143a9643ea8Slogwang IPSEC_ISTAT(sproto, hdrops);
144a9643ea8Slogwang DPRINTF(("%s: packet too small\n", __func__));
145a9643ea8Slogwang return EINVAL;
146a9643ea8Slogwang }
147a9643ea8Slogwang
148a9643ea8Slogwang /* Retrieve the SPI from the relevant IPsec header */
149a9643ea8Slogwang if (sproto == IPPROTO_ESP)
150a9643ea8Slogwang m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi);
151a9643ea8Slogwang else if (sproto == IPPROTO_AH)
152a9643ea8Slogwang m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
153a9643ea8Slogwang (caddr_t) &spi);
154a9643ea8Slogwang else if (sproto == IPPROTO_IPCOMP) {
155a9643ea8Slogwang u_int16_t cpi;
156a9643ea8Slogwang m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t),
157a9643ea8Slogwang (caddr_t) &cpi);
158a9643ea8Slogwang spi = ntohl(htons(cpi));
159a9643ea8Slogwang }
160a9643ea8Slogwang
161a9643ea8Slogwang /*
162a9643ea8Slogwang * Find the SA and (indirectly) call the appropriate
163a9643ea8Slogwang * kernel crypto routine. The resulting mbuf chain is a valid
164a9643ea8Slogwang * IP packet ready to go through input processing.
165a9643ea8Slogwang */
166a9643ea8Slogwang bzero(&dst_address, sizeof (dst_address));
167a9643ea8Slogwang dst_address.sa.sa_family = af;
168a9643ea8Slogwang switch (af) {
169a9643ea8Slogwang #ifdef INET
170a9643ea8Slogwang case AF_INET:
171a9643ea8Slogwang dst_address.sin.sin_len = sizeof(struct sockaddr_in);
172a9643ea8Slogwang m_copydata(m, offsetof(struct ip, ip_dst),
173a9643ea8Slogwang sizeof(struct in_addr),
174a9643ea8Slogwang (caddr_t) &dst_address.sin.sin_addr);
175a9643ea8Slogwang break;
176a9643ea8Slogwang #endif /* INET */
177a9643ea8Slogwang #ifdef INET6
178a9643ea8Slogwang case AF_INET6:
179a9643ea8Slogwang dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6);
180a9643ea8Slogwang m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
181a9643ea8Slogwang sizeof(struct in6_addr),
182a9643ea8Slogwang (caddr_t) &dst_address.sin6.sin6_addr);
183a9643ea8Slogwang /* We keep addresses in SADB without embedded scope id */
184a9643ea8Slogwang if (IN6_IS_SCOPE_LINKLOCAL(&dst_address.sin6.sin6_addr)) {
185a9643ea8Slogwang /* XXX: sa6_recoverscope() */
186a9643ea8Slogwang dst_address.sin6.sin6_scope_id =
187a9643ea8Slogwang ntohs(dst_address.sin6.sin6_addr.s6_addr16[1]);
188a9643ea8Slogwang dst_address.sin6.sin6_addr.s6_addr16[1] = 0;
189a9643ea8Slogwang }
190a9643ea8Slogwang break;
191a9643ea8Slogwang #endif /* INET6 */
192a9643ea8Slogwang default:
193a9643ea8Slogwang DPRINTF(("%s: unsupported protocol family %u\n", __func__, af));
194a9643ea8Slogwang m_freem(m);
195a9643ea8Slogwang IPSEC_ISTAT(sproto, nopf);
196a9643ea8Slogwang return EPFNOSUPPORT;
197a9643ea8Slogwang }
198a9643ea8Slogwang
199a9643ea8Slogwang /* NB: only pass dst since key_allocsa follows RFC2401 */
200*22ce4affSfengbojiang sav = key_allocsa(&dst_address, sproto, spi);
201a9643ea8Slogwang if (sav == NULL) {
202a9643ea8Slogwang DPRINTF(("%s: no key association found for SA %s/%08lx/%u\n",
203a9643ea8Slogwang __func__, ipsec_address(&dst_address, buf, sizeof(buf)),
204a9643ea8Slogwang (u_long) ntohl(spi), sproto));
205a9643ea8Slogwang IPSEC_ISTAT(sproto, notdb);
206a9643ea8Slogwang m_freem(m);
207a9643ea8Slogwang return ENOENT;
208a9643ea8Slogwang }
209a9643ea8Slogwang
210a9643ea8Slogwang if (sav->tdb_xform == NULL) {
211a9643ea8Slogwang DPRINTF(("%s: attempted to use uninitialized SA %s/%08lx/%u\n",
212a9643ea8Slogwang __func__, ipsec_address(&dst_address, buf, sizeof(buf)),
213a9643ea8Slogwang (u_long) ntohl(spi), sproto));
214a9643ea8Slogwang IPSEC_ISTAT(sproto, noxform);
215*22ce4affSfengbojiang key_freesav(&sav);
216a9643ea8Slogwang m_freem(m);
217a9643ea8Slogwang return ENXIO;
218a9643ea8Slogwang }
219a9643ea8Slogwang
220a9643ea8Slogwang /*
221a9643ea8Slogwang * Call appropriate transform and return -- callback takes care of
222a9643ea8Slogwang * everything else.
223a9643ea8Slogwang */
224a9643ea8Slogwang error = (*sav->tdb_xform->xf_input)(m, sav, skip, protoff);
225*22ce4affSfengbojiang return (error);
226a9643ea8Slogwang }
227a9643ea8Slogwang
228a9643ea8Slogwang #ifdef INET
229*22ce4affSfengbojiang extern struct protosw inetsw[];
230*22ce4affSfengbojiang
231*22ce4affSfengbojiang /*
232*22ce4affSfengbojiang * IPSEC_INPUT() method implementation for IPv4.
233*22ce4affSfengbojiang * 0 - Permitted by inbound security policy for further processing.
234*22ce4affSfengbojiang * EACCES - Forbidden by inbound security policy.
235*22ce4affSfengbojiang * EINPROGRESS - consumed by IPsec.
236*22ce4affSfengbojiang */
237a9643ea8Slogwang int
ipsec4_input(struct mbuf * m,int offset,int proto)238*22ce4affSfengbojiang ipsec4_input(struct mbuf *m, int offset, int proto)
239a9643ea8Slogwang {
240a9643ea8Slogwang
241*22ce4affSfengbojiang switch (proto) {
242*22ce4affSfengbojiang case IPPROTO_AH:
243*22ce4affSfengbojiang case IPPROTO_ESP:
244*22ce4affSfengbojiang case IPPROTO_IPCOMP:
245*22ce4affSfengbojiang /* Do inbound IPsec processing for AH/ESP/IPCOMP */
246*22ce4affSfengbojiang ipsec_common_input(m, offset,
247*22ce4affSfengbojiang offsetof(struct ip, ip_p), AF_INET, proto);
248*22ce4affSfengbojiang return (EINPROGRESS); /* mbuf consumed by IPsec */
249*22ce4affSfengbojiang default:
250*22ce4affSfengbojiang /*
251*22ce4affSfengbojiang * Protocols with further headers get their IPsec treatment
252*22ce4affSfengbojiang * within the protocol specific processing.
253*22ce4affSfengbojiang */
254*22ce4affSfengbojiang if ((inetsw[ip_protox[proto]].pr_flags & PR_LASTHDR) == 0)
255*22ce4affSfengbojiang return (0);
256*22ce4affSfengbojiang /* FALLTHROUGH */
257*22ce4affSfengbojiang };
258*22ce4affSfengbojiang /*
259*22ce4affSfengbojiang * Enforce IPsec policy checking if we are seeing last header.
260*22ce4affSfengbojiang */
261*22ce4affSfengbojiang if (ipsec4_in_reject(m, NULL) != 0) {
262*22ce4affSfengbojiang /* Forbidden by inbound security policy */
263*22ce4affSfengbojiang m_freem(m);
264*22ce4affSfengbojiang return (EACCES);
265a9643ea8Slogwang }
266*22ce4affSfengbojiang return (0);
267a9643ea8Slogwang }
268a9643ea8Slogwang
269a9643ea8Slogwang /*
270a9643ea8Slogwang * IPsec input callback for INET protocols.
271a9643ea8Slogwang * This routine is called as the transform callback.
272a9643ea8Slogwang * Takes care of filtering and other sanity checks on
273a9643ea8Slogwang * the processed packet.
274a9643ea8Slogwang */
275a9643ea8Slogwang int
ipsec4_common_input_cb(struct mbuf * m,struct secasvar * sav,int skip,int protoff)276a9643ea8Slogwang ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
277a9643ea8Slogwang int protoff)
278a9643ea8Slogwang {
279*22ce4affSfengbojiang IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
280*22ce4affSfengbojiang struct epoch_tracker et;
281a9643ea8Slogwang struct ipsec_ctx_data ctx;
282*22ce4affSfengbojiang struct xform_history *xh;
283a9643ea8Slogwang struct secasindex *saidx;
284*22ce4affSfengbojiang struct m_tag *mtag;
285*22ce4affSfengbojiang struct ip *ip;
286*22ce4affSfengbojiang int error, prot, af, sproto, isr_prot;
287a9643ea8Slogwang
288a9643ea8Slogwang IPSEC_ASSERT(sav != NULL, ("null SA"));
289a9643ea8Slogwang IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
290a9643ea8Slogwang saidx = &sav->sah->saidx;
291a9643ea8Slogwang af = saidx->dst.sa.sa_family;
292a9643ea8Slogwang IPSEC_ASSERT(af == AF_INET, ("unexpected af %u", af));
293a9643ea8Slogwang sproto = saidx->proto;
294a9643ea8Slogwang IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
295a9643ea8Slogwang sproto == IPPROTO_IPCOMP,
296a9643ea8Slogwang ("unexpected security protocol %u", sproto));
297a9643ea8Slogwang
298a9643ea8Slogwang if (skip != 0) {
299a9643ea8Slogwang /*
300a9643ea8Slogwang * Fix IPv4 header
301a9643ea8Slogwang */
302a9643ea8Slogwang if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) {
303a9643ea8Slogwang DPRINTF(("%s: processing failed for SA %s/%08lx\n",
304a9643ea8Slogwang __func__, ipsec_address(&sav->sah->saidx.dst,
305a9643ea8Slogwang buf, sizeof(buf)), (u_long) ntohl(sav->spi)));
306a9643ea8Slogwang IPSEC_ISTAT(sproto, hdrops);
307a9643ea8Slogwang error = ENOBUFS;
308a9643ea8Slogwang goto bad;
309a9643ea8Slogwang }
310a9643ea8Slogwang
311a9643ea8Slogwang ip = mtod(m, struct ip *);
312a9643ea8Slogwang ip->ip_len = htons(m->m_pkthdr.len);
313a9643ea8Slogwang ip->ip_sum = 0;
314a9643ea8Slogwang ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
315a9643ea8Slogwang } else {
316a9643ea8Slogwang ip = mtod(m, struct ip *);
317a9643ea8Slogwang }
318a9643ea8Slogwang prot = ip->ip_p;
319*22ce4affSfengbojiang /*
320*22ce4affSfengbojiang * Check that we have NAT-T enabled and apply transport mode
321*22ce4affSfengbojiang * decapsulation NAT procedure (RFC3948).
322*22ce4affSfengbojiang * Do this before invoking into the PFIL.
323*22ce4affSfengbojiang */
324*22ce4affSfengbojiang if (sav->natt != NULL &&
325*22ce4affSfengbojiang (prot == IPPROTO_UDP || prot == IPPROTO_TCP))
326*22ce4affSfengbojiang udp_ipsec_adjust_cksum(m, sav, prot, skip);
327a9643ea8Slogwang
328*22ce4affSfengbojiang IPSEC_INIT_CTX(&ctx, &m, NULL, sav, AF_INET, IPSEC_ENC_BEFORE);
329a9643ea8Slogwang if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
330a9643ea8Slogwang goto bad;
331*22ce4affSfengbojiang ip = mtod(m, struct ip *); /* update pointer */
332a9643ea8Slogwang
333a9643ea8Slogwang /* IP-in-IP encapsulation */
334a9643ea8Slogwang if (prot == IPPROTO_IPIP &&
335a9643ea8Slogwang saidx->mode != IPSEC_MODE_TRANSPORT) {
336a9643ea8Slogwang if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
337a9643ea8Slogwang IPSEC_ISTAT(sproto, hdrops);
338a9643ea8Slogwang error = EINVAL;
339a9643ea8Slogwang goto bad;
340a9643ea8Slogwang }
341a9643ea8Slogwang /* enc0: strip outer IPv4 header */
342a9643ea8Slogwang m_striphdr(m, 0, ip->ip_hl << 2);
343a9643ea8Slogwang }
344a9643ea8Slogwang #ifdef INET6
345a9643ea8Slogwang /* IPv6-in-IP encapsulation. */
346a9643ea8Slogwang else if (prot == IPPROTO_IPV6 &&
347a9643ea8Slogwang saidx->mode != IPSEC_MODE_TRANSPORT) {
348a9643ea8Slogwang if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
349a9643ea8Slogwang IPSEC_ISTAT(sproto, hdrops);
350a9643ea8Slogwang error = EINVAL;
351a9643ea8Slogwang goto bad;
352a9643ea8Slogwang }
353a9643ea8Slogwang /* enc0: strip IPv4 header, keep IPv6 header only */
354a9643ea8Slogwang m_striphdr(m, 0, ip->ip_hl << 2);
355a9643ea8Slogwang }
356a9643ea8Slogwang #endif /* INET6 */
357a9643ea8Slogwang else if (prot != IPPROTO_IPV6 && saidx->mode == IPSEC_MODE_ANY) {
358a9643ea8Slogwang /*
359a9643ea8Slogwang * When mode is wildcard, inner protocol is IPv6 and
360a9643ea8Slogwang * we have no INET6 support - drop this packet a bit later.
361*22ce4affSfengbojiang * In other cases we assume transport mode. Set prot to
362*22ce4affSfengbojiang * correctly choose netisr.
363a9643ea8Slogwang */
364a9643ea8Slogwang prot = IPPROTO_IPIP;
365a9643ea8Slogwang }
366a9643ea8Slogwang
367a9643ea8Slogwang /*
368a9643ea8Slogwang * Record what we've done to the packet (under what SA it was
369a9643ea8Slogwang * processed).
370a9643ea8Slogwang */
371a9643ea8Slogwang if (sproto != IPPROTO_IPCOMP) {
372a9643ea8Slogwang mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
373*22ce4affSfengbojiang sizeof(struct xform_history), M_NOWAIT);
374a9643ea8Slogwang if (mtag == NULL) {
375a9643ea8Slogwang DPRINTF(("%s: failed to get tag\n", __func__));
376a9643ea8Slogwang IPSEC_ISTAT(sproto, hdrops);
377a9643ea8Slogwang error = ENOMEM;
378a9643ea8Slogwang goto bad;
379a9643ea8Slogwang }
380a9643ea8Slogwang
381*22ce4affSfengbojiang xh = (struct xform_history *)(mtag + 1);
382*22ce4affSfengbojiang bcopy(&saidx->dst, &xh->dst, saidx->dst.sa.sa_len);
383*22ce4affSfengbojiang xh->spi = sav->spi;
384*22ce4affSfengbojiang xh->proto = sproto;
385*22ce4affSfengbojiang xh->mode = saidx->mode;
386a9643ea8Slogwang m_tag_prepend(m, mtag);
387a9643ea8Slogwang }
388a9643ea8Slogwang
389a9643ea8Slogwang key_sa_recordxfer(sav, m); /* record data transfer */
390a9643ea8Slogwang
391a9643ea8Slogwang /*
392a9643ea8Slogwang * In transport mode requeue decrypted mbuf back to IPv4 protocol
393a9643ea8Slogwang * handler. This is necessary to correctly expose rcvif.
394a9643ea8Slogwang */
395a9643ea8Slogwang if (saidx->mode == IPSEC_MODE_TRANSPORT)
396a9643ea8Slogwang prot = IPPROTO_IPIP;
397a9643ea8Slogwang /*
398a9643ea8Slogwang * Re-dispatch via software interrupt.
399a9643ea8Slogwang */
400a9643ea8Slogwang switch (prot) {
401a9643ea8Slogwang case IPPROTO_IPIP:
402a9643ea8Slogwang isr_prot = NETISR_IP;
403a9643ea8Slogwang af = AF_INET;
404a9643ea8Slogwang break;
405a9643ea8Slogwang #ifdef INET6
406a9643ea8Slogwang case IPPROTO_IPV6:
407a9643ea8Slogwang isr_prot = NETISR_IPV6;
408a9643ea8Slogwang af = AF_INET6;
409a9643ea8Slogwang break;
410a9643ea8Slogwang #endif
411a9643ea8Slogwang default:
412a9643ea8Slogwang DPRINTF(("%s: cannot handle inner ip proto %d\n",
413a9643ea8Slogwang __func__, prot));
414a9643ea8Slogwang IPSEC_ISTAT(sproto, nopf);
415a9643ea8Slogwang error = EPFNOSUPPORT;
416a9643ea8Slogwang goto bad;
417a9643ea8Slogwang }
418a9643ea8Slogwang
419*22ce4affSfengbojiang IPSEC_INIT_CTX(&ctx, &m, NULL, sav, af, IPSEC_ENC_AFTER);
420a9643ea8Slogwang if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
421a9643ea8Slogwang goto bad;
422*22ce4affSfengbojiang
423*22ce4affSfengbojiang /* Handle virtual tunneling interfaces */
424*22ce4affSfengbojiang if (saidx->mode == IPSEC_MODE_TUNNEL)
425*22ce4affSfengbojiang error = ipsec_if_input(m, sav, af);
426*22ce4affSfengbojiang if (error == 0) {
427*22ce4affSfengbojiang NET_EPOCH_ENTER(et);
428a9643ea8Slogwang error = netisr_queue_src(isr_prot, (uintptr_t)sav->spi, m);
429*22ce4affSfengbojiang NET_EPOCH_EXIT(et);
430a9643ea8Slogwang if (error) {
431a9643ea8Slogwang IPSEC_ISTAT(sproto, qfull);
432a9643ea8Slogwang DPRINTF(("%s: queue full; proto %u packet dropped\n",
433a9643ea8Slogwang __func__, sproto));
434a9643ea8Slogwang }
435*22ce4affSfengbojiang }
436*22ce4affSfengbojiang key_freesav(&sav);
437*22ce4affSfengbojiang return (error);
438a9643ea8Slogwang bad:
439*22ce4affSfengbojiang key_freesav(&sav);
440*22ce4affSfengbojiang if (m != NULL)
441a9643ea8Slogwang m_freem(m);
442*22ce4affSfengbojiang return (error);
443a9643ea8Slogwang }
444a9643ea8Slogwang #endif /* INET */
445a9643ea8Slogwang
446a9643ea8Slogwang #ifdef INET6
447*22ce4affSfengbojiang /*
448*22ce4affSfengbojiang * IPSEC_INPUT() method implementation for IPv6.
449*22ce4affSfengbojiang * 0 - Permitted by inbound security policy for further processing.
450*22ce4affSfengbojiang * EACCES - Forbidden by inbound security policy.
451*22ce4affSfengbojiang * EINPROGRESS - consumed by IPsec.
452*22ce4affSfengbojiang */
453a9643ea8Slogwang int
ipsec6_input(struct mbuf * m,int offset,int proto)454*22ce4affSfengbojiang ipsec6_input(struct mbuf *m, int offset, int proto)
455a9643ea8Slogwang {
456a9643ea8Slogwang
457*22ce4affSfengbojiang switch (proto) {
458*22ce4affSfengbojiang case IPPROTO_AH:
459*22ce4affSfengbojiang case IPPROTO_ESP:
460*22ce4affSfengbojiang case IPPROTO_IPCOMP:
461*22ce4affSfengbojiang /* Do inbound IPsec processing for AH/ESP/IPCOMP */
462*22ce4affSfengbojiang ipsec_common_input(m, offset,
463*22ce4affSfengbojiang offsetof(struct ip6_hdr, ip6_nxt), AF_INET6, proto);
464*22ce4affSfengbojiang return (EINPROGRESS); /* mbuf consumed by IPsec */
465*22ce4affSfengbojiang default:
466*22ce4affSfengbojiang /*
467*22ce4affSfengbojiang * Protocols with further headers get their IPsec treatment
468*22ce4affSfengbojiang * within the protocol specific processing.
469*22ce4affSfengbojiang */
470*22ce4affSfengbojiang if ((inet6sw[ip6_protox[proto]].pr_flags & PR_LASTHDR) == 0)
471*22ce4affSfengbojiang return (0);
472*22ce4affSfengbojiang /* FALLTHROUGH */
473*22ce4affSfengbojiang };
474*22ce4affSfengbojiang /*
475*22ce4affSfengbojiang * Enforce IPsec policy checking if we are seeing last header.
476*22ce4affSfengbojiang */
477*22ce4affSfengbojiang if (ipsec6_in_reject(m, NULL) != 0) {
478*22ce4affSfengbojiang /* Forbidden by inbound security policy */
479*22ce4affSfengbojiang m_freem(m);
480*22ce4affSfengbojiang return (EACCES);
481a9643ea8Slogwang }
482*22ce4affSfengbojiang return (0);
483a9643ea8Slogwang }
484a9643ea8Slogwang
485a9643ea8Slogwang /*
486a9643ea8Slogwang * IPsec input callback, called by the transform callback. Takes care of
487a9643ea8Slogwang * filtering and other sanity checks on the processed packet.
488a9643ea8Slogwang */
489a9643ea8Slogwang int
ipsec6_common_input_cb(struct mbuf * m,struct secasvar * sav,int skip,int protoff)490a9643ea8Slogwang ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
491a9643ea8Slogwang int protoff)
492a9643ea8Slogwang {
493*22ce4affSfengbojiang IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
494*22ce4affSfengbojiang struct epoch_tracker et;
495a9643ea8Slogwang struct ipsec_ctx_data ctx;
496*22ce4affSfengbojiang struct xform_history *xh;
497*22ce4affSfengbojiang struct secasindex *saidx;
498a9643ea8Slogwang struct ip6_hdr *ip6;
499a9643ea8Slogwang struct m_tag *mtag;
500*22ce4affSfengbojiang int prot, af, sproto;
501a9643ea8Slogwang int nxt, isr_prot;
502a9643ea8Slogwang int error, nest;
503*22ce4affSfengbojiang uint8_t nxt8;
504a9643ea8Slogwang
505a9643ea8Slogwang IPSEC_ASSERT(sav != NULL, ("null SA"));
506a9643ea8Slogwang IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
507a9643ea8Slogwang saidx = &sav->sah->saidx;
508a9643ea8Slogwang af = saidx->dst.sa.sa_family;
509a9643ea8Slogwang IPSEC_ASSERT(af == AF_INET6, ("unexpected af %u", af));
510a9643ea8Slogwang sproto = saidx->proto;
511a9643ea8Slogwang IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
512a9643ea8Slogwang sproto == IPPROTO_IPCOMP,
513a9643ea8Slogwang ("unexpected security protocol %u", sproto));
514a9643ea8Slogwang
515a9643ea8Slogwang /* Fix IPv6 header */
516a9643ea8Slogwang if (m->m_len < sizeof(struct ip6_hdr) &&
517a9643ea8Slogwang (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
518a9643ea8Slogwang DPRINTF(("%s: processing failed for SA %s/%08lx\n",
519a9643ea8Slogwang __func__, ipsec_address(&sav->sah->saidx.dst, buf,
520a9643ea8Slogwang sizeof(buf)), (u_long) ntohl(sav->spi)));
521a9643ea8Slogwang
522a9643ea8Slogwang IPSEC_ISTAT(sproto, hdrops);
523a9643ea8Slogwang error = EACCES;
524a9643ea8Slogwang goto bad;
525a9643ea8Slogwang }
526a9643ea8Slogwang
527*22ce4affSfengbojiang IPSEC_INIT_CTX(&ctx, &m, NULL, sav, af, IPSEC_ENC_BEFORE);
528*22ce4affSfengbojiang if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
529*22ce4affSfengbojiang goto bad;
530*22ce4affSfengbojiang
531a9643ea8Slogwang ip6 = mtod(m, struct ip6_hdr *);
532a9643ea8Slogwang ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
533a9643ea8Slogwang
534a9643ea8Slogwang /* Save protocol */
535a9643ea8Slogwang m_copydata(m, protoff, 1, &nxt8);
536a9643ea8Slogwang prot = nxt8;
537a9643ea8Slogwang
538a9643ea8Slogwang /* IPv6-in-IP encapsulation */
539a9643ea8Slogwang if (prot == IPPROTO_IPV6 &&
540a9643ea8Slogwang saidx->mode != IPSEC_MODE_TRANSPORT) {
541a9643ea8Slogwang if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
542a9643ea8Slogwang IPSEC_ISTAT(sproto, hdrops);
543a9643ea8Slogwang error = EINVAL;
544a9643ea8Slogwang goto bad;
545a9643ea8Slogwang }
546a9643ea8Slogwang /* ip6n will now contain the inner IPv6 header. */
547a9643ea8Slogwang m_striphdr(m, 0, skip);
548a9643ea8Slogwang skip = 0;
549a9643ea8Slogwang }
550a9643ea8Slogwang #ifdef INET
551a9643ea8Slogwang /* IP-in-IP encapsulation */
552a9643ea8Slogwang else if (prot == IPPROTO_IPIP &&
553a9643ea8Slogwang saidx->mode != IPSEC_MODE_TRANSPORT) {
554a9643ea8Slogwang if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
555a9643ea8Slogwang IPSEC_ISTAT(sproto, hdrops);
556a9643ea8Slogwang error = EINVAL;
557a9643ea8Slogwang goto bad;
558a9643ea8Slogwang }
559a9643ea8Slogwang /* ipn will now contain the inner IPv4 header */
560a9643ea8Slogwang m_striphdr(m, 0, skip);
561a9643ea8Slogwang skip = 0;
562a9643ea8Slogwang }
563a9643ea8Slogwang #endif /* INET */
564a9643ea8Slogwang else {
565a9643ea8Slogwang prot = IPPROTO_IPV6; /* for correct BPF processing */
566a9643ea8Slogwang }
567a9643ea8Slogwang
568a9643ea8Slogwang /*
569a9643ea8Slogwang * Record what we've done to the packet (under what SA it was
570a9643ea8Slogwang * processed).
571a9643ea8Slogwang */
572a9643ea8Slogwang if (sproto != IPPROTO_IPCOMP) {
573a9643ea8Slogwang mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
574*22ce4affSfengbojiang sizeof(struct xform_history), M_NOWAIT);
575a9643ea8Slogwang if (mtag == NULL) {
576a9643ea8Slogwang DPRINTF(("%s: failed to get tag\n", __func__));
577a9643ea8Slogwang IPSEC_ISTAT(sproto, hdrops);
578a9643ea8Slogwang error = ENOMEM;
579a9643ea8Slogwang goto bad;
580a9643ea8Slogwang }
581a9643ea8Slogwang
582*22ce4affSfengbojiang xh = (struct xform_history *)(mtag + 1);
583*22ce4affSfengbojiang bcopy(&saidx->dst, &xh->dst, saidx->dst.sa.sa_len);
584*22ce4affSfengbojiang xh->spi = sav->spi;
585*22ce4affSfengbojiang xh->proto = sproto;
586*22ce4affSfengbojiang xh->mode = saidx->mode;
587a9643ea8Slogwang m_tag_prepend(m, mtag);
588a9643ea8Slogwang }
589a9643ea8Slogwang
590a9643ea8Slogwang key_sa_recordxfer(sav, m);
591a9643ea8Slogwang
592a9643ea8Slogwang #ifdef INET
593a9643ea8Slogwang if (prot == IPPROTO_IPIP)
594a9643ea8Slogwang af = AF_INET;
595a9643ea8Slogwang else
596a9643ea8Slogwang #endif
597a9643ea8Slogwang af = AF_INET6;
598*22ce4affSfengbojiang IPSEC_INIT_CTX(&ctx, &m, NULL, sav, af, IPSEC_ENC_AFTER);
599a9643ea8Slogwang if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
600a9643ea8Slogwang goto bad;
601a9643ea8Slogwang if (skip == 0) {
602a9643ea8Slogwang /*
603a9643ea8Slogwang * We stripped outer IPv6 header.
604a9643ea8Slogwang * Now we should requeue decrypted packet via netisr.
605a9643ea8Slogwang */
606a9643ea8Slogwang switch (prot) {
607a9643ea8Slogwang #ifdef INET
608a9643ea8Slogwang case IPPROTO_IPIP:
609a9643ea8Slogwang isr_prot = NETISR_IP;
610a9643ea8Slogwang break;
611a9643ea8Slogwang #endif
612a9643ea8Slogwang case IPPROTO_IPV6:
613a9643ea8Slogwang isr_prot = NETISR_IPV6;
614a9643ea8Slogwang break;
615a9643ea8Slogwang default:
616a9643ea8Slogwang DPRINTF(("%s: cannot handle inner ip proto %d\n",
617a9643ea8Slogwang __func__, prot));
618a9643ea8Slogwang IPSEC_ISTAT(sproto, nopf);
619a9643ea8Slogwang error = EPFNOSUPPORT;
620a9643ea8Slogwang goto bad;
621a9643ea8Slogwang }
622*22ce4affSfengbojiang /* Handle virtual tunneling interfaces */
623*22ce4affSfengbojiang if (saidx->mode == IPSEC_MODE_TUNNEL)
624*22ce4affSfengbojiang error = ipsec_if_input(m, sav, af);
625*22ce4affSfengbojiang if (error == 0) {
626*22ce4affSfengbojiang NET_EPOCH_ENTER(et);
627*22ce4affSfengbojiang error = netisr_queue_src(isr_prot,
628*22ce4affSfengbojiang (uintptr_t)sav->spi, m);
629*22ce4affSfengbojiang NET_EPOCH_EXIT(et);
630a9643ea8Slogwang if (error) {
631a9643ea8Slogwang IPSEC_ISTAT(sproto, qfull);
632*22ce4affSfengbojiang DPRINTF(("%s: queue full; proto %u packet"
633*22ce4affSfengbojiang " dropped\n", __func__, sproto));
634a9643ea8Slogwang }
635*22ce4affSfengbojiang }
636*22ce4affSfengbojiang key_freesav(&sav);
637a9643ea8Slogwang return (error);
638a9643ea8Slogwang }
639a9643ea8Slogwang /*
640a9643ea8Slogwang * See the end of ip6_input for this logic.
641a9643ea8Slogwang * IPPROTO_IPV[46] case will be processed just like other ones
642a9643ea8Slogwang */
643a9643ea8Slogwang nest = 0;
644a9643ea8Slogwang nxt = nxt8;
645*22ce4affSfengbojiang NET_EPOCH_ENTER(et);
646a9643ea8Slogwang while (nxt != IPPROTO_DONE) {
647a9643ea8Slogwang if (V_ip6_hdrnestlimit && (++nest > V_ip6_hdrnestlimit)) {
648a9643ea8Slogwang IP6STAT_INC(ip6s_toomanyhdr);
649a9643ea8Slogwang error = EINVAL;
650*22ce4affSfengbojiang goto bad_epoch;
651a9643ea8Slogwang }
652a9643ea8Slogwang
653a9643ea8Slogwang /*
654a9643ea8Slogwang * Protection against faulty packet - there should be
655a9643ea8Slogwang * more sanity checks in header chain processing.
656a9643ea8Slogwang */
657a9643ea8Slogwang if (m->m_pkthdr.len < skip) {
658a9643ea8Slogwang IP6STAT_INC(ip6s_tooshort);
659a9643ea8Slogwang in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
660a9643ea8Slogwang error = EINVAL;
661*22ce4affSfengbojiang goto bad_epoch;
662a9643ea8Slogwang }
663a9643ea8Slogwang /*
664a9643ea8Slogwang * Enforce IPsec policy checking if we are seeing last header.
665a9643ea8Slogwang * note that we do not visit this with protocols with pcb layer
666a9643ea8Slogwang * code - like udp/tcp/raw ip.
667a9643ea8Slogwang */
668a9643ea8Slogwang if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
669a9643ea8Slogwang ipsec6_in_reject(m, NULL)) {
670a9643ea8Slogwang error = EINVAL;
671*22ce4affSfengbojiang goto bad_epoch;
672a9643ea8Slogwang }
673a9643ea8Slogwang nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt);
674a9643ea8Slogwang }
675*22ce4affSfengbojiang NET_EPOCH_EXIT(et);
676*22ce4affSfengbojiang key_freesav(&sav);
677*22ce4affSfengbojiang return (0);
678*22ce4affSfengbojiang bad_epoch:
679*22ce4affSfengbojiang NET_EPOCH_EXIT(et);
680a9643ea8Slogwang bad:
681*22ce4affSfengbojiang key_freesav(&sav);
682a9643ea8Slogwang if (m)
683a9643ea8Slogwang m_freem(m);
684*22ce4affSfengbojiang return (error);
685a9643ea8Slogwang }
686a9643ea8Slogwang #endif /* INET6 */
687