diff options
author | Simon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de> | 2012-10-18 07:47:42 -0400 |
---|---|---|
committer | Antonio Quartulli <ordex@autistici.org> | 2012-11-21 06:35:45 -0500 |
commit | 004e86fc585f617f07bff38480eeee335be9b017 (patch) | |
tree | 6155b18b4f9b14105dbde5330c53f30adac7e6bf | |
parent | 95a066d82c422c812c10bfd4de01225b1714fa45 (diff) |
batman-adv: Fix broadcast duplist for fragmentation
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>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
-rw-r--r-- | net/batman-adv/bridge_loop_avoidance.c | 18 | ||||
-rw-r--r-- | net/batman-adv/bridge_loop_avoidance.h | 6 | ||||
-rw-r--r-- | net/batman-adv/routing.c | 8 | ||||
-rw-r--r-- | net/batman-adv/types.h | 2 |
4 files changed, 11 insertions, 23 deletions
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 7ffef8b2d4cd..5aebe9327d68 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
@@ -1249,8 +1249,7 @@ int batadv_bla_init(struct batadv_priv *bat_priv) | |||
1249 | /** | 1249 | /** |
1250 | * batadv_bla_check_bcast_duplist | 1250 | * batadv_bla_check_bcast_duplist |
1251 | * @bat_priv: the bat priv with all the soft interface information | 1251 | * @bat_priv: the bat priv with all the soft interface information |
1252 | * @bcast_packet: encapsulated broadcast frame plus batman header | 1252 | * @skb: contains the bcast_packet to be checked |
1253 | * @bcast_packet_len: length of encapsulated broadcast frame plus batman header | ||
1254 | * | 1253 | * |
1255 | * check if it is on our broadcast list. Another gateway might | 1254 | * check if it is on our broadcast list. Another gateway might |
1256 | * have sent the same packet because it is connected to the same backbone, | 1255 | * 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) | |||
1262 | * the same host however as this might be intended. | 1261 | * the same host however as this might be intended. |
1263 | */ | 1262 | */ |
1264 | int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | 1263 | int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, |
1265 | struct batadv_bcast_packet *bcast_packet, | 1264 | struct sk_buff *skb) |
1266 | int bcast_packet_len) | ||
1267 | { | 1265 | { |
1268 | int i, length, curr, ret = 0; | 1266 | int i, curr, ret = 0; |
1269 | uint8_t *content; | 1267 | __be32 crc; |
1270 | uint16_t crc; | 1268 | struct batadv_bcast_packet *bcast_packet; |
1271 | struct batadv_bcast_duplist_entry *entry; | 1269 | struct batadv_bcast_duplist_entry *entry; |
1272 | 1270 | ||
1273 | length = bcast_packet_len - sizeof(*bcast_packet); | 1271 | bcast_packet = (struct batadv_bcast_packet *)skb->data; |
1274 | content = (uint8_t *)bcast_packet; | ||
1275 | content += sizeof(*bcast_packet); | ||
1276 | 1272 | ||
1277 | /* calculate the crc ... */ | 1273 | /* calculate the crc ... */ |
1278 | crc = crc16(0, content, length); | 1274 | crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1)); |
1279 | 1275 | ||
1280 | spin_lock_bh(&bat_priv->bla.bcast_duplist_lock); | 1276 | spin_lock_bh(&bat_priv->bla.bcast_duplist_lock); |
1281 | 1277 | ||
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index 789cb73bde67..196d9a0254bc 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h | |||
@@ -31,8 +31,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, | |||
31 | void *offset); | 31 | void *offset); |
32 | int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig); | 32 | int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig); |
33 | int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | 33 | int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, |
34 | struct batadv_bcast_packet *bcast_packet, | 34 | struct sk_buff *skb); |
35 | int hdr_size); | ||
36 | void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, | 35 | void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, |
37 | struct batadv_hard_iface *primary_if, | 36 | struct batadv_hard_iface *primary_if, |
38 | struct batadv_hard_iface *oldif); | 37 | struct batadv_hard_iface *oldif); |
@@ -81,8 +80,7 @@ static inline int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, | |||
81 | 80 | ||
82 | static inline int | 81 | static inline int |
83 | batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | 82 | batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, |
84 | struct batadv_bcast_packet *bcast_packet, | 83 | struct sk_buff *skb) |
85 | int hdr_size) | ||
86 | { | 84 | { |
87 | return 0; | 85 | return 0; |
88 | } | 86 | } |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 8d64348e3cc0..1aa1722d0187 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -1196,14 +1196,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, | |||
1196 | 1196 | ||
1197 | spin_unlock_bh(&orig_node->bcast_seqno_lock); | 1197 | spin_unlock_bh(&orig_node->bcast_seqno_lock); |
1198 | 1198 | ||
1199 | /* keep skb linear for crc calculation */ | ||
1200 | if (skb_linearize(skb) < 0) | ||
1201 | goto out; | ||
1202 | |||
1203 | bcast_packet = (struct batadv_bcast_packet *)skb->data; | ||
1204 | |||
1205 | /* check whether this has been sent by another originator before */ | 1199 | /* check whether this has been sent by another originator before */ |
1206 | if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len)) | 1200 | if (batadv_bla_check_bcast_duplist(bat_priv, skb)) |
1207 | goto out; | 1201 | goto out; |
1208 | 1202 | ||
1209 | /* rebroadcast packet */ | 1203 | /* rebroadcast packet */ |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 7b3d0d7ef06a..ae9ac9aca8c5 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -156,7 +156,7 @@ struct batadv_neigh_node { | |||
156 | #ifdef CONFIG_BATMAN_ADV_BLA | 156 | #ifdef CONFIG_BATMAN_ADV_BLA |
157 | struct batadv_bcast_duplist_entry { | 157 | struct batadv_bcast_duplist_entry { |
158 | uint8_t orig[ETH_ALEN]; | 158 | uint8_t orig[ETH_ALEN]; |
159 | uint16_t crc; | 159 | __be32 crc; |
160 | unsigned long entrytime; | 160 | unsigned long entrytime; |
161 | }; | 161 | }; |
162 | #endif | 162 | #endif |