diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2010-02-27 14:41:40 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-28 03:48:43 -0500 |
commit | 68b7c895be336b19f4c38d7cb500132fabba0afd (patch) | |
tree | 13f2a04c86d22abd1c44e9659e54a13c8f939689 /net/bridge/br_input.c | |
parent | 87557c18ac36241b596984589a0889c5c4bf916c (diff) |
bridge: Allow tail-call on br_pass_frame_up
This patch allows tail-call on the call to br_pass_frame_up
in br_handle_frame_finish. This is now possible because of the
previous patch to call br_pass_frame_up last.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_input.c')
-rw-r--r-- | net/bridge/br_input.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 9589937e1c0a..be5ab8df6661 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -20,9 +20,9 @@ | |||
20 | /* Bridge group multicast address 802.1d (pg 51). */ | 20 | /* Bridge group multicast address 802.1d (pg 51). */ |
21 | const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; | 21 | const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; |
22 | 22 | ||
23 | static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb) | 23 | static int br_pass_frame_up(struct sk_buff *skb) |
24 | { | 24 | { |
25 | struct net_device *indev, *brdev = br->dev; | 25 | struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; |
26 | 26 | ||
27 | brdev->stats.rx_packets++; | 27 | brdev->stats.rx_packets++; |
28 | brdev->stats.rx_bytes += skb->len; | 28 | brdev->stats.rx_bytes += skb->len; |
@@ -30,8 +30,8 @@ static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb) | |||
30 | indev = skb->dev; | 30 | indev = skb->dev; |
31 | skb->dev = brdev; | 31 | skb->dev = brdev; |
32 | 32 | ||
33 | NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, | 33 | return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, |
34 | netif_receive_skb); | 34 | netif_receive_skb); |
35 | } | 35 | } |
36 | 36 | ||
37 | /* note: already called with rcu_read_lock (preempt_disabled) */ | 37 | /* note: already called with rcu_read_lock (preempt_disabled) */ |
@@ -53,6 +53,8 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
53 | if (p->state == BR_STATE_LEARNING) | 53 | if (p->state == BR_STATE_LEARNING) |
54 | goto drop; | 54 | goto drop; |
55 | 55 | ||
56 | BR_INPUT_SKB_CB(skb)->brdev = br->dev; | ||
57 | |||
56 | /* The packet skb2 goes to the local host (NULL to skip). */ | 58 | /* The packet skb2 goes to the local host (NULL to skip). */ |
57 | skb2 = NULL; | 59 | skb2 = NULL; |
58 | 60 | ||
@@ -81,7 +83,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
81 | } | 83 | } |
82 | 84 | ||
83 | if (skb2) | 85 | if (skb2) |
84 | br_pass_frame_up(br, skb2); | 86 | return br_pass_frame_up(skb2); |
85 | 87 | ||
86 | out: | 88 | out: |
87 | return 0; | 89 | return 0; |