diff options
Diffstat (limited to 'net/bridge/br_if.c')
-rw-r--r-- | net/bridge/br_if.c | 41 |
1 files changed, 19 insertions, 22 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 1d420f64ff27..f603e5b0b930 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
16 | #include <linux/etherdevice.h> | ||
16 | #include <linux/netpoll.h> | 17 | #include <linux/netpoll.h> |
17 | #include <linux/ethtool.h> | 18 | #include <linux/ethtool.h> |
18 | #include <linux/if_arp.h> | 19 | #include <linux/if_arp.h> |
@@ -33,20 +34,18 @@ | |||
33 | */ | 34 | */ |
34 | static int port_cost(struct net_device *dev) | 35 | static int port_cost(struct net_device *dev) |
35 | { | 36 | { |
36 | if (dev->ethtool_ops && dev->ethtool_ops->get_settings) { | 37 | struct ethtool_cmd ecmd; |
37 | struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET, }; | 38 | |
38 | 39 | if (!__ethtool_get_settings(dev, &ecmd)) { | |
39 | if (!dev_ethtool_get_settings(dev, &ecmd)) { | 40 | switch (ethtool_cmd_speed(&ecmd)) { |
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: | 44 | return 4; |
44 | return 4; | 45 | case SPEED_100: |
45 | case SPEED_100: | 46 | return 19; |
46 | return 19; | 47 | case SPEED_10: |
47 | case SPEED_10: | 48 | return 100; |
48 | return 100; | ||
49 | } | ||
50 | } | 49 | } |
51 | } | 50 | } |
52 | 51 | ||
@@ -325,7 +324,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
325 | 324 | ||
326 | /* Don't allow bridging non-ethernet like devices */ | 325 | /* Don't allow bridging non-ethernet like devices */ |
327 | if ((dev->flags & IFF_LOOPBACK) || | 326 | if ((dev->flags & IFF_LOOPBACK) || |
328 | dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN) | 327 | dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN || |
328 | !is_valid_ether_addr(dev->dev_addr)) | ||
329 | return -EINVAL; | 329 | return -EINVAL; |
330 | 330 | ||
331 | /* No bridging of bridges */ | 331 | /* No bridging of bridges */ |
@@ -353,10 +353,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
353 | err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj), | 353 | err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj), |
354 | SYSFS_BRIDGE_PORT_ATTR); | 354 | SYSFS_BRIDGE_PORT_ATTR); |
355 | if (err) | 355 | if (err) |
356 | goto err0; | ||
357 | |||
358 | err = br_fdb_insert(br, p, dev->dev_addr); | ||
359 | if (err) | ||
360 | goto err1; | 356 | goto err1; |
361 | 357 | ||
362 | err = br_sysfs_addif(p); | 358 | err = br_sysfs_addif(p); |
@@ -397,6 +393,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
397 | 393 | ||
398 | dev_set_mtu(br->dev, br_min_mtu(br)); | 394 | dev_set_mtu(br->dev, br_min_mtu(br)); |
399 | 395 | ||
396 | if (br_fdb_insert(br, p, dev->dev_addr)) | ||
397 | netdev_err(dev, "failed insert local address bridge forwarding table\n"); | ||
398 | |||
400 | kobject_uevent(&p->kobj, KOBJ_ADD); | 399 | kobject_uevent(&p->kobj, KOBJ_ADD); |
401 | 400 | ||
402 | return 0; | 401 | return 0; |
@@ -406,11 +405,9 @@ err4: | |||
406 | err3: | 405 | err3: |
407 | sysfs_remove_link(br->ifobj, p->dev->name); | 406 | sysfs_remove_link(br->ifobj, p->dev->name); |
408 | err2: | 407 | err2: |
409 | br_fdb_delete_by_port(br, p, 1); | ||
410 | err1: | ||
411 | kobject_put(&p->kobj); | 408 | kobject_put(&p->kobj); |
412 | p = NULL; /* kobject_put frees */ | 409 | p = NULL; /* kobject_put frees */ |
413 | err0: | 410 | err1: |
414 | dev_set_promiscuity(dev, -1); | 411 | dev_set_promiscuity(dev, -1); |
415 | put_back: | 412 | put_back: |
416 | dev_put(dev); | 413 | dev_put(dev); |