git: 00524fd47599 - main - ipsec_output(): add mtu argument

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 12 Jul 2024 11:24:56 UTC
The branch main has been updated by kib:

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

commit 00524fd475995d30780ce80ec75e085223206cac
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-01-30 17:56:00 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-07-12 03:29:31 +0000

    ipsec_output(): add mtu argument
    
    Similarly, mtu is needed to decide inline IPSEC offloiad for the driver.
    
    Sponsored by: NVIDIA networking
    Differential revision:  https://reviews.freebsd.org/D44224
---
 sys/net/if_ipsec.c           |  4 ++--
 sys/netinet/ip_output.c      |  2 +-
 sys/netinet6/ip6_output.c    |  2 +-
 sys/netipsec/ipsec.h         |  2 +-
 sys/netipsec/ipsec6.h        |  2 +-
 sys/netipsec/ipsec_output.c  | 36 ++++++++++++++++++------------------
 sys/netipsec/ipsec_support.h |  9 +++++----
 sys/netipsec/subr_ipsec.c    |  7 ++++---
 8 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/sys/net/if_ipsec.c b/sys/net/if_ipsec.c
index bdf500431eff..849127f75de6 100644
--- a/sys/net/if_ipsec.c
+++ b/sys/net/if_ipsec.c
@@ -415,12 +415,12 @@ ipsec_transmit(struct ifnet *ifp, struct mbuf *m)
 	switch (af) {
 #ifdef INET
 	case AF_INET:
-		error = ipsec4_process_packet(ifp, m, sp, NULL);
+		error = ipsec4_process_packet(ifp, m, sp, NULL, ifp->if_mtu);
 		break;
 #endif
 #ifdef INET6
 	case AF_INET6:
-		error = ipsec6_process_packet(ifp, m, sp, NULL);
+		error = ipsec6_process_packet(ifp, m, sp, NULL, ifp->if_mtu);
 		break;
 #endif
 	default:
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 77708f84c3e9..770a95dae659 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -673,7 +673,7 @@ sendit:
 			error = ENOBUFS;
 			goto bad;
 		}
-		if ((error = IPSEC_OUTPUT(ipv4, ifp, m, inp)) != 0) {
+		if ((error = IPSEC_OUTPUT(ipv4, ifp, m, inp, mtu)) != 0) {
 			if (error == EINPROGRESS)
 				error = 0;
 			goto done;
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 800fa691062f..68dd376af5d0 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -462,7 +462,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
 			error = ENOBUFS;
 			goto bad;
 		}
-		if ((error = IPSEC_OUTPUT(ipv6, ifp, m, inp)) != 0) {
+		if ((error = IPSEC_OUTPUT(ipv6, ifp, m, inp, mtu)) != 0) {
 			if (error == EINPROGRESS)
 				error = 0;
 			goto done;
diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h
index a90953531b99..2a1dcb8bb77b 100644
--- a/sys/netipsec/ipsec.h
+++ b/sys/netipsec/ipsec.h
@@ -338,7 +338,7 @@ void ipsec4_setsockaddrs(const struct mbuf *, union sockaddr_union *,
 int ipsec4_common_input_cb(struct mbuf *, struct secasvar *, int, int);
 int ipsec4_check_pmtu(struct ifnet *, struct mbuf *, struct secpolicy *, int);
 int ipsec4_process_packet(struct ifnet *, struct mbuf *, struct secpolicy *,
-    struct inpcb *);
+    struct inpcb *, u_long);
 int ipsec_process_done(struct mbuf *, struct secpolicy *, struct secasvar *,
     u_int);
 
diff --git a/sys/netipsec/ipsec6.h b/sys/netipsec/ipsec6.h
index 9c5d6e695417..a7410733c43f 100644
--- a/sys/netipsec/ipsec6.h
+++ b/sys/netipsec/ipsec6.h
@@ -68,7 +68,7 @@ void ipsec6_setsockaddrs(const struct mbuf *, union sockaddr_union *,
 int ipsec6_common_input_cb(struct mbuf *, struct secasvar *, int, int);
 int ipsec6_check_pmtu(struct ifnet *, struct mbuf *, struct secpolicy *, int);
 int ipsec6_process_packet(struct ifnet *, struct mbuf *, struct secpolicy *,
-    struct inpcb *);
+    struct inpcb *, u_long);
 
 int ip6_ipsec_filtertunnel(struct mbuf *);
 int ip6_ipsec_pcbctl(struct inpcb *, struct sockopt *);
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
index 08b6289ec1d5..be996f257b64 100644
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -188,7 +188,7 @@ next:
  */
 static int
 ipsec4_perform_request(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
-    struct inpcb *inp, u_int idx)
+    struct inpcb *inp, u_int idx, u_long mtu)
 {
 	struct ipsec_ctx_data ctx;
 	union sockaddr_union *dst;
@@ -290,10 +290,10 @@ bad:
 
 int
 ipsec4_process_packet(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
-    struct inpcb *inp)
+    struct inpcb *inp, u_long mtu)
 {
 
-	return (ipsec4_perform_request(ifp, m, sp, inp, 0));
+	return (ipsec4_perform_request(ifp, m, sp, inp, 0, mtu));
 }
 
 int
@@ -371,7 +371,7 @@ setdf:
 
 static int
 ipsec4_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
-    int forwarding)
+    int forwarding, u_long mtu)
 {
 	struct secpolicy *sp;
 	int error;
@@ -423,7 +423,7 @@ ipsec4_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
 		return (error);
 	}
 
