diff --git a/net/core/dev.c b/net/core/dev.c index 307142a702d5df5c491d6a6c75d05775e284d6c7..a4c4a1bf07d521047bf3401248a174e39978f05a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2324,6 +2324,13 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, skb->vlan_tci = 0; } + /* If encapsulation offload request, verify we are testing + * hardware encapsulation features instead of standard + * features for the netdev + */ + if (skb->encapsulation) + features &= dev->hw_enc_features; + if (netif_needs_gso(skb, features)) { if (unlikely(dev_gso_segment(skb, features))) goto out_kfree_skb; @@ -2339,8 +2346,12 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, * checksumming here. */ if (skb->ip_summed == CHECKSUM_PARTIAL) { - skb_set_transport_header(skb, - skb_checksum_start_offset(skb)); + if (skb->encapsulation) + skb_set_inner_transport_header(skb, + skb_checksum_start_offset(skb)); + else + skb_set_transport_header(skb, + skb_checksum_start_offset(skb)); if (!(features & NETIF_F_ALL_CSUM) && skb_checksum_help(skb)) goto out_kfree_skb; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 6537a408a4fb451d906b574def4746c064399fd9..3e98ed2bff55d7328aae7209ecbda4f78445c87a 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -595,6 +595,10 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) } slow_path: + /* for offloaded checksums cleanup checksum before fragmentation */ + if ((skb->ip_summed == CHECKSUM_PARTIAL) && skb_checksum_help(skb)) + goto fail; + left = skb->len - hlen; /* Space per frame */ ptr = hlen; /* Where to start from */