[01/11] batman-adv: don't rely on positions in struct for hashing

Message ID 1352798139-19458-2-git-send-email-ordex@autistici.org (mailing list archive)
State Not Applicable, archived
Headers

Commit Message

Antonio Quartulli Nov. 13, 2012, 9:15 a.m. UTC
  From: Simon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>

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>
---
 net/batman-adv/bridge_loop_avoidance.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)
  

Comments

David Miller Nov. 13, 2012, 7:24 p.m. UTC | #1
From: Antonio Quartulli <ordex@autistici.org>
Date: Tue, 13 Nov 2012 10:15:29 +0100

> @@ -37,18 +37,26 @@ static void batadv_bla_periodic_work(struct work_struct *work);
>  static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
>  				     struct batadv_backbone_gw *backbone_gw);
>  
> +static inline void hash_bytes(uint32_t *hash, void *data, uint32_t size)
> +{
> +	const unsigned char *key = data;
> +	int i;
> +
> +	for (i = 0; i < size; i++) {
> +		*hash += key[i];
> +		*hash += (*hash << 10);
> +		*hash ^= (*hash >> 6);
> +	}
> +}
> +

Remove the inline tag.

Return the uint32_t resulting hash value rather than passing it by
reference.
  

Patch

diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 29a5542..decc042 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -37,18 +37,26 @@  static void batadv_bla_periodic_work(struct work_struct *work);
 static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
 				     struct batadv_backbone_gw *backbone_gw);
 
+static inline void hash_bytes(uint32_t *hash, void *data, uint32_t size)
+{
+	const unsigned char *key = data;
+	int i;
+
+	for (i = 0; i < size; i++) {
+		*hash += key[i];
+		*hash += (*hash << 10);
+		*hash ^= (*hash >> 6);
+	}
+}
+
 /* return the index of the claim */
 static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
 {
-	const unsigned char *key = data;
+	struct batadv_claim *claim = (struct batadv_claim *)data;
 	uint32_t hash = 0;
-	size_t i;
 
-	for (i = 0; i < ETH_ALEN + sizeof(short); i++) {
-		hash += key[i];
-		hash += (hash << 10);
-		hash ^= (hash >> 6);
-	}
+	hash_bytes(&hash, &claim->addr, sizeof(claim->addr));
+	hash_bytes(&hash, &claim->vid, sizeof(claim->vid));
 
 	hash += (hash << 3);
 	hash ^= (hash >> 11);
@@ -61,15 +69,11 @@  static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
 static inline uint32_t batadv_choose_backbone_gw(const void *data,
 						 uint32_t size)
 {
-	const unsigned char *key = data;
+	struct batadv_claim *claim = (struct batadv_claim *)data;
 	uint32_t hash = 0;
-	size_t i;
 
-	for (i = 0; i < ETH_ALEN + sizeof(short); i++) {
-		hash += key[i];
-		hash += (hash << 10);
-		hash ^= (hash >> 6);
-	}
+	hash_bytes(&hash, &claim->addr, sizeof(claim->addr));
+	hash_bytes(&hash, &claim->vid, sizeof(claim->vid));
 
 	hash += (hash << 3);
 	hash ^= (hash >> 11);