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