summaryrefslogtreecommitdiff
path: root/net/bridge
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-06-27 00:47:37 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-10 22:15:52 -0700
commitd212f87b068c9d72065ef579d85b5ee6b8b59381 (patch)
treea194d5c667c277c7ea5392c9cf97857a0cd1d321 /net/bridge
parentd3d6dd3adaaad71eae20902ed81808a66a40a5b9 (diff)
downloadlinux-3.10-d212f87b068c9d72065ef579d85b5ee6b8b59381.tar.gz
linux-3.10-d212f87b068c9d72065ef579d85b5ee6b8b59381.tar.bz2
linux-3.10-d212f87b068c9d72065ef579d85b5ee6b8b59381.zip
[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/bridge')
-rw-r--r--net/bridge/br_if.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 849deaf1410..7b4ce9113be 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -368,10 +368,18 @@ void br_features_recompute(struct net_bridge *br)
list_for_each_entry(p, &br->port_list, list) {
unsigned long feature = p->dev->features;
+ /* if device needs checksumming, downgrade to hw checksumming */
if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
+
+ /* if device can't do all checksum, downgrade to ipv4/ipv6 */
if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
- checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
+ checksum ^= NETIF_F_HW_CSUM
+ | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+ if (checksum & NETIF_F_IPV6_CSUM && !(feature & NETIF_F_IPV6_CSUM))
+ checksum &= ~NETIF_F_IPV6_CSUM;
+
if (!(feature & NETIF_F_IP_CSUM))
checksum = 0;