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-devel

[Xen-devel] [PATCH] Fix checksum errors when firewalling in domU

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] Fix checksum errors when firewalling in domU
From: James Dykman <dykman@xxxxxxxxxx>
Date: Tue, 9 May 2006 15:22:07 -0400
Delivery-date: Tue, 09 May 2006 12:22:36 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Another checksum offload problem was reported on xen-users, when using a 
domU as a firewall:
http://lists.xensource.com/archives/html/xen-users/2006-04/msg01150.html
It also fails without VLANs.

The path from dom0->domU with ip_summed==CHECKSUM_HW/proto_csum_blank==1 
is broken.
- skb_checksum_setup() assumes that a checksum will definitely be 
calculated in dev_queue_xmit(), but
   the destination device is netback, which is advertising NETIF_F_IP_CSUM 
---> no checksum. So, 
   added reset_proto_csum_blank() to skbuff.h, and call it in 
dev_queue_xmit() and xfrm4_output() AFTER
   the checksum is calculated.
- The CHECKSUM_HW/proto_csum_blank vars are getting lost/stomped in 
various places. 

Tested on -unstable changeset 9925:
- The network xm-tests on -bridge and -route
- A domU firewalling between two bridges (similar to the error report, but 
without VLANs)
- The IPSec tunnel config from a previous checksum bug. (#143?)
I had to update the patch for the renamed patches/linux-2.6.16.13 
directory this morning. It compiles, but 
I haven't retested.

Signed-off-by: Jim Dykman <dykman@xxxxxxxxxx>
Fix checksum errors when firewalling in domU

diff -r 1e3977e029fd linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Mon May  8 
18:21:41 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Tue May  9 
13:38:56 2006
@@ -172,6 +172,7 @@
                BUG_ON(ret);
                nskb->dev = skb->dev;
                nskb->proto_data_valid = skb->proto_data_valid;
+               nskb->proto_csum_blank = skb->proto_csum_blank;
                dev_kfree_skb(skb);
                skb = nskb;
        }
@@ -340,6 +341,8 @@
                        flags |= NETRXF_csum_blank | 
NETRXF_data_validated;
                else if (skb->proto_data_valid) /* remote but checksummed? 
*/
                        flags |= NETRXF_data_validated;
+               else if (skb->proto_csum_blank) /* forwarded, !checksummed 
*/
+                       flags |= NETRXF_csum_blank;
                if (make_rx_response(netif, id, status,
                                     (unsigned long)skb->data & 
~PAGE_MASK,
                                     size, flags) &&
@@ -669,7 +672,10 @@
                 * can infer it from csum_blank so test both flags.
                 */
                if (txreq.flags & 
(NETTXF_data_validated|NETTXF_csum_blank)) {
-                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+                       if (txreq.flags & NETTXF_csum_blank)
+                               skb->ip_summed = CHECKSUM_HW;
+                       else
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;
                        skb->proto_data_valid = 1;
                } else {
                        skb->ip_summed = CHECKSUM_NONE;
diff -r 1e3977e029fd linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Mon May  8 
18:21:41 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue May  9 
13:38:56 2006
@@ -819,7 +819,10 @@
                 * can infer it from csum_blank so test both flags.
                 */
                if (rx->flags & (NETRXF_data_validated|NETRXF_csum_blank)) 
{
-                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+                       if (rx->flags & NETRXF_csum_blank)
+                               skb->ip_summed = CHECKSUM_HW;
+                       else
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;
                        skb->proto_data_valid = 1;
                } else {
                        skb->ip_summed = CHECKSUM_NONE;
diff -r 1e3977e029fd linux-2.6-xen-sparse/include/linux/skbuff.h
--- a/linux-2.6-xen-sparse/include/linux/skbuff.h       Mon May  8 
18:21:41 2006
+++ b/linux-2.6-xen-sparse/include/linux/skbuff.h       Tue May  9 
13:38:56 2006
@@ -1281,6 +1281,14 @@
 extern void skb_init(void);
 extern void skb_add_mtu(int mtu);

+#ifdef CONFIG_XEN
+static inline void reset_proto_csum_blank(struct sk_buff *skb)
+{
+       skb->proto_csum_blank=0;
+}
+#else
+static inline void reset_proto_csum_blank(const struct sk_buff *skb) { }
+#endif
 /**
  *     skb_get_timestamp - get timestamp from a skb
  *     @skb: skb to get stamp from
diff -r 1e3977e029fd linux-2.6-xen-sparse/net/core/dev.c
--- a/linux-2.6-xen-sparse/net/core/dev.c       Mon May  8 18:21:41 2006
+++ b/linux-2.6-xen-sparse/net/core/dev.c       Tue May  9 13:38:56 2006
@@ -1246,7 +1246,6 @@
                if ((skb->h.raw + skb->csum + 2) > skb->tail)
                        goto out;
                skb->ip_summed = CHECKSUM_HW;
-               skb->proto_csum_blank = 0;
        }
        return 0;
 out:
@@ -1315,9 +1314,11 @@
        if (skb->ip_summed == CHECKSUM_HW &&
            (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
             (!(dev->features & NETIF_F_IP_CSUM) ||
-             skb->protocol != htons(ETH_P_IP))))
+             skb->protocol != htons(ETH_P_IP)))) {
                if (skb_checksum_help(skb, 0))
                        goto out_kfree_skb;
+               reset_proto_csum_blank(skb);
+       }

        spin_lock_prefetch(&dev->queue_lock);

diff -r 1e3977e029fd patches/linux-2.6.16.13/net-csum.patch
--- a/patches/linux-2.6.16.13/net-csum.patch    Mon May  8 18:21:41 2006
+++ b/patches/linux-2.6.16.13/net-csum.patch    Tue May  9 13:38:56 2006
@@ -40,8 +40,8 @@
        return 1;
  }
 diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/xfrm4_output.c 
./net/ipv4/xfrm4_output.c
---- ../pristine-linux-2.6.16.13/net/ipv4/xfrm4_output.c        2006-05-02 
22:38:44.000000000 +0100
-+++ ./net/ipv4/xfrm4_output.c  2006-05-04 17:41:37.000000000 +0100
+--- ../pristine-linux-2.6.16.13/net/ipv4/xfrm4_output.c        2006-05-02 
17:38:44.000000000 -0400
++++ ./net/ipv4/xfrm4_output.c  2006-05-09 13:08:15.000000000 -0400
 @@ -17,6 +17,8 @@
  #include <net/xfrm.h>
  #include <net/icmp.h>
@@ -51,7 +51,7 @@
  /* Add encapsulation header.
   *
   * In transport mode, the IP header will be moved forward to make space
-@@ -103,6 +105,10 @@ static int xfrm4_output_one(struct sk_bu
+@@ -103,10 +105,15 @@ static int xfrm4_output_one(struct sk_bu
        struct xfrm_state *x = dst->xfrm;
        int err;

@@ -62,3 +62,8 @@
        if (skb->ip_summed == CHECKSUM_HW) {
                err = skb_checksum_help(skb, 0);
                if (err)
+                       goto error_nolock;
++              reset_proto_csum_blank(skb);
+       }
+
+       if (x->props.mode) {

Attachment: vlanfw.patch
Description: Binary data

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