From patchwork Fri May 16 05:34:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Timo Teras X-Patchwork-Id: 349447 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 0E74F14008B for ; Fri, 16 May 2014 15:34:36 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753846AbaEPFeb (ORCPT ); Fri, 16 May 2014 01:34:31 -0400 Received: from mail-la0-f45.google.com ([209.85.215.45]:63135 "EHLO mail-la0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752719AbaEPFea (ORCPT ); Fri, 16 May 2014 01:34:30 -0400 Received: by mail-la0-f45.google.com with SMTP id gl10so1567864lab.18 for ; Thu, 15 May 2014 22:34:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=zE+LSzOncaWXJP1kGoPRLiP9hv92u7FTelu34wLRyUU=; b=xRI7xBm1AseqJamQ7S/QDou06EYIcmsJ8UgKDm0f+JTlXJ/5svcywg/KiByrX48+2f sLis2fNcf1kCVfSMahEXYY1M2DuYvnSk8UgwXDUaLA6B6X5DATF+ed2ZMkqOAKamCDxR W/ept2yhZDJJBhNtYuHalvOmEo0oIg0Izih2o/m9thtmb90Q0mZzYwtuCgZVvOEAeTgD ddLsPKlMkLi68/+xm6etWEffmkSb00VMwcTmBx6Sr7bav7AsOMfVFvkNZAApHmxIEnNb Y4SJwBT2MfmwjeEc2Bk+RzwWSUV7MGuV3zft7+b4BFUSbEE3ueFQj7APImDc1l9BrQqD 6BpA== X-Received: by 10.152.207.74 with SMTP id lu10mr10495451lac.28.1400218469166; Thu, 15 May 2014 22:34:29 -0700 (PDT) Received: from vostro.util.wtbts.net ([83.145.235.199]) by mx.google.com with ESMTPSA id i10sm7509460lbc.16.2014.05.15.22.34.28 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 15 May 2014 22:34:28 -0700 (PDT) From: =?UTF-8?q?Timo=20Ter=C3=A4s?= To: David Miller , netdev@vger.kernel.org Cc: =?UTF-8?q?Timo=20Ter=C3=A4s?= , Tom Herbert , Eric Dumazet Subject: [PATCH net, v2] ipv4: ip_tunnels: disable cache for nbma gre tunnels Date: Fri, 16 May 2014 08:34:39 +0300 Message-Id: <1400218479-10166-1-git-send-email-timo.teras@iki.fi> X-Mailer: git-send-email 1.9.3 In-Reply-To: <20140515.232905.995406666776115109.davem@davemloft.net> References: <20140515.232905.995406666776115109.davem@davemloft.net> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The connected check fails to check for ip_gre nbma mode tunnels properly. ip_gre creates temporary tnl_params with daddr specified to pass-in the actual target on per-packet basis from neighbor layer. Detect these tunnels by inspecting the actual tunnel configuration. Minimal test case: ip route add 192.168.1.1/32 via 10.0.0.1 ip route add 192.168.1.2/32 via 10.0.0.2 ip tunnel add nbma0 mode gre key 1 tos c0 ip addr add 172.17.0.0/16 dev nbma0 ip link set nbma0 up ip neigh add 172.17.0.1 lladdr 192.168.1.1 dev nbma0 ip neigh add 172.17.0.2 lladdr 192.168.1.2 dev nbma0 ping 172.17.0.1 ping 172.17.0.2 The second ping should be going to 192.168.1.2 and head 10.0.0.2; but cached gre tunnel level route is used and it's actually going to 192.168.1.1 via 10.0.0.1. The lladdr's need to go to separate dst for the bug to trigger. Test case uses separate route entries, but this can also happen when the route entry is same: if there is a nexthop exception or the GRE tunnel is IPsec'ed in which case the dst points to xfrm bundle unique to the gre lladdr. Fixes: 7d442fab0a67 ("ipv4: Cache dst in tunnels") Signed-off-by: Timo Teräs Cc: Tom Herbert Cc: Eric Dumazet --- Should go to 3.14-stable too. net/ipv4/ip_tunnel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index e77381d..4eb9196 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -538,9 +538,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, unsigned int max_headroom; /* The extra header space needed */ __be32 dst; int err; - bool connected = true; + bool connected; inner_iph = (const struct iphdr *)skb_inner_network_header(skb); + connected = (tunnel->parms.iph.daddr != 0); dst = tnl_params->daddr; if (dst == 0) {