Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751802AbdLNLhX (ORCPT ); Thu, 14 Dec 2017 06:37:23 -0500 Received: from ec2-13-54-119-68.ap-southeast-2.compute.amazonaws.com ([13.54.119.68]:39510 "EHLO mail.hermana.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751489AbdLNLhW (ORCPT ); Thu, 14 Dec 2017 06:37:22 -0500 From: Brendan McGrath To: Eric Dumazet , "David S . Miller" Cc: Marcelo Ricardo Leitner , Alexey Kuznetsov , Hideaki YOSHIFUJI , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Brendan McGrath Subject: [PATCHv2] ipv6: ip6mr: Recalc UDP checksum before forwarding Date: Thu, 14 Dec 2017 22:37:03 +1100 Message-Id: <1513251423-4166-1-git-send-email-redmcg@redmandi.dyndns.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513187564.25033.65.camel@gmail.com> References: <1513187564.25033.65.camel@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1877 Lines: 58 Currently, when forwarding a multicast packet originating from a Virtual Interface on a Multicast Router to one of its Physical Interfaces, ip_summed is set to a value of CHECKSUM_UNNECESSARY and the UDP checksum is not calculated. The checksum value of the forwarded packet is left as is and therefore rejected by the receiving machine(s). This patch ensures the checksum is recalculated before forwarding. Signed-off-by: Brendan McGrath --- Changes since PATCH v1: - fixed formatting - clarified in git comment that issue is with packet originating on multicast router - check value of pkt_type instead of ip_summed To gaurentee we don't correct the checksum on a packet that was corrupted beforehand, I changed the code to check if pkt_type is PACKET_LOOPBACK. I also found that ip_summed is set to CHECKSUM_UNNECESSARY in dev_loopback_xmit. So every packet that originates and is forwarded by the same host will have ip_summed set to CHECKSUM_UNNECESSARY. Note that this scenario appears to be unique to multicasting as unicast always originates on the interface where the packet will be sent (thus a unicast packet is never forwarded by the host on which it originates). net/ipv6/ip6mr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 890f9bda..96f035f 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -2077,6 +2077,14 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt, ipv6h = ipv6_hdr(skb); ipv6h->hop_limit--; + if (ipv6h->nexthdr == NEXTHDR_UDP && + skb->pkt_type == PACKET_LOOPBACK) { + struct udphdr *uh = udp_hdr(skb); + + udp6_set_csum(false, skb, &ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, ntohs(uh->len)); + } + IP6CB(skb)->flags |= IP6SKB_FORWARDED; return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, -- 2.7.4