rpms/kernel-xen-2.6/devel linux-2.6-csum-missing-line.patch, NONE, 1.3.2.1 linux-2.6-disable-netback-checksum.patch, NONE, 1.2.2.1 linux-2.6-forwarding_of_ip_summed.patch, NONE, 1.3.2.1 linux-2.6-kill_skbuff_hack.patch, NONE, 1.3.2.1 linux-2.6-treat_partial_as_unnecessary.patch, NONE, 1.3.2.1 linux-2.6-use_csum_start_offset_instead.patch, NONE, 1.3.2.1 kernel-xen.spec, 1.35, 1.35.2.1

Eduardo Habkost (ehabkost) fedora-extras-commits at redhat.com
Mon Aug 6 15:19:42 UTC 2007


Author: ehabkost

Update of /cvs/pkgs/rpms/kernel-xen-2.6/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv27102

Modified Files:
      Tag: private-ehabkost-testing-csum-patches
	kernel-xen.spec 
Added Files:
      Tag: private-ehabkost-testing-csum-patches
	linux-2.6-csum-missing-line.patch 
	linux-2.6-disable-netback-checksum.patch 
	linux-2.6-forwarding_of_ip_summed.patch 
	linux-2.6-kill_skbuff_hack.patch 
	linux-2.6-treat_partial_as_unnecessary.patch 
	linux-2.6-use_csum_start_offset_instead.patch 
Log Message:
Re-add checksum patches, now ported to xen-3.1.0



linux-2.6-csum-missing-line.patch:

--- NEW FILE linux-2.6-csum-missing-line.patch ---
Date: Sat, 28 Apr 2007 16:23:31 +1000
From: Herbert Xu <herbert.xu at redhat.com>
Subject: [XEN]: Set csum_start when setting csum_offset
Message-ID: <20070428062331.GA6461 at gondor.apana.org.au>

On Fri, Apr 27, 2007 at 09:40:03PM -0300, Eduardo Pereira Habkost wrote:
> 
> On CVS, rpms/kernel-xen-2.6/devel, branch private-ehabkost-xen-3_0_5-branch.

Thanks.  It looks like somewhere along the line I managed to
lose an important line in the patch.


The new csum model requires csum_start to be set for csum_offset to
be meaningful.

Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
Index: linux-2.6.20.i386/net/core/skbuff.c
===================================================================
--- linux-2.6.20.i386.orig/net/core/skbuff.c
+++ linux-2.6.20.i386/net/core/skbuff.c
@@ -2073,6 +2073,7 @@ int skb_checksum_setup(struct sk_buff *s
 	skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl;
 	if (skb->h.raw >= skb->tail)
 		goto out;
+	skb->csum_start = skb->h.raw - skb->head;
 	switch (skb->nh.iph->protocol) {
 	case IPPROTO_TCP:
 		skb->csum_offset = offsetof(struct tcphdr, check);

linux-2.6-disable-netback-checksum.patch:

--- NEW FILE linux-2.6-disable-netback-checksum.patch ---
From: Herbert Xu <herbert.xu at redhat.com>
Subject: Re: Final resolution for the checksum problems


Daniel P. Berrange <berrange at redhat.com> wrote:
>
>> > Alternatively we could just make netback default tx checksums to off
>> > which should have a similar effect as disabling it on virbr0.
>> 
>> This seems like a simpler path than introducing new infrastructure for
>> scripts to run every time the interface is brought up/down.  And then
>> it's even easier to remove the "trigger" when we get the functionality
>> in the kernel
> 
> I agree - this would be even simpler. 

Here is a patch which does just that.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
--- a/drivers/xen/netback/interface.c	2007-04-28 11:57:31.000000000 +1000
+++ b/drivers/xen/netback/interface.c	2007-05-02 19:58:16.000000000 +1000
@@ -161,7 +161,6 @@
 	dev->open            = net_open;
 	dev->stop            = net_close;
 	dev->change_mtu	     = netbk_change_mtu;
-	dev->features        = NETIF_F_IP_CSUM;
 
 	SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
 



linux-2.6-forwarding_of_ip_summed.patch:

--- NEW FILE linux-2.6-forwarding_of_ip_summed.patch ---
From: Herbert Xu <herbert.xu at redhat.com>
Subject: [1/4] [NET]: Allow forwarding of ip_summed except CHECKSUM_COMPLETE

Hi:

[NET]: Allow forwarding of ip_summed except CHECKSUM_COMPLETE

Right now Xen has a horrible hack that lets it forward packets with
partial checksums.  One of the reasons that CHECKSUM_PARTIAL and
CHECKSUM_COMPLETE were added is so that we can get rid of this hack
(where it creates two extra bits in the skbuff to essentially mirror
ip_summed without being destroyed by the forwarding code).

I had forgotten that I've already gone through all the deivce drivers
last time around to make sure that they're looking at ip_summed ==
CHECKSUM_PARTIAL rather than ip_summed != 0 on transmit.  In any case,
I've now done that again so it should definitely be safe.

Unfortunately nobody has yet added any code to update CHECKSUM_COMPLETE
values on forward so we I'm setting that to CHECKSUM_NONE.  This should
be safe to remove for bridging but I'd like to check that code path
first.

So here is the patch that lets us get rid of the hack by preserving
ip_summed (mostly) on forwarded packets.

Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff -ur linux-2.6.20.i386.orig/include/linux/skbuff.h linux-2.6.20.i386/include/linux/skbuff.h
--- linux-2.6.20.i386.orig/include/linux/skbuff.h	2007-04-24 13:18:41.000000000 +1000
+++ linux-2.6.20.i386/include/linux/skbuff.h	2007-04-24 13:31:01.000000000 +1000
@@ -1494,5 +1494,12 @@
 	return skb_shinfo(skb)->gso_size;
 }
 
+static inline void skb_forward_csum(struct sk_buff *skb)
+{
+	/* Unfortunately we don't support this one.  Any brave souls? */
+	if (skb->ip_summed == CHECKSUM_COMPLETE)
+		skb->ip_summed = CHECKSUM_NONE;
+}
+
 #endif	/* __KERNEL__ */
 #endif	/* _LINUX_SKBUFF_H */
diff -ur linux-2.6.20.i386.orig/net/bridge/br_forward.c linux-2.6.20.i386/net/bridge/br_forward.c
--- linux-2.6.20.i386.orig/net/bridge/br_forward.c	2007-03-30 13:39:09.000000000 +1000
+++ linux-2.6.20.i386/net/bridge/br_forward.c	2007-04-24 13:31:01.000000000 +1000
@@ -71,7 +71,7 @@
 
 	indev = skb->dev;
 	skb->dev = to->dev;
-	skb->ip_summed = CHECKSUM_NONE;
+	skb_forward_csum(skb);
 
 	NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
 			br_forward_finish);
