net: bugfix for rx of big frames
The misbehavior can be reproduced with
ping -s 422 192.168.16.200
now, the first frame is fully stored to the queue:
copy_out: head 368 avail 512 len 2
copy_out: head 370 avail 510 len 14
copy_out: head 384 avail 496 len 24
copy_out: head 408 avail 472 len 450
but it is retrieved only partially:
copy_in: tail 368 avail 22 len 2
copy_in: tail 370 avail 24 len 14
copy_in: tail 384 avail 38 len 24
copy_in: tail 408 avail 62 len 400
The tail of the frame remains in the queue, and is
not correctly removed. So we have:
update_rx_queues: queue for socket full; [avail 462 required 490]
(because 50 bytes are lost there). And the next rx frame,
the tail of the previous one is considered size, then truncated
to the payload buffer size (here 400 for icmp), so we never realign:
copy_out: head 346 avail 462 len 2
copy_out: head 348 avail 460 len 14
copy_out: head 362 avail 446 len 24
copy_out: head 386 avail 422 len 84
Q: Size 84 head 470 Smac 0:4:25:12:34:56
update_rx_queues: saved packet to queue [avail 338 n 1 size 124]
copy_in: tail 296 avail 338 len 2
copy_in: tail 298 avail 340 len 14
copy_in: tail 312 avail 354 len 24
copy_in: tail 336 avail 378 len 400
So the available space in the 512-big queue explodes (and ping gets no
replies):
copy_in: tail 120 avail 1326 len 400
In the caller I got one reply and nothing more, not even the short pings:
68 bytes from 192.168.16.200: icmp_req=1 ttl=63 (truncated)
5 packets transmitted, 1 received, 80% packet loss, time 4009ms
With this commit everything flows
68 bytes from 192.168.16.200: icmp_req=1 ttl=63 (truncated)
68 bytes from 192.168.16.200: icmp_req=2 ttl=63 (truncated)
68 bytes from 192.168.16.200: icmp_req=3 ttl=63 (truncated)
64 bytes from 192.168.16.200: icmp_req=1 ttl=63 time=2.02 ms
64 bytes from 192.168.16.200: icmp_req=2 ttl=63 time=1.61 ms
Signed-off-by:
Alessandro Rubini <rubini@gnudd.com>
Please register or sign in to comment