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); #endif } -- 2.7.4