All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jon Mason <jdmason@us.ibm.com>
To: xen-devel@lists.xensource.com
Cc: dykman@us.ibm.com, jonmccune@cmu.edu
Subject: [PATCH] Fix IPSec for Xen checksum offload packets
Date: Fri, 21 Apr 2006 16:11:36 -0500	[thread overview]
Message-ID: <20060421211136.GA24108@us.ibm.com> (raw)

# HG changeset patch
# User Jon Mason <jdmason@us.ibm.com>
# Node ID 4f83fe4a8606d4a1f56f4ddd0badc0809cfe8a8c
# Parent  65894fff3649f58851fa59f38a66ab06e1244ba6

The Xen checksum offload feature attempts to insert a TCP/UDP
checksums into already encrypted packets (esp4) in dom0.  Obviously,
it is not possible to insert a checksum into an already encrypted
packet, so this patch inserts the checksum prior to encrypting
packets in net/ipv4/xfrm4_output.c.

To do this cleanly, the TCP/UDP header pointers need to be pointed to
the correct spot, so this functionality has been abstracted into a new
function.

This patch fixes bug 143 (verified by Jim Dykman).  Earlier version
verified by Jon McCune.

Signed-off-by: James Dykman <dykman@us.ibm.com>
Signed-off-by: Jon Mason <jdmason@us.ibm.com>

diff -r 65894fff3649 -r 4f83fe4a8606 linux-2.6-xen-sparse/net/core/dev.c
--- a/linux-2.6-xen-sparse/net/core/dev.c	Fri Apr 21 13:03:07 2006
+++ b/linux-2.6-xen-sparse/net/core/dev.c	Fri Apr 21 21:04:39 2006
@@ -1220,62 +1220,15 @@
 	}						\
 }
 
