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; /*