Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/cxgbe/tom/t4_tls.c
Show First 20 Lines • Show All 701 Lines • ▼ Show 20 Lines | t4_set_tls_tcb_field(toep, W_TCB_ULP_RAW, | ||||
V_TCB_ULP_RAW((V_TF_TLS_KEY_SIZE(3) | | V_TCB_ULP_RAW((V_TF_TLS_KEY_SIZE(3) | | ||||
V_TF_TLS_CONTROL(1) | | V_TF_TLS_CONTROL(1) | | ||||
V_TF_TLS_ACTIVE(1) | | V_TF_TLS_ACTIVE(1) | | ||||
V_TF_TLS_ENABLE(1)))); | V_TF_TLS_ENABLE(1)))); | ||||
t4_set_tls_tcb_field(toep, W_TCB_TLS_SEQ, | t4_set_tls_tcb_field(toep, W_TCB_TLS_SEQ, | ||||
V_TCB_TLS_SEQ(M_TCB_TLS_SEQ), | V_TCB_TLS_SEQ(M_TCB_TLS_SEQ), | ||||
V_TCB_TLS_SEQ(0)); | V_TCB_TLS_SEQ(0)); | ||||
t4_clear_rx_quiesce(toep); | t4_clear_rx_quiesce(toep); | ||||
toep->flags |= TPF_TLS_RECEIVE; | |||||
} else { | } else { | ||||
unsigned short pdus_per_ulp; | unsigned short pdus_per_ulp; | ||||
if (tls_ofld->key_location == TLS_SFO_WR_CONTEXTLOC_IMMEDIATE) | if (tls_ofld->key_location == TLS_SFO_WR_CONTEXTLOC_IMMEDIATE) | ||||
tls_ofld->tx_key_addr = 1; | tls_ofld->tx_key_addr = 1; | ||||
tls_ofld->fcplenmax = get_tp_plen_max(tls_ofld); | tls_ofld->fcplenmax = get_tp_plen_max(tls_ofld); | ||||
tls_ofld->expn_per_ulp = tls_expansion_size(toep, | tls_ofld->expn_per_ulp = tls_expansion_size(toep, | ||||
▲ Show 20 Lines • Show All 341 Lines • ▼ Show 20 Lines | if (direction == KTLS_TX) { | ||||
toep->tls.pdus_per_ulp = 1; | toep->tls.pdus_per_ulp = 1; | ||||
toep->tls.adjusted_plen = toep->tls.expn_per_ulp + | toep->tls.adjusted_plen = toep->tls.expn_per_ulp + | ||||
toep->tls.k_ctx.frag_size; | toep->tls.k_ctx.frag_size; | ||||
} else { | } else { | ||||
/* Stop timer on handshake completion */ | /* Stop timer on handshake completion */ | ||||
tls_stop_handshake_timer(toep); | tls_stop_handshake_timer(toep); | ||||
toep->flags &= ~TPF_FORCE_CREDITS; | toep->flags &= ~TPF_FORCE_CREDITS; | ||||
toep->flags |= TPF_TLS_RECEIVE; | |||||
/* | /* | ||||
* RX key tags are an index into the key portion of MA | * RX key tags are an index into the key portion of MA | ||||
* memory stored as an offset from the base address in | * memory stored as an offset from the base address in | ||||
* units of 64 bytes. | * units of 64 bytes. | ||||
*/ | */ | ||||
key_offset = toep->tls.rx_key_addr - sc->vres.key.start; | key_offset = toep->tls.rx_key_addr - sc->vres.key.start; | ||||
t4_set_tls_keyid(toep, key_offset / 64); | t4_set_tls_keyid(toep, key_offset / 64); | ||||
▲ Show 20 Lines • Show All 1,138 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
sorwakeup_locked(so); | sorwakeup_locked(so); | ||||
SOCKBUF_UNLOCK_ASSERT(sb); | SOCKBUF_UNLOCK_ASSERT(sb); | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
return (0); | return (0); | ||||
} | |||||
void | |||||
do_rx_data_tls(const struct cpl_rx_data *cpl, struct toepcb *toep, | |||||
struct mbuf *m) | |||||
{ | |||||
struct inpcb *inp = toep->inp; | |||||
struct tls_ofld_info *tls_ofld = &toep->tls; | |||||
struct tls_hdr *hdr; | |||||
struct tcpcb *tp; | |||||
struct socket *so; | |||||
struct sockbuf *sb; | |||||
int error, len; | |||||
len = m->m_pkthdr.len; | |||||
INP_WLOCK_ASSERT(inp); | |||||
so = inp_inpcbtosocket(inp); | |||||
tp = intotcpcb(inp); | |||||
sb = &so->so_rcv; | |||||
SOCKBUF_LOCK(sb); | |||||
CURVNET_SET(toep->vnet); | |||||
tp->rcv_nxt += len; | |||||
KASSERT(tp->rcv_wnd >= len, ("%s: negative window size", __func__)); | |||||
tp->rcv_wnd -= len; | |||||
/* Do we have a full TLS header? */ | |||||
if (len < sizeof(*hdr)) { | |||||
CTR3(KTR_CXGBE, "%s: tid %u len %d: too short for a TLS header", | |||||
__func__, toep->tid, len); | |||||
so->so_error = EMSGSIZE; | |||||
goto out; | |||||
} | |||||
hdr = mtod(m, struct tls_hdr *); | |||||
/* Is the header valid? */ | |||||
if (be16toh(hdr->version) != tls_ofld->k_ctx.proto_ver) { | |||||
CTR3(KTR_CXGBE, "%s: tid %u invalid version %04x", | |||||
__func__, toep->tid, be16toh(hdr->version)); | |||||
error = EINVAL; | |||||
goto report_error; | |||||
} | |||||
if (be16toh(hdr->length) < sizeof(*hdr)) { | |||||
CTR3(KTR_CXGBE, "%s: tid %u invalid length %u", | |||||
__func__, toep->tid, be16toh(hdr->length)); | |||||
error = EBADMSG; | |||||
goto report_error; | |||||
} | |||||
/* Did we get a truncated record? */ | |||||
if (len < be16toh(hdr->length)) { | |||||
CTR4(KTR_CXGBE, "%s: tid %u truncated TLS record (%d vs %u)", | |||||
__func__, toep->tid, len, be16toh(hdr->length)); | |||||
error = EMSGSIZE; | |||||
goto report_error; | |||||
} | |||||
/* Is the header type unknown? */ | |||||
switch (hdr->type) { | |||||
case CONTENT_TYPE_CCS: | |||||
case CONTENT_TYPE_ALERT: | |||||
case CONTENT_TYPE_APP_DATA: | |||||
case CONTENT_TYPE_HANDSHAKE: | |||||
break; | |||||
default: | |||||
CTR3(KTR_CXGBE, "%s: tid %u invalid TLS record type %u", | |||||
__func__, toep->tid, hdr->type); | |||||
error = EBADMSG; | |||||
goto report_error; | |||||
} | |||||
/* | |||||
* Just punt. Although this could fall back to software | |||||
* decryption, this case should never really happen. | |||||
*/ | |||||
CTR4(KTR_CXGBE, "%s: tid %u dropping TLS record type %u, length %u", | |||||
__func__, toep->tid, hdr->type, be16toh(hdr->length)); | |||||
error = EBADMSG; | |||||
report_error: | |||||
#ifdef KERN_TLS | |||||
if (toep->tls.mode == TLS_MODE_KTLS) | |||||
so->so_error = error; | |||||
else | |||||
#endif | |||||
{ | |||||
/* | |||||
* Report errors by sending an empty TLS record | |||||
* with an error record type. | |||||
*/ | |||||
hdr->type = CONTENT_TYPE_ERROR; | |||||
/* Trim this CPL's mbuf to only include the TLS header. */ | |||||
KASSERT(m->m_len == len && m->m_next == NULL, | |||||
("%s: CPL spans multiple mbufs", __func__)); | |||||
m->m_len = TLS_HEADER_LENGTH; | |||||
m->m_pkthdr.len = TLS_HEADER_LENGTH; | |||||
sbappendstream_locked(sb, m, 0); | |||||
m = NULL; | |||||
} | |||||
out: | |||||
/* | |||||
jhb: I've left this in for you to look at Navdeep to decide if we should enable this or if we should… | |||||
Not Done Inline ActionsLet's leave it enabled for now because in theory we haven't seen a FIN so the rcv window np: Let's leave it enabled for now because in theory we haven't seen a FIN so the rcv window
should… | |||||
* This connection is going to die anyway, so probably don't | |||||
* need to bother with returning credits. | |||||
*/ | |||||
rx_credits = sbspace(sb) > tp->rcv_wnd ? sbspace(sb) - tp->rcv_wnd : 0; | |||||
#ifdef VERBOSE_TRACES | |||||
CTR4(KTR_CXGBE, "%s: tid %u rx_credits %u rcv_wnd %u", | |||||
__func__, tid, rx_credits, tp->rcv_wnd); | |||||
#endif | |||||
if (rx_credits > 0 && sbused(sb) + tp->rcv_wnd < sb->sb_lowat) { | |||||
rx_credits = send_rx_credits(sc, toep, rx_credits); | |||||
tp->rcv_wnd += rx_credits; | |||||
tp->rcv_adv += rx_credits; | |||||
} | |||||
sorwakeup_locked(so); | |||||
SOCKBUF_UNLOCK_ASSERT(sb); | |||||
INP_WUNLOCK(inp); | |||||
CURVNET_RESTORE(); | |||||
m_freem(m); | |||||
} | } | ||||
void | void | ||||
t4_tls_mod_load(void) | t4_tls_mod_load(void) | ||||
{ | { | ||||
mtx_init(&tls_handshake_lock, "t4tls handshake", NULL, MTX_DEF); | 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_TLS_DATA, do_tls_data); | ||||
Show All 12 Lines |
I've left this in for you to look at Navdeep to decide if we should enable this or if we should axe it instead. If we axe it, I will probably leave the comment about not bothering to return credits as a placeholder for the removed code.