Module Name:    src
Committed By:   ozaki-r
Date:           Fri Jul 21 03:08:10 UTC 2017

Modified Files:
        src/sys/netipsec: ipsec.c ipsec.h ipsec_output.c

Log Message:
Don't use sp->req->sav when handling NAT-T ESP fragmentation

In order to do this we need to look up a sav however an additional
look-up degrades performance. A sav is later looked up in
ipsec4_process_packet so delay the fragmentation check until then
to avoid an extra look-up.


To generate a diff of this commit:
cvs rdiff -u -r1.107 -r1.108 src/sys/netipsec/ipsec.c
cvs rdiff -u -r1.52 -r1.53 src/sys/netipsec/ipsec.h
cvs rdiff -u -r1.55 -r1.56 src/sys/netipsec/ipsec_output.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netipsec/ipsec.c
diff -u src/sys/netipsec/ipsec.c:1.107 src/sys/netipsec/ipsec.c:1.108
--- src/sys/netipsec/ipsec.c:1.107	Fri Jul 21 02:51:12 2017
+++ src/sys/netipsec/ipsec.c	Fri Jul 21 03:08:10 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec.c,v 1.107 2017/07/21 02:51:12 ozaki-r Exp $	*/
+/*	$NetBSD: ipsec.c,v 1.108 2017/07/21 03:08:10 ozaki-r Exp $	*/
 /*	$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $	*/
 /*	$KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.107 2017/07/21 02:51:12 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.108 2017/07/21 03:08:10 ozaki-r Exp $");
 
 /*
  * IPsec controller part.
@@ -655,7 +655,6 @@ int
 ipsec4_output(struct mbuf *m, struct inpcb *inp, int flags,
     u_long *mtu, bool *natt_frag, bool *done)
 {
-	const struct ip *ip = mtod(m, const struct ip *);
 	struct secpolicy *sp = NULL;
 	int error, s;
 
@@ -704,21 +703,6 @@ ipsec4_output(struct mbuf *m, struct inp
 	}
 
 	/*
-	 * NAT-T ESP fragmentation: do not do IPSec processing now,
-	 * we will do it on each fragmented packet.
-	 */
-	if (sp->req->sav && (sp->req->sav->natt_type &
-	    (UDP_ENCAP_ESPINUDP|UDP_ENCAP_ESPINUDP_NON_IKE))) {
-		if (ntohs(ip->ip_len) > sp->req->sav->esp_frag) {
-			*mtu = sp->req->sav->esp_frag;
-			*natt_frag = true;
-			KEY_FREESP(&sp);
-			splx(s);
-			return 0;
-		}
-	}
-
-	/*
 	 * Do delayed checksums now because we send before
 	 * this is done in the normal processing path.
 	 */
@@ -727,8 +711,24 @@ ipsec4_output(struct mbuf *m, struct inp
 		m->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
 	}
 
+    {
+	u_long _mtu = 0;
+
 	/* Note: callee frees mbuf */
-	error = ipsec4_process_packet(m, sp->req);
+	error = ipsec4_process_packet(m, sp->req, &_mtu);
+
+	if (error == 0 && _mtu != 0) {
+		/*
+		 * NAT-T ESP fragmentation: do not do IPSec processing
+		 * now, we will do it on each fragmented packet.
+		 */
+		*mtu = _mtu;
+		*natt_frag = true;
+		KEY_FREESP(&sp);
+		splx(s);
+		return 0;
+    }
+	}
 	/*
 	 * Preserve KAME behaviour: ENOENT can be returned
 	 * when an SA acquire is in progress.  Don't propagate

Index: src/sys/netipsec/ipsec.h
diff -u src/sys/netipsec/ipsec.h:1.52 src/sys/netipsec/ipsec.h:1.53
--- src/sys/netipsec/ipsec.h:1.52	Fri Jul 14 12:26:26 2017
+++ src/sys/netipsec/ipsec.h	Fri Jul 21 03:08:10 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec.h,v 1.52 2017/07/14 12:26:26 ozaki-r Exp $	*/
+/*	$NetBSD: ipsec.h,v 1.53 2017/07/21 03:08:10 ozaki-r Exp $	*/
 /*	$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.h,v 1.2.4.2 2004/02/14 22:23:23 bms Exp $	*/
 /*	$KAME: ipsec.h,v 1.53 2001/11/20 08:32:38 itojun Exp $	*/
 
@@ -340,7 +340,7 @@ struct m_tag;
 void ipsec4_common_input(struct mbuf *m, ...);
 int ipsec4_common_input_cb(struct mbuf *, struct secasvar *,
 			int, int);
-int ipsec4_process_packet(struct mbuf *, struct ipsecrequest *);
+int ipsec4_process_packet(struct mbuf *, struct ipsecrequest *, u_long *);
 int ipsec_process_done(struct mbuf *, struct ipsecrequest *, struct secasvar *);
 #define ipsec_indone(m)	\
 	(m_tag_find((m), PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL)

Index: src/sys/netipsec/ipsec_output.c
diff -u src/sys/netipsec/ipsec_output.c:1.55 src/sys/netipsec/ipsec_output.c:1.56
--- src/sys/netipsec/ipsec_output.c:1.55	Wed Jul 19 09:03:52 2017
+++ src/sys/netipsec/ipsec_output.c	Fri Jul 21 03:08:10 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_output.c,v 1.55 2017/07/19 09:03:52 ozaki-r Exp $	*/
+/*	$NetBSD: ipsec_output.c,v 1.56 2017/07/21 03:08:10 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.55 2017/07/19 09:03:52 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.56 2017/07/21 03:08:10 ozaki-r Exp $");
 
 /*
  * IPsec output processing.
@@ -249,7 +249,7 @@ ipsec_process_done(struct mbuf *m, struc
 		switch ( saidx->dst.sa.sa_family ) {
 #ifdef INET
 		case AF_INET:
-			return ipsec4_process_packet(m, isr->next);
+			return ipsec4_process_packet(m, isr->next, NULL);
 #endif /* INET */
 #ifdef INET6
 		case AF_INET6:
@@ -441,7 +441,8 @@ bad:
  * IPsec output logic for IPv4.
  */
 int
-ipsec4_process_packet(struct mbuf *m, struct ipsecrequest *isr)
+ipsec4_process_packet(struct mbuf *m, struct ipsecrequest *isr,
+    u_long *mtu)
 {
 	struct secasvar *sav = NULL;
 	struct ip *ip;
@@ -468,6 +469,24 @@ ipsec4_process_packet(struct mbuf *m, st
 	}
 
 	KASSERT(sav != NULL);
+	/*
+	 * Check if we need to handle NAT-T fragmentation.
+	 */
+	if (isr == isr->sp->req) { /* Check only if called from ipsec4_output */
+		KASSERT(mtu != NULL);
+		ip = mtod(m, struct ip *);
+		if (!(sav->natt_type &
+		    (UDP_ENCAP_ESPINUDP|UDP_ENCAP_ESPINUDP_NON_IKE))) {
+			goto noneed;
+		}
+		if (ntohs(ip->ip_len) <= sav->esp_frag)
+			goto noneed;
+		*mtu = sav->esp_frag;
+		KEY_FREESAV(&sav);
+		splx(s);
+		return 0;
+	}
+noneed:
 	dst = &sav->sah->saidx.dst;
 
 	/*

Reply via email to