--- zzzz-none-000/linux-2.4.17/net/bridge/br_fdb.c 2000-11-09 23:57:53.000000000 +0000 +++ sangam-fb-401/linux-2.4.17/net/bridge/br_fdb.c 2005-09-20 12:59:20.000000000 +0000 @@ -5,7 +5,7 @@ * Authors: * Lennert Buytenhek * - * $Id: br_fdb.c,v 1.5 2000/11/08 05:16:40 davem Exp $ + * $Id: br_fdb.c,v 1.1.1.1 2002/03/18 15:12:19 jharrell Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -56,6 +56,11 @@ { unsigned long x; +#ifdef AVM_FAST_HASH + u16 *p = (u16 *)mac; + x = *p + *(p+1) + *(p+2); + x = x + (x >> 8); +#else x = mac[0]; x = (x << 2) ^ mac[1]; x = (x << 2) ^ mac[2]; @@ -64,6 +69,7 @@ x = (x << 2) ^ mac[5]; x ^= x >> 8; +#endif return x & (BR_HASH_SIZE - 1); } @@ -165,6 +171,32 @@ write_unlock_bh(&br->hash_lock); } +/* UDO */ +void br_fdb_delete_by_mac_if_local_without_port(struct net_bridge *br, unsigned char *addr) +{ + int i; + + write_lock_bh(&br->hash_lock); + for (i=0;ihash[i]; + while (f != NULL) { + struct net_bridge_fdb_entry *g; + + g = f->next_hash; + if (f->dst == 0 && f->is_local && !memcmp(f->addr.addr, addr, ETH_ALEN)) { + __hash_unlink(f); + br_fdb_put(f); + goto end; + } + f = g; + } + } +end: + write_unlock_bh(&br->hash_lock); +} + struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br, unsigned char *addr) { struct net_bridge_fdb_entry *fdb; @@ -172,7 +204,14 @@ read_lock_bh(&br->hash_lock); fdb = br->hash[br_mac_hash(addr)]; while (fdb != NULL) { + +#if defined (CONFIG_MIPS_AVALANCHE_FAST_BRIDGE) + + if ( (*((short *)fdb->addr.addr) == *((short *)addr)) && ((*(short *)(((char *)fdb->addr.addr + 2))) == (*(short *)(addr + 2))) + && ((*(short *)(((char *)fdb->addr.addr + 4))) == (*(short *)(addr + 4))) ) { +#else if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) { +#endif if (!has_expired(br, fdb)) { atomic_inc(&fdb->use_count); read_unlock_bh(&br->hash_lock); @@ -272,7 +311,9 @@ int is_local) { if (!fdb->is_static || is_local) { - fdb->dst = source; + /* UDO - don't overwrite fdb->dst with 0 if it is a local entry */ + if (source != 0 || !fdb->is_local) + fdb->dst = source; fdb->is_local = is_local; fdb->is_static = is_local; fdb->ageing_timer = jiffies;