smoltcp
smoltcp copied to clipboard
Allow to configure ChecksumCapabilities for RawSocket
On Linux, packets that stay local to the machine (moving from the host to a container for example) don't always have their checksum computed, see for example https://patchwork.ozlabs.org/patch/261822/. The proper fix would be to check for TP_STATUS_CSUMNOTREADY, but an easy workaround is to have a way to change the ChecksumCapabilities or DeviceCapabilities.
As a rust noob here my solution for now:
#[derive(Debug)]
pub struct RawSocket2 {
inner: RawSocket,
}
impl AsRawFd for RawSocket2 {
fn as_raw_fd(&self) -> RawFd {
self.inner.as_raw_fd()
}
}
impl RawSocket2 {
pub fn new(name: &str) -> io::Result<RawSocket2> {
Ok(RawSocket2{
inner: RawSocket::new(name)?,
})
}
}
impl<'a> Device<'a> for RawSocket2 {
type RxToken = <RawSocket as Device<'a>>::RxToken;
type TxToken = <RawSocket as Device<'a>>::TxToken;
fn capabilities(&self) -> DeviceCapabilities {
let mut checksum_caps = ChecksumCapabilities::default();
checksum_caps.ipv4 = Checksum::Tx;
checksum_caps.udp = Checksum::Tx;
checksum_caps.tcp = Checksum::Tx;
checksum_caps.icmpv4 = Checksum::Tx;
checksum_caps.icmpv6 = Checksum::Tx;
let mut c = self.inner.capabilities();
c.checksum = checksum_caps;
c
}
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
self.inner.receive()
}
fn transmit(&'a mut self) -> Option<Self::TxToken> {
self.inner.transmit()
}
}
I agree that checking for TP_STATUS_CSUMNOTREADY would be a proper solution. Unfortunately we can't integrate it with the rest of smoltcp at the moment, I believe, since checksum capabilities are tracked in it per-interface, not per-packet. Is there a way to determine whether an interface will always return packets with TP_STATUS_CSUMNOTREADY set?
I'm only using smoltcp for a POC, so being able to configure ChecksumCapabilities is good enough me.
No interface will return 100% packets with TP_STATUS_CSUMNOTREADY I think, anything routed from outside will have a checksum. I don't see any good heuristics.
What do you think about checking for TP_STATUS_CSUMNOTREADY and if it is set, recalculating the checksum?
good idea, that would make smoltcp just work even if not optimal for performance