aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_fdb.c
diff options
context:
space:
mode:
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>2009-06-05 01:35:28 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-12 00:03:21 -0400
commitda6782927de809d9d427bd4bd6a4024243e41f13 (patch)
tree79419b352017a0c125c2b17e6a170589b31d8cb3 /net/bridge/br_fdb.c
parent746e6ad23cd6fec2edce056e014a0eabeffa838c (diff)
bridge: Simplify interface for ATM LANE
This patch changes FDB entry check for ATM LANE bridge integration. There's no point in holding a FDB entry around SKB building. br_fdb_get()/br_fdb_put() pair are changed into single br_fdb_test_addr() hook that checks if the addr has FDB entry pointing to other port to the one the request arrived on. FDB entry refcounting is removed as it's not used anywhere else. Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl> Acked-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_fdb.c')
-rw-r--r--net/bridge/br_fdb.c43
1 files changed, 21 insertions, 22 deletions
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index cb3e97b93aeb..57bf05c353bc 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -71,10 +71,17 @@ static inline int br_mac_hash(const unsigned char *mac)
71 return jhash_1word(key, fdb_salt) & (BR_HASH_SIZE - 1); 71 return jhash_1word(key, fdb_salt) & (BR_HASH_SIZE - 1);
72} 72}
73 73
74static void fdb_rcu_free(struct rcu_head *head)
75{
76 struct net_bridge_fdb_entry *ent
77 = container_of(head, struct net_bridge_fdb_entry, rcu);
78 kmem_cache_free(br_fdb_cache, ent);
79}
80
74static inline void fdb_delete(struct net_bridge_fdb_entry *f) 81static inline void fdb_delete(struct net_bridge_fdb_entry *f)
75{ 82{
76 hlist_del_rcu(&f->hlist); 83 hlist_del_rcu(&f->hlist);
77 br_fdb_put(f); 84 call_rcu(&f->rcu, fdb_rcu_free);
78} 85}
79 86
80void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) 87void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
@@ -226,33 +233,26 @@ struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
226 return NULL; 233 return NULL;
227} 234}
228 235
229/* Interface used by ATM hook that keeps a ref count */ 236#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
230struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br, 237/* Interface used by ATM LANE hook to test
231 unsigned char *addr) 238 * if an addr is on some other bridge port */
239int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
232{ 240{
233 struct net_bridge_fdb_entry *fdb; 241 struct net_bridge_fdb_entry *fdb;
242 int ret;
243
244 if (!dev->br_port)
245 return 0;
234 246
235 rcu_read_lock(); 247 rcu_read_lock();
236 fdb = __br_fdb_get(br, addr); 248 fdb = __br_fdb_get(dev->br_port->br, addr);
237 if (fdb && !atomic_inc_not_zero(&fdb->use_count)) 249 ret = fdb && fdb->dst->dev != dev &&
238 fdb = NULL; 250 fdb->dst->state == BR_STATE_FORWARDING;
239 rcu_read_unlock(); 251 rcu_read_unlock();
240 return fdb;
241}
242
243static void fdb_rcu_free(struct rcu_head *head)
244{
245 struct net_bridge_fdb_entry *ent
246 = container_of(head, struct net_bridge_fdb_entry, rcu);
247 kmem_cache_free(br_fdb_cache, ent);
248}
249 252
250/* Set entry up for deletion with RCU */ 253 return ret;
251void br_fdb_put(struct net_bridge_fdb_entry *ent)
252{
253 if (atomic_dec_and_test(&ent->use_count))
254 call_rcu(&ent->rcu, fdb_rcu_free);
255} 254}
255#endif /* CONFIG_ATM_LANE */
256 256
257/* 257/*
258 * Fill buffer with forwarding table records in 258 * Fill buffer with forwarding table records in
@@ -326,7 +326,6 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head,
326 fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); 326 fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC);
327 if (fdb) { 327 if (fdb) {
328 memcpy(fdb->addr.addr, addr, ETH_ALEN); 328 memcpy(fdb->addr.addr, addr, ETH_ALEN);
329 atomic_set(&fdb->use_count, 1);
330 hlist_add_head_rcu(&fdb->hlist, head); 329 hlist_add_head_rcu(&fdb->hlist, head);
331 330
332 fdb->dst = source; 331 fdb->dst = source;