]>
Commit | Line | Data |
---|---|---|
1d6cf50a GKH |
1 | From 7f112af40fecf5399b61e69ffc6b55a9d82789f7 Mon Sep 17 00:00:00 2001 |
2 | From: Linus Lüssing <linus.luessing@web.de> | |
3 | Date: Wed, 17 Oct 2012 14:53:04 +0200 | |
4 | Subject: batman-adv: Fix broadcast packet CRC calculation | |
5 | ||
6 | From: Linus Lüssing <linus.luessing@web.de> | |
7 | ||
8 | commit 7f112af40fecf5399b61e69ffc6b55a9d82789f7 upstream. | |
9 | ||
10 | So far the crc16 checksum for a batman-adv broadcast data packet, received | |
11 | on a batman-adv hard interface, was calculated over zero bytes of its | |
12 | content leading to many incoming broadcast data packets wrongly being | |
13 | dropped (60-80% packet loss). | |
14 | ||
15 | This patch fixes this issue by calculating the crc16 over the actual, | |
16 | complete broadcast payload. | |
17 | ||
18 | The issue is a regression introduced by | |
19 | ("batman-adv: add broadcast duplicate check"). | |
20 | ||
21 | Signed-off-by: Linus Lüssing <linus.luessing@web.de> | |
22 | Acked-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> | |
23 | Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> | |
24 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
25 | ||
26 | --- | |
27 | net/batman-adv/bridge_loop_avoidance.c | 8 ++++---- | |
28 | net/batman-adv/routing.c | 8 +++++++- | |
29 | 2 files changed, 11 insertions(+), 5 deletions(-) | |
30 | ||
31 | --- a/net/batman-adv/bridge_loop_avoidance.c | |
32 | +++ b/net/batman-adv/bridge_loop_avoidance.c | |
33 | @@ -1205,8 +1205,8 @@ int batadv_bla_init(struct batadv_priv * | |
34 | /** | |
35 | * batadv_bla_check_bcast_duplist | |
36 | * @bat_priv: the bat priv with all the soft interface information | |
37 | - * @bcast_packet: originator mac address | |
38 | - * @hdr_size: maximum length of the frame | |
39 | + * @bcast_packet: encapsulated broadcast frame plus batman header | |
40 | + * @bcast_packet_len: length of encapsulated broadcast frame plus batman header | |
41 | * | |
42 | * check if it is on our broadcast list. Another gateway might | |
43 | * have sent the same packet because it is connected to the same backbone, | |
44 | @@ -1219,14 +1219,14 @@ int batadv_bla_init(struct batadv_priv * | |
45 | */ | |
46 | int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | |
47 | struct batadv_bcast_packet *bcast_packet, | |
48 | - int hdr_size) | |
49 | + int bcast_packet_len) | |
50 | { | |
51 | int i, length, curr; | |
52 | uint8_t *content; | |
53 | uint16_t crc; | |
54 | struct batadv_bcast_duplist_entry *entry; | |
55 | ||
56 | - length = hdr_size - sizeof(*bcast_packet); | |
57 | + length = bcast_packet_len - sizeof(*bcast_packet); | |
58 | content = (uint8_t *)bcast_packet; | |
59 | content += sizeof(*bcast_packet); | |
60 | ||
61 | --- a/net/batman-adv/routing.c | |
62 | +++ b/net/batman-adv/routing.c | |
63 | @@ -1136,8 +1136,14 @@ int batadv_recv_bcast_packet(struct sk_b | |
64 | ||
65 | spin_unlock_bh(&orig_node->bcast_seqno_lock); | |
66 | ||
67 | + /* keep skb linear for crc calculation */ | |
68 | + if (skb_linearize(skb) < 0) | |
69 | + goto out; | |
70 | + | |
71 | + bcast_packet = (struct batadv_bcast_packet *)skb->data; | |
72 | + | |
73 | /* check whether this has been sent by another originator before */ | |
74 | - if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size)) | |
75 | + if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len)) | |
76 | goto out; | |
77 | ||
78 | /* rebroadcast packet */ |