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.c77
1 files changed, 55 insertions, 22 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 70b7ef917234..7fa3a5a9971f 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -106,6 +106,20 @@ done:
106 rtnl_unlock(); 106 rtnl_unlock();
107} 107}
108 108
109static void release_nbp(struct kobject *kobj)
110{
111 struct net_bridge_port *p
112 = container_of(kobj, struct net_bridge_port, kobj);
113 kfree(p);
114}
115
116static struct kobj_type brport_ktype = {
117#ifdef CONFIG_SYSFS
118 .sysfs_ops = &brport_sysfs_ops,
119#endif
120 .release = release_nbp,
121};
122
109static void destroy_nbp(struct net_bridge_port *p) 123static void destroy_nbp(struct net_bridge_port *p)
110{ 124{
111 struct net_device *dev = p->dev; 125 struct net_device *dev = p->dev;
@@ -114,7 +128,7 @@ static void destroy_nbp(struct net_bridge_port *p)
114 p->dev = NULL; 128 p->dev = NULL;
115 dev_put(dev); 129 dev_put(dev);
116 130
117 br_sysfs_freeif(p); 131 kobject_put(&p->kobj);
118} 132}
119 133
120static void destroy_nbp_rcu(struct rcu_head *head) 134static void destroy_nbp_rcu(struct rcu_head *head)
@@ -138,6 +152,8 @@ static void del_nbp(struct net_bridge_port *p)
138 struct net_bridge *br = p->br; 152 struct net_bridge *br = p->br;
139 struct net_device *dev = p->dev; 153 struct net_device *dev = p->dev;
140 154
155 sysfs_remove_link(&br->ifobj, dev->name);
156
141 dev_set_promiscuity(dev, -1); 157 dev_set_promiscuity(dev, -1);
142 158
143 cancel_delayed_work(&p->carrier_check); 159 cancel_delayed_work(&p->carrier_check);
@@ -152,6 +168,8 @@ static void del_nbp(struct net_bridge_port *p)
152 168
153 rcu_assign_pointer(dev->br_port, NULL); 169 rcu_assign_pointer(dev->br_port, NULL);
154 170
171 kobject_del(&p->kobj);
172
155 call_rcu(&p->rcu, destroy_nbp_rcu); 173 call_rcu(&p->rcu, destroy_nbp_rcu);
156} 174}
157 175
@@ -161,7 +179,6 @@ static void del_br(struct net_bridge *br)
161 struct net_bridge_port *p, *n; 179 struct net_bridge_port *p, *n;
162 180
163 list_for_each_entry_safe(p, n, &br->port_list, list) { 181 list_for_each_entry_safe(p, n, &br->port_list, list) {
164 br_sysfs_removeif(p);
165 del_nbp(p); 182 del_nbp(p);
166 } 183 }
167 184
@@ -261,6 +278,11 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
261 INIT_WORK(&p->carrier_check, port_carrier_check, dev); 278 INIT_WORK(&p->carrier_check, port_carrier_check, dev);
262 kobject_init(&p->kobj); 279 kobject_init(&p->kobj);
263 280
281 kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR);
282 p->kobj.ktype = &brport_ktype;
283 p->kobj.parent = &(dev->class_dev.kobj);
284 p->kobj.kset = NULL;
285
264 return p; 286 return p;
265} 287}
266 288
@@ -388,31 +410,43 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
388 if (dev->br_port != NULL) 410 if (dev->br_port != NULL)
389 return -EBUSY; 411 return -EBUSY;
390 412
391 if (IS_ERR(p = new_nbp(br, dev))) 413 p = new_nbp(br, dev);
414 if (IS_ERR(p))
392 return PTR_ERR(p); 415 return PTR_ERR(p);
393 416
394 if ((err = br_fdb_insert(br, p, dev->dev_addr))) 417 err = kobject_add(&p->kobj);
395 destroy_nbp(p); 418 if (err)
396 419 goto err0;
397 else if ((err = br_sysfs_addif(p)))
398 del_nbp(p);
399 else {
400 rcu_assign_pointer(dev->br_port, p);
401 dev_set_promiscuity(dev, 1);
402 420
403 list_add_rcu(&p->list, &br->port_list); 421 err = br_fdb_insert(br, p, dev->dev_addr);
422 if (err)
423 goto err1;
404 424
405 spin_lock_bh(&br->lock); 425 err = br_sysfs_addif(p);
406 br_stp_recalculate_bridge_id(br); 426 if (err)
407 br_features_recompute(br); 427 goto err2;
408 if ((br->dev->flags & IFF_UP)
409 && (dev->flags & IFF_UP) && netif_carrier_ok(dev))
410 br_stp_enable_port(p);
411 spin_unlock_bh(&br->lock);
412 428
413 dev_set_mtu(br->dev, br_min_mtu(br)); 429 rcu_assign_pointer(dev->br_port, p);
414 } 430 dev_set_promiscuity(dev, 1);
431
432 list_add_rcu(&p->list, &br->port_list);
433
434 spin_lock_bh(&br->lock);
435 br_stp_recalculate_bridge_id(br);
436 br_features_recompute(br);
437 schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
438 spin_unlock_bh(&br->lock);
439
440 dev_set_mtu(br->dev, br_min_mtu(br));
441 kobject_uevent(&p->kobj, KOBJ_ADD);
415 442
443 return 0;
444err2:
445 br_fdb_delete_by_port(br, p);
446err1:
447 kobject_del(&p->kobj);
448err0:
449 kobject_put(&p->kobj);
416 return err; 450 return err;
417} 451}
418 452
@@ -424,7 +458,6 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
424 if (!p || p->br != br) 458 if (!p || p->br != br)
425 return -EINVAL; 459 return -EINVAL;
426 460
427 br_sysfs_removeif(p);
428 del_nbp(p); 461 del_nbp(p);
429 462
430 spin_lock_bh(&br->lock); 463 spin_lock_bh(&br->lock);