Skip to content

Commit b20ac8d

Browse files
committed
Merge branch 'net-tls-small-general-improvements'
Jakub Kicinski says: ==================== net/tls: small general improvements This series cleans up and improves the tls code, mostly the offload parts. First a slight performance optimization - avoiding unnecessary re- -encryption of records in patch 1. Next patch 2 makes the code more resilient by checking for errors in skb_copy_bits(). Next commit removes a warning which can be triggered in normal operation, (especially for devices explicitly making use of the fallback path). Next two paths change the condition checking around the call to tls_device_decrypted() to make it easier to extend. Remaining commits are centered around reorganizing struct tls_context for better cache utilization. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 7e7d199 + fb0f886 commit b20ac8d

File tree

8 files changed

+75
-65
lines changed

8 files changed

+75
-65
lines changed

Documentation/networking/tls-offload.rst

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,6 @@ by the driver:
379379
but did not arrive in the expected order
380380
* ``tx_tls_drop_no_sync_data`` - number of TX packets dropped because
381381
they arrived out of order and associated record could not be found
382-
(see also :ref:`pre_tls_data`)
383382

384383
Notable corner cases, exceptions and additional requirements
385384
============================================================
@@ -462,21 +461,3 @@ Redirects leak clear text
462461

463462
In the RX direction, if segment has already been decrypted by the device
464463
and it gets redirected or mirrored - clear text will be transmitted out.
465-
466-
.. _pre_tls_data:
467-
468-
Transmission of pre-TLS data
469-
----------------------------
470-
471-
User can enqueue some already encrypted and framed records before enabling
472-
``ktls`` on the socket. Those records have to get sent as they are. This is
473-
perfectly easy to handle in the software case - such data will be waiting
474-
in the TCP layer, TLS ULP won't see it. In the offloaded case when pre-queued
475-
segment reaches transmission point it appears to be out of order (before the
476-
expected TCP sequence number) and the stack does not have a record information
477-
associated.
478-
479-
All segments without record information cannot, however, be assumed to be
480-
pre-queued data, because a race condition exists between TCP stack queuing
481-
a retransmission, the driver seeing the retransmission and TCP ACK arriving
482-
for the retransmitted data.

include/linux/skbuff.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,7 @@ struct sk_buff *alloc_skb_with_frags(unsigned long header_len,
10631063
int max_page_order,
10641064
int *errcode,
10651065
gfp_t gfp_mask);
1066+
struct sk_buff *alloc_skb_for_msg(struct sk_buff *first);
10661067

10671068
/* Layout of fast clones : [skb1][skb2][fclone_ref] */
10681069
struct sk_buff_fclones {

include/net/tls.h

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -236,34 +236,32 @@ struct tls_prot_info {
236236
};
237237

238238
struct tls_context {
239+
/* read-only cache line */
239240
struct tls_prot_info prot_info;
240241

241-
union tls_crypto_context crypto_send;
242-
union tls_crypto_context crypto_recv;
242+
u8 tx_conf:3;
243+
u8 rx_conf:3;
243244

244-
struct list_head list;
245-
struct net_device *netdev;
246-
refcount_t refcount;
245+
int (*push_pending_record)(struct sock *sk, int flags);
246+
void (*sk_write_space)(struct sock *sk);
247247

248248
void *priv_ctx_tx;
249249
void *priv_ctx_rx;
250250

251-
u8 tx_conf:3;
252-
u8 rx_conf:3;
251+
struct net_device *netdev;
253252

253+
/* rw cache line */
254254
struct cipher_context tx;
255255
struct cipher_context rx;
256256

257257
struct scatterlist *partially_sent_record;
258258
u16 partially_sent_offset;
259259

260-
unsigned long flags;
261260
bool in_tcp_sendpages;
262261
bool pending_open_record_frags;
262+
unsigned long flags;
263263

264-
int (*push_pending_record)(struct sock *sk, int flags);
265-
266-
void (*sk_write_space)(struct sock *sk);
264+
/* cache cold stuff */
267265
void (*sk_destruct)(struct sock *sk);
268266
void (*sk_proto_close)(struct sock *sk, long timeout);
269267

@@ -275,6 +273,12 @@ struct tls_context {
275273
int __user *optlen);
276274
int (*hash)(struct sock *sk);
277275
void (*unhash)(struct sock *sk);
276+
277+
union tls_crypto_context crypto_send;
278+
union tls_crypto_context crypto_recv;
279+
280+
struct list_head list;
281+
refcount_t refcount;
278282
};
279283

280284
enum tls_offload_ctx_dir {
@@ -442,19 +446,15 @@ static inline struct tls_context *tls_get_ctx(const struct sock *sk)
442446
}
443447

444448
static inline void tls_advance_record_sn(struct sock *sk,
445-
struct cipher_context *ctx,
446-
int version)
449+
struct tls_prot_info *prot,
450+
struct cipher_context *ctx)
447451
{
448-
struct tls_context *tls_ctx = tls_get_ctx(sk);
449-
struct tls_prot_info *prot = &tls_ctx->prot_info;
450-
451452
if (tls_bigint_increment(ctx->rec_seq, prot->rec_seq_size))
452453
tls_err_abort(sk, EBADMSG);
453454

454-
if (version != TLS_1_3_VERSION) {
455+
if (prot->version != TLS_1_3_VERSION)
455456
tls_bigint_increment(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
456457
prot->iv_size);
457-
}
458458
}
459459

