static int ipf_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) { #if defined(INET6) # if defined(M_CSUM_TCPv6) && (__NetBSD_Version__ > 200000000) /* * If the packet is out-bound, we can't delay checksums * here. For in-bound, the checksum has already been * validated. */ if (dir == PFIL_OUT) { if ((*mp)->m_pkthdr.csum_flags & (M_CSUM_TCPv6|M_CSUM_UDPv6)) { # if (__NetBSD_Version__ > 399000600) in6_delayed_cksum(*mp); # endif (*mp)->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv6| M_CSUM_UDPv6); } } # endif #endif /* INET6 */ return (ipf_check(&ipfmain, mtod(*mp, struct ip *), sizeof(struct ip6_hdr), ifp, (dir == PFIL_OUT), mp)); }
int ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error) { #ifdef IPSEC struct secpolicy *sp; /* * Check the security policy (SP) for the packet and, if * required, do IPsec-related processing. There are two * cases here; the first time a packet is sent through * it will be untagged and handled by ipsec4_checkpolicy. * If the packet is resubmitted to ip6_output (e.g. after * AH, ESP, etc. processing), there will be a tag to bypass * the lookup and related policy checking. */ if (m_tag_find(*m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL) { *error = 0; return (0); } sp = ipsec4_checkpolicy(*m, IPSEC_DIR_OUTBOUND, error, inp); /* * There are four return cases: * sp != NULL apply IPsec policy * sp == NULL, error == 0 no IPsec handling needed * sp == NULL, error == -EINVAL discard packet w/o error * sp == NULL, error != 0 discard packet, report error */ if (sp != NULL) { /* * Do delayed checksums now because we send before * this is done in the normal processing path. */ #ifdef INET if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { in_delayed_cksum(*m); (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; } #endif if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { in6_delayed_cksum(*m, (*m)->m_pkthdr.len - sizeof(struct ip6_hdr), sizeof(struct ip6_hdr)); (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6; } #ifdef SCTP if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) { sctp_delayed_cksum(*m, sizeof(struct ip6_hdr)); (*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6; } #endif /* NB: callee frees mbuf */ *error = ipsec6_process_packet(*m, sp->req); if (*error == EJUSTRETURN) { /* * We had a SP with a level of 'use' and no SA. We * will just continue to process the packet without * IPsec processing. */ *error = 0; goto done; } /* * Preserve KAME behaviour: ENOENT can be returned * when an SA acquire is in progress. Don't propagate * this to user-level; it confuses applications. * * XXX this will go away when the SADB is redone. */ if (*error == ENOENT) *error = 0; goto reinjected; } else { /* sp == NULL */ if (*error != 0) { /* * Hack: -EINVAL is used to signal that a packet * should be silently discarded. This is typically * because we asked key management for an SA and * it was delayed (e.g. kicked up to IKE). */ if (*error == -EINVAL) *error = 0; goto bad; } /* No IPsec processing for this packet. */ } done: if (sp != NULL) KEY_FREESP(&sp); return 0; reinjected: if (sp != NULL) KEY_FREESP(&sp); return -1; bad: if (sp != NULL) KEY_FREESP(&sp); return 1; #endif /* IPSEC */ return 0; }