Skip to content

Commit 3f89092

Browse files
Stephen HemmingerDavid S. Miller
authored andcommitted
bridge: simpler hash with salt
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]>
1 parent 467aea0 commit 3f89092

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

net/bridge/br_fdb.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,24 @@
2020
#include <linux/netdevice.h>
2121
#include <linux/etherdevice.h>
2222
#include <linux/jhash.h>
23+
#include <linux/random.h>
2324
#include <asm/atomic.h>
25+
#include <asm/unaligned.h>
2426
#include "br_private.h"
2527

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

32+
static u32 fdb_salt __read_mostly;
33+
3034
void __init br_fdb_init(void)
3135
{
3236
br_fdb_cache = kmem_cache_create("bridge_fdb_cache",
3337
sizeof(struct net_bridge_fdb_entry),
3438
0,
3539
SLAB_HWCACHE_ALIGN, NULL, NULL);
40+
get_random_bytes(&fdb_salt, sizeof(fdb_salt));
3641
}
3742

3843
void __exit br_fdb_fini(void)
@@ -44,24 +49,26 @@ void __exit br_fdb_fini(void)
4449
/* if topology_changing then use forward_delay (default 15 sec)
4550
* otherwise keep longer (default 5 minutes)
4651
*/
47-
static __inline__ unsigned long hold_time(const struct net_bridge *br)
52+
static inline unsigned long hold_time(const struct net_bridge *br)
4853
{
4954
return br->topology_change ? br->forward_delay : br->ageing_time;
5055
}
5156

52-
static __inline__ int has_expired(const struct net_bridge *br,
57+
static inline int has_expired(const struct net_bridge *br,
5358
const struct net_bridge_fdb_entry *fdb)
5459
{
5560
return !fdb->is_static
5661
&& time_before_eq(fdb->ageing_timer + hold_time(br), jiffies);
5762
}
5863

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

64-
static __inline__ void fdb_delete(struct net_bridge_fdb_entry *f)
71+
static inline void fdb_delete(struct net_bridge_fdb_entry *f)
6572
{
6673
hlist_del_rcu(&f->hlist);
6774
br_fdb_put(f);

0 commit comments

Comments
 (0)