aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/ipvs/ip_vs_proto_udp.c
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2010-10-17 16:14:31 +0300
committerSimon Horman <horms@verge.net.au>2010-10-21 10:49:39 +0200
commit5bc9068e9d962ca6b8bec3f0eb6f60ab4dee1d04 (patch)
treefaa2317aa2a175a1dff24ab62447aeddda342b8e /net/netfilter/ipvs/ip_vs_proto_udp.c
parentd86bef73b4a24e59e7c1f896a72bbf38430ac2c6 (diff)
downloadkernel_samsung_smdk4412-5bc9068e9d962ca6b8bec3f0eb6f60ab4dee1d04.zip
kernel_samsung_smdk4412-5bc9068e9d962ca6b8bec3f0eb6f60ab4dee1d04.tar.gz
kernel_samsung_smdk4412-5bc9068e9d962ca6b8bec3f0eb6f60ab4dee1d04.tar.bz2
ipvs: fix CHECKSUM_PARTIAL for TCP, UDP
Fix CHECKSUM_PARTIAL handling. Tested for IPv4 TCP, UDP not tested because it needs network card with HW CSUM support. May be fixes problem where IPVS can not be used in virtual boxes. Problem appears with DNAT to local address when the local stack sends reply in CHECKSUM_PARTIAL mode. Fix tcp_dnat_handler and udp_dnat_handler to provide vaddr and daddr in right order (old and new IP) when calling tcp_partial_csum_update/udp_partial_csum_update (CHECKSUM_PARTIAL). Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/netfilter/ipvs/ip_vs_proto_udp.c')
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_udp.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
index 8553231..f929089 100644
--- a/net/netfilter/ipvs/ip_vs_proto_udp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
@@ -102,15 +102,15 @@ udp_partial_csum_update(int af, struct udphdr *uhdr,
#ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6)
uhdr->check =
- csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
+ ~csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
ip_vs_check_diff2(oldlen, newlen,
- ~csum_unfold(uhdr->check))));
+ csum_unfold(uhdr->check))));
else
#endif
uhdr->check =
- csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
+ ~csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
ip_vs_check_diff2(oldlen, newlen,
- ~csum_unfold(uhdr->check))));
+ csum_unfold(uhdr->check))));
}
@@ -229,7 +229,7 @@ udp_dnat_handler(struct sk_buff *skb,
* Adjust UDP checksums
*/
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
+ udp_partial_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr,
htons(oldlen),
htons(skb->len - udphoff));
} else if (!cp->app && (udph->check != 0)) {