1 /*- 2 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 /* 30 * IPsec output processing. 31 */ 32 #include "opt_inet.h" 33 #include "opt_inet6.h" 34 #include "opt_ipsec.h" 35 #include "opt_enc.h" 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/mbuf.h> 40 #include <sys/domain.h> 41 #include <sys/protosw.h> 42 #include <sys/socket.h> 43 #include <sys/errno.h> 44 #include <sys/syslog.h> 45 #include <sys/vimage.h> 46 47 #include <net/if.h> 48 #include <net/pfil.h> 49 #include <net/route.h> 50 51 #include <netinet/in.h> 52 #include <netinet/in_systm.h> 53 #include <netinet/ip.h> 54 #include <netinet/ip_var.h> 55 #include <netinet/in_var.h> 56 #include <netinet/ip_ecn.h> 57 #ifdef INET6 58 #include <netinet6/ip6_ecn.h> 59 #endif 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 70 #include <netipsec/ipsec.h> 71 #ifdef INET6 72 #include <netipsec/ipsec6.h> 73 #endif 74 #include <netipsec/ah_var.h> 75 #include <netipsec/esp_var.h> 76 #include <netipsec/ipcomp_var.h> 77 78 #include <netipsec/xform.h> 79 80 #include <netipsec/key.h> 81 #include <netipsec/keydb.h> 82 #include <netipsec/key_debug.h> 83 84 #include <machine/in_cksum.h> 85 86 #ifdef DEV_ENC 87 #include <net/if_enc.h> 88 #endif 89 90 91 int 92 ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) 93 { 94 INIT_VNET_IPSEC(curvnet); 95 struct tdb_ident *tdbi; 96 struct m_tag *mtag; 97 struct secasvar *sav; 98 struct secasindex *saidx; 99 int error; 100 101 IPSEC_ASSERT(m != NULL, ("null mbuf")); 102 IPSEC_ASSERT(isr != NULL, ("null ISR")); 103 sav = isr->sav; 104 IPSEC_ASSERT(sav != NULL, ("null SA")); 105 IPSEC_ASSERT(sav->sah != NULL, ("null SAH")); 106 107 saidx = &sav->sah->saidx; 108 switch (saidx->dst.sa.sa_family) { 109 #ifdef INET 110 case AF_INET: 111 /* Fix the header length, for AH processing. */ 112 mtod(m, struct ip *)->ip_len = htons(m->m_pkthdr.len); 113 break; 114 #endif /* INET */ 115 #ifdef INET6 116 case AF_INET6: 117 /* Fix the header length, for AH processing. */ 118 if (m->m_pkthdr.len < sizeof (struct ip6_hdr)) { 119 error = ENXIO; 120 goto bad; 121 } 122 if (m->m_pkthdr.len - sizeof (struct ip6_hdr) > IPV6_MAXPACKET) { 123 /* No jumbogram support. */ 124 error = ENXIO; /*?*/ 125 goto bad; 126 } 127 mtod(m, struct ip6_hdr *)->ip6_plen = 128 htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); 129 break; 130 #endif /* INET6 */ 131 default: 132 DPRINTF(("%s: unknown protocol family %u\n", __func__, 133 saidx->dst.sa.sa_family)); 134 error = ENXIO; 135 goto bad; 136 } 137 138 /* 139 * Add a record of what we've done or what needs to be done to the 140 * packet. 141 */ 142 mtag = m_tag_get(PACKET_TAG_IPSEC_OUT_DONE, 143 sizeof(struct tdb_ident), M_NOWAIT); 144 if (mtag == NULL) { 145 DPRINTF(("%s: could not get packet tag\n", __func__)); 146 error = ENOMEM; 147 goto bad; 148 } 149 150 tdbi = (struct tdb_ident *)(mtag + 1); 151 tdbi->dst = saidx->dst; 152 tdbi->proto = saidx->proto; 153 tdbi->spi = sav->spi; 154 m_tag_prepend(m, mtag); 155 156 /* 157 * If there's another (bundled) SA to apply, do so. 158 * Note that this puts a burden on the kernel stack size. 159 * If this is a problem we'll need to introduce a queue 160 * to set the packet on so we can unwind the stack before 161 * doing further processing. 162 */ 163 if (isr->next) { 164 V_ipsec4stat.ips_out_bundlesa++; 165 return ipsec4_process_packet(m, isr->next, 0, 0); 166 } 167 key_sa_recordxfer(sav, m); /* record data transfer */ 168 169 /* 170 * We're done with IPsec processing, transmit the packet using the 171 * appropriate network protocol (IP or IPv6). SPD lookup will be 172 * performed again there. 173 */ 174 switch (saidx->dst.sa.sa_family) { 175 #ifdef INET 176 struct ip *ip; 177 case AF_INET: 178 ip = mtod(m, struct ip *); 179 ip->ip_len = ntohs(ip->ip_len); 180 ip->ip_off = ntohs(ip->ip_off); 181 182 return ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL); 183 #endif /* INET */ 184 #ifdef INET6 185 case AF_INET6: 186 /* 187 * We don't need massage, IPv6 header fields are always in 188 * net endian. 189 */ 190 return ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 191 #endif /* INET6 */ 192 } 193 panic("ipsec_process_done"); 194 bad: 195 m_freem(m); 196 KEY_FREESAV(&sav); 197 return (error); 198 } 199 200 static struct ipsecrequest * 201 ipsec_nextisr( 202 struct mbuf *m, 203 struct ipsecrequest *isr, 204 int af, 205 struct secasindex *saidx, 206 int *error 207 ) 208 { 209 #define IPSEC_OSTAT(x,y,z) (isr->saidx.proto == IPPROTO_ESP ? (x)++ : \ 210 isr->saidx.proto == IPPROTO_AH ? (y)++ : (z)++) 211 INIT_VNET_IPSEC(curvnet); 212 struct secasvar *sav; 213 214 IPSECREQUEST_LOCK_ASSERT(isr); 215 216 IPSEC_ASSERT(af == AF_INET || af == AF_INET6, 217 ("invalid address family %u", af)); 218 again: 219 /* 220 * Craft SA index to search for proper SA. Note that 221 * we only fillin unspecified SA peers for transport 222 * mode; for tunnel mode they must already be filled in. 223 */ 224 *saidx = isr->saidx; 225 if (isr->saidx.mode == IPSEC_MODE_TRANSPORT) { 226 /* Fillin unspecified SA peers only for transport mode */ 227 if (af == AF_INET) { 228 struct sockaddr_in *sin; 229 struct ip *ip = mtod(m, struct ip *); 230 231 if (saidx->src.sa.sa_len == 0) { 232 sin = &saidx->src.sin; 233 sin->sin_len = sizeof(*sin); 234 sin->sin_family = AF_INET; 235 sin->sin_port = IPSEC_PORT_ANY; 236 sin->sin_addr = ip->ip_src; 237 } 238 if (saidx->dst.sa.sa_len == 0) { 239 sin = &saidx->dst.sin; 240 sin->sin_len = sizeof(*sin); 241 sin->sin_family = AF_INET; 242 sin->sin_port = IPSEC_PORT_ANY; 243 sin->sin_addr = ip->ip_dst; 244 } 245 } else { 246 struct sockaddr_in6 *sin6; 247 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 248 249 if (saidx->src.sin6.sin6_len == 0) { 250 sin6 = (struct sockaddr_in6 *)&saidx->src; 251 sin6->sin6_len = sizeof(*sin6); 252 sin6->sin6_family = AF_INET6; 253 sin6->sin6_port = IPSEC_PORT_ANY; 254 sin6->sin6_addr = ip6->ip6_src; 255 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) { 256 /* fix scope id for comparing SPD */ 257 sin6->sin6_addr.s6_addr16[1] = 0; 258 sin6->sin6_scope_id = 259 ntohs(ip6->ip6_src.s6_addr16[1]); 260 } 261 } 262 if (saidx->dst.sin6.sin6_len == 0) { 263 sin6 = (struct sockaddr_in6 *)&saidx->dst; 264 sin6->sin6_len = sizeof(*sin6); 265 sin6->sin6_family = AF_INET6; 266 sin6->sin6_port = IPSEC_PORT_ANY; 267 sin6->sin6_addr = ip6->ip6_dst; 268 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) { 269 /* fix scope id for comparing SPD */ 270 sin6->sin6_addr.s6_addr16[1] = 0; 271 sin6->sin6_scope_id = 272 ntohs(ip6->ip6_dst.s6_addr16[1]); 273 } 274 } 275 } 276 } 277 278 /* 279 * Lookup SA and validate it. 280 */ 281 *error = key_checkrequest(isr, saidx); 282 if (*error != 0) { 283 /* 284 * IPsec processing is required, but no SA found. 285 * I assume that key_acquire() had been called 286 * to get/establish the SA. Here I discard 287 * this packet because it is responsibility for 288 * upper layer to retransmit the packet. 289 */ 290 V_ipsec4stat.ips_out_nosa++; 291 goto bad; 292 } 293 sav = isr->sav; 294 if (sav == NULL) { 295 IPSEC_ASSERT(ipsec_get_reqlevel(isr) == IPSEC_LEVEL_USE, 296 ("no SA found, but required; level %u", 297 ipsec_get_reqlevel(isr))); 298 IPSECREQUEST_UNLOCK(isr); 299 isr = isr->next; 300 /* 301 * If isr is NULL, we found a 'use' policy w/o SA. 302 * Return w/o error and w/o isr so we can drop out 303 * and continue w/o IPsec processing. 304 */ 305 if (isr == NULL) 306 return isr; 307 IPSECREQUEST_LOCK(isr); 308 goto again; 309 } 310 311 /* 312 * Check system global policy controls. 313 */ 314 if ((isr->saidx.proto == IPPROTO_ESP && !V_esp_enable) || 315 (isr->saidx.proto == IPPROTO_AH && !V_ah_enable) || 316 (isr->saidx.proto == IPPROTO_IPCOMP && !V_ipcomp_enable)) { 317 DPRINTF(("%s: IPsec outbound packet dropped due" 318 " to policy (check your sysctls)\n", __func__)); 319 IPSEC_OSTAT(V_espstat.esps_pdrops, V_ahstat.ahs_pdrops, 320 V_ipcompstat.ipcomps_pdrops); 321 *error = EHOSTUNREACH; 322 goto bad; 323 } 324 325 /* 326 * Sanity check the SA contents for the caller 327 * before they invoke the xform output method. 328 */ 329 if (sav->tdb_xform == NULL) { 330 DPRINTF(("%s: no transform for SA\n", __func__)); 331 IPSEC_OSTAT(V_espstat.esps_noxform, V_ahstat.ahs_noxform, 332 V_ipcompstat.ipcomps_noxform); 333 *error = EHOSTUNREACH; 334 goto bad; 335 } 336 return isr; 337 bad: 338 IPSEC_ASSERT(*error != 0, ("error return w/ no error code")); 339 IPSECREQUEST_UNLOCK(isr); 340 return NULL; 341 #undef IPSEC_OSTAT 342 } 343 344 #ifdef INET 345 /* 346 * IPsec output logic for IPv4. 347 */ 348 int 349 ipsec4_process_packet( 350 struct mbuf *m, 351 struct ipsecrequest *isr, 352 int flags, 353 int tunalready) 354 { 355 INIT_VNET_IPSEC(curvnet); 356 struct secasindex saidx; 357 struct secasvar *sav; 358 struct ip *ip; 359 int error, i, off; 360 361 IPSEC_ASSERT(m != NULL, ("null mbuf")); 362 IPSEC_ASSERT(isr != NULL, ("null isr")); 363 364 IPSECREQUEST_LOCK(isr); /* insure SA contents don't change */ 365 366 isr = ipsec_nextisr(m, isr, AF_INET, &saidx, &error); 367 if (isr == NULL) { 368 if (error != 0) 369 goto bad; 370 return EJUSTRETURN; 371 } 372 373 sav = isr->sav; 374 375 #ifdef DEV_ENC 376 encif->if_opackets++; 377 encif->if_obytes += m->m_pkthdr.len; 378 379 /* pass the mbuf to enc0 for bpf processing */ 380 ipsec_bpf(m, sav, AF_INET, ENC_OUT|ENC_BEFORE); 381 /* pass the mbuf to enc0 for packet filtering */ 382 if ((error = ipsec_filter(&m, PFIL_OUT, ENC_OUT|ENC_BEFORE)) != 0) 383 goto bad; 384 #endif 385 386 if (!tunalready) { 387 union sockaddr_union *dst = &sav->sah->saidx.dst; 388 int setdf; 389 390 /* 391 * Collect IP_DF state from the outer header. 392 */ 393 if (dst->sa.sa_family == AF_INET) { 394 if (m->m_len < sizeof (struct ip) && 395 (m = m_pullup(m, sizeof (struct ip))) == NULL) { 396 error = ENOBUFS; 397 goto bad; 398 } 399 ip = mtod(m, struct ip *); 400 /* Honor system-wide control of how to handle IP_DF */ 401 switch (V_ip4_ipsec_dfbit) { 402 case 0: /* clear in outer header */ 403 case 1: /* set in outer header */ 404 setdf = V_ip4_ipsec_dfbit; 405 break; 406 default: /* propagate to outer header */ 407 setdf = ntohs(ip->ip_off & IP_DF); 408 break; 409 } 410 } else { 411 ip = NULL; /* keep compiler happy */ 412 setdf = 0; 413 } 414 /* Do the appropriate encapsulation, if necessary */ 415 if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */ 416 dst->sa.sa_family != AF_INET || /* PF mismatch */ 417 #if 0 418 (sav->flags & SADB_X_SAFLAGS_TUNNEL) || /* Tunnel requ'd */ 419 sav->tdb_xform->xf_type == XF_IP4 || /* ditto */ 420 #endif 421 (dst->sa.sa_family == AF_INET && /* Proxy */ 422 dst->sin.sin_addr.s_addr != INADDR_ANY && 423 dst->sin.sin_addr.s_addr != ip->ip_dst.s_addr)) { 424 struct mbuf *mp; 425 426 /* Fix IPv4 header checksum and length */ 427 if (m->m_len < sizeof (struct ip) && 428 (m = m_pullup(m, sizeof (struct ip))) == NULL) { 429 error = ENOBUFS; 430 goto bad; 431 } 432 ip = mtod(m, struct ip *); 433 ip->ip_len = htons(m->m_pkthdr.len); 434 ip->ip_sum = 0; 435 #ifdef _IP_VHL 436 if (ip->ip_vhl == IP_VHL_BORING) 437 ip->ip_sum = in_cksum_hdr(ip); 438 else 439 ip->ip_sum = in_cksum(m, 440 _IP_VHL_HL(ip->ip_vhl) << 2); 441 #else 442 ip->ip_sum = in_cksum(m, ip->ip_hl << 2); 443 #endif 444 445 /* Encapsulate the packet */ 446 error = ipip_output(m, isr, &mp, 0, 0); 447 if (mp == NULL && !error) { 448 /* Should never happen. */ 449 DPRINTF(("%s: ipip_output returns no mbuf and " 450 "no error!", __func__)); 451 error = EFAULT; 452 } 453 if (error) { 454 if (mp) { 455 /* XXX: Should never happen! */ 456 m_freem(mp); 457 } 458 m = NULL; /* ipip_output() already freed it */ 459 goto bad; 460 } 461 m = mp, mp = NULL; 462 /* 463 * ipip_output clears IP_DF in the new header. If 464 * we need to propagate IP_DF from the outer header, 465 * then we have to do it here. 466 * 467 * XXX shouldn't assume what ipip_output does. 468 */ 469 if (dst->sa.sa_family == AF_INET && setdf) { 470 if (m->m_len < sizeof (struct ip) && 471 (m = m_pullup(m, sizeof (struct ip))) == NULL) { 472 error = ENOBUFS; 473 goto bad; 474 } 475 ip = mtod(m, struct ip *); 476 ip->ip_off = ntohs(ip->ip_off); 477 ip->ip_off |= IP_DF; 478 ip->ip_off = htons(ip->ip_off); 479 } 480 } 481 } 482 483 #ifdef DEV_ENC 484 /* pass the mbuf to enc0 for bpf processing */ 485 ipsec_bpf(m, sav, AF_INET, ENC_OUT|ENC_AFTER); 486 /* pass the mbuf to enc0 for packet filtering */ 487 if ((error = ipsec_filter(&m, PFIL_OUT, ENC_OUT|ENC_AFTER)) != 0) 488 goto bad; 489 #endif 490 491 /* 492 * Dispatch to the appropriate IPsec transform logic. The 493 * packet will be returned for transmission after crypto 494 * processing, etc. are completed. For encapsulation we 495 * bypass this call because of the explicit call done above 496 * (necessary to deal with IP_DF handling for IPv4). 497 * 498 * NB: m & sav are ``passed to caller'' who's reponsible for 499 * for reclaiming their resources. 500 */ 501 if (sav->tdb_xform->xf_type != XF_IP4) { 502 ip = mtod(m, struct ip *); 503 i = ip->ip_hl << 2; 504 off = offsetof(struct ip, ip_p); 505 error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off); 506 } else { 507 error = ipsec_process_done(m, isr); 508 } 509 IPSECREQUEST_UNLOCK(isr); 510 return error; 511 bad: 512 if (isr) 513 IPSECREQUEST_UNLOCK(isr); 514 if (m) 515 m_freem(m); 516 return error; 517 } 518 #endif 519 520 #ifdef INET6 521 /* 522 * Chop IP6 header from the payload. 523 */ 524 static struct mbuf * 525 ipsec6_splithdr(struct mbuf *m) 526 { 527 struct mbuf *mh; 528 struct ip6_hdr *ip6; 529 int hlen; 530 531 IPSEC_ASSERT(m->m_len >= sizeof (struct ip6_hdr), 532 ("first mbuf too short, len %u", m->m_len)); 533 ip6 = mtod(m, struct ip6_hdr *); 534 hlen = sizeof(struct ip6_hdr); 535 if (m->m_len > hlen) { 536 MGETHDR(mh, M_DONTWAIT, MT_DATA); 537 if (!mh) { 538 m_freem(m); 539 return NULL; 540 } 541 M_MOVE_PKTHDR(mh, m); 542 MH_ALIGN(mh, hlen); 543 m->m_len -= hlen; 544 m->m_data += hlen; 545 mh->m_next = m; 546 m = mh; 547 m->m_len = hlen; 548 bcopy((caddr_t)ip6, mtod(m, caddr_t), hlen); 549 } else if (m->m_len < hlen) { 550 m = m_pullup(m, hlen); 551 if (!m) 552 return NULL; 553 } 554 return m; 555 } 556 557 /* 558 * IPsec output logic for IPv6, transport mode. 559 */ 560 int 561 ipsec6_output_trans( 562 struct ipsec_output_state *state, 563 u_char *nexthdrp, 564 struct mbuf *mprev, 565 struct secpolicy *sp, 566 int flags, 567 int *tun) 568 { 569 INIT_VNET_IPSEC(curvnet); 570 struct ipsecrequest *isr; 571 struct secasindex saidx; 572 int error = 0; 573 struct mbuf *m; 574 575 IPSEC_ASSERT(state != NULL, ("null state")); 576 IPSEC_ASSERT(state->m != NULL, ("null m")); 577 IPSEC_ASSERT(nexthdrp != NULL, ("null nexthdrp")); 578 IPSEC_ASSERT(mprev != NULL, ("null mprev")); 579 IPSEC_ASSERT(sp != NULL, ("null sp")); 580 IPSEC_ASSERT(tun != NULL, ("null tun")); 581 582 KEYDEBUG(KEYDEBUG_IPSEC_DATA, 583 printf("%s: applied SP\n", __func__); 584 kdebug_secpolicy(sp)); 585 586 isr = sp->req; 587 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) { 588 /* the rest will be handled by ipsec6_output_tunnel() */ 589 *tun = 1; /* need tunnel-mode processing */ 590 return 0; 591 } 592 593 *tun = 0; 594 m = state->m; 595 596 IPSECREQUEST_LOCK(isr); /* insure SA contents don't change */ 597 isr = ipsec_nextisr(m, isr, AF_INET6, &saidx, &error); 598 if (isr == NULL) { 599 if (error != 0) { 600 #ifdef notdef 601 /* XXX should notification be done for all errors ? */ 602 /* 603 * Notify the fact that the packet is discarded 604 * to ourselves. I believe this is better than 605 * just silently discarding. (jinmei@kame.net) 606 * XXX: should we restrict the error to TCP packets? 607 * XXX: should we directly notify sockets via 608 * pfctlinputs? 609 */ 610 icmp6_error(m, ICMP6_DST_UNREACH, 611 ICMP6_DST_UNREACH_ADMIN, 0); 612 m = NULL; /* NB: icmp6_error frees mbuf */ 613 #endif 614 goto bad; 615 } 616 return EJUSTRETURN; 617 } 618 619 error = (*isr->sav->tdb_xform->xf_output)(m, isr, NULL, 620 sizeof (struct ip6_hdr), 621 offsetof(struct ip6_hdr, 622 ip6_nxt)); 623 IPSECREQUEST_UNLOCK(isr); 624 return error; 625 bad: 626 if (isr) 627 IPSECREQUEST_UNLOCK(isr); 628 if (m) 629 m_freem(m); 630 state->m = NULL; 631 return error; 632 } 633 634 static int 635 ipsec6_encapsulate(struct mbuf *m, struct secasvar *sav) 636 { 637 INIT_VNET_IPSEC(curvnet); 638 struct ip6_hdr *oip6; 639 struct ip6_hdr *ip6; 640 size_t plen; 641 642 /* can't tunnel between different AFs */ 643 if (sav->sah->saidx.src.sa.sa_family != AF_INET6 || 644 sav->sah->saidx.dst.sa.sa_family != AF_INET6) { 645 m_freem(m); 646 return EINVAL; 647 } 648 IPSEC_ASSERT(m->m_len == sizeof (struct ip6_hdr), 649 ("mbuf wrong size; len %u", m->m_len)); 650 651 652 /* 653 * grow the mbuf to accomodate the new IPv6 header. 654 */ 655 plen = m->m_pkthdr.len; 656 if (M_LEADINGSPACE(m->m_next) < sizeof(struct ip6_hdr)) { 657 struct mbuf *n; 658 MGET(n, M_DONTWAIT, MT_DATA); 659 if (!n) { 660 m_freem(m); 661 return ENOBUFS; 662 } 663 n->m_len = sizeof(struct ip6_hdr); 664 n->m_next = m->m_next; 665 m->m_next = n; 666 m->m_pkthdr.len += sizeof(struct ip6_hdr); 667 oip6 = mtod(n, struct ip6_hdr *); 668 } else { 669 m->m_next->m_len += sizeof(struct ip6_hdr); 670 m->m_next->m_data -= sizeof(struct ip6_hdr); 671 m->m_pkthdr.len += sizeof(struct ip6_hdr); 672 oip6 = mtod(m->m_next, struct ip6_hdr *); 673 } 674 ip6 = mtod(m, struct ip6_hdr *); 675 bcopy((caddr_t)ip6, (caddr_t)oip6, sizeof(struct ip6_hdr)); 676 677 /* Fake link-local scope-class addresses */ 678 if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_src)) 679 oip6->ip6_src.s6_addr16[1] = 0; 680 if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_dst)) 681 oip6->ip6_dst.s6_addr16[1] = 0; 682 683 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */ 684 /* ECN consideration. */ 685 ip6_ecn_ingress(V_ip6_ipsec_ecn, &ip6->ip6_flow, &oip6->ip6_flow); 686 if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr)) 687 ip6->ip6_plen = htons(plen); 688 else { 689 /* ip6->ip6_plen will be updated in ip6_output() */ 690 } 691 ip6->ip6_nxt = IPPROTO_IPV6; 692 ip6->ip6_src = sav->sah->saidx.src.sin6.sin6_addr; 693 ip6->ip6_dst = sav->sah->saidx.dst.sin6.sin6_addr; 694 ip6->ip6_hlim = IPV6_DEFHLIM; 695 696 /* XXX Should ip6_src be updated later ? */ 697 698 return 0; 699 } 700 701 /* 702 * IPsec output logic for IPv6, tunnel mode. 703 */ 704 int 705 ipsec6_output_tunnel(struct ipsec_output_state *state, struct secpolicy *sp, int flags) 706 { 707 INIT_VNET_INET6(curvnet); 708 INIT_VNET_IPSEC(curvnet); 709 struct ip6_hdr *ip6; 710 struct ipsecrequest *isr; 711 struct secasindex saidx; 712 int error; 713 struct sockaddr_in6* dst6; 714 struct mbuf *m; 715 716 IPSEC_ASSERT(state != NULL, ("null state")); 717 IPSEC_ASSERT(state->m != NULL, ("null m")); 718 IPSEC_ASSERT(sp != NULL, ("null sp")); 719 720 KEYDEBUG(KEYDEBUG_IPSEC_DATA, 721 printf("%s: applied SP\n", __func__); 722 kdebug_secpolicy(sp)); 723 724 m = state->m; 725 /* 726 * transport mode ipsec (before the 1st tunnel mode) is already 727 * processed by ipsec6_output_trans(). 728 */ 729 for (isr = sp->req; isr; isr = isr->next) { 730 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) 731 break; 732 } 733 734 IPSECREQUEST_LOCK(isr); /* insure SA contents don't change */ 735 isr = ipsec_nextisr(m, isr, AF_INET6, &saidx, &error); 736 if (isr == NULL) { 737 if (error != 0) 738 goto bad; 739 return EJUSTRETURN; 740 } 741 742 #ifdef DEV_ENC 743 encif->if_opackets++; 744 encif->if_obytes += m->m_pkthdr.len; 745 746 /* pass the mbuf to enc0 for bpf processing */ 747 ipsec_bpf(m, isr->sav, AF_INET6, ENC_OUT|ENC_BEFORE); 748 /* pass the mbuf to enc0 for packet filtering */ 749 if ((error = ipsec_filter(&m, PFIL_OUT, ENC_OUT|ENC_BEFORE)) != 0) 750 goto bad; 751 #endif 752 753 /* 754 * There may be the case that SA status will be changed when 755 * we are refering to one. So calling splsoftnet(). 756 */ 757 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) { 758 /* 759 * build IPsec tunnel. 760 */ 761 /* XXX should be processed with other familiy */ 762 if (isr->sav->sah->saidx.src.sa.sa_family != AF_INET6) { 763 ipseclog((LOG_ERR, "%s: family mismatched between " 764 "inner and outer, spi=%u\n", __func__, 765 ntohl(isr->sav->spi))); 766 V_ipsec6stat.ips_out_inval++; 767 error = EAFNOSUPPORT; 768 goto bad; 769 } 770 771 m = ipsec6_splithdr(m); 772 if (!m) { 773 V_ipsec6stat.ips_out_nomem++; 774 error = ENOMEM; 775 goto bad; 776 } 777 error = ipsec6_encapsulate(m, isr->sav); 778 if (error) { 779 m = NULL; 780 goto bad; 781 } 782 ip6 = mtod(m, struct ip6_hdr *); 783 784 state->ro = &isr->sav->sah->sa_route; 785 state->dst = (struct sockaddr *)&state->ro->ro_dst; 786 dst6 = (struct sockaddr_in6 *)state->dst; 787 if (state->ro->ro_rt 788 && ((state->ro->ro_rt->rt_flags & RTF_UP) == 0 789 || !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst))) { 790 RTFREE(state->ro->ro_rt); 791 state->ro->ro_rt = NULL; 792 } 793 if (state->ro->ro_rt == 0) { 794 bzero(dst6, sizeof(*dst6)); 795 dst6->sin6_family = AF_INET6; 796 dst6->sin6_len = sizeof(*dst6); 797 dst6->sin6_addr = ip6->ip6_dst; 798 rtalloc(state->ro); 799 } 800 if (state->ro->ro_rt == 0) { 801 V_ip6stat.ip6s_noroute++; 802 V_ipsec6stat.ips_out_noroute++; 803 error = EHOSTUNREACH; 804 goto bad; 805 } 806 807 /* adjust state->dst if tunnel endpoint is offlink */ 808 if (state->ro->ro_rt->rt_flags & RTF_GATEWAY) { 809 state->dst = (struct sockaddr *)state->ro->ro_rt->rt_gateway; 810 dst6 = (struct sockaddr_in6 *)state->dst; 811 } 812 } 813 814 m = ipsec6_splithdr(m); 815 if (!m) { 816 V_ipsec6stat.ips_out_nomem++; 817 error = ENOMEM; 818 goto bad; 819 } 820 ip6 = mtod(m, struct ip6_hdr *); 821 822 #ifdef DEV_ENC 823 /* pass the mbuf to enc0 for bpf processing */ 824 ipsec_bpf(m, isr->sav, AF_INET6, ENC_OUT|ENC_AFTER); 825 /* pass the mbuf to enc0 for packet filtering */ 826 if ((error = ipsec_filter(&m, PFIL_OUT, ENC_OUT|ENC_AFTER)) != 0) 827 goto bad; 828 #endif 829 830 error = (*isr->sav->tdb_xform->xf_output)(m, isr, NULL, 831 sizeof (struct ip6_hdr), 832 offsetof(struct ip6_hdr, ip6_nxt)); 833 IPSECREQUEST_UNLOCK(isr); 834 return error; 835 bad: 836 if (isr) 837 IPSECREQUEST_UNLOCK(isr); 838 if (m) 839 m_freem(m); 840 state->m = NULL; 841 return error; 842 } 843 #endif /*INET6*/ 844