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