diff options
Diffstat (limited to 'net/bridge/br_if.c')
-rw-r--r-- | net/bridge/br_if.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index ed307db7a12b..1849d96b3c91 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -424,6 +424,7 @@ netdev_features_t br_features_recompute(struct net_bridge *br, features = netdev_increment_features(features, p->dev->features, mask); } + features = netdev_add_tso_features(features, mask); return features; } @@ -435,10 +436,16 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) int err = 0; bool changed_addr; - /* Don't allow bridging non-ethernet like devices */ + /* Don't allow bridging non-ethernet like devices, or DSA-enabled + * master network devices since the bridge layer rx_handler prevents + * the DSA fake ethertype handler to be invoked, so we do not strip off + * the DSA switch tag protocol header and the bridge layer just return + * RX_HANDLER_CONSUMED, stopping RX processing for these frames. + */ if ((dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN || - !is_valid_ether_addr(dev->dev_addr)) + !is_valid_ether_addr(dev->dev_addr) || + netdev_uses_dsa(dev)) return -EINVAL; /* No bridging of bridges */ @@ -556,6 +563,8 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) */ del_nbp(p); + dev_set_mtu(br->dev, br_min_mtu(br)); + spin_lock_bh(&br->lock); changed_addr = br_stp_recalculate_bridge_id(br); spin_unlock_bh(&br->lock); |