diff -ur linux-2.6.20.i386.orig/net/ipv4/ip_forward.c linux-2.6.20.i386/net/ipv4/ip_forward.c
--- linux-2.6.20.i386.orig/net/ipv4/ip_forward.c	2007-03-30 13:39:10.000000000 +1000
+++ linux-2.6.20.i386/net/ipv4/ip_forward.c	2007-04-24 13:31:20.000000000 +1000
@@ -68,7 +68,7 @@
 	if (skb->pkt_type != PACKET_HOST)
 		goto drop;
 
-	skb->ip_summed = CHECKSUM_NONE;
+	skb_forward_csum(skb);
 	
 	/*
 	 *	According to the RFC, we must first decrease the TTL field. If
diff -ur linux-2.6.20.i386.orig/net/ipv6/ip6_output.c linux-2.6.20.i386/net/ipv6/ip6_output.c
--- linux-2.6.20.i386.orig/net/ipv6/ip6_output.c	2007-03-30 13:39:11.000000000 +1000
+++ linux-2.6.20.i386/net/ipv6/ip6_output.c	2007-04-24 13:31:01.000000000 +1000
@@ -372,7 +372,7 @@
 		goto drop;
 	}
 
-	skb->ip_summed = CHECKSUM_NONE;
+	skb_forward_csum(skb);
 
 	/*
 	 *	We DO NOT make any processing on



linux-2.6-kill_skbuff_hack.patch:

--- NEW FILE linux-2.6-kill_skbuff_hack.patch ---
From: Herbert Xu <herbert.xu at redhat.com>
Subject: [4/4] [XEN]: Kill skbuff hack

Hi:

This patch is based on the FC6 kernel.

[XEN]: Kill skbuff hack

Now that the Linux stack can accept packets with partial checksums and
relay them back out again, we can eliminate the skbuff hacks.

Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
Index: linux-2.6.20.i386/drivers/xen/netback/loopback.c
===================================================================
--- linux-2.6.20.i386.orig/drivers/xen/netback/loopback.c
+++ linux-2.6.20.i386/drivers/xen/netback/loopback.c
@@ -149,16 +149,6 @@ static int loopback_start_xmit(struct sk
 	np->stats.rx_bytes += skb->len;
 	np->stats.rx_packets++;
 
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		/* Defer checksum calculation. */
-		skb->proto_csum_blank = 1;
-		/* Must be a local packet: assert its integrity. */
-		skb->proto_data_valid = 1;
-	}
-
-	skb->ip_summed = skb->proto_data_valid ?
-		CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
-
 	skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
 	skb->protocol = eth_type_trans(skb, dev);
 	skb->dev      = dev;
Index: linux-2.6.20.i386/drivers/xen/netback/netback.c
===================================================================
--- linux-2.6.20.i386.orig/drivers/xen/netback/netback.c
+++ linux-2.6.20.i386/drivers/xen/netback/netback.c
@@ -263,7 +263,6 @@ int netif_be_start_xmit(struct sk_buff *
 		/* Copy only the header fields we use in this driver. */
 		nskb->dev = skb->dev;
 		nskb->ip_summed = skb->ip_summed;
-		nskb->proto_data_valid = skb->proto_data_valid;
 		dev_kfree_skb(skb);
 		skb = nskb;
 	}
