summaryrefslogtreecommitdiffstats
path: root/net/core/skbuff.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-04-14 16:23:42 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-14 16:23:42 -0400
commitedd93cd72741b80633969c247a2f86f177242cfb (patch)
tree74fe0a4a057a2e0ac7eab2fc98e09bf146392255 /net/core/skbuff.c
parentcb689269acc8cf911a2b28d22da155ee83f8dbdc (diff)
parentf7a6272bf3cbd2576165dba020e0329c9ca67c1f (diff)
downloadtalos-obmc-linux-edd93cd72741b80633969c247a2f86f177242cfb.tar.gz
talos-obmc-linux-edd93cd72741b80633969c247a2f86f177242cfb.zip
Merge branch 'gro-fixed-id-gso-partial'
Alexander Duyck says: ==================== GRO Fixed IPv4 ID support and GSO partial support This patch series sets up a few different things. First it adds support for GRO of frames with a fixed IP ID value. This will allow us to perform GRO for frames that go through things like an IPv6 to IPv4 header translation. The second item we add is support for segmenting frames that are generated this way. Most devices only support an incrementing IP ID value, and in the case of TCP the IP ID can be ignored in many cases since the DF bit should be set. So we can technically segment these frames using existing TSO if we are willing to allow the IP ID to be mangled. As such I have added a matching feature for the new form of GRO/GSO called TCP IPv4 ID mangling. With this enabled we can assemble and disassemble a frame with the sequence number fixed and the only ill effect will be that the IPv4 ID will be altered which may or may not have any noticeable effect. As such I have defaulted the feature to disabled. The third item this patch series adds is support for partial GSO segmentation. Partial GSO segmentation allows us to split a large frame into two pieces. The first piece will have an even multiple of MSS worth of data and the headers before the one pointed to by csum_start will have been updated so that they are correct for if the data payload had already been segmented. By doing this we can do things such as precompute the outer header checksums for a frame to be segmented allowing us to perform TSO on devices that don't support tunneling, or tunneling with outer header checksums. This patch set is based on the net-next tree, but I included "net: remove netdevice gso_min_segs" in my tree as I assume it is likely to be applied before this patch set will and I wanted to avoid a merge conflict. v2: Fixed items reported by Jesse Gross fixed missing GSO flag in MPLS check adding DF check for MANGLEID Moved extra GSO feature checks into gso_features_check Rebased batches to account for "net: remove netdevice gso_min_segs" Driver patches from the first patch set should still be compatible. However I do have a few changes in them so I will submit a v2 of those to Jeff Kirsher once these patches are accepted into net-next. Example driver patches for i40e, ixgbe, and igb: https://patchwork.ozlabs.org/patch/608221/ https://patchwork.ozlabs.org/patch/608224/ https://patchwork.ozlabs.org/patch/608225/ ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r--net/core/skbuff.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index d04c2d1c8c87..4cc594cdaada 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3076,8 +3076,9 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
struct sk_buff *frag_skb = head_skb;
unsigned int offset = doffset;
unsigned int tnl_hlen = skb_tnl_header_len(head_skb);
+ unsigned int partial_segs = 0;
unsigned int headroom;
- unsigned int len;
+ unsigned int len = head_skb->len;
__be16 proto;
bool csum;
int sg = !!(features & NETIF_F_SG);
@@ -3094,6 +3095,15 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
csum = !!can_checksum_protocol(features, proto);
+ /* GSO partial only requires that we trim off any excess that
+ * doesn't fit into an MSS sized block, so take care of that
+ * now.
+ */
+ if (features & NETIF_F_GSO_PARTIAL) {
+ partial_segs = len / mss;
+ mss *= partial_segs;
+ }
+
headroom = skb_headroom(head_skb);
pos = skb_headlen(head_skb);
@@ -3281,6 +3291,23 @@ perform_csum_check:
*/
segs->prev = tail;
+ /* Update GSO info on first skb in partial sequence. */
+ if (partial_segs) {
+ int type = skb_shinfo(head_skb)->gso_type;
+
+ /* Update type to add partial and then remove dodgy if set */
+ type |= SKB_GSO_PARTIAL;
+ type &= ~SKB_GSO_DODGY;
+
+ /* Update GSO info and prepare to start updating headers on
+ * our way back down the stack of protocols.
+ */
+ skb_shinfo(segs)->gso_size = skb_shinfo(head_skb)->gso_size;
+ skb_shinfo(segs)->gso_segs = partial_segs;
+ skb_shinfo(segs)->gso_type = type;
+ SKB_GSO_CB(segs)->data_offset = skb_headroom(segs) + doffset;
+ }
+
/* Following permits correct backpressure, for protocols
* using skb_set_owner_w().
* Idea is to tranfert ownership from head_skb to last segment.
OpenPOWER on IntegriCloud