1 /* $NetBSD: ipsec_output.c,v 1.65 2017/11/17 07:37:12 ozaki-r Exp $ */ 2 3 /*- 4 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD: /repoman/r/ncvs/src/sys/netipsec/ipsec_output.c,v 1.3.2.2 2003/03/28 20:32:53 sam Exp $ 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.65 2017/11/17 07:37:12 ozaki-r Exp $"); 33 34 /* 35 * IPsec output processing. 36 */ 37 #if defined(_KERNEL_OPT) 38 #include "opt_inet.h" 39 #include "opt_net_mpsafe.h" 40 #endif 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/mbuf.h> 45 #include <sys/domain.h> 46 #include <sys/protosw.h> 47 #include <sys/socket.h> 48 #include <sys/errno.h> 49 #include <sys/syslog.h> 50 51 #include <net/if.h> 52 #include <net/route.h> 53 54 #include <netinet/in.h> 55 #include <netinet/in_systm.h> 56 #include <netinet/ip.h> 57 #include <netinet/ip_var.h> 58 #include <netinet/in_var.h> 59 #include <netinet/ip_ecn.h> 60 61 #include <netinet/ip6.h> 62 #ifdef INET6 63 #include <netinet6/ip6_var.h> 64 #endif 65 #include <netinet/in_pcb.h> 66 #ifdef INET6 67 #include <netinet/icmp6.h> 68 #endif 69 #include <netinet/udp.h> 70 71 #include <netipsec/ipsec.h> 72 #include <netipsec/ipsec_var.h> 73 #include <netipsec/ipsec_private.h> 74 #ifdef INET6 75 #include <netipsec/ipsec6.h> 76 #endif 77 #include <netipsec/ah_var.h> 78 #include <netipsec/esp_var.h> 79 #include <netipsec/ipcomp_var.h> 80 81 #include <netipsec/xform.h> 82 83 #include <netipsec/key.h> 84 #include <netipsec/keydb.h> 85 #include <netipsec/key_debug.h> 86 87 #include <net/net_osdep.h> /* ovbcopy() in ipsec6_encapsulate() */ 88 89 static percpu_t *ipsec_rtcache_percpu __cacheline_aligned; 90 91 /* 92 * Add a IPSEC_OUT_DONE tag to mark that we have finished the ipsec processing 93 * It will be used by ip{,6}_output to check if we have already or not 94 * processed this packet. 95 */ 96 static int 97 ipsec_register_done(struct mbuf *m, int * error) 98 { 99 struct m_tag *mtag; 100 101 mtag = m_tag_get(PACKET_TAG_IPSEC_OUT_DONE, 0, M_NOWAIT); 102 if (mtag == NULL) { 103 IPSECLOG(LOG_DEBUG, "could not get packet tag\n"); 104 *error = ENOMEM; 105 return -1; 106 } 107 108 m_tag_prepend(m, mtag); 109 return 0; 110 } 111 112 static int 113 ipsec_reinject_ipstack(struct mbuf *m, int af) 114 { 115 int rv = -1; 116 struct route *ro; 117 118 KASSERT(af == AF_INET || af == AF_INET6); 119 120 KERNEL_LOCK_UNLESS_NET_MPSAFE(); 121 ro = percpu_getref(ipsec_rtcache_percpu); 122 switch (af) { 123 #ifdef INET 124 case AF_INET: 125 rv = ip_output(m, NULL, ro, IP_RAWOUTPUT|IP_NOIPNEWID, 126 NULL, NULL); 127 break; 128 #endif 129 #ifdef INET6 130 case AF_INET6: 131 /* 132 * We don't need massage, IPv6 header fields are always in 133 * net endian. 134 */ 135 rv = ip6_output(m, NULL, ro, 0, NULL, NULL, NULL); 136 break; 137 #endif 138 } 139 percpu_putref(ipsec_rtcache_percpu); 140 KERNEL_UNLOCK_UNLESS_NET_MPSAFE(); 141 142 return rv; 143 } 144 145 int 146 ipsec_process_done(struct mbuf *m, const struct ipsecrequest *isr, 147 struct secasvar *sav) 148 { 149 struct secasindex *saidx; 150 int error; 151 #ifdef INET 152 struct ip * ip; 153 #endif /* INET */ 154 #ifdef INET6 155 struct ip6_hdr * ip6; 156 #endif /* INET6 */ 157 struct mbuf * mo; 158 struct udphdr *udp = NULL; 159 uint64_t * data = NULL; 160 int hlen, roff; 161 162 IPSEC_SPLASSERT_SOFTNET("ipsec_process_done"); 163 164 KASSERT(m != NULL); 165 KASSERT(isr != NULL); 166 KASSERT(sav != NULL); 167 168 saidx = &sav->sah->saidx; 169 170 if(sav->natt_type != 0) { 171 ip = mtod(m, struct ip *); 172 173 hlen = sizeof(struct udphdr); 174 if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) 175 hlen += sizeof(uint64_t); 176 177 mo = m_makespace(m, sizeof(struct ip), hlen, &roff); 178 if (mo == NULL) { 179 char buf[IPSEC_ADDRSTRLEN]; 180 IPSECLOG(LOG_DEBUG, 181 "failed to inject %u byte UDP for SA %s/%08lx\n", 182 hlen, ipsec_address(&saidx->dst, buf, sizeof(buf)), 183 (u_long) ntohl(sav->spi)); 184 error = ENOBUFS; 185 goto bad; 186 } 187 188 udp = (struct udphdr*) (mtod(mo, char*) + roff); 189 data = (uint64_t*) (udp + 1); 190 191 if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) 192 *data = 0; /* NON-IKE Marker */ 193 194 if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) 195 udp->uh_sport = htons(UDP_ENCAP_ESPINUDP_PORT); 196 else 197 udp->uh_sport = key_portfromsaddr(&saidx->src); 198 199 udp->uh_dport = key_portfromsaddr(&saidx->dst); 200 udp->uh_sum = 0; 201 udp->uh_ulen = htons(m->m_pkthdr.len - (ip->ip_hl << 2)); 202 } 203 204 switch (saidx->dst.sa.sa_family) { 205 #ifdef INET 206 case AF_INET: 207 /* Fix the header length, for AH processing. */ 208 ip = mtod(m, struct ip *); 209 ip->ip_len = htons(m->m_pkthdr.len); 210 if (sav->natt_type != 0) 211 ip->ip_p = IPPROTO_UDP; 212 break; 213 #endif /* INET */ 214 #ifdef INET6 215 case AF_INET6: 216 /* Fix the header length, for AH processing. */ 217 if (m->m_pkthdr.len < sizeof (struct ip6_hdr)) { 218 error = ENXIO; 219 goto bad; 220 } 221 if (m->m_pkthdr.len - sizeof (struct ip6_hdr) > IPV6_MAXPACKET) { 222 /* No jumbogram support. */ 223 error = ENXIO; /*?*/ 224 goto bad; 225 } 226 ip6 = mtod(m, struct ip6_hdr *); 227 ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); 228 if (sav->natt_type != 0) 229 ip6->ip6_nxt = IPPROTO_UDP; 230 break; 231 #endif /* INET6 */ 232 default: 233 IPSECLOG(LOG_DEBUG, "unknown protocol family %u\n", 234 saidx->dst.sa.sa_family); 235 error = ENXIO; 236 goto bad; 237 } 238 239 key_sa_recordxfer(sav, m); 240 241 /* 242 * If there's another (bundled) SA to apply, do so. 243 * Note that this puts a burden on the kernel stack size. 244 * If this is a problem we'll need to introduce a queue 245 * to set the packet on so we can unwind the stack before 246 * doing further processing. 247 */ 248 if (isr->next) { 249 IPSEC_STATINC(IPSEC_STAT_OUT_BUNDLESA); 250 switch ( saidx->dst.sa.sa_family ) { 251 #ifdef INET 252 case AF_INET: 253 return ipsec4_process_packet(m, isr->next, NULL); 254 #endif /* INET */ 255 #ifdef INET6 256 case AF_INET6: 257 return ipsec6_process_packet(m,isr->next); 258 #endif /* INET6 */ 259 default : 260 IPSECLOG(LOG_DEBUG, "unknown protocol family %u\n", 261 saidx->dst.sa.sa_family); 262 error = ENXIO; 263 goto bad; 264 } 265 } 266 267 /* 268 * We're done with IPsec processing, 269 * mark that we have already processed the packet 270 * transmit it packet using the appropriate network protocol (IP or IPv6). 271 */ 272 273 if (ipsec_register_done(m, &error) < 0) 274 goto bad; 275 276 return ipsec_reinject_ipstack(m, saidx->dst.sa.sa_family); 277 bad: 278 m_freem(m); 279 return (error); 280 } 281 282 static void 283 ipsec_fill_saidx_bymbuf(struct secasindex *saidx, const struct mbuf *m, 284 const int af) 285 { 286 287 if (af == AF_INET) { 288 struct sockaddr_in *sin; 289 struct ip *ip = mtod(m, struct ip *); 290 291 if (saidx->src.sa.sa_len == 0) { 292 sin = &saidx->src.sin; 293 sin->sin_len = sizeof(*sin); 294 sin->sin_family = AF_INET; 295 sin->sin_port = IPSEC_PORT_ANY; 296 sin->sin_addr = ip->ip_src; 297 } 298 if (saidx->dst.sa.sa_len == 0) { 299 sin = &saidx->dst.sin; 300 sin->sin_len = sizeof(*sin); 301 sin->sin_family = AF_INET; 302 sin->sin_port = IPSEC_PORT_ANY; 303 sin->sin_addr = ip->ip_dst; 304 } 305 } else { 306 struct sockaddr_in6 *sin6; 307 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 308 309 if (saidx->src.sin6.sin6_len == 0) { 310 sin6 = (struct sockaddr_in6 *)&saidx->src; 311 sin6->sin6_len = sizeof(*sin6); 312 sin6->sin6_family = AF_INET6; 313 sin6->sin6_port = IPSEC_PORT_ANY; 314 sin6->sin6_addr = ip6->ip6_src; 315 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) { 316 /* fix scope id for comparing SPD */ 317 sin6->sin6_addr.s6_addr16[1] = 0; 318 sin6->sin6_scope_id = 319 ntohs(ip6->ip6_src.s6_addr16[1]); 320 } 321 } 322 if (saidx->dst.sin6.sin6_len == 0) { 323 sin6 = (struct sockaddr_in6 *)&saidx->dst; 324 sin6->sin6_len = sizeof(*sin6); 325 sin6->sin6_family = AF_INET6; 326 sin6->sin6_port = IPSEC_PORT_ANY; 327 sin6->sin6_addr = ip6->ip6_dst; 328 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) { 329 /* fix scope id for comparing SPD */ 330 sin6->sin6_addr.s6_addr16[1] = 0; 331 sin6->sin6_scope_id = 332 ntohs(ip6->ip6_dst.s6_addr16[1]); 333 } 334 } 335 } 336 } 337 338 struct secasvar * 339 ipsec_lookup_sa(const struct ipsecrequest *isr, const struct mbuf *m) 340 { 341 struct secasindex saidx; 342 343 saidx = isr->saidx; 344 if (isr->saidx.mode == IPSEC_MODE_TRANSPORT) { 345 /* Fillin unspecified SA peers only for transport mode */ 346 ipsec_fill_saidx_bymbuf(&saidx, m, isr->saidx.dst.sa.sa_family); 347 } 348 349 return key_lookup_sa_bysaidx(&saidx); 350 } 351 352 /* 353 * ipsec_nextisr can return : 354 * - isr == NULL and error != 0 => something is bad : the packet must be 355 * discarded 356 * - isr == NULL and error == 0 => no more rules to apply, ipsec processing 357 * is done, reinject it in ip stack 358 * - isr != NULL (error == 0) => we need to apply one rule to the packet 359 */ 360 static const struct ipsecrequest * 361 ipsec_nextisr( 362 struct mbuf *m, 363 const struct ipsecrequest *isr, 364 int af, 365 int *error, 366 struct secasvar **ret 367 ) 368 { 369 #define IPSEC_OSTAT(type) \ 370 do { \ 371 switch (isr->saidx.proto) { \ 372 case IPPROTO_ESP: \ 373 ESP_STATINC(ESP_STAT_ ## type); \ 374 break; \ 375 case IPPROTO_AH: \ 376 AH_STATINC(AH_STAT_ ## type); \ 377 break; \ 378 default: \ 379 IPCOMP_STATINC(IPCOMP_STAT_ ## type); \ 380 break; \ 381 } \ 382 } while (/*CONSTCOND*/0) 383 384 struct secasvar *sav = NULL; 385 struct secasindex saidx; 386 387 IPSEC_SPLASSERT_SOFTNET("ipsec_nextisr"); 388 KASSERTMSG(af == AF_INET || af == AF_INET6, 389 "invalid address family %u", af); 390 again: 391 /* 392 * Craft SA index to search for proper SA. Note that 393 * we only fillin unspecified SA peers for transport 394 * mode; for tunnel mode they must already be filled in. 395 */ 396 saidx = isr->saidx; 397 if (isr->saidx.mode == IPSEC_MODE_TRANSPORT) { 398 /* Fillin unspecified SA peers only for transport mode */ 399 ipsec_fill_saidx_bymbuf(&saidx, m, af); 400 } 401 402 /* 403 * Lookup SA and validate it. 404 */ 405 *error = key_checkrequest(isr, &saidx, &sav); 406 if (*error != 0) { 407 /* 408 * IPsec processing is required, but no SA found. 409 * I assume that key_acquire() had been called 410 * to get/establish the SA. Here I discard 411 * this packet because it is responsibility for 412 * upper layer to retransmit the packet. 413 */ 414 IPSEC_STATINC(IPSEC_STAT_OUT_NOSA); 415 goto bad; 416 } 417 /* sav may be NULL here if we have an USE rule */ 418 if (sav == NULL) { 419 KASSERTMSG(ipsec_get_reqlevel(isr) == IPSEC_LEVEL_USE, 420 "no SA found, but required; level %u", 421 ipsec_get_reqlevel(isr)); 422 isr = isr->next; 423 /* 424 * No more rules to apply, return NULL isr and no error 425 * It can happen when the last rules are USE rules 426 * */ 427 if (isr == NULL) { 428 *ret = NULL; 429 *error = 0; 430 return isr; 431 } 432 goto again; 433 } 434 435 /* 436 * Check system global policy controls. 437 */ 438 if ((isr->saidx.proto == IPPROTO_ESP && !esp_enable) || 439 (isr->saidx.proto == IPPROTO_AH && !ah_enable) || 440 (isr->saidx.proto == IPPROTO_IPCOMP && !ipcomp_enable)) { 441 IPSECLOG(LOG_DEBUG, "IPsec outbound packet dropped due" 442 " to policy (check your sysctls)\n"); 443 IPSEC_OSTAT(PDROPS); 444 *error = EHOSTUNREACH; 445 KEY_SA_UNREF(&sav); 446 goto bad; 447 } 448 449 /* 450 * Sanity check the SA contents for the caller 451 * before they invoke the xform output method. 452 */ 453 KASSERT(sav->tdb_xform != NULL); 454 *ret = sav; 455 return isr; 456 bad: 457 KASSERTMSG(*error != 0, "error return w/ no error code"); 458 return NULL; 459 #undef IPSEC_OSTAT 460 } 461 462 #ifdef INET 463 /* 464 * IPsec output logic for IPv4. 465 */ 466 int 467 ipsec4_process_packet(struct mbuf *m, const struct ipsecrequest *isr, 468 u_long *mtu) 469 { 470 struct secasvar *sav = NULL; 471 struct ip *ip; 472 int s, error, i, off; 473 union sockaddr_union *dst; 474 int setdf; 475 476 KASSERT(m != NULL); 477 KASSERT(isr != NULL); 478 479 s = splsoftnet(); /* insure SA contents don't change */ 480 481 isr = ipsec_nextisr(m, isr, AF_INET, &error, &sav); 482 if (isr == NULL) { 483 if (error != 0) { 484 goto bad; 485 } else { 486 if (ipsec_register_done(m, &error) < 0) 487 goto bad; 488 489 splx(s); 490 return ipsec_reinject_ipstack(m, AF_INET); 491 } 492 } 493 494 KASSERT(sav != NULL); 495 /* 496 * Check if we need to handle NAT-T fragmentation. 497 */ 498 if (isr == isr->sp->req) { /* Check only if called from ipsec4_output */ 499 KASSERT(mtu != NULL); 500 ip = mtod(m, struct ip *); 501 if (!(sav->natt_type & 502 (UDP_ENCAP_ESPINUDP|UDP_ENCAP_ESPINUDP_NON_IKE))) { 503 goto noneed; 504 } 505 if (ntohs(ip->ip_len) <= sav->esp_frag) 506 goto noneed; 507 *mtu = sav->esp_frag; 508 KEY_SA_UNREF(&sav); 509 splx(s); 510 return 0; 511 } 512 noneed: 513 dst = &sav->sah->saidx.dst; 514 515 /* 516 * Collect IP_DF state from the outer header. 517 */ 518 if (dst->sa.sa_family == AF_INET) { 519 if (m->m_len < sizeof (struct ip) && 520 (m = m_pullup(m, sizeof (struct ip))) == NULL) { 521 error = ENOBUFS; 522 goto unrefsav; 523 } 524 ip = mtod(m, struct ip *); 525 /* Honor system-wide control of how to handle IP_DF */ 526 switch (ip4_ipsec_dfbit) { 527 case 0: /* clear in outer header */ 528 case 1: /* set in outer header */ 529 setdf = ip4_ipsec_dfbit; 530 break; 531 default: /* propagate to outer header */ 532 setdf = ip->ip_off; 533 setdf = ntohs(setdf); 534 setdf = htons(setdf & IP_DF); 535 break; 536 } 537 } else { 538 ip = NULL; /* keep compiler happy */ 539 setdf = 0; 540 } 541 /* Do the appropriate encapsulation, if necessary */ 542 if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */ 543 dst->sa.sa_family != AF_INET || /* PF mismatch */ 544 #if 0 545 (sav->flags & SADB_X_SAFLAGS_TUNNEL) || /* Tunnel requ'd */ 546 sav->tdb_xform->xf_type == XF_IP4 || /* ditto */ 547 #endif 548 (dst->sa.sa_family == AF_INET && /* Proxy */ 549 dst->sin.sin_addr.s_addr != INADDR_ANY && 550 dst->sin.sin_addr.s_addr != ip->ip_dst.s_addr)) { 551 struct mbuf *mp; 552 553 /* Fix IPv4 header checksum and length */ 554 if (m->m_len < sizeof (struct ip) && 555 (m = m_pullup(m, sizeof (struct ip))) == NULL) { 556 error = ENOBUFS; 557 goto unrefsav; 558 } 559 ip = mtod(m, struct ip *); 560 ip->ip_len = htons(m->m_pkthdr.len); 561 ip->ip_sum = 0; 562 ip->ip_sum = in_cksum(m, ip->ip_hl << 2); 563 564 /* Encapsulate the packet */ 565 error = ipip_output(m, isr, sav, &mp, 0, 0); 566 if (mp == NULL && !error) { 567 /* Should never happen. */ 568 IPSECLOG(LOG_DEBUG, 569 "ipip_output returns no mbuf and no error!"); 570 error = EFAULT; 571 } 572 if (error) { 573 if (mp) { 574 /* XXX: Should never happen! */ 575 m_freem(mp); 576 } 577 m = NULL; /* ipip_output() already freed it */ 578 goto unrefsav; 579 } 580 m = mp, mp = NULL; 581 /* 582 * ipip_output clears IP_DF in the new header. If 583 * we need to propagate IP_DF from the outer header, 584 * then we have to do it here. 585 * 586 * XXX shouldn't assume what ipip_output does. 587 */ 588 if (dst->sa.sa_family == AF_INET && setdf) { 589 if (m->m_len < sizeof (struct ip) && 590 (m = m_pullup(m, sizeof (struct ip))) == NULL) { 591 error = ENOBUFS; 592 goto unrefsav; 593 } 594 ip = mtod(m, struct ip *); 595 ip->ip_off |= htons(IP_DF); 596 } 597 } 598 599 /* 600 * Dispatch to the appropriate IPsec transform logic. The 601 * packet will be returned for transmission after crypto 602 * processing, etc. are completed. For encapsulation we 603 * bypass this call because of the explicit call done above 604 * (necessary to deal with IP_DF handling for IPv4). 605 * 606 * NB: m & sav are ``passed to caller'' who's reponsible for 607 * for reclaiming their resources. 608 */ 609 if (sav->tdb_xform->xf_type != XF_IP4) { 610 if (dst->sa.sa_family == AF_INET) { 611 ip = mtod(m, struct ip *); 612 i = ip->ip_hl << 2; 613 off = offsetof(struct ip, ip_p); 614 } else { 615 i = sizeof(struct ip6_hdr); 616 off = offsetof(struct ip6_hdr, ip6_nxt); 617 } 618 error = (*sav->tdb_xform->xf_output)(m, isr, sav, NULL, i, off); 619 } else { 620 error = ipsec_process_done(m, isr, sav); 621 } 622 KEY_SA_UNREF(&sav); 623 splx(s); 624 return error; 625 unrefsav: 626 KEY_SA_UNREF(&sav); 627 bad: 628 splx(s); 629 if (m) 630 m_freem(m); 631 return error; 632 } 633 #endif 634 635 #ifdef INET6 636 static void 637 compute_ipsec_pos(struct mbuf *m, int *i, int *off) 638 { 639 int nxt; 640 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr*); 641 struct ip6_ext ip6e; 642 int dstopt = 0; 643 644 *i = sizeof(struct ip6_hdr); 645 *off = offsetof(struct ip6_hdr, ip6_nxt); 646 nxt = ip6->ip6_nxt; 647 648 /* 649 * chase mbuf chain to find the appropriate place to 650 * put AH/ESP/IPcomp header. 651 * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload] 652 */ 653 do { 654 switch (nxt) { 655 case IPPROTO_AH: 656 case IPPROTO_ESP: 657 case IPPROTO_IPCOMP: 658 /* 659 * we should not skip security header added 660 * beforehand. 661 */ 662 return; 663 664 case IPPROTO_HOPOPTS: 665 case IPPROTO_DSTOPTS: 666 case IPPROTO_ROUTING: 667 /* 668 * if we see 2nd destination option header, 669 * we should stop there. 670 */ 671 if (nxt == IPPROTO_DSTOPTS && dstopt) 672 return; 673 674 if (nxt == IPPROTO_DSTOPTS) { 675 /* 676 * seen 1st or 2nd destination option. 677 * next time we see one, it must be 2nd. 678 */ 679 dstopt = 1; 680 } else if (nxt == IPPROTO_ROUTING) { 681 /* 682 * if we see destionation option next 683 * time, it must be dest2. 684 */ 685 dstopt = 2; 686 } 687 688 /* skip this header */ 689 m_copydata(m, *i, sizeof(ip6e), &ip6e); 690 nxt = ip6e.ip6e_nxt; 691 *off = *i + offsetof(struct ip6_ext, ip6e_nxt); 692 /* 693 * we will never see nxt == IPPROTO_AH 694 * so it is safe to omit AH case. 695 */ 696 *i += (ip6e.ip6e_len + 1) << 3; 697 break; 698 default: 699 return; 700 } 701 } while (*i < m->m_pkthdr.len); 702 } 703 704 static int 705 in6_sa_equal_addrwithscope(const struct sockaddr_in6 *sa, const struct in6_addr *ia) 706 { 707 struct in6_addr ia2; 708 709 memcpy(&ia2, &sa->sin6_addr, sizeof(ia2)); 710 if (IN6_IS_SCOPE_LINKLOCAL(&sa->sin6_addr)) 711 ia2.s6_addr16[1] = htons(sa->sin6_scope_id); 712 713 return IN6_ARE_ADDR_EQUAL(ia, &ia2); 714 } 715 716 int 717 ipsec6_process_packet( 718 struct mbuf *m, 719 const struct ipsecrequest *isr 720 ) 721 { 722 struct secasvar *sav = NULL; 723 struct ip6_hdr *ip6; 724 int s, error, i, off; 725 union sockaddr_union *dst; 726 727 KASSERT(m != NULL); 728 KASSERT(isr != NULL); 729 730 s = splsoftnet(); /* insure SA contents don't change */ 731 732 isr = ipsec_nextisr(m, isr, AF_INET6, &error, &sav); 733 if (isr == NULL) { 734 if (error != 0) { 735 /* XXX Should we send a notification ? */ 736 goto bad; 737 } else { 738 if (ipsec_register_done(m, &error) < 0) 739 goto bad; 740 741 splx(s); 742 return ipsec_reinject_ipstack(m, AF_INET6); 743 } 744 } 745 746 KASSERT(sav != NULL); 747 dst = &sav->sah->saidx.dst; 748 749 ip6 = mtod(m, struct ip6_hdr *); /* XXX */ 750 751 /* Do the appropriate encapsulation, if necessary */ 752 if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */ 753 dst->sa.sa_family != AF_INET6 || /* PF mismatch */ 754 ((dst->sa.sa_family == AF_INET6) && 755 (!IN6_IS_ADDR_UNSPECIFIED(&dst->sin6.sin6_addr)) && 756 (!in6_sa_equal_addrwithscope(&dst->sin6, 757 &ip6->ip6_dst)))) { 758 struct mbuf *mp; 759 760 /* Fix IPv6 header payload length. */ 761 if (m->m_len < sizeof(struct ip6_hdr)) { 762 if ((m = m_pullup(m,sizeof(struct ip6_hdr))) == NULL) { 763 error = ENOBUFS; 764 goto unrefsav; 765 } 766 } 767 768 if (m->m_pkthdr.len - sizeof(*ip6) > IPV6_MAXPACKET) { 769 /* No jumbogram support. */ 770 error = ENXIO; /*XXX*/ 771 goto unrefsav; 772 } 773 774 ip6 = mtod(m, struct ip6_hdr *); 775 ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); 776 777 /* Encapsulate the packet */ 778 error = ipip_output(m, isr, sav, &mp, 0, 0); 779 if (mp == NULL && !error) { 780 /* Should never happen. */ 781 IPSECLOG(LOG_DEBUG, 782 "ipip_output returns no mbuf and no error!"); 783 error = EFAULT; 784 } 785 786 if (error) { 787 if (mp) { 788 /* XXX: Should never happen! */ 789 m_freem(mp); 790 } 791 m = NULL; /* ipip_output() already freed it */ 792 goto unrefsav; 793 } 794 795 m = mp; 796 mp = NULL; 797 } 798 799 if (dst->sa.sa_family == AF_INET) { 800 struct ip *ip; 801 ip = mtod(m, struct ip *); 802 i = ip->ip_hl << 2; 803 off = offsetof(struct ip, ip_p); 804 } else { 805 compute_ipsec_pos(m, &i, &off); 806 } 807 error = (*sav->tdb_xform->xf_output)(m, isr, sav, NULL, i, off); 808 KEY_SA_UNREF(&sav); 809 splx(s); 810 return error; 811 unrefsav: 812 KEY_SA_UNREF(&sav); 813 bad: 814 splx(s); 815 if (m) 816 m_freem(m); 817 return error; 818 } 819 #endif /*INET6*/ 820 821 void 822 ipsec_output_init(void) 823 { 824 825 ipsec_rtcache_percpu = percpu_alloc(sizeof(struct route)); 826 } 827