On Sun, 25 Feb 2001, Chris Wedgwood wrote:

> On Fri, Feb 23, 2001 at 11:42:49AM +0100, Jan Rekorajski wrote:
>     
>     Could you please make a patch with this fix only? Or is it
>     available somewhere?
> 
[cut incomplete patch ;)]

There are more changes, I hacked'em out of vger CVS:

diff -urN linux/include/net/ip.h linux.fixed/include/net/ip.h
--- linux/include/net/ip.h      Thu Feb 22 01:10:38 2001
+++ linux.fixed/include/net/ip.h        Fri Feb 23 14:40:40 2001
@@ -188,11 +188,16 @@
 
 extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst);
 
-static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst)
+static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct 
+sock *sk)
 {
-       if (iph->frag_off&__constant_htons(IP_DF))
-               iph->id = 0;
-       else
+       if (iph->frag_off&__constant_htons(IP_DF)) {
+               /* This is only to work around buggy Windows95/2000
+                * VJ compression implementations.  If the ID field
+                * does not change, they drop every other packet in
+                * a TCP stream using header compression.
+                */
+               iph->id = (sk ? sk->protinfo.af_inet.id++ : 0);
+       } else
                __ip_select_ident(iph, dst);
 }
 
diff -urN linux/include/net/ipip.h linux.fixed/include/net/ipip.h
--- linux/include/net/ipip.h    Sat Aug  5 03:18:49 2000
+++ linux.fixed/include/net/ipip.h      Fri Feb 23 14:40:43 2001
@@ -30,7 +30,7 @@
        int pkt_len = skb->len;                                         \
                                                                        \
        iph->tot_len = htons(skb->len);                                 \
-       ip_select_ident(iph, &rt->u.dst);                               \
+       ip_select_ident(iph, &rt->u.dst, NULL);                         \
        ip_send_check(iph);                                             \
                                                                        \
        err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, do_ip_send); 
\
diff -urN linux/include/net/sock.h linux.fixed/include/net/sock.h
--- linux/include/net/sock.h    Thu Feb 22 01:10:24 2001
+++ linux.fixed/include/net/sock.h      Fri Feb 23 14:40:49 2001
@@ -204,6 +204,7 @@
        __u8                    mc_loop;                /* Loopback */
        unsigned                recverr : 1,
                                freebind : 1;
+       __u16                   id;                     /* ID counter for DF pkts */
        __u8                    pmtudisc;
        int                     mc_index;               /* Multicast device index */
        __u32                   mc_addr;
diff -urN linux/net/ipv4/af_inet.c linux.fixed/net/ipv4/af_inet.c
--- linux/net/ipv4/af_inet.c    Fri Dec 29 23:07:24 2000
+++ linux.fixed/net/ipv4/af_inet.c      Fri Feb 23 14:40:34 2001
@@ -355,6 +355,8 @@
        else
                sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
 
+       sk->protinfo.af_inet.id = 0;
+
        sock_init_data(sock,sk);
 
        sk->destruct = inet_sock_destruct;
diff -urN linux/net/ipv4/igmp.c linux.fixed/net/ipv4/igmp.c
--- linux/net/ipv4/igmp.c       Tue Jan  9 19:54:57 2001
+++ linux.fixed/net/ipv4/igmp.c Fri Feb 23 14:40:38 2001
@@ -235,7 +235,7 @@
        iph->saddr    = rt->rt_src;
        iph->protocol = IPPROTO_IGMP;
        iph->tot_len  = htons(IGMP_SIZE);
-       ip_select_ident(iph, &rt->u.dst);
+       ip_select_ident(iph, &rt->u.dst, NULL);
        ((u8*)&iph[1])[0] = IPOPT_RA;
        ((u8*)&iph[1])[1] = 4;
        ((u8*)&iph[1])[2] = 0;
