Skip to content

feat(phy): add TCP segmentation support#1148

Open
cagatay-y wants to merge 2 commits into
smoltcp-rs:mainfrom
cagatay-y:segmentation-offload
Open

feat(phy): add TCP segmentation support#1148
cagatay-y wants to merge 2 commits into
smoltcp-rs:mainfrom
cagatay-y:segmentation-offload

Conversation

@cagatay-y

Copy link
Copy Markdown
Contributor

The Windows and Linux documentations for the same feature were used as references. It was more difficult to find information on how devices support the feature, so the interface is mostly based on how virtio-net devices expect to be driven. The code was tested on the Hermit kernel with a virtio-net device, but only with IPv4, as Hermit does not support IPv6.

Design rationale

  • The segmentation capabilities are specified separately for TCP on IPv4 and IPv6. This follows the example of Linux and Windows. This should provide flexibility for devices that support only one of the IP versions and should not be a problem for devices that support both as a single feature.
  • As it is necessary to communicate to the device what the target segment size is, a field is added to PacketMeta. To keep the compiler able to optimise out the structure if the features associated with the fields, the segmentation offload feature is optional, following the example of packetmeta-id.
  • For pre-segmentation IP packets whose size exceeds the maximum that is allowed by the length field of the IP header, we fall back to zero. An alternative would be to set the field to zero unconditionally, and this seems to be a "should" level expectation for at least for some Intel cards. The fallback approach has the advantage of keeping code that uses the IP header field (for example for constructing TcpPackets to set the partial checksum in our case) functional for sufficiently small unsegmented packets. On the other hand, it can also be argued that causing a failure even for smaller packets can help uncover the error case with the larger packets earlier in the development of the device drivers.

Comparison to #830

  • The segmentation capabilities struct in the older PR follows the structure of ChecksumCapabilities. This PR does not do so for the following reasons:
    • The segmentation capability for a given protocol is not binary. Different devices may support large (i.e. unsegmented) packets of different maximum sizes (references for various devices)
    • On the receive side the related feature seems to be called "coalescing." It may be somewhat confusing to represent information for the receive side in a structure whose name refers to "segmentation."
  • The capability structure is named SegmentationCapabilities rather than the TCP specific name TsoCapabilities. I believe the current structure can be expanded to support UDP, though I currently do not have a prototype for that.
  • The current PR has support for communicating the target segment size to the device.
  • This PR is missing an equivalent to this line. The addition of the set_meta calls seems correct to me but because it is not segmentation offload specific and I was not able to test its necessity because of the lack of IPv6 support on our test platform, I did not include it in this PR.

cagatay-y added 2 commits May 5, 2026 17:08
It is possible for packets larger than the current capture limits to be
sent with the segmentation offload feature.
@codecov

codecov Bot commented May 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 48.27586% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.48%. Comparing base (e347a1e) to head (ff1f082).

Files with missing lines Patch % Lines
src/phy/pcap_writer.rs 0.00% 11 Missing ⚠️
src/iface/interface/mod.rs 33.33% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1148      +/-   ##
==========================================
- Coverage   81.48%   81.48%   -0.01%     
==========================================
  Files          81       81              
  Lines       25007    25014       +7     
==========================================
+ Hits        20378    20383       +5     
- Misses       4629     4631       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread src/socket/tcp.rs
crate::wire::IpVersion::Ipv6 => segmentation_caps.tcpv6,
}
.map(|buf_size| {
#[cfg(feature = "medium-ethernet")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checking feature = "medium-ethernet" here is not enough, you have to check the actual medium in the phy capabilities.

It's possible to enable medium-ethernet and medium-ip at the same time, so even if medium-ethernet is enabled you may have an IP medium phy.

Comment thread src/phy/mod.rs
#[cfg(feature = "packetmeta-id")]
pub id: u32,
#[cfg(feature = "segmentation-offload")]
pub segmentation_offload_size: Option<NonZeroU16>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you document what this does?

Comment thread src/socket/tcp.rs
ip_mtu - ip_repr.header_len() - TCP_HEADER_LEN
})
.unwrap_or(segment_size)
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add tests for the logic here? e.g. that if segmentation offload is enabled oversized packets are emitted up to the limit supported by the phy, with the right MSS value in the meta.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants