WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] The Xen checksum offload feature attempts to insert a TC

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] The Xen checksum offload feature attempts to insert a TCP/UDP
From: Xen patchbot -3.0-testing <patchbot-3.0-testing@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 22 Apr 2006 14:48:19 +0000
Delivery-date: Sat, 22 Apr 2006 07:58:17 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID a8da66acde0c2c06c85476c62e287bd1201a0715
# Parent  395e0186bd8981bd2067674e65a90e56585ebcd5
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@xxxxxxxxxx>
Signed-off-by: Jon Mason <jdmason@xxxxxxxxxx>

diff -r 395e0186bd89 -r a8da66acde0c linux-2.6-xen-sparse/net/core/dev.c
--- a/linux-2.6-xen-sparse/net/core/dev.c       Sat Apr 22 10:38:27 2006 +0100
+++ b/linux-2.6-xen-sparse/net/core/dev.c       Sat Apr 22 10:42:34 2006 +0100
@@ -1220,62 +1220,15 @@ int __skb_linearize(struct sk_buff *skb,
        }                                               \
 }
 
-/**
- *     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 @@ int dev_queue_xmit(struct sk_buff *skb)
                                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_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 395e0186bd89 -r a8da66acde0c patches/linux-2.6.16/net-csum.patch
--- a/patches/linux-2.6.16/net-csum.patch       Sat Apr 22 10:38:27 2006 +0100
+++ b/patches/linux-2.6.16/net-csum.patch       Sat Apr 22 10:42:34 2006 +0100
@@ -39,3 +39,26 @@ diff -pruN ../pristine-linux-2.6.16/net/
        *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)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

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