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.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index d9d1e2bac1d6..718b60366dfe 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -148,6 +148,8 @@ static void del_nbp(struct net_bridge_port *p)
148 148
149 netdev_rx_handler_unregister(dev); 149 netdev_rx_handler_unregister(dev);
150 150
151 netdev_set_master(dev, NULL);
152
151 br_multicast_del_port(p); 153 br_multicast_del_port(p);
152 154
153 kobject_uevent(&p->kobj, KOBJ_REMOVE); 155 kobject_uevent(&p->kobj, KOBJ_REMOVE);
@@ -365,7 +367,7 @@ int br_min_mtu(const struct net_bridge *br)
365void br_features_recompute(struct net_bridge *br) 367void br_features_recompute(struct net_bridge *br)
366{ 368{
367 struct net_bridge_port *p; 369 struct net_bridge_port *p;
368 unsigned long features, mask; 370 u32 features, mask;
369 371
370 features = mask = br->feature_mask; 372 features = mask = br->feature_mask;
371 if (list_empty(&br->port_list)) 373 if (list_empty(&br->port_list))
@@ -379,7 +381,7 @@ void br_features_recompute(struct net_bridge *br)
379 } 381 }
380 382
381done: 383done:
382 br->dev->features = netdev_fix_features(features, NULL); 384 br->dev->features = netdev_fix_features(br->dev, features);
383} 385}
384 386
385/* called with RTNL */ 387/* called with RTNL */
@@ -387,6 +389,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
387{ 389{
388 struct net_bridge_port *p; 390 struct net_bridge_port *p;
389 int err = 0; 391 int err = 0;
392 bool changed_addr;
390 393
391 /* Don't allow bridging non-ethernet like devices */ 394 /* Don't allow bridging non-ethernet like devices */
392 if ((dev->flags & IFF_LOOPBACK) || 395 if ((dev->flags & IFF_LOOPBACK) ||
@@ -429,10 +432,14 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
429 if (br_netpoll_info(br) && ((err = br_netpoll_enable(p)))) 432 if (br_netpoll_info(br) && ((err = br_netpoll_enable(p))))
430 goto err3; 433 goto err3;
431 434
432 err = netdev_rx_handler_register(dev, br_handle_frame, p); 435 err = netdev_set_master(dev, br->dev);
433 if (err) 436 if (err)
434 goto err3; 437 goto err3;
435 438
439 err = netdev_rx_handler_register(dev, br_handle_frame, p);
440 if (err)
441 goto err4;
442
436 dev->priv_flags |= IFF_BRIDGE_PORT; 443 dev->priv_flags |= IFF_BRIDGE_PORT;
437 444
438 dev_disable_lro(dev); 445 dev_disable_lro(dev);
@@ -440,7 +447,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
440 list_add_rcu(&p->list, &br->port_list); 447 list_add_rcu(&p->list, &br->port_list);
441 448
442 spin_lock_bh(&br->lock); 449 spin_lock_bh(&br->lock);
443 br_stp_recalculate_bridge_id(br); 450 changed_addr = br_stp_recalculate_bridge_id(br);
444 br_features_recompute(br); 451 br_features_recompute(br);
445 452
446 if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && 453 if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
@@ -450,11 +457,17 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
450 457
451 br_ifinfo_notify(RTM_NEWLINK, p); 458 br_ifinfo_notify(RTM_NEWLINK, p);
452 459
460 if (changed_addr)
461 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
462
453 dev_set_mtu(br->dev, br_min_mtu(br)); 463 dev_set_mtu(br->dev, br_min_mtu(br));
454 464
455 kobject_uevent(&p->kobj, KOBJ_ADD); 465 kobject_uevent(&p->kobj, KOBJ_ADD);
456 466
457 return 0; 467 return 0;
468
469err4:
470 netdev_set_master(dev, NULL);
458err3: 471err3:
459 sysfs_remove_link(br->ifobj, p->dev->name); 472 sysfs_remove_link(br->ifobj, p->dev->name);
460err2: 473err2: