diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-06-02 07:21:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-06-02 13:39:42 -0400 |
commit | 51263fffadee28c99152fb78a2d41e3d10c9b0b5 (patch) | |
tree | 08ea7ae9257bef3c14ff29163a07de3c5c00b2d0 /net | |
parent | 86c92ee3a2a22bf87537072f0f2021089ab87395 (diff) |
6lowpan_rtnl: fix fragmentation with two fragments
This patch fix the 6LoWPAN fragmentation for the case if we have exactly
two fragments. The problem is that the (skb_unprocessed >= frag_cap)
condition is always false on the second fragment after sending the first
fragment. A fragmentation with only one fragment doesn't make any sense.
The solution is that we use a do while loop here, that ensures we sending
always a minimum of two fragments if we need a fragmentation.
This issue was introduced by commit d4b2816d67d6e07b2f27037f282d8db03a5829d7
("6lowpan: fix fragmentation").
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ieee802154/6lowpan_rtnl.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 1ae8a5628fb5..9d57026fd9d5 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c | |||
@@ -312,7 +312,7 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev, | |||
312 | frag_hdr[0] |= LOWPAN_DISPATCH_FRAGN; | 312 | frag_hdr[0] |= LOWPAN_DISPATCH_FRAGN; |
313 | frag_cap = round_down(payload_cap - LOWPAN_FRAGN_HEAD_SIZE, 8); | 313 | frag_cap = round_down(payload_cap - LOWPAN_FRAGN_HEAD_SIZE, 8); |
314 | 314 | ||
315 | while (skb_unprocessed >= frag_cap) { | 315 | do { |
316 | dgram_offset += frag_len; | 316 | dgram_offset += frag_len; |
317 | skb_offset += frag_len; | 317 | skb_offset += frag_len; |
318 | skb_unprocessed -= frag_len; | 318 | skb_unprocessed -= frag_len; |
@@ -328,7 +328,7 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev, | |||
328 | __func__, frag_tag, skb_offset); | 328 | __func__, frag_tag, skb_offset); |
329 | goto err; | 329 | goto err; |
330 | } | 330 | } |
331 | } | 331 | } while (skb_unprocessed >= frag_cap); |
332 | 332 | ||
333 | consume_skb(skb); | 333 | consume_skb(skb); |
334 | return NET_XMIT_SUCCESS; | 334 | return NET_XMIT_SUCCESS; |