LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

[PATCH ipvs] ipvs: invoke skb_checksum_help prior to encapsulation in tu

To: <horms@xxxxxxxxxxxx>
Subject: [PATCH ipvs] ipvs: invoke skb_checksum_help prior to encapsulation in tunnel xmit
Cc: <ja@xxxxxx>, <lvs-devel@xxxxxxxxxxxxxxx>, <agartrell@xxxxxx>, <kernel-team@xxxxxx>
From: Alex Gartrell <agartrell@xxxxxx>
Date: Wed, 23 Jul 2014 12:16:27 -0700
If we don't do this and we have hardware checksumming enabled, we'll simply
never actually checksum NF_INET_LOCAL_OUT tcp packets.  This is due to the
fact that the partially checksummed packet is plucked on it's way out of
the system and thrown through the ipvs machinery.  While the expectation
was that the NIC would be able to checksum the packet as it was, once we
place the packet into an ipip packet, the NIC can no longer fulfill that
expectation.  Thus, we send out random garbage, which is dropped by the
real server.

skb_checksum_help does the right things insofar as checking to see if the
checksum is only partial and then completing the checksum if it is, so we
can blindly call it on every packet and let it figure things out.

There's no reason to keep ip_send check either.

Signed-off-by: Alex Gartrell <agartrell@xxxxxx>
---
 net/netfilter/ipvs/ip_vs_xmit.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 6f70bdd..9c68089 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -862,10 +862,12 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn 
*cp,
                old_iph = ip_hdr(skb);
        }
 
-       skb->transport_header = skb->network_header;
+       /* We are about to encapsulate the ip header, which breaks hardware
+        * checksum offload.  Let's call skb_checksum_help to finish up any
+        * partial checksums */
+       skb_checksum_help(skb);
 
-       /* fix old IP header checksum */
-       ip_send_check(old_iph);
+       skb->transport_header = skb->network_header;
 
        skb_push(skb, sizeof(struct iphdr));
        skb_reset_network_header(skb);
@@ -953,6 +955,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct 
ip_vs_conn *cp,
                old_iph = ipv6_hdr(skb);
        }
 
+       /* We are about to encapsulate the ip header, which breaks hardware
+        * checksum offload.  Let's call skb_checksum_help to finish up any
+        * partial checksums */
+       skb_checksum_help(skb);
+
        skb->transport_header = skb->network_header;
 
        skb_push(skb, sizeof(struct ipv6hdr));
-- 
1.8.1

--
To unsubscribe from this list: send the line "unsubscribe lvs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH ipvs] ipvs: invoke skb_checksum_help prior to encapsulation in tunnel xmit, Alex Gartrell <=