From owner-svn-src-all@freebsd.org Thu Dec 3 22:06:10 2020 Return-Path: Delivered-To: svn-src-all@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 A92A44B1018; Thu, 3 Dec 2020 22:06:10 +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 4Cn9024Myzz4q22; Thu, 3 Dec 2020 22:06:10 +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 88EDA20BC3; Thu, 3 Dec 2020 22:06:10 +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 0B3M6AwM096823; Thu, 3 Dec 2020 22:06:10 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0B3M68Yx096816; Thu, 3 Dec 2020 22:06:08 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <202012032206.0B3M68Yx096816@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Thu, 3 Dec 2020 22:06:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r368316 - in head/sys/dev/cxgbe: . tom X-SVN-Group: head X-SVN-Commit-Author: jhb X-SVN-Commit-Paths: in head/sys/dev/cxgbe: . tom X-SVN-Commit-Revision: 368316 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Dec 2020 22:06:10 -0000 Author: jhb Date: Thu Dec 3 22:06:08 2020 New Revision: 368316 URL: https://svnweb.freebsd.org/changeset/base/368316 Log: Clear TLS offload mode if a TLS socket hangs without receiving data. By default, if a TOE TLS socket stops receiving data for more than 5 seconds, revert the connection back to plain TOE mode. This provides a fallback if the userland SSL library does not support KTLS. In addition, for client TLS 1.3 sockets using connect(), the TOE socket blocks before the handshake has completed since the socket option is only invoked for the final handshake. The timeout defaults to 5 seconds, but can be changed at boot via the hw.cxgbe.toe.tls_rx_timeout tunable or for an individual interface via the dev..toe.tls_rx_timeout sysctl. Reviewed by: np MFC after: 2 weeks Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D27470 Modified: head/sys/dev/cxgbe/offload.h head/sys/dev/cxgbe/t4_main.c head/sys/dev/cxgbe/tom/t4_connect.c head/sys/dev/cxgbe/tom/t4_cpl_io.c head/sys/dev/cxgbe/tom/t4_tls.c head/sys/dev/cxgbe/tom/t4_tom.c head/sys/dev/cxgbe/tom/t4_tom.h Modified: head/sys/dev/cxgbe/offload.h ============================================================================== --- head/sys/dev/cxgbe/offload.h Thu Dec 3 22:04:23 2020 (r368315) +++ head/sys/dev/cxgbe/offload.h Thu Dec 3 22:06:08 2020 (r368316) @@ -225,6 +225,7 @@ struct tom_tunables { int ddp; int rx_coalesce; int tls; + int tls_rx_timeout; int *tls_rx_ports; int num_tls_rx_ports; int tx_align; Modified: head/sys/dev/cxgbe/t4_main.c ============================================================================== --- head/sys/dev/cxgbe/t4_main.c Thu Dec 3 22:04:23 2020 (r368315) +++ head/sys/dev/cxgbe/t4_main.c Thu Dec 3 22:06:08 2020 (r368316) @@ -403,6 +403,11 @@ SYSCTL_INT(_hw_cxgbe_toe_rexmt_backoff, OID_AUTO, 14, &t4_toe_rexmt_backoff[14], 0, ""); SYSCTL_INT(_hw_cxgbe_toe_rexmt_backoff, OID_AUTO, 15, CTLFLAG_RDTUN, &t4_toe_rexmt_backoff[15], 0, ""); + +static int t4_toe_tls_rx_timeout = 5; +SYSCTL_INT(_hw_cxgbe_toe, OID_AUTO, tls_rx_timeout, CTLFLAG_RDTUN, + &t4_toe_tls_rx_timeout, 0, + "Timeout in seconds to downgrade TLS sockets to plain TOE"); #endif #ifdef DEV_NETMAP @@ -786,6 +791,7 @@ static int sysctl_cpus(SYSCTL_HANDLER_ARGS); #ifdef TCP_OFFLOAD static int sysctl_tls(SYSCTL_HANDLER_ARGS); static int sysctl_tls_rx_ports(SYSCTL_HANDLER_ARGS); +static int sysctl_tls_rx_timeout(SYSCTL_HANDLER_ARGS); static int sysctl_tp_tick(SYSCTL_HANDLER_ARGS); static int sysctl_tp_dack_timer(SYSCTL_HANDLER_ARGS); static int sysctl_tp_timer(SYSCTL_HANDLER_ARGS); @@ -6789,6 +6795,12 @@ t4_sysctls(struct adapter *sc) sysctl_tls_rx_ports, "I", "TCP ports that use inline TLS+TOE RX"); + sc->tt.tls_rx_timeout = t4_toe_tls_rx_timeout; + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tls_rx_timeout", + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0, + sysctl_tls_rx_timeout, "I", + "Timeout in seconds to downgrade TLS sockets to plain TOE"); + sc->tt.tx_align = -1; SYSCTL_ADD_INT(ctx, children, OID_AUTO, "tx_align", CTLFLAG_RW, &sc->tt.tx_align, 0, "chop and align payload"); @@ -10046,6 +10058,29 @@ sysctl_tls_rx_ports(SYSCTL_HANDLER_ARGS) return (rc); } +static int +sysctl_tls_rx_timeout(SYSCTL_HANDLER_ARGS) +{ + struct adapter *sc = arg1; + int v, rc; + + v = sc->tt.tls_rx_timeout; + rc = sysctl_handle_int(oidp, &v, 0, req); + if (rc != 0 || req->newptr == NULL) + return (rc); + + if (v < 0) + return (EINVAL); + + if (v != 0 && !(sc->cryptocaps & FW_CAPS_CONFIG_TLSKEYS)) + return (ENOTSUP); + + sc->tt.tls_rx_timeout = v; + + return (0); + +} + static void unit_conv(char *buf, size_t len, u_int val, u_int factor) { @@ -11287,6 +11322,9 @@ tweak_tunables(void) if (t4_pktc_idx_ofld < -1 || t4_pktc_idx_ofld >= SGE_NCOUNTERS) t4_pktc_idx_ofld = PKTC_IDX_OFLD; + + if (t4_toe_tls_rx_timeout < 0) + t4_toe_tls_rx_timeout = 0; #else if (t4_rdmacaps_allowed == -1) t4_rdmacaps_allowed = 0; Modified: head/sys/dev/cxgbe/tom/t4_connect.c ============================================================================== --- head/sys/dev/cxgbe/tom/t4_connect.c Thu Dec 3 22:04:23 2020 (r368315) +++ head/sys/dev/cxgbe/tom/t4_connect.c Thu Dec 3 22:06:08 2020 (r368316) @@ -105,9 +105,6 @@ do_act_establish(struct sge_iq *iq, const struct rss_h inp->inp_flowtype = M_HASHTYPE_OPAQUE; inp->inp_flowid = tid; - if (ulp_mode(toep) == ULP_MODE_TLS) - tls_establish(toep); - done: INP_WUNLOCK(inp); CURVNET_RESTORE(); Modified: head/sys/dev/cxgbe/tom/t4_cpl_io.c ============================================================================== --- head/sys/dev/cxgbe/tom/t4_cpl_io.c Thu Dec 3 22:04:23 2020 (r368315) +++ head/sys/dev/cxgbe/tom/t4_cpl_io.c Thu Dec 3 22:06:08 2020 (r368316) @@ -392,6 +392,9 @@ make_established(struct toepcb *toep, uint32_t iss, ui send_flowc_wr(toep, tp); soisconnected(so); + + if (ulp_mode(toep) == ULP_MODE_TLS) + tls_establish(toep); } int Modified: head/sys/dev/cxgbe/tom/t4_tls.c ============================================================================== --- head/sys/dev/cxgbe/tom/t4_tls.c Thu Dec 3 22:04:23 2020 (r368315) +++ head/sys/dev/cxgbe/tom/t4_tls.c Thu Dec 3 22:06:08 2020 (r368316) @@ -64,14 +64,6 @@ __FBSDID("$FreeBSD$"); */ #define tls_tcp_seq PH_loc.thirtytwo[0] -/* - * Handshake lock used for the handshake timer. Having a global lock - * is perhaps not ideal, but it avoids having to use callout_drain() - * in tls_uninit_toep() which can't block. Also, the timer shouldn't - * actually fire for most connections. - */ -static struct mtx tls_handshake_lock; - static void t4_set_tls_tcb_field(struct toepcb *toep, uint16_t word, uint64_t mask, uint64_t val) @@ -149,7 +141,7 @@ tls_clr_ofld_mode(struct toepcb *toep) V_TCB_ULP_TYPE(M_TCB_ULP_TYPE), V_TCB_ULP_TYPE(ULP_MODE_NONE)); t4_clear_rx_quiesce(toep); - toep->flags &= ~TPF_FORCE_CREDITS; + toep->flags &= ~(TPF_FORCE_CREDITS | TPF_TLS_ESTABLISHED); toep->params.ulp_mode = ULP_MODE_NONE; } @@ -748,6 +740,25 @@ tls_send_handshake_ack(void *arg) struct adapter *sc = td_adapter(toep->td); /* + * If this connection has timed out without receiving more + * data, downgrade to plain TOE mode and don't re-arm the + * timer. + */ + if (sc->tt.tls_rx_timeout != 0) { + struct inpcb *inp; + struct tcpcb *tp; + + inp = toep->inp; + tp = intotcpcb(inp); + if ((ticks - tp->t_rcvtime) >= sc->tt.tls_rx_timeout) { + CTR2(KTR_CXGBE, "%s: tid %d clr_ofld_mode", __func__, + toep->tid); + tls_clr_ofld_mode(toep); + return; + } + } + + /* * XXX: Does not have the t4_get_tcb() checks to refine the * workaround. */ @@ -762,10 +773,9 @@ tls_start_handshake_timer(struct toepcb *toep) { struct tls_ofld_info *tls_ofld = &toep->tls; - mtx_lock(&tls_handshake_lock); + INP_WLOCK_ASSERT(toep->inp); callout_reset(&tls_ofld->handshake_timer, TLS_SRV_HELLO_BKOFF_TM * hz, tls_send_handshake_ack, toep); - mtx_unlock(&tls_handshake_lock); } void @@ -773,9 +783,8 @@ tls_stop_handshake_timer(struct toepcb *toep) { struct tls_ofld_info *tls_ofld = &toep->tls; - mtx_lock(&tls_handshake_lock); + INP_WLOCK_ASSERT(toep->inp); callout_stop(&tls_ofld->handshake_timer); - mtx_unlock(&tls_handshake_lock); } int @@ -1129,9 +1138,6 @@ tls_init_toep(struct toepcb *toep) tls_ofld->key_location = TLS_SFO_WR_CONTEXTLOC_DDR; tls_ofld->rx_key_addr = -1; tls_ofld->tx_key_addr = -1; - if (ulp_mode(toep) == ULP_MODE_TLS) - callout_init_mtx(&tls_ofld->handshake_timer, - &tls_handshake_lock, 0); } void @@ -1149,17 +1155,27 @@ tls_establish(struct toepcb *toep) t4_set_tls_tcb_field(toep, W_TCB_ULP_RAW, V_TCB_ULP_RAW(M_TCB_ULP_RAW), V_TCB_ULP_RAW(V_TF_TLS_ENABLE(1))); - toep->flags |= TPF_FORCE_CREDITS; + toep->flags |= TPF_FORCE_CREDITS | TPF_TLS_ESTABLISHED; + callout_init_rw(&toep->tls.handshake_timer, &toep->inp->inp_lock, 0); tls_start_handshake_timer(toep); } void -tls_uninit_toep(struct toepcb *toep) +tls_detach(struct toepcb *toep) { - if (ulp_mode(toep) == ULP_MODE_TLS) + if (toep->flags & TPF_TLS_ESTABLISHED) { tls_stop_handshake_timer(toep); + toep->flags &= ~TPF_TLS_ESTABLISHED; + } +} + +void +tls_uninit_toep(struct toepcb *toep) +{ + + MPASS((toep->flags & TPF_TLS_ESTABLISHED) == 0); clear_tls_keyid(toep); } @@ -2383,7 +2399,6 @@ void t4_tls_mod_load(void) { - mtx_init(&tls_handshake_lock, "t4tls handshake", NULL, MTX_DEF); t4_register_cpl_handler(CPL_TLS_DATA, do_tls_data); t4_register_cpl_handler(CPL_RX_TLS_CMP, do_rx_tls_cmp); } @@ -2394,6 +2409,5 @@ t4_tls_mod_unload(void) t4_register_cpl_handler(CPL_TLS_DATA, NULL); t4_register_cpl_handler(CPL_RX_TLS_CMP, NULL); - mtx_destroy(&tls_handshake_lock); } #endif /* TCP_OFFLOAD */ Modified: head/sys/dev/cxgbe/tom/t4_tom.c ============================================================================== --- head/sys/dev/cxgbe/tom/t4_tom.c Thu Dec 3 22:04:23 2020 (r368315) +++ head/sys/dev/cxgbe/tom/t4_tom.c Thu Dec 3 22:06:08 2020 (r368316) @@ -382,6 +382,9 @@ t4_pcb_detach(struct toedev *tod __unused, struct tcpc } #endif + if (ulp_mode(toep) == ULP_MODE_TLS) + tls_detach(toep); + tp->tod = NULL; tp->t_toe = NULL; tp->t_flags &= ~TF_TOE; @@ -845,6 +848,8 @@ final_cpl_received(struct toepcb *toep) if (ulp_mode(toep) == ULP_MODE_TCPDDP) release_ddp_resources(toep); + else if (ulp_mode(toep) == ULP_MODE_TLS) + tls_detach(toep); toep->inp = NULL; toep->flags &= ~TPF_CPL_PENDING; mbufq_drain(&toep->ulp_pdu_reclaimq); Modified: head/sys/dev/cxgbe/tom/t4_tom.h ============================================================================== --- head/sys/dev/cxgbe/tom/t4_tom.h Thu Dec 3 22:04:23 2020 (r368315) +++ head/sys/dev/cxgbe/tom/t4_tom.h Thu Dec 3 22:06:08 2020 (r368316) @@ -75,6 +75,7 @@ enum { TPF_KTLS = (1 << 11), /* send TLS records from KTLS */ TPF_INITIALIZED = (1 << 12), /* init_toepcb has been called */ TPF_TLS_RECEIVE = (1 << 13), /* should receive TLS records */ + TPF_TLS_ESTABLISHED = (1 << 14), /* TLS handshake timer initialized */ }; enum { @@ -448,6 +449,7 @@ void t4_push_tls_records(struct adapter *, struct toep void t4_push_ktls(struct adapter *, struct toepcb *, int); void t4_tls_mod_load(void); void t4_tls_mod_unload(void); +void tls_detach(struct toepcb *); void tls_establish(struct toepcb *); void tls_init_toep(struct toepcb *); int tls_rx_key(struct toepcb *);