--- linux-2.4.19-smp/net/ipv4/ip_output.c.orig Mon May 13 23:34:37 2002 +++ linux-2.4.19-smp/net/ipv4/ip_output.c Mon Jun 17 23:13:28 2002 @@ -437,6 +437,8 @@ struct rtable *rt, int flags) { + struct sk_buff_head frags; + struct sk_buff * skb; unsigned int fraglen, maxfraglen, fragheaderlen; int err; int offset, mf; @@ -512,10 +514,10 @@ */ id = sk->protinfo.af_inet.id++; + skb_queue_head_init(&frags); do { char *data; - struct sk_buff * skb; /* * Get the memory we require with some space left for alignment. @@ -599,7 +601,11 @@ fraglen = maxfraglen; nfrags++; + __skb_queue_head(&frags, skb); + } while (offset >= 0); + /* Ensure we send fragments in order of increasing offset */ + while ((skb = __skb_dequeue(&frags)) != NULL) { err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dst->dev, output_maybe_reroute); if (err) { @@ -608,7 +614,7 @@ if (err) goto error; } - } while (offset >= 0); + } if (nfrags>1) ip_statistics[smp_processor_id()*2 + !in_softirq()].IpFragCreates += nfrags; @@ -617,6 +623,10 @@ error: IP_INC_STATS(IpOutDiscards); + while ((skb = __skb_dequeue(&frags)) != NULL) { + kfree_skb(skb); + nfrags--; + } if (nfrags>1) ip_statistics[smp_processor_id()*2 + !in_softirq()].IpFragCreates += nfrags; return err;