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 46 #include <net/if.h> 47 #include <net/if_var.h> 48 #include <net/pfil.h> 49 #include <net/vnet.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 #include <netinet6/scope6_var.h> 65 #endif 66 #include <netinet/in_pcb.h> 67 #ifdef INET6 68 #include <netinet/icmp6.h> 69 #endif 70 71 #include <netipsec/ipsec.h> 72 #ifdef INET6 73 #include <netipsec/ipsec6.h> 74 #endif 75 #include <netipsec/ah_var.h> 76 #include <netipsec/esp_var.h> 77 #include <netipsec/ipcomp_var.h> 78 79 #include <netipsec/xform.h> 80 81 #include <netipsec/key.h> 82 #include <netipsec/keydb.h> 83 #include <netipsec/key_debug.h> 84 85 #include <machine/in_cksum.h> 86 87 #ifdef IPSEC_NAT_T 88 #include <netinet/udp.h> 89 #endif 90 91 #ifdef DEV_ENC 92 #include <net/if_enc.h> 93 #endif 94 95 96 int 97 ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) 98 { 99 struct tdb_ident *tdbi; 100 struct m_tag *mtag; 101 struct secasvar *sav; 102 struct secasindex *saidx; 103 int error; 104 105 IPSEC_ASSERT(m != NULL, ("null mbuf")); 106 IPSEC_ASSERT(isr != NULL, ("null ISR")); 107 IPSEC_ASSERT(isr->sp != NULL, ("NULL isr->sp")); 108 sav = isr->sav; 109 IPSEC_ASSERT(sav != NULL, ("null SA")); 110 IPSEC_ASSERT(sav->sah != NULL, ("null SAH")); 111 112 saidx = &sav->sah->saidx; 113 switch (saidx->dst.sa.sa_family) { 114 #ifdef INET 115 case AF_INET: 116 /* Fix the header length, for AH processing. */ 117 mtod(m, struct ip *)->ip_len = htons(m->m_pkthdr.len); 118 break; 119 #endif /* INET */ 120 #ifdef INET6 121 case AF_INET6: 122 /* Fix the header length, for AH processing. */ 123 if (m->m_pkthdr.len < sizeof (struct ip6_hdr)) { 124 error = ENXIO; 125 goto bad; 126 } 127 if (m->m_pkthdr.len - sizeof (struct ip6_hdr) > IPV6_MAXPACKET) { 128 /* No jumbogram support. */ 129 error = ENXIO; /*?*/ 130 goto bad; 131 } 132 mtod(m, struct ip6_hdr *)->ip6_plen = 133 htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); 134 break; 135 #endif /* INET6 */ 136 default: 137 DPRINTF(("%s: unknown protocol family %u\n", __func__, 138 saidx->dst.sa.sa_family)); 139 error = ENXIO; 140 goto bad; 141 } 142 143 /* 144 * Add a record of what we've done or what needs to be done to the 145 * packet. 146 */ 147 mtag = m_tag_get(PACKET_TAG_IPSEC_OUT_DONE, 148 sizeof(struct tdb_ident), M_NOWAIT); 149 if (mtag == NULL) { 150 DPRINTF(("%s: could not get packet tag\n", __func__)); 151 error = ENOMEM; 152 goto bad; 153 } 154 155 tdbi = (struct tdb_ident *)(mtag + 1); 156 tdbi->dst = saidx->dst; 157 tdbi->proto = saidx->proto; 158 tdbi->spi = sav->spi; 159 m_tag_prepend(m, mtag); 160 161 key_sa_recordxfer(sav, m); /* record data transfer */ 162 163 /* 164 * If there's another (bundled) SA to apply, do so. 165 * Note that this puts a burden on the kernel stack size. 166 * If this is a problem we'll need to introduce a queue 167 * to set the packet on so we can unwind the stack before 168 * doing further processing. 169 * 170 * If ipsec[46]_process_packet() will successfully queue 171 * the request, we need to take additional reference to SP, 172 * because xform callback will release reference. 173 */ 174 if (isr->next) { 175 /* XXX-BZ currently only support same AF bundles. */ 176 switch (saidx->dst.sa.sa_family) { 177 #ifdef INET 178 case AF_INET: 179 IPSECSTAT_INC(ips_out_bundlesa); 180 key_addref(isr->sp); 181 error = ipsec4_process_packet(m, isr->next); 182 if (error != 0) 183 KEY_FREESP(&isr->sp); 184 return (error); 185 /* NOTREACHED */ 186 #endif 187 #ifdef notyet 188 #ifdef INET6 189 case AF_INET6: 190 /* XXX */ 191 IPSEC6STAT_INC(ips_out_bundlesa); 192 key_addref(isr->sp); 193 error = ipsec6_process_packet(m, isr->next); 194 if (error != 0) 195 KEY_FREESP(&isr->sp); 196 return (error); 197 /* NOTREACHED */ 198 #endif /* INET6 */ 199 #endif 200 default: 201 DPRINTF(("%s: unknown protocol family %u\n", __func__, 202 saidx->dst.sa.sa_family)); 203 error = ENXIO; 204 goto bad; 205 } 206 } 207 208 /* 209 * We're done with IPsec processing, transmit the packet using the 210 * appropriate network protocol (IP or IPv6). 211 */ 212 switch (saidx->dst.sa.sa_family) { 213 #ifdef INET 214 case AF_INET: 215 #ifdef IPSEC_NAT_T 216 /* 217 * If NAT-T is enabled, now that all IPsec processing is done 218 * insert UDP encapsulation header after IP header. 219 */ 220 if (sav->natt_type) { 221 struct ip *ip = mtod(m, struct ip *); 222 const int hlen = (ip->ip_hl << 2); 223 int size, off; 224 struct mbuf *mi; 225 struct udphdr *udp; 226 227 size = sizeof(struct udphdr); 228 if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) { 229 /* 230 * draft-ietf-ipsec-nat-t-ike-0[01].txt and 231 * draft-ietf-ipsec-udp-encaps-(00/)01.txt, 232 * ignoring possible AH mode 233 * non-IKE marker + non-ESP marker 234 * from draft-ietf-ipsec-udp-encaps-00.txt. 235 */ 236 size += sizeof(u_int64_t); 237 } 238 mi = m_makespace(m, hlen, size, &off); 239 if (mi == NULL) { 240 DPRINTF(("%s: m_makespace for udphdr failed\n", 241 __func__)); 242 error = ENOBUFS; 243 goto bad; 244 } 245 246 udp = (struct udphdr *)(mtod(mi, caddr_t) + off); 247 if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) 248 udp->uh_sport = htons(UDP_ENCAP_ESPINUDP_PORT); 249 else 250 udp->uh_sport = 251 KEY_PORTFROMSADDR(&sav->sah->saidx.src); 252 udp->uh_dport = KEY_PORTFROMSADDR(&sav->sah->saidx.dst); 253 udp->uh_sum = 0; 254 udp->uh_ulen = htons(m->m_pkthdr.len - hlen); 255 ip->ip_len = htons(m->m_pkthdr.len); 256 ip->ip_p = IPPROTO_UDP; 257 258 if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) 259 *(u_int64_t *)(udp + 1) = 0; 260 } 261 #endif /* IPSEC_NAT_T */ 262 263 return ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL); 264 #endif /* INET */ 265 #ifdef INET6 266 case AF_INET6: 267 /* 268 * We don't need massage, IPv6 header fields are always in 269 * net endian. 270 */ 271 return ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 272 #endif /* INET6 */ 273 } 274 panic("ipsec_process_done"); 275 bad: 276 m_freem(m); 277 return (error); 278 } 279 280 static struct ipsecrequest * 281 ipsec_nextisr( 282 struct mbuf *m, 283 struct ipsecrequest *isr, 284 int af, 285 struct secasindex *saidx, 286 int *error 287 ) 288 { 289 #define IPSEC_OSTAT(name) do { \ 290 if (isr->saidx.proto == IPPROTO_ESP) \ 291 ESPSTAT_INC(esps_##name); \ 292 else if (isr->saidx.proto == IPPROTO_AH)\ 293 AHSTAT_INC(ahs_##name); \ 294 else \ 295 IPCOMPSTAT_INC(ipcomps_##name); \ 296 } while (0) 297 struct secasvar *sav; 298 299 IPSECREQUEST_LOCK_ASSERT(isr); 300 301 IPSEC_ASSERT(af == AF_INET || af == AF_INET6, 302 ("invalid address family %u", af)); 303 again: 304 /* 305 * Craft SA index to search for proper SA. Note that 306 * we only fillin unspecified SA peers for transport 307 * mode; for tunnel mode they must already be filled in. 308 */ 309 *saidx = isr->saidx; 310 if (isr->saidx.mode == IPSEC_MODE_TRANSPORT) { 311 /* Fillin unspecified SA peers only for transport mode */ 312 if (af == AF_INET) { 313 struct sockaddr_in *sin; 314 struct ip *ip = mtod(m, struct ip *); 315 316 if (saidx->src.sa.sa_len == 0) { 317 sin = &saidx->src.sin; 318 sin->sin_len = sizeof(*sin); 319 sin->sin_family = AF_INET; 320 sin->sin_port = IPSEC_PORT_ANY; 321 sin->sin_addr = ip->ip_src; 322 } 323 if (saidx->dst.sa.sa_len == 0) { 324 sin = &saidx->dst.sin; 325 sin->sin_len = sizeof(*sin); 326 sin->sin_family = AF_INET; 327 sin->sin_port = IPSEC_PORT_ANY; 328 sin->sin_addr = ip->ip_dst; 329 } 330 } else { 331 struct sockaddr_in6 *sin6; 332 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 333 334 if (saidx->src.sin6.sin6_len == 0) { 335 sin6 = (struct sockaddr_in6 *)&saidx->src; 336 sin6->sin6_len = sizeof(*sin6); 337 sin6->sin6_family = AF_INET6; 338 sin6->sin6_port = IPSEC_PORT_ANY; 339 sin6->sin6_addr = ip6->ip6_src; 340 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) { 341 /* fix scope id for comparing SPD */ 342 sin6->sin6_addr.s6_addr16[1] = 0; 343 sin6->sin6_scope_id = 344 ntohs(ip6->ip6_src.s6_addr16[1]); 345 } 346 } 347 if (saidx->dst.sin6.sin6_len == 0) { 348 sin6 = (struct sockaddr_in6 *)&saidx->dst; 349 sin6->sin6_len = sizeof(*sin6); 350 sin6->sin6_family = AF_INET6; 351 sin6->sin6_port = IPSEC_PORT_ANY; 352 sin6->sin6_addr = ip6->ip6_dst; 353 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) { 354 /* fix scope id for comparing SPD */ 355 sin6->sin6_addr.s6_addr16[1] = 0; 356 sin6->sin6_scope_id = 357 ntohs(ip6->ip6_dst.s6_addr16[1]); 358 } 359 } 360 } 361 } 362 363 /* 364 * Lookup SA and validate it. 365 */ 366 *error = key_checkrequest(isr, saidx); 367 if (*error != 0) { 368 /* 369 * IPsec processing is required, but no SA found. 370 * I assume that key_acquire() had been called 371 * to get/establish the SA. Here I discard 372 * this packet because it is responsibility for 373 * upper layer to retransmit the packet. 374 */ 375 switch(af) { 376 case AF_INET: 377 IPSECSTAT_INC(ips_out_nosa); 378 break; 379 #ifdef INET6 380 case AF_INET6: 381 IPSEC6STAT_INC(ips_out_nosa); 382 break; 383 #endif 384 } 385 goto bad; 386 } 387 sav = isr->sav; 388 if (sav == NULL) { 389 IPSEC_ASSERT(ipsec_get_reqlevel(isr) == IPSEC_LEVEL_USE, 390 ("no SA found, but required; level %u", 391 ipsec_get_reqlevel(isr))); 392 IPSECREQUEST_UNLOCK(isr); 393 isr = isr->next; 394 /* 395 * If isr is NULL, we found a 'use' policy w/o SA. 396 * Return w/o error and w/o isr so we can drop out 397 * and continue w/o IPsec processing. 398 */ 399 if (isr == NULL) 400 return isr; 401 IPSECREQUEST_LOCK(isr); 402 goto again; 403 } 404 405 /* 406 * Check system global policy controls. 407 */ 408 if ((isr->saidx.proto == IPPROTO_ESP && !V_esp_enable) || 409 (isr->saidx.proto == IPPROTO_AH && !V_ah_enable) || 410 (isr->saidx.proto == IPPROTO_IPCOMP && !V_ipcomp_enable)) { 411 DPRINTF(("%s: IPsec outbound packet dropped due" 412 " to policy (check your sysctls)\n", __func__)); 413 IPSEC_OSTAT(pdrops); 414 *error = EHOSTUNREACH; 415 goto bad; 416 } 417 418 /* 419 * Sanity check the SA contents for the caller 420 * before they invoke the xform output method. 421 */ 422 if (sav->tdb_xform == NULL) { 423 DPRINTF(("%s: no transform for SA\n", __func__)); 424 IPSEC_OSTAT(noxform); 425 *error = EHOSTUNREACH; 426 goto bad; 427 } 428 return isr; 429 bad: 430 IPSEC_ASSERT(*error != 0, ("error return w/ no error code")); 431 IPSECREQUEST_UNLOCK(isr); 432 return NULL; 433 #undef IPSEC_OSTAT 434 } 435 436 static int 437 ipsec_encap(struct mbuf **mp, struct secasindex *saidx) 438 { 439 #ifdef INET6 440 struct ip6_hdr *ip6; 441 #endif 442 struct ip *ip; 443 int setdf; 444 uint8_t itos, proto; 445 446 ip = mtod(*mp, struct ip *); 447 switch (ip->ip_v) { 448 #ifdef INET 449 case IPVERSION: 450 proto = IPPROTO_IPIP; 451 /* 452 * Collect IP_DF state from the inner header 453 * and honor system-wide control of how to handle it. 454 */ 455 switch (V_ip4_ipsec_dfbit) { 456 case 0: /* clear in outer header */ 457 case 1: /* set in outer header */ 458 setdf = V_ip4_ipsec_dfbit; 459 break; 460 default:/* propagate to outer header */ 461 setdf = (ip->ip_off & ntohs(IP_DF)) != 0; 462 } 463 itos = ip->ip_tos; 464 break; 465 #endif 466 #ifdef INET6 467 case (IPV6_VERSION >> 4): 468 proto = IPPROTO_IPV6; 469 ip6 = mtod(*mp, struct ip6_hdr *); 470 itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; 471 setdf = V_ip4_ipsec_dfbit ? 1: 0; 472 /* scoped address handling */ 473 in6_clearscope(&ip6->ip6_src); 474 in6_clearscope(&ip6->ip6_dst); 475 break; 476 #endif 477 default: 478 return (EAFNOSUPPORT); 479 } 480 switch (saidx->dst.sa.sa_family) { 481 #ifdef INET 482 case AF_INET: 483 if (saidx->src.sa.sa_family != AF_INET || 484 saidx->src.sin.sin_addr.s_addr == INADDR_ANY || 485 saidx->dst.sin.sin_addr.s_addr == INADDR_ANY) 486 return (EINVAL); 487 M_PREPEND(*mp, sizeof(struct ip), M_NOWAIT); 488 if (*mp == NULL) 489 return (ENOBUFS); 490 ip = mtod(*mp, struct ip *); 491 ip->ip_v = IPVERSION; 492 ip->ip_hl = sizeof(struct ip) >> 2; 493 ip->ip_p = proto; 494 ip->ip_len = htons((*mp)->m_pkthdr.len); 495 ip->ip_ttl = V_ip_defttl; 496 ip->ip_sum = 0; 497 ip->ip_off = setdf ? htons(IP_DF): 0; 498 ip->ip_src = saidx->src.sin.sin_addr; 499 ip->ip_dst = saidx->dst.sin.sin_addr; 500 ip_ecn_ingress(V_ip4_ipsec_ecn, &ip->ip_tos, &itos); 501 ip_fillid(ip); 502 break; 503 #endif /* INET */ 504 #ifdef INET6 505 case AF_INET6: 506 if (saidx->src.sa.sa_family != AF_INET6 || 507 IN6_IS_ADDR_UNSPECIFIED(&saidx->src.sin6.sin6_addr) || 508 IN6_IS_ADDR_UNSPECIFIED(&saidx->dst.sin6.sin6_addr)) 509 return (EINVAL); 510 M_PREPEND(*mp, sizeof(struct ip6_hdr), M_NOWAIT); 511 if (*mp == NULL) 512 return (ENOBUFS); 513 ip6 = mtod(*mp, struct ip6_hdr *); 514 ip6->ip6_flow = 0; 515 ip6->ip6_vfc = IPV6_VERSION; 516 ip6->ip6_hlim = V_ip6_defhlim; 517 ip6->ip6_nxt = proto; 518 ip6->ip6_dst = saidx->dst.sin6.sin6_addr; 519 /* For link-local address embed scope zone id */ 520 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) 521 ip6->ip6_dst.s6_addr16[1] = 522 htons(saidx->dst.sin6.sin6_scope_id & 0xffff); 523 ip6->ip6_src = saidx->src.sin6.sin6_addr; 524 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) 525 ip6->ip6_src.s6_addr16[1] = 526 htons(saidx->src.sin6.sin6_scope_id & 0xffff); 527 ip6->ip6_plen = htons((*mp)->m_pkthdr.len - sizeof(*ip6)); 528 ip_ecn_ingress(V_ip6_ipsec_ecn, &proto, &itos); 529 ip6->ip6_flow |= htonl((uint32_t)proto << 20); 530 break; 531 #endif /* INET6 */ 532 default: 533 return (EAFNOSUPPORT); 534 } 535 return (0); 536 } 537 538 #ifdef INET 539 /* 540 * IPsec output logic for IPv4. 541 */ 542 int 543 ipsec4_process_packet(struct mbuf *m, struct ipsecrequest *isr) 544 { 545 char sbuf[INET6_ADDRSTRLEN], dbuf[INET6_ADDRSTRLEN]; 546 union sockaddr_union *dst; 547 struct secasindex saidx; 548 struct secasvar *sav; 549 struct ip *ip; 550 int error, i, off; 551 552 IPSEC_ASSERT(m != NULL, ("null mbuf")); 553 IPSEC_ASSERT(isr != NULL, ("null isr")); 554 555 IPSECREQUEST_LOCK(isr); /* insure SA contents don't change */ 556 557 isr = ipsec_nextisr(m, isr, AF_INET, &saidx, &error); 558 if (isr == NULL) { 559 if (error != 0) 560 goto bad; 561 return EJUSTRETURN; 562 } 563 564 sav = isr->sav; 565 if (m->m_len < sizeof(struct ip) && 566 (m = m_pullup(m, sizeof (struct ip))) == NULL) { 567 error = ENOBUFS; 568 goto bad; 569 } 570 ip = mtod(m, struct ip *); 571 dst = &sav->sah->saidx.dst; 572 #ifdef DEV_ENC 573 if_inc_counter(encif, IFCOUNTER_OPACKETS, 1); 574 if_inc_counter(encif, IFCOUNTER_OBYTES, m->m_pkthdr.len); 575 576 /* pass the mbuf to enc0 for bpf processing */ 577 ipsec_bpf(m, sav, AF_INET, ENC_OUT|ENC_BEFORE); 578 /* pass the mbuf to enc0 for packet filtering */ 579 if ((error = ipsec_filter(&m, PFIL_OUT, ENC_OUT|ENC_BEFORE)) != 0) 580 goto bad; 581 ip = mtod(m, struct ip *); 582 #endif 583 /* Do the appropriate encapsulation, if necessary */ 584 if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */ 585 dst->sa.sa_family != AF_INET || /* PF mismatch */ 586 (dst->sa.sa_family == AF_INET && /* Proxy */ 587 dst->sin.sin_addr.s_addr != INADDR_ANY && 588 dst->sin.sin_addr.s_addr != ip->ip_dst.s_addr)) { 589 /* Fix IPv4 header checksum and length */ 590 ip->ip_len = htons(m->m_pkthdr.len); 591 ip->ip_sum = 0; 592 ip->ip_sum = in_cksum(m, ip->ip_hl << 2); 593 error = ipsec_encap(&m, &sav->sah->saidx); 594 if (error != 0) { 595 DPRINTF(("%s: encapsulation for SA %s->%s " 596 "SPI 0x%08x failed with error %d\n", __func__, 597 ipsec_address(&sav->sah->saidx.src, sbuf, 598 sizeof(sbuf)), 599 ipsec_address(&sav->sah->saidx.dst, dbuf, 600 sizeof(dbuf)), ntohl(sav->spi), error)); 601 goto bad; 602 } 603 } 604 #ifdef DEV_ENC 605 /* pass the mbuf to enc0 for bpf processing */ 606 ipsec_bpf(m, sav, sav->sah->saidx.dst.sa.sa_family, ENC_OUT|ENC_AFTER); 607 /* pass the mbuf to enc0 for packet filtering */ 608 if ((error = ipsec_filter(&m, PFIL_OUT, ENC_OUT|ENC_AFTER)) != 0) 609 goto bad; 610 #endif 611 612 /* 613 * Dispatch to the appropriate IPsec transform logic. The 614 * packet will be returned for transmission after crypto 615 * processing, etc. are completed. 616 * 617 * NB: m & sav are ``passed to caller'' who's reponsible for 618 * for reclaiming their resources. 619 */ 620 switch(dst->sa.sa_family) { 621 case AF_INET: 622 ip = mtod(m, struct ip *); 623 i = ip->ip_hl << 2; 624 off = offsetof(struct ip, ip_p); 625 break; 626 #ifdef INET6 627 case AF_INET6: 628 i = sizeof(struct ip6_hdr); 629 off = offsetof(struct ip6_hdr, ip6_nxt); 630 break; 631 #endif /* INET6 */ 632 default: 633 DPRINTF(("%s: unsupported protocol family %u\n", 634 __func__, dst->sa.sa_family)); 635 error = EPFNOSUPPORT; 636 IPSECSTAT_INC(ips_out_inval); 637 goto bad; 638 } 639 error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off); 640 IPSECREQUEST_UNLOCK(isr); 641 return (error); 642 bad: 643 if (isr) 644 IPSECREQUEST_UNLOCK(isr); 645 if (m) 646 m_freem(m); 647 return error; 648 } 649 #endif 650 651 652 #ifdef INET6 653 static int 654 in6_sa_equal_addrwithscope(const struct sockaddr_in6 *sa, const struct in6_addr *ia) 655 { 656 struct in6_addr ia2; 657 658 memcpy(&ia2, &sa->sin6_addr, sizeof(ia2)); 659 if (IN6_IS_SCOPE_LINKLOCAL(&sa->sin6_addr)) 660 ia2.s6_addr16[1] = htons(sa->sin6_scope_id); 661 662 return IN6_ARE_ADDR_EQUAL(ia, &ia2); 663 } 664 665 /* 666 * IPsec output logic for IPv6. 667 */ 668 int 669 ipsec6_process_packet(struct mbuf *m, struct ipsecrequest *isr) 670 { 671 char sbuf[INET6_ADDRSTRLEN], dbuf[INET6_ADDRSTRLEN]; 672 struct secasindex saidx; 673 struct secasvar *sav; 674 struct ip6_hdr *ip6; 675 int error, i, off; 676 union sockaddr_union *dst; 677 678 IPSEC_ASSERT(m != NULL, ("ipsec6_process_packet: null mbuf")); 679 IPSEC_ASSERT(isr != NULL, ("ipsec6_process_packet: null isr")); 680 681 IPSECREQUEST_LOCK(isr); /* insure SA contents don't change */ 682 683 isr = ipsec_nextisr(m, isr, AF_INET6, &saidx, &error); 684 if (isr == NULL) { 685 if (error != 0) 686 goto bad; 687 return EJUSTRETURN; 688 } 689 sav = isr->sav; 690 dst = &sav->sah->saidx.dst; 691 692 ip6 = mtod(m, struct ip6_hdr *); 693 ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); 694 #ifdef DEV_ENC 695 if_inc_counter(encif, IFCOUNTER_OPACKETS, 1); 696 if_inc_counter(encif, IFCOUNTER_OBYTES, m->m_pkthdr.len); 697 698 /* pass the mbuf to enc0 for bpf processing */ 699 ipsec_bpf(m, isr->sav, AF_INET6, ENC_OUT|ENC_BEFORE); 700 /* pass the mbuf to enc0 for packet filtering */ 701 if ((error = ipsec_filter(&m, PFIL_OUT, ENC_OUT|ENC_BEFORE)) != 0) 702 goto bad; 703 ip6 = mtod(m, struct ip6_hdr *); 704 #endif /* DEV_ENC */ 705 706 /* Do the appropriate encapsulation, if necessary */ 707 if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */ 708 dst->sa.sa_family != AF_INET6 || /* PF mismatch */ 709 ((dst->sa.sa_family == AF_INET6) && 710 (!IN6_IS_ADDR_UNSPECIFIED(&dst->sin6.sin6_addr)) && 711 (!in6_sa_equal_addrwithscope(&dst->sin6, 712 &ip6->ip6_dst)))) { 713 if (m->m_pkthdr.len - sizeof(*ip6) > IPV6_MAXPACKET) { 714 /* No jumbogram support. */ 715 error = ENXIO; /*XXX*/ 716 goto bad; 717 } 718 error = ipsec_encap(&m, &sav->sah->saidx); 719 if (error != 0) { 720 DPRINTF(("%s: encapsulation for SA %s->%s " 721 "SPI 0x%08x failed with error %d\n", __func__, 722 ipsec_address(&sav->sah->saidx.src, sbuf, 723 sizeof(sbuf)), 724 ipsec_address(&sav->sah->saidx.dst, dbuf, 725 sizeof(dbuf)), ntohl(sav->spi), error)); 726 goto bad; 727 } 728 } 729 730 #ifdef DEV_ENC 731 ipsec_bpf(m, isr->sav, dst->sa.sa_family, ENC_OUT|ENC_AFTER); 732 /* pass the mbuf to enc0 for packet filtering */ 733 if ((error = ipsec_filter(&m, PFIL_OUT, ENC_OUT|ENC_AFTER)) != 0) 734 goto bad; 735 #endif /* DEV_ENC */ 736 737 switch(dst->sa.sa_family) { 738 #ifdef INET 739 case AF_INET: 740 { 741 struct ip *ip; 742 ip = mtod(m, struct ip *); 743 i = ip->ip_hl << 2; 744 off = offsetof(struct ip, ip_p); 745 } 746 break; 747 #endif /* AF_INET */ 748 case AF_INET6: 749 i = sizeof(struct ip6_hdr); 750 off = offsetof(struct ip6_hdr, ip6_nxt); 751 break; 752 default: 753 DPRINTF(("%s: unsupported protocol family %u\n", 754 __func__, dst->sa.sa_family)); 755 error = EPFNOSUPPORT; 756 IPSEC6STAT_INC(ips_out_inval); 757 goto bad; 758 } 759 error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off); 760 IPSECREQUEST_UNLOCK(isr); 761 return error; 762 bad: 763 764 if (isr) 765 IPSECREQUEST_UNLOCK(isr); 766 if (m) 767 m_freem(m); 768 return error; 769 } 770 #endif /*INET6*/ 771