Praveen Chaudhary <praveen5...@gmail.com> wrote: > Update skb->csum, when netfilter code updates IPV6 SRC\DST address in IPV6 > HEADER due to iptable rule. > > Signed-off-by: Praveen Chaudhary <pchaudh...@linkedin.com> > Signed-off-by: Zhenggen Xu <z...@linkedin.com> > Signed-off-by: Andy Stracner <astrac...@linkedin.com> > --- > include/net/checksum.h | 2 ++ > net/core/utils.c | 13 +++++++++++++ > net/netfilter/nf_nat_proto.c | 2 ++ > 3 files changed, 17 insertions(+) > > diff --git a/include/net/checksum.h b/include/net/checksum.h > index 97bf488..d7d28b7 100644 > --- a/include/net/checksum.h > +++ b/include/net/checksum.h > @@ -145,6 +145,8 @@ void inet_proto_csum_replace4(__sum16 *sum, struct > sk_buff *skb, > void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, > const __be32 *from, const __be32 *to, > bool pseudohdr); > +void inet_proto_skb_csum_replace16(struct sk_buff *skb, > + const __be32 *from, const __be32 *to); > void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, > __wsum diff, bool pseudohdr); > > diff --git a/net/core/utils.c b/net/core/utils.c > index 6b6e51d..ab3284b 100644 > --- a/net/core/utils.c > +++ b/net/core/utils.c > @@ -458,6 +458,19 @@ void inet_proto_csum_replace16(__sum16 *sum, struct > sk_buff *skb, > } > EXPORT_SYMBOL(inet_proto_csum_replace16); > > +void inet_proto_skb_csum_replace16(struct sk_buff *skb, > + const __be32 *from, const __be32 *to) > +{ > + __be32 diff[] = { > + ~from[0], ~from[1], ~from[2], ~from[3], > + to[0], to[1], to[2], to[3], > + }; > + if (skb->ip_summed == CHECKSUM_COMPLETE) > + skb->csum = csum_partial(diff, sizeof(diff), > + skb->csum); > +} > +EXPORT_SYMBOL(inet_proto_skb_csum_replace16); > + > void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, > __wsum diff, bool pseudohdr) > { > diff --git a/net/netfilter/nf_nat_proto.c b/net/netfilter/nf_nat_proto.c > index 0a59c14..de94590 100644 > --- a/net/netfilter/nf_nat_proto.c > +++ b/net/netfilter/nf_nat_proto.c > @@ -467,6 +467,8 @@ static void nf_nat_ipv6_csum_update(struct sk_buff *skb, > } > inet_proto_csum_replace16(check, skb, oldip->s6_addr32, > newip->s6_addr32, true); > + inet_proto_skb_csum_replace16(skb, oldip->s6_addr32, > + newip->s6_addr32);
This is confusing. You're saying that inet_proto_csum_replace16() is producing a wrong skb->csum. So why are you adding a new function to do the csum calculation instead of fixing inet_proto_csum_replace16() to do the right thing?