diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 40 |
1 files changed, 12 insertions, 28 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 2f838f1d222c..3fe443be4b15 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1732,33 +1732,6 @@ void netif_device_attach(struct net_device *dev) | |||
1732 | } | 1732 | } |
1733 | EXPORT_SYMBOL(netif_device_attach); | 1733 | EXPORT_SYMBOL(netif_device_attach); |
1734 | 1734 | ||
1735 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) | ||
1736 | { | ||
1737 | return ((features & NETIF_F_GEN_CSUM) || | ||
1738 | ((features & NETIF_F_V4_CSUM) && | ||
1739 | protocol == htons(ETH_P_IP)) || | ||
1740 | ((features & NETIF_F_V6_CSUM) && | ||
1741 | protocol == htons(ETH_P_IPV6)) || | ||
1742 | ((features & NETIF_F_FCOE_CRC) && | ||
1743 | protocol == htons(ETH_P_FCOE))); | ||
1744 | } | ||
1745 | |||
1746 | static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) | ||
1747 | { | ||
1748 | __be16 protocol = skb->protocol; | ||
1749 | int features = dev->features; | ||
1750 | |||
1751 | if (vlan_tx_tag_present(skb)) { | ||
1752 | features &= dev->vlan_features; | ||
1753 | } else if (protocol == htons(ETH_P_8021Q)) { | ||
1754 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | ||
1755 | protocol = veh->h_vlan_encapsulated_proto; | ||
1756 | features &= dev->vlan_features; | ||
1757 | } | ||
1758 | |||
1759 | return can_checksum_protocol(features, protocol); | ||
1760 | } | ||
1761 | |||
1762 | /** | 1735 | /** |
1763 | * skb_dev_set -- assign a new device to a buffer | 1736 | * skb_dev_set -- assign a new device to a buffer |
1764 | * @skb: buffer for the new device | 1737 | * @skb: buffer for the new device |
@@ -2015,6 +1988,17 @@ static inline void skb_orphan_try(struct sk_buff *skb) | |||
2015 | } | 1988 | } |
2016 | } | 1989 | } |
2017 | 1990 | ||
1991 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) | ||
1992 | { | ||
1993 | return ((features & NETIF_F_GEN_CSUM) || | ||
1994 | ((features & NETIF_F_V4_CSUM) && | ||
1995 | protocol == htons(ETH_P_IP)) || | ||
1996 | ((features & NETIF_F_V6_CSUM) && | ||
1997 | protocol == htons(ETH_P_IPV6)) || | ||
1998 | ((features & NETIF_F_FCOE_CRC) && | ||
1999 | protocol == htons(ETH_P_FCOE))); | ||
2000 | } | ||
2001 | |||
2018 | static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features) | 2002 | static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features) |
2019 | { | 2003 | { |
2020 | if (!can_checksum_protocol(protocol, features)) { | 2004 | if (!can_checksum_protocol(protocol, features)) { |
@@ -2117,7 +2101,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2117 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 2101 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
2118 | skb_set_transport_header(skb, | 2102 | skb_set_transport_header(skb, |
2119 | skb_checksum_start_offset(skb)); | 2103 | skb_checksum_start_offset(skb)); |
2120 | if (!dev_can_checksum(dev, skb) && | 2104 | if (!(features & NETIF_F_ALL_CSUM) && |
2121 | skb_checksum_help(skb)) | 2105 | skb_checksum_help(skb)) |
2122 | goto out_kfree_skb; | 2106 | goto out_kfree_skb; |
2123 | } | 2107 | } |