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