Skip to content

Commit d829e9c

Browse files
borkmannAlexei Starovoitov
authored and
Alexei Starovoitov
committed
tls: convert to generic sk_msg interface
Convert kTLS over to make use of sk_msg interface for plaintext and encrypted scattergather data, so it reuses all the sk_msg helpers and data structure which later on in a second step enables to glue this to BPF. This also allows to remove quite a bit of open coded helpers which are covered by the sk_msg API. Recent changes in kTLs 80ece6a ("tls: Remove redundant vars from tls record structure") and 4e6d472 ("tls: Add support for inplace records encryption") changed the data path handling a bit; while we've kept the latter optimization intact, we had to undo the former change to better fit the sk_msg model, hence the sg_aead_in and sg_aead_out have been brought back and are linked into the sk_msg sgs. Now the kTLS record contains a msg_plaintext and msg_encrypted sk_msg each. In the original code, the zerocopy_from_iter() has been used out of TX but also RX path. For the strparser skb-based RX path, we've left the zerocopy_from_iter() in decrypt_internal() mostly untouched, meaning it has been moved into tls_setup_from_iter() with charging logic removed (as not used from RX). Given RX path is not based on sk_msg objects, we haven't pursued setting up a dummy sk_msg to call into sk_msg_zerocopy_from_iter(), but it could be an option to prusue in a later step. Joint work with John. Signed-off-by: Daniel Borkmann <[email protected]> Signed-off-by: John Fastabend <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 604326b commit d829e9c

File tree

8 files changed

+236
-402
lines changed

8 files changed

+236
-402
lines changed

include/linux/skmsg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ struct sk_psock {
102102

103103
int sk_msg_alloc(struct sock *sk, struct sk_msg *msg, int len,
104104
int elem_first_coalesce);
105+
int sk_msg_clone(struct sock *sk, struct sk_msg *dst, struct sk_msg *src,
106+
u32 off, u32 len);
105107
void sk_msg_trim(struct sock *sk, struct sk_msg *msg, int len);
106108
int sk_msg_free(struct sock *sk, struct sk_msg *msg);
107109
int sk_msg_free_nocharge(struct sock *sk, struct sk_msg *msg);

include/net/sock.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,10 +2214,6 @@ static inline struct page_frag *sk_page_frag(struct sock *sk)
22142214

22152215
bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag);
22162216

2217-
int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
2218-
int sg_start, int *sg_curr, unsigned int *sg_size,
2219-
int first_coalesce);
2220-
22212217
/*
22222218
* Default write policy as shown to user space via poll/select/SIGIO
22232219
*/