-	error = ipsec4_process_packet(ifp, m, sp, inp);
+	error = ipsec4_process_packet(ifp, m, sp, inp, mtu);
 	if (error == EJUSTRETURN) {
 		/*
 		 * We had a SP with a level of 'use' and no SA. We
@@ -443,7 +443,7 @@ ipsec4_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
  * other values - mbuf consumed by IPsec.
  */
 int
-ipsec4_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp)
+ipsec4_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp, u_long mtu)
 {
 
 	/*
@@ -454,7 +454,7 @@ ipsec4_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp)
 	if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL)
 		return (0);
 
-	return (ipsec4_common_output(ifp, m, inp, 0));
+	return (ipsec4_common_output(ifp, m, inp, 0, mtu));
 }
 
 /*
@@ -474,7 +474,7 @@ ipsec4_forward(struct mbuf *m)
 		m_freem(m);
 		return (EACCES);
 	}
-	return (ipsec4_common_output(NULL /* XXXKIB */, m, NULL, 1));
+	return (ipsec4_common_output(NULL /* XXXKIB */, m, NULL, 1, 0));
 }
 #endif
 
@@ -584,7 +584,7 @@ next:
  */
 static int
 ipsec6_perform_request(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
-    struct inpcb *inp, u_int idx)
+    struct inpcb *inp, u_int idx, u_long mtu)
 {
 	struct ipsec_ctx_data ctx;
 	union sockaddr_union *dst;
@@ -676,10 +676,10 @@ bad:
 
 int
 ipsec6_process_packet(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
-    struct inpcb *inp)
+    struct inpcb *inp, u_long mtu)
 {
 
-	return (ipsec6_perform_request(ifp, m, sp, inp, 0));
+	return (ipsec6_perform_request(ifp, m, sp, inp, 0, mtu));
 }
 
 /*
@@ -751,7 +751,7 @@ ipsec6_check_pmtu(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
 
 static int
 ipsec6_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
-    int forwarding)
+    int forwarding, u_long mtu)
 {
 	struct secpolicy *sp;
 	int error;
@@ -794,7 +794,7 @@ ipsec6_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
 	}
 
 	/* NB: callee frees mbuf and releases reference to SP */
-	error = ipsec6_process_packet(ifp, m, sp, inp);
+	error = ipsec6_process_packet(ifp, m, sp, inp, mtu);
 	if (error == EJUSTRETURN) {
 		/*
 		 * We had a SP with a level of 'use' and no SA. We
@@ -814,7 +814,7 @@ ipsec6_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
  * other values - mbuf consumed by IPsec.
  */
 int
-ipsec6_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp)
+ipsec6_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp, u_long mtu)
 {
 
 	/*
@@ -825,7 +825,7 @@ ipsec6_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp)
 	if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL)
 		return (0);
 
-	return (ipsec6_common_output(ifp, m, inp, 0));
+	return (ipsec6_common_output(ifp, m, inp, 0, mtu));
 }
 
 /*
@@ -845,7 +845,7 @@ ipsec6_forward(struct mbuf *m)
 		m_freem(m);
 		return (EACCES);
 	}
-	return (ipsec6_common_output(NULL /* XXXKIB */, m, NULL, 1));
+	return (ipsec6_common_output(NULL /* XXXKIB */, m, NULL, 1, 0));
 }
 #endif /* INET6 */
 
@@ -923,7 +923,7 @@ ipsec_process_done(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
 			key_freesav(&sav);
 			IPSECSTAT_INC(ips_out_bundlesa);
 			return (ipsec4_perform_request(NULL, m, sp, NULL,
-			    idx));
+			    idx, 0));
 			/* NOTREACHED */
 #endif
 #ifdef INET6
