Skip to content

Commit

Permalink
nfp: tls: make use of kernel-driven TX resync
Browse files Browse the repository at this point in the history
When TCP stream gets out of sync (driver stops receiving skbs
with expected TCP sequence numbers) request a TX resync from
the kernel.

We try to distinguish retransmissions from missed transmissions
by comparing the sequence number to expected - if it's further
than the expected one - we probably missed packets.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jakub Kicinski authored and David S. Miller committed Jun 11, 2019
1 parent 5018007 commit 9ed431c
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
1 change: 0 additions & 1 deletion drivers/net/ethernet/netronome/nfp/crypto/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ struct nfp_net_tls_offload_ctx {
*/

u32 next_seq;
bool out_of_sync;
};

#ifdef CONFIG_TLS_DEVICE
Expand Down
21 changes: 13 additions & 8 deletions drivers/net/ethernet/netronome/nfp/crypto/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,25 +390,30 @@ nfp_net_tls_resync(struct net_device *netdev, struct sock *sk, u32 seq,
struct nfp_net_tls_offload_ctx *ntls;
struct nfp_crypto_req_update *req;
struct sk_buff *skb;
gfp_t flags;

if (WARN_ON_ONCE(direction != TLS_OFFLOAD_CTX_DIR_RX))
return;

skb = nfp_net_tls_alloc_simple(nn, sizeof(*req), GFP_ATOMIC);
flags = direction == TLS_OFFLOAD_CTX_DIR_TX ? GFP_KERNEL : GFP_ATOMIC;
skb = nfp_net_tls_alloc_simple(nn, sizeof(*req), flags);
if (!skb)
return;

ntls = tls_driver_ctx(sk, TLS_OFFLOAD_CTX_DIR_RX);
ntls = tls_driver_ctx(sk, direction);
req = (void *)skb->data;
req->ep_id = 0;
req->opcode = NFP_NET_CRYPTO_OP_TLS_1_2_AES_GCM_128_DEC;
req->opcode = nfp_tls_1_2_dir_to_opcode(direction);
memset(req->resv, 0, sizeof(req->resv));
memcpy(req->handle, ntls->fw_handle, sizeof(ntls->fw_handle));
req->tcp_seq = cpu_to_be32(seq);
memcpy(req->rec_no, rcd_sn, sizeof(req->rec_no));

nfp_ccm_mbox_post(nn, skb, NFP_CCM_TYPE_CRYPTO_UPDATE,
sizeof(struct nfp_crypto_reply_simple));
if (direction == TLS_OFFLOAD_CTX_DIR_TX) {
nfp_net_tls_communicate_simple(nn, skb, "sync",
NFP_CCM_TYPE_CRYPTO_UPDATE);
ntls->next_seq = seq;
} else {
nfp_ccm_mbox_post(nn, skb, NFP_CCM_TYPE_CRYPTO_UPDATE,
sizeof(struct nfp_crypto_reply_simple));
}
}

static const struct tlsdev_ops nfp_net_tls_ops = {
Expand Down
8 changes: 5 additions & 3 deletions drivers/net/ethernet/netronome/nfp/nfp_net_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,7 @@ nfp_net_tls_tx(struct nfp_net_dp *dp, struct nfp_net_r_vector *r_vec,
{
struct nfp_net_tls_offload_ctx *ntls;
struct sk_buff *nskb;
bool resync_pending;
u32 datalen, seq;

if (likely(!dp->ktls_tx))
Expand All @@ -839,7 +840,8 @@ nfp_net_tls_tx(struct nfp_net_dp *dp, struct nfp_net_r_vector *r_vec,
datalen = skb->len - (skb_transport_offset(skb) + tcp_hdrlen(skb));
seq = ntohl(tcp_hdr(skb)->seq);
ntls = tls_driver_ctx(skb->sk, TLS_OFFLOAD_CTX_DIR_TX);
if (unlikely(ntls->next_seq != seq || ntls->out_of_sync)) {
resync_pending = tls_offload_tx_resync_pending(skb->sk);
if (unlikely(resync_pending || ntls->next_seq != seq)) {
/* Pure ACK out of order already */
if (!datalen)
return skb;
Expand Down Expand Up @@ -869,8 +871,8 @@ nfp_net_tls_tx(struct nfp_net_dp *dp, struct nfp_net_r_vector *r_vec,
}

/* jump forward, a TX may have gotten lost, need to sync TX */
if (!ntls->out_of_sync && seq - ntls->next_seq < U32_MAX / 4)
ntls->out_of_sync = true;
if (!resync_pending && seq - ntls->next_seq < U32_MAX / 4)
tls_offload_tx_resync_request(nskb->sk);

*nr_frags = 0;
return nskb;
Expand Down

0 comments on commit 9ed431c

Please sign in to comment.