include/net/tls.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#include <linux/crypto.h>
4040
#include <linux/socket.h>
4141
#include <linux/tcp.h>
42+
#include <linux/skmsg.h>
43+
4244
#include <net/tcp.h>
4345
#include <net/strparser.h>
4446
#include <crypto/aead.h>
@@ -103,15 +105,13 @@ struct tls_rec {
103105
int tx_flags;
104106
int inplace_crypto;
105107

106-
/* AAD | sg_plaintext_data | sg_tag */
107-
struct scatterlist sg_plaintext_data[MAX_SKB_FRAGS + 1];
108-
/* AAD | sg_encrypted_data (data contain overhead for hdr&iv&tag) */
109-
struct scatterlist sg_encrypted_data[MAX_SKB_FRAGS + 1];
108+
struct sk_msg msg_plaintext;
109+
struct sk_msg msg_encrypted;
110110

111-
unsigned int sg_plaintext_size;
112-
unsigned int sg_encrypted_size;
113-
int sg_plaintext_num_elem;
114-
int sg_encrypted_num_elem;
111+
/* AAD | msg_plaintext.sg.data | sg_tag */
112+
struct scatterlist sg_aead_in[2];
113+
/* AAD | msg_encrypted.sg.data (data contains overhead for hdr & iv & tag) */
114+
struct scatterlist sg_aead_out[2];
115115

116116
char aad_space[TLS_AAD_SPACE_SIZE];
117117
struct aead_request aead_req;
@@ -223,8 +223,8 @@ struct tls_context {
223223

224224
unsigned long flags;
225225
bool in_tcp_sendpages;
226+
bool pending_open_record_frags;
226227

227-
u16 pending_open_record_frags;
228228
int (*push_pending_record)(struct sock *sk, int flags);
229229

230230
void (*sk_write_space)(struct sock *sk);

net/core/skmsg.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,45 @@ int sk_msg_alloc(struct sock *sk, struct sk_msg *msg, int len,
7373
}
7474
EXPORT_SYMBOL_GPL(sk_msg_alloc);
7575

76+
int sk_msg_clone(struct sock *sk, struct sk_msg *dst, struct sk_msg *src,
77+
u32 off, u32 len)
78+
{
79+
int i = src->sg.start;
80+
struct scatterlist *sge = sk_msg_elem(src, i);
81+
u32 sge_len, sge_off;
82+
83+
if (sk_msg_full(dst))
84+
return -ENOSPC;
85+
86+
while (off) {
87+
if (sge->length > off)
88+
break;
89+
off -= sge->length;
90+
sk_msg_iter_var_next(i);
91+
if (i == src->sg.end && off)
92+
return -ENOSPC;
93+
sge = sk_msg_elem(src, i);
94+
}
95+
96+
while (len) {
97+
sge_len = sge->length - off;
98+
sge_off = sge->offset + off;
99+
if (sge_len > len)
100+
sge_len = len;
101+
off = 0;
102+
len -= sge_len;
103+
sk_msg_page_add(dst, sg_page(sge), sge_len, sge_off);
104+
sk_mem_charge(sk, sge_len);
105+
sk_msg_iter_var_next(i);
106+
if (i == src->sg.end && len)
107+
return -ENOSPC;
108+
sge = sk_msg_elem(src, i);
109+
}
110+
111+
return 0;
112+
}
113+
EXPORT_SYMBOL_GPL(sk_msg_clone);
114+
76115
void sk_msg_return_zero(struct sock *sk, struct sk_msg *msg, int bytes)
77116
{
78117
int i = msg->sg.start;

net/core/sock.c

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,67 +2238,6 @@ bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag)
22382238
}
22392239
EXPORT_SYMBOL(sk_page_frag_refill);
22402240

2241-
int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
2242-
int sg_start, int *sg_curr_index, unsigned int *sg_curr_size,
2243-
int first_coalesce)
2244-
{
2245-
int sg_curr = *sg_curr_index, use = 0, rc = 0;
2246-
unsigned int size = *sg_curr_size;
2247-
struct page_frag *pfrag;
2248-
struct scatterlist *sge;
2249-
2250-
len -= size;
2251-
pfrag = sk_page_frag(sk);
2252-
2253-
while (len > 0) {
2254-
unsigned int orig_offset;
2255-
2256-
if (!sk_page_frag_refill(sk, pfrag)) {
2257-
rc = -ENOMEM;
2258-
goto out;
2259-
}
2260-
2261-
use = min_t(int, len, pfrag->size - pfrag->offset);
2262-
2263-
if (!sk_wmem_schedule(sk, use)) {
2264-
rc = -ENOMEM;
2265-
goto out;
2266-
}
2267-
2268-
sk_mem_charge(sk, use);
2269-
size += use;
2270-
orig_offset = pfrag->offset;
2271-
pfrag->offset += use;
2272-
2273-
sge = sg + sg_curr - 1;
2274-
if (sg_curr > first_coalesce && sg_page(sge) == pfrag->page &&
2275-
sge->offset + sge->length == orig_offset) {
2276-
sge->length += use;
2277-
} else {
2278-
sge = sg + sg_curr;
2279-
sg_unmark_end(sge);
2280-
sg_set_page(sge, pfrag->page, use, orig_offset);
2281-
get_page(pfrag->page);
2282-
sg_curr++;
2283-
2284-
if (sg_curr == MAX_SKB_FRAGS)
2285-
sg_curr = 0;
2286-
2287-
if (sg_curr == sg_start) {
2288-
rc = -ENOSPC;
2289-
break;
2290-
}
2291-
}
2292-
2293-
len -= use;
2294-
}
2295-
out:
2296-
*sg_curr_size = size;
2297-
*sg_curr_index = sg_curr;
2298-
return rc;
2299-
}
2300-
EXPORT_SYMBOL(sk_alloc_sg);
2301-
23022241
static void __lock_sock(struct sock *sk)
23032242
__releases(&sk->sk_lock.slock)
23042243
__acquires(&sk->sk_lock.slock)

net/tls/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ config TLS
88
select CRYPTO_AES
99
select CRYPTO_GCM
1010
select STREAM_PARSER
11+
select NET_SOCK_MSG
1112
default n
1213
---help---
1314
Enable kernel support for TLS protocol. This allows symmetric

net/tls/tls_device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ static int tls_push_data(struct sock *sk,
421421
tls_push_record_flags = flags;
422422
if (more) {
423423
tls_ctx->pending_open_record_frags =
424-
record->num_frags;
424+
!!record->num_frags;
425425
break;
426426
}
427427

0 commit comments

Comments
 (0)