| From foo@baz Thu Feb 27 20:11:26 PST 2014 |
| From: Antonio Quartulli <antonio@open-mesh.com> |
| Date: Tue, 11 Feb 2014 17:05:06 +0100 |
| Subject: batman-adv: fix TT CRC computation by ensuring byte order |
| |
| From: Antonio Quartulli <antonio@open-mesh.com> |
| |
| [ Upstream commit a30e22ca8464c2dc573e0144a972221c2f06c2cd ] |
| |
| When computing the CRC on a 2byte variable the order of |
| the bytes obviously alters the final result. This means |
| that computing the CRC over the same value on two archs |
| having different endianess leads to different numbers. |
| |
| The global and local translation table CRC computation |
| routine makes this mistake while processing the clients |
| VIDs. The result is a continuous CRC mismatching between |
| nodes having different endianess. |
| |
| Fix this by converting the VID to Network Order before |
| processing it. This guarantees that every node uses the same |
| byte order. |
| |
| Introduced by 7ea7b4a142758deaf46c1af0ca9ceca6dd55138b |
| ("batman-adv: make the TT CRC logic VLAN specific") |
| |
| Reported-by: Russel Senior <russell@personaltelco.net> |
| Signed-off-by: Antonio Quartulli <antonio@open-mesh.com> |
| Tested-by: Russell Senior <russell@personaltelco.net> |
| Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/batman-adv/translation-table.c | 16 ++++++++++++---- |
| 1 file changed, 12 insertions(+), 4 deletions(-) |
| |
| --- a/net/batman-adv/translation-table.c |
| +++ b/net/batman-adv/translation-table.c |
| @@ -1961,6 +1961,7 @@ static uint32_t batadv_tt_global_crc(str |
| struct hlist_head *head; |
| uint32_t i, crc_tmp, crc = 0; |
| uint8_t flags; |
| + __be16 tmp_vid; |
| |
| for (i = 0; i < hash->size; i++) { |
| head = &hash->table[i]; |
| @@ -1997,8 +1998,11 @@ static uint32_t batadv_tt_global_crc(str |
| orig_node)) |
| continue; |
| |
| - crc_tmp = crc32c(0, &tt_common->vid, |
| - sizeof(tt_common->vid)); |
| + /* use network order to read the VID: this ensures that |
| + * every node reads the bytes in the same order. |
| + */ |
| + tmp_vid = htons(tt_common->vid); |
| + crc_tmp = crc32c(0, &tmp_vid, sizeof(tmp_vid)); |
| |
| /* compute the CRC on flags that have to be kept in sync |
| * among nodes |
| @@ -2032,6 +2036,7 @@ static uint32_t batadv_tt_local_crc(stru |
| struct hlist_head *head; |
| uint32_t i, crc_tmp, crc = 0; |
| uint8_t flags; |
| + __be16 tmp_vid; |
| |
| for (i = 0; i < hash->size; i++) { |
| head = &hash->table[i]; |
| @@ -2050,8 +2055,11 @@ static uint32_t batadv_tt_local_crc(stru |
| if (tt_common->flags & BATADV_TT_CLIENT_NEW) |
| continue; |
| |
| - crc_tmp = crc32c(0, &tt_common->vid, |
| - sizeof(tt_common->vid)); |
| + /* use network order to read the VID: this ensures that |
| + * every node reads the bytes in the same order. |
| + */ |
| + tmp_vid = htons(tt_common->vid); |
| + crc_tmp = crc32c(0, &tmp_vid, sizeof(tmp_vid)); |
| |
| /* compute the CRC on flags that have to be kept in sync |
| * among nodes |