smoltcp icon indicating copy to clipboard operation
smoltcp copied to clipboard

Allow to configure ChecksumCapabilities for RawSocket

Open champtar opened this issue 5 years ago • 4 comments

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()
    }
}

champtar avatar Mar 15 '20 06:03 champtar

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?

whitequark avatar Apr 14 '20 08:04 whitequark

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.

champtar avatar Apr 14 '20 11:04 champtar

What do you think about checking for TP_STATUS_CSUMNOTREADY and if it is set, recalculating the checksum?

whitequark avatar Apr 14 '20 11:04 whitequark

good idea, that would make smoltcp just work even if not optimal for performance

champtar avatar Apr 14 '20 12:04 champtar