@@ -649,9 +648,11 @@ static void net_rx_action(unsigned long 
 		id = meta[npo.meta_cons].id;
 		flags = nr_frags ? NETRXF_more_data : 0;
 
-		if (skb->ip_summed == CHECKSUM_PARTIAL) /* local packet? */
+		if (skb->ip_summed == CHECKSUM_PARTIAL)
+			/* local packet? */
 			flags |= NETRXF_csum_blank | NETRXF_data_validated;
-		else if (skb->proto_data_valid) /* remote but checksummed? */
+		else if (skb->ip_summed == CHECKSUM_UNNECESSARY)
+			/* remote but checksummed? */
 			flags |= NETRXF_data_validated;
 
 		if (meta[npo.meta_cons].copy)
@@ -1290,23 +1291,19 @@ static void net_tx_action(unsigned long 
 			netif_idx_release(pending_idx);
 		}
 
-		/*
-		 * Old frontends do not assert data_validated but we
-		 * can infer it from csum_blank so test both flags.
-		 */
-		if (txp->flags & (NETTXF_data_validated|NETTXF_csum_blank)) {
-			skb->ip_summed = CHECKSUM_UNNECESSARY;
-			skb->proto_data_valid = 1;
-		} else {
-			skb->ip_summed = CHECKSUM_NONE;
-			skb->proto_data_valid = 0;
-		}
-		skb->proto_csum_blank = !!(txp->flags & NETTXF_csum_blank);
-
 		netbk_fill_frags(skb);
 
 		skb->dev      = netif->dev;
 		skb->protocol = eth_type_trans(skb, skb->dev);
+		skb->nh.raw   = skb->data;
+
+		if (txp->flags & NETTXF_csum_blank) {
+			if (skb_checksum_setup(skb)) {
+				kfree_skb(skb);
+				continue;
+			}
+		} else if (txp->flags & NETTXF_data_validated)
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 		netif->stats.rx_bytes += skb->len;
 		netif->stats.rx_packets++;
Index: linux-2.6.20.i386/drivers/xen/netfront/netfront.c
===================================================================
--- linux-2.6.20.i386.orig/drivers/xen/netfront/netfront.c
+++ linux-2.6.20.i386/drivers/xen/netfront/netfront.c
@@ -978,12 +978,12 @@ static int network_start_xmit(struct sk_
 	tx->flags = 0;
 	extra = NULL;
 
-	if (skb->ip_summed == CHECKSUM_PARTIAL) /* local packet? */
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		/* local packet? */
 		tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
-#ifdef CONFIG_XEN
-	if (skb->proto_data_valid) /* remote but checksummed? */
+	else if (skb->ip_summed == CHECKSUM_UNNECESSARY)
+		/* remote but checksummed? */
 		tx->flags |= NETTXF_data_validated;
-#endif
 
 #ifdef HAVE_TSO
 	if (skb_is_gso(skb)) {
@@ -1404,20 +1404,10 @@ err:	
 		skb->truesize += skb->data_len - (RX_COPY_THRESHOLD - len);
 		skb->len += skb->data_len;
 
-		/*
-		 * Old backends do not assert data_validated but we
-		 * can infer it from csum_blank so test both flags.
-		 */
-		if (rx->flags & (NETRXF_data_validated|NETRXF_csum_blank))
+		if (rx->flags & NETRXF_csum_blank)
+			skb->ip_summed = CHECKSUM_PARTIAL;
+		else if (rx->flags & NETRXF_data_validated)
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
-		else
-			skb->ip_summed = CHECKSUM_NONE;
-#ifdef CONFIG_XEN
-		skb->proto_data_valid = (skb->ip_summed != CHECKSUM_NONE);
-		skb->proto_csum_blank = !!(rx->flags & NETRXF_csum_blank);
-#endif
-		np->stats.rx_packets++;
-		np->stats.rx_bytes += skb->len;
 
 		__skb_queue_tail(&rxq, skb);
 
@@ -1457,6 +1447,19 @@ err:	
 
 		/* Ethernet work: Delayed to here as it peeks the header. */
 		skb->protocol = eth_type_trans(skb, dev);
+		skb->nh.raw = skb->data;
+
+		if (skb->ip_summed == CHECKSUM_PARTIAL) {
+			if (skb_checksum_setup(skb)) {
+				work_done--;
+				kfree_skb(skb);
+				np->stats.rx_errors++;
+				continue;
+			}
+		}
+
+		np->stats.rx_packets++;
+		np->stats.rx_bytes += skb->len;
 
 		/* Pass it up. */
 		netif_receive_skb(skb);
Index: linux-2.6.20.i386/include/linux/skbuff.h
===================================================================
--- linux-2.6.20.i386.orig/include/linux/skbuff.h
+++ linux-2.6.20.i386/include/linux/skbuff.h
@@ -205,8 +205,6 @@ enum {
  *	@local_df: allow local fragmentation
  *	@cloned: Head may be cloned (check refcnt to be sure)
  *	@nohdr: Payload reference only, must not modify header
- *	@proto_data_valid: Protocol data validated since arriving at localhost
- *	@proto_csum_blank: Protocol csum must be added before leaving localhost
  *	@pkt_type: Packet class
  *	@fclone: skbuff clone status
  *	@ip_summed: Driver fed us an IP checksum
@@ -293,13 +291,7 @@ struct sk_buff {
 				nfctinfo:3;
 	__u8			pkt_type:3,
 				fclone:2,
-#ifndef CONFIG_XEN
 				ipvs_property:1;
-#else
-				ipvs_property:1,
-				proto_data_valid:1,
-				proto_csum_blank:1;
-#endif
 	__be16			protocol;
 
 	void			(*destructor)(struct sk_buff *skb);
@@ -1347,6 +1339,8 @@ extern void	       skb_split(struct sk_b
 
 extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
 
+extern int skb_checksum_setup(struct sk_buff *skb);
+
 static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
 				       int len, void *buffer)
 {
Index: linux-2.6.20.i386/net/core/dev.c
===================================================================
--- linux-2.6.20.i386.orig/net/core/dev.c
+++ linux-2.6.20.i386/net/core/dev.c
@@ -117,12 +117,6 @@
 #include <linux/err.h>
 #include <linux/ctype.h>
 
-#ifdef CONFIG_XEN
-#include <net/ip.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-#endif
-
 /*
  *	The list of packet types we will receive (as opposed to discard)
  *	and the routines to invoke.
@@ -1400,43 +1394,6 @@ out_kfree_skb:
 	}						\
 }
 
-#ifdef CONFIG_XEN
-inline int skb_checksum_setup(struct sk_buff *skb)
-{
-	if (skb->proto_csum_blank) {
-		if (skb->protocol != htons(ETH_P_IP))
-			goto out;
-		skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl;
-		if (skb->h.raw >= skb->tail)
-			goto out;
-		switch (skb->nh.iph->protocol) {
-		case IPPROTO_TCP:
-			skb->csum = offsetof(struct tcphdr, check);
-			break;
-		case IPPROTO_UDP:
-			skb->csum = offsetof(struct udphdr, check);
-			break;
-		default:
-			if (net_ratelimit())
-				printk(KERN_ERR "Attempting to checksum a non-"
-				       "TCP/UDP packet, dropping a protocol"
-				       " %d packet", skb->nh.iph->protocol);
-			goto out;
-		}
-		if ((skb->h.raw + skb->csum + 2) > skb->tail)
-			goto out;
-		skb->ip_summed = CHECKSUM_PARTIAL;
-		skb->proto_csum_blank = 0;
-	}
-	return 0;
-out:
-	return -EPROTO;
-}
-#else
-inline int skb_checksum_setup(struct sk_buff *skb) { return 0; }
-#endif
-
-
 /**
  *	dev_queue_xmit - transmit a buffer
  *	@skb: buffer to transmit
@@ -1469,12 +1426,6 @@ int dev_queue_xmit(struct sk_buff *skb)
 	struct Qdisc *q;
 	int rc = -ENOMEM;
 
- 	/* If a checksum-deferred packet is forwarded to a device that needs a
- 	 * checksum, correct the pointers and force checksumming.
- 	 */
- 	if (skb_checksum_setup(skb))
- 		goto out_kfree_skb;
-
 	/* GSO will handle the following emulations directly. */
 	if (netif_needs_gso(dev, skb))
 		goto gso;
@@ -1853,19 +1804,6 @@ int netif_receive_skb(struct sk_buff *sk
 	}
 #endif
 
-#ifdef CONFIG_XEN
-	switch (skb->ip_summed) {
-	case CHECKSUM_UNNECESSARY:
-		skb->proto_data_valid = 1;
-		break;
-	case CHECKSUM_PARTIAL:
-		/* XXX Implement me. */
-	default:
-		skb->proto_data_valid = 0;
-		break;
-	}
-#endif
-
 	list_for_each_entry_rcu(ptype, &ptype_all, list) {
 		if (!ptype->dev || ptype->dev == skb->dev) {
 			if (pt_prev) 
@@ -3632,7 +3570,6 @@ EXPORT_SYMBOL(unregister_netdevice_notif
 EXPORT_SYMBOL(net_enable_timestamp);
 EXPORT_SYMBOL(net_disable_timestamp);
 EXPORT_SYMBOL(dev_get_flags);
-EXPORT_SYMBOL(skb_checksum_setup);
 
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 EXPORT_SYMBOL(br_handle_frame_hook);
Index: linux-2.6.20.i386/net/core/skbuff.c
===================================================================
--- linux-2.6.20.i386.orig/net/core/skbuff.c
+++ linux-2.6.20.i386/net/core/skbuff.c
@@ -66,6 +66,11 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+#include <linux/if_ether.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <net/ip.h>
+
 #include "kmap_skb.h"
 
 static struct kmem_cache *skbuff_head_cache __read_mostly;
@@ -470,10 +475,6 @@ struct sk_buff *skb_clone(struct sk_buff
 	C(local_df);
 	n->cloned = 1;
 	n->nohdr = 0;
-#ifdef CONFIG_XEN
-	C(proto_data_valid);
-	C(proto_csum_blank);
-#endif
 	C(pkt_type);
 	C(ip_summed);
 	C(priority);
@@ -2065,6 +2066,38 @@ void __init skb_init(void)
 						NULL, NULL);
 }
 
+int skb_checksum_setup(struct sk_buff *skb)
+{
+	if (skb->protocol != htons(ETH_P_IP))
+		goto out;
+	skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl;
+	if (skb->h.raw >= skb->tail)
+		goto out;
+	switch (skb->nh.iph->protocol) {
+	case IPPROTO_TCP:
+		skb->csum_offset = offsetof(struct tcphdr, check);
+		break;
+	case IPPROTO_UDP:
+		skb->csum_offset = offsetof(struct udphdr, check);
+		break;
+	default:
+		if (net_ratelimit())
+			printk(KERN_ERR "Attempting to checksum a non-"
+			       "TCP/UDP packet, dropping a protocol"
+			       " %d packet", skb->nh.iph->protocol);
+		goto out;
+	}
+	if ((skb->h.raw + skb->csum_offset + 2) > skb->tail)
+		goto out;
+	skb->ip_summed = CHECKSUM_PARTIAL;
+
+	return 0;
+out:
+	return -EPROTO;
+}
+EXPORT_SYMBOL(skb_checksum_setup);
+
+
 EXPORT_SYMBOL(___pskb_trim);
 EXPORT_SYMBOL(__kfree_skb);
 EXPORT_SYMBOL(kfree_skb);
Index: linux-2.6.20.i386/net/ipv4/netfilter/ip_nat_proto_tcp.c
===================================================================
--- linux-2.6.20.i386.orig/net/ipv4/netfilter/ip_nat_proto_tcp.c
+++ linux-2.6.20.i386/net/ipv4/netfilter/ip_nat_proto_tcp.c
@@ -129,15 +129,8 @@ tcp_manip_pkt(struct sk_buff **pskb,
 	if (hdrsize < sizeof(*hdr))
 		return 1;
 
-#ifdef CONFIG_XEN
-	if ((*pskb)->proto_csum_blank)
-		nf_csum_replace4(&hdr->check, oldip, newip);
-	else
-#endif
-	{
 	nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
 	nf_proto_csum_replace2(&hdr->check, *pskb, oldport, newport, 0);
-	}
 	return 1;
 }
 
Index: linux-2.6.20.i386/net/ipv4/netfilter/ip_nat_proto_udp.c
===================================================================
--- linux-2.6.20.i386.orig/net/ipv4/netfilter/ip_nat_proto_udp.c
+++ linux-2.6.20.i386/net/ipv4/netfilter/ip_nat_proto_udp.c
@@ -115,16 +115,8 @@ udp_manip_pkt(struct sk_buff **pskb,
 	}
 
 	if (hdr->check || (*pskb)->ip_summed == CHECKSUM_PARTIAL) {
-#ifdef CONFIG_XEN
-		if ((*pskb)->proto_csum_blank)
-			nf_csum_replace4(&hdr->check, oldip, newip);
-		else
-#endif
-		{
 		nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
 		nf_proto_csum_replace2(&hdr->check, *pskb, *portptr, newport, 0);
-		}
-
 		if (!hdr->check)
 			hdr->check = CSUM_MANGLED_0;
 	}
Index: linux-2.6.20.i386/net/ipv4/xfrm4_output.c
===================================================================
--- linux-2.6.20.i386.orig/net/ipv4/xfrm4_output.c
+++ linux-2.6.20.i386/net/ipv4/xfrm4_output.c
@@ -18,8 +18,6 @@
 #include <net/xfrm.h>
 #include <net/icmp.h>
 
-extern int skb_checksum_setup(struct sk_buff *skb);
-
 static int xfrm4_tunnel_check_size(struct sk_buff *skb)
 {
 	int mtu, ret = 0;
@@ -49,10 +47,6 @@ static int xfrm4_output_one(struct sk_bu
 	struct dst_entry *dst = skb->dst;
 	struct xfrm_state *x = dst->xfrm;
 	int err;
-	
-	err = skb_checksum_setup(skb);
-	if (err)
-		goto error_nolock;
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		err = skb_checksum_help(skb);

linux-2.6-treat_partial_as_unnecessary.patch:

--- NEW FILE linux-2.6-treat_partial_as_unnecessary.patch ---
From: Herbert Xu <herbert.xu at redhat.com>
Subject: [3/4] [NET]: Treat CHECKSUM_PARTIAL as CHECKSUM_UNNECESSARY

Hi:

[NET]: Treat CHECKSUM_PARTIAL as CHECKSUM_UNNECESSARY

When a transmitted packet is looped back directly, CHECKSUM_PARTIAL
maps to the semantics of CHECKSUM_UNNECESSARY.  Therefore we should
treat it as such in the stack.

Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff -ur linux-2.6.20.i386.orig/include/linux/skbuff.h linux-2.6.20.i386/include/linux/skbuff.h
--- linux-2.6.20.i386.orig/include/linux/skbuff.h	2007-04-24 13:42:01.000000000 +1000
+++ linux-2.6.20.i386/include/linux/skbuff.h	2007-04-24 15:16:44.000000000 +1000
@@ -31,10 +31,11 @@
 #define HAVE_ALLOC_SKB		/* For the drivers to know */
 #define HAVE_ALIGNABLE_SKB	/* Ditto 8)		   */
 
+/* Don't change this without changing skb_csum_unnecessary! */
 #define CHECKSUM_NONE 0
-#define CHECKSUM_PARTIAL 1
-#define CHECKSUM_UNNECESSARY 2
-#define CHECKSUM_COMPLETE 3
+#define CHECKSUM_UNNECESSARY 1
+#define CHECKSUM_COMPLETE 2
+#define CHECKSUM_PARTIAL 3
 
 #define SKB_DATA_ALIGN(X)	(((X) + (SMP_CACHE_BYTES - 1)) & \
 				 ~(SMP_CACHE_BYTES - 1))
@@ -1401,6 +1402,11 @@
 
 extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
 
+static inline int skb_csum_unnecessary(const struct sk_buff *skb)
+{
+	return skb->ip_summed & CHECKSUM_UNNECESSARY;
+}
+
 /**
  *	skb_checksum_complete - Calculate checksum of an entire packet
  *	@skb: packet to process
@@ -1419,8 +1425,8 @@
  */
 static inline unsigned int skb_checksum_complete(struct sk_buff *skb)
 {
-	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
-		__skb_checksum_complete(skb);
+	return skb_csum_unnecessary(skb) ?
+	       0 : __skb_checksum_complete(skb);
 }
 
 #ifdef CONFIG_NETFILTER
diff -ur linux-2.6.20.i386.orig/include/net/tcp.h linux-2.6.20.i386/include/net/tcp.h
--- linux-2.6.20.i386.orig/include/net/tcp.h	2007-03-30 13:39:07.000000000 +1000
+++ linux-2.6.20.i386/include/net/tcp.h	2007-04-24 15:16:44.000000000 +1000
@@ -816,7 +816,7 @@
 
 static inline int tcp_checksum_complete(struct sk_buff *skb)
 {
-	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
+	return !skb_csum_unnecessary(skb) &&
 		__tcp_checksum_complete(skb);
 }
 
diff -ur linux-2.6.20.i386.orig/include/net/udp.h linux-2.6.20.i386/include/net/udp.h
--- linux-2.6.20.i386.orig/include/net/udp.h	2007-03-30 13:39:07.000000000 +1000
+++ linux-2.6.20.i386/include/net/udp.h	2007-04-24 15:16:44.000000000 +1000
@@ -80,7 +80,7 @@
 
 static inline int udp_lib_checksum_complete(struct sk_buff *skb)
 {
-	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
+	return !skb_csum_unnecessary(skb) &&
 		__udp_lib_checksum_complete(skb);
 }
 
diff -ur linux-2.6.20.i386.orig/net/core/netpoll.c linux-2.6.20.i386/net/core/netpoll.c
--- linux-2.6.20.i386.orig/net/core/netpoll.c	2007-03-30 13:39:09.000000000 +1000
+++ linux-2.6.20.i386/net/core/netpoll.c	2007-04-24 15:16:44.000000000 +1000
@@ -86,7 +86,7 @@
 {
 	__wsum psum;
 
-	if (uh->check == 0 || skb->ip_summed == CHECKSUM_UNNECESSARY)
+	if (uh->check == 0 || skb_csum_unnecessary(skb))
 		return 0;
 
 	psum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
diff -ur linux-2.6.20.i386.orig/net/ipv4/ipvs/ip_vs_core.c linux-2.6.20.i386/net/ipv4/ipvs/ip_vs_core.c
--- linux-2.6.20.i386.orig/net/ipv4/ipvs/ip_vs_core.c	2007-03-30 13:39:10.000000000 +1000
+++ linux-2.6.20.i386/net/ipv4/ipvs/ip_vs_core.c	2007-04-24 15:16:44.000000000 +1000
@@ -680,8 +680,7 @@
 	}
 
 	/* Ensure the checksum is correct */
-	if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
-	    ip_vs_checksum_complete(skb, ihl)) {
+	if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
 		/* Failed checksum! */
 		IP_VS_DBG(1, "Forward ICMP: failed checksum from %d.%d.%d.%d!\n",
 			  NIPQUAD(iph->saddr));
@@ -921,8 +920,7 @@
 	verdict = NF_DROP;
 
 	/* Ensure the checksum is correct */
-	if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
-	    ip_vs_checksum_complete(skb, ihl)) {
+	if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
 		/* Failed checksum! */
 		IP_VS_DBG(1, "Incoming ICMP: failed checksum from %d.%d.%d.%d!\n",
 			  NIPQUAD(iph->saddr));
diff -ur linux-2.6.20.i386.orig/net/ipv4/tcp_input.c linux-2.6.20.i386/net/ipv4/tcp_input.c
--- linux-2.6.20.i386.orig/net/ipv4/tcp_input.c	2007-03-30 13:39:10.000000000 +1000
+++ linux-2.6.20.i386/net/ipv4/tcp_input.c	2007-04-24 15:16:44.000000000 +1000
@@ -3775,7 +3775,7 @@
 	int err;
 
 	local_bh_enable();
-	if (skb->ip_summed==CHECKSUM_UNNECESSARY)
+	if (skb_csum_unnecessary(skb))
 		err = skb_copy_datagram_iovec(skb, hlen, tp->ucopy.iov, chunk);
 	else
 		err = skb_copy_and_csum_datagram_iovec(skb, hlen,
@@ -3807,7 +3807,7 @@
 
 static inline int tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
 {
-	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
+	return !skb_csum_unnecessary(skb) &&
 		__tcp_checksum_complete_user(sk, skb);
 }
 
@@ -3825,7 +3825,7 @@
 	if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
 		tp->ucopy.dma_chan = get_softnet_dma();
 
-	if (tp->ucopy.dma_chan && skb->ip_summed == CHECKSUM_UNNECESSARY) {
+	if (tp->ucopy.dma_chan && skb_csum_unnecessary(skb)) {
 
 		dma_cookie = dma_skb_copy_datagram_iovec(tp->ucopy.dma_chan,
 			skb, hlen, tp->ucopy.iov, chunk, tp->ucopy.pinned_list);
diff -ur linux-2.6.20.i386.orig/net/ipv4/tcp_ipv4.c linux-2.6.20.i386/net/ipv4/tcp_ipv4.c
--- linux-2.6.20.i386.orig/net/ipv4/tcp_ipv4.c	2007-04-24 15:09:28.000000000 +1000
+++ linux-2.6.20.i386/net/ipv4/tcp_ipv4.c	2007-04-24 15:16:44.000000000 +1000
@@ -1636,8 +1636,7 @@
 	 * Packet length and doff are validated by header prediction,
 	 * provided case of th->doff==0 is eliminated.
 	 * So, we defer the checks. */
-	if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
-	     tcp_v4_checksum_init(skb)))
+	if (!skb_csum_unnecessary(skb) && tcp_v4_checksum_init(skb))
 		goto bad_packet;
 
 	th = skb->h.th;
diff -ur linux-2.6.20.i386.orig/net/ipv4/udp.c linux-2.6.20.i386/net/ipv4/udp.c
--- linux-2.6.20.i386.orig/net/ipv4/udp.c	2007-04-24 15:10:23.000000000 +1000
+++ linux-2.6.20.i386/net/ipv4/udp.c	2007-04-24 15:18:08.000000000 +1000
@@ -839,7 +839,7 @@
 	 * 	          (re-)compute it if message is truncated.
 	 * 	UDP-Lite: always needs to checksum, no HW support.
 	 */
-	copy_only = (skb->ip_summed==CHECKSUM_UNNECESSARY);
+	copy_only = skb_csum_unnecessary(skb);
 
 	if (is_udplite  ||  (!copy_only  &&  msg->msg_flags&MSG_TRUNC)) {
 		if (__udp_lib_checksum_complete(skb))
@@ -1095,7 +1095,7 @@
 		}
 	}
 
-	if (sk->sk_filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
+	if (sk->sk_filter && !skb_csum_unnecessary(skb)) {
 		if (__udp_lib_checksum_complete(skb))
 			goto drop;
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1175,7 +1175,7 @@
 				      skb->len, IPPROTO_UDP, skb->csum       ))
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 	}
-	if (skb->ip_summed != CHECKSUM_UNNECESSARY)
+	if (!skb_csum_unnecessary(skb))
 		skb->csum = csum_tcpudp_nofold(skb->nh.iph->saddr,
 					       skb->nh.iph->daddr,
 					       skb->len, IPPROTO_UDP, 0);
diff -ur linux-2.6.20.i386.orig/net/ipv6/raw.c linux-2.6.20.i386/net/ipv6/raw.c
--- linux-2.6.20.i386.orig/net/ipv6/raw.c	2007-03-30 13:39:11.000000000 +1000
+++ linux-2.6.20.i386/net/ipv6/raw.c	2007-04-24 15:18:35.000000000 +1000
@@ -369,7 +369,7 @@
 				     skb->len, inet->num, skb->csum))
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 	}
-	if (skb->ip_summed != CHECKSUM_UNNECESSARY)
+	if (!skb_csum_unnecessary(skb))
 		skb->csum = ~csum_unfold(csum_ipv6_magic(&skb->nh.ipv6h->saddr,
 					     &skb->nh.ipv6h->daddr,
 					     skb->len, inet->num, 0));
@@ -421,7 +421,7 @@
   		msg->msg_flags |= MSG_TRUNC;
   	}
 
-	if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
+	if (skb_csum_unnecessary(skb)) {
 		err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 	} else if (msg->msg_flags&MSG_TRUNC) {
 		if (__skb_checksum_complete(skb))
diff -ur linux-2.6.20.i386.orig/net/ipv6/tcp_ipv6.c linux-2.6.20.i386/net/ipv6/tcp_ipv6.c
--- linux-2.6.20.i386.orig/net/ipv6/tcp_ipv6.c	2007-04-24 15:10:43.000000000 +1000
+++ linux-2.6.20.i386/net/ipv6/tcp_ipv6.c	2007-04-24 15:16:44.000000000 +1000
@@ -1705,8 +1705,7 @@
 	if (!pskb_may_pull(skb, th->doff*4))
 		goto discard_it;
 
-	if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
-	     tcp_v6_checksum_init(skb)))
+	if (!skb_csum_unnecessary(skb) && tcp_v6_checksum_init(skb))
 		goto bad_packet;
 
 	th = skb->h.th;
diff -ur linux-2.6.20.i386.orig/net/ipv6/udp.c linux-2.6.20.i386/net/ipv6/udp.c
--- linux-2.6.20.i386.orig/net/ipv6/udp.c	2007-03-30 13:39:11.000000000 +1000
+++ linux-2.6.20.i386/net/ipv6/udp.c	2007-04-24 15:19:35.000000000 +1000
@@ -144,7 +144,7 @@
 	/*
 	 * 	Decide whether to checksum and/or copy data.
 	 */
-	copy_only = (skb->ip_summed==CHECKSUM_UNNECESSARY);
+	copy_only = skb_csum_unnecessary(skb);
 
 	if (is_udplite  ||  (!copy_only  &&  msg->msg_flags&MSG_TRUNC)) {
 		if (__udp_lib_checksum_complete(skb))
@@ -382,7 +382,7 @@
 		    	     skb->len, IPPROTO_UDP, skb->csum             ))
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-	if (skb->ip_summed != CHECKSUM_UNNECESSARY)
+	if (!skb_csum_unnecessary(skb))
 		skb->csum = ~csum_unfold(csum_ipv6_magic(&skb->nh.ipv6h->saddr,
 							 &skb->nh.ipv6h->daddr,
 							 skb->len, IPPROTO_UDP,
diff -ur linux-2.6.20.i386.orig/net/sctp/input.c linux-2.6.20.i386/net/sctp/input.c
--- linux-2.6.20.i386.orig/net/sctp/input.c	2007-03-30 13:39:11.000000000 +1000
+++ linux-2.6.20.i386/net/sctp/input.c	2007-04-24 15:16:44.000000000 +1000
@@ -144,8 +144,7 @@
 	__skb_pull(skb, skb->h.raw - skb->data);
 	if (skb->len < sizeof(struct sctphdr))
 		goto discard_it;
-	if ((skb->ip_summed != CHECKSUM_UNNECESSARY) &&
-	    (sctp_rcv_checksum(skb) < 0))
+	if (!skb_csum_unnecessary(skb) && sctp_rcv_checksum(skb) < 0)
 		goto discard_it;
 
 	skb_pull(skb, sizeof(struct sctphdr));
diff -ur linux-2.6.20.i386.orig/net/sunrpc/socklib.c linux-2.6.20.i386/net/sunrpc/socklib.c
--- linux-2.6.20.i386.orig/net/sunrpc/socklib.c	2007-03-30 13:39:12.000000000 +1000
+++ linux-2.6.20.i386/net/sunrpc/socklib.c	2007-04-24 15:16:44.000000000 +1000
@@ -154,7 +154,7 @@
 	desc.offset = sizeof(struct udphdr);
 	desc.count = skb->len - desc.offset;
 
-	if (skb->ip_summed == CHECKSUM_UNNECESSARY)
+	if (skb_csum_unnecessary(skb))
 		goto no_checksum;
 
 	desc.csum = csum_partial(skb->data, desc.offset, skb->csum);



linux-2.6-use_csum_start_offset_instead.patch:

--- NEW FILE linux-2.6-use_csum_start_offset_instead.patch ---
From: Herbert Xu <herbert.xu at redhat.com>
Subject: [2/4] [NET]: Use csum_start offset instead of skb_transport_header

Hi:

Note this is based on the upstream net-2.6.22 tree so merging it
into anything before that will require undoing the transport header
changes.  Let me know if there are problems merging it.

[NET]: Use csum_start offset instead of skb_transport_header

The skb transport pointer is currently used to specify the start
of the checksum region for transmit checksum offload.  Unfortunately,
the same pointer is also used during receive side processing.

This creates a problem when we want to retransmit a received
packet with partial checksums since the skb transport pointer
would be overwritten.

This patch solves this problem by creating a new 16-bit csum_start
offset value to replace the skb transport header for the purpose
of checksums.  This offset is calculated from skb->head so that
it does not have to change when skb->data changes.

No extra space is required since csum_offset itself fits within
a 16-bit word so we can use the other 16 bits for csum_start.

For backwards compatibility, just before we push a packet with
partial checksums off into the device driver, we set the skb
transport header to what it would have been under the old scheme.

Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff -ur linux-2.6.20.i386.orig/include/linux/skbuff.h linux-2.6.20.i386/include/linux/skbuff.h
--- linux-2.6.20.i386.orig/include/linux/skbuff.h	2007-04-24 13:31:01.000000000 +1000
+++ linux-2.6.20.i386/include/linux/skbuff.h	2007-04-24 13:42:01.000000000 +1000
@@ -198,7 +198,9 @@
  *	@len: Length of actual data
  *	@data_len: Data length
  *	@mac_len: Length of link layer header
- *	@csum: Checksum
+ *	@csum: Checksum (must include start/offset pair)
+ *	@csum_start: Offset from skb->head where checksumming should start
+ *	@csum_offset: Offset from csum_start where checksum should be stored
  *	@local_df: allow local fragmentation
  *	@cloned: Head may be cloned (check refcnt to be sure)
  *	@nohdr: Payload reference only, must not modify header
@@ -276,7 +278,10 @@
 				mac_len;
 	union {
 		__wsum		csum;
-		__u32		csum_offset;
+		struct {
+			__u16	csum_start;
+			__u16	csum_offset;
+		};
 	};
 	__u32			priority;
 	__u8			local_df:1,
diff -ur linux-2.6.20.i386.orig/net/core/dev.c linux-2.6.20.i386/net/core/dev.c
--- linux-2.6.20.i386.orig/net/core/dev.c	2007-04-24 13:18:41.000000000 +1000
+++ linux-2.6.20.i386/net/core/dev.c	2007-04-24 15:14:04.000000000 +1000
@@ -1176,7 +1176,7 @@
 int skb_checksum_help(struct sk_buff *skb)
 {
 	__wsum csum;
-	int ret = 0, offset = skb->h.raw - skb->data;
+	int ret = 0, offset;
 
 	if (skb->ip_summed == CHECKSUM_COMPLETE)
 		goto out_set_summed;
@@ -1192,14 +1192,16 @@
 			goto out;
 	}
 
+	offset = skb->csum_start - skb_headroom(skb);
 	BUG_ON(offset > (int)skb->len);
 	csum = skb_checksum(skb, offset, skb->len-offset, 0);
 
-	offset = skb->tail - skb->h.raw;
+	offset = skb_headlen(skb) - offset;
 	BUG_ON(offset <= 0);
 	BUG_ON(skb->csum_offset + 2 > offset);
 
-	*(__sum16*)(skb->h.raw + skb->csum_offset) = csum_fold(csum);
+	*(__sum16 *)(skb->head + skb->csum_start + skb->csum_offset) =
+		csum_fold(csum);
 
 out_set_summed:
 	skb->ip_summed = CHECKSUM_NONE;
@@ -1494,12 +1496,15 @@
 	/* If packet is not checksummed and device does not support
 	 * checksumming for this protocol, complete checksumming here.
 	 */
-	if (skb->ip_summed == CHECKSUM_PARTIAL &&
-	    (!(dev->features & NETIF_F_GEN_CSUM) &&
-	     (!(dev->features & NETIF_F_IP_CSUM) ||
-	      skb->protocol != htons(ETH_P_IP))))
-	      	if (skb_checksum_help(skb))
-	      		goto out_kfree_skb;
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		skb->h.raw = skb->head + skb->csum_start;
+
+		if (!(dev->features & NETIF_F_GEN_CSUM) &&
+		    (!(dev->features & NETIF_F_IP_CSUM) ||
+		     skb->protocol != htons(ETH_P_IP)))
+		      	if (skb_checksum_help(skb))
+		      		goto out_kfree_skb;
+	}
 
 gso:
 	spin_lock_prefetch(&dev->queue_lock);
diff -ur linux-2.6.20.i386.orig/net/core/skbuff.c linux-2.6.20.i386/net/core/skbuff.c
--- linux-2.6.20.i386.orig/net/core/skbuff.c	2007-04-24 13:18:41.000000000 +1000
+++ linux-2.6.20.i386/net/core/skbuff.c	2007-04-24 15:08:07.000000000 +1000
@@ -1422,7 +1422,7 @@
 	long csstart;
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL)
-		csstart = skb->h.raw - skb->data;
+		csstart = skb->csum_start - skb_headroom(skb);
 	else
 		csstart = skb_headlen(skb);
 
diff -ur linux-2.6.20.i386.orig/net/ipv4/tcp_ipv4.c linux-2.6.20.i386/net/ipv4/tcp_ipv4.c
--- linux-2.6.20.i386.orig/net/ipv4/tcp_ipv4.c	2007-03-30 13:39:10.000000000 +1000
+++ linux-2.6.20.i386/net/ipv4/tcp_ipv4.c	2007-04-24 15:09:28.000000000 +1000
@@ -504,6 +504,7 @@
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		th->check = ~tcp_v4_check(th, len,
 					  inet->saddr, inet->daddr, 0);
+		skb->csum_start = skb->h.raw - skb->head;
 		skb->csum_offset = offsetof(struct tcphdr, check);
 	} else {
 		th->check = tcp_v4_check(th, len, inet->saddr, inet->daddr,
@@ -526,6 +527,7 @@
 
 	th->check = 0;
 	th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0);
+	skb->csum_start = skb->h.raw - skb->head;
 	skb->csum_offset = offsetof(struct tcphdr, check);
 	skb->ip_summed = CHECKSUM_PARTIAL;
 	return 0;
diff -ur linux-2.6.20.i386.orig/net/ipv4/udp.c linux-2.6.20.i386/net/ipv4/udp.c
--- linux-2.6.20.i386.orig/net/ipv4/udp.c	2007-04-24 13:18:40.000000000 +1000
+++ linux-2.6.20.i386/net/ipv4/udp.c	2007-04-24 15:10:23.000000000 +1000
@@ -425,6 +425,7 @@
 		/*
 		 * Only one fragment on the socket.
 		 */
+		skb->csum_start = skb->h.raw - skb->head;
 		skb->csum_offset = offsetof(struct udphdr, check);
 		uh->check = ~csum_tcpudp_magic(src, dst, len, IPPROTO_UDP, 0);
 	} else {
diff -ur linux-2.6.20.i386.orig/net/ipv6/tcp_ipv6.c linux-2.6.20.i386/net/ipv6/tcp_ipv6.c
--- linux-2.6.20.i386.orig/net/ipv6/tcp_ipv6.c	2007-03-30 13:39:11.000000000 +1000
+++ linux-2.6.20.i386/net/ipv6/tcp_ipv6.c	2007-04-24 15:10:43.000000000 +1000
@@ -948,6 +948,7 @@
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP,  0);
+		skb->csum_start = skb->h.raw - skb->head;
 		skb->csum_offset = offsetof(struct tcphdr, check);
 	} else {
 		th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 
@@ -970,6 +971,7 @@
 	th->check = 0;
 	th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,
 				     IPPROTO_TCP, 0);
