netfilter: ip6t_NPT: Fix checksuming.
Subsystems (2)
RFC PATCH 1/4 netfilter: ip6t_NPT: Fix checksuming.
Cast __wsum from/to __sum16 is wrong. Instead, apply appropriate conversion function: csum_unfold() or csum_fold().
--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/ipv6/netfilter/ip6t_NPT.c +3 -3
@@ -30,7 +30,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]); } - npt->adjustment = (__force __sum16 )csum_sub (src_sum, dst_sum); + npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum));return 0 ; }
@@ -66,8 +66,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,return false; } - sum = (__force __sum16 )csum_add ((__force __wsum )addr->s6_addr16[idx], - npt->adjustment); + sum =csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), +csum_unfold (npt->adjustment)));if (sum ==CSUM_MANGLED_0 ) sum =0 ; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;
Signature · 1 line
1.7.9.5
Hi Yoshofuji,
thanks for your patches! If I add a onces complement to the return value of csum_fold() it works for my setup.
Cheers
Ulrich
Quoted 33 lines · YOSHIFUJI Hideaki
Cast
__wsumfrom/to__sum16is wrong. Instead, apply appropriate conversion function:csum_unfold()orcsum_fold().Signed-off-by YOSHIFUJI Hideaki <[email protected]>--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)net/ipv6/netfilter/ip6t_NPT.c +3
-3@@ -30,7 +30,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]); } - npt->adjustment = (__force __sum16 )csum_sub (src_sum, dst_sum); + npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum));return 0 ; }@@ -66,8 +66,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,return false; } - sum = (__force __sum16 )csum_add ((__force __wsum )addr->s6_addr16[idx], - npt->adjustment); + sum =csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), +csum_unfold (npt->adjustment)));if (sum ==CSUM_MANGLED_0 ) sum =0 ; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;
Quoted 1 line
From
40e0c6d86514a8dcc80f18fbe8a2945c6ee78f6dMon Sep 17 00:00:00 2001
From: Ulrich Weber <[email protected]>
Date: Tue, 29 Jan 2013 15:24:21 +0100
Subject: [PATCH] netfilter: ip6t_NTP: Use onces complement of csum_fold
we need a 16bit value but not folded
--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/ipv6/netfilter/ip6t_NPT.c +3 -3
@@ -35,7 +35,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) src_sum =csum_partial (&npt->src_pfx.in6,sizeof (npt->src_pfx.in6),0 ); dst_sum =csum_partial (&npt->dst_pfx.in6,sizeof (npt->dst_pfx.in6),0 ); - npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum)); + npt->adjustment = ~csum_fold (csum_sub (src_sum, dst_sum));return 0 ; }
@@ -71,8 +71,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,return false; } - sum =csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), -csum_unfold (npt->adjustment))); + sum = ~csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), +csum_unfold (npt->adjustment)));if (sum ==CSUM_MANGLED_0 ) sum =0 ; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;
Signature · 1 line
1.7.9.5
Pablo Neira Ayuso
maintainerHi,
Quoted 4 lines · Ulrich Weber
Hi Yoshofuji,
thanks for your patches! If I add a onces complement to the return value of
csum_fold()it works for my setup.
Any consensus on the fix for this? I'd like to have some solution into 3.8-rc.
Thanks.
Quoted 74 lines · YOSHIFUJI Hideaki
Quoted 22 lines
Cast
__wsumfrom/to__sum16is wrong. Instead, apply appropriate conversion function:csum_unfold()orcsum_fold().Signed-off-by YOSHIFUJI Hideaki <[email protected]>--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)net/ipv6/netfilter/ip6t_NPT.c +1
-1@@ -30,7 +30,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]); } - npt->adjustment = (__force __sum16 )csum_sub (src_sum, dst_sum); + npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum));return 0 ; }net/ipv6/netfilter/ip6t_NPT.c static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, · line 73
Quoted 10 lines
net/ipv6/netfilter/ip6t_NPT.c +2
-2@@ -66,8 +66,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,return false; } - sum = (__force __sum16 )csum_add ((__force __wsum )addr->s6_addr16[idx], - npt->adjustment); + sum =csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), +csum_unfold (npt->adjustment)));if (sum ==CSUM_MANGLED_0 ) sum =0 ; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;From
40e0c6d86514a8dcc80f18fbe8a2945c6ee78f6dMon Sep 17 00:00:00 2001
From: Ulrich Weber <[email protected]>
Date: Tue, 29 Jan 2013 15:24:21 +0100
Subject: [PATCH] netfilter:ip6t_NTP: Use onces complement ofcsum_foldwe need a 16bit value but not folded
Signed-off-by Ulrich Weber <[email protected]>--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)net/ipv6/netfilter/ip6t_NPT.c +3
-3@@ -35,7 +35,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) src_sum =csum_partial (&npt->src_pfx.in6,sizeof (npt->src_pfx.in6),0 ); dst_sum =csum_partial (&npt->dst_pfx.in6,sizeof (npt->dst_pfx.in6),0 ); - npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum)); + npt->adjustment = ~csum_fold (csum_sub (src_sum, dst_sum));return 0 ; }@@ -71,8 +71,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,return false; } - sum =csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), -csum_unfold (npt->adjustment))); + sum = ~csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), +csum_unfold (npt->adjustment)));if (sum ==CSUM_MANGLED_0 ) sum =0 ; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;Signature · 1 line
1.7.9.5
From my side, apply yoshofuji patches and my
onces complement patch, that worked for me ;)
I can do some more testing tomorrow with different addresses and ranges if nobody else finds time...
Cheers
Ulrich
Quoted 84 lines · Pablo Neira Ayuso
Hi,
Quoted 4 lines · Ulrich Weber
Hi Yoshofuji,
thanks for your patches! If I add a onces complement to the return value of
csum_fold()it works for my setup.Any consensus on the fix for this? I'd like to have some solution into 3.8-rc.
Thanks.
Quoted 72 lines · YOSHIFUJI Hideaki
Quoted 22 lines
Cast
__wsumfrom/to__sum16is wrong. Instead, apply appropriate conversion function:csum_unfold()orcsum_fold().Signed-off-by YOSHIFUJI Hideaki <[email protected]>--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)net/ipv6/netfilter/ip6t_NPT.c +1
-1@@ -30,7 +30,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]); } - npt->adjustment = (__force __sum16 )csum_sub (src_sum, dst_sum); + npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum));return 0 ; }net/ipv6/netfilter/ip6t_NPT.c static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, · line 73
Quoted 10 lines
net/ipv6/netfilter/ip6t_NPT.c +2
-2@@ -66,8 +66,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,return false; } - sum = (__force __sum16 )csum_add ((__force __wsum )addr->s6_addr16[idx], - npt->adjustment); + sum =csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), +csum_unfold (npt->adjustment)));if (sum ==CSUM_MANGLED_0 ) sum =0 ; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;From
40e0c6d86514a8dcc80f18fbe8a2945c6ee78f6dMon Sep 17 00:00:00 2001
From: Ulrich Weber <[email protected]>
Date: Tue, 29 Jan 2013 15:24:21 +0100
Subject: [PATCH] netfilter:ip6t_NTP: Use onces complement ofcsum_foldwe need a 16bit value but not folded
Signed-off-by Ulrich Weber <[email protected]>--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)net/ipv6/netfilter/ip6t_NPT.c +3
-3@@ -35,7 +35,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) src_sum =csum_partial (&npt->src_pfx.in6,sizeof (npt->src_pfx.in6),0 ); dst_sum =csum_partial (&npt->dst_pfx.in6,sizeof (npt->dst_pfx.in6),0 ); - npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum)); + npt->adjustment = ~csum_fold (csum_sub (src_sum, dst_sum));return 0 ; }@@ -71,8 +71,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,return false; } - sum =csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), -csum_unfold (npt->adjustment))); + sum = ~csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), +csum_unfold (npt->adjustment)));if (sum ==CSUM_MANGLED_0 ) sum =0 ; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;Signature · 1 line
1.7.9.5
I'll make some tests this week-end. I have had no time theses days.
Regards,
Jean-Michel
Quoted 90 lines · Ulrich Weber
From my side, apply yoshofuji patches and my
onces complement patch, that worked for me ;)I can do some more testing tomorrow with different addresses and ranges if nobody else finds time...
Cheers
UlrichQuoted 78 lines · Pablo Neira Ayuso
Hi,
Quoted 4 lines · Ulrich Weber
Hi Yoshofuji,
thanks for your patches! If I add a onces complement to the return value of
csum_fold()it works for my setup.Any consensus on the fix for this? I'd like to have some solution into 3.8-rc.
Thanks.
Quoted 66 lines · YOSHIFUJI Hideaki
Quoted 19 lines
Cast
__wsumfrom/to__sum16is wrong. Instead, apply appropriate conversion function:csum_unfold()orcsum_fold().Signed-off-by YOSHIFUJI Hideaki <[email protected]>--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)net/ipv6/netfilter/ip6t_NPT.c +1
-0@@ -30,7 +30,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]); } - npt->adjustment = (__force __sum16 )csum_sub (src_sum, dst_sum); + npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum));return 0 ; }net/ipv6/netfilter/ip6t_NPT.c static int ip6t_npt_checkentry(const struct xt_tgchk_param *par)
Quoted 10 lines
net/ipv6/netfilter/ip6t_NPT.c +2
-1@@ -66,8 +66,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, return false; } - sum = (__force __sum16 )csum_add ((__force __wsum )addr->s6_addr16[idx], - npt->adjustment); + sum =csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), + csum_unfold(npt->adjustment)));if (sum ==CSUM_MANGLED_0 ) sum =0 ; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;From
40e0c6d86514a8dcc80f18fbe8a2945c6ee78f6dMon Sep 17 00:00:00 2001
From: Ulrich Weber <[email protected]>
Date: Tue, 29 Jan 2013 15:24:21 +0100
Subject: [PATCH] netfilter:ip6t_NTP: Use onces complement ofcsum_foldwe need a 16bit value but not folded
Signed-off-by Ulrich Weber <[email protected]>--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)net/ipv6/netfilter/ip6t_NPT.c +3
-1@@ -35,7 +35,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) src_sum =csum_partial (&npt->src_pfx.in6,sizeof (npt->src_pfx.in6),0 ); dst_sum =csum_partial (&npt->dst_pfx.in6,sizeof (npt->dst_pfx.in6),0 ); - npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum)); + npt->adjustment = ~csum_fold (csum_sub (src_sum, dst_sum));return 0 ; } @@ -71,8 +71,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, return false; } - sum = csum_fold(csum_add(csum_unfold((__force __sum16)addr->s6_addr16[idx]), -csum_unfold (npt->adjustment))); + sum = ~csum_fold(csum_add(csum_unfold((__force __sum16)addr->s6_addr16[idx]), + csum_unfold(npt->adjustment))); if (sum == CSUM_MANGLED_0) sum = 0; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;Signature · 1 line
1.7.9.5
Looks good from here. :)
Regards,
JMichel DILLY
Quoted 90 lines · Ulrich Weber
From my side, apply yoshofuji patches and my
onces complement patch, that worked for me ;)I can do some more testing tomorrow with different addresses and ranges if nobody else finds time...
Cheers
UlrichQuoted 78 lines · Pablo Neira Ayuso
Hi,
Quoted 4 lines · Ulrich Weber
Hi Yoshofuji,
thanks for your patches! If I add a onces complement to the return value of
csum_fold()it works for my setup.Any consensus on the fix for this? I'd like to have some solution into 3.8-rc.
Thanks.
Quoted 66 lines · YOSHIFUJI Hideaki
Quoted 19 lines
Cast
__wsumfrom/to__sum16is wrong. Instead, apply appropriate conversion function:csum_unfold()orcsum_fold().Signed-off-by YOSHIFUJI Hideaki <[email protected]>--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)net/ipv6/netfilter/ip6t_NPT.c +1
-0@@ -30,7 +30,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]); } - npt->adjustment = (__force __sum16 )csum_sub (src_sum, dst_sum); + npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum));return 0 ; }net/ipv6/netfilter/ip6t_NPT.c static int ip6t_npt_checkentry(const struct xt_tgchk_param *par)
Quoted 10 lines
net/ipv6/netfilter/ip6t_NPT.c +2
-1@@ -66,8 +66,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, return false; } - sum = (__force __sum16 )csum_add ((__force __wsum )addr->s6_addr16[idx], - npt->adjustment); + sum =csum_fold (csum_add (csum_unfold ((__force __sum16 )addr->s6_addr16[idx]), + csum_unfold(npt->adjustment)));if (sum ==CSUM_MANGLED_0 ) sum =0 ; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;From
40e0c6d86514a8dcc80f18fbe8a2945c6ee78f6dMon Sep 17 00:00:00 2001
From: Ulrich Weber <[email protected]>
Date: Tue, 29 Jan 2013 15:24:21 +0100
Subject: [PATCH] netfilter:ip6t_NTP: Use onces complement ofcsum_foldwe need a 16bit value but not folded
Signed-off-by Ulrich Weber <[email protected]>--- net/ipv6/netfilter/ip6t_NPT.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)net/ipv6/netfilter/ip6t_NPT.c +3
-1@@ -35,7 +35,7 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) src_sum =csum_partial (&npt->src_pfx.in6,sizeof (npt->src_pfx.in6),0 ); dst_sum =csum_partial (&npt->dst_pfx.in6,sizeof (npt->dst_pfx.in6),0 ); - npt->adjustment =csum_fold (csum_sub (src_sum, dst_sum)); + npt->adjustment = ~csum_fold (csum_sub (src_sum, dst_sum));return 0 ; } @@ -71,8 +71,8 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, return false; } - sum = csum_fold(csum_add(csum_unfold((__force __sum16)addr->s6_addr16[idx]), -csum_unfold (npt->adjustment))); + sum = ~csum_fold(csum_add(csum_unfold((__force __sum16)addr->s6_addr16[idx]), + csum_unfold(npt->adjustment))); if (sum == CSUM_MANGLED_0) sum = 0; *(__force __sum16 *)&addr->s6_addr16[idx] = sum;Signature · 1 line
1.7.9.5
Quoted 2 lines · YOSHIFUJI Hideaki
Cast
__wsumfrom/to__sum16is wrong. Instead, apply appropriate conversion function:csum_unfold()orcsum_fold().
Applied.
I have mangled this patch by collapsing Ulrich's:
http://patchwork.ozlabs.org/patch/216563/
And I have added this to the description:
[ 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. ]
Thanks.