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
This commit is contained in:
John Baldwin 2021-01-19 11:51:27 -08:00
parent c6e27f5697
commit 8e9313caa6

View File

@ -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;
}