xform_ipip.c revision 274132
1/*	$FreeBSD: stable/10/sys/netipsec/xform_ipip.c 274132 2014-11-05 09:23:29Z ae $	*/
2/*	$OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */
3/*-
4 * The authors of this code are John Ioannidis (ji@tla.org),
5 * Angelos D. Keromytis (kermit@csd.uch.gr) and
6 * Niels Provos (provos@physnet.uni-hamburg.de).
7 *
8 * The original version of this code was written by John Ioannidis
9 * for BSD/OS in Athens, Greece, in November 1995.
10 *
11 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
12 * by Angelos D. Keromytis.
13 *
14 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
15 * and Niels Provos.
16 *
17 * Additional features in 1999 by Angelos D. Keromytis.
18 *
19 * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
20 * Angelos D. Keromytis and Niels Provos.
21 * Copyright (c) 2001, Angelos D. Keromytis.
22 *
23 * Permission to use, copy, and modify this software with or without fee
24 * is hereby granted, provided that this entire notice is included in
25 * all copies of any software which is or includes a copy or
26 * modification of this software.
27 * You may use this code under the GNU public license if you so wish. Please
28 * contribute changes back to the authors under this freer than GPL license
29 * so that we may further the use of strong encryption without limitations to
30 * all.
31 *
32 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
33 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
34 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
35 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
36 * PURPOSE.
37 */
38
39/*
40 * IP-inside-IP processing
41 */
42#include "opt_inet.h"
43#include "opt_inet6.h"
44#include "opt_enc.h"
45
46#include <sys/param.h>
47#include <sys/systm.h>
48#include <sys/mbuf.h>
49#include <sys/socket.h>
50#include <sys/kernel.h>
51#include <sys/protosw.h>
52#include <sys/sysctl.h>
53
54#include <net/if.h>
55#include <net/pfil.h>
56#include <net/route.h>
57#include <net/netisr.h>
58#include <net/vnet.h>
59
60#include <netinet/in.h>
61#include <netinet/in_systm.h>
62#include <netinet/in_var.h>
63#include <netinet/ip.h>
64#include <netinet/ip_ecn.h>
65#include <netinet/ip_var.h>
66#include <netinet/ip_encap.h>
67
68#include <netipsec/ipsec.h>
69#include <netipsec/xform.h>
70
71#include <netipsec/ipip_var.h>
72
73#ifdef INET6
74#include <netinet/ip6.h>
75#include <netipsec/ipsec6.h>
76#include <netinet6/ip6_ecn.h>
77#include <netinet6/in6_var.h>
78#include <netinet6/ip6protosw.h>
79#endif
80
81#include <netipsec/key.h>
82#include <netipsec/key_debug.h>
83
84#include <machine/stdarg.h>
85
86/*
87 * We can control the acceptance of IP4 packets by altering the sysctl
88 * net.inet.ipip.allow value.  Zero means drop them, all else is acceptance.
89 */
90VNET_DEFINE(int, ipip_allow) = 0;
91VNET_PCPUSTAT_DEFINE(struct ipipstat, ipipstat);
92VNET_PCPUSTAT_SYSINIT(ipipstat);
93
94#ifdef VIMAGE
95VNET_PCPUSTAT_SYSUNINIT(ipipstat);
96#endif /* VIMAGE */
97
98SYSCTL_DECL(_net_inet_ipip);
99SYSCTL_VNET_INT(_net_inet_ipip, OID_AUTO,
100	ipip_allow,	CTLFLAG_RW,	&VNET_NAME(ipip_allow),	0, "");
101SYSCTL_VNET_PCPUSTAT(_net_inet_ipip, IPSECCTL_STATS, stats,
102    struct ipipstat, ipipstat,
103    "IPIP statistics (struct ipipstat, netipsec/ipip_var.h)");
104
105/* XXX IPCOMP */
106#define	M_IPSEC	(M_AUTHIPHDR|M_AUTHIPDGM|M_DECRYPTED)
107
108static void _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp);
109
110#ifdef INET6
111/*
112 * Really only a wrapper for ipip_input(), for use with IPv6.
113 */
114int
115ip4_input6(struct mbuf **m, int *offp, int proto)
116{
117#if 0
118	/* If we do not accept IP-in-IP explicitly, drop.  */
119	if (!V_ipip_allow && ((*m)->m_flags & M_IPSEC) == 0) {
120		DPRINTF(("%s: dropped due to policy\n", __func__));
121		IPIPSTAT_INC(ipips_pdrops);
122		m_freem(*m);
123		return IPPROTO_DONE;
124	}
125#endif
126	_ipip_input(*m, *offp, NULL);
127	return IPPROTO_DONE;
128}
129#endif /* INET6 */
130
131#ifdef INET
132/*
133 * Really only a wrapper for ipip_input(), for use with IPv4.
134 */
135void
136ip4_input(struct mbuf *m, int off)
137{
138#if 0
139	/* If we do not accept IP-in-IP explicitly, drop.  */
140	if (!V_ipip_allow && (m->m_flags & M_IPSEC) == 0) {
141		DPRINTF(("%s: dropped due to policy\n", __func__));
142		IPIPSTAT_INC(ipips_pdrops);
143		m_freem(m);
144		return;
145	}
146#endif
147	_ipip_input(m, off, NULL);
148}
149#endif /* INET */
150
151/*
152 * ipip_input gets called when we receive an IP{46} encapsulated packet,
153 * either because we got it at a real interface, or because AH or ESP
154 * were being used in tunnel mode (in which case the rcvif element will
155 * contain the address of the encX interface associated with the tunnel.
156 */
157
158static void
159_ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
160{
161	struct ip *ipo;
162#ifdef INET6
163	struct ip6_hdr *ip6 = NULL;
164	u_int8_t itos;
165#endif
166	int isr;
167	u_int8_t otos;
168	u_int8_t v;
169	int hlen;
170
171	IPIPSTAT_INC(ipips_ipackets);
172
173	m_copydata(m, 0, 1, &v);
174
175	switch (v >> 4) {
176#ifdef INET
177        case 4:
178		hlen = sizeof(struct ip);
179		break;
180#endif /* INET */
181#ifdef INET6
182        case 6:
183		hlen = sizeof(struct ip6_hdr);
184		break;
185#endif
186        default:
187		IPIPSTAT_INC(ipips_family);
188		m_freem(m);
189		return /* EAFNOSUPPORT */;
190	}
191
192	/* Bring the IP header in the first mbuf, if not there already */
193	if (m->m_len < hlen) {
194		if ((m = m_pullup(m, hlen)) == NULL) {
195			DPRINTF(("%s: m_pullup (1) failed\n", __func__));
196			IPIPSTAT_INC(ipips_hdrops);
197			return;
198		}
199	}
200	ipo = mtod(m, struct ip *);
201
202	/* Keep outer ecn field. */
203	switch (v >> 4) {
204#ifdef INET
205	case 4:
206		otos = ipo->ip_tos;
207		break;
208#endif /* INET */
209#ifdef INET6
210	case 6:
211		otos = (ntohl(mtod(m, struct ip6_hdr *)->ip6_flow) >> 20) & 0xff;
212		break;
213#endif
214	default:
215		panic("ipip_input: unknown ip version %u (outer)", v>>4);
216	}
217
218	/* Remove outer IP header */
219	m_adj(m, iphlen);
220
221	/* Sanity check */
222	if (m->m_pkthdr.len < sizeof(struct ip))  {
223		IPIPSTAT_INC(ipips_hdrops);
224		m_freem(m);
225		return;
226	}
227
228	m_copydata(m, 0, 1, &v);
229
230	switch (v >> 4) {
231#ifdef INET
232        case 4:
233		hlen = sizeof(struct ip);
234		break;
235#endif /* INET */
236
237#ifdef INET6
238        case 6:
239		hlen = sizeof(struct ip6_hdr);
240		break;
241#endif
242	default:
243		IPIPSTAT_INC(ipips_family);
244		m_freem(m);
245		return; /* EAFNOSUPPORT */
246	}
247
248	/*
249	 * Bring the inner IP header in the first mbuf, if not there already.
250	 */
251	if (m->m_len < hlen) {
252		if ((m = m_pullup(m, hlen)) == NULL) {
253			DPRINTF(("%s: m_pullup (2) failed\n", __func__));
254			IPIPSTAT_INC(ipips_hdrops);
255			return;
256		}
257	}
258
259	/*
260	 * RFC 1853 specifies that the inner TTL should not be touched on
261	 * decapsulation. There's no reason this comment should be here, but
262	 * this is as good as any a position.
263	 */
264
265	/* Some sanity checks in the inner IP header */
266	switch (v >> 4) {
267#ifdef INET
268    	case 4:
269                ipo = mtod(m, struct ip *);
270		ip_ecn_egress(V_ip4_ipsec_ecn, &otos, &ipo->ip_tos);
271                break;
272#endif /* INET */
273#ifdef INET6
274    	case 6:
275                ip6 = (struct ip6_hdr *) ipo;
276		itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
277		ip_ecn_egress(V_ip6_ipsec_ecn, &otos, &itos);
278		ip6->ip6_flow &= ~htonl(0xff << 20);
279		ip6->ip6_flow |= htonl((u_int32_t) itos << 20);
280                break;
281#endif
282	default:
283		panic("ipip_input: unknown ip version %u (inner)", v>>4);
284	}
285
286	/* Check for local address spoofing. */
287	if ((m->m_pkthdr.rcvif == NULL ||
288	    !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) &&
289	    V_ipip_allow != 2) {
290#ifdef INET
291		if ((v >> 4) == IPVERSION &&
292		    in_localip(ipo->ip_src) != 0) {
293			IPIPSTAT_INC(ipips_spoof);
294			m_freem(m);
295			return;
296		}
297#endif
298#ifdef INET6
299		if ((v & IPV6_VERSION_MASK) == IPV6_VERSION &&
300		    in6_localip(&ip6->ip6_src) != 0) {
301			IPIPSTAT_INC(ipips_spoof);
302			m_freem(m);
303			return;
304		}
305#endif
306	}
307
308	/* Statistics */
309	IPIPSTAT_ADD(ipips_ibytes, m->m_pkthdr.len - iphlen);
310
311	/*
312	 * Interface pointer stays the same; if no IPsec processing has
313	 * been done (or will be done), this will point to a normal
314	 * interface. Otherwise, it'll point to an enc interface, which
315	 * will allow a packet filter to distinguish between secure and
316	 * untrusted packets.
317	 */
318
319	switch (v >> 4) {
320#ifdef INET
321	case 4:
322		isr = NETISR_IP;
323		break;
324#endif
325#ifdef INET6
326	case 6:
327		isr = NETISR_IPV6;
328		break;
329#endif
330	default:
331		panic("%s: bogus ip version %u", __func__, v>>4);
332	}
333
334	if (netisr_queue(isr, m)) {	/* (0) on success. */
335		IPIPSTAT_INC(ipips_qfull);
336		DPRINTF(("%s: packet dropped because of full queue\n",
337			__func__));
338	}
339}
340
341int
342ipip_output(
343	struct mbuf *m,
344	struct ipsecrequest *isr,
345	struct mbuf **mp,
346	int skip,
347	int protoff
348)
349{
350	struct secasvar *sav;
351	u_int8_t tp, otos;
352	struct secasindex *saidx;
353	int error;
354#if defined(INET) || defined(INET6)
355	u_int8_t itos;
356#endif
357#ifdef INET
358	struct ip *ipo;
359#endif /* INET */
360#ifdef INET6
361	struct ip6_hdr *ip6, *ip6o;
362#endif /* INET6 */
363
364	sav = isr->sav;
365	IPSEC_ASSERT(sav != NULL, ("null SA"));
366	IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
367
368	/* XXX Deal with empty TDB source/destination addresses. */
369
370	m_copydata(m, 0, 1, &tp);
371	tp = (tp >> 4) & 0xff;  /* Get the IP version number. */
372
373	saidx = &sav->sah->saidx;
374	switch (saidx->dst.sa.sa_family) {
375#ifdef INET
376	case AF_INET:
377		if (saidx->src.sa.sa_family != AF_INET ||
378		    saidx->src.sin.sin_addr.s_addr == INADDR_ANY ||
379		    saidx->dst.sin.sin_addr.s_addr == INADDR_ANY) {
380			DPRINTF(("%s: unspecified tunnel endpoint "
381			    "address in SA %s/%08lx\n", __func__,
382			    ipsec_address(&saidx->dst),
383			    (u_long) ntohl(sav->spi)));
384			IPIPSTAT_INC(ipips_unspec);
385			error = EINVAL;
386			goto bad;
387		}
388
389		M_PREPEND(m, sizeof(struct ip), M_NOWAIT);
390		if (m == 0) {
391			DPRINTF(("%s: M_PREPEND failed\n", __func__));
392			IPIPSTAT_INC(ipips_hdrops);
393			error = ENOBUFS;
394			goto bad;
395		}
396
397		ipo = mtod(m, struct ip *);
398
399		ipo->ip_v = IPVERSION;
400		ipo->ip_hl = 5;
401		ipo->ip_len = htons(m->m_pkthdr.len);
402		ipo->ip_ttl = V_ip_defttl;
403		ipo->ip_sum = 0;
404		ipo->ip_src = saidx->src.sin.sin_addr;
405		ipo->ip_dst = saidx->dst.sin.sin_addr;
406
407		ipo->ip_id = ip_newid();
408
409		/* If the inner protocol is IP... */
410		switch (tp) {
411		case IPVERSION:
412			/* Save ECN notification */
413			m_copydata(m, sizeof(struct ip) +
414			    offsetof(struct ip, ip_tos),
415			    sizeof(u_int8_t), (caddr_t) &itos);
416
417			ipo->ip_p = IPPROTO_IPIP;
418
419			/*
420			 * We should be keeping tunnel soft-state and
421			 * send back ICMPs if needed.
422			 */
423			m_copydata(m, sizeof(struct ip) +
424			    offsetof(struct ip, ip_off),
425			    sizeof(u_int16_t), (caddr_t) &ipo->ip_off);
426			ipo->ip_off = ntohs(ipo->ip_off);
427			ipo->ip_off &= ~(IP_DF | IP_MF | IP_OFFMASK);
428			ipo->ip_off = htons(ipo->ip_off);
429			break;
430#ifdef INET6
431		case (IPV6_VERSION >> 4):
432		{
433			u_int32_t itos32;
434
435			/* Save ECN notification. */
436			m_copydata(m, sizeof(struct ip) +
437			    offsetof(struct ip6_hdr, ip6_flow),
438			    sizeof(u_int32_t), (caddr_t) &itos32);
439			itos = ntohl(itos32) >> 20;
440			ipo->ip_p = IPPROTO_IPV6;
441			ipo->ip_off = 0;
442			break;
443		}
444#endif /* INET6 */
445		default:
446			goto nofamily;
447		}
448
449		otos = 0;
450		ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
451		ipo->ip_tos = otos;
452		break;
453#endif /* INET */
454
455#ifdef INET6
456	case AF_INET6:
457		if (IN6_IS_ADDR_UNSPECIFIED(&saidx->dst.sin6.sin6_addr) ||
458		    saidx->src.sa.sa_family != AF_INET6 ||
459		    IN6_IS_ADDR_UNSPECIFIED(&saidx->src.sin6.sin6_addr)) {
460			DPRINTF(("%s: unspecified tunnel endpoint "
461			    "address in SA %s/%08lx\n", __func__,
462			    ipsec_address(&saidx->dst),
463			    (u_long) ntohl(sav->spi)));
464			IPIPSTAT_INC(ipips_unspec);
465			error = ENOBUFS;
466			goto bad;
467		}
468
469		/* scoped address handling */
470		ip6 = mtod(m, struct ip6_hdr *);
471		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
472			ip6->ip6_src.s6_addr16[1] = 0;
473		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
474			ip6->ip6_dst.s6_addr16[1] = 0;
475
476		M_PREPEND(m, sizeof(struct ip6_hdr), M_NOWAIT);
477		if (m == 0) {
478			DPRINTF(("%s: M_PREPEND failed\n", __func__));
479			IPIPSTAT_INC(ipips_hdrops);
480			error = ENOBUFS;
481			goto bad;
482		}
483
484		/* Initialize IPv6 header */
485		ip6o = mtod(m, struct ip6_hdr *);
486		ip6o->ip6_flow = 0;
487		ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
488		ip6o->ip6_vfc |= IPV6_VERSION;
489		ip6o->ip6_plen = htons(m->m_pkthdr.len);
490		ip6o->ip6_hlim = IPV6_DEFHLIM;
491		ip6o->ip6_dst = saidx->dst.sin6.sin6_addr;
492		ip6o->ip6_src = saidx->src.sin6.sin6_addr;
493
494		/* Fix payload length */
495		ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6));
496
497		switch (tp) {
498#ifdef INET
499		case IPVERSION:
500			/* Save ECN notification */
501			m_copydata(m, sizeof(struct ip6_hdr) +
502			    offsetof(struct ip, ip_tos), sizeof(u_int8_t),
503			    (caddr_t) &itos);
504
505			/* This is really IPVERSION. */
506			ip6o->ip6_nxt = IPPROTO_IPIP;
507			break;
508#endif /* INET */
509		case (IPV6_VERSION >> 4):
510		{
511			u_int32_t itos32;
512
513			/* Save ECN notification. */
514			m_copydata(m, sizeof(struct ip6_hdr) +
515			    offsetof(struct ip6_hdr, ip6_flow),
516			    sizeof(u_int32_t), (caddr_t) &itos32);
517			itos = ntohl(itos32) >> 20;
518
519			ip6o->ip6_nxt = IPPROTO_IPV6;
520			break;
521		}
522		default:
523			goto nofamily;
524		}
525
526		otos = 0;
527		ip_ecn_ingress(V_ip6_ipsec_ecn, &otos, &itos);
528		ip6o->ip6_flow |= htonl((u_int32_t) otos << 20);
529		break;
530#endif /* INET6 */
531
532	default:
533nofamily:
534		DPRINTF(("%s: unsupported protocol family %u\n", __func__,
535		    saidx->dst.sa.sa_family));
536		IPIPSTAT_INC(ipips_family);
537		error = EAFNOSUPPORT;		/* XXX diffs from openbsd */
538		goto bad;
539	}
540
541	IPIPSTAT_INC(ipips_opackets);
542	*mp = m;
543
544#ifdef INET
545	if (saidx->dst.sa.sa_family == AF_INET) {
546#if 0
547		if (sav->tdb_xform->xf_type == XF_IP4)
548			tdb->tdb_cur_bytes +=
549			    m->m_pkthdr.len - sizeof(struct ip);
550#endif
551		IPIPSTAT_ADD(ipips_obytes,
552		    m->m_pkthdr.len - sizeof(struct ip));
553	}
554#endif /* INET */
555
556#ifdef INET6
557	if (saidx->dst.sa.sa_family == AF_INET6) {
558#if 0
559		if (sav->tdb_xform->xf_type == XF_IP4)
560			tdb->tdb_cur_bytes +=
561			    m->m_pkthdr.len - sizeof(struct ip6_hdr);
562#endif
563		IPIPSTAT_ADD(ipips_obytes,
564		    m->m_pkthdr.len - sizeof(struct ip6_hdr));
565	}
566#endif /* INET6 */
567
568	return 0;
569bad:
570	if (m)
571		m_freem(m);
572	*mp = NULL;
573	return (error);
574}
575
576#ifdef IPSEC
577#if defined(INET) || defined(INET6)
578static int
579ipe4_init(struct secasvar *sav, struct xformsw *xsp)
580{
581	sav->tdb_xform = xsp;
582	return 0;
583}
584
585static int
586ipe4_zeroize(struct secasvar *sav)
587{
588	sav->tdb_xform = NULL;
589	return 0;
590}
591
592static int
593ipe4_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
594{
595	/* This is a rather serious mistake, so no conditional printing. */
596	printf("%s: should never be called\n", __func__);
597	if (m)
598		m_freem(m);
599	return EOPNOTSUPP;
600}
601
602static struct xformsw ipe4_xformsw = {
603	XF_IP4,		0,		"IPv4 Simple Encapsulation",
604	ipe4_init,	ipe4_zeroize,	ipe4_input,	ipip_output,
605};
606
607extern struct domain inetdomain;
608#endif /* INET || INET6 */
609#ifdef INET
610static struct protosw ipe4_protosw = {
611	.pr_type =	SOCK_RAW,
612	.pr_domain =	&inetdomain,
613	.pr_protocol =	IPPROTO_IPV4,
614	.pr_flags =	PR_ATOMIC|PR_ADDR|PR_LASTHDR,
615	.pr_input =	ip4_input,
616	.pr_ctloutput =	rip_ctloutput,
617	.pr_usrreqs =	&rip_usrreqs
618};
619#endif /* INET */
620#if defined(INET6) && defined(INET)
621static struct ip6protosw ipe6_protosw = {
622	.pr_type =	SOCK_RAW,
623	.pr_domain =	&inetdomain,
624	.pr_protocol =	IPPROTO_IPV6,
625	.pr_flags =	PR_ATOMIC|PR_ADDR|PR_LASTHDR,
626	.pr_input =	ip4_input6,
627	.pr_ctloutput =	rip_ctloutput,
628	.pr_usrreqs =	&rip_usrreqs
629};
630#endif /* INET6 && INET */
631
632#ifdef INET
633/*
634 * Check the encapsulated packet to see if we want it
635 */
636static int
637ipe4_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
638{
639	/*
640	 * Only take packets coming from IPSEC tunnels; the rest
641	 * must be handled by the gif tunnel code.  Note that we
642	 * also return a minimum priority when we want the packet
643	 * so any explicit gif tunnels take precedence.
644	 */
645	return ((m->m_flags & M_IPSEC) != 0 ? 1 : 0);
646}
647#endif /* INET */
648
649static void
650ipe4_attach(void)
651{
652
653	xform_register(&ipe4_xformsw);
654	/* attach to encapsulation framework */
655	/* XXX save return cookie for detach on module remove */
656#ifdef INET
657	(void) encap_attach_func(AF_INET, -1,
658		ipe4_encapcheck, &ipe4_protosw, NULL);
659#endif
660#if defined(INET6) && defined(INET)
661	(void) encap_attach_func(AF_INET6, -1,
662		ipe4_encapcheck, (struct protosw *)&ipe6_protosw, NULL);
663#endif
664}
665SYSINIT(ipe4_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ipe4_attach, NULL);
666#endif	/* IPSEC */
667