Changeset View
Changeset View
Standalone View
Standalone View
sys/netipsec/ipsec_output.c
Show First 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | else \ | ||||
IPCOMPSTAT_INC(ipcomps_##name); \ | IPCOMPSTAT_INC(ipcomps_##name); \ | ||||
} while (0) | } while (0) | ||||
static int ipsec_encap(struct mbuf **mp, struct secasindex *saidx); | static int ipsec_encap(struct mbuf **mp, struct secasindex *saidx); | ||||
static size_t ipsec_get_pmtu(struct secasvar *sav); | static size_t ipsec_get_pmtu(struct secasvar *sav); | ||||
#ifdef INET | #ifdef INET | ||||
static struct secasvar * | static struct secasvar * | ||||
ipsec4_allocsa(struct mbuf *m, struct secpolicy *sp, u_int *pidx, int *error) | ipsec4_allocsa(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp, | ||||
u_int *pidx, int *error) | |||||
{ | { | ||||
struct secasindex *saidx, tmpsaidx; | struct secasindex *saidx, tmpsaidx; | ||||
struct ipsecrequest *isr; | struct ipsecrequest *isr; | ||||
struct sockaddr_in *sin; | struct sockaddr_in *sin; | ||||
struct secasvar *sav; | struct secasvar *sav; | ||||
struct ip *ip; | struct ip *ip; | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | next: | ||||
IPSEC_ASSERT(sav->tdb_xform != NULL, ("SA with NULL tdb_xform")); | IPSEC_ASSERT(sav->tdb_xform != NULL, ("SA with NULL tdb_xform")); | ||||
return (sav); | return (sav); | ||||
} | } | ||||
/* | /* | ||||
* IPsec output logic for IPv4. | * IPsec output logic for IPv4. | ||||
*/ | */ | ||||
static int | static int | ||||
ipsec4_perform_request(struct mbuf *m, struct secpolicy *sp, | ipsec4_perform_request(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp, | ||||
struct inpcb *inp, u_int idx) | struct inpcb *inp, u_int idx) | ||||
{ | { | ||||
struct ipsec_ctx_data ctx; | struct ipsec_ctx_data ctx; | ||||
union sockaddr_union *dst; | union sockaddr_union *dst; | ||||
struct secasvar *sav; | struct secasvar *sav; | ||||
struct ip *ip; | struct ip *ip; | ||||
int error, i, off; | int error, i, off; | ||||
IPSEC_ASSERT(idx < sp->tcount, ("Wrong IPsec request index %d", idx)); | IPSEC_ASSERT(idx < sp->tcount, ("Wrong IPsec request index %d", idx)); | ||||
/* | /* | ||||
* We hold the reference to SP. Content of SP couldn't be changed. | * We hold the reference to SP. Content of SP couldn't be changed. | ||||
* Craft secasindex and do lookup for suitable SA. | * Craft secasindex and do lookup for suitable SA. | ||||
* Then do encapsulation if needed and call xform's output. | * Then do encapsulation if needed and call xform's output. | ||||
* We need to store SP in the xform callback parameters. | * We need to store SP in the xform callback parameters. | ||||
* In xform callback we will extract SP and it can be used to | * In xform callback we will extract SP and it can be used to | ||||
* determine next transform. At the end of transform we can | * determine next transform. At the end of transform we can | ||||
* release reference to SP. | * release reference to SP. | ||||
*/ | */ | ||||
sav = ipsec4_allocsa(m, sp, &idx, &error); | sav = ipsec4_allocsa(ifp, m, sp, &idx, &error); | ||||
if (sav == NULL) { | if (sav == NULL) { | ||||
if (error == EJUSTRETURN) { /* No IPsec required */ | if (error == EJUSTRETURN) { /* No IPsec required */ | ||||
key_freesp(&sp); | key_freesp(&sp); | ||||
return (error); | return (error); | ||||
} | } | ||||
goto bad; | goto bad; | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | if (m != NULL) | ||||
m_freem(m); | m_freem(m); | ||||
if (sav != NULL) | if (sav != NULL) | ||||
key_freesav(&sav); | key_freesav(&sav); | ||||
key_freesp(&sp); | key_freesp(&sp); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
ipsec4_process_packet(struct mbuf *m, struct secpolicy *sp, | ipsec4_process_packet(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp, | ||||
struct inpcb *inp) | struct inpcb *inp) | ||||
{ | { | ||||
return (ipsec4_perform_request(m, sp, inp, 0)); | return (ipsec4_perform_request(ifp, m, sp, inp, 0)); | ||||
} | } | ||||
int | int | ||||
ipsec4_check_pmtu(struct mbuf *m, struct secpolicy *sp, int forwarding) | ipsec4_check_pmtu(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp, | ||||
int forwarding) | |||||
{ | { | ||||
struct secasvar *sav; | struct secasvar *sav; | ||||
struct ip *ip; | struct ip *ip; | ||||
size_t hlen, pmtu; | size_t hlen, pmtu; | ||||
uint32_t idx; | uint32_t idx; | ||||
int error; | int error; | ||||
/* Don't check PMTU if the frame won't have DF bit set. */ | /* Don't check PMTU if the frame won't have DF bit set. */ | ||||
if (!V_ip4_ipsec_dfbit) | if (!V_ip4_ipsec_dfbit) | ||||
return (0); | return (0); | ||||
if (V_ip4_ipsec_dfbit == 1) | if (V_ip4_ipsec_dfbit == 1) | ||||
goto setdf; | goto setdf; | ||||
/* V_ip4_ipsec_dfbit > 1 - we will copy it from inner header. */ | /* V_ip4_ipsec_dfbit > 1 - we will copy it from inner header. */ | ||||
ip = mtod(m, struct ip *); | ip = mtod(m, struct ip *); | ||||
if (!(ip->ip_off & htons(IP_DF))) | if (!(ip->ip_off & htons(IP_DF))) | ||||
return (0); | return (0); | ||||
setdf: | setdf: | ||||
idx = sp->tcount - 1; | idx = sp->tcount - 1; | ||||
sav = ipsec4_allocsa(m, sp, &idx, &error); | sav = ipsec4_allocsa(ifp, m, sp, &idx, &error); | ||||
if (sav == NULL) { | if (sav == NULL) { | ||||
key_freesp(&sp); | key_freesp(&sp); | ||||
/* | /* | ||||
* No matching SA was found and SADB_ACQUIRE message was generated. | * No matching SA was found and SADB_ACQUIRE message was generated. | ||||
* Since we have matched a SP to this packet drop it silently. | * Since we have matched a SP to this packet drop it silently. | ||||
*/ | */ | ||||
if (error == 0) | if (error == 0) | ||||
error = EINPROGRESS; | error = EINPROGRESS; | ||||
Show All 34 Lines | if (forwarding) { | ||||
return (EMSGSIZE); | return (EMSGSIZE); | ||||
} | } | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
ipsec4_common_output(struct mbuf *m, struct inpcb *inp, int forwarding) | ipsec4_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp, | ||||
int forwarding) | |||||
{ | { | ||||
struct secpolicy *sp; | struct secpolicy *sp; | ||||
int error; | int error; | ||||
/* Lookup for the corresponding outbound security policy */ | /* Lookup for the corresponding outbound security policy */ | ||||
sp = ipsec4_checkpolicy(m, inp, &error, !forwarding); | sp = ipsec4_checkpolicy(m, inp, &error, !forwarding); | ||||
if (sp == NULL) { | if (sp == NULL) { | ||||
if (error == -EINVAL) { | if (error == -EINVAL) { | ||||
Show All 27 Lines | if (m->m_pkthdr.csum_flags & CSUM_SCTP) { | ||||
ip = mtod(m, struct ip *); | ip = mtod(m, struct ip *); | ||||
sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); | sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); | ||||
m->m_pkthdr.csum_flags &= ~CSUM_SCTP; | m->m_pkthdr.csum_flags &= ~CSUM_SCTP; | ||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
/* NB: callee frees mbuf and releases reference to SP */ | /* NB: callee frees mbuf and releases reference to SP */ | ||||
error = ipsec4_check_pmtu(m, sp, forwarding); | error = ipsec4_check_pmtu(ifp, m, sp, forwarding); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (error == EJUSTRETURN) | if (error == EJUSTRETURN) | ||||
return (0); | return (0); | ||||
return (error); | return (error); | ||||
} | } | ||||
error = ipsec4_process_packet(m, sp, inp); | error = ipsec4_process_packet(ifp, m, sp, inp); | ||||
if (error == EJUSTRETURN) { | if (error == EJUSTRETURN) { | ||||
/* | /* | ||||
* We had a SP with a level of 'use' and no SA. We | * We had a SP with a level of 'use' and no SA. We | ||||
* will just continue to process the packet without | * will just continue to process the packet without | ||||
* IPsec processing and return without error. | * IPsec processing and return without error. | ||||
*/ | */ | ||||
return (0); | return (0); | ||||
} | } | ||||
if (error == 0) | if (error == 0) | ||||
return (EINPROGRESS); /* consumed by IPsec */ | return (EINPROGRESS); /* consumed by IPsec */ | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* IPSEC_OUTPUT() method implementation for IPv4. | * IPSEC_OUTPUT() method implementation for IPv4. | ||||
* 0 - no IPsec handling needed | * 0 - no IPsec handling needed | ||||
* other values - mbuf consumed by IPsec. | * other values - mbuf consumed by IPsec. | ||||
*/ | */ | ||||
int | int | ||||
ipsec4_output(struct mbuf *m, struct inpcb *inp) | ipsec4_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp) | ||||
{ | { | ||||
/* | /* | ||||
* If the packet is resubmitted to ip_output (e.g. after | * If the packet is resubmitted to ip_output (e.g. after | ||||
* AH, ESP, etc. processing), there will be a tag to bypass | * AH, ESP, etc. processing), there will be a tag to bypass | ||||
* the lookup and related policy checking. | * the lookup and related policy checking. | ||||
*/ | */ | ||||
if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL) | if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL) | ||||
return (0); | return (0); | ||||
return (ipsec4_common_output(m, inp, 0)); | return (ipsec4_common_output(ifp, m, inp, 0)); | ||||
} | } | ||||
/* | /* | ||||
* IPSEC_FORWARD() method implementation for IPv4. | * IPSEC_FORWARD() method implementation for IPv4. | ||||
* 0 - no IPsec handling needed | * 0 - no IPsec handling needed | ||||
* other values - mbuf consumed by IPsec. | * other values - mbuf consumed by IPsec. | ||||
*/ | */ | ||||
int | int | ||||
ipsec4_forward(struct mbuf *m) | ipsec4_forward(struct mbuf *m) | ||||
{ | { | ||||
/* | /* | ||||
* Check if this packet has an active inbound SP and needs to be | * Check if this packet has an active inbound SP and needs to be | ||||
* dropped instead of forwarded. | * dropped instead of forwarded. | ||||
*/ | */ | ||||
if (ipsec4_in_reject(m, NULL) != 0) { | if (ipsec4_in_reject(m, NULL) != 0) { | ||||
m_freem(m); | m_freem(m); | ||||
return (EACCES); | return (EACCES); | ||||
} | } | ||||
return (ipsec4_common_output(m, NULL, 1)); | return (ipsec4_common_output(NULL /* XXXKIB */, m, NULL, 1)); | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef INET6 | #ifdef INET6 | ||||
static int | static int | ||||
in6_sa_equal_addrwithscope(const struct sockaddr_in6 *sa, | in6_sa_equal_addrwithscope(const struct sockaddr_in6 *sa, | ||||
const struct in6_addr *ia) | const struct in6_addr *ia) | ||||
{ | { | ||||
struct in6_addr ia2; | struct in6_addr ia2; | ||||
if (IN6_IS_SCOPE_LINKLOCAL(&sa->sin6_addr)) { | if (IN6_IS_SCOPE_LINKLOCAL(&sa->sin6_addr)) { | ||||
memcpy(&ia2, &sa->sin6_addr, sizeof(ia2)); | memcpy(&ia2, &sa->sin6_addr, sizeof(ia2)); | ||||
ia2.s6_addr16[1] = htons(sa->sin6_scope_id); | ia2.s6_addr16[1] = htons(sa->sin6_scope_id); | ||||
return (IN6_ARE_ADDR_EQUAL(ia, &ia2)); | return (IN6_ARE_ADDR_EQUAL(ia, &ia2)); | ||||
} | } | ||||
return (IN6_ARE_ADDR_EQUAL(&sa->sin6_addr, ia)); | return (IN6_ARE_ADDR_EQUAL(&sa->sin6_addr, ia)); | ||||
} | } | ||||
static struct secasvar * | static struct secasvar * | ||||
ipsec6_allocsa(struct mbuf *m, struct secpolicy *sp, u_int *pidx, int *error) | ipsec6_allocsa(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp, | ||||
u_int *pidx, int *error) | |||||
{ | { | ||||
struct secasindex *saidx, tmpsaidx; | struct secasindex *saidx, tmpsaidx; | ||||
struct ipsecrequest *isr; | struct ipsecrequest *isr; | ||||
struct sockaddr_in6 *sin6; | struct sockaddr_in6 *sin6; | ||||
struct secasvar *sav; | struct secasvar *sav; | ||||
struct ip6_hdr *ip6; | struct ip6_hdr *ip6; | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | next: | ||||
IPSEC_ASSERT(sav->tdb_xform != NULL, ("SA with NULL tdb_xform")); | IPSEC_ASSERT(sav->tdb_xform != NULL, ("SA with NULL tdb_xform")); | ||||
return (sav); | return (sav); | ||||
} | } | ||||
/* | /* | ||||
* IPsec output logic for IPv6. | * IPsec output logic for IPv6. | ||||
*/ | */ | ||||
static int | static int | ||||
ipsec6_perform_request(struct mbuf *m, struct secpolicy *sp, | ipsec6_perform_request(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp, | ||||
struct inpcb *inp, u_int idx) | struct inpcb *inp, u_int idx) | ||||
{ | { | ||||
struct ipsec_ctx_data ctx; | struct ipsec_ctx_data ctx; | ||||
union sockaddr_union *dst; | union sockaddr_union *dst; | ||||
struct secasvar *sav; | struct secasvar *sav; | ||||
struct ip6_hdr *ip6; | struct ip6_hdr *ip6; | ||||
int error, i, off; | int error, i, off; | ||||
IPSEC_ASSERT(idx < sp->tcount, ("Wrong IPsec request index %d", idx)); | IPSEC_ASSERT(idx < sp->tcount, ("Wrong IPsec request index %d", idx)); | ||||
sav = ipsec6_allocsa(m, sp, &idx, &error); | sav = ipsec6_allocsa(ifp, m, sp, &idx, &error); | ||||
if (sav == NULL) { | if (sav == NULL) { | ||||
if (error == EJUSTRETURN) { /* No IPsec required */ | if (error == EJUSTRETURN) { /* No IPsec required */ | ||||
key_freesp(&sp); | key_freesp(&sp); | ||||
return (error); | return (error); | ||||
} | } | ||||
goto bad; | goto bad; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | if (m != NULL) | ||||
m_freem(m); | m_freem(m); | ||||
if (sav != NULL) | if (sav != NULL) | ||||
key_freesav(&sav); | key_freesav(&sav); | ||||
key_freesp(&sp); | key_freesp(&sp); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
ipsec6_process_packet(struct mbuf *m, struct secpolicy *sp, | ipsec6_process_packet(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp, | ||||
struct inpcb *inp) | struct inpcb *inp) | ||||
{ | { | ||||
return (ipsec6_perform_request(m, sp, inp, 0)); | return (ipsec6_perform_request(ifp, m, sp, inp, 0)); | ||||
} | } | ||||
/* | /* | ||||
* IPv6 implementation is based on IPv4 implementation. | * IPv6 implementation is based on IPv4 implementation. | ||||
*/ | */ | ||||
int | int | ||||
ipsec6_check_pmtu(struct mbuf *m, struct secpolicy *sp, int forwarding) | ipsec6_check_pmtu(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp, | ||||
int forwarding) | |||||
{ | { | ||||
struct secasvar *sav; | struct secasvar *sav; | ||||
size_t hlen, pmtu; | size_t hlen, pmtu; | ||||
uint32_t idx; | uint32_t idx; | ||||
int error; | int error; | ||||
/* | /* | ||||
* According to RFC8200 L3 fragmentation is supposed to be done only on | * According to RFC8200 L3 fragmentation is supposed to be done only on | ||||
* locally generated packets. During L3 forwarding packets that are too | * locally generated packets. During L3 forwarding packets that are too | ||||
* big are always supposed to be dropped, with an ICMPv6 packet being | * big are always supposed to be dropped, with an ICMPv6 packet being | ||||
* sent back. | * sent back. | ||||
*/ | */ | ||||
if (!forwarding) | if (!forwarding) | ||||
return (0); | return (0); | ||||
idx = sp->tcount - 1; | idx = sp->tcount - 1; | ||||
sav = ipsec6_allocsa(m, sp, &idx, &error); | sav = ipsec6_allocsa(ifp, m, sp, &idx, &error); | ||||
if (sav == NULL) { | if (sav == NULL) { | ||||
key_freesp(&sp); | key_freesp(&sp); | ||||
/* | /* | ||||
* No matching SA was found and SADB_ACQUIRE message was generated. | * No matching SA was found and SADB_ACQUIRE message was generated. | ||||
* Since we have matched a SP to this packet drop it silently. | * Since we have matched a SP to this packet drop it silently. | ||||
*/ | */ | ||||
if (error == 0) | if (error == 0) | ||||
error = EINPROGRESS; | error = EINPROGRESS; | ||||
Show All 29 Lines | if (forwarding) { | ||||
return (EINPROGRESS); /* Pretend that we consumed it. */ | return (EINPROGRESS); /* Pretend that we consumed it. */ | ||||
} | } | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
ipsec6_common_output(struct mbuf *m, struct inpcb *inp, int forwarding) | ipsec6_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp, | ||||
int forwarding) | |||||
{ | { | ||||
struct secpolicy *sp; | struct secpolicy *sp; | ||||
int error; | int error; | ||||
/* Lookup for the corresponding outbound security policy */ | /* Lookup for the corresponding outbound security policy */ | ||||
sp = ipsec6_checkpolicy(m, inp, &error, !forwarding); | sp = ipsec6_checkpolicy(m, inp, &error, !forwarding); | ||||
if (sp == NULL) { | if (sp == NULL) { | ||||
if (error == -EINVAL) { | if (error == -EINVAL) { | ||||
Show All 17 Lines | |||||
#if defined(SCTP) || defined(SCTP_SUPPORT) | #if defined(SCTP) || defined(SCTP_SUPPORT) | ||||
if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) { | if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) { | ||||
sctp_delayed_cksum(m, sizeof(struct ip6_hdr)); | sctp_delayed_cksum(m, sizeof(struct ip6_hdr)); | ||||
m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6; | m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6; | ||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
error = ipsec6_check_pmtu(m, sp, forwarding); | error = ipsec6_check_pmtu(ifp, m, sp, forwarding); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (error == EJUSTRETURN) | if (error == EJUSTRETURN) | ||||
return (0); | return (0); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* NB: callee frees mbuf and releases reference to SP */ | /* NB: callee frees mbuf and releases reference to SP */ | ||||
error = ipsec6_process_packet(m, sp, inp); | error = ipsec6_process_packet(ifp, m, sp, inp); | ||||
if (error == EJUSTRETURN) { | if (error == EJUSTRETURN) { | ||||
/* | /* | ||||
* We had a SP with a level of 'use' and no SA. We | * We had a SP with a level of 'use' and no SA. We | ||||
* will just continue to process the packet without | * will just continue to process the packet without | ||||
* IPsec processing and return without error. | * IPsec processing and return without error. | ||||
*/ | */ | ||||
return (0); | return (0); | ||||
} | } | ||||
if (error == 0) | if (error == 0) | ||||
return (EINPROGRESS); /* consumed by IPsec */ | return (EINPROGRESS); /* consumed by IPsec */ | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* IPSEC_OUTPUT() method implementation for IPv6. | * IPSEC_OUTPUT() method implementation for IPv6. | ||||
* 0 - no IPsec handling needed | * 0 - no IPsec handling needed | ||||
* other values - mbuf consumed by IPsec. | * other values - mbuf consumed by IPsec. | ||||
*/ | */ | ||||
int | int | ||||
ipsec6_output(struct mbuf *m, struct inpcb *inp) | ipsec6_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp) | ||||
{ | { | ||||
/* | /* | ||||
* If the packet is resubmitted to ip_output (e.g. after | * If the packet is resubmitted to ip_output (e.g. after | ||||
* AH, ESP, etc. processing), there will be a tag to bypass | * AH, ESP, etc. processing), there will be a tag to bypass | ||||
* the lookup and related policy checking. | * the lookup and related policy checking. | ||||
*/ | */ | ||||
if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL) | if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL) | ||||
return (0); | return (0); | ||||
return (ipsec6_common_output(m, inp, 0)); | return (ipsec6_common_output(ifp, m, inp, 0)); | ||||
} | } | ||||
/* | /* | ||||
* IPSEC_FORWARD() method implementation for IPv6. | * IPSEC_FORWARD() method implementation for IPv6. | ||||
* 0 - no IPsec handling needed | * 0 - no IPsec handling needed | ||||
* other values - mbuf consumed by IPsec. | * other values - mbuf consumed by IPsec. | ||||
*/ | */ | ||||
int | int | ||||
ipsec6_forward(struct mbuf *m) | ipsec6_forward(struct mbuf *m) | ||||
{ | { | ||||
/* | /* | ||||
* Check if this packet has an active inbound SP and needs to be | * Check if this packet has an active inbound SP and needs to be | ||||
* dropped instead of forwarded. | * dropped instead of forwarded. | ||||
*/ | */ | ||||
if (ipsec6_in_reject(m, NULL) != 0) { | if (ipsec6_in_reject(m, NULL) != 0) { | ||||
m_freem(m); | m_freem(m); | ||||
return (EACCES); | return (EACCES); | ||||
} | } | ||||
return (ipsec6_common_output(m, NULL, 1)); | return (ipsec6_common_output(NULL /* XXXKIB */, m, NULL, 1)); | ||||
} | } | ||||
#endif /* INET6 */ | #endif /* INET6 */ | ||||
int | int | ||||
ipsec_process_done(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, | ipsec_process_done(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, | ||||
u_int idx) | u_int idx) | ||||
{ | { | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | #endif /* INET6 */ | ||||
* doing further processing. | * doing further processing. | ||||
*/ | */ | ||||
if (++idx < sp->tcount) { | if (++idx < sp->tcount) { | ||||
switch (saidx->dst.sa.sa_family) { | switch (saidx->dst.sa.sa_family) { | ||||
#ifdef INET | #ifdef INET | ||||
case AF_INET: | case AF_INET: | ||||
key_freesav(&sav); | key_freesav(&sav); | ||||
IPSECSTAT_INC(ips_out_bundlesa); | IPSECSTAT_INC(ips_out_bundlesa); | ||||
return (ipsec4_perform_request(m, sp, NULL, idx)); | return (ipsec4_perform_request(NULL, m, sp, NULL, | ||||
idx)); | |||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
#endif | #endif | ||||
#ifdef INET6 | #ifdef INET6 | ||||
case AF_INET6: | case AF_INET6: | ||||
key_freesav(&sav); | key_freesav(&sav); | ||||
IPSEC6STAT_INC(ips_out_bundlesa); | IPSEC6STAT_INC(ips_out_bundlesa); | ||||
return (ipsec6_perform_request(m, sp, NULL, idx)); | return (ipsec6_perform_request(NULL, m, sp, NULL, | ||||
idx)); | |||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
#endif /* INET6 */ | #endif /* INET6 */ | ||||
default: | default: | ||||
DPRINTF(("%s: unknown protocol family %u\n", __func__, | DPRINTF(("%s: unknown protocol family %u\n", __func__, | ||||
saidx->dst.sa.sa_family)); | saidx->dst.sa.sa_family)); | ||||
error = EPFNOSUPPORT; | error = EPFNOSUPPORT; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 246 Lines • Show Last 20 Lines |