aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>2013-01-26 03:37:48 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2013-02-07 12:37:41 -0500
commitf5271fff56c76e92fde122bcc02f102e99da5c8a (patch)
tree88e0f58ea00fbc4f8652f92d915b40403aa38f3e /net/ipv6
parent4b47bc9a9e69141ed3a854c57601f548e82c78ba (diff)
netfilter: ip6t_NPT: Fix adjustment calculation
Cast __wsum from/to __sum16 is wrong. Instead, apply appropriate conversion function: csum_unfold() or csum_fold(). [ The original patch has been modified to undo the final ~ that csum_fold returns. We only need to fold the 32-bit word that results from the checksum calculation into a 16-bit to ensure that the original subnet is restored appropriately. Spotted by Ulrich Weber. ] Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/ip6t_NPT.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/net/ipv6/netfilter/ip6t_NPT.c b/net/ipv6/netfilter/ip6t_NPT.c
index 7302b0b7b642..68788c84aee7 100644
--- a/net/ipv6/netfilter/ip6t_NPT.c
+++ b/net/ipv6/netfilter/ip6t_NPT.c
@@ -30,7 +30,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par)
30 (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]); 30 (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]);
31 } 31 }
32 32
33 npt->adjustment = (__force __sum16) csum_sub(src_sum, dst_sum); 33 npt->adjustment = ~csum_fold(csum_sub(src_sum, dst_sum));
34 return 0; 34 return 0;
35} 35}
36 36
@@ -66,8 +66,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,
66 return false; 66 return false;
67 } 67 }
68 68
69 sum = (__force __sum16) csum_add((__force __wsum)addr->s6_addr16[idx], 69 sum = ~csum_fold(csum_add(csum_unfold((__force __sum16)addr->s6_addr16[idx]),
70 npt->adjustment); 70 csum_unfold(npt->adjustment)));
71 if (sum == CSUM_MANGLED_0) 71 if (sum == CSUM_MANGLED_0)
72 sum = 0; 72 sum = 0;
73 *(__force __sum16 *)&addr->s6_addr16[idx] = sum; 73 *(__force __sum16 *)&addr->s6_addr16[idx] = sum;