diff options
Diffstat (limited to 'net/bridge/br_if.c')
-rw-r--r-- | net/bridge/br_if.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 0b6b1f2ff7ac..18b245e2c00e 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/netpoll.h> | ||
16 | #include <linux/ethtool.h> | 17 | #include <linux/ethtool.h> |
17 | #include <linux/if_arp.h> | 18 | #include <linux/if_arp.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
@@ -132,7 +133,7 @@ static void del_nbp(struct net_bridge_port *p) | |||
132 | struct net_bridge *br = p->br; | 133 | struct net_bridge *br = p->br; |
133 | struct net_device *dev = p->dev; | 134 | struct net_device *dev = p->dev; |
134 | 135 | ||
135 | sysfs_remove_link(br->ifobj, dev->name); | 136 | sysfs_remove_link(br->ifobj, p->dev->name); |
136 | 137 | ||
137 | dev_set_promiscuity(dev, -1); | 138 | dev_set_promiscuity(dev, -1); |
138 | 139 | ||
@@ -153,6 +154,7 @@ static void del_nbp(struct net_bridge_port *p) | |||
153 | kobject_uevent(&p->kobj, KOBJ_REMOVE); | 154 | kobject_uevent(&p->kobj, KOBJ_REMOVE); |
154 | kobject_del(&p->kobj); | 155 | kobject_del(&p->kobj); |
155 | 156 | ||
157 | br_netpoll_disable(br, dev); | ||
156 | call_rcu(&p->rcu, destroy_nbp_rcu); | 158 | call_rcu(&p->rcu, destroy_nbp_rcu); |
157 | } | 159 | } |
158 | 160 | ||
@@ -165,6 +167,8 @@ static void del_br(struct net_bridge *br, struct list_head *head) | |||
165 | del_nbp(p); | 167 | del_nbp(p); |
166 | } | 168 | } |
167 | 169 | ||
170 | br_netpoll_cleanup(br->dev); | ||
171 | |||
168 | del_timer_sync(&br->gc_timer); | 172 | del_timer_sync(&br->gc_timer); |
169 | 173 | ||
170 | br_sysfs_delbr(br->dev); | 174 | br_sysfs_delbr(br->dev); |
@@ -186,6 +190,12 @@ static struct net_device *new_bridge_dev(struct net *net, const char *name) | |||
186 | br = netdev_priv(dev); | 190 | br = netdev_priv(dev); |
187 | br->dev = dev; | 191 | br->dev = dev; |
188 | 192 | ||
193 | br->stats = alloc_percpu(struct br_cpu_netstats); | ||
194 | if (!br->stats) { | ||
195 | free_netdev(dev); | ||
196 | return NULL; | ||
197 | } | ||
198 | |||
189 | spin_lock_init(&br->lock); | 199 | spin_lock_init(&br->lock); |
190 | INIT_LIST_HEAD(&br->port_list); | 200 | INIT_LIST_HEAD(&br->port_list); |
191 | spin_lock_init(&br->hash_lock); | 201 | spin_lock_init(&br->hash_lock); |
@@ -438,6 +448,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
438 | 448 | ||
439 | kobject_uevent(&p->kobj, KOBJ_ADD); | 449 | kobject_uevent(&p->kobj, KOBJ_ADD); |
440 | 450 | ||
451 | br_netpoll_enable(br, dev); | ||
452 | |||
441 | return 0; | 453 | return 0; |
442 | err2: | 454 | err2: |
443 | br_fdb_delete_by_port(br, p, 1); | 455 | br_fdb_delete_by_port(br, p, 1); |