Subject: Re: calculation in UDP
To: Thomas Finneid <tfinneid@ifi.uio.no>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-net
Date: 12/07/2002 21:29:11
On Sun, Dec 08, 2002 at 03:22:19AM +0100, Thomas Finneid wrote:

 > This is why I am asking the question, it basically does not add up. I am
 > using 1.6 and am assuming checksumming is turned on by default (as all
 > literature and experience has told us it should be). 

[ snip ]

 > On Sat, 7 Dec 2002 14:57:46 +0100 netbsd@gve.ch wrote:
 > 
 > > hi,
 > > it seems the code is in the file sys/netinet/udp_usrreq.c
 > > in udp_output():
 > > 
 > >         /*
 > >          * Set up checksum and output datagram.
 > >          */
 > >                 ui->ui_sum = in_cksum_phdr(ui->ui_src.s_addr,
 > >                   ui->ui_dst.s_addr, htons((u_int16_t)len +
 > >                   sizeof(struct udphdr) + IPPROTO_UDP));
 > >                 m->m_pkthdr.csum_flags = M_CSUM_UDPv4;
 > >                 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);

Right, so this is just some setup ... the actual payload checksum is
performed later, just before the packet is handed to the network interface.
This is so we can offload the payload checksum to hardware if the network
interface supports it.

Take a look at ip_output.c:

                /*
                 * Always initialize the sum to 0!  Some HW assisted
                 * checksumming requires this.
                 */
                ip->ip_sum = 0;
                m->m_pkthdr.csum_flags |= M_CSUM_IPv4;

                sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx;

                /*
                 * Perform any checksums that the hardware can't do
                 * for us.
                 *
                 * XXX Does any hardware require the {th,uh}_sum
                 * XXX fields to be 0?
                 */
                if (sw_csum & M_CSUM_IPv4)
                        ip->ip_sum = in_cksum(m, hlen);
                if (sw_csum & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
                        in_delayed_cksum(m);
                        sw_csum &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
                }
                m->m_pkthdr.csum_flags &= ifp->if_csum_flags_tx;

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>