xform_ipip.c revision 264814
1/*	$FreeBSD: stable/10/sys/netipsec/xform_ipip.c 264814 2014-04-23 11:22:54Z 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#ifdef DEV_ENC
312	switch (v >> 4) {
313#ifdef INET
314	case 4:
315		ipsec_bpf(m, NULL, AF_INET, ENC_IN|ENC_AFTER);
316		break;
317#endif
318#ifdef INET6
319	case 6:
320		ipsec_bpf(m, NULL, AF_INET6, ENC_IN|ENC_AFTER);
321		break;
322#endif
323	default:
324		panic("%s: bogus ip version %u", __func__, v>>4);
325	}
326	/* pass the mbuf to enc0 for packet filtering */
327	if (ipsec_filter(&m, PFIL_IN, ENC_IN|ENC_AFTER) != 0)
328		return;
329#endif
330
331	/*
332	 * Interface pointer stays the same; if no IPsec processing has
333	 * been done (or will be done), this will point to a normal
334	 * interface. Otherwise, it'll point to an enc interface, which
335	 * will allow a packet filter to distinguish between secure and
336	 * untrusted packets.
337	 */
338
339	switch (v >> 4) {
340#ifdef INET
341	case 4:
342		isr = NETISR_IP;
343		break;
344#endif
345#ifdef INET6
346	case 6:
347		isr = NETISR_IPV6;
348		break;
349#endif
350	default:
351		panic("%s: bogus ip version %u", __func__, v>>4);
352	}
353
354	if (netisr_queue(isr, m)) {	/* (0) on success. */
355		IPIPSTAT_INC(ipips_qfull);
356		DPRINTF(("%s: packet dropped because of full queue\n",
357			__func__));
358	}
359}
360
361int
362ipip_output(
363	struct mbuf *m,
364	struct ipsecrequest *isr,
365	struct mbuf **mp,
366	int skip,
367	int protoff
368)
369{
370	struct secasvar *sav;
371	u_int8_t tp, otos;
372	struct secasindex *saidx;
373	int error;
374#if defined(INET) || defined(INET6)
375	u_int8_t itos;
376#endif
377#ifdef INET
378	struct ip *ipo;
379#endif /* INET */
380#ifdef INET6
381	struct ip6_hdr *ip6, *ip6o;
382#endif /* INET6 */
383
384	sav = isr->sav;
385	IPSEC_ASSERT(sav != NULL, ("null SA"));
386	IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
387
388	/* XXX Deal with empty TDB source/destination addresses. */
389
390	m_copydata(m, 0, 1, &tp);
391	tp = (tp >> 4) & 0xff;  /* Get the IP version number. */
392
393	saidx = &sav->sah->saidx;
394	switch (saidx->dst.sa.sa_family) {
395#ifdef INET
396	case AF_INET:
397		if (saidx->src.sa.sa_family != AF_INET ||
398		    saidx->src.sin.sin_addr.s_addr == INADDR_ANY ||
399		    saidx->dst.sin.sin_addr.s_addr == INADDR_ANY) {
400			DPRINTF(("%s: unspecified tunnel endpoint "
401			    "address in SA %s/%08lx\n", __func__,
402			    ipsec_address(&saidx->dst),
403			    (u_long) ntohl(sav->spi)));
404			IPIPSTAT_INC(ipips_unspec);
405			error = EINVAL;
406			goto bad;
407		}
408
409		M_PREPEND(m, sizeof(struct ip), M_NOWAIT);
410		if (m == 0) {
411			DPRINTF(("%s: M_PREPEND failed\n", __func__));
412			IPIPSTAT_INC(ipips_hdrops);
413			error = ENOBUFS;
414			goto bad;
415		}
416
417		ipo = mtod(m, struct ip *);
418
419		ipo->ip_v = IPVERSION;
420		ipo->ip_hl = 5;
421		ipo->ip_len = htons(m->m_pkthdr.len);
422		ipo->ip_ttl = V_ip_defttl;
423		ipo->ip_sum = 0;
424		ipo->ip_src = saidx->src.sin.sin_addr;
425		ipo->ip_dst = saidx->dst.sin.sin_addr;
426
427		ipo->ip_id = ip_newid();
428
429		/* If the inner protocol is IP... */
430		switch (tp) {
431		case IPVERSION:
432			/* Save ECN notification */
433			m_copydata(m, sizeof(struct ip) +
434			    offsetof(struct ip, ip_tos),
435			    sizeof(u_int8_t), (caddr_t) &itos);
436
437			ipo->ip_p = IPPROTO_IPIP;
438
439			/*
440			 * We should be keeping tunnel soft-state and
441			 * send back ICMPs if needed.
442			 */
443			m_copydata(m, sizeof(struct ip) +
444			    offsetof(struct ip, ip_off),
445			    sizeof(u_int16_t), (caddr_t) &ipo->ip_off);
446			ipo->ip_off = ntohs(ipo->ip_off);
447			ipo->ip_off &= ~(IP_DF | IP_MF | IP_OFFMASK);
448			ipo->ip_off = htons(ipo->ip_off);
449			break;
450#ifdef INET6
451		case (IPV6_VERSION >> 4):
452		{
453			u_int32_t itos32;
454
455			/* Save ECN notification. */
456			m_copydata(m, sizeof(struct ip) +
457			    offsetof(struct ip6_hdr, ip6_flow),
458			    sizeof(u_int32_t), (caddr_t) &itos32);
459			itos = ntohl(itos32) >> 20;
460			ipo->ip_p = IPPROTO_IPV6;
461			ipo->ip_off = 0;
462			break;
463		}
464#endif /* INET6 */
465		default:
466			goto nofamily;
467		}
468
469		otos = 0;
470		ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
471		ipo->ip_tos = otos;
472		break;
473#endif /* INET */
474
475#ifdef INET6
476	case AF_INET6:
477		if (IN6_IS_ADDR_UNSPECIFIED(&saidx->dst.sin6.sin6_addr) ||
478		    saidx->src.sa.sa_family != AF_INET6 ||
479		    IN6_IS_ADDR_UNSPECIFIED(&saidx->src.sin6.sin6_addr)) {
480			DPRINTF(("%s: unspecified tunnel endpoint "
481			    "address in SA %s/%08lx\n", __func__,
482			    ipsec_address(&saidx->dst),
483			    (u_long) ntohl(sav->spi)));
484			IPIPSTAT_INC(ipips_unspec);
485			error = ENOBUFS;
486			goto bad;
487		}
488
489		/* scoped address handling */
490		ip6 = mtod(m, struct ip6_hdr *);
491		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
492			ip6->ip6_src.s6_addr16[1] = 0;
493		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
494			ip6->ip6_dst.s6_addr16[1] = 0;
495
496		M_PREPEND(m, sizeof(struct ip6_hdr), M_NOWAIT);
497		if (m == 0) {
498			DPRINTF(("%s: M_PREPEND failed\n", __func__));
499			IPIPSTAT_INC(ipips_hdrops);
500			error = ENOBUFS;
501			goto bad;
502		}
503
504		/* Initialize IPv6 header */
505		ip6o = mtod(m, struct ip6_hdr *);
506		ip6o->ip6_flow = 0;
507		ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
508		ip6o->ip6_vfc |= IPV6_VERSION;
509		ip6o->ip6_plen = htons(m->m_pkthdr.len);
510		ip6o->ip6_hlim = V_ip_defttl;
511		ip6o->ip6_dst = saidx->dst.sin6.sin6_addr;
512		ip6o->ip6_src = saidx->src.sin6.sin6_addr;
513
514		switch (tp) {
515#ifdef INET
516		case IPVERSION:
517			/* Save ECN notification */
518			m_copydata(m, sizeof(struct ip6_hdr) +
519			    offsetof(struct ip, ip_tos), sizeof(u_int8_t),
520			    (caddr_t) &itos);
521
522			/* This is really IPVERSION. */
523			ip6o->ip6_nxt = IPPROTO_IPIP;
524			break;
525#endif /* INET */
526		case (IPV6_VERSION >> 4):
527		{
528			u_int32_t itos32;
529
530			/* Save ECN notification. */
531			m_copydata(m, sizeof(struct ip6_hdr) +
532			    offsetof(struct ip6_hdr, ip6_flow),
533			    sizeof(u_int32_t), (caddr_t) &itos32);
534			itos = ntohl(itos32) >> 20;
535
536			ip6o->ip6_nxt = IPPROTO_IPV6;
537			break;
538		}
539		default:
540			goto nofamily;
541		}
542
543		otos = 0;
544		ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
545		ip6o->ip6_flow |= htonl((u_int32_t) otos << 20);
546		break;
547#endif /* INET6 */
548
549	default:
550nofamily:
551		DPRINTF(("%s: unsupported protocol family %u\n", __func__,
552		    saidx->dst.sa.sa_family));
553		IPIPSTAT_INC(ipips_family);
554		error = EAFNOSUPPORT;		/* XXX diffs from openbsd */
555		goto bad;
556	}
557
558	IPIPSTAT_INC(ipips_opackets);
559	*mp = m;
560
561#ifdef INET
562	if (saidx->dst.sa.sa_family == AF_INET) {
563#if 0
564		if (sav->tdb_xform->xf_type == XF_IP4)
565			tdb->tdb_cur_bytes +=
566			    m->m_pkthdr.len - sizeof(struct ip);
567#endif
568		IPIPSTAT_ADD(ipips_obytes,
569		    m->m_pkthdr.len - sizeof(struct ip));
570	}
571#endif /* INET */
572
573#ifdef INET6
574	if (saidx->dst.sa.sa_family == AF_INET6) {
575#if 0
576		if (sav->tdb_xform->xf_type == XF_IP4)
577			tdb->tdb_cur_bytes +=
578			    m->m_pkthdr.len - sizeof(struct ip6_hdr);
579#endif
580		IPIPSTAT_ADD(ipips_obytes,
581		    m->m_pkthdr.len - sizeof(struct ip6_hdr));
582	}
583#endif /* INET6 */
584
585	return 0;
586bad:
587	if (m)
588		m_freem(m);
589	*mp = NULL;
590	return (error);
591}
592
593#ifdef IPSEC
594#if defined(INET) || defined(INET6)
595static int
596ipe4_init(struct secasvar *sav, struct xformsw *xsp)
597{
598	sav->tdb_xform = xsp;
599	return 0;
600}
601
602static int
603ipe4_zeroize(struct secasvar *sav)
604{
605	sav->tdb_xform = NULL;
606	return 0;
607}
608
609static int
610ipe4_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
611{
612	/* This is a rather serious mistake, so no conditional printing. */
613	printf("%s: should never be called\n", __func__);
614	if (m)
615		m_freem(m);
616	return EOPNOTSUPP;
617}
618
619static struct xformsw ipe4_xformsw = {
620	XF_IP4,		0,		"IPv4 Simple Encapsulation",
621	ipe4_init,	ipe4_zeroize,	ipe4_input,	ipip_output,
622};
623
624extern struct domain inetdomain;
625#endif /* INET || INET6 */
626#ifdef INET
627static struct protosw ipe4_protosw = {
628	.pr_type =	SOCK_RAW,
629	.pr_domain =	&inetdomain,
630	.pr_protocol =	IPPROTO_IPV4,
631	.pr_flags =	PR_ATOMIC|PR_ADDR|PR_LASTHDR,
632	.pr_input =	ip4_input,
633	.pr_ctloutput =	rip_ctloutput,
634	.pr_usrreqs =	&rip_usrreqs
635};
636#endif /* INET */
637#if defined(INET6) && defined(INET)
638static struct ip6protosw ipe6_protosw = {
639	.pr_type =	SOCK_RAW,
640	.pr_domain =	&inetdomain,
641	.pr_protocol =	IPPROTO_IPV6,
642	.pr_flags =	PR_ATOMIC|PR_ADDR|PR_LASTHDR,
643	.pr_input =	ip4_input6,
644	.pr_ctloutput =	rip_ctloutput,
645	.pr_usrreqs =	&rip_usrreqs
646};
647#endif /* INET6 && INET */
648
649#ifdef INET
650/*
651 * Check the encapsulated packet to see if we want it
652 */
653static int
654ipe4_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
655{
656	/*
657	 * Only take packets coming from IPSEC tunnels; the rest
658	 * must be handled by the gif tunnel code.  Note that we
659	 * also return a minimum priority when we want the packet
660	 * so any explicit gif tunnels take precedence.
661	 */
662	return ((m->m_flags & M_IPSEC) != 0 ? 1 : 0);
663}
664#endif /* INET */
665
666static void
667ipe4_attach(void)
668{
669
670	xform_register(&ipe4_xformsw);
671	/* attach to encapsulation framework */
672	/* XXX save return cookie for detach on module remove */
673#ifdef INET
674	(void) encap_attach_func(AF_INET, -1,
675		ipe4_encapcheck, &ipe4_protosw, NULL);
676#endif
677#if defined(INET6) && defined(INET)
678	(void) encap_attach_func(AF_INET6, -1,
679		ipe4_encapcheck, (struct protosw *)&ipe6_protosw, NULL);
680#endif
681}
682SYSINIT(ipe4_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ipe4_attach, NULL);
683#endif	/* IPSEC */
684