git: b0e020764aae - main - ipsec + ktls: cannot coexists

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 13 Jan 2025 19:30:12 UTC
The branch main has been updated by kib:

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

commit b0e020764aae970545357b0f146dcba7b4b55864
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-12-28 08:30:49 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-01-13 19:29:31 +0000

    ipsec + ktls: cannot coexists
    
    but instead of tripping the assert in debug kernel, and silently falling
    into UB for prod, skip IPSEC processing for KTLS framed packets when
    mb_unmapped_to_ext() failed.
    
    Reviewed by:    markj
    Sponsored by:   NVidia networking
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D48265
---
 sys/netinet/ip_output.c   | 33 +++++++++++++++++++++++++--------
 sys/netinet6/ip6_output.c | 34 ++++++++++++++++++++++++++--------
 2 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 770a95dae659..4f5d8b7279ba 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -667,17 +667,25 @@ again:
 sendit:
 #if defined(IPSEC) || defined(IPSEC_SUPPORT)
 	if (IPSEC_ENABLED(ipv4)) {
-		m = mb_unmapped_to_ext(m);
-		if (m == NULL) {
-			IPSTAT_INC(ips_odropped);
-			error = ENOBUFS;
-			goto bad;
+		struct mbuf *m1;
+
+		error = mb_unmapped_to_ext(m, &m1);
+		if (error != 0) {
+			if (error == ENOMEM) {
+				IPSTAT_INC(ips_odropped);
+				error = ENOBUFS;
+				goto bad;
+			}
+			/* XXXKIB */
+			goto no_ipsec;
 		}
+		m = m1;
 		if ((error = IPSEC_OUTPUT(ipv4, ifp, m, inp, mtu)) != 0) {
 			if (error == EINPROGRESS)
 				error = 0;
 			goto done;
 		}
+no_ipsec:;
 	}
 	/*
 	 * Check if there was a route for this packet; return error if not.
@@ -731,11 +739,20 @@ sendit:
 
 	/* Ensure the packet data is mapped if the interface requires it. */
 	if ((ifp->if_capenable & IFCAP_MEXTPG) == 0) {
-		m = mb_unmapped_to_ext(m);
-		if (m == NULL) {
+		struct mbuf *m1;
+
+		error = mb_unmapped_to_ext(m, &m1);
+		if (error != 0) {
+			if (error == EINVAL) {
+				if_printf(ifp, "TLS packet\n");
+				/* XXXKIB */
+			} else if (error == ENOMEM) {
+				error = ENOBUFS;
+			}
 			IPSTAT_INC(ips_odropped);
-			error = ENOBUFS;
 			goto bad;
+		} else {
+			m = m1;
 		}
 	}
 
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 9e4985cdc6cd..c6907835bc67 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -792,18 +792,26 @@ nonh6lookup:
 	 * XXX: need scope argument.
 	 */
 	if (IPSEC_ENABLED(ipv6)) {
-		m = mb_unmapped_to_ext(m);
-		if (m == NULL) {
-			IP6STAT_INC(ip6s_odropped);
-			error = ENOBUFS;
-			goto bad;
+		struct mbuf *m1;
+
+		error = mb_unmapped_to_ext(m, &m1);
+		if (error != 0) {
+			if (error == ENOMEM) {
+				IP6STAT_INC(ip6s_odropped);
+				error = ENOBUFS;
+				goto bad;
+			}
+			/* XXXKIB */
+			goto no_ipsec;
 		}
+		m = m1;
 		if ((error = IPSEC_OUTPUT(ipv6, ifp, m, inp, mtu == 0 ?
 		    ifp->if_mtu : mtu)) != 0) {
 			if (error == EINPROGRESS)
 				error = 0;
 			goto done;
 		}
+no_ipsec:;
 	}
 #endif /* IPSEC */
 
@@ -1106,10 +1114,20 @@ passout:
 
 	/* Ensure the packet data is mapped if the interface requires it. */
 	if ((ifp->if_capenable & IFCAP_MEXTPG) == 0) {
-		m = mb_unmapped_to_ext(m);
-		if (m == NULL) {
+		struct mbuf *m1;
+
+		error = mb_unmapped_to_ext(m, &m1);
+		if (error != 0) {
+			if (error == EINVAL) {
+				if_printf(ifp, "TLS packet\n");
+				/* XXXKIB */
+			} else if (error == ENOMEM) {
+				error = ENOBUFS;
+			}
 			IP6STAT_INC(ip6s_odropped);
-			return (ENOBUFS);
+			return (error);
+		} else {
+			m = m1;
 		}
 	}