From patchwork Fri Oct 28 12:32:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Sitnicki X-Patchwork-Id: 688374 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3t537w6csDz9t0H for ; Fri, 28 Oct 2016 23:33:16 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756612AbcJ1MdL (ORCPT ); Fri, 28 Oct 2016 08:33:11 -0400 Received: from mail-wm0-f44.google.com ([74.125.82.44]:35415 "EHLO mail-wm0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760007AbcJ1Mco (ORCPT ); Fri, 28 Oct 2016 08:32:44 -0400 Received: by mail-wm0-f44.google.com with SMTP id e69so97908438wmg.0 for ; Fri, 28 Oct 2016 05:32:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pXW7HukipWFgFavcCij28O8DCqGndo6Svre329FRyyM=; b=gb3tOEsCZjx8gCE5zc6VgnFggo3D6AeS8NnkAB6k3NjoxYPNOQt9HxlXiDtOj9QOOp QGi8GBtva+NcU+vf2UuJJDAxOIzSrLuhpDpNO9BskMDYUztBg1wqUg31egIEOm/2ZW/3 mlOYqGmSvb4olJ6w4Z5NVDm5SceHzo1TKCXt9OQDeI8a4US2uHFgkWXSjHy5QiovlMSE m2JiOj3PGwUa7aHkuZGctq7LaolvJb+tQABtIpVH59eGRWnFd3cfsBYLZnmYZQoC/YIe Q8qxx20PMIxjAZ80KmHR/l7cAEuAi2jIXaQ57QiNzzCGNgK+ACYD0yLs2nvkSCyksSS9 0UIw== X-Gm-Message-State: ABUngvcHySDsQq7UdezxiKP3iShXJVOo4rlqzEJRLLdQsean5EYw8B/LXxFnkpi2Ff0XmVCE X-Received: by 10.28.133.202 with SMTP id h193mr3245801wmd.85.1477657962800; Fri, 28 Oct 2016 05:32:42 -0700 (PDT) Received: from redhat.com ([149.6.38.86]) by smtp.gmail.com with ESMTPSA id q125sm8755377wmd.2.2016.10.28.05.32.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Oct 2016 05:32:42 -0700 (PDT) From: Jakub Sitnicki To: netdev@vger.kernel.org Cc: "David S. Miller" , Hannes Frederic Sowa , Hideaki YOSHIFUJI , Tom Herbert Subject: [PATCH net-next v2 5/5] ipv6: Compute multipath hash for forwarded ICMP errors from offending packet Date: Fri, 28 Oct 2016 14:32:35 +0200 Message-Id: <1477657955-5157-6-git-send-email-jkbs@redhat.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1477657955-5157-1-git-send-email-jkbs@redhat.com> References: <1477657955-5157-1-git-send-email-jkbs@redhat.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Same as for the transmit path, let's do our best to ensure that received ICMP errors that may be subject to forwarding will be routed the same path as flow that triggered the error, if it was going in the opposite direction. v1 -> v2: - style change, put as many arguments as possible on the first line of a function call, and align consecutive lines to the first argument, pointed out by David Miller Signed-off-by: Jakub Sitnicki Acked-by: Hannes Frederic Sowa --- net/ipv6/route.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1184c2b..269e30d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1150,6 +1150,30 @@ struct dst_entry *ip6_route_input_lookup(struct net *net, } EXPORT_SYMBOL_GPL(ip6_route_input_lookup); +static u32 ip6_multipath_icmp_hash(const struct sk_buff *skb) +{ + const struct icmp6hdr *icmph = icmp6_hdr(skb); + const struct ipv6hdr *inner_iph; + struct ipv6hdr _inner_iph; + + if (icmph->icmp6_type != ICMPV6_DEST_UNREACH && + icmph->icmp6_type != ICMPV6_PKT_TOOBIG && + icmph->icmp6_type != ICMPV6_TIME_EXCEED && + icmph->icmp6_type != ICMPV6_PARAMPROB) + goto standard_hash; + + inner_iph = skb_header_pointer(skb, + skb_transport_offset(skb) + sizeof(*icmph), + sizeof(_inner_iph), &_inner_iph); + if (!inner_iph) + goto standard_hash; + + return icmpv6_multipath_hash(inner_iph); + +standard_hash: + return 0; /* compute it later, if needed */ +} + void ip6_route_input(struct sk_buff *skb) { const struct ipv6hdr *iph = ipv6_hdr(skb); @@ -1168,6 +1192,8 @@ void ip6_route_input(struct sk_buff *skb) tun_info = skb_tunnel_info(skb); if (tun_info && !(tun_info->mode & IP_TUNNEL_INFO_TX)) fl6.flowi6_tun_key.tun_id = tun_info->key.tun_id; + if (unlikely(fl6.flowi6_proto == IPPROTO_ICMPV6)) + fl6.mp_hash = ip6_multipath_icmp_hash(skb); skb_dst_drop(skb); skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags)); }