]> git.hungrycats.org Git - linux/commitdiff
net: gso: use feature flag argument in all protocol gso handlers
authorFlorian Westphal <fw@strlen.de>
Thu, 27 Aug 2015 05:17:39 +0000 (22:17 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 1 Oct 2015 09:36:25 +0000 (11:36 +0200)
[ Upstream commit 1e16aa3ddf863c6b9f37eddf52503230a62dedb3 ]

skb_gso_segment() has a 'features' argument representing offload features
available to the output path.

A few handlers, e.g. GRE, instead re-fetch the features of skb->dev and use
those instead of the provided ones when handing encapsulation/tunnels.

Depending on dev->hw_enc_features of the output device skb_gso_segment() can
then return NULL even when the caller has disabled all GSO feature bits,
as segmentation of inner header thinks device will take care of segmentation.

This e.g. affects the tbf scheduler, which will silently drop GRE-encap GSO skbs
that did not fit the remaining token quota as the segmentation does not work
when device supports corresponding hw offload capabilities.

Cc: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
[jay.vosburgh: backported to 3.14. ]
Signed-off-by: Jay Vosburgh <jay.vosburgh@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/ipv4/af_inet.c
net/ipv4/gre_offload.c
net/ipv4/udp.c
net/ipv6/ip6_offload.c
net/mpls/mpls_gso.c

index 951fe55b167126131c7a095244ad2d315fb8190d..f4c804dbd3b4416d21e9343ed7802ff506c9e23a 100644 (file)
@@ -1291,7 +1291,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
 
        encap = SKB_GSO_CB(skb)->encap_level > 0;
        if (encap)
-               features = skb->dev->hw_enc_features & netif_skb_features(skb);
+               features &= skb->dev->hw_enc_features;
        SKB_GSO_CB(skb)->encap_level += ihl;
 
        skb_reset_transport_header(skb);
index 278836f1a5ada5d7b251dfdab311f23d6421638f..0da513e7730a899b5de32666e6330d41f3ec5235 100644 (file)
@@ -69,7 +69,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
        skb->mac_len = skb_inner_network_offset(skb);
 
        /* segment inner packet. */
-       enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
+       enc_features = skb->dev->hw_enc_features & features;
        segs = skb_mac_gso_segment(skb, enc_features);
        if (!segs || IS_ERR(segs)) {
                skb_gso_error_unwind(skb, protocol, ghl, mac_offset, mac_len);
index 947dcae8a77a4639ed043740bb0b29c3fabe1510..6970e36ad7b8c728fee8e772b76e1f4a46974b8b 100644 (file)
@@ -2517,7 +2517,7 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
        skb->protocol = htons(ETH_P_TEB);
 
        /* segment inner packet. */
-       enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
+       enc_features = skb->dev->hw_enc_features & features;
        segs = skb_mac_gso_segment(skb, enc_features);
        if (!segs || IS_ERR(segs)) {
                skb_gso_error_unwind(skb, protocol, tnl_hlen, mac_offset,
index b2f091566f88453bce5eb3c33b47e1c9c040447c..dc46ebae19873f2e03d980eda82acfbd7c17fa57 100644 (file)
@@ -112,7 +112,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
 
        encap = SKB_GSO_CB(skb)->encap_level > 0;
        if (encap)
-               features = skb->dev->hw_enc_features & netif_skb_features(skb);
+               features &= skb->dev->hw_enc_features;
        SKB_GSO_CB(skb)->encap_level += sizeof(*ipv6h);
 
        ipv6h = ipv6_hdr(skb);
index 851cd880b0c048c4dcd45e1b6652888338490cf9..0c970cbe0405c90852b48a98f08f5755e2df00e5 100644 (file)
@@ -47,7 +47,7 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb,
        __skb_push(skb, skb->mac_len);
 
        /* Segment inner packet. */
-       mpls_features = skb->dev->mpls_features & netif_skb_features(skb);
+       mpls_features = skb->dev->mpls_features & features;
        segs = skb_mac_gso_segment(skb, mpls_features);