diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-09-16 19:20:48 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-09-16 19:20:48 -0400 |
commit | e081e1e3ef4682802ac63b1e5e26158fb9ca9e90 (patch) | |
tree | c43b403bd09c209df7f093810b68e672dcc6330b /net/bridge/br_input.c | |
parent | 9355ec23397af32799038d0e8edbfa5b6f425c27 (diff) |
[BRIDGE]: Kill clone argument to br_flood_*
The clone argument is only used by one caller and that caller can clone
the packet itself. This patch moves the clone call into the caller and
kills the clone argument.
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 | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 6f468fc3357a..3a8a015c92e0 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -43,7 +43,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
43 | struct net_bridge_port *p = rcu_dereference(skb->dev->br_port); | 43 | struct net_bridge_port *p = rcu_dereference(skb->dev->br_port); |
44 | struct net_bridge *br; | 44 | struct net_bridge *br; |
45 | struct net_bridge_fdb_entry *dst; | 45 | struct net_bridge_fdb_entry *dst; |
46 | int passedup = 0; | 46 | struct sk_buff *skb2; |
47 | 47 | ||
48 | if (!p || p->state == BR_STATE_DISABLED) | 48 | if (!p || p->state == BR_STATE_DISABLED) |
49 | goto drop; | 49 | goto drop; |
@@ -55,39 +55,35 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
55 | if (p->state == BR_STATE_LEARNING) | 55 | if (p->state == BR_STATE_LEARNING) |
56 | goto drop; | 56 | goto drop; |
57 | 57 | ||
58 | if (br->dev->flags & IFF_PROMISC) { | 58 | /* The packet skb2 goes to the local host (NULL to skip). */ |
59 | struct sk_buff *skb2; | 59 | skb2 = NULL; |
60 | 60 | ||
61 | skb2 = skb_clone(skb, GFP_ATOMIC); | 61 | if (br->dev->flags & IFF_PROMISC) |
62 | if (skb2 != NULL) { | 62 | skb2 = skb; |
63 | passedup = 1; | 63 | |
64 | br_pass_frame_up(br, skb2); | 64 | dst = NULL; |
65 | } | ||
66 | } | ||
67 | 65 | ||
68 | if (is_multicast_ether_addr(dest)) { | 66 | if (is_multicast_ether_addr(dest)) { |
69 | br->statistics.multicast++; | 67 | br->statistics.multicast++; |
70 | br_flood_forward(br, skb, !passedup); | 68 | skb2 = skb; |
71 | if (!passedup) | 69 | } else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) { |
72 | br_pass_frame_up(br, skb); | 70 | skb2 = skb; |
73 | goto out; | 71 | /* Do not forward the packet since it's local. */ |
72 | skb = NULL; | ||
74 | } | 73 | } |
75 | 74 | ||
76 | dst = __br_fdb_get(br, dest); | 75 | if (skb2 == skb) |
77 | if (dst != NULL && dst->is_local) { | 76 | skb2 = skb_clone(skb, GFP_ATOMIC); |
78 | if (!passedup) | ||
79 | br_pass_frame_up(br, skb); | ||
80 | else | ||
81 | kfree_skb(skb); | ||
82 | goto out; | ||
83 | } | ||
84 | 77 | ||
85 | if (dst != NULL) { | 78 | if (skb2) |
86 | br_forward(dst->dst, skb); | 79 | br_pass_frame_up(br, skb2); |
87 | goto out; | ||
88 | } | ||
89 | 80 | ||
90 | br_flood_forward(br, skb, 0); | 81 | if (skb) { |
82 | if (dst) | ||
83 | br_forward(dst->dst, skb); | ||
84 | else | ||
85 | br_flood_forward(br, skb); | ||
86 | } | ||
91 | 87 | ||
92 | out: | 88 | out: |
93 | return 0; | 89 | return 0; |