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

tls: rx: jump out for cases which need to leave skb on list

The current invese logic is harder to follow (and adds extra
tests to the fast path). We have to enumerate all cases which
need to keep the skb before consuming it. It's simpler to
jump out of the full record flow as we detect those cases.

This makes it clear that partial consumption and peek can
only reach end of the function thru the !zc case so move
the code up there.
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b1a2c178
...@@ -1773,7 +1773,6 @@ int tls_sw_recvmsg(struct sock *sk, ...@@ -1773,7 +1773,6 @@ int tls_sw_recvmsg(struct sock *sk,
decrypted = 0; decrypted = 0;
while (len && (decrypted + copied < target || ctx->recv_pkt)) { while (len && (decrypted + copied < target || ctx->recv_pkt)) {
struct tls_decrypt_arg darg = {}; struct tls_decrypt_arg darg = {};
bool retain_skb = false;
int to_decrypt, chunk; int to_decrypt, chunk;
skb = tls_wait_data(sk, psock, flags & MSG_DONTWAIT, timeo, &err); skb = tls_wait_data(sk, psock, flags & MSG_DONTWAIT, timeo, &err);
...@@ -1833,12 +1832,17 @@ int tls_sw_recvmsg(struct sock *sk, ...@@ -1833,12 +1832,17 @@ int tls_sw_recvmsg(struct sock *sk,
if (async) { if (async) {
/* TLS 1.2-only, to_decrypt must be text length */ /* TLS 1.2-only, to_decrypt must be text length */
chunk = min_t(int, to_decrypt, len); chunk = min_t(int, to_decrypt, len);
goto pick_next_record; leave_on_list:
decrypted += chunk;
len -= chunk;
continue;
} }
/* TLS 1.3 may have updated the length by more than overhead */ /* TLS 1.3 may have updated the length by more than overhead */
chunk = rxm->full_len; chunk = rxm->full_len;
if (!darg.zc) { if (!darg.zc) {
bool partially_consumed = chunk > len;
if (bpf_strp_enabled) { if (bpf_strp_enabled) {
err = sk_psock_tls_strp_read(psock, skb); err = sk_psock_tls_strp_read(psock, skb);
if (err != __SK_PASS) { if (err != __SK_PASS) {
...@@ -1851,39 +1855,36 @@ int tls_sw_recvmsg(struct sock *sk, ...@@ -1851,39 +1855,36 @@ int tls_sw_recvmsg(struct sock *sk,
} }
} }
if (chunk > len) { if (partially_consumed)
retain_skb = true;
chunk = len; chunk = len;
}
err = skb_copy_datagram_msg(skb, rxm->offset, err = skb_copy_datagram_msg(skb, rxm->offset,
msg, chunk); msg, chunk);
if (err < 0) if (err < 0)
goto recv_end; goto recv_end;
if (!is_peek) { if (is_peek)
rxm->offset = rxm->offset + chunk; goto leave_on_list;
rxm->full_len = rxm->full_len - chunk;
if (partially_consumed) {
rxm->offset += chunk;
rxm->full_len -= chunk;
goto leave_on_list;
} }
} }
pick_next_record:
decrypted += chunk; decrypted += chunk;
len -= chunk; len -= chunk;
/* For async or peek case, queue the current skb */ skb_unlink(skb, &ctx->rx_list);
if (!(async || is_peek || retain_skb)) { consume_skb(skb);
skb_unlink(skb, &ctx->rx_list);
consume_skb(skb);
/* Return full control message to /* Return full control message to userspace before trying
* userspace before trying to parse * to parse another message type
* another message type */
*/ msg->msg_flags |= MSG_EOR;
msg->msg_flags |= MSG_EOR; if (control != TLS_RECORD_TYPE_DATA)
if (control != TLS_RECORD_TYPE_DATA) break;
goto recv_end;
}
} }
recv_end: recv_end:
......
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