Commit 53601c68 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

nfp: tls: use unique connection ids instead of 4-tuple for TX

Connection 4 tuple reuse is slightly problematic - TLS socket
and context do not get destroyed until all the associated skbs
left the system and all references are released. This leads
to stale connection entry in the device preventing addition
of new one if the 4 tuple is reused quickly enough.

Instead of using read 4 tuple as the key use a unique ID.
Set the protocol to TCP and port to 0 to ensure no collisions
with real connections.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarDirk van der Merwe <dirk.vandermerwe@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ff8869d5
...@@ -31,6 +31,8 @@ struct nfp_crypto_req_add_front { ...@@ -31,6 +31,8 @@ struct nfp_crypto_req_add_front {
u8 key_len; u8 key_len;
__be16 ipver_vlan __packed; __be16 ipver_vlan __packed;
u8 l4_proto; u8 l4_proto;
#define NFP_NET_TLS_NON_ADDR_KEY_LEN 8
u8 l3_addrs[0];
}; };
struct nfp_crypto_req_add_back { struct nfp_crypto_req_add_back {
......
...@@ -155,17 +155,30 @@ nfp_net_tls_set_ipver_vlan(struct nfp_crypto_req_add_front *front, u8 ipver) ...@@ -155,17 +155,30 @@ nfp_net_tls_set_ipver_vlan(struct nfp_crypto_req_add_front *front, u8 ipver)
NFP_NET_TLS_VLAN_UNUSED)); NFP_NET_TLS_VLAN_UNUSED));
} }
static void
nfp_net_tls_assign_conn_id(struct nfp_net *nn,
struct nfp_crypto_req_add_front *front)
{
u32 len;
u64 id;
id = atomic64_inc_return(&nn->ktls_conn_id_gen);
len = front->key_len - NFP_NET_TLS_NON_ADDR_KEY_LEN;
memcpy(front->l3_addrs, &id, sizeof(id));
memset(front->l3_addrs + sizeof(id), 0, len - sizeof(id));
}
static struct nfp_crypto_req_add_back * static struct nfp_crypto_req_add_back *
nfp_net_tls_set_ipv4(struct nfp_crypto_req_add_v4 *req, struct sock *sk, nfp_net_tls_set_ipv4(struct nfp_net *nn, struct nfp_crypto_req_add_v4 *req,
int direction) struct sock *sk, int direction)
{ {
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
req->front.key_len += sizeof(__be32) * 2; req->front.key_len += sizeof(__be32) * 2;
if (direction == TLS_OFFLOAD_CTX_DIR_TX) { if (direction == TLS_OFFLOAD_CTX_DIR_TX) {
req->src_ip = inet->inet_saddr; nfp_net_tls_assign_conn_id(nn, &req->front);
req->dst_ip = inet->inet_daddr;
} else { } else {
req->src_ip = inet->inet_daddr; req->src_ip = inet->inet_daddr;
req->dst_ip = inet->inet_saddr; req->dst_ip = inet->inet_saddr;
...@@ -175,8 +188,8 @@ nfp_net_tls_set_ipv4(struct nfp_crypto_req_add_v4 *req, struct sock *sk, ...@@ -175,8 +188,8 @@ nfp_net_tls_set_ipv4(struct nfp_crypto_req_add_v4 *req, struct sock *sk,
} }
static struct nfp_crypto_req_add_back * static struct nfp_crypto_req_add_back *
nfp_net_tls_set_ipv6(struct nfp_crypto_req_add_v6 *req, struct sock *sk, nfp_net_tls_set_ipv6(struct nfp_net *nn, struct nfp_crypto_req_add_v6 *req,
int direction) struct sock *sk, int direction)
{ {
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
...@@ -184,8 +197,7 @@ nfp_net_tls_set_ipv6(struct nfp_crypto_req_add_v6 *req, struct sock *sk, ...@@ -184,8 +197,7 @@ nfp_net_tls_set_ipv6(struct nfp_crypto_req_add_v6 *req, struct sock *sk,
req->front.key_len += sizeof(struct in6_addr) * 2; req->front.key_len += sizeof(struct in6_addr) * 2;
if (direction == TLS_OFFLOAD_CTX_DIR_TX) { if (direction == TLS_OFFLOAD_CTX_DIR_TX) {
memcpy(req->src_ip, &np->saddr, sizeof(req->src_ip)); nfp_net_tls_assign_conn_id(nn, &req->front);
memcpy(req->dst_ip, &sk->sk_v6_daddr, sizeof(req->dst_ip));
} else { } else {
memcpy(req->src_ip, &sk->sk_v6_daddr, sizeof(req->src_ip)); memcpy(req->src_ip, &sk->sk_v6_daddr, sizeof(req->src_ip));
memcpy(req->dst_ip, &np->saddr, sizeof(req->dst_ip)); memcpy(req->dst_ip, &np->saddr, sizeof(req->dst_ip));
...@@ -205,8 +217,8 @@ nfp_net_tls_set_l4(struct nfp_crypto_req_add_front *front, ...@@ -205,8 +217,8 @@ nfp_net_tls_set_l4(struct nfp_crypto_req_add_front *front,
front->l4_proto = IPPROTO_TCP; front->l4_proto = IPPROTO_TCP;
if (direction == TLS_OFFLOAD_CTX_DIR_TX) { if (direction == TLS_OFFLOAD_CTX_DIR_TX) {
back->src_port = inet->inet_sport; back->src_port = 0;
back->dst_port = inet->inet_dport; back->dst_port = 0;
} else { } else {
back->src_port = inet->inet_dport; back->src_port = inet->inet_dport;
back->dst_port = inet->inet_sport; back->dst_port = inet->inet_sport;
...@@ -260,6 +272,7 @@ nfp_net_tls_add(struct net_device *netdev, struct sock *sk, ...@@ -260,6 +272,7 @@ nfp_net_tls_add(struct net_device *netdev, struct sock *sk,
struct nfp_crypto_reply_add *reply; struct nfp_crypto_reply_add *reply;
struct sk_buff *skb; struct sk_buff *skb;
size_t req_sz; size_t req_sz;
void *req;
bool ipv6; bool ipv6;
int err; int err;
...@@ -302,16 +315,17 @@ nfp_net_tls_add(struct net_device *netdev, struct sock *sk, ...@@ -302,16 +315,17 @@ nfp_net_tls_add(struct net_device *netdev, struct sock *sk,
front = (void *)skb->data; front = (void *)skb->data;
front->ep_id = 0; front->ep_id = 0;
front->key_len = 8; front->key_len = NFP_NET_TLS_NON_ADDR_KEY_LEN;
front->opcode = nfp_tls_1_2_dir_to_opcode(direction); front->opcode = nfp_tls_1_2_dir_to_opcode(direction);
memset(front->resv, 0, sizeof(front->resv)); memset(front->resv, 0, sizeof(front->resv));
nfp_net_tls_set_ipver_vlan(front, ipv6 ? 6 : 4); nfp_net_tls_set_ipver_vlan(front, ipv6 ? 6 : 4);
req = (void *)skb->data;
if (ipv6) if (ipv6)
back = nfp_net_tls_set_ipv6((void *)skb->data, sk, direction); back = nfp_net_tls_set_ipv6(nn, req, sk, direction);
else else
back = nfp_net_tls_set_ipv4((void *)skb->data, sk, direction); back = nfp_net_tls_set_ipv4(nn, req, sk, direction);
nfp_net_tls_set_l4(front, back, sk, direction); nfp_net_tls_set_l4(front, back, sk, direction);
...@@ -329,7 +343,8 @@ nfp_net_tls_add(struct net_device *netdev, struct sock *sk, ...@@ -329,7 +343,8 @@ nfp_net_tls_add(struct net_device *netdev, struct sock *sk,
err = nfp_ccm_mbox_communicate(nn, skb, NFP_CCM_TYPE_CRYPTO_ADD, err = nfp_ccm_mbox_communicate(nn, skb, NFP_CCM_TYPE_CRYPTO_ADD,
sizeof(*reply), sizeof(*reply)); sizeof(*reply), sizeof(*reply));
if (err) { if (err) {
nn_dp_warn(&nn->dp, "failed to add TLS: %d\n", err); nn_dp_warn(&nn->dp, "failed to add TLS: %d (%d)\n",
err, direction == TLS_OFFLOAD_CTX_DIR_TX);
/* communicate frees skb on error */ /* communicate frees skb on error */
goto err_conn_remove; goto err_conn_remove;
} }
......
...@@ -583,6 +583,7 @@ struct nfp_net_dp { ...@@ -583,6 +583,7 @@ struct nfp_net_dp {
* @tlv_caps: Parsed TLV capabilities * @tlv_caps: Parsed TLV capabilities
* @ktls_tx_conn_cnt: Number of offloaded kTLS TX connections * @ktls_tx_conn_cnt: Number of offloaded kTLS TX connections
* @ktls_rx_conn_cnt: Number of offloaded kTLS RX connections * @ktls_rx_conn_cnt: Number of offloaded kTLS RX connections
* @ktls_conn_id_gen: Trivial generator for kTLS connection ids (for TX)
* @ktls_no_space: Counter of firmware rejecting kTLS connection due to * @ktls_no_space: Counter of firmware rejecting kTLS connection due to
* lack of space * lack of space
* @mbox_cmsg: Common Control Message via vNIC mailbox state * @mbox_cmsg: Common Control Message via vNIC mailbox state
...@@ -670,6 +671,8 @@ struct nfp_net { ...@@ -670,6 +671,8 @@ struct nfp_net {
unsigned int ktls_tx_conn_cnt; unsigned int ktls_tx_conn_cnt;
unsigned int ktls_rx_conn_cnt; unsigned int ktls_rx_conn_cnt;
atomic64_t ktls_conn_id_gen;
atomic_t ktls_no_space; atomic_t ktls_no_space;
struct { struct {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment