From f82eb2a6f04c2a4193378f932fe8ab9b84fbb67d Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 25 Jun 2020 23:57:30 +0000 Subject: 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 --- sys/netipsec/ipsec_output.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'sys/netipsec/ipsec_output.c') diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c index 0bfc709e80b96..557c0d1d4a4e9 100644 --- a/sys/netipsec/ipsec_output.c +++ b/sys/netipsec/ipsec_output.c @@ -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 *sp, struct secasvar *sav, * 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); -- cgit v1.2.3