diff options
author | Steffen Klassert <steffen.klassert@secunet.com> | 2016-09-19 06:58:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-09-19 20:59:34 -0400 |
commit | 07b26c9454a2a19fff86d6fcf2aba6bc801eb8d8 (patch) | |
tree | 45cf751adb10dabaf383eaa07238c3427e3fe3f0 /net/ipv4/tcp_offload.c | |
parent | e867e87ae88c54f741d1cabd1de536b4497a0504 (diff) |
gso: Support partial splitting at the frag_list pointer
Since commit 8a29111c7 ("net: gro: allow to build full sized skb")
gro may build buffers with a frag_list. This can hurt forwarding
because most NICs can't offload such packets, they need to be
segmented in software. This patch splits buffers with a frag_list
at the frag_list pointer into buffers that can be TSO offloaded.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Acked-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_offload.c')
-rw-r--r-- | net/ipv4/tcp_offload.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c index 5c5964962d0c..bc68da38ea86 100644 --- a/net/ipv4/tcp_offload.c +++ b/net/ipv4/tcp_offload.c | |||
@@ -90,12 +90,6 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb, | |||
90 | goto out; | 90 | goto out; |
91 | } | 91 | } |
92 | 92 | ||
93 | /* GSO partial only requires splitting the frame into an MSS | ||
94 | * multiple and possibly a remainder. So update the mss now. | ||
95 | */ | ||
96 | if (features & NETIF_F_GSO_PARTIAL) | ||
97 | mss = skb->len - (skb->len % mss); | ||
98 | |||
99 | copy_destructor = gso_skb->destructor == tcp_wfree; | 93 | copy_destructor = gso_skb->destructor == tcp_wfree; |
100 | ooo_okay = gso_skb->ooo_okay; | 94 | ooo_okay = gso_skb->ooo_okay; |
101 | /* All segments but the first should have ooo_okay cleared */ | 95 | /* All segments but the first should have ooo_okay cleared */ |
@@ -108,6 +102,13 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb, | |||
108 | /* Only first segment might have ooo_okay set */ | 102 | /* Only first segment might have ooo_okay set */ |
109 | segs->ooo_okay = ooo_okay; | 103 | segs->ooo_okay = ooo_okay; |
110 | 104 | ||
105 | /* GSO partial and frag_list segmentation only requires splitting | ||
106 | * the frame into an MSS multiple and possibly a remainder, both | ||
107 | * cases return a GSO skb. So update the mss now. | ||
108 | */ | ||
109 | if (skb_is_gso(segs)) | ||
110 | mss *= skb_shinfo(segs)->gso_segs; | ||
111 | |||
111 | delta = htonl(oldlen + (thlen + mss)); | 112 | delta = htonl(oldlen + (thlen + mss)); |
112 | 113 | ||
113 | skb = segs; | 114 | skb = segs; |