diff options
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_device.c | 2 | ||||
-rw-r--r-- | net/bridge/br_if.c | 36 |
2 files changed, 5 insertions, 33 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 5e1892d8d874..0eded176ce99 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -179,5 +179,5 @@ void br_dev_setup(struct net_device *dev) | |||
179 | dev->priv_flags = IFF_EBRIDGE; | 179 | dev->priv_flags = IFF_EBRIDGE; |
180 | 180 | ||
181 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | | 181 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | |
182 | NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST; | 182 | NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX; |
183 | } | 183 | } |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index b40dada002bf..749f0e8f541d 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -349,43 +349,15 @@ int br_min_mtu(const struct net_bridge *br) | |||
349 | void br_features_recompute(struct net_bridge *br) | 349 | void br_features_recompute(struct net_bridge *br) |
350 | { | 350 | { |
351 | struct net_bridge_port *p; | 351 | struct net_bridge_port *p; |
352 | unsigned long features, checksum; | 352 | unsigned long features; |
353 | 353 | ||
354 | checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0; | 354 | features = br->feature_mask; |
355 | features = br->feature_mask & ~NETIF_F_ALL_CSUM; | ||
356 | 355 | ||
357 | list_for_each_entry(p, &br->port_list, list) { | 356 | list_for_each_entry(p, &br->port_list, list) { |
358 | unsigned long feature = p->dev->features; | 357 | features = netdev_compute_features(features, p->dev->features); |
359 | |||
360 | /* if device needs checksumming, downgrade to hw checksumming */ | ||
361 | if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM)) | ||
362 | checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; | ||
363 | |||
364 | /* if device can't do all checksum, downgrade to ipv4/ipv6 */ | ||
365 | if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM)) | ||
366 | checksum ^= NETIF_F_HW_CSUM | ||
367 | | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; | ||
368 | |||
369 | if (checksum & NETIF_F_IPV6_CSUM && !(feature & NETIF_F_IPV6_CSUM)) | ||
370 | checksum &= ~NETIF_F_IPV6_CSUM; | ||
371 | |||
372 | if (!(feature & NETIF_F_IP_CSUM)) | ||
373 | checksum = 0; | ||
374 | |||
375 | if (feature & NETIF_F_GSO) | ||
376 | feature |= NETIF_F_GSO_SOFTWARE; | ||
377 | feature |= NETIF_F_GSO; | ||
378 | |||
379 | features &= feature; | ||
380 | } | 358 | } |
381 | 359 | ||
382 | if (!(checksum & NETIF_F_ALL_CSUM)) | 360 | br->dev->features = features; |
383 | features &= ~NETIF_F_SG; | ||
384 | if (!(features & NETIF_F_SG)) | ||
385 | features &= ~NETIF_F_GSO_MASK; | ||
386 | |||
387 | br->dev->features = features | checksum | NETIF_F_LLTX | | ||
388 | NETIF_F_GSO_ROBUST; | ||
389 | } | 361 | } |
390 | 362 | ||
391 | /* called with RTNL */ | 363 | /* called with RTNL */ |