aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorJiri Pirko <jiri@resnulli.us>2014-09-05 09:51:28 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-09 14:29:54 -0400
commit0f49579a39533bf839b2af807b094fc652f9e49b (patch)
tree2f3e7d978d92767ec7f3894f52f714ce7f8ab92f /net/bridge
parent49a601589caaf0e93194c0cc9b4ecddbe75dd2d5 (diff)
bridge: switch order of rx_handler reg and upper dev link
The thing is that netdev_master_upper_dev_link calls call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev). That generates rtnl link message and during that, rtnl_link_ops->fill_slave_info is called. But with current ordering, rx_handler and IFF_BRIDGE_PORT are not set yet so there would have to be check for that in fill_slave_info callback. Resolve this by reordering to similar what bonding and team does to avoid the check. Also add removal of IFF_BRIDGE_PORT flag into error path. Signed-off-by: Jiri Pirko <jiri@resnulli.us> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_if.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 078d336a1f37..a9f54a9b6690 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -252,12 +252,12 @@ static void del_nbp(struct net_bridge_port *p)
252 br_fdb_delete_by_port(br, p, 1); 252 br_fdb_delete_by_port(br, p, 1);
253 nbp_update_port_count(br); 253 nbp_update_port_count(br);
254 254
255 netdev_upper_dev_unlink(dev, br->dev);
256
255 dev->priv_flags &= ~IFF_BRIDGE_PORT; 257 dev->priv_flags &= ~IFF_BRIDGE_PORT;
256 258
257 netdev_rx_handler_unregister(dev); 259 netdev_rx_handler_unregister(dev);
258 260
259 netdev_upper_dev_unlink(dev, br->dev);
260
261 br_multicast_del_port(p); 261 br_multicast_del_port(p);
262 262
263 kobject_uevent(&p->kobj, KOBJ_REMOVE); 263 kobject_uevent(&p->kobj, KOBJ_REMOVE);
@@ -476,16 +476,16 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
476 if (err) 476 if (err)
477 goto err3; 477 goto err3;
478 478
479 err = netdev_master_upper_dev_link(dev, br->dev); 479 err = netdev_rx_handler_register(dev, br_handle_frame, p);
480 if (err) 480 if (err)
481 goto err4; 481 goto err4;
482 482
483 err = netdev_rx_handler_register(dev, br_handle_frame, p); 483 dev->priv_flags |= IFF_BRIDGE_PORT;
484
485 err = netdev_master_upper_dev_link(dev, br->dev);
484 if (err) 486 if (err)
485 goto err5; 487 goto err5;
486 488
487 dev->priv_flags |= IFF_BRIDGE_PORT;
488
489 dev_disable_lro(dev); 489 dev_disable_lro(dev);
490 490
491 list_add_rcu(&p->list, &br->port_list); 491 list_add_rcu(&p->list, &br->port_list);
@@ -520,7 +520,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
520 return 0; 520 return 0;
521 521
522err5: 522err5:
523 netdev_upper_dev_unlink(dev, br->dev); 523 dev->priv_flags &= ~IFF_BRIDGE_PORT;
524 netdev_rx_handler_unregister(dev);
524err4: 525err4:
525 br_netpoll_disable(p); 526 br_netpoll_disable(p);
526err3: 527err3: