diff options
author | Patrick McHardy <kaber@trash.net> | 2010-05-10 12:39:28 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-05-10 12:39:28 -0400 |
commit | 1e4b1057121bc756b91758a434b504d2010f6088 (patch) | |
tree | b016cf2c728289c7e36d9e4e488f30ab0bd0ae6e /net/bridge/br_device.c | |
parent | 3b254c54ec46eb022cb26ee6ab37fae23f5f7d6a (diff) | |
parent | 3ee943728fff536edaf8f59faa58aaa1aa7366e3 (diff) |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
net/bridge/br_device.c
net/bridge/br_forward.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/bridge/br_device.c')
-rw-r--r-- | net/bridge/br_device.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 007bde87415d..f15f9c4a0dd2 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -13,9 +13,12 @@ | |||
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/etherdevice.h> | 17 | #include <linux/etherdevice.h> |
17 | #include <linux/ethtool.h> | 18 | #include <linux/ethtool.h> |
19 | #include <linux/list.h> | ||
18 | #include <linux/netfilter_bridge.h> | 20 | #include <linux/netfilter_bridge.h> |
21 | |||
19 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
20 | #include "br_private.h" | 23 | #include "br_private.h" |
21 | 24 | ||
@@ -43,7 +46,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
43 | skb_reset_mac_header(skb); | 46 | skb_reset_mac_header(skb); |
44 | skb_pull(skb, ETH_HLEN); | 47 | skb_pull(skb, ETH_HLEN); |
45 | 48 | ||
46 | if (dest[0] & 1) { | 49 | if (is_multicast_ether_addr(dest)) { |
47 | if (br_multicast_rcv(br, NULL, skb)) | 50 | if (br_multicast_rcv(br, NULL, skb)) |
48 | goto out; | 51 | goto out; |
49 | 52 | ||
@@ -195,6 +198,59 @@ static int br_set_tx_csum(struct net_device *dev, u32 data) | |||
195 | return 0; | 198 | return 0; |
196 | } | 199 | } |
197 | 200 | ||
201 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
202 | bool br_devices_support_netpoll(struct net_bridge *br) | ||
203 | { | ||
204 | struct net_bridge_port *p; | ||
205 | bool ret = true; | ||
206 | int count = 0; | ||
207 | unsigned long flags; | ||
208 | |||
209 | spin_lock_irqsave(&br->lock, flags); | ||
210 | list_for_each_entry(p, &br->port_list, list) { | ||
211 | count++; | ||
212 | if ((p->dev->priv_flags & IFF_DISABLE_NETPOLL) || | ||
213 | !p->dev->netdev_ops->ndo_poll_controller) | ||
214 | ret = false; | ||
215 | } | ||
216 | spin_unlock_irqrestore(&br->lock, flags); | ||
217 | return count != 0 && ret; | ||
218 | } | ||
219 | |||
220 | static void br_poll_controller(struct net_device *br_dev) | ||
221 | { | ||
222 | struct netpoll *np = br_dev->npinfo->netpoll; | ||
223 | |||
224 | if (np->real_dev != br_dev) | ||
225 | netpoll_poll_dev(np->real_dev); | ||
226 | } | ||
227 | |||
228 | void br_netpoll_cleanup(struct net_device *br_dev) | ||
229 | { | ||
230 | struct net_bridge *br = netdev_priv(br_dev); | ||
231 | struct net_bridge_port *p, *n; | ||
232 | const struct net_device_ops *ops; | ||
233 | |||
234 | br->dev->npinfo = NULL; | ||
235 | list_for_each_entry_safe(p, n, &br->port_list, list) { | ||
236 | if (p->dev) { | ||
237 | ops = p->dev->netdev_ops; | ||
238 | if (ops->ndo_netpoll_cleanup) | ||
239 | ops->ndo_netpoll_cleanup(p->dev); | ||
240 | else | ||
241 | p->dev->npinfo = NULL; | ||
242 | } | ||
243 | } | ||
244 | } | ||
245 | |||
246 | #else | ||
247 | |||
248 | void br_netpoll_cleanup(struct net_device *br_dev) | ||
249 | { | ||
250 | } | ||
251 | |||
252 | #endif | ||
253 | |||
198 | static const struct ethtool_ops br_ethtool_ops = { | 254 | static const struct ethtool_ops br_ethtool_ops = { |
199 | .get_drvinfo = br_getinfo, | 255 | .get_drvinfo = br_getinfo, |
200 | .get_link = ethtool_op_get_link, | 256 | .get_link = ethtool_op_get_link, |
@@ -218,6 +274,10 @@ static const struct net_device_ops br_netdev_ops = { | |||
218 | .ndo_set_multicast_list = br_dev_set_multicast_list, | 274 | .ndo_set_multicast_list = br_dev_set_multicast_list, |
219 | .ndo_change_mtu = br_change_mtu, | 275 | .ndo_change_mtu = br_change_mtu, |
220 | .ndo_do_ioctl = br_dev_ioctl, | 276 | .ndo_do_ioctl = br_dev_ioctl, |
277 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
278 | .ndo_netpoll_cleanup = br_netpoll_cleanup, | ||
279 | .ndo_poll_controller = br_poll_controller, | ||
280 | #endif | ||
221 | }; | 281 | }; |
222 | 282 | ||
223 | static void br_dev_free(struct net_device *dev) | 283 | static void br_dev_free(struct net_device *dev) |