Commit af1905db authored by Ben Hutchings's avatar Ben Hutchings Committed by David S. Miller

net: Fix some corner cases in dev_can_checksum()

dev_can_checksum() incorrectly returns true in these cases:

1. The skb has both out-of-band and in-band VLAN tags and the device
   supports checksum offload for the encapsulated protocol but only with
   one layer of encapsulation.
2. The skb has a VLAN tag and the device supports generic checksumming
   but not in conjunction with VLAN encapsulation.

Rearrange the VLAN tag checks to avoid these.
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cd0ea241
...@@ -1696,22 +1696,18 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol) ...@@ -1696,22 +1696,18 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol)
static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
{ {
__be16 protocol = skb->protocol;
int features = dev->features; int features = dev->features;
if (vlan_tx_tag_present(skb)) if (vlan_tx_tag_present(skb)) {
features &= dev->vlan_features; features &= dev->vlan_features;
} else if (protocol == htons(ETH_P_8021Q)) {
if (can_checksum_protocol(features, skb->protocol))
return true;
if (skb->protocol == htons(ETH_P_8021Q)) {
struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
if (can_checksum_protocol(dev->features & dev->vlan_features, protocol = veh->h_vlan_encapsulated_proto;
veh->h_vlan_encapsulated_proto)) features &= dev->vlan_features;
return true;
} }
return false; return can_checksum_protocol(features, protocol);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment