From: Linus Lüssing Date: Wed, 17 Oct 2012 12:53:04 +0000 (+0200) Subject: batman-adv: Fix broadcast packet CRC calculation X-Git-Tag: v3.6.7~36 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=d736f6b4c9b302f5a4712ca81d06f8a9cd07a658;p=karo-tx-linux.git batman-adv: Fix broadcast packet CRC calculation commit 7f112af40fecf5399b61e69ffc6b55a9d82789f7 upstream. So far the crc16 checksum for a batman-adv broadcast data packet, received on a batman-adv hard interface, was calculated over zero bytes of its content leading to many incoming broadcast data packets wrongly being dropped (60-80% packet loss). This patch fixes this issue by calculating the crc16 over the actual, complete broadcast payload. The issue is a regression introduced by ("batman-adv: add broadcast duplicate check"). Signed-off-by: Linus Lüssing Acked-by: Simon Wunderlich Signed-off-by: Marek Lindner Signed-off-by: Greg Kroah-Hartman --- diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 6705d35b17ce..e7b577743192 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1205,8 +1205,8 @@ int batadv_bla_init(struct batadv_priv *bat_priv) /** * batadv_bla_check_bcast_duplist * @bat_priv: the bat priv with all the soft interface information - * @bcast_packet: originator mac address - * @hdr_size: maximum length of the frame + * @bcast_packet: encapsulated broadcast frame plus batman header + * @bcast_packet_len: length of encapsulated broadcast frame plus batman header * * check if it is on our broadcast list. Another gateway might * have sent the same packet because it is connected to the same backbone, @@ -1219,14 +1219,14 @@ int batadv_bla_init(struct batadv_priv *bat_priv) */ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, struct batadv_bcast_packet *bcast_packet, - int hdr_size) + int bcast_packet_len) { int i, length, curr; uint8_t *content; uint16_t crc; struct batadv_bcast_duplist_entry *entry; - length = hdr_size - sizeof(*bcast_packet); + length = bcast_packet_len - sizeof(*bcast_packet); content = (uint8_t *)bcast_packet; content += sizeof(*bcast_packet); diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index bc2b88bbea1f..f861b7c2310a 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -1136,8 +1136,14 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, spin_unlock_bh(&orig_node->bcast_seqno_lock); + /* keep skb linear for crc calculation */ + if (skb_linearize(skb) < 0) + goto out; + + bcast_packet = (struct batadv_bcast_packet *)skb->data; + /* check whether this has been sent by another originator before */ - if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size)) + if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len)) goto out; /* rebroadcast packet */