aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-09-16 19:20:48 -0400
committerDavid S. Miller <davem@davemloft.net>2007-09-16 19:20:48 -0400
commite081e1e3ef4682802ac63b1e5e26158fb9ca9e90 (patch)
treec43b403bd09c209df7f093810b68e672dcc6330b /net/bridge
parent9355ec23397af32799038d0e8edbfa5b6f425c27 (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')
-rw-r--r--net/bridge/br_device.c4
-rw-r--r--net/bridge/br_forward.c21
-rw-r--r--net/bridge/br_input.c48
-rw-r--r--net/bridge/br_private.h8
4 files changed, 31 insertions, 50 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 0eded176ce99..99292e8e1d0f 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -41,11 +41,11 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
41 skb_pull(skb, ETH_HLEN); 41 skb_pull(skb, ETH_HLEN);
42 42
43 if (dest[0] & 1) 43 if (dest[0] & 1)
44 br_flood_deliver(br, skb, 0); 44 br_flood_deliver(br, skb);
45 else if ((dst = __br_fdb_get(br, dest)) != NULL) 45 else if ((dst = __br_fdb_get(br, dest)) != NULL)
46 br_deliver(dst->dst, skb); 46 br_deliver(dst->dst, skb);
47 else 47 else
48 br_flood_deliver(br, skb, 0); 48 br_flood_deliver(br, skb);
49 49
50 return 0; 50 return 0;
51} 51}
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index ada7f495445c..bdd7c35c3c7b 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -100,24 +100,13 @@ void br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
100} 100}
101 101
102/* called under bridge lock */ 102/* called under bridge lock */
103static void br_flood(struct net_bridge *br, struct sk_buff *skb, int clone, 103static void br_flood(struct net_bridge *br, struct sk_buff *skb,
104 void (*__packet_hook)(const struct net_bridge_port *p, 104 void (*__packet_hook)(const struct net_bridge_port *p,
105 struct sk_buff *skb)) 105 struct sk_buff *skb))
106{ 106{
107 struct net_bridge_port *p; 107 struct net_bridge_port *p;
108 struct net_bridge_port *prev; 108 struct net_bridge_port *prev;
109 109
110 if (clone) {
111 struct sk_buff *skb2;
112
113 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) {
114 br->statistics.tx_dropped++;
115 return;
116 }
117
118 skb = skb2;
119 }
120
121 prev = NULL; 110 prev = NULL;
122 111
123 list_for_each_entry_rcu(p, &br->port_list, list) { 112 list_for_each_entry_rcu(p, &br->port_list, list) {
@@ -148,13 +137,13 @@ static void br_flood(struct net_bridge *br, struct sk_buff *skb, int clone,
148 137
149 138
150/* called with rcu_read_lock */ 139/* called with rcu_read_lock */
151void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, int clone) 140void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb)
152{ 141{
153 br_flood(br, skb, clone, __br_deliver); 142 br_flood(br, skb, __br_deliver);
154} 143}
155 144
156/* called under bridge lock */ 145/* called under bridge lock */
157void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, int clone) 146void br_flood_forward(struct net_bridge *br, struct sk_buff *skb)
158{ 147{
159 br_flood(br, skb, clone, __br_forward); 148 br_flood(br, skb, __br_forward);
160} 149}
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
92out: 88out:
93 return 0; 89 return 0;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 21bf3a9a03fd..e6dc6f52990d 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -170,12 +170,8 @@ extern int br_dev_queue_push_xmit(struct sk_buff *skb);
170extern void br_forward(const struct net_bridge_port *to, 170extern void br_forward(const struct net_bridge_port *to,
171 struct sk_buff *skb); 171 struct sk_buff *skb);
172extern int br_forward_finish(struct sk_buff *skb); 172extern int br_forward_finish(struct sk_buff *skb);
173extern void br_flood_deliver(struct net_bridge *br, 173extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb);
174 struct sk_buff *skb, 174extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb);
175 int clone);
176extern void br_flood_forward(struct net_bridge *br,
177 struct sk_buff *skb,
178 int clone);
179 175
180/* br_if.c */ 176/* br_if.c */
181extern void br_port_carrier_check(struct net_bridge_port *p); 177extern void br_port_carrier_check(struct net_bridge_port *p);