1 /* $NetBSD: xform_ipip.c,v 1.23 2008/04/24 11:38:38 ad Exp $ */
2 /* $FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */
3 /* $OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */
6 * The authors of this code are John Ioannidis (ji@tla.org),
7 * Angelos D. Keromytis (kermit@csd.uch.gr) and
8 * Niels Provos (provos@physnet.uni-hamburg.de).
10 * The original version of this code was written by John Ioannidis
11 * for BSD/OS in Athens, Greece, in November 1995.
13 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
14 * by Angelos D. Keromytis.
16 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
19 * Additional features in 1999 by Angelos D. Keromytis.
21 * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
22 * Angelos D. Keromytis and Niels Provos.
23 * Copyright (c) 2001, Angelos D. Keromytis.
25 * Permission to use, copy, and modify this software with or without fee
26 * is hereby granted, provided that this entire notice is included in
27 * all copies of any software which is or includes a copy or
28 * modification of this software.
29 * You may use this code under the GNU public license if you so wish. Please
30 * contribute changes back to the authors under this freer than GPL license
31 * so that we may further the use of strong encryption without limitations to
34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.23 2008/04/24 11:38:38 ad Exp $");
45 * IP-inside-IP processing
49 #include "opt_inet6.h"
50 #include "opt_random_ip_id.h"
51 #endif /* __FreeBSD__ */
54 #include <sys/param.h>
55 #include <sys/systm.h>
57 #include <sys/socket.h>
58 #include <sys/kernel.h>
59 #include <sys/protosw.h>
60 #include <sys/sysctl.h>
63 #include <net/route.h>
64 #include <net/netisr.h>
66 #include <netinet/in.h>
67 #include <netinet/in_systm.h>
68 #include <netinet/in_var.h>
69 #include <netinet/ip.h>
70 #include <netinet/ip_ecn.h>
71 #include <netinet/ip_var.h>
72 #include <netinet/ip_encap.h>
74 #include <netinet/ipprotosw.h>
77 #include <netipsec/ipsec.h>
78 #include <netipsec/ipsec_private.h>
79 #include <netipsec/xform.h>
81 #include <netipsec/ipip_var.h>
84 #include <netinet/ip_mroute.h>
88 #include <netinet/ip6.h>
89 #include <netipsec/ipsec6.h>
91 # include <netinet6/ip6_ecn.h>
93 #include <netinet6/in6_var.h>
94 #include <netinet6/ip6protosw.h>
97 #include <netipsec/key.h>
98 #include <netipsec/key_debug.h>
99 #include <netipsec/ipsec_osdep.h>
101 #include <machine/stdarg.h>
104 typedef void pr_in_input_t (struct mbuf
*, int, int); /* XXX FIX THIS */
106 typedef void pr_in_input_t (struct mbuf
*m
, ...);
110 * We can control the acceptance of IP4 packets by altering the sysctl
111 * net.inet.ipip.allow value. Zero means drop them, all else is acceptance.
115 percpu_t
*ipipstat_percpu
;
118 SYSCTL_DECL(_net_inet_ipip
);
120 SYSCTL_INT(_net_inet_ipip
, OID_AUTO
,
121 ipip_allow
, CTLFLAG_RW
, &ipip_allow
, 0, "");
122 SYSCTL_STRUCT(_net_inet_ipip
, IPSECCTL_STATS
,
123 stats
, CTLFLAG_RD
, &ipipstat
, ipipstat
, "");
130 void ipe4_attach(void);
134 #define M_IPSEC (M_AUTHIPHDR|M_AUTHIPDGM|M_DECRYPTED)
136 static void _ipip_input(struct mbuf
*m
, int iphlen
, struct ifnet
*gifp
);
140 * Really only a wrapper for ipip_input(), for use with IPv6.
143 ip4_input6(struct mbuf
**m
, int *offp
, int proto
)
146 /* If we do not accept IP-in-IP explicitly, drop. */
147 if (!ipip_allow
&& ((*m
)->m_flags
& M_IPSEC
) == 0) {
148 DPRINTF(("ip4_input6: dropped due to policy\n"));
149 IPIP_STATINC(IPIP_STAT_PDROPS
);
154 _ipip_input(*m
, *offp
, NULL
);
161 * Really only a wrapper for ipip_input(), for use with IPv4.
164 ip4_input(struct mbuf
*m
, ...)
170 /* If we do not accept IP-in-IP explicitly, drop. */
171 if (!ipip_allow
&& (m
->m_flags
& M_IPSEC
) == 0) {
172 DPRINTF(("ip4_input: dropped due to policy\n"));
173 IPIP_STATINC(IPIP_STAT_PDROPS
);
179 iphlen
= va_arg(ap
, int);
182 _ipip_input(m
, iphlen
, NULL
);
187 * ipip_input gets called when we receive an IP{46} encapsulated packet,
188 * either because we got it at a real interface, or because AH or ESP
189 * were being used in tunnel mode (in which case the rcvif element will
190 * contain the address of the encX interface associated with the tunnel.
194 _ipip_input(struct mbuf
*m
, int iphlen
, struct ifnet
*gifp
)
196 register struct sockaddr_in
*sin
;
197 register struct ifnet
*ifp
;
198 register struct ifaddr
*ifa
;
199 struct ifqueue
*ifq
= NULL
;
202 register struct sockaddr_in6
*sin6
;
203 struct ip6_hdr
*ip6
= NULL
;
212 IPIP_STATINC(IPIP_STAT_IPACKETS
);
214 m_copydata(m
, 0, 1, &v
);
219 hlen
= sizeof(struct ip
);
224 hlen
= sizeof(struct ip6_hdr
);
228 DPRINTF(("_ipip_input: bad protocol version 0x%x (%u) "
229 "for outer header\n", v
, v
>>4));
230 IPIP_STATINC(IPIP_STAT_FAMILY
);
232 return /* EAFNOSUPPORT */;
235 /* Bring the IP header in the first mbuf, if not there already */
236 if (m
->m_len
< hlen
) {
237 if ((m
= m_pullup(m
, hlen
)) == NULL
) {
238 DPRINTF(("ipip_input: m_pullup (1) failed\n"));
239 IPIP_STATINC(IPIP_STAT_HDROPS
);
244 ipo
= mtod(m
, struct ip
*);
247 if (ipo
->ip_v
== IPVERSION
&& ipo
->ip_p
== IPPROTO_IPV4
) {
248 if (IN_MULTICAST(((struct ip
*)((char *) ipo
+ iphlen
))->ip_dst
.s_addr
)) {
249 ipip_mroute_input (m
, iphlen
);
253 #endif /* MROUTING */
255 /* Keep outer ecn field. */
264 otos
= (ntohl(mtod(m
, struct ip6_hdr
*)->ip6_flow
) >> 20) & 0xff;
268 panic("ipip_input: unknown ip version %u (outer)", v
>>4);
271 /* Remove outer IP header */
275 if (m
->m_pkthdr
.len
< sizeof(struct ip
)) {
276 IPIP_STATINC(IPIP_STAT_HDROPS
);
281 m_copydata(m
, 0, 1, &v
);
286 hlen
= sizeof(struct ip
);
292 hlen
= sizeof(struct ip6_hdr
);
296 DPRINTF(("_ipip_input: bad protocol version 0x%x (%u) "
297 "for inner header\n", v
, v
>>4));
298 IPIP_STATINC(IPIP_STAT_FAMILY
);
300 return; /* EAFNOSUPPORT */
304 * Bring the inner IP header in the first mbuf, if not there already.
306 if (m
->m_len
< hlen
) {
307 if ((m
= m_pullup(m
, hlen
)) == NULL
) {
308 DPRINTF(("ipip_input: m_pullup (2) failed\n"));
309 IPIP_STATINC(IPIP_STAT_HDROPS
);
315 * RFC 1853 specifies that the inner TTL should not be touched on
316 * decapsulation. There's no reason this comment should be here, but
317 * this is as good as any a position.
320 /* Some sanity checks in the inner IP header */
324 ipo
= mtod(m
, struct ip
*);
326 ip_ecn_egress(ip4_ipsec_ecn
, &otos
, &ipo
->ip_tos
);
331 ip6
= (struct ip6_hdr
*) ipo
;
333 itos
= (ntohl(ip6
->ip6_flow
) >> 20) & 0xff;
334 ip_ecn_egress(ip6_ipsec_ecn
, &otos
, &itos
);
335 ip6
->ip6_flow
&= ~htonl(0xff << 20);
336 ip6
->ip6_flow
|= htonl((u_int32_t
) itos
<< 20);
340 panic("ipip_input: unknown ip version %u (inner)", v
>>4);
343 /* Check for local address spoofing. */
344 if ((m
->m_pkthdr
.rcvif
== NULL
||
345 !(m
->m_pkthdr
.rcvif
->if_flags
& IFF_LOOPBACK
)) &&
348 IFADDR_FOREACH(ifa
, ifp
) {
351 if (ifa
->ifa_addr
->sa_family
!=
355 sin
= (struct sockaddr_in
*) ifa
->ifa_addr
;
357 if (sin
->sin_addr
.s_addr
==
358 ipo
->ip_src
.s_addr
) {
359 IPIP_STATINC(IPIP_STAT_SPOOF
);
368 if (ifa
->ifa_addr
->sa_family
!=
372 sin6
= (struct sockaddr_in6
*) ifa
->ifa_addr
;
374 if (IN6_ARE_ADDR_EQUAL(&sin6
->sin6_addr
, &ip6
->ip6_src
)) {
375 IPIP_STATINC(IPIP_STAT_SPOOF
);
387 IPIP_STATADD(IPIP_STAT_IBYTES
, m
->m_pkthdr
.len
- iphlen
);
390 * Interface pointer stays the same; if no IPsec processing has
391 * been done (or will be done), this will point to a normal
392 * interface. Otherwise, it'll point to an enc interface, which
393 * will allow a packet filter to distinguish between secure and
411 panic("ipip_input: should never reach here");
414 if (!IF_HANDOFF(ifq
, m
, NULL
)) {
415 IPIP_STATINC(IPIP_STAT_QFULL
);
417 DPRINTF(("ipip_input: packet dropped because of full queue\n"));
426 struct ipsecrequest
*isr
,
432 struct secasvar
*sav
;
434 struct secasindex
*saidx
;
441 struct ip6_hdr
*ip6
, *ip6o
;
444 IPSEC_SPLASSERT_SOFTNET("ipip_output");
447 IPSEC_ASSERT(sav
!= NULL
, ("ipip_output: null SA"));
448 IPSEC_ASSERT(sav
->sah
!= NULL
, ("ipip_output: null SAH"));
450 /* XXX Deal with empty TDB source/destination addresses. */
452 m_copydata(m
, 0, 1, &tp
);
453 tp
= (tp
>> 4) & 0xff; /* Get the IP version number. */
455 saidx
= &sav
->sah
->saidx
;
456 switch (saidx
->dst
.sa
.sa_family
) {
459 if (saidx
->src
.sa
.sa_family
!= AF_INET
||
460 saidx
->src
.sin
.sin_addr
.s_addr
== INADDR_ANY
||
461 saidx
->dst
.sin
.sin_addr
.s_addr
== INADDR_ANY
) {
462 DPRINTF(("ipip_output: unspecified tunnel endpoint "
463 "address in SA %s/%08lx\n",
464 ipsec_address(&saidx
->dst
),
465 (u_long
) ntohl(sav
->spi
)));
466 IPIP_STATINC(IPIP_STAT_UNSPEC
);
471 M_PREPEND(m
, sizeof(struct ip
), M_DONTWAIT
);
473 DPRINTF(("ipip_output: M_PREPEND failed\n"));
474 IPIP_STATINC(IPIP_STAT_HDROPS
);
479 ipo
= mtod(m
, struct ip
*);
481 ipo
->ip_v
= IPVERSION
;
483 ipo
->ip_len
= htons(m
->m_pkthdr
.len
);
484 ipo
->ip_ttl
= ip_defttl
;
486 ipo
->ip_src
= saidx
->src
.sin
.sin_addr
;
487 ipo
->ip_dst
= saidx
->dst
.sin
.sin_addr
;
489 #if defined(__NetBSD__)
490 ipo
->ip_id
= ip_newid(NULL
);
491 #elif defined(RANDOM_IP_ID)
492 ipo
->ip_id
= ip_randomid();
494 ipo
->ip_id
= htons(ip_id
++);
497 /* If the inner protocol is IP... */
498 if (tp
== IPVERSION
) {
499 /* Save ECN notification */
500 m_copydata(m
, sizeof(struct ip
) +
501 offsetof(struct ip
, ip_tos
),
502 sizeof(u_int8_t
), &itos
);
504 ipo
->ip_p
= IPPROTO_IPIP
;
507 * We should be keeping tunnel soft-state and
508 * send back ICMPs if needed.
510 m_copydata(m
, sizeof(struct ip
) +
511 offsetof(struct ip
, ip_off
),
512 sizeof(u_int16_t
), &ipo
->ip_off
);
513 ipo
->ip_off
&= ~ IP_OFF_CONVERT(IP_DF
| IP_MF
| IP_OFFMASK
);
516 else if (tp
== (IPV6_VERSION
>> 4)) {
519 /* Save ECN notification. */
520 m_copydata(m
, sizeof(struct ip
) +
521 offsetof(struct ip6_hdr
, ip6_flow
),
522 sizeof(u_int32_t
), &itos32
);
523 itos
= ntohl(itos32
) >> 20;
524 ipo
->ip_p
= IPPROTO_IPV6
;
533 ip_ecn_ingress(ECN_ALLOWED
, &otos
, &itos
);
540 if (IN6_IS_ADDR_UNSPECIFIED(&saidx
->dst
.sin6
.sin6_addr
) ||
541 saidx
->src
.sa
.sa_family
!= AF_INET6
||
542 IN6_IS_ADDR_UNSPECIFIED(&saidx
->src
.sin6
.sin6_addr
)) {
543 DPRINTF(("ipip_output: unspecified tunnel endpoint "
544 "address in SA %s/%08lx\n",
545 ipsec_address(&saidx
->dst
),
546 (u_long
) ntohl(sav
->spi
)));
547 IPIP_STATINC(IPIP_STAT_UNSPEC
);
552 /* scoped address handling */
553 ip6
= mtod(m
, struct ip6_hdr
*);
554 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
))
555 ip6
->ip6_src
.s6_addr16
[1] = 0;
556 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
))
557 ip6
->ip6_dst
.s6_addr16
[1] = 0;
559 M_PREPEND(m
, sizeof(struct ip6_hdr
), M_DONTWAIT
);
561 DPRINTF(("ipip_output: M_PREPEND failed\n"));
562 IPIP_STATINC(IPIP_STAT_HDROPS
);
567 /* Initialize IPv6 header */
568 ip6o
= mtod(m
, struct ip6_hdr
*);
570 ip6o
->ip6_vfc
&= ~IPV6_VERSION_MASK
;
571 ip6o
->ip6_vfc
|= IPV6_VERSION
;
572 ip6o
->ip6_plen
= htons(m
->m_pkthdr
.len
);
573 ip6o
->ip6_hlim
= ip_defttl
;
574 ip6o
->ip6_dst
= saidx
->dst
.sin6
.sin6_addr
;
575 ip6o
->ip6_src
= saidx
->src
.sin6
.sin6_addr
;
578 if (tp
== IPVERSION
) {
579 /* Save ECN notification */
580 m_copydata(m
, sizeof(struct ip6_hdr
) +
581 offsetof(struct ip
, ip_tos
), sizeof(u_int8_t
),
584 /* This is really IPVERSION. */
585 ip6o
->ip6_nxt
= IPPROTO_IPIP
;
588 if (tp
== (IPV6_VERSION
>> 4)) {
591 /* Save ECN notification. */
592 m_copydata(m
, sizeof(struct ip6_hdr
) +
593 offsetof(struct ip6_hdr
, ip6_flow
),
594 sizeof(u_int32_t
), &itos32
);
595 itos
= ntohl(itos32
) >> 20;
597 ip6o
->ip6_nxt
= IPPROTO_IPV6
;
603 ip_ecn_ingress(ECN_ALLOWED
, &otos
, &itos
);
604 ip6o
->ip6_flow
|= htonl((u_int32_t
) otos
<< 20);
610 DPRINTF(("ipip_output: unsupported protocol family %u\n",
611 saidx
->dst
.sa
.sa_family
));
612 IPIP_STATINC(IPIP_STAT_FAMILY
);
613 error
= EAFNOSUPPORT
; /* XXX diffs from openbsd */
617 IPIP_STATINC(IPIP_STAT_OPACKETS
);
621 if (saidx
->dst
.sa
.sa_family
== AF_INET
) {
623 if (sav
->tdb_xform
->xf_type
== XF_IP4
)
624 tdb
->tdb_cur_bytes
+=
625 m
->m_pkthdr
.len
- sizeof(struct ip
);
627 IPIP_STATADD(IPIP_STAT_OBYTES
,
628 m
->m_pkthdr
.len
- sizeof(struct ip
));
633 if (saidx
->dst
.sa
.sa_family
== AF_INET6
) {
635 if (sav
->tdb_xform
->xf_type
== XF_IP4
)
636 tdb
->tdb_cur_bytes
+=
637 m
->m_pkthdr
.len
- sizeof(struct ip6_hdr
);
639 IPIP_STATADD(IPIP_STAT_IBYTES
,
640 m
->m_pkthdr
.len
- sizeof(struct ip6_hdr
));
654 ipe4_init(struct secasvar
*sav
, struct xformsw
*xsp
)
656 sav
->tdb_xform
= xsp
;
661 ipe4_zeroize(struct secasvar
*sav
)
663 sav
->tdb_xform
= NULL
;
670 struct secasvar
*sav
,
675 /* This is a rather serious mistake, so no conditional printing. */
676 printf("ipe4_input: should never be called\n");
682 static struct xformsw ipe4_xformsw
= {
683 XF_IP4
, 0, "IPv4 Simple Encapsulation",
684 ipe4_init
, ipe4_zeroize
, ipe4_input
, ipip_output
,
689 PR_WRAP_CTLOUTPUT(rip_ctloutput
)
690 PR_WRAP_USRREQ(rip_usrreq
)
691 #define rip_ctloutput rip_ctloutput_wrapper
692 #define rip_usrreq rip_usrreq_wrapper
694 extern struct domain inetdomain
;
695 static struct ipprotosw ipe4_protosw
= {
697 .pr_domain
= &inetdomain
,
698 .pr_protocol
= IPPROTO_IPV4
,
699 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_LASTHDR
,
700 .pr_input
= ip4_input
,
703 .pr_ctloutput
= rip_ctloutput
,
704 .pr_usrreq
= rip_usrreq
,
712 PR_WRAP_CTLOUTPUT(rip6_ctloutput
)
713 PR_WRAP_USRREQ(rip6_usrreq
)
714 #define rip6_ctloutput rip6_ctloutput_wrapper
715 #define rip6_usrreq rip6_usrreq_wrapper
717 extern struct domain inet6domain
;
718 static struct ip6protosw ipe4_protosw6
= {
720 .pr_domain
= &inet6domain
,
721 .pr_protocol
= IPPROTO_IPV6
,
722 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_LASTHDR
,
723 .pr_input
= ip4_input6
,
726 .pr_ctloutput
= rip6_ctloutput
,
727 .pr_usrreq
= rip6_usrreq
,
735 #endif /* FAST_IPSEC */
738 * Check the encapsulated packet to see if we want it
741 ipe4_encapcheck(struct mbuf
*m
,
748 * Only take packets coming from IPSEC tunnels; the rest
749 * must be handled by the gif tunnel code. Note that we
750 * also return a minimum priority when we want the packet
751 * so any explicit gif tunnels take precedence.
753 return ((m
->m_flags
& M_IPSEC
) != 0 ? 1 : 0);
760 ipipstat_percpu
= percpu_alloc(sizeof(uint64_t) * IPIP_NSTATS
);
762 xform_register(&ipe4_xformsw
);
763 /* attach to encapsulation framework */
764 /* XXX save return cookie for detach on module remove */
766 (void) encap_attach_func(AF_INET
, -1,
767 ipe4_encapcheck
, (struct protosw
*) &ipe4_protosw
, NULL
);
770 (void) encap_attach_func(AF_INET6
, -1,
771 ipe4_encapcheck
, (struct protosw
*) &ipe4_protosw6
, NULL
);
776 SYSINIT(ipe4_xform_init
, SI_SUB_PROTO_DOMAIN
, SI_ORDER_MIDDLE
, ipe4_attach
, NULL
);