Generic/TCP Segmentation Offload and Wireshark

Before reading this post you may have a look at the link http://en.wikipedia.org/wiki/Large_segment_offload which is the main motive of this post. While I was trying to troubleshoot some TCP communication, I wanted to investigate something which I have ignored so far. Maybe one screenshot is more than many words;

Have a look at total length field of this IP packet. It is 2948 on a link whose MTU is 1500. I asked myself how could that happen? A little search showed that it is because of segmentation offload in the network adapter. Normally TCP segmentation is handled by the host CPU with which wireshark displays reasonable lengths. However if segmentation is handed over to network adapter, host machine instead of doing segmentation itself, it sends chunk of segment to network adapter for segmentation at which wireshark captures this transmission and displays a header length which you don’t expect. TSO is definitely an improvement on host resource usage but for demonstration and testing it really makes things difficult. We can display current setting for tso/gso via;

root@rtoo:~# ethtool -k eth0

We can turn this feature off via;

After turning it off, if you take another capture, wireshark will display what you expect indeed.If your tcp-segmentation-offload is also on, turn it off via

For some more info on TSO/GSO check the links below:
GSO: http://www.linuxfoundation.org/collaborate/workgroups/networking/gso
TSO : http://www.linuxfoundation.org/collaborate/workgroups/networking/tso

5 thoughts on “Generic/TCP Segmentation Offload and Wireshark

  1. Josef

    Thank you for your answer, but in ( http://rtoodtoo.net/2012/03/24/ip-fragmentation/ ) you are talking about IP fragmentation and my question was actually about the Tcp Segmentation Offload (TSO).
    When Wireshark writes on a packet description “TCP segment of a reassembled PDU”, and then on the last segment “[xx Reassembled TCP Segments (xxxx bytes): #46(1440), #48(113), #50(1440), #52(1440), #54(1440), #56(1440), #58(1440)….]” how did wireshark know that it was the last segment.

    Reply
  2. rtoodtoo Post author

    Hi Josef,
    I am not exactly sure how wireshark determines this indeed but my guess is
    this is really an high level operation associated with the TCP dissector and these dissectors are protocol specific. In the case of HTTP for example, if an image is requested from a web server via GET, response from the server indicates the length of the PDU for which wireshark may be deciding how segments are split and can also
    determine the last segment that belongs to the same PDU. Things probably get complicated in HTTP pipelining or chunked encoding.
    What I have written so far is just my theory which may be completely wrong:)
    As I couldn’t find a concrete answer from wireshark documentation. For example I have seen that wireshark has a filter named “tcp.pdu.last_frame” but there isn’t any explanation how it is determined.

    Reply

You have a feedback?