Commit 5f04a6d8 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'nfp-tls-implement-the-stream-sync-RX-resync'



Jakub Kicinski says:

====================
nfp: tls: implement the stream sync RX resync

This small series adds support for using the device
in stream scan RX resync mode which improves the RX
resync success rate. Without stream scan it's pretty
much impossible to successfully resync a continuous
stream.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8fb0d2ce 6a35ddc5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ enum nfp_ccm_type {
	NFP_CCM_TYPE_CRYPTO_ADD		= 10,
	NFP_CCM_TYPE_CRYPTO_DEL		= 11,
	NFP_CCM_TYPE_CRYPTO_UPDATE	= 12,
	NFP_CCM_TYPE_CRYPTO_RESYNC	= 13,
	__NFP_CCM_TYPE_MAX,
};

+15 −0
Original line number Diff line number Diff line
@@ -4,6 +4,10 @@
#ifndef NFP_CRYPTO_H
#define NFP_CRYPTO_H 1

struct net_device;
struct nfp_net;
struct nfp_net_tls_resync_req;

struct nfp_net_tls_offload_ctx {
	__be32 fw_handle[2];

@@ -17,11 +21,22 @@ struct nfp_net_tls_offload_ctx {

#ifdef CONFIG_TLS_DEVICE
int nfp_net_tls_init(struct nfp_net *nn);
int nfp_net_tls_rx_resync_req(struct net_device *netdev,
			      struct nfp_net_tls_resync_req *req,
			      void *pkt, unsigned int pkt_len);
#else
static inline int nfp_net_tls_init(struct nfp_net *nn)
{
	return 0;
}

static inline int
nfp_net_tls_rx_resync_req(struct net_device *netdev,
			  struct nfp_net_tls_resync_req *req,
			  void *pkt, unsigned int pkt_len)
{
	return -EOPNOTSUPP;
}
#endif

#endif
+8 −0
Original line number Diff line number Diff line
@@ -9,6 +9,14 @@
#define NFP_NET_CRYPTO_OP_TLS_1_2_AES_GCM_128_ENC	0
#define NFP_NET_CRYPTO_OP_TLS_1_2_AES_GCM_128_DEC	1

struct nfp_net_tls_resync_req {
	__be32 fw_handle[2];
	__be32 tcp_seq;
	u8 l3_offset;
	u8 l4_offset;
	u8 resv[2];
};

struct nfp_crypto_reply_simple {
	struct nfp_ccm_hdr hdr;
	__be32 error;
+84 −5
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <linux/ipv6.h>
#include <linux/skbuff.h>
#include <linux/string.h>
#include <net/inet6_hashtables.h>
#include <net/tls.h>

#include "../ccm.h"
@@ -391,8 +392,9 @@ nfp_net_tls_add(struct net_device *netdev, struct sock *sk,
	if (direction == TLS_OFFLOAD_CTX_DIR_TX)
		return 0;

	tls_offload_rx_resync_set_type(sk,
				       TLS_OFFLOAD_SYNC_TYPE_CORE_NEXT_HINT);
	if (!nn->tlv_caps.tls_resync_ss)
		tls_offload_rx_resync_set_type(sk, TLS_OFFLOAD_SYNC_TYPE_CORE_NEXT_HINT);

	return 0;

err_fw_remove:
@@ -424,6 +426,7 @@ nfp_net_tls_resync(struct net_device *netdev, struct sock *sk, u32 seq,
	struct nfp_net *nn = netdev_priv(netdev);
	struct nfp_net_tls_offload_ctx *ntls;
	struct nfp_crypto_req_update *req;
	enum nfp_ccm_type type;
	struct sk_buff *skb;
	gfp_t flags;
	int err;
@@ -442,15 +445,18 @@ nfp_net_tls_resync(struct net_device *netdev, struct sock *sk, u32 seq,
	req->tcp_seq = cpu_to_be32(seq);
	memcpy(req->rec_no, rcd_sn, sizeof(req->rec_no));

	type = NFP_CCM_TYPE_CRYPTO_UPDATE;
	if (direction == TLS_OFFLOAD_CTX_DIR_TX) {
		err = nfp_net_tls_communicate_simple(nn, skb, "sync",
						     NFP_CCM_TYPE_CRYPTO_UPDATE);
		err = nfp_net_tls_communicate_simple(nn, skb, "sync", type);
		if (err)
			return err;
		ntls->next_seq = seq;
	} else {
		nfp_ccm_mbox_post(nn, skb, NFP_CCM_TYPE_CRYPTO_UPDATE,
		if (nn->tlv_caps.tls_resync_ss)
			type = NFP_CCM_TYPE_CRYPTO_RESYNC;
		nfp_ccm_mbox_post(nn, skb, type,
				  sizeof(struct nfp_crypto_reply_simple));
		atomic_inc(&nn->ktls_rx_resync_sent);
	}

	return 0;
@@ -462,6 +468,79 @@ static const struct tlsdev_ops nfp_net_tls_ops = {
	.tls_dev_resync = nfp_net_tls_resync,
};

int nfp_net_tls_rx_resync_req(struct net_device *netdev,
			      struct nfp_net_tls_resync_req *req,
			      void *pkt, unsigned int pkt_len)
{
	struct nfp_net *nn = netdev_priv(netdev);
	struct nfp_net_tls_offload_ctx *ntls;
	struct ipv6hdr *ipv6h;
	struct tcphdr *th;
	struct iphdr *iph;
	struct sock *sk;
	__be32 tcp_seq;
	int err;

	iph = pkt + req->l3_offset;
	ipv6h = pkt + req->l3_offset;
	th = pkt + req->l4_offset;

	if ((u8 *)&th[1] > (u8 *)pkt + pkt_len) {
		netdev_warn_once(netdev, "invalid TLS RX resync request (l3_off: %hhu l4_off: %hhu pkt_len: %u)\n",
				 req->l3_offset, req->l4_offset, pkt_len);
		err = -EINVAL;
		goto err_cnt_ign;
	}

	switch (iph->version) {
	case 4:
		sk = inet_lookup_established(dev_net(netdev), &tcp_hashinfo,
					     iph->saddr, th->source, iph->daddr,
					     th->dest, netdev->ifindex);
		break;
#if IS_ENABLED(CONFIG_IPV6)
	case 6:
		sk = __inet6_lookup_established(dev_net(netdev), &tcp_hashinfo,
						&ipv6h->saddr, th->source,
						&ipv6h->daddr, ntohs(th->dest),
						netdev->ifindex, 0);
		break;
#endif
	default:
		netdev_warn_once(netdev, "invalid TLS RX resync request (l3_off: %hhu l4_off: %hhu ipver: %u)\n",
				 req->l3_offset, req->l4_offset, iph->version);
		err = -EINVAL;
		goto err_cnt_ign;
	}

	err = 0;
	if (!sk)
		goto err_cnt_ign;
	if (!tls_is_sk_rx_device_offloaded(sk) ||
	    sk->sk_shutdown & RCV_SHUTDOWN)
		goto err_put_sock;

	ntls = tls_driver_ctx(sk, TLS_OFFLOAD_CTX_DIR_RX);
	/* some FW versions can't report the handle and report 0s */
	if (memchr_inv(&req->fw_handle, 0, sizeof(req->fw_handle)) &&
	    memcmp(&req->fw_handle, &ntls->fw_handle, sizeof(ntls->fw_handle)))
		goto err_put_sock;

	/* copy to ensure alignment */
	memcpy(&tcp_seq, &req->tcp_seq, sizeof(tcp_seq));
	tls_offload_rx_resync_request(sk, tcp_seq);
	atomic_inc(&nn->ktls_rx_resync_req);

	sock_gen_put(sk);
	return 0;

err_put_sock:
	sock_gen_put(sk);
err_cnt_ign:
	atomic_inc(&nn->ktls_rx_resync_ign);
	return err;
}

static int nfp_net_tls_reset(struct nfp_net *nn)
{
	struct nfp_crypto_req_reset *req;
+6 −0
Original line number Diff line number Diff line
@@ -586,6 +586,9 @@ struct nfp_net_dp {
 * @ktls_conn_id_gen:	Trivial generator for kTLS connection ids (for TX)
 * @ktls_no_space:	Counter of firmware rejecting kTLS connection due to
 *			lack of space
 * @ktls_rx_resync_req:	Counter of TLS RX resync requested
 * @ktls_rx_resync_ign:	Counter of TLS RX resync requests ignored
 * @ktls_rx_resync_sent:    Counter of TLS RX resync completed
 * @mbox_cmsg:		Common Control Message via vNIC mailbox state
 * @mbox_cmsg.queue:	CCM mbox queue of pending messages
 * @mbox_cmsg.wq:	CCM mbox wait queue of waiting processes
@@ -674,6 +677,9 @@ struct nfp_net {
	atomic64_t ktls_conn_id_gen;

	atomic_t ktls_no_space;
	atomic_t ktls_rx_resync_req;
	atomic_t ktls_rx_resync_ign;
	atomic_t ktls_rx_resync_sent;

	struct {
		struct sk_buff_head queue;
Loading