aboutsummaryrefslogtreecommitdiff
path: root/net/bridge/br_fdb.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-06-17 12:52:15 +0200
committerIngo Molnar <mingo@elte.hu>2009-06-17 12:56:49 +0200
commiteadb8a091b27a840de7450f84ecff5ef13476424 (patch)
tree58c3782d40def63baa8167f3d31e3048cb4c7660 /net/bridge/br_fdb.c
parent73874005cd8800440be4299bd095387fff4b90ac (diff)
parent65795efbd380a832ae508b04dba8f8e53f0b84d9 (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.c45
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 */