460460
static inline void tls_fill_prepend(struct tls_context *ctx,

net/core/skbuff.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,31 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
913913
#undef C
914914
}
915915

916+
/**
917+
* alloc_skb_for_msg() - allocate sk_buff to wrap frag list forming a msg
918+
* @first: first sk_buff of the msg
919+
*/
920+
struct sk_buff *alloc_skb_for_msg(struct sk_buff *first)
921+
{
922+
struct sk_buff *n;
923+
924+
n = alloc_skb(0, GFP_ATOMIC);
925+
if (!n)
926+
return NULL;
927+
928+
n->len = first->len;
929+
n->data_len = first->len;
930+
n->truesize = first->truesize;
931+
932+
skb_shinfo(n)->frag_list = first;
933+
934+
__copy_skb_header(n, first);
935+
n->destructor = NULL;
936+
937+
return n;
938+
}
939+
EXPORT_SYMBOL_GPL(alloc_skb_for_msg);
940+
916941
/**
917942
* skb_morph - morph one skb into another
918943
* @dst: the skb to receive the contents

net/strparser/strparser.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,18 +160,14 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
160160
return 0;
161161
}
162162

163-
skb = alloc_skb(0, GFP_ATOMIC);
163+
skb = alloc_skb_for_msg(head);
164164
if (!skb) {
165165
STRP_STATS_INCR(strp->stats.mem_fail);
166166
desc->error = -ENOMEM;
167167
return 0;
168168
}
169-
skb->len = head->len;
170-
skb->data_len = head->len;
171-
skb->truesize = head->truesize;
172-
*_strp_msg(skb) = *_strp_msg(head);
169+
173170
strp->skb_nextp = &head->next;
174-
skb_shinfo(skb)->frag_list = head;
175171
strp->skb_head = skb;
176172
head = skb;
177173
} else {

net/tls/tls_device.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ static int tls_push_record(struct sock *sk,
252252
skb_frag_address(frag),
253253
record->len - prot->prepend_size,
254254
record_type,
255-
ctx->crypto_send.info.version);
255+
prot->version);
256256

257257
/* HW doesn't care about the data in the tag, because it fills it. */
258258
dummy_tag_frag.page = skb_frag_page(frag);
@@ -264,7 +264,7 @@ static int tls_push_record(struct sock *sk,
264264
list_add_tail(&record->list, &offload_ctx->records_list);
265265
spin_unlock_irq(&offload_ctx->lock);
266266
offload_ctx->open_record = NULL;
267-
tls_advance_record_sn(sk, &ctx->tx, ctx->crypto_send.info.version);
267+
tls_advance_record_sn(sk, prot, &ctx->tx);
268268

269269
for (i = 0; i < record->num_frags; i++) {
270270
frag = &record->frags[i];
@@ -603,8 +603,10 @@ static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb)
603603
sg_set_buf(&sg[0], buf,
604604
rxm->full_len + TLS_HEADER_SIZE +
605605
TLS_CIPHER_AES_GCM_128_IV_SIZE);
606-
skb_copy_bits(skb, offset, buf,
607-
TLS_HEADER_SIZE + TLS_CIPHER_AES_GCM_128_IV_SIZE);
606+
err = skb_copy_bits(skb, offset, buf,
607+
TLS_HEADER_SIZE + TLS_CIPHER_AES_GCM_128_IV_SIZE);
608+
if (err)
609+
goto free_buf;
608610

609611
/* We are interested only in the decrypted data not the auth */
610612
err = decrypt_skb(sk, skb, sg);
@@ -618,8 +620,11 @@ static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb)
618620
if (skb_pagelen(skb) > offset) {
619621
copy = min_t(int, skb_pagelen(skb) - offset, data_len);
620622

621-
if (skb->decrypted)
622-
skb_store_bits(skb, offset, buf, copy);
623+
if (skb->decrypted) {
624+
err = skb_store_bits(skb, offset, buf, copy);
625+
if (err)
626+
goto free_buf;
627+
}
623628

624629
offset += copy;
625630
buf += copy;
@@ -642,8 +647,11 @@ static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb)
642647
copy = min_t(int, skb_iter->len - frag_pos,
643648
data_len + rxm->offset - offset);
644649