+	skb->csum_start = skb->h.raw - skb->head;
 	skb->csum_offset = offsetof(struct tcphdr, check);
 	skb->ip_summed = CHECKSUM_PARTIAL;
 	return 0;




Index: kernel-xen.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/devel/kernel-xen.spec,v
retrieving revision 1.35
retrieving revision 1.35.2.1
diff -u -r1.35 -r1.35.2.1
--- kernel-xen.spec	20 Jul 2007 20:53:17 -0000	1.35
+++ kernel-xen.spec	6 Aug 2007 15:19:10 -0000	1.35.2.1
@@ -428,6 +428,16 @@
 Patch1620: linux-2.6-serial-tickle-nmi.patch
 Patch1650: linux-2.6-serial-460800.patch
 
+
+# checksum fixes (bug #223258)
+Patch1660: linux-2.6-forwarding_of_ip_summed.patch
+Patch1661: linux-2.6-use_csum_start_offset_instead.patch
+Patch1662: linux-2.6-treat_partial_as_unnecessary.patch
+Patch1663: linux-2.6-kill_skbuff_hack.patch
+Patch1664: linux-2.6-csum-missing-line.patch
+Patch1665: linux-2.6-disable-netback-checksum.patch
+
+
 Patch1681: linux-2.6-xfs-umount-fix.patch
 Patch1682: linux-2.6-xfs_attr2.patch
 Patch1690: linux-2.6-PT_LOAD-align.patch
@@ -972,6 +982,15 @@
 # Allow to use 480600 baud on 16C950 UARTs
 %patch1650 -p1
 
+# checksum fixes (bug #223258)
+%patch1660 -p1
+%patch1661 -p1
+%patch1662 -p1
+%patch1663 -p1
+%patch1664 -p1
+%patch1665 -p1
+
+
 # Fix XFS umount bug.
 %patch1681 -p1
 # Fix attr2 corruption with btree data extents
@@ -2003,6 +2022,9 @@
 #  - tux.
 
 %changelog
+* Mon Aug 06 2007 Eduardo Habkost <ehabkost at redhat.com>
+- Re-add checksum patches, now ported to xen-3.1.0
+
 * Wed Jul 20 2007 Eduardo Habkost <ehabkost at redhat.com>
 - Update xen patch to xen 3.1.0
 - Remove old network checksum patches. They should be




More information about the fedora-extras-commits mailing list