checksum offloading

an7 <[email protected]> Thu, 6 Nov 2003 10:35:55 +0100 (CET)
Newsgroups gmane.linux.drivers.eepro100.devel
Message-ID <[email protected]>
Hi all, please answer on my mail address (i have not
subscribed to the list)

I am trying to understand how the driver realise the
hardware computation.

if we consider the upper layers :

from tcp_ipv4.c

if ((skb->ip_summed !=3D CHECKSUM_UNNECESSARY &&
         tcp_v4_checksum_init(skb) < 0))
            goto bad_packet;


with :

static int tcp_v4_checksum_init(struct sk_buff *skb)
    {
        if (skb->ip_summed =3D=3D CHECKSUM_HW) {
            skb->ip_summed =3D CHECKSUM_UNNECESSARY;
            if
(!tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr,
                            =20
skb->nh.iph->daddr,skb->csum))
                    return 0;
  [...]

                    skb->ip_summed =3D CHECKSUM_NONE;
        }

The first line is obvious. If the checksum has been
computed in hardware, we set ip->summed to
checksum_unnecessary, and the TCP checksum is verified
(first params are for the pseudo header, and skb->csum
is used for the checksum of tcpheader+data). So the
combination of the skb->csum value and pseudo header
checksum finally gives the TCP checksum.
       =20
This part of code is dealing with hardware computed
checksums, when packets come to the tcp layer.

Here, i decide to look at the networking driver code,
and found :

in the e100_rx_srv() function :

     if (bdp->flags & DF_CSUM_OFFLOAD) {
             if (bdp->rev_id >=3D D102_REV_ID) {
                     skb->ip_summed =3D
e100_D102_check_checksum(rfd);
             } else {
                     skb->ip_summed =3D
e100_D101M_checksum(bdp, skb);
             }
     } else {
             skb->ip_summed =3D CHECKSUM_NONE;
     }

So here, we deal with checksum offloading.

Pay attention to the line :

       skb->ip_summed =3D e100_D101M_checksum(bdp, skb);

Going ahead :

static unsigned char
    e100_D101M_checksum(struct e100_private *bdp,
struct sk_buff *skb)
    {
        unsigned short proto =3D (skb->protocol);

        if (proto =3D=3D __constant_htons(ETH_P_IP)) {

                skb->csum =3D get_unaligned((u16 *)
(skb->tail));
                return CHECKSUM_HW;
        }
        return CHECKSUM_NONE;
    }

this function is responsible for filling skb->csum.
The comment says that the sum which has been
calculated in hardware can be found at the end of data
contained in skb (skb->tail), and the comment tells
too that the sums covers all words in the frame
(excepting ethernet II header).=20

If we _suppose_ hardware computes checksum, skb->csum
is filled with a sum including ip header.=20

I prove you that then the skb->csum is used as a
complement for the pseudo header to finnaly compute
the tcp checksum. So in my opinion skb->csum must only
covers tcpheader+data. I prove u again that this is
according to the code, not the case :

 * Sets the skb->csum value from D101 csum found at
the end of the Rx frame. The
 * D101M sums all words in frame excluding the
ethernet II header (14 bytes) so
 * in case the packet is ethernet II and the protocol
is IP, all is need is to
 * assign this value to skb->csum.

And i recall, as it is used as a complement of pseudo
header checksum for tcp checksum computing , there is
a problem as we cover the ipheader too.

I think it is right place here for this sort of stuff.

Please answer to email address (i haven't subscribed)

___________________________________________________________
Do You Yahoo!? -- Une adresse @yahoo.fr gratuite et en fran=E7ais !
Yahoo! Mail : http://fr.mail.yahoo.com