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, 13 insertions, 10 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 0d142ed0bbe3..c03d2c3ff03e 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -147,8 +147,9 @@ static void del_nbp(struct net_bridge_port *p)
147 147
148 list_del_rcu(&p->list); 148 list_del_rcu(&p->list);
149 149
150 dev->priv_flags &= ~IFF_BRIDGE_PORT;
151
150 netdev_rx_handler_unregister(dev); 152 netdev_rx_handler_unregister(dev);
151 rcu_assign_pointer(dev->br_port, NULL);
152 153
153 br_multicast_del_port(p); 154 br_multicast_del_port(p);
154 155
@@ -400,7 +401,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
400 return -ELOOP; 401 return -ELOOP;
401 402
402 /* Device is already being bridged */ 403 /* Device is already being bridged */
403 if (dev->br_port != NULL) 404 if (br_port_exists(dev))
404 return -EBUSY; 405 return -EBUSY;
405 406
406 /* No bridging devices that dislike that (e.g. wireless) */ 407 /* No bridging devices that dislike that (e.g. wireless) */
@@ -431,11 +432,11 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
431 if (br_netpoll_info(br) && ((err = br_netpoll_enable(p)))) 432 if (br_netpoll_info(br) && ((err = br_netpoll_enable(p))))
432 goto err3; 433 goto err3;
433 434
434 rcu_assign_pointer(dev->br_port, p); 435 err = netdev_rx_handler_register(dev, br_handle_frame, p);
435
436 err = netdev_rx_handler_register(dev, br_handle_frame, NULL);
437 if (err) 436 if (err)
438 goto err4; 437 goto err3;
438
439 dev->priv_flags |= IFF_BRIDGE_PORT;
439 440
440 dev_disable_lro(dev); 441 dev_disable_lro(dev);
441 442
@@ -457,8 +458,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
457 kobject_uevent(&p->kobj, KOBJ_ADD); 458 kobject_uevent(&p->kobj, KOBJ_ADD);
458 459
459 return 0; 460 return 0;
460err4:
461 rcu_assign_pointer(dev->br_port, NULL);
462err3: 461err3:
463 sysfs_remove_link(br->ifobj, p->dev->name); 462 sysfs_remove_link(br->ifobj, p->dev->name);
464err2: 463err2:
@@ -477,9 +476,13 @@ put_back:
477/* called with RTNL */ 476/* called with RTNL */
478int br_del_if(struct net_bridge *br, struct net_device *dev) 477int br_del_if(struct net_bridge *br, struct net_device *dev)
479{ 478{
480 struct net_bridge_port *p = dev->br_port; 479 struct net_bridge_port *p;
480
481 if (!br_port_exists(dev))
482 return -EINVAL;
481 483
482 if (!p || p->br != br) 484 p = br_port_get(dev);
485 if (p->br != br)
483 return -EINVAL; 486 return -EINVAL;
484 487
485 del_nbp(p); 488 del_nbp(p);