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.kicin...@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vanderme...@netronome.com>
---
 .../ethernet/netronome/nfp/nfp_net_common.c   | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 54dd98b2d645..9903805717da 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -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 @@ static int nfp_net_tx(struct sk_buff *skb, struct 
net_device *netdev)
        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;
 }
-- 
2.21.0

Reply via email to