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.c132
1 files changed, 89 insertions, 43 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index ba442883e877..f36b35edd60c 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -79,27 +79,48 @@ static int port_cost(struct net_device *dev)
79 */ 79 */
80static void port_carrier_check(void *arg) 80static void port_carrier_check(void *arg)
81{ 81{
82 struct net_bridge_port *p = arg; 82 struct net_device *dev = arg;
83 struct net_bridge_port *p;
84 struct net_bridge *br;
83 85
84 rtnl_lock(); 86 rtnl_lock();
85 if (netif_carrier_ok(p->dev)) { 87 p = dev->br_port;
86 u32 cost = port_cost(p->dev); 88 if (!p)
89 goto done;
90 br = p->br;
91
92 if (netif_carrier_ok(dev))
93 p->path_cost = port_cost(dev);
87 94
88 spin_lock_bh(&p->br->lock); 95 if (br->dev->flags & IFF_UP) {
89 if (p->state == BR_STATE_DISABLED) { 96 spin_lock_bh(&br->lock);
90 p->path_cost = cost; 97 if (netif_carrier_ok(dev)) {
91 br_stp_enable_port(p); 98 if (p->state == BR_STATE_DISABLED)
99 br_stp_enable_port(p);
100 } else {
101 if (p->state != BR_STATE_DISABLED)
102 br_stp_disable_port(p);
92 } 103 }
93 spin_unlock_bh(&p->br->lock); 104 spin_unlock_bh(&br->lock);
94 } else {
95 spin_lock_bh(&p->br->lock);
96 if (p->state != BR_STATE_DISABLED)
97 br_stp_disable_port(p);
98 spin_unlock_bh(&p->br->lock);
99 } 105 }
106done:
100 rtnl_unlock(); 107 rtnl_unlock();
101} 108}
102 109
110static void release_nbp(struct kobject *kobj)
111{
112 struct net_bridge_port *p
113 = container_of(kobj, struct net_bridge_port, kobj);
114 kfree(p);
115}
116
117static struct kobj_type brport_ktype = {
118#ifdef CONFIG_SYSFS
119 .sysfs_ops = &brport_sysfs_ops,
120#endif
121 .release = release_nbp,
122};
123
103static void destroy_nbp(struct net_bridge_port *p) 124static void destroy_nbp(struct net_bridge_port *p)
104{ 125{
105 struct net_device *dev = p->dev; 126 struct net_device *dev = p->dev;
@@ -108,7 +129,7 @@ static void destroy_nbp(struct net_bridge_port *p)
108 p->dev = NULL; 129 p->dev = NULL;
109 dev_put(dev); 130 dev_put(dev);
110 131
111 br_sysfs_freeif(p); 132 kobject_put(&p->kobj);
112} 133}
113 134
114static void destroy_nbp_rcu(struct rcu_head *head) 135static void destroy_nbp_rcu(struct rcu_head *head)
@@ -118,17 +139,25 @@ static void destroy_nbp_rcu(struct rcu_head *head)
118 destroy_nbp(p); 139 destroy_nbp(p);
119} 140}
120 141
121/* called with RTNL */ 142/* Delete port(interface) from bridge is done in two steps.
143 * via RCU. First step, marks device as down. That deletes
144 * all the timers and stops new packets from flowing through.
145 *
146 * Final cleanup doesn't occur until after all CPU's finished
147 * processing packets.
148 *
149 * Protected from multiple admin operations by RTNL mutex
150 */
122static void del_nbp(struct net_bridge_port *p) 151static void del_nbp(struct net_bridge_port *p)
123{ 152{
124 struct net_bridge *br = p->br; 153 struct net_bridge *br = p->br;
125 struct net_device *dev = p->dev; 154 struct net_device *dev = p->dev;
126 155
127 dev->br_port = NULL; 156 sysfs_remove_link(&br->ifobj, dev->name);
157
128 dev_set_promiscuity(dev, -1); 158 dev_set_promiscuity(dev, -1);
129 159
130 cancel_delayed_work(&p->carrier_check); 160 cancel_delayed_work(&p->carrier_check);
131 flush_scheduled_work();
132 161
133 spin_lock_bh(&br->lock); 162 spin_lock_bh(&br->lock);
134 br_stp_disable_port(p); 163 br_stp_disable_port(p);
@@ -138,10 +167,11 @@ static void del_nbp(struct net_bridge_port *p)
138 167
139 list_del_rcu(&p->list); 168 list_del_rcu(&p->list);
140 169
141 del_timer_sync(&p->message_age_timer); 170 rcu_assign_pointer(dev->br_port, NULL);
142 del_timer_sync(&p->forward_delay_timer); 171
143 del_timer_sync(&p->hold_timer); 172 kobject_uevent(&p->kobj, KOBJ_REMOVE);
144 173 kobject_del(&p->kobj);
174
145 call_rcu(&p->rcu, destroy_nbp_rcu); 175 call_rcu(&p->rcu, destroy_nbp_rcu);
146} 176}
147 177
@@ -151,7 +181,6 @@ static void del_br(struct net_bridge *br)
151 struct net_bridge_port *p, *n; 181 struct net_bridge_port *p, *n;
152 182
153 list_for_each_entry_safe(p, n, &br->port_list, list) { 183 list_for_each_entry_safe(p, n, &br->port_list, list) {
154 br_sysfs_removeif(p);
155 del_nbp(p); 184 del_nbp(p);
156 } 185 }
157 186
@@ -245,12 +274,17 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
245 p->dev = dev; 274 p->dev = dev;
246 p->path_cost = port_cost(dev); 275 p->path_cost = port_cost(dev);
247 p->priority = 0x8000 >> BR_PORT_BITS; 276 p->priority = 0x8000 >> BR_PORT_BITS;
248 dev->br_port = p;
249 p->port_no = index; 277 p->port_no = index;
250 br_init_port(p); 278 br_init_port(p);
251 p->state = BR_STATE_DISABLED; 279 p->state = BR_STATE_DISABLED;
252 INIT_WORK(&p->carrier_check, port_carrier_check, p); 280 INIT_WORK(&p->carrier_check, port_carrier_check, dev);
281 br_stp_port_timer_init(p);
282
253 kobject_init(&p->kobj); 283 kobject_init(&p->kobj);
284 kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR);
285 p->kobj.ktype = &brport_ktype;
286 p->kobj.parent = &(dev->class_dev.kobj);
287 p->kobj.kset = NULL;
254 288
255 return p; 289 return p;
256} 290}
@@ -379,30 +413,43 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
379 if (dev->br_port != NULL) 413 if (dev->br_port != NULL)
380 return -EBUSY; 414 return -EBUSY;
381 415
382 if (IS_ERR(p = new_nbp(br, dev))) 416 p = new_nbp(br, dev);
417 if (IS_ERR(p))
383 return PTR_ERR(p); 418 return PTR_ERR(p);
384 419
385 if ((err = br_fdb_insert(br, p, dev->dev_addr))) 420 err = kobject_add(&p->kobj);
386 destroy_nbp(p); 421 if (err)
387 422 goto err0;
388 else if ((err = br_sysfs_addif(p)))
389 del_nbp(p);
390 else {
391 dev_set_promiscuity(dev, 1);
392 423
393 list_add_rcu(&p->list, &br->port_list); 424 err = br_fdb_insert(br, p, dev->dev_addr);
425 if (err)
426 goto err1;
394 427
395 spin_lock_bh(&br->lock); 428 err = br_sysfs_addif(p);
396 br_stp_recalculate_bridge_id(br); 429 if (err)
397 br_features_recompute(br); 430 goto err2;
398 if ((br->dev->flags & IFF_UP)
399 && (dev->flags & IFF_UP) && netif_carrier_ok(dev))
400 br_stp_enable_port(p);
401 spin_unlock_bh(&br->lock);
402 431
403 dev_set_mtu(br->dev, br_min_mtu(br)); 432 rcu_assign_pointer(dev->br_port, p);
404 } 433 dev_set_promiscuity(dev, 1);
434
435 list_add_rcu(&p->list, &br->port_list);
405 436
437 spin_lock_bh(&br->lock);
438 br_stp_recalculate_bridge_id(br);
439 br_features_recompute(br);
440 schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
441 spin_unlock_bh(&br->lock);
442
443 dev_set_mtu(br->dev, br_min_mtu(br));
444 kobject_uevent(&p->kobj, KOBJ_ADD);
445
446 return 0;
447err2:
448 br_fdb_delete_by_port(br, p);
449err1:
450 kobject_del(&p->kobj);
451err0:
452 kobject_put(&p->kobj);
406 return err; 453 return err;
407} 454}
408 455
@@ -414,7 +461,6 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
414 if (!p || p->br != br) 461 if (!p || p->br != br)
415 return -EINVAL; 462 return -EINVAL;
416 463
417 br_sysfs_removeif(p);
418 del_nbp(p); 464 del_nbp(p);
419 465
420 spin_lock_bh(&br->lock); 466 spin_lock_bh(&br->lock);