net/tls: fully initialize the msg wrapper skb
If strparser gets cornered into starting a new message from an sk_buff which already has frags, it will allocate a new skb to become the "wrapper" around the fragments of the message. This new skb does not inherit any metadata fields. In case of TLS offload this may lead to unnecessarily re-encrypting the message, as skb->decrypted is not set for the wrapper skb. Try to be conservative and copy all fields of old skb strparser's user may reasonably need. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com> Reviewed-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7e7d199e05
commit
da29e4b466
|
@ -1063,6 +1063,7 @@ struct sk_buff *alloc_skb_with_frags(unsigned long header_len,
|
|||
int max_page_order,
|
||||
int *errcode,
|
||||
gfp_t gfp_mask);
|
||||
struct sk_buff *alloc_skb_for_msg(struct sk_buff *first);
|
||||
|
||||
/* Layout of fast clones : [skb1][skb2][fclone_ref] */
|
||||
struct sk_buff_fclones {
|
||||
|
|
|
@ -913,6 +913,31 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
|
|||
#undef C
|
||||
}
|
||||
|
||||
/**
|
||||
* alloc_skb_for_msg() - allocate sk_buff to wrap frag list forming a msg
|
||||
* @first: first sk_buff of the msg
|
||||
*/
|
||||
struct sk_buff *alloc_skb_for_msg(struct sk_buff *first)
|
||||
{
|
||||
struct sk_buff *n;
|
||||
|
||||
n = alloc_skb(0, GFP_ATOMIC);
|
||||
if (!n)
|
||||
return NULL;
|
||||
|
||||
n->len = first->len;
|
||||
n->data_len = first->len;
|
||||
n->truesize = first->truesize;
|
||||
|
||||
skb_shinfo(n)->frag_list = first;
|
||||
|
||||
__copy_skb_header(n, first);
|
||||
n->destructor = NULL;
|
||||
|
||||
return n;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(alloc_skb_for_msg);
|
||||
|
||||
/**
|
||||
* skb_morph - morph one skb into another
|
||||
* @dst: the skb to receive the contents
|
||||
|
|
|
@ -160,18 +160,14 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
skb = alloc_skb(0, GFP_ATOMIC);
|
||||
skb = alloc_skb_for_msg(head);
|
||||
if (!skb) {
|
||||
STRP_STATS_INCR(strp->stats.mem_fail);
|
||||
desc->error = -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
skb->len = head->len;
|
||||
skb->data_len = head->len;
|
||||
skb->truesize = head->truesize;
|
||||
*_strp_msg(skb) = *_strp_msg(head);
|
||||
|
||||
strp->skb_nextp = &head->next;
|
||||
skb_shinfo(skb)->frag_list = head;
|
||||
strp->skb_head = skb;
|
||||
head = skb;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue