Skip to content

Commit

Permalink
nfp: tls: add datapath support for TLS TX
Browse files Browse the repository at this point in the history
Prepend connection handle to each transmitted TLS packet.

For each connection, the driver tracks the next sequence number
expected. If an out of order packet is observed, the driver calls into
the TLS kernel code to reencrypt that particular skb.

Signed-off-by: Dirk van der Merwe <[email protected]>
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Dirk van der Merwe authored and davem330 committed Jun 6, 2019
1 parent b9727d7 commit c3991d3
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
7 changes: 7 additions & 0 deletions drivers/net/ethernet/netronome/nfp/crypto/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
#ifndef NFP_CRYPTO_H
#define NFP_CRYPTO_H 1

struct nfp_net_tls_offload_ctx {
__be32 fw_handle[2];

u32 next_seq;
bool out_of_sync;
};

#ifdef CONFIG_TLS_DEVICE
int nfp_net_tls_init(struct nfp_net *nn);
#else
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/netronome/nfp/nfp_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ struct nfp_stat_pair {
* @netdev: Backpointer to net_device structure
* @is_vf: Is the driver attached to a VF?
* @chained_metadata_format: Firemware will use new metadata format
* @ktls_tx: Is kTLS TX enabled?
* @rx_dma_dir: Mapping direction for RX buffers
* @rx_dma_off: Offset at which DMA packets (for XDP headroom)
* @rx_offset: Offset in the RX buffers where packet data starts
Expand All @@ -483,6 +484,7 @@ struct nfp_net_dp {

u8 is_vf:1;
u8 chained_metadata_format:1;
u8 ktls_tx:1;

u8 rx_dma_dir;
u8 rx_offset;
Expand Down
56 changes: 56 additions & 0 deletions drivers/net/ethernet/netronome/nfp/nfp_net_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <linux/vmalloc.h>
#include <linux/ktime.h>

#include <net/tls.h>
#include <net/vxlan.h>

#include "nfpcore/nfp_nsp.h"
Expand Down Expand Up @@ -801,6 +802,55 @@ static void nfp_net_tx_csum(struct nfp_net_dp *dp,
u64_stats_update_end(&r_vec->tx_sync);
}

#ifdef CONFIG_TLS_DEVICE
static struct sk_buff *
nfp_net_tls_tx(struct nfp_net_dp *dp, struct sk_buff *skb, u64 *tls_handle,
int *nr_frags)
{
struct nfp_net_tls_offload_ctx *ntls;
struct sk_buff *nskb;
u32 datalen, seq;

if (likely(!dp->ktls_tx))
return skb;
if (!skb->sk || !tls_is_sk_tx_device_offloaded(skb->sk))
return skb;

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)) {
/* Pure ACK out of order already */
if (!datalen)
return skb;

nskb = tls_encrypt_skb(skb);
if (!nskb)
return NULL;
/* encryption wasn't necessary */
if (nskb == skb)
return skb;
/* we don't re-check ring space */
if (unlikely(skb_is_nonlinear(nskb))) {
nn_dp_warn(dp, "tls_encrypt_skb() produced fragmented frame\n");
dev_kfree_skb_any(nskb);
return NULL;
}

/* 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;

*nr_frags = 0;
return nskb;
}

memcpy(tls_handle, ntls->fw_handle, sizeof(ntls->fw_handle));
ntls->next_seq += datalen;
return skb;
}
#endif

static void nfp_net_tx_xmit_more_flush(struct nfp_net_tx_ring *tx_ring)
{
wmb();
Expand Down Expand Up @@ -893,6 +943,12 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_BUSY;
}

#ifdef CONFIG_TLS_DEVICE
skb = nfp_net_tls_tx(dp, skb, &tls_handle, &nr_frags);
if (unlikely(!skb))
goto err_flush;
#endif

md_bytes = nfp_net_prep_tx_meta(skb, tls_handle);
if (unlikely(md_bytes < 0))
goto err_flush;
Expand Down

0 comments on commit c3991d3

Please sign in to comment.