]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/tls/tls_device.c
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
[linux.git] / net / tls / tls_device.c
index 683d0083769350e3fa57c356e8bb43a5d8e350b4..0683788bbef07adec1e60b0e5545e904edfa9dcf 100644 (file)
@@ -38,6 +38,8 @@
 #include <net/tcp.h>
 #include <net/tls.h>
 
+#include "trace.h"
+
 /* device_offload_lock is used to synchronize tls_dev_add
  * against NETDEV_DOWN notifications.
  */
@@ -202,6 +204,15 @@ void tls_device_free_resources_tx(struct sock *sk)
        tls_free_partial_record(sk, tls_ctx);
 }
 
+void tls_offload_tx_resync_request(struct sock *sk, u32 got_seq, u32 exp_seq)
+{
+       struct tls_context *tls_ctx = tls_get_ctx(sk);
+
+       trace_tls_device_tx_resync_req(sk, got_seq, exp_seq);
+       WARN_ON(test_and_set_bit(TLS_TX_SYNC_SCHED, &tls_ctx->flags));
+}
+EXPORT_SYMBOL_GPL(tls_offload_tx_resync_request);
+
 static void tls_device_resync_tx(struct sock *sk, struct tls_context *tls_ctx,
                                 u32 seq)
 {
@@ -216,6 +227,7 @@ static void tls_device_resync_tx(struct sock *sk, struct tls_context *tls_ctx,
 
        rcd_sn = tls_ctx->tx.rec_seq;
 
+       trace_tls_device_tx_resync_send(sk, seq, rcd_sn);
        down_read(&device_offload_lock);
        netdev = tls_ctx->netdev;
        if (netdev)
@@ -419,7 +431,7 @@ static int tls_push_data(struct sock *sk,
            ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_SENDPAGE_NOTLAST))
                return -ENOTSUPP;
 
-       if (sk->sk_err)
+       if (unlikely(sk->sk_err))
                return -sk->sk_err;
 
        flags |= MSG_SENDPAGE_DECRYPTED;
@@ -440,9 +452,8 @@ static int tls_push_data(struct sock *sk,
        max_open_record_len = TLS_MAX_PAYLOAD_SIZE +
                              prot->prepend_size;
        do {
-               rc = tls_do_allocation(sk, ctx, pfrag,
-                                      prot->prepend_size);
-               if (rc) {
+               rc = tls_do_allocation(sk, ctx, pfrag, prot->prepend_size);
+               if (unlikely(rc)) {
                        rc = sk_stream_wait_memory(sk, &timeo);
                        if (!rc)
                                continue;
@@ -645,15 +656,19 @@ void tls_device_write_space(struct sock *sk, struct tls_context *ctx)
 static void tls_device_resync_rx(struct tls_context *tls_ctx,
                                 struct sock *sk, u32 seq, u8 *rcd_sn)
 {
+       struct tls_offload_context_rx *rx_ctx = tls_offload_ctx_rx(tls_ctx);
        struct net_device *netdev;
 
        if (WARN_ON(test_and_set_bit(TLS_RX_SYNC_RUNNING, &tls_ctx->flags)))
                return;
+
+       trace_tls_device_rx_resync_send(sk, seq, rcd_sn, rx_ctx->resync_type);
        netdev = READ_ONCE(tls_ctx->netdev);
        if (netdev)
                netdev->tlsdev_ops->tls_dev_resync(netdev, sk, seq, rcd_sn,
                                                   TLS_OFFLOAD_CTX_DIR_RX);
        clear_bit_unlock(TLS_RX_SYNC_RUNNING, &tls_ctx->flags);
+       TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSRXDEVICERESYNC);
 }
 
 void tls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq)
@@ -661,8 +676,8 @@ void tls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq)
        struct tls_context *tls_ctx = tls_get_ctx(sk);
        struct tls_offload_context_rx *rx_ctx;
        u8 rcd_sn[TLS_MAX_REC_SEQ_SIZE];
+       u32 sock_data, is_req_pending;
        struct tls_prot_info *prot;
-       u32 is_req_pending;
        s64 resync_req;
        u32 req_seq;
 
@@ -691,8 +706,12 @@ void tls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq)
                /* head of next rec is already in, note that the sock_inq will
                 * include the currently parsed message when called from parser
                 */
-               if (tcp_inq(sk) > rcd_len)
+               sock_data = tcp_inq(sk);
+               if (sock_data > rcd_len) {
+                       trace_tls_device_rx_resync_nh_delay(sk, sock_data,
+                                                           rcd_len);
                        return;
+               }
 
                rx_ctx->resync_nh_do_now = 0;
                seq += rcd_len;
@@ -736,6 +755,7 @@ static void tls_device_core_ctrl_rx_resync(struct tls_context *tls_ctx,
 
        /* head of next rec is already in, parser will sync for us */
        if (tcp_inq(sk) > rxm->full_len) {
+               trace_tls_device_rx_resync_nh_schedule(sk);
                ctx->resync_nh_do_now = 1;
        } else {
                struct tls_prot_info *prot = &tls_ctx->prot_info;
@@ -834,9 +854,9 @@ static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb)
        return err;
 }
 
-int tls_device_decrypted(struct sock *sk, struct sk_buff *skb)
+int tls_device_decrypted(struct sock *sk, struct tls_context *tls_ctx,
+                        struct sk_buff *skb, struct strp_msg *rxm)
 {
-       struct tls_context *tls_ctx = tls_get_ctx(sk);
        struct tls_offload_context_rx *ctx = tls_offload_ctx_rx(tls_ctx);
        int is_decrypted = skb->decrypted;
        int is_encrypted = !is_decrypted;
@@ -848,6 +868,10 @@ int tls_device_decrypted(struct sock *sk, struct sk_buff *skb)
                is_encrypted &= !skb_iter->decrypted;
        }
 
+       trace_tls_device_decrypted(sk, tcp_sk(sk)->copied_seq - rxm->full_len,
+                                  tls_ctx->rx.rec_seq, rxm->full_len,
+                                  is_encrypted, is_decrypted);
+
        ctx->sw.decrypted |= is_decrypted;
 
        /* Return immediately if the record is either entirely plaintext or
@@ -1021,6 +1045,8 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
        rc = netdev->tlsdev_ops->tls_dev_add(netdev, sk, TLS_OFFLOAD_CTX_DIR_TX,
                                             &ctx->crypto_send.info,
                                             tcp_sk(sk)->write_seq);
+       trace_tls_device_offload_set(sk, TLS_OFFLOAD_CTX_DIR_TX,
+                                    tcp_sk(sk)->write_seq, rec_seq, rc);
        if (rc)
                goto release_lock;
 
@@ -1057,6 +1083,7 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
 
 int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx)
 {
+       struct tls12_crypto_info_aes_gcm_128 *info;
        struct tls_offload_context_rx *context;
        struct net_device *netdev;
        int rc = 0;
@@ -1104,6 +1131,9 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx)
        rc = netdev->tlsdev_ops->tls_dev_add(netdev, sk, TLS_OFFLOAD_CTX_DIR_RX,
                                             &ctx->crypto_recv.info,
                                             tcp_sk(sk)->copied_seq);
+       info = (void *)&ctx->crypto_recv.info;
+       trace_tls_device_offload_set(sk, TLS_OFFLOAD_CTX_DIR_RX,
+                                    tcp_sk(sk)->copied_seq, info->rec_seq, rc);
        if (rc)
                goto free_sw_resources;