| 608 | } |
| 609 | |
| 610 | static int |
| 611 | ipsec6_common_output(struct mbuf *m, struct inpcb *inp, int forwarding) |
| 612 | { |
| 613 | struct secpolicy *sp; |
| 614 | int error; |
| 615 | |
| 616 | /* Lookup for the corresponding outbound security policy */ |
| 617 | sp = ipsec6_checkpolicy(m, inp, &error, !forwarding); |
| 618 | if (sp == NULL) { |
| 619 | if (error == -EINVAL) { |
| 620 | /* Discarded by policy. */ |
| 621 | m_freem(m); |
| 622 | return (EACCES); |
| 623 | } |
| 624 | return (0); /* No IPsec required. */ |
| 625 | } |
| 626 | |
| 627 | if (!forwarding) { |
| 628 | /* |
| 629 | * Do delayed checksums now because we send before |
| 630 | * this is done in the normal processing path. |
| 631 | */ |
| 632 | if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { |
| 633 | m = mb_unmapped_to_ext(m); |
| 634 | if (m == NULL) { |
| 635 | IPSEC6STAT_INC(ips_out_nomem); |
| 636 | key_freesp(&sp); |
| 637 | return (ENOBUFS); |
| 638 | } |
| 639 | in6_delayed_cksum(m, m->m_pkthdr.len - |
| 640 | sizeof(struct ip6_hdr), sizeof(struct ip6_hdr)); |
| 641 | m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6; |
| 642 | } |
| 643 | #if defined(SCTP) || defined(SCTP_SUPPORT) |
| 644 | if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) { |
| 645 | m = mb_unmapped_to_ext(m); |
| 646 | if (m == NULL) { |
| 647 | IPSEC6STAT_INC(ips_out_nomem); |
| 648 | key_freesp(&sp); |
| 649 | return (ENOBUFS); |
| 650 | } |
| 651 | sctp_delayed_cksum(m, sizeof(struct ip6_hdr)); |
| 652 | m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6; |
| 653 | } |
| 654 | #endif |
| 655 | } |
| 656 | /* NB: callee frees mbuf and releases reference to SP */ |
| 657 | error = ipsec6_process_packet(m, sp, inp); |
| 658 | if (error == EJUSTRETURN) { |
| 659 | /* |
| 660 | * We had a SP with a level of 'use' and no SA. We |
| 661 | * will just continue to process the packet without |
| 662 | * IPsec processing and return without error. |
| 663 | */ |
| 664 | return (0); |
| 665 | } |
| 666 | if (error == 0) |
| 667 | return (EINPROGRESS); /* consumed by IPsec */ |
no test coverage detected