[v4] batman-adv: Fix broadcast duplist for fragmentation
Commit Message
If the skb is fragmented, the checksum must be computed on the
individual fragments, just using skb->data may fail on fragmented
data. Instead of doing linearizing the packet, use the new
batadv_crc32 to do that more efficiently- it should not hurt
replacing the old crc16 by the new crc32.
Reported-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
PATCHv2: change uint32_t to __be32
PATCHv3: this time also changed in types.h
PATCHv4: also compile if bla is disabled
---
bridge_loop_avoidance.c | 18 +++++++-----------
bridge_loop_avoidance.h | 6 ++----
routing.c | 10 +++-------
types.h | 2 +-
4 files changed, 13 insertions(+), 23 deletions(-)
Comments
On Thursday, October 18, 2012 19:47:42 Simon Wunderlich wrote:
> If the skb is fragmented, the checksum must be computed on the
> individual fragments, just using skb->data may fail on fragmented
> data. Instead of doing linearizing the packet, use the new
> batadv_crc32 to do that more efficiently- it should not hurt
> replacing the old crc16 by the new crc32.
>
> Reported-by: Sven Eckelmann <sven@narfation.org>
> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
> ---
> PATCHv2: change uint32_t to __be32
> PATCHv3: this time also changed in types.h
> PATCHv4: also compile if bla is disabled
> ---
> bridge_loop_avoidance.c | 18 +++++++-----------
> bridge_loop_avoidance.h | 6 ++----
> routing.c | 10 +++-------
> types.h | 2 +-
> 4 files changed, 13 insertions(+), 23 deletions(-)
Applied in revision da14489.
Thanks,
Marek
@@ -1249,8 +1249,7 @@ 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: encapsulated broadcast frame plus batman header
- * @bcast_packet_len: length of encapsulated broadcast frame plus batman header
+ * @skb: contains the bcast_packet to be checked
*
* check if it is on our broadcast list. Another gateway might
* have sent the same packet because it is connected to the same backbone,
@@ -1262,20 +1261,17 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
* the same host however as this might be intended.
*/
int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
- struct batadv_bcast_packet *bcast_packet,
- int bcast_packet_len)
+ struct sk_buff *skb)
{
- int i, length, curr, ret = 0;
- uint8_t *content;
- uint16_t crc;
+ int i, curr, ret = 0;
+ __be32 crc;
+ struct batadv_bcast_packet *bcast_packet;
struct batadv_bcast_duplist_entry *entry;
- length = bcast_packet_len - sizeof(*bcast_packet);
- content = (uint8_t *)bcast_packet;
- content += sizeof(*bcast_packet);
+ bcast_packet = (struct batadv_bcast_packet *)skb->data;
/* calculate the crc ... */
- crc = crc16(0, content, length);
+ crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
@@ -31,8 +31,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
void *offset);
int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig);
int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
- struct batadv_bcast_packet *bcast_packet,
- int hdr_size);
+ struct sk_buff *skb);
void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
struct batadv_hard_iface *primary_if,
struct batadv_hard_iface *oldif);
@@ -81,8 +80,7 @@ static inline int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv,
static inline int
batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
- struct batadv_bcast_packet *bcast_packet,
- int hdr_size)
+ struct sk_buff *skb)
{
return 0;
}
@@ -1181,16 +1181,12 @@ 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, skb->len))
+ if (batadv_bla_check_bcast_duplist(bat_priv, skb))
goto out;
+ bcast_packet = (struct batadv_bcast_packet *)skb->data;
+
/* rebroadcast packet */
batadv_add_bcast_packet_to_list(bat_priv, skb, 1);
@@ -156,7 +156,7 @@ struct batadv_neigh_node {
#ifdef CONFIG_BATMAN_ADV_BLA
struct batadv_bcast_duplist_entry {
uint8_t orig[ETH_ALEN];
- uint16_t crc;
+ __be32 crc;
unsigned long entrytime;
};
#endif