# HG changeset patch
# User Jon Mason <jdmason@xxxxxxxxxx>
# 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@xxxxxxxxxx>
Signed-off-by: Jon Mason <jdmason@xxxxxxxxxx>
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)
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|