udp_input() and CSUM_PSEUDO_HDR
udp_input() and CSUM_PSEUDO_HDR
- Subject: udp_input() and CSUM_PSEUDO_HDR
- From: Andrew Gallatin <email@hidden>
- Date: Tue, 30 Nov 2004 11:38:19 -0500 (EST)
Hi,
I have a driver which does TCP and UDP checksum offload. The device
tells me the partial (payload) checksum, which I fill into
m_pkthdr.csum_data.
However, udp_input() ignores partial checksums:
/*
* Checksum extended UDP header and data.
*/
if (uh->uh_sum) {
if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
uh->uh_sum = m->m_pkthdr.csum_data;
else
goto doudpcksum;
uh->uh_sum ^= 0xffff;
FreeBSD's udp_input() is mostly identical, except in place of
goto doudpcksum; it has the code to integrate the partial checksum:
uh->uh_sum = in_pseudo(ip->ip_src.s_addr,
ip->ip_dst.s_addr, htonl((u_short)len +
m->m_pkthdr.csum_data + IPPROTO_UDP));
Is this just a bug, or is it a workaround for a broken device? If
the latter, is there any way the workaround could be changed to allow
for non-broken drivers to pass partial checksums up the stack?
Right now, since I want to handle UDP checksum offload, I have some
ugly code in my driver figure out if its a tcp or udp packet, and to
call in_pseudo() on it (as above) to get the complete checksum. Its
pretty ugly, and adds some cost to the receive path. It would be nice
to be able to remove it.
Thanks,
Drew
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden