Skip to content

Commit

Permalink
bridge: simpler hash with salt
Browse files Browse the repository at this point in the history
Instead of hashing the whole Ethernet address, it should be faster
to just use the last 4 bytes. Add a random salt value to the hash
to make it more difficult to construct worst case DoS hash chains.

Signed-off-by: Stephen Hemminger <[email protected]>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Apr 26, 2007
1 parent 467aea0 commit 3f89092
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions net/bridge/br_fdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,24 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/jhash.h>
#include <linux/random.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
#include "br_private.h"

static struct kmem_cache *br_fdb_cache __read_mostly;
static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
const unsigned char *addr);

static u32 fdb_salt __read_mostly;

void __init br_fdb_init(void)
{
br_fdb_cache = kmem_cache_create("bridge_fdb_cache",
sizeof(struct net_bridge_fdb_entry),
0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
get_random_bytes(&fdb_salt, sizeof(fdb_salt));
}

void __exit br_fdb_fini(void)
Expand All @@ -44,24 +49,26 @@ void __exit br_fdb_fini(void)
/* if topology_changing then use forward_delay (default 15 sec)
* otherwise keep longer (default 5 minutes)
*/
static __inline__ unsigned long hold_time(const struct net_bridge *br)
static inline unsigned long hold_time(const struct net_bridge *br)
{
return br->topology_change ? br->forward_delay : br->ageing_time;
}

static __inline__ int has_expired(const struct net_bridge *br,
static inline int has_expired(const struct net_bridge *br,
const struct net_bridge_fdb_entry *fdb)
{
return !fdb->is_static
&& time_before_eq(fdb->ageing_timer + hold_time(br), jiffies);
}

static __inline__ int br_mac_hash(const unsigned char *mac)
static inline int br_mac_hash(const unsigned char *mac)
{
return jhash(mac, ETH_ALEN, 0) & (BR_HASH_SIZE - 1);
/* use 1 byte of OUI cnd 3 bytes of NIC */
u32 key = get_unaligned((u32 *)(mac + 2));
return jhash_1word(key, fdb_salt) & (BR_HASH_SIZE - 1);
}

static __inline__ void fdb_delete(struct net_bridge_fdb_entry *f)
static inline void fdb_delete(struct net_bridge_fdb_entry *f)
{
hlist_del_rcu(&f->hlist);
br_fdb_put(f);
Expand Down

0 comments on commit 3f89092

Please sign in to comment.