git: faba420cb9b1 - stable/13 - ip_divert: calculate delayed checksum for IPv6 adress family

From: Andrey V. Elsukov <ae_at_FreeBSD.org>
Date: Fri, 12 Nov 2021 12:20:23 UTC
The branch stable/13 has been updated by ae:

URL: https://cgit.FreeBSD.org/src/commit/?id=faba420cb9b1f60d04bbf9f3f4e2ab89894ba898

commit faba420cb9b1f60d04bbf9f3f4e2ab89894ba898
Author:     Andrey V. Elsukov <ae@FreeBSD.org>
AuthorDate: 2021-11-02 16:59:06 +0000
Commit:     Andrey V. Elsukov <ae@FreeBSD.org>
CommitDate: 2021-11-12 12:19:19 +0000

    ip_divert: calculate delayed checksum for IPv6 adress family
    
    Before passing an IPv6 packet to application apply delayed checksum
    calculation. Mbuf flags will be lost when divert listener will return a
    packet back, so we will not be able to do delayed checksum calculation
    later. Also an application will get a packet with correct checksum.
    
    Reviewed by:    donner
    Differential Revision: https://reviews.freebsd.org/D32807
    
    (cherry picked from commit 4a9e95286cacce5bf7cd193b43c4a461cf7d69b8)
---
 sys/netinet/ip_divert.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 4141386a6a2d..4919893d6a61 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -227,6 +227,25 @@ divert_packet(struct mbuf *m, bool incoming)
 		m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
 	}
 #endif
+#ifdef INET6
+	if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
+		m = mb_unmapped_to_ext(m);
+		if (m == NULL)
+			return;
+		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;
+	}
+#if defined(SCTP) || defined(SCTP_SUPPORT)
+	if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) {
+		m = mb_unmapped_to_ext(m);
+		if (m == NULL)
+			return;
+		sctp_delayed_cksum(m, sizeof(struct ip6_hdr));
+		m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6;
+	}
+#endif
+#endif /* INET6 */
 	bzero(&divsrc, sizeof(divsrc));
 	divsrc.sin_len = sizeof(divsrc);
 	divsrc.sin_family = AF_INET;