645-
if (skb_iter->decrypted)
646-
skb_store_bits(skb_iter, frag_pos, buf, copy);
650+
if (skb_iter->decrypted) {
651+
err = skb_store_bits(skb_iter, frag_pos, buf, copy);
652+
if (err)
653+
goto free_buf;
654+
}
647655

648656
offset += copy;
649657
buf += copy;
@@ -664,10 +672,6 @@ int tls_device_decrypted(struct sock *sk, struct sk_buff *skb)
664672
int is_encrypted = !is_decrypted;
665673
struct sk_buff *skb_iter;
666674

667-
/* Skip if it is already decrypted */
668-
if (ctx->sw.decrypted)
669-
return 0;
670-
671675
/* Check if all the data is decrypted already */
672676
skb_walk_frags(skb, skb_iter) {
673677
is_decrypted &= skb_iter->decrypted;

net/tls/tls_device_fallback.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ static int fill_sg_in(struct scatterlist *sg_in,
240240
record = tls_get_record(ctx, tcp_seq, rcd_sn);
241241
if (!record) {
242242
spin_unlock_irqrestore(&ctx->lock, flags);
243-
WARN(1, "Record not found for seq %u\n", tcp_seq);
244243
return -EINVAL;
245244
}
246245

@@ -409,7 +408,10 @@ static struct sk_buff *tls_sw_fallback(struct sock *sk, struct sk_buff *skb)
409408
put_page(sg_page(&sg_in[--resync_sgs]));
410409
kfree(sg_in);
411410
free_orig:
412-
kfree_skb(skb);
411+
if (nskb)
412+
consume_skb(skb);
413+
else
414+
kfree_skb(skb);
413415
return nskb;
414416
}
415417

net/tls/tls_sw.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ static int tls_do_encryption(struct sock *sk,
534534

535535
/* Unhook the record from context if encryption is not failure */
536536
ctx->open_rec = NULL;
537-
tls_advance_record_sn(sk, &tls_ctx->tx, prot->version);
537+
tls_advance_record_sn(sk, prot, &tls_ctx->tx);
538538
return rc;
539539
}
540540

@@ -1486,24 +1486,25 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb,
14861486
struct tls_context *tls_ctx = tls_get_ctx(sk);
14871487
struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
14881488
struct tls_prot_info *prot = &tls_ctx->prot_info;
1489-
int version = prot->version;
14901489
struct strp_msg *rxm = strp_msg(skb);
14911490
int pad, err = 0;
14921491

14931492
if (!ctx->decrypted) {
14941493
#ifdef CONFIG_TLS_DEVICE
1495-
err = tls_device_decrypted(sk, skb);
1496-
if (err < 0)
1497-
return err;
1494+
if (tls_ctx->rx_conf == TLS_HW) {
1495+
err = tls_device_decrypted(sk, skb);
1496+
if (err < 0)
1497+
return err;
1498+
}
14981499
#endif
14991500
/* Still not decrypted after tls_device */
15001501
if (!ctx->decrypted) {
15011502
err = decrypt_internal(sk, skb, dest, NULL, chunk, zc,
15021503
async);
15031504
if (err < 0) {
15041505
if (err == -EINPROGRESS)
1505-
tls_advance_record_sn(sk, &tls_ctx->rx,
1506-
version);
1506+
tls_advance_record_sn(sk, prot,
1507+
&tls_ctx->rx);
15071508

15081509
return err;
15091510
}
@@ -1518,7 +1519,7 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb,
15181519
rxm->full_len -= pad;
15191520
rxm->offset += prot->prepend_size;
15201521
rxm->full_len -= prot->overhead_size;
1521-
tls_advance_record_sn(sk, &tls_ctx->rx, version);
1522+
tls_advance_record_sn(sk, prot, &tls_ctx->rx);
15221523
ctx->decrypted = true;
15231524
ctx->saved_data_ready(sk);
15241525
} else {

0 commit comments

Comments
 (0)