aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_if.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_if.c')
-rw-r--r--net/bridge/br_if.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 69872bf3b87e..91bb895375f4 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -314,6 +314,28 @@ int br_min_mtu(const struct net_bridge *br)
314 return mtu; 314 return mtu;
315} 315}
316 316
317/*
318 * Recomputes features using slave's features
319 */
320void br_features_recompute(struct net_bridge *br)
321{
322 struct net_bridge_port *p;
323 unsigned long features, checksum;
324
325 features = NETIF_F_SG | NETIF_F_FRAGLIST
326 | NETIF_F_HIGHDMA | NETIF_F_TSO;
327 checksum = NETIF_F_IP_CSUM; /* least commmon subset */
328
329 list_for_each_entry(p, &br->port_list, list) {
330 if (!(p->dev->features
331 & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
332 checksum = 0;
333 features &= p->dev->features;
334 }
335
336 br->dev->features = features | checksum | NETIF_F_LLTX;
337}
338
317/* called with RTNL */ 339/* called with RTNL */
318int br_add_if(struct net_bridge *br, struct net_device *dev) 340int br_add_if(struct net_bridge *br, struct net_device *dev)
319{ 341{
@@ -368,6 +390,7 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
368 390
369 spin_lock_bh(&br->lock); 391 spin_lock_bh(&br->lock);
370 br_stp_recalculate_bridge_id(br); 392 br_stp_recalculate_bridge_id(br);
393 br_features_recompute(br);
371 spin_unlock_bh(&br->lock); 394 spin_unlock_bh(&br->lock);
372 395
373 return 0; 396 return 0;