diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-06-17 12:52:15 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-17 12:56:49 +0200 |
commit | eadb8a091b27a840de7450f84ecff5ef13476424 (patch) | |
tree | 58c3782d40def63baa8167f3d31e3048cb4c7660 /net/bridge/br_fdb.c | |
parent | 73874005cd8800440be4299bd095387fff4b90ac (diff) | |
parent | 65795efbd380a832ae508b04dba8f8e53f0b84d9 (diff) |
Merge branch 'linus' into tracing/hw-breakpoints
Conflicts:
arch/x86/Kconfig
arch/x86/kernel/traps.c
arch/x86/power/cpu.c
arch/x86/power/cpu_32.c
kernel/Makefile
Semantic conflict:
arch/x86/kernel/hw_breakpoint.c
Merge reason: Resolve the conflicts, move from put_cpu_no_sched() to
put_cpu() in arch/x86/kernel/hw_breakpoint.c.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net/bridge/br_fdb.c')
-rw-r--r-- | net/bridge/br_fdb.c | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index a48f5efdb6b..57bf05c353b 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) return jhash_1word(key, fdb_salt) & (BR_HASH_SIZE - 1); } +static void fdb_rcu_free(struct rcu_head *head) +{ + struct net_bridge_fdb_entry *ent + = container_of(head, struct net_bridge_fdb_entry, rcu); + kmem_cache_free(br_fdb_cache, ent); +} + static inline void fdb_delete(struct net_bridge_fdb_entry *f) { hlist_del_rcu(&f->hlist); - br_fdb_put(f); + call_rcu(&f->rcu, fdb_rcu_free); } void 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, return NULL; } -/* Interface used by ATM hook that keeps a ref count */ -struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br, - unsigned char *addr) +#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) +/* Interface used by ATM LANE hook to test + * if an addr is on some other bridge port */ +int br_fdb_test_addr(struct net_device *dev, unsigned char *addr) { struct net_bridge_fdb_entry *fdb; + int ret; + + if (!dev->br_port) + return 0; rcu_read_lock(); - fdb = __br_fdb_get(br, addr); - if (fdb && !atomic_inc_not_zero(&fdb->use_count)) - fdb = NULL; + fdb = __br_fdb_get(dev->br_port->br, addr); + ret = fdb && fdb->dst->dev != dev && + fdb->dst->state == BR_STATE_FORWARDING; rcu_read_unlock(); - return fdb; -} - -static void fdb_rcu_free(struct rcu_head *head) -{ - struct net_bridge_fdb_entry *ent - = container_of(head, struct net_bridge_fdb_entry, rcu); - kmem_cache_free(br_fdb_cache, ent); -} -/* Set entry up for deletion with RCU */ -void br_fdb_put(struct net_bridge_fdb_entry *ent) -{ - if (atomic_dec_and_test(&ent->use_count)) - call_rcu(&ent->rcu, fdb_rcu_free); + return ret; } +#endif /* CONFIG_ATM_LANE */ /* * Fill buffer with forwarding table records in @@ -326,7 +326,6 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); if (fdb) { memcpy(fdb->addr.addr, addr, ETH_ALEN); - atomic_set(&fdb->use_count, 1); hlist_add_head_rcu(&fdb->hlist, head); fdb->dst = source; @@ -398,7 +397,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, if (unlikely(fdb->is_local)) { if (net_ratelimit()) printk(KERN_WARNING "%s: received packet with " - " own address as source address\n", + "own address as source address\n", source->dev->name); } else { /* fastpath: update of existing entry */ |