Merge branch 'vlan_features'
Michal Kubecek says: ==================== net: device features handling fixes > I think we need to think more about what exact behavior is desired in > mixed csum feature set cases. Probably whatever csum offload type is > the most prevelant should be the one advertised by the master. It > means we will do that software checksum fixup for the oddball slaves, > but it seems the best we can do. I've been thinking about it some more and I believe what I proposed is correct: features that are or-ed (ONE_FOR_ALL) should start with 0, those which are and-ed (ALL_FOR_ALL) with 1. But once we do that, we have to fix another problem in vlan module: features of a vlan device are mostly computed as bitwise AND of features and vlan_features of its underlying device. The problem is checksumming features don't really behave like independent flags as their main purpose is to be used in can_checksum_protocol() whose logic is that HW_CSUM (GEN_CSUM) means "can checksum everything" so that it kind of contains IP(V6)_CSUM functionality. Therefore intersection of HW_CSUM and IP(V6)_CSUM should result in the latter. An alternative approach would be to always set IP(V6)_CSUM once HW_CSUM (any of GEN_CSUM) is set but as for long time people were taught not to do that and we even have a warning for it, switching to the exact opposite could cause a lot of problems. > Also, like Jay, I agree that whatever we do in bonding needs to be > done in team too and I'd like the bug fixed at the same time in both > places. Agreed. Added a similar patch for teaming driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
a33fa47e89
|
@ -1038,6 +1038,7 @@ static void bond_compute_features(struct bonding *bond)
|
|||
|
||||
if (!bond_has_slaves(bond))
|
||||
goto done;
|
||||
vlan_features &= NETIF_F_ALL_FOR_ALL;
|
||||
|
||||
bond_for_each_slave(bond, slave, iter) {
|
||||
vlan_features = netdev_increment_features(vlan_features,
|
||||
|
|
|
@ -968,7 +968,7 @@ static void team_port_disable(struct team *team,
|
|||
static void __team_compute_features(struct team *team)
|
||||
{
|
||||
struct team_port *port;
|
||||
u32 vlan_features = TEAM_VLAN_FEATURES;
|
||||
u32 vlan_features = TEAM_VLAN_FEATURES & NETIF_F_ALL_FOR_ALL;
|
||||
unsigned short max_hard_header_len = ETH_HLEN;
|
||||
unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE;
|
||||
|
||||
|
|
|
@ -3153,6 +3153,20 @@ const char *netdev_drivername(const struct net_device *dev);
|
|||
|
||||
void linkwatch_run_queue(void);
|
||||
|
||||
static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
|
||||
netdev_features_t f2)
|
||||
{
|
||||
if (f1 & NETIF_F_GEN_CSUM)
|
||||
f1 |= (NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
|
||||
if (f2 & NETIF_F_GEN_CSUM)
|
||||
f2 |= (NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
|
||||
f1 &= f2;
|
||||
if (f1 & NETIF_F_GEN_CSUM)
|
||||
f1 &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
|
||||
|
||||
return f1;
|
||||
}
|
||||
|
||||
static inline netdev_features_t netdev_get_wanted_features(
|
||||
struct net_device *dev)
|
||||
{
|
||||
|
|
|
@ -678,9 +678,9 @@ static netdev_features_t vlan_dev_fix_features(struct net_device *dev,
|
|||
struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
|
||||
netdev_features_t old_features = features;
|
||||
|
||||
features &= real_dev->vlan_features;
|
||||
features = netdev_intersect_features(features, real_dev->vlan_features);
|
||||
features |= NETIF_F_RXCSUM;
|
||||
features &= real_dev->features;
|
||||
features = netdev_intersect_features(features, real_dev->features);
|
||||
|
||||
features |= old_features & NETIF_F_SOFT_FEATURES;
|
||||
features |= NETIF_F_LLTX;
|
||||
|
|
Loading…
Reference in New Issue