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_forward.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_forward.c')
| -rw-r--r-- | net/bridge/br_forward.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 396f077216a3..92ad9feb199d 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/netdevice.h> | 17 | #include <linux/netdevice.h> |
| 18 | #include <linux/netpoll.h> | ||
| 18 | #include <linux/skbuff.h> | 19 | #include <linux/skbuff.h> |
| 19 | #include <linux/if_vlan.h> | 20 | #include <linux/if_vlan.h> |
| 20 | #include <linux/netfilter_bridge.h> | 21 | #include <linux/netfilter_bridge.h> |
| @@ -50,7 +51,13 @@ int br_dev_queue_push_xmit(struct sk_buff *skb) | |||
| 50 | else { | 51 | else { |
| 51 | skb_push(skb, ETH_HLEN); | 52 | skb_push(skb, ETH_HLEN); |
| 52 | 53 | ||
| 53 | dev_queue_xmit(skb); | 54 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 55 | if (unlikely(skb->dev->priv_flags & IFF_IN_NETPOLL)) { | ||
| 56 | netpoll_send_skb(skb->dev->npinfo->netpoll, skb); | ||
| 57 | skb->dev->priv_flags &= ~IFF_IN_NETPOLL; | ||
| 58 | } else | ||
| 59 | #endif | ||
| 60 | dev_queue_xmit(skb); | ||
| 54 | } | 61 | } |
| 55 | } | 62 | } |
| 56 | 63 | ||
| @@ -66,9 +73,23 @@ int br_forward_finish(struct sk_buff *skb) | |||
| 66 | 73 | ||
| 67 | static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) | 74 | static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) |
| 68 | { | 75 | { |
| 76 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 77 | struct net_bridge *br = to->br; | ||
| 78 | if (unlikely(br->dev->priv_flags & IFF_IN_NETPOLL)) { | ||
| 79 | struct netpoll *np; | ||
| 80 | to->dev->npinfo = skb->dev->npinfo; | ||
| 81 | np = skb->dev->npinfo->netpoll; | ||
| 82 | np->real_dev = np->dev = to->dev; | ||
| 83 | to->dev->priv_flags |= IFF_IN_NETPOLL; | ||
| 84 | } | ||
| 85 | #endif | ||
| 69 | skb->dev = to->dev; | 86 | skb->dev = to->dev; |
| 70 | NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, | 87 | NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
| 71 | br_forward_finish); | 88 | br_forward_finish); |
| 89 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 90 | if (skb->dev->npinfo) | ||
| 91 | skb->dev->npinfo->netpoll->dev = br->dev; | ||
| 92 | #endif | ||
| 72 | } | 93 | } |
| 73 | 94 | ||
| 74 | static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) | 95 | static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) |
