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.c104
1 files changed, 16 insertions, 88 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 718b60366dfe..5dbdfdfc3a34 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -36,8 +36,8 @@ static int port_cost(struct net_device *dev)
36 if (dev->ethtool_ops && dev->ethtool_ops->get_settings) { 36 if (dev->ethtool_ops && dev->ethtool_ops->get_settings) {
37 struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET, }; 37 struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET, };
38 38
39 if (!dev->ethtool_ops->get_settings(dev, &ecmd)) { 39 if (!dev_ethtool_get_settings(dev, &ecmd)) {
40 switch(ecmd.speed) { 40 switch (ethtool_cmd_speed(&ecmd)) {
41 case SPEED_10000: 41 case SPEED_10000:
42 return 2; 42 return 2;
43 case SPEED_1000: 43 case SPEED_1000:
@@ -175,56 +175,6 @@ static void del_br(struct net_bridge *br, struct list_head *head)
175 unregister_netdevice_queue(br->dev, head); 175 unregister_netdevice_queue(br->dev, head);
176} 176}
177 177
178static struct net_device *new_bridge_dev(struct net *net, const char *name)
179{
180 struct net_bridge *br;
181 struct net_device *dev;
182
183 dev = alloc_netdev(sizeof(struct net_bridge), name,
184 br_dev_setup);
185
186 if (!dev)
187 return NULL;
188 dev_net_set(dev, net);
189
190 br = netdev_priv(dev);
191 br->dev = dev;
192
193 br->stats = alloc_percpu(struct br_cpu_netstats);
194 if (!br->stats) {
195 free_netdev(dev);
196 return NULL;
197 }
198
199 spin_lock_init(&br->lock);
200 INIT_LIST_HEAD(&br->port_list);
201 spin_lock_init(&br->hash_lock);
202
203 br->bridge_id.prio[0] = 0x80;
204 br->bridge_id.prio[1] = 0x00;
205
206 memcpy(br->group_addr, br_group_address, ETH_ALEN);
207
208 br->feature_mask = dev->features;
209 br->stp_enabled = BR_NO_STP;
210 br->designated_root = br->bridge_id;
211 br->root_path_cost = 0;
212 br->root_port = 0;
213 br->bridge_max_age = br->max_age = 20 * HZ;
214 br->bridge_hello_time = br->hello_time = 2 * HZ;
215 br->bridge_forward_delay = br->forward_delay = 15 * HZ;
216 br->topology_change = 0;
217 br->topology_change_detected = 0;
218 br->ageing_time = 300 * HZ;
219
220 br_netfilter_rtable_init(br);
221
222 br_stp_timer_init(br);
223 br_multicast_init(br);
224
225 return dev;
226}
227
228/* find an available port number */ 178/* find an available port number */
229static int find_portno(struct net_bridge *br) 179static int find_portno(struct net_bridge *br)
230{ 180{
@@ -277,42 +227,19 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
277 return p; 227 return p;
278} 228}
279 229
280static struct device_type br_type = {
281 .name = "bridge",
282};
283
284int br_add_bridge(struct net *net, const char *name) 230int br_add_bridge(struct net *net, const char *name)
285{ 231{
286 struct net_device *dev; 232 struct net_device *dev;
287 int ret;
288 233
289 dev = new_bridge_dev(net, name); 234 dev = alloc_netdev(sizeof(struct net_bridge), name,
235 br_dev_setup);
236
290 if (!dev) 237 if (!dev)
291 return -ENOMEM; 238 return -ENOMEM;
292 239
293 rtnl_lock(); 240 dev_net_set(dev, net);
294 if (strchr(dev->name, '%')) {
295 ret = dev_alloc_name(dev, dev->name);
296 if (ret < 0)
297 goto out_free;
298 }
299
300 SET_NETDEV_DEVTYPE(dev, &br_type);
301
302 ret = register_netdevice(dev);
303 if (ret)
304 goto out_free;
305
306 ret = br_sysfs_addbr(dev);
307 if (ret)
308 unregister_netdevice(dev);
309 out:
310 rtnl_unlock();
311 return ret;
312 241
313out_free: 242 return register_netdev(dev);
314 free_netdev(dev);
315 goto out;
316} 243}
317 244
318int br_del_bridge(struct net *net, const char *name) 245int br_del_bridge(struct net *net, const char *name)
@@ -364,15 +291,15 @@ int br_min_mtu(const struct net_bridge *br)
364/* 291/*
365 * Recomputes features using slave's features 292 * Recomputes features using slave's features
366 */ 293 */
367void br_features_recompute(struct net_bridge *br) 294u32 br_features_recompute(struct net_bridge *br, u32 features)
368{ 295{
369 struct net_bridge_port *p; 296 struct net_bridge_port *p;
370 u32 features, mask; 297 u32 mask;
371 298
372 features = mask = br->feature_mask;
373 if (list_empty(&br->port_list)) 299 if (list_empty(&br->port_list))
374 goto done; 300 return features;
375 301
302 mask = features;
376 features &= ~NETIF_F_ONE_FOR_ALL; 303 features &= ~NETIF_F_ONE_FOR_ALL;
377 304
378 list_for_each_entry(p, &br->port_list, list) { 305 list_for_each_entry(p, &br->port_list, list) {
@@ -380,8 +307,7 @@ void br_features_recompute(struct net_bridge *br)
380 p->dev->features, mask); 307 p->dev->features, mask);
381 } 308 }
382 309
383done: 310 return features;
384 br->dev->features = netdev_fix_features(br->dev, features);
385} 311}
386 312
387/* called with RTNL */ 313/* called with RTNL */
@@ -446,9 +372,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
446 372
447 list_add_rcu(&p->list, &br->port_list); 373 list_add_rcu(&p->list, &br->port_list);
448 374
375 netdev_update_features(br->dev);
376
449 spin_lock_bh(&br->lock); 377 spin_lock_bh(&br->lock);
450 changed_addr = br_stp_recalculate_bridge_id(br); 378 changed_addr = br_stp_recalculate_bridge_id(br);
451 br_features_recompute(br);
452 379
453 if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && 380 if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
454 (br->dev->flags & IFF_UP)) 381 (br->dev->flags & IFF_UP))
@@ -496,9 +423,10 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
496 423
497 spin_lock_bh(&br->lock); 424 spin_lock_bh(&br->lock);
498 br_stp_recalculate_bridge_id(br); 425 br_stp_recalculate_bridge_id(br);
499 br_features_recompute(br);
500 spin_unlock_bh(&br->lock); 426 spin_unlock_bh(&br->lock);
501 427
428 netdev_update_features(br->dev);
429
502 return 0; 430 return 0;
503} 431}
504 432