diff options
author | Stephen Hemminger <shemminger@linux-foundation.org> | 2007-06-27 03:47:37 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-11 01:15:52 -0400 |
commit | d212f87b068c9d72065ef579d85b5ee6b8b59381 (patch) | |
tree | a194d5c667c277c7ea5392c9cf97857a0cd1d321 /net/core | |
parent | d3d6dd3adaaad71eae20902ed81808a66a40a5b9 (diff) |
[NET]: IPV6 checksum offloading in network devices
The existing model for checksum offload does not correctly handle
devices that can offload IPV4 and IPV6 only. The NETIF_F_HW_CSUM flag
implies device can do any arbitrary protocol.
This patch:
* adds NETIF_F_IPV6_CSUM for those devices
* fixes bnx2 and tg3 devices that need it
* add NETIF_F_IPV6_CSUM to ipv6 output (incl GSO)
* fixes assumptions about NETIF_F_ALL_CSUM in nat
* adjusts bridge union of checksumming computation
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index ee051bb398a0..a0a46e7ed137 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1509,9 +1509,11 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
1509 | skb_set_transport_header(skb, skb->csum_start - | 1509 | skb_set_transport_header(skb, skb->csum_start - |
1510 | skb_headroom(skb)); | 1510 | skb_headroom(skb)); |
1511 | 1511 | ||
1512 | if (!(dev->features & NETIF_F_GEN_CSUM) && | 1512 | if (!(dev->features & NETIF_F_GEN_CSUM) |
1513 | (!(dev->features & NETIF_F_IP_CSUM) || | 1513 | || ((dev->features & NETIF_F_IP_CSUM) |
1514 | skb->protocol != htons(ETH_P_IP))) | 1514 | && skb->protocol == htons(ETH_P_IP)) |
1515 | || ((dev->features & NETIF_F_IPV6_CSUM) | ||
1516 | && skb->protocol == htons(ETH_P_IPV6))) | ||
1515 | if (skb_checksum_help(skb)) | 1517 | if (skb_checksum_help(skb)) |
1516 | goto out_kfree_skb; | 1518 | goto out_kfree_skb; |
1517 | } | 1519 | } |
@@ -3107,6 +3109,22 @@ int register_netdevice(struct net_device *dev) | |||
3107 | } | 3109 | } |
3108 | } | 3110 | } |
3109 | 3111 | ||
3112 | /* Fix illegal checksum combinations */ | ||
3113 | if ((dev->features & NETIF_F_HW_CSUM) && | ||
3114 | (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | ||
3115 | printk(KERN_NOTICE "%s: mixed HW and IP checksum settings.\n", | ||
3116 | dev->name); | ||
3117 | dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); | ||
3118 | } | ||
3119 | |||
3120 | if ((dev->features & NETIF_F_NO_CSUM) && | ||
3121 | (dev->features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | ||
3122 | printk(KERN_NOTICE "%s: mixed no checksumming and other settings.\n", | ||
3123 | dev->name); | ||
3124 | dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); | ||
3125 | } | ||
3126 | |||
3127 | |||
3110 | /* Fix illegal SG+CSUM combinations. */ | 3128 | /* Fix illegal SG+CSUM combinations. */ |
3111 | if ((dev->features & NETIF_F_SG) && | 3129 | if ((dev->features & NETIF_F_SG) && |
3112 | !(dev->features & NETIF_F_ALL_CSUM)) { | 3130 | !(dev->features & NETIF_F_ALL_CSUM)) { |