[VLAN]: Propagate selected feature bits to VLAN devices

Propagate feature bits from the NETDEV_FEAT_CHANGE notifier. For now
only TSO is propagated for devices that announce their ability to
support TSO in combination with VLAN accel by setting the NETIF_F_VLAN_TSO
flag.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Patrick McHardy and committed by
David S. Miller
5fb13570 7ff6e6f7

+41 -2
+4 -2
include/linux/netdevice.h
··· 514 #define NETIF_F_NETNS_LOCAL 8192 /* Does not change network namespaces */ 515 #define NETIF_F_MULTI_QUEUE 16384 /* Has multiple TX/RX queues */ 516 #define NETIF_F_LRO 32768 /* large receive offload */ 517 518 /* Segmentation offload features */ 519 - #define NETIF_F_GSO_SHIFT 16 520 - #define NETIF_F_GSO_MASK 0xffff0000 521 #define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT) 522 #define NETIF_F_UFO (SKB_GSO_UDP << NETIF_F_GSO_SHIFT) 523 #define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
··· 514 #define NETIF_F_NETNS_LOCAL 8192 /* Does not change network namespaces */ 515 #define NETIF_F_MULTI_QUEUE 16384 /* Has multiple TX/RX queues */ 516 #define NETIF_F_LRO 32768 /* large receive offload */ 517 + #define NETIF_F_VLAN_TSO 65536 /* Supports TSO for VLANs */ 518 + #define NETIF_F_VLAN_CSUM 131072 /* Supports TX checksumming for VLANs */ 519 520 /* Segmentation offload features */ 521 + #define NETIF_F_GSO_SHIFT 20 522 + #define NETIF_F_GSO_MASK 0xfff00000 523 #define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT) 524 #define NETIF_F_UFO (SKB_GSO_UDP << NETIF_F_GSO_SHIFT) 525 #define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
+30
net/8021q/vlan.c
··· 382 memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); 383 } 384 385 static void __vlan_device_event(struct net_device *dev, unsigned long event) 386 { 387 switch (event) { ··· 464 465 vlan_sync_address(dev, vlandev); 466 } 467 break; 468 469 case NETDEV_DOWN:
··· 382 memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); 383 } 384 385 + static void vlan_transfer_features(struct net_device *dev, 386 + struct net_device *vlandev) 387 + { 388 + unsigned long old_features = vlandev->features; 389 + 390 + if (dev->features & NETIF_F_VLAN_TSO) { 391 + vlandev->features &= ~VLAN_TSO_FEATURES; 392 + vlandev->features |= dev->features & VLAN_TSO_FEATURES; 393 + } 394 + if (dev->features & NETIF_F_VLAN_CSUM) { 395 + vlandev->features &= ~NETIF_F_ALL_CSUM; 396 + vlandev->features |= dev->features & NETIF_F_ALL_CSUM; 397 + } 398 + 399 + if (old_features != vlandev->features) 400 + netdev_features_change(vlandev); 401 + } 402 + 403 static void __vlan_device_event(struct net_device *dev, unsigned long event) 404 { 405 switch (event) { ··· 446 447 vlan_sync_address(dev, vlandev); 448 } 449 + break; 450 + 451 + case NETDEV_FEAT_CHANGE: 452 + /* Propagate device features to underlying device */ 453 + for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 454 + vlandev = vlan_group_get_device(grp, i); 455 + if (!vlandev) 456 + continue; 457 + 458 + vlan_transfer_features(dev, vlandev); 459 + } 460 + 461 break; 462 463 case NETDEV_DOWN:
+2
net/8021q/vlan.h
··· 7 #define VLAN_GRP_HASH_SIZE (1 << VLAN_GRP_HASH_SHIFT) 8 #define VLAN_GRP_HASH_MASK (VLAN_GRP_HASH_SIZE - 1) 9 10 /* Find a VLAN device by the MAC address of its Ethernet device, and 11 * it's VLAN ID. The default configuration is to have VLAN's scope 12 * to be box-wide, so the MAC will be ignored. The mac will only be
··· 7 #define VLAN_GRP_HASH_SIZE (1 << VLAN_GRP_HASH_SHIFT) 8 #define VLAN_GRP_HASH_MASK (VLAN_GRP_HASH_SIZE - 1) 9 10 + #define VLAN_TSO_FEATURES (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG) 11 + 12 /* Find a VLAN device by the MAC address of its Ethernet device, and 13 * it's VLAN ID. The default configuration is to have VLAN's scope 14 * to be box-wide, so the MAC will be ignored. The mac will only be
+5
net/8021q/vlan_dev.c
··· 663 (1<<__LINK_STATE_DORMANT))) | 664 (1<<__LINK_STATE_PRESENT); 665 666 /* ipv6 shared card related stuff */ 667 dev->dev_id = real_dev->dev_id; 668
··· 663 (1<<__LINK_STATE_DORMANT))) | 664 (1<<__LINK_STATE_PRESENT); 665 666 + if (real_dev->features & NETIF_F_VLAN_TSO) 667 + dev->features |= real_dev->features & VLAN_TSO_FEATURES; 668 + if (real_dev->features & NETIF_F_VLAN_CSUM) 669 + dev->features |= real_dev->features & NETIF_F_ALL_CSUM; 670 + 671 /* ipv6 shared card related stuff */ 672 dev->dev_id = real_dev->dev_id; 673