Commit 83e8b877 authored by Sven Eckelmann's avatar Sven Eckelmann Committed by Antonio Quartulli

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: default avatarSven Eckelmann <sven@narfation.org>
Acked-by: default avatarMartin Hundebøll <martin@hundeboll.net>
Signed-off-by: default avatarMarek Lindner <mareklindner@neomailbox.ch>
parent 53e77145
...@@ -231,19 +231,13 @@ static bool batadv_frag_insert_packet(struct batadv_orig_node *orig_node, ...@@ -231,19 +231,13 @@ static bool batadv_frag_insert_packet(struct batadv_orig_node *orig_node,
* Returns the merged skb or NULL on error. * Returns the merged skb or NULL on error.
*/ */
static struct sk_buff * static struct sk_buff *
batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb) batadv_frag_merge_packets(struct hlist_head *chain)
{ {
struct batadv_frag_packet *packet; struct batadv_frag_packet *packet;
struct batadv_frag_list_entry *entry; struct batadv_frag_list_entry *entry;
struct sk_buff *skb_out = NULL; struct sk_buff *skb_out = NULL;
int size, hdr_size = sizeof(struct batadv_frag_packet); int size, hdr_size = sizeof(struct batadv_frag_packet);
/* Make sure incoming skb has non-bogus data. */
packet = (struct batadv_frag_packet *)skb->data;
size = ntohs(packet->total_size);
if (size > batadv_frag_size_limit())
goto free;
/* Remove first entry, as this is the destination for the rest of the /* Remove first entry, as this is the destination for the rest of the
* fragments. * fragments.
*/ */
...@@ -252,6 +246,9 @@ batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb) ...@@ -252,6 +246,9 @@ batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb)
skb_out = entry->skb; skb_out = entry->skb;
kfree(entry); kfree(entry);
packet = (struct batadv_frag_packet *)skb_out->data;
size = ntohs(packet->total_size);
/* Make room for the rest of the fragments. */ /* Make room for the rest of the fragments. */
if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) { if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) {
kfree_skb(skb_out); kfree_skb(skb_out);
...@@ -307,7 +304,7 @@ bool batadv_frag_skb_buffer(struct sk_buff **skb, ...@@ -307,7 +304,7 @@ bool batadv_frag_skb_buffer(struct sk_buff **skb,
if (hlist_empty(&head)) if (hlist_empty(&head))
goto out; goto out;
skb_out = batadv_frag_merge_packets(&head, *skb); skb_out = batadv_frag_merge_packets(&head);
if (!skb_out) if (!skb_out)
goto out_err; goto out_err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment