aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c40
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}
1733EXPORT_SYMBOL(netif_device_attach); 1733EXPORT_SYMBOL(netif_device_attach);
1734 1734
1735static 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
1746static 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
1991static 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
2018static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features) 2002static 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 }