aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2014-12-01 04:37:28 -0500
committerAntonio Quartulli <antonio@meshcoding.com>2015-05-29 04:13:35 -0400
commit83e8b87721f21b26b843633caca8ef453e943623 (patch)
treec987f856131f264bc54667c1531d75cb875a5256
parent53e771457e823fbc21834f60508c42a4270534fd (diff)
batman-adv: Use only queued fragments when merging
The fragment queueing code now validates the total_size of each fragment, checks when enough fragments are queued to allow to merge them into a single packet and if the fragments have the correct size. Therefore, it is not required to have any other parameter for the merging function than a list of queued fragments. This change should avoid problems like in the past when the different skb from the list and the function parameter were mixed incorrectly. Signed-off-by: Sven Eckelmann <sven@narfation.org> Acked-by: Martin Hundebøll <martin@hundeboll.net> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
-rw-r--r--net/batman-adv/fragmentation.c13
1 files changed, 5 insertions, 8 deletions
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index a9fc6537214b..6ce3c84a7e55 100644
--- a/net/batman-adv/fragmentation.c
+++ b/net/batman-adv/fragmentation.c
@@ -231,19 +231,13 @@ err:
231 * Returns the merged skb or NULL on error. 231 * Returns the merged skb or NULL on error.
232 */ 232 */
233static struct sk_buff * 233static struct sk_buff *
234batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb) 234batadv_frag_merge_packets(struct hlist_head *chain)
235{ 235{
236 struct batadv_frag_packet *packet; 236 struct batadv_frag_packet *packet;
237 struct batadv_frag_list_entry *entry; 237 struct batadv_frag_list_entry *entry;
238 struct sk_buff *skb_out = NULL; 238 struct sk_buff *skb_out = NULL;
239 int size, hdr_size = sizeof(struct batadv_frag_packet); 239 int size, hdr_size = sizeof(struct batadv_frag_packet);
240 240
241 /* Make sure incoming skb has non-bogus data. */
242 packet = (struct batadv_frag_packet *)skb->data;
243 size = ntohs(packet->total_size);
244 if (size > batadv_frag_size_limit())
245 goto free;
246
247 /* Remove first entry, as this is the destination for the rest of the 241 /* Remove first entry, as this is the destination for the rest of the
248 * fragments. 242 * fragments.
249 */ 243 */
@@ -252,6 +246,9 @@ batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb)
252 skb_out = entry->skb; 246 skb_out = entry->skb;
253 kfree(entry); 247 kfree(entry);
254 248
249 packet = (struct batadv_frag_packet *)skb_out->data;
250 size = ntohs(packet->total_size);
251
255 /* Make room for the rest of the fragments. */ 252 /* Make room for the rest of the fragments. */
256 if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) { 253 if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) {
257 kfree_skb(skb_out); 254 kfree_skb(skb_out);
@@ -307,7 +304,7 @@ bool batadv_frag_skb_buffer(struct sk_buff **skb,
307 if (hlist_empty(&head)) 304 if (hlist_empty(&head))
308 goto out; 305 goto out;
309 306
310 skb_out = batadv_frag_merge_packets(&head, *skb); 307 skb_out = batadv_frag_merge_packets(&head);
311 if (!skb_out) 308 if (!skb_out)
312 goto out_err; 309 goto out_err;
313 310