mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
macvlan: fix netdev feature propagation from lower device
There are inconsistencies wrt. feature propagation/inheritance between macvlan and the underlying interface. When a feature is turned off on the real device before a macvlan is created on top, these will remain enabled on the macvlan device, whereas turning off the feature on the lower device after macvlan creation the kernel will propagate the changes to the macvlan. The second issue is that, when propagating changes from underlying device to the macvlan interface, macvlan can erronously lose its NETIF_F_LLTX flag, as features are anded with the underlying device. However, LLTX should be kept since it has no dependencies on physical hardware (LLTX is set on macvlan creation regardless of the lower device properties, see8ffab51b3d
(macvlan: lockless tx path). The LLTX flag is now forced regardless of user settings in absence of layer2 hw acceleration (a6cc0cfa72
, net: Add layer 2 hardware acceleration operations for macvlan devices). Use netdev_increment_features to rebuild the feature set on capability changes on either the lower device or on the macvlan interface. As pointed out by Ben Hutchings, use netdev_update_features on NETDEV_FEAT_CHANGE event (it calls macvlan_fix_features/netdev_features_change if needed). Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
61e7f09d0f
commit
797f87f83b
@ -690,8 +690,19 @@ static netdev_features_t macvlan_fix_features(struct net_device *dev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
struct macvlan_dev *vlan = netdev_priv(dev);
|
||||
netdev_features_t mask;
|
||||
|
||||
return features & (vlan->set_features | ~MACVLAN_FEATURES);
|
||||
features |= NETIF_F_ALL_FOR_ALL;
|
||||
features &= (vlan->set_features | ~MACVLAN_FEATURES);
|
||||
mask = features;
|
||||
|
||||
features = netdev_increment_features(vlan->lowerdev->features,
|
||||
features,
|
||||
mask);
|
||||
if (!vlan->fwd_priv)
|
||||
features |= NETIF_F_LLTX;
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
static const struct ethtool_ops macvlan_ethtool_ops = {
|
||||
@ -1019,9 +1030,8 @@ static int macvlan_device_event(struct notifier_block *unused,
|
||||
break;
|
||||
case NETDEV_FEAT_CHANGE:
|
||||
list_for_each_entry(vlan, &port->vlans, list) {
|
||||
vlan->dev->features = dev->features & MACVLAN_FEATURES;
|
||||
vlan->dev->gso_max_size = dev->gso_max_size;
|
||||
netdev_features_change(vlan->dev);
|
||||
netdev_update_features(vlan->dev);
|
||||
}
|
||||
break;
|
||||
case NETDEV_UNREGISTER:
|
||||
|
Loading…
Reference in New Issue
Block a user