Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netipsec Don't use sp->req->sav when handling NAT-T ESP ...



details:   https://anonhg.NetBSD.org/src/rev/22c7e13c6889
branches:  trunk
changeset: 825549:22c7e13c6889
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Fri Jul 21 03:08:10 2017 +0000

description:
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.

diffstat:

 sys/netipsec/ipsec.c        |  38 +++++++++++++++++++-------------------
 sys/netipsec/ipsec.h        |   4 ++--
 sys/netipsec/ipsec_output.c |  27 +++++++++++++++++++++++----
 3 files changed, 44 insertions(+), 25 deletions(-)

diffs (154 lines):

diff -r 979e361753b3 -r 22c7e13c6889 sys/netipsec/ipsec.c
--- a/sys/netipsec/ipsec.c      Fri Jul 21 02:51:12 2017 +0000
+++ b/sys/netipsec/ipsec.c      Fri Jul 21 03:08:10 2017 +0000
@@ -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 @@
 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 @@
        }
 
        /*
-        * 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 @@
                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
diff -r 979e361753b3 -r 22c7e13c6889 sys/netipsec/ipsec.h
--- a/sys/netipsec/ipsec.h      Fri Jul 21 02:51:12 2017 +0000
+++ b/sys/netipsec/ipsec.h      Fri Jul 21 03:08:10 2017 +0000
@@ -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 @@
 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)
diff -r 979e361753b3 -r 22c7e13c6889 sys/netipsec/ipsec_output.c
--- a/sys/netipsec/ipsec_output.c       Fri Jul 21 02:51:12 2017 +0000
+++ b/sys/netipsec/ipsec_output.c       Fri Jul 21 03:08:10 2017 +0000
@@ -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 @@
                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 @@
  * 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 @@
        }
 
        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;
 
        /*



Home | Main Index | Thread Index | Old Index