From owner-svn-src-head@freebsd.org Thu Jun 25 23:57:31 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 1DB1A348355; Thu, 25 Jun 2020 23:57:31 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49tH4p75lgz3WYN; Thu, 25 Jun 2020 23:57:30 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id EF059B634; Thu, 25 Jun 2020 23:57:30 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05PNvUhs037277; Thu, 25 Jun 2020 23:57:30 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05PNvU3S037276; Thu, 25 Jun 2020 23:57:30 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <202006252357.05PNvU3S037276@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Thu, 25 Jun 2020 23:57:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r362635 - head/sys/netipsec X-SVN-Group: head X-SVN-Commit-Author: jhb X-SVN-Commit-Paths: head/sys/netipsec X-SVN-Commit-Revision: 362635 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Jun 2020 23:57:31 -0000 Author: jhb Date: Thu Jun 25 23:57:30 2020 New Revision: 362635 URL: https://svnweb.freebsd.org/changeset/base/362635 Log: Enter and exit the network epoch for async IPsec callbacks. When an IPsec packet has been encrypted or decrypted, the next step in the packet's traversal through the network stack is invoked from a crypto worker thread, not from the original calling thread. These threads need to enter the network epoch before passing packets down to IP output routines or up to transport protocols. Reviewed by: ae Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D25444 Modified: head/sys/netipsec/ipsec_input.c head/sys/netipsec/ipsec_output.c Modified: head/sys/netipsec/ipsec_input.c ============================================================================== --- head/sys/netipsec/ipsec_input.c Thu Jun 25 21:34:43 2020 (r362634) +++ head/sys/netipsec/ipsec_input.c Thu Jun 25 23:57:30 2020 (r362635) @@ -278,6 +278,7 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar int protoff) { IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); + struct epoch_tracker et; struct ipsec_ctx_data ctx; struct xform_history *xh; struct secasindex *saidx; @@ -424,7 +425,9 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar if (saidx->mode == IPSEC_MODE_TUNNEL) error = ipsec_if_input(m, sav, af); if (error == 0) { + NET_EPOCH_ENTER(et); error = netisr_queue_src(isr_prot, (uintptr_t)sav->spi, m); + NET_EPOCH_EXIT(et); if (error) { IPSEC_ISTAT(sproto, qfull); DPRINTF(("%s: queue full; proto %u packet dropped\n", @@ -489,6 +492,7 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar int protoff) { IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); + struct epoch_tracker et; struct ipsec_ctx_data ctx; struct xform_history *xh; struct secasindex *saidx; @@ -621,8 +625,10 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar if (saidx->mode == IPSEC_MODE_TUNNEL) error = ipsec_if_input(m, sav, af); if (error == 0) { + NET_EPOCH_ENTER(et); error = netisr_queue_src(isr_prot, (uintptr_t)sav->spi, m); + NET_EPOCH_EXIT(et); if (error) { IPSEC_ISTAT(sproto, qfull); DPRINTF(("%s: queue full; proto %u packet" @@ -638,11 +644,12 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar */ nest = 0; nxt = nxt8; + NET_EPOCH_ENTER(et); while (nxt != IPPROTO_DONE) { if (V_ip6_hdrnestlimit && (++nest > V_ip6_hdrnestlimit)) { IP6STAT_INC(ip6s_toomanyhdr); error = EINVAL; - goto bad; + goto bad_epoch; } /* @@ -653,7 +660,7 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar IP6STAT_INC(ip6s_tooshort); in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); error = EINVAL; - goto bad; + goto bad_epoch; } /* * Enforce IPsec policy checking if we are seeing last header. @@ -663,12 +670,15 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 && ipsec6_in_reject(m, NULL)) { error = EINVAL; - goto bad; + goto bad_epoch; } nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt); } + NET_EPOCH_EXIT(et); key_freesav(&sav); return (0); +bad_epoch: + NET_EPOCH_EXIT(et); bad: key_freesav(&sav); if (m) Modified: head/sys/netipsec/ipsec_output.c ============================================================================== --- head/sys/netipsec/ipsec_output.c Thu Jun 25 21:34:43 2020 (r362634) +++ head/sys/netipsec/ipsec_output.c Thu Jun 25 23:57:30 2020 (r362635) @@ -688,6 +688,7 @@ int ipsec_process_done(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, u_int idx) { + struct epoch_tracker et; struct xform_history *xh; struct secasindex *saidx; struct m_tag *mtag; @@ -789,19 +790,25 @@ ipsec_process_done(struct mbuf *m, struct secpolicy *s * We're done with IPsec processing, transmit the packet using the * appropriate network protocol (IP or IPv6). */ + NET_EPOCH_ENTER(et); switch (saidx->dst.sa.sa_family) { #ifdef INET case AF_INET: key_freesav(&sav); - return ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL); + error = ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL); + break; #endif /* INET */ #ifdef INET6 case AF_INET6: key_freesav(&sav); - return ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); + error = ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); + break; #endif /* INET6 */ + default: + panic("ipsec_process_done"); } - panic("ipsec_process_done"); + NET_EPOCH_EXIT(et); + return (error); bad: m_freem(m); key_freesav(&sav);