diff -urN linux/net/ipv4/ip_output.c linux.fixed/net/ipv4/ip_output.c
--- linux/net/ipv4/ip_output.c  Fri Oct 27 20:03:14 2000
+++ linux.fixed/net/ipv4/ip_output.c    Fri Feb 23 14:54:17 2001
@@ -141,7 +141,7 @@
        iph->saddr    = rt->rt_src;
        iph->protocol = sk->protocol;
        iph->tot_len  = htons(skb->len);
-       ip_select_ident(iph, &rt->u.dst);
+       ip_select_ident(iph, &rt->u.dst, sk);
        skb->nh.iph   = iph;
 
        if (opt && opt->optlen) {
@@ -307,7 +307,7 @@
        if (ip_dont_fragment(sk, &rt->u.dst))
                iph->frag_off |= __constant_htons(IP_DF);
 
-       ip_select_ident(iph, &rt->u.dst);
+       ip_select_ident(iph, &rt->u.dst, sk);
 
        /* Add an IP checksum. */
        ip_send_check(iph);
@@ -328,7 +328,7 @@
                kfree_skb(skb);
                return -EMSGSIZE;
        }
-       ip_select_ident(iph, &rt->u.dst);
+       ip_select_ident(iph, &rt->u.dst, sk);
        return ip_fragment(skb, skb->dst->output);
 }
 
@@ -425,7 +425,7 @@
        int err;
        int offset, mf;
        int mtu;
-       u16 id = 0;
+       u16 id;
 
        int hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
        int nfrags=0;
@@ -495,6 +495,8 @@
         *      Begin outputting the bytes.
         */
 
+       id = (sk ? sk->protinfo.af_inet.id++ : 0);
+
        do {
                char *data;
                struct sk_buff * skb;
@@ -677,7 +679,7 @@
                iph->tot_len = htons(length);
                iph->frag_off = df;
                iph->ttl=sk->protinfo.af_inet.mc_ttl;
-               ip_select_ident(iph, &rt->u.dst);
+               ip_select_ident(iph, &rt->u.dst, sk);
                if (rt->rt_type != RTN_MULTICAST)
                        iph->ttl=sk->protinfo.af_inet.ttl;
                iph->protocol=sk->protocol;
diff -urN linux/net/ipv4/ipmr.c linux.fixed/net/ipv4/ipmr.c
--- linux/net/ipv4/ipmr.c       Wed Nov 29 06:53:45 2000
+++ linux.fixed/net/ipv4/ipmr.c Fri Feb 23 14:40:45 2001
@@ -1092,7 +1092,7 @@
        iph->protocol   =       IPPROTO_IPIP;
        iph->ihl        =       5;
        iph->tot_len    =       htons(skb->len);
-       ip_select_ident(iph, skb->dst);
+       ip_select_ident(iph, skb->dst, NULL);
        ip_send_check(iph);
 
        skb->h.ipiph = skb->nh.iph;
diff -urN linux/net/ipv4/raw.c linux.fixed/net/ipv4/raw.c
--- linux/net/ipv4/raw.c        Fri Feb  9 20:29:44 2001
+++ linux.fixed/net/ipv4/raw.c  Fri Feb 23 14:40:47 2001
@@ -296,7 +296,7 @@
                 *      ip_build_xmit clean (well less messy).
                 */
                if (!iph->id)
-                       ip_select_ident(iph, rfh->dst);
+                       ip_select_ident(iph, rfh->dst, NULL);
                iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl);
        }
        return 0;

> FWIW; I am still seeing _really_ bad throughput on a 10M ethernet
> segment between 2.4.2+zc-2 and Windows98 SE. Nobody else has
> complained so I guess it is something local (mii-tool for Windows
> wouldn't be a bad idea), but if the above doesn't work for you I'd
> been keen to know about it.

I hadn't the time to test it fully yet, but DaveM's quick and dirty patch
for this cured my problems.

Jan
-- 
Jan Rękorajski            |  ALL SUSPECTS ARE GUILTY. PERIOD!
baggins<at>mimuw.edu.pl   |  OTHERWISE THEY WOULDN'T BE SUSPECTS, WOULD THEY?
BOFH, MANIAC              |                   -- TROOPS by Kevin Rubio
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to