public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Chris Edwards <chris@edwards.mine.nu>
To: linux-kernel@vger.kernel.org
Subject: Occasional TCP checksum errors with qdisc
Date: Sat, 26 Oct 2002 18:43:23 +1000	[thread overview]
Message-ID: <20021026084323.GA18838@ummagumma> (raw)

Hi,

I've been developing a kernel module which acts as a queuing discipline,
and modifies TCP packets to include an extra option. This obviously
involves updating the checksums. It looked like it was all working fine,
but occasionally packets get the wrong TCP checksum! I've only been able to
reproduce this when talking to a remote solaris 8 machine. Running gigs
of data against local Linux machines produces nothing! The IP checksum
is always correct, even though it too is modified.

Most of the code was taken from the ipt_TCPMSS module, which performs a
similar task. I've included the relevant bit of code below:. I can send
the full module if that helps. 

Also, I've tried performing a full checksum on the packet and that
seemed to produce the same checksums as the code below, and obviously
that didn't work!

Any help would be greatly appreciated!! I suspect something happens with
qdiscs which I don't know about. The strange thing is that it very
rarely causes problems.

Chris


        if (skb_tailroom(skb) >= TCPOLEN_QSIZE &&
                        skb->len <= (sch->dev->mtu - TCPOLEN_QSIZE)) {
                struct tcphdr *tcph;
                struct iphdr *iph;
                u_int16_t tcplen, newtotlen, oldval;
                u_int16_t pofq;

                u_int8_t *opt;

                iph = skb->nh.iph;
                tcplen = skb->len - iph->ihl * 4;

                tcph = (void *) iph + iph->ihl * 4;

                skb_put(skb, TCPOLEN_QSIZE);

                opt = (u_int8_t *) tcph + sizeof(struct tcphdr);
                memmove(opt + TCPOLEN_QSIZE, opt,
                                tcplen - sizeof(struct tcphdr));

                tcph->check = cheat_check(htons(tcplen) ^ 0xFFFF,
                                htons(tcplen + TCPOLEN_QSIZE),
                        tcph->check);

                tcplen += TCPOLEN_QSIZE;

                /* Fill the extra 4 bytes with our option. */
                opt[0] = TCPO_QSIZE;
                opt[1] = TCPOLEN_QSIZE;

                pofq = evaluatepq(sch);
                opt[2] = (pofq & 0xff00) >> 8;
                opt[3] = (pofq & 0x00ff);

                tcph->check = cheat_check(~0, *((u_int32_t *) opt),
                                tcph->check);

                oldval = ((u_int16_t *) tcph)[6];
                tcph->doff += TCPOLEN_QSIZE / 4; 

                tcph->check = cheat_check(oldval ^ 0xFFFF,
                                ((u_int16_t *) tcph)[6], tcph->check);

                newtotlen = htons(ntohs(iph->tot_len) + 4);
                iph->check = cheat_check(iph->tot_len ^ 0xFFFF,
                                newtotlen, iph->check);
                iph->tot_len = newtotlen;

                /* We need to invalidate the existing checksum, in case
                the
                 * hardware has already produced one. */
                skb->ip_summed = CHECKSUM_NONE;

                return skb;
        }

--
Chris Edwards <chris@edwards.mine.nu>

hippo 18:32:01 up 7 days, 22:47,  6 users,  load average: 0.00, 0.00, 0.00

                 reply	other threads:[~2002-10-26  8:37 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20021026084323.GA18838@ummagumma \
    --to=chris@edwards.mine.nu \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox