| 420 | } |
| 421 | |
| 422 | static struct secasvar * |
| 423 | ipsec6_allocsa(struct mbuf *m, struct secpolicy *sp, u_int *pidx, int *error) |
| 424 | { |
| 425 | struct secasindex *saidx, tmpsaidx; |
| 426 | struct ipsecrequest *isr; |
| 427 | struct sockaddr_in6 *sin6; |
| 428 | struct secasvar *sav; |
| 429 | struct ip6_hdr *ip6; |
| 430 | |
| 431 | /* |
| 432 | * Check system global policy controls. |
| 433 | */ |
| 434 | next: |
| 435 | isr = sp->req[*pidx]; |
| 436 | if ((isr->saidx.proto == IPPROTO_ESP && !V_esp_enable) || |
| 437 | (isr->saidx.proto == IPPROTO_AH && !V_ah_enable) || |
| 438 | (isr->saidx.proto == IPPROTO_IPCOMP && !V_ipcomp_enable)) { |
| 439 | DPRINTF(("%s: IPsec outbound packet dropped due" |
| 440 | " to policy (check your sysctls)\n", __func__)); |
| 441 | IPSEC_OSTAT_INC(isr->saidx.proto, pdrops); |
| 442 | *error = EHOSTUNREACH; |
| 443 | return (NULL); |
| 444 | } |
| 445 | /* |
| 446 | * Craft SA index to search for proper SA. Note that |
| 447 | * we only fillin unspecified SA peers for transport |
| 448 | * mode; for tunnel mode they must already be filled in. |
| 449 | */ |
| 450 | if (isr->saidx.mode == IPSEC_MODE_TRANSPORT) { |
| 451 | saidx = &tmpsaidx; |
| 452 | *saidx = isr->saidx; |
| 453 | ip6 = mtod(m, struct ip6_hdr *); |
| 454 | if (saidx->src.sin6.sin6_len == 0) { |
| 455 | sin6 = (struct sockaddr_in6 *)&saidx->src; |
| 456 | sin6->sin6_len = sizeof(*sin6); |
| 457 | sin6->sin6_family = AF_INET6; |
| 458 | sin6->sin6_port = IPSEC_PORT_ANY; |
| 459 | sin6->sin6_addr = ip6->ip6_src; |
| 460 | if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) { |
| 461 | /* fix scope id for comparing SPD */ |
| 462 | sin6->sin6_addr.s6_addr16[1] = 0; |
| 463 | sin6->sin6_scope_id = |
| 464 | ntohs(ip6->ip6_src.s6_addr16[1]); |
| 465 | } |
| 466 | } |
| 467 | if (saidx->dst.sin6.sin6_len == 0) { |
| 468 | sin6 = (struct sockaddr_in6 *)&saidx->dst; |
| 469 | sin6->sin6_len = sizeof(*sin6); |
| 470 | sin6->sin6_family = AF_INET6; |
| 471 | sin6->sin6_port = IPSEC_PORT_ANY; |
| 472 | sin6->sin6_addr = ip6->ip6_dst; |
| 473 | if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) { |
| 474 | /* fix scope id for comparing SPD */ |
| 475 | sin6->sin6_addr.s6_addr16[1] = 0; |
| 476 | sin6->sin6_scope_id = |
| 477 | ntohs(ip6->ip6_dst.s6_addr16[1]); |
| 478 | } |
| 479 | } |
no test coverage detected