LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

Re: Re: Re: Re: trouble about IP Fragmentation by using the Linux Virtua

To: frederic.buche@xxxxxxxxxx
Subject: Re: Re: Re: Re: trouble about IP Fragmentation by using the Linux Virtual Server
Cc: lvs-users@xxxxxxxxxxxxxxxxxxxxxx
From: Julian Anastasov <ja@xxxxxx>
Date: Wed, 18 Sep 2002 12:26:24 +0300 (EEST)
        Hello,

On Wed, 18 Sep 2002 frederic.buche@xxxxxxxxxx wrote:

> I have set up the second patch you gave me (csum2.diff) . It is still
> correct.
> As you told me, I consider that I can put this patch on my system, and I
> expect to get the patch inside the next release of IPVS.

        Yes

> Could you tell me in a few words what was the trouble ? I just see into
> the patch that you force ip_send_check(iph) to be done;

        Of course:

1. net/core/netfilter.c:nf_hook_slow() linearizes every packet.
Assume that when packet is fragmented we have all the fragments
in separate skbs. Such skbs are linked in chains when someone
calls ip_defrag() and by this way creates chain of skbs ordered
by offset. The purpose of skb_linearize is to reallocate
all skbs from this chain in one skb, useful for payload inspection.
In the cases when only IP+PROTO header is inspected we can work
with chain, without linearization. And we really do so.

2. Netfilter's connection tracking (net/ipv4/netfilter/ip_conntrack_core.c,
ip_ct_gather_frags) can linearize, call ip_defrag and ip_send_check.
ip_send_check is needed to fix the IP csum after calling ip_defrag()
because in 2.4 the reassembling does not fix the csum as in 2.2, it
is assumed that reassembling should happen only on local delivery
where the valid csum is not expected because the incoming csum is
already checked on each fragment.

3. If packet is delivered locally net/ipv4/ip_input.c:ip_local_deliver()
calls ip_defrag which returns skb with wrong csum but nobody cares,
the assumption is that this packet will not be sent.

4. The packet reaches LVS. As result, we don't know whether
ip_send_check is called after ip_defrag. We used to think that
the skb_is_nonlinear check remains as evidence that the packet
was fragmented, a mistake while the stopgap exists.

        So, how the bug happens:

- if netfilter connection tracking is used, ip_send_check is called
after ip_defrag and LVS has packet with valid IP csum.

- while the stopgap in nf_hook_slow exists we can not notice that
the packet was fragmented, so it depends whether netfilter done
the job for us

        Now, after introducing the Layer 8 factor (Julian) who
decided to test by removing the stopgap in nf_hook_slow(), you
see the result, with unpatched kernels the skbs are always linearized,
no matter ip_defrag is called for them.

        So, we add unconditional ip_send_check when we know the
packet will be forwarded to another host. We can not know that
someone fixed the csum after ip_defrag.


        Hm, what is this, tcpdump trying to calc TCP csum for
packets with MF bit set?:

> 14:10:52.709739 195.101.125.28.19678 > 195.6.241.14.smtp: . [bad tcp cksum
> 9749!] 88:1516(1428) ack 295 win 8466 (frag 22077:1448@0+) [tos 0x10] (ttl
> 124, len 1468)
> 14:10:52.709742 195.101.125.28 > 195.6.241.14: (frag 22077:32@1448) [tos
> 0x10]  (ttl 124, len 52)
> 14:10:52.709795 195.101.125.28.19678 > 195.6.241.14.smtp: . [tcp sum ok]
> 88:1548(1460) ack 295 win 8466 [tos 0x10]  (ttl 124, id 22077, len 1500)

> Frédéric BUCHE
> mailto : frederic.buche@xxxxxxxxxx

Regards

--
Julian Anastasov <ja@xxxxxx>



<Prev in Thread] Current Thread [Next in Thread>