@@ -931,7 +931,7 @@ ipsec_process_done(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
 			key_freesav(&sav);
 			IPSEC6STAT_INC(ips_out_bundlesa);
 			return (ipsec6_perform_request(NULL, m, sp, NULL,
-			    idx));
+			    idx, 0));
 			/* NOTREACHED */
 #endif /* INET6 */
 		default:
diff --git a/sys/netipsec/ipsec_support.h b/sys/netipsec/ipsec_support.h
index 96d753f48f42..0cbfe6ddfee5 100644
--- a/sys/netipsec/ipsec_support.h
+++ b/sys/netipsec/ipsec_support.h
@@ -59,7 +59,7 @@ int ipsec4_in_reject(const struct mbuf *, struct inpcb *);
 int ipsec4_input(struct mbuf *, int, int);
 int ipsec4_forward(struct mbuf *);
 int ipsec4_pcbctl(struct inpcb *, struct sockopt *);
-int ipsec4_output(struct ifnet *, struct mbuf *, struct inpcb *);
+int ipsec4_output(struct ifnet *, struct mbuf *, struct inpcb *, u_long);
 int ipsec4_capability(struct mbuf *, u_int);
 int ipsec4_ctlinput(ipsec_ctlinput_param_t);
 #endif /* INET */
@@ -69,7 +69,7 @@ int ipsec6_input(struct mbuf *, int, int);
 int ipsec6_in_reject(const struct mbuf *, struct inpcb *);
 int ipsec6_forward(struct mbuf *);
 int ipsec6_pcbctl(struct inpcb *, struct sockopt *);
-int ipsec6_output(struct ifnet *, struct mbuf *, struct inpcb *);
+int ipsec6_output(struct ifnet *, struct mbuf *, struct inpcb *, u_long);
 int ipsec6_capability(struct mbuf *, u_int);
 int ipsec6_ctlinput(ipsec_ctlinput_param_t);
 #endif /* INET6 */
@@ -78,7 +78,8 @@ struct ipsec_methods {
 	int	(*input)(struct mbuf *, int, int);
 	int	(*check_policy)(const struct mbuf *, struct inpcb *);
 	int	(*forward)(struct mbuf *);
-	int	(*output)(struct ifnet *, struct mbuf *, struct inpcb *);
+	int	(*output)(struct ifnet *, struct mbuf *, struct inpcb *,
+		    u_long);
 	int	(*pcbctl)(struct inpcb *, struct sockopt *);
 	size_t	(*hdrsize)(struct inpcb *);
 	int	(*capability)(struct mbuf *, u_int);
@@ -189,7 +190,7 @@ int ipsec_kmod_check_policy(struct ipsec_support * const, struct mbuf *,
     struct inpcb *);
 int ipsec_kmod_forward(struct ipsec_support * const, struct mbuf *);
 int ipsec_kmod_output(struct ipsec_support * const, struct ifnet *,
-    struct mbuf *, struct inpcb *);
+    struct mbuf *, struct inpcb *, u_long);
 int ipsec_kmod_pcbctl(struct ipsec_support * const, struct inpcb *,
     struct sockopt *);
 int ipsec_kmod_capability(struct ipsec_support * const, struct mbuf *, u_int);
diff --git a/sys/netipsec/subr_ipsec.c b/sys/netipsec/subr_ipsec.c
index 46b3439908ce..2f7e0f09882e 100644
--- a/sys/netipsec/subr_ipsec.c
+++ b/sys/netipsec/subr_ipsec.c
@@ -368,9 +368,10 @@ IPSEC_KMOD_METHOD(int, ipsec_kmod_ctlinput, sc,
 	ipsec_ctlinput_param_t param), METHOD_ARGS(param)
 )
 
-IPSEC_KMOD_METHOD(int, ipsec_kmod_output, sc,
-    output, METHOD_DECL(struct ipsec_support * const sc, struct ifnet *ifp,
-    struct mbuf *m, struct inpcb *inp), METHOD_ARGS(ifp, m, inp)
+IPSEC_KMOD_METHOD(int, ipsec_kmod_output, sc, output,
+    METHOD_DECL(struct ipsec_support * const sc, struct ifnet *ifp,
+    struct mbuf *m, struct inpcb *inp, u_long mtu),
+    METHOD_ARGS(ifp, m, inp, mtu)
 )
 
 IPSEC_KMOD_METHOD(int, ipsec_kmod_pcbctl, sc,