-/**
- *	dev_queue_xmit - transmit a buffer
- *	@skb: buffer to transmit
- *
- *	Queue a buffer for transmission to a network device. The caller must
- *	have set the device and priority and built the buffer before calling
- *	this function. The function can be called from an interrupt.
- *
- *	A negative errno code is returned on a failure. A success does not
- *	guarantee the frame will be transmitted as it may be dropped due
- *	to congestion or traffic shaping.
- *
- * -----------------------------------------------------------------------------------
- *      I notice this method can also return errors from the queue disciplines,
- *      including NET_XMIT_DROP, which is a positive value.  So, errors can also
- *      be positive.
- *
- *      Regardless of the return value, the skb is consumed, so it is currently
- *      difficult to retry a send to this method.  (You can bump the ref count
- *      before sending to hold a reference for retry if you are careful.)
- *
- *      When calling this method, interrupts MUST be enabled.  This is because
- *      the BH enable code must have IRQs enabled so that it will not deadlock.
- *          --BLG
- */
-
-int dev_queue_xmit(struct sk_buff *skb)
-{
-	struct net_device *dev = skb->dev;
-	struct Qdisc *q;
-	int rc = -ENOMEM;
-
-	if (skb_shinfo(skb)->frag_list &&
-	    !(dev->features & NETIF_F_FRAGLIST) &&
-	    __skb_linearize(skb, GFP_ATOMIC))
-		goto out_kfree_skb;
-
-	/* Fragmented skb is linearized if device does not support SG,
-	 * or if at least one of fragments is in highmem and device
-	 * does not support DMA from it.
-	 */
-	if (skb_shinfo(skb)->nr_frags &&
-	    (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
-	    __skb_linearize(skb, GFP_ATOMIC))
-		goto out_kfree_skb;
-
 #ifdef CONFIG_XEN
-	/* If a checksum-deferred packet is forwarded to a device that needs a
-	 * checksum, correct the pointers and force checksumming.
-	 */
+inline int skb_checksum_setup(struct sk_buff *skb)
+{
 	if (skb->proto_csum_blank) {
 		if (skb->protocol != htons(ETH_P_IP))
-			goto out_kfree_skb;
+			goto out;
 		skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl;
 		if (skb->h.raw >= skb->tail)
-			goto out_kfree_skb;
+			goto out;
 		switch (skb->nh.iph->protocol) {
 		case IPPROTO_TCP:
 			skb->csum = offsetof(struct tcphdr, check);
@@ -1288,16 +1241,74 @@
 				printk(KERN_ERR "Attempting to checksum a non-"
 				       "TCP/UDP packet, dropping a protocol"
 				       " %d packet", skb->nh.iph->protocol);
-			rc = -EPROTO;
-			goto out_kfree_skb;
+			goto out;
 		}
 		if ((skb->h.raw + skb->csum + 2) > skb->tail)
-			goto out_kfree_skb;
+			goto out;
 		skb->ip_summed = CHECKSUM_HW;
 		skb->proto_csum_blank = 0;
 	}
+	return 0;
+out:
+	return -EPROTO;
+}
+#else
+inline int skb_checksum_setup(struct sk_buff *skb) {}
 #endif
 
+
+/**
+ *	dev_queue_xmit - transmit a buffer
+ *	@skb: buffer to transmit
+ *
+ *	Queue a buffer for transmission to a network device. The caller must
+ *	have set the device and priority and built the buffer before calling
+ *	this function. The function can be called from an interrupt.
+ *
+ *	A negative errno code is returned on a failure. A success does not
+ *	guarantee the frame will be transmitted as it may be dropped due
+ *	to congestion or traffic shaping.
+ *
+ * -----------------------------------------------------------------------------------
+ *      I notice this method can also return errors from the queue disciplines,
+ *      including NET_XMIT_DROP, which is a positive value.  So, errors can also
+ *      be positive.
+ *
+ *      Regardless of the return value, the skb is consumed, so it is currently
+ *      difficult to retry a send to this method.  (You can bump the ref count
+ *      before sending to hold a reference for retry if you are careful.)
+ *
+ *      When calling this method, interrupts MUST be enabled.  This is because
+ *      the BH enable code must have IRQs enabled so that it will not deadlock.
+ *          --BLG
+ */
+
+int dev_queue_xmit(struct sk_buff *skb)
+{
+	struct net_device *dev = skb->dev;
+	struct Qdisc *q;
+	int rc = -ENOMEM;
+
+	if (skb_shinfo(skb)->frag_list &&
+	    !(dev->features & NETIF_F_FRAGLIST) &&
+	    __skb_linearize(skb, GFP_ATOMIC))
+		goto out_kfree_skb;
+
+	/* Fragmented skb is linearized if device does not support SG,
+	 * or if at least one of fragments is in highmem and device
+	 * does not support DMA from it.
+	 */
+	if (skb_shinfo(skb)->nr_frags &&
+	    (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
+	    __skb_linearize(skb, GFP_ATOMIC))
+		goto out_kfree_skb;
+
+ 	/* 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;
+  
 	/* If packet is not checksummed and device does not support
 	 * checksumming for this protocol, complete checksumming here.
 	 */
@@ -3351,6 +3362,7 @@
 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);
diff -r 65894fff3649 -r 4f83fe4a8606 patches/linux-2.6.16/net-csum.patch
--- a/patches/linux-2.6.16/net-csum.patch	Fri Apr 21 13:03:07 2006
+++ b/patches/linux-2.6.16/net-csum.patch	Fri Apr 21 21:04:39 2006
@@ -39,3 +39,26 @@
  	*portptr = newport;
  	return 1;
  }
+diff -r 601fa226a761 net/ipv4/xfrm4_output.c
+--- a/net/ipv4/xfrm4_output.c	Wed Apr 19 18:52:30 2006
++++ b/net/ipv4/xfrm4_output.c	Thu Apr 20 15:49:40 2006
+@@ -16,6 +16,8 @@
+ #include <net/ip.h>
+ #include <net/xfrm.h>
+ #include <net/icmp.h>
++
++extern int skb_checksum_setup(struct sk_buff *skb);
+ 
+ /* Add encapsulation header.
+  *
+@@ -103,6 +105,10 @@
+ 	struct xfrm_state *x = dst->xfrm;
+ 	int err;
+ 	
++	err = skb_checksum_setup(skb);
++	if (err)
++		goto error_nolock;
++
+ 	if (skb->ip_summed == CHECKSUM_HW) {
+ 		err = skb_checksum_help(skb, 0);
+ 		if (err)

             reply	other threads:[~2006-04-21 21:11 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-21 21:11 Jon Mason [this message]
  -- strict thread matches above, loose matches on Subject: below --
2006-02-06 19:43 [PATCH] Fix IPSec for Xen checksum offload packets Jon Mason

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=20060421211136.GA24108@us.ibm.com \
    --to=jdmason@us.ibm.com \
    --cc=dykman@us.ibm.com \
    --cc=jonmccune@cmu.edu \
    --cc=xen-devel@lists.xensource.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.