summaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_offload.c
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2016-09-19 12:58:47 +0200
committerDavid S. Miller <davem@davemloft.net>2016-09-19 20:59:34 -0400
commit07b26c9454a2a19fff86d6fcf2aba6bc801eb8d8 (patch)
tree45cf751adb10dabaf383eaa07238c3427e3fe3f0 /net/ipv4/tcp_offload.c
parente867e87ae88c54f741d1cabd1de536b4497a0504 (diff)
downloadlinux-07b26c9454a2a19fff86d6fcf2aba6bc801eb8d8.tar.gz
linux-07b26c9454a2a19fff86d6fcf2aba6bc801eb8d8.tar.bz2
linux-07b26c9454a2a19fff86d6fcf2aba6bc801eb8d8.zip
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.c13
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,
goto out;
}
- /* GSO partial only requires splitting the frame into an MSS
- * multiple and possibly a remainder. So update the mss now.
- */
- if (features & NETIF_F_GSO_PARTIAL)
- mss = skb->len - (skb->len % mss);
-
copy_destructor = gso_skb->destructor == tcp_wfree;
ooo_okay = gso_skb->ooo_okay;
/* All segments but the first should have ooo_okay cleared */
@@ -108,6 +102,13 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
/* Only first segment might have ooo_okay set */
segs->ooo_okay = ooo_okay;
+ /* GSO partial and frag_list segmentation only requires splitting
+ * the frame into an MSS multiple and possibly a remainder, both
+ * cases return a GSO skb. So update the mss now.
+ */
+ if (skb_is_gso(segs))
+ mss *= skb_shinfo(segs)->gso_segs;
+
delta = htonl(oldlen + (thlen + mss));
skb = segs;