[PATCH ipvs] ipvs: invoke skb_checksum_help prior to encapsulation in tunnel xmit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Filesystem Devel]     [Linux NFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]     [X.Org]

  Powered by Linux