Re: tcp/udp hardware checksum offload support..
Re: tcp/udp hardware checksum offload support..
- Subject: Re: tcp/udp hardware checksum offload support..
- From: Josh Graessley <email@hidden>
- Date: Tue, 29 Jan 2002 13:15:51 -0800
On 1/29/02 8:10 AM, "Andrew Gallatin" <email@hidden> wrote:
>
>> Also, why does darwin not allow csum offloading for received ip
>
>> fragments using the CSUM_TCP_SUM16 method?
>
>
>
> The CSUM_TCP_SUM16 flag is used to indicate that the GMAC's checksum is
>
> being used. The GMAC hardware checksum has some limitations. There are a lot
>
> of checks for the various limitations to avoid cases where the hardware does
>
> the wrong thing. I believe IP fragments may be one of the cases where the
>
> chipset does the wrong thing.
>
>
Hehe.. Yes, but all the world's not a GMAC. It appears that the GMAC
>
specific code has replaced the general code. Eg, if you set
>
CSUM_DATA_VALID without setting CSUM_TCP_SUM16, you're ignored. The
>
only to not be ignored is to set either CSUM_PSEUDO_HDR or
>
CSUM_TCP_SUM16. Setting CSUM_PSEUDO_HDR gives me the same problem --
>
no frags can be dealt with unless I want to implement reassembly in my
>
driver (I don't). So I'm screwed either way.
CSUM_TCP_SUM16 is only for the GMAC hardware, you shouldn't need to set it
for your hardware. It only causes some weird special case code to be
executed. Ideally, you should be able to get things working with the other
flags. The hardware checksum support in the kernel is still new, so it may
contain some rough edges you'll get snagged on, as you're noticing. Some of
this is addressed on a branch we're working on.
I don't recall what the psuedo header does. Perhaps someone else can help
out there. I do know that you can't perform hardware udp/tcp checksums on
fragmented packets unless you're going to handle reassembly in your
hardware. The UDP or TCP checksum is in the first fragment that contains the
UDP or TCP header. All other fragments of the packet contain the IP header
followed by UDP or TCP data. You can't calculate the UDP/TCP checksum until
you've collected all fragments. I believe most stacks avoid TCP
fragmentation, so I doubt you'll see much if any of that. This will still be
a problem from UDP though.
>
There should be a 3rd case. Eg:
>
>
--- tcp_input.c Sun Dec 16 10:59:16 2001
>
+++ tcp_input.c.new Tue Jan 29 11:06:45 2002
>
@@ -520,7 +520,10 @@
>
else {
>
if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
>
th->th_sum = m->m_pkthdr.csum_data;
>
- else goto dotcpcksum;
>
+ else
>
+ th->th_sum = in_pseudo(ip->ip_src.s_addr,
>
+ ip->ip_dst.s_addr, htonl(m->m_pkthdr.csum_data +
>
+ ip->ip_len + IPPROTO_TCP));
>
}
>
th->th_sum ^= 0xffff;
I believe you're right. In fact, something very similar to this is done in
FreeBSD 4.4. We have these changes on a branch that we're hoping to get in
to xnu some time soon. If you'd like to be able to track the progress,
you're welcome to file a bug.
-josh