aboutsummaryrefslogtreecommitdiff
path: root/sys/netipsec
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2021-01-19 19:51:27 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2021-01-19 19:52:00 +0000
commit8e9313caa6725f8c65fcacb147ce88a9ba6f6f2a (patch)
treee8f27cc13178511c9f2fef679a740ad562b8dce4 /sys/netipsec
parentc6e27f5697c28e188739ea1b4994dc8869dfb6c2 (diff)
downloadsrc-8e9313caa6725f8c65fcacb147ce88a9ba6f6f2a.tar.gz
src-8e9313caa6725f8c65fcacb147ce88a9ba6f6f2a.zip
Convert unmapped mbufs before computing checksums in IPsec.
This is similar to the logic used in ip_output() to convert mbufs prior to computing checksums. Unmapped mbufs can be sent when using sendfile() over IPsec or using KTLS over IPsec. Reported by: Sony Arpita Das @ Chelsio QA Reviewed by: np Sponsored by: Chelsio Differential Revision: https://reviews.freebsd.org/D28187
Diffstat (limited to 'sys/netipsec')
-rw-r--r--sys/netipsec/ipsec_output.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
index f95a35226f6f..86f06fd10947 100644
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -323,13 +323,26 @@ ipsec4_common_output(struct mbuf *m, struct inpcb *inp, int forwarding)
* this is done in the normal processing path.
*/
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ m = mb_unmapped_to_ext(m);
+ if (m == NULL) {
+ IPSECSTAT_INC(ips_out_nomem);
+ key_freesp(&sp);
+ return (ENOBUFS);
+ }
in_delayed_cksum(m);
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
#if defined(SCTP) || defined(SCTP_SUPPORT)
if (m->m_pkthdr.csum_flags & CSUM_SCTP) {
- struct ip *ip = mtod(m, struct ip *);
+ struct ip *ip;
+ m = mb_unmapped_to_ext(m);
+ if (m == NULL) {
+ IPSECSTAT_INC(ips_out_nomem);
+ key_freesp(&sp);
+ return (ENOBUFS);
+ }
+ ip = mtod(m, struct ip *);
sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2));
m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
}
@@ -617,12 +630,24 @@ ipsec6_common_output(struct mbuf *m, struct inpcb *inp, int forwarding)
* this is done in the normal processing path.
*/
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
+ m = mb_unmapped_to_ext(m);
+ if (m == NULL) {
+ IPSEC6STAT_INC(ips_out_nomem);
+ key_freesp(&sp);
+ return (ENOBUFS);
+ }
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;
+ m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
}
#if defined(SCTP) || defined(SCTP_SUPPORT)
if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) {
+ m = mb_unmapped_to_ext(m);
+ if (m == NULL) {
+ IPSEC6STAT_INC(ips_out_nomem);
+ key_freesp(&sp);
+ return (ENOBUFS);
+ }
sctp_delayed_cksum(m, sizeof(struct ip6_hdr));
m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6;
}