aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>2012-08-30 12:22:27 -0400
committerAntonio Quartulli <ordex@autistici.org>2012-11-14 15:00:32 -0500
commit07568d0369f93cd54d2e5ca6f5c64f5b55557857 (patch)
treef30f4188b200b9cdb1d3b68d52f1d791e4791ac3
parentbf0098f22ca7b59e8844ac6882bbae230d34b98d (diff)
batman-adv: don't rely on positions in struct for hashing
The hash functions in the bridge loop avoidance code expects the VLAN vid to be right after the mac address, but this is not guaranteed. Fix this by explicitly hashing over the right fields of the struct. Reported-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> Signed-off-by: Antonio Quartulli <ordex@autistici.org>
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c20
-rw-r--r--net/batman-adv/hash.h22
2 files changed, 28 insertions, 14 deletions
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 29a5542aac75..49c35a60195a 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -40,15 +40,11 @@ static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
40/* return the index of the claim */ 40/* return the index of the claim */
41static inline uint32_t batadv_choose_claim(const void *data, uint32_t size) 41static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
42{ 42{
43 const unsigned char *key = data; 43 struct batadv_claim *claim = (struct batadv_claim *)data;
44 uint32_t hash = 0; 44 uint32_t hash = 0;
45 size_t i;
46 45
47 for (i = 0; i < ETH_ALEN + sizeof(short); i++) { 46 hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
48 hash += key[i]; 47 hash = batadv_hash_bytes(hash, &claim->vid, sizeof(claim->vid));
49 hash += (hash << 10);
50 hash ^= (hash >> 6);
51 }
52 48
53 hash += (hash << 3); 49 hash += (hash << 3);
54 hash ^= (hash >> 11); 50 hash ^= (hash >> 11);
@@ -61,15 +57,11 @@ static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
61static inline uint32_t batadv_choose_backbone_gw(const void *data, 57static inline uint32_t batadv_choose_backbone_gw(const void *data,
62 uint32_t size) 58 uint32_t size)
63{ 59{
64 const unsigned char *key = data; 60 struct batadv_claim *claim = (struct batadv_claim *)data;
65 uint32_t hash = 0; 61 uint32_t hash = 0;
66 size_t i;
67 62
68 for (i = 0; i < ETH_ALEN + sizeof(short); i++) { 63 hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
69 hash += key[i]; 64 hash = batadv_hash_bytes(hash, &claim->vid, sizeof(claim->vid));
70 hash += (hash << 10);
71 hash ^= (hash >> 6);
72 }
73 65
74 hash += (hash << 3); 66 hash += (hash << 3);
75 hash ^= (hash >> 11); 67 hash ^= (hash >> 11);
diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h
index 977de9c75fc2..e05333905afd 100644
--- a/net/batman-adv/hash.h
+++ b/net/batman-adv/hash.h
@@ -82,6 +82,28 @@ static inline void batadv_hash_delete(struct batadv_hashtable *hash,
82} 82}
83 83
84/** 84/**
85 * batadv_hash_bytes - hash some bytes and add them to the previous hash
86 * @hash: previous hash value
87 * @data: data to be hashed
88 * @size: number of bytes to be hashed
89 *
90 * Returns the new hash value.
91 */
92static inline uint32_t batadv_hash_bytes(uint32_t hash, void *data,
93 uint32_t size)
94{
95 const unsigned char *key = data;
96 int i;
97
98 for (i = 0; i < size; i++) {
99 hash += key[i];
100 hash += (hash << 10);
101 hash ^= (hash >> 6);
102 }
103 return hash;
104}
105
106/**
85 * batadv_hash_add - adds data to the hashtable 107 * batadv_hash_add - adds data to the hashtable
86 * @hash: storage hash table 108 * @hash: storage hash table
87 * @compare: callback to determine if 2 hash elements are identical 109 * @compare: callback to determine if 2 hash elements are identical