nfp: tls: undo TLS sequence tracking when dropping the frame
authorJakub Kicinski <jakub.kicinski@netronome.com>
Tue, 9 Jul 2019 02:53:17 +0000 (19:53 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 9 Jul 2019 03:21:09 +0000 (20:21 -0700)
If driver has to drop the TLS frame it needs to undo the TCP
sequence tracking changes, otherwise device will receive
segments out of order and drop them.

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>
drivers/net/ethernet/netronome/nfp/nfp_net_common.c

index 54dd98b2d64565125a355ef1c8c8b1469ad0574e..9903805717da4ebfb7f6a222eb4d9aafd8755753 100644 (file)
@@ -893,6 +893,28 @@ nfp_net_tls_tx(struct nfp_net_dp *dp, struct nfp_net_r_vector *r_vec,
        return skb;
 }
 
+static void nfp_net_tls_tx_undo(struct sk_buff *skb, u64 tls_handle)
+{
+#ifdef CONFIG_TLS_DEVICE
+       struct nfp_net_tls_offload_ctx *ntls;
+       u32 datalen, seq;
+
+       if (!tls_handle)
+               return;
+       if (WARN_ON_ONCE(!skb->sk || !tls_is_sk_tx_device_offloaded(skb->sk)))
+               return;
+
+       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 (ntls->next_seq == seq + datalen)
+               ntls->next_seq = seq;
+       else
+               WARN_ON_ONCE(1);
+#endif
+}
+
 static void nfp_net_tx_xmit_more_flush(struct nfp_net_tx_ring *tx_ring)
 {
        wmb();
@@ -1102,6 +1124,7 @@ err_flush:
        u64_stats_update_begin(&r_vec->tx_sync);
        r_vec->tx_errors++;
        u64_stats_update_end(&r_vec->tx_sync);
+       nfp_net_tls_tx_undo(skb, tls_handle);
        dev_kfree_skb_any(skb);
        return NETDEV_TX_OK;
 }