Skip to content

Commit 7ab89b1

Browse files
ilantayarigregkh
authored andcommitted
gso: Validate assumption of frag_list segementation
[ Upstream commit 43170c4 ] Commit 07b26c9 ("gso: Support partial splitting at the frag_list pointer") assumes that all SKBs in a frag_list (except maybe the last one) contain the same amount of GSO payload. This assumption is not always correct, resulting in the following warning message in the log: skb_segment: too many frags For example, mlx5 driver in Striding RQ mode creates some RX SKBs with one frag, and some with 2 frags. After GRO, the frag_list SKBs end up having different amounts of payload. If this frag_list SKB is then forwarded, the aforementioned assumption is violated. Validate the assumption, and fall back to software GSO if it not true. Change-Id: Ia03983f4a47b6534dd987d7a2aad96d54d46d212 Fixes: 07b26c9 ("gso: Support partial splitting at the frag_list pointer") Signed-off-by: Ilan Tayari <ilant@mellanox.com> Signed-off-by: Ilya Lesokhin <ilyal@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent fcbf5a7 commit 7ab89b1

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

net/core/skbuff.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3076,22 +3076,32 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
30763076
if (sg && csum && (mss != GSO_BY_FRAGS)) {
30773077
if (!(features & NETIF_F_GSO_PARTIAL)) {
30783078
struct sk_buff *iter;
3079+
unsigned int frag_len;
30793080

30803081
if (!list_skb ||
30813082
!net_gso_ok(features, skb_shinfo(head_skb)->gso_type))
30823083
goto normal;
30833084

3084-
/* Split the buffer at the frag_list pointer.
3085-
* This is based on the assumption that all
3086-
* buffers in the chain excluding the last
3087-
* containing the same amount of data.
3085+
/* If we get here then all the required
3086+
* GSO features except frag_list are supported.
3087+
* Try to split the SKB to multiple GSO SKBs
3088+
* with no frag_list.
3089+
* Currently we can do that only when the buffers don't
3090+
* have a linear part and all the buffers except
3091+
* the last are of the same length.
30883092
*/
3093+
frag_len = list_skb->len;
30893094
skb_walk_frags(head_skb, iter) {
3095+
if (frag_len != iter->len && iter->next)
3096+
goto normal;
30903097
if (skb_headlen(iter))
30913098
goto normal;
30923099

30933100
len -= iter->len;
30943101
}
3102+
3103+
if (len != frag_len)
3104+
goto normal;
30953105
}
30963106

30973107
/* GSO partial only requires that we trim off any excess that

0 commit comments

Comments
 (0)