|
|
d994f31 |
From: Sven Eckelmann <sven@narfation.org>
|
|
|
d994f31 |
Date: Sat, 20 Dec 2014 13:48:55 +0100
|
|
|
d994f31 |
Subject: [PATCH] batman-adv: Calculate extra tail size based on queued
|
|
|
d994f31 |
fragments
|
|
|
d994f31 |
MIME-Version: 1.0
|
|
|
d994f31 |
Content-Type: text/plain; charset=UTF-8
|
|
|
d994f31 |
Content-Transfer-Encoding: 8bit
|
|
|
d994f31 |
|
|
|
d994f31 |
The fragmentation code was replaced in 610bfc6bc99bc83680d190ebc69359a05fc7f605
|
|
|
d994f31 |
("batman-adv: Receive fragmented packets and merge"). The new code provided a
|
|
|
d994f31 |
mostly unused parameter skb for the merging function. It is used inside the
|
|
|
d994f31 |
function to calculate the additionally needed skb tailroom. But instead of
|
|
|
d994f31 |
increasing its own tailroom, it is only increasing the tailroom of the first
|
|
|
d994f31 |
queued skb. This is not correct in some situations because the first queued
|
|
|
d994f31 |
entry can be a different one than the parameter.
|
|
|
d994f31 |
|
|
|
d994f31 |
An observed problem was:
|
|
|
d994f31 |
|
|
|
d994f31 |
1. packet with size 104, total_size 1464, fragno 1 was received
|
|
|
d994f31 |
- packet is queued
|
|
|
d994f31 |
2. packet with size 1400, total_size 1464, fragno 0 was received
|
|
|
d994f31 |
- packet is queued at the end of the list
|
|
|
d994f31 |
3. enough data was received and can be given to the merge function
|
|
|
d994f31 |
(1464 == (1400 - 20) + (104 - 20))
|
|
|
d994f31 |
- merge functions gets 1400 byte large packet as skb argument
|
|
|
d994f31 |
4. merge function gets first entry in queue (104 byte)
|
|
|
d994f31 |
- stored as skb_out
|
|
|
d994f31 |
5. merge function calculates the required extra tail as total_size - skb->len
|
|
|
d994f31 |
- pskb_expand_head tail of skb_out with 64 bytes
|
|
|
d994f31 |
6. merge function tries to squeeze the extra 1380 bytes from the second queued
|
|
|
d994f31 |
skb (1400 byte aka skb parameter) in the 64 extra tail bytes of skb_out
|
|
|
d994f31 |
|
|
|
d994f31 |
Instead calculate the extra required tail bytes for skb_out also using skb_out
|
|
|
d994f31 |
instead of using the parameter skb. The skb parameter is only used to get the
|
|
|
d994f31 |
total_size from the last received packet. This is also the total_size used to
|
|
|
d994f31 |
decide that all fragments were received.
|
|
|
d994f31 |
|
|
|
d994f31 |
Reported-by: Philipp Psurek <philipp.psurek@gmail.com>
|
|
|
d994f31 |
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
|
|
d994f31 |
Acked-by: Martin Hundebøll <martin@hundeboll.net>
|
|
|
d994f31 |
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
|
d994f31 |
---
|
|
|
d994f31 |
net/batman-adv/fragmentation.c | 2 +-
|
|
|
d994f31 |
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
d994f31 |
|
|
|
d994f31 |
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
|
|
|
d994f31 |
index fc1835c6bb40..8af3461d18d2 100644
|
|
|
d994f31 |
--- a/net/batman-adv/fragmentation.c
|
|
|
d994f31 |
+++ b/net/batman-adv/fragmentation.c
|
|
|
d994f31 |
@@ -251,7 +251,7 @@ batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb)
|
|
|
d994f31 |
kfree(entry);
|
|
|
d994f31 |
|
|
|
d994f31 |
/* Make room for the rest of the fragments. */
|
|
|
d994f31 |
- if (pskb_expand_head(skb_out, 0, size - skb->len, GFP_ATOMIC) < 0) {
|
|
|
d994f31 |
+ if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) {
|
|
|
d994f31 |
kfree_skb(skb_out);
|
|
|
d994f31 |
skb_out = NULL;
|
|
|
d994f31 |
goto free;
|
|
|
d994f31 |
--
|
|
|
d994f31 |
2.1.0
|
|
|
d994f31 |
|