net: ipv6_fragment: fix shift_packets() algorithm
The purpose of shift_packets() is to make room to insert one fragment in
the list. This is not what it does currently, potentially leading to
-ENOMEM even if there is enough free room.
To see the current behaviour, let's assume that we receive 3 fragments
in reverse order:
- Frag3(offset = 0x40, M=0)
- Frag2(offset = 0x20, M=1)
- Frag1(offset = 0x00, M=1)
After receiving Frag3 and Frag2, pkt[] will look like:
.-------.-------.-------.
| Frag2 | Frag3 | NULL |
| 0x20 | 0x40 | |
'-------'-------'-------'
pkt[0] pkt[1] pkt[2]
When receiving Frag1, shift_packets(pos = 0) is called to make some room
at position 0. It will iterate up to i = 2 where there is a free
element. The current algorithm will try to shift pkt[0] to pkt[2], which
is indeed impossible but also unnecessary. It is only required to shift
pkt[0] and pkt[1] by one element in order to free pkt[0] to insert
Frag1.
Update the algorithm in order to shift the memory only by one element.
As a result, the ENOMEM test is only simpler: as long as we encounter
one free element, we are guaranteed that we can shift by one element.
Also assign a NULL value to the newly freed element since memmove() only
copy bytes.
Signed-off-by:
Florian Vaussard <florian.vaussard@gmail.com>
Loading
Please sign in to comment