diff options
author | WANG Cong <amwang@redhat.com> | 2010-05-06 03:48:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-05-06 03:48:24 -0400 |
commit | c06ee961d3c0e51009cbd0e123b61fbb97f37d0b (patch) | |
tree | 5d5899374a6f32f5ab77a78e6baeeb4a122a4721 /net/bridge/br_if.c | |
parent | 0e34e93177fb1f642cab080e0bde664c06c7183a (diff) |
bridge: make bridge support netpoll
Based on the previous patch, make bridge support netpoll by:
1) implement the 2 methods to support netpoll for bridge;
2) modify netpoll during forwarding packets via bridge;
3) disable netpoll support of bridge when a netpoll-unabled device
is added to bridge;
4) enable netpoll support when all underlying devices support netpoll.
Cc: David Miller <davem@davemloft.net>
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: Stephen Hemminger <shemminger@linux-foundation.org>
Cc: Matt Mackall <mpm@selenic.com>
Signed-off-by: WANG Cong <amwang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_if.c')
-rw-r--r-- | net/bridge/br_if.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 521439333316..537bdd60d9b9 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> |
@@ -153,6 +154,14 @@ 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 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
158 | if (br_devices_support_netpoll(br)) | ||
159 | br->dev->priv_flags &= ~IFF_DISABLE_NETPOLL; | ||
160 | if (dev->netdev_ops->ndo_netpoll_cleanup) | ||
161 | dev->netdev_ops->ndo_netpoll_cleanup(dev); | ||
162 | else | ||
163 | dev->npinfo = NULL; | ||
164 | #endif | ||
156 | call_rcu(&p->rcu, destroy_nbp_rcu); | 165 | call_rcu(&p->rcu, destroy_nbp_rcu); |
157 | } | 166 | } |
158 | 167 | ||
@@ -165,6 +174,8 @@ static void del_br(struct net_bridge *br, struct list_head *head) | |||
165 | del_nbp(p); | 174 | del_nbp(p); |
166 | } | 175 | } |
167 | 176 | ||
177 | br_netpoll_cleanup(br->dev); | ||
178 | |||
168 | del_timer_sync(&br->gc_timer); | 179 | del_timer_sync(&br->gc_timer); |
169 | 180 | ||
170 | br_sysfs_delbr(br->dev); | 181 | br_sysfs_delbr(br->dev); |
@@ -444,6 +455,20 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
444 | 455 | ||
445 | kobject_uevent(&p->kobj, KOBJ_ADD); | 456 | kobject_uevent(&p->kobj, KOBJ_ADD); |
446 | 457 | ||
458 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
459 | if (br_devices_support_netpoll(br)) { | ||
460 | br->dev->priv_flags &= ~IFF_DISABLE_NETPOLL; | ||
461 | if (br->dev->npinfo) | ||
462 | dev->npinfo = br->dev->npinfo; | ||
463 | } else if (!(br->dev->priv_flags & IFF_DISABLE_NETPOLL)) { | ||
464 | br->dev->priv_flags |= IFF_DISABLE_NETPOLL; | ||
465 | printk(KERN_INFO "New device %s does not support netpoll\n", | ||
466 | dev->name); | ||
467 | printk(KERN_INFO "Disabling netpoll for %s\n", | ||
468 | br->dev->name); | ||
469 | } | ||
470 | #endif | ||
471 | |||
447 | return 0; | 472 | return 0; |
448 | err2: | 473 | err2: |
449 | br_fdb_delete_by_port(br, p, 1); | 474 | br_fdb_delete_by_port(br, p, 1); |