From patchwork Tue Sep 19 00:38:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 815215 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=quantonium-net.20150623.gappssmtp.com header.i=@quantonium-net.20150623.gappssmtp.com header.b="aGB3SSwH"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xx3tK6LRDz9s78 for ; Tue, 19 Sep 2017 10:39:53 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751210AbdISAjd (ORCPT ); Mon, 18 Sep 2017 20:39:33 -0400 Received: from mail-pf0-f169.google.com ([209.85.192.169]:54195 "EHLO mail-pf0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751016AbdISAjc (ORCPT ); Mon, 18 Sep 2017 20:39:32 -0400 Received: by mail-pf0-f169.google.com with SMTP id x78so1102618pff.10 for ; Mon, 18 Sep 2017 17:39:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quantonium-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=p4/uHanYkSLTDDyJ1/R/fpW4eCV1EFLfoTQrShRbRC8=; b=aGB3SSwH67gCDaTTQ0FDQsgngY3ipBgrS1Pz83AYOc/URQ18q5HEf1EV94/6r5Ctf4 kpGLXlVEYyji7lRJgF0x6S5UEhLo20ZVDNYr+s+8yCUkxepFpTyvvkH6GvKd2sDLAv29 Xdtqcn3qbjVwT5/hliApZhpmD5rByFPS5Blftu0pExXdkwdoRIDqeJrc7wLBFekF9VqJ x2zHQZARaIts47OSjSlMsNwqsrOyIDV78Ha9EAM1SjNEYjcjpUtYUGhYZhYThL2Nhhuq phLuPRNPpC3q3ZsOVrG4/LZptuH9vGfhx3SjBVvNq6Y00CQhh9cm5eH88lpiXRcXWEHv gZCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=p4/uHanYkSLTDDyJ1/R/fpW4eCV1EFLfoTQrShRbRC8=; b=CUw32eg/RQl9vdK8Yy4FqNvAsZwS1VdxV1uKBeC9a6pPSyLg5/SA7qqJKXejkfTXgk AzV5TElbQRsgJYdOqyV9pSUKL5wESTbB4N3SbOI/5+JGDWBLY+GgZQGDZnJKhzrLGF77 hQETtT4rUF3Wr9mD68t+C1rbrKm0zriB2Lsd/shcpPfo2STDs6wWNF+Rijc55AYqDSiP llpaKI6Fw23D8Qz3iQgDCHndknNGJcCkEfc9qy/CifmVHLRg+wYCjA/2ZwuFpS++93vQ EPS4D3fU6pqKP90L5qRNjxK3zDxxRUA6kRxZxJ+NsJjXGd4e1Y6uAfGBQFe9n14vLckE 3J0g== X-Gm-Message-State: AHPjjUgF+zh/+Pyw7R1sC01q24y6YdkugAXa+0VBlrSYfznM4UIDO7Lb FqbewgPUuTLfQB9F X-Google-Smtp-Source: AOwi7QDhjPzJ7ATztsS5JtBG8Z3TJi6DU9Ikbx+L667Y/GKW6L0OzxWP6TxvyvW+Wnw32hyI7VzNnQ== X-Received: by 10.101.83.4 with SMTP id m4mr353506pgq.266.1505781571883; Mon, 18 Sep 2017 17:39:31 -0700 (PDT) Received: from localhost.localdomain (c-73-162-13-107.hsd1.ca.comcast.net. [73.162.13.107]) by smtp.gmail.com with ESMTPSA id k78sm662018pfb.157.2017.09.18.17.39.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Sep 2017 17:39:30 -0700 (PDT) From: Tom Herbert To: davem@davemloft.net Cc: netdev@vger.kernel.org, pablo@netfilter.org, laforge@gnumonks.org, rohit@quantonium.net, Tom Herbert Subject: [PATCH net-next 01/14] iptunnel: Add common functions to get a tunnel route Date: Mon, 18 Sep 2017 17:38:51 -0700 Message-Id: <20170919003904.5124-2-tom@quantonium.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170919003904.5124-1-tom@quantonium.net> References: <20170919003904.5124-1-tom@quantonium.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org ip_tunnel_get_route and ip6_tnl_get_route are create to return routes for a tunnel. These functions are derived from the VXLAN functions. Signed-off-by: Tom Herbert --- include/net/ip6_tunnel.h | 33 +++++++++++++++++++++++++++++++++ include/net/ip_tunnels.h | 33 +++++++++++++++++++++++++++++++++ net/ipv4/ip_tunnel.c | 41 +++++++++++++++++++++++++++++++++++++++++ net/ipv6/ip6_tunnel.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+) diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index 08fbc7f7d8d7..233097bf07a2 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -142,6 +142,39 @@ __u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr, struct net *ip6_tnl_get_link_net(const struct net_device *dev); int ip6_tnl_get_iflink(const struct net_device *dev); int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu); +struct dst_entry *__ip6_tnl_get_route(struct net_device *dev, + struct sk_buff *skb, struct sock *sk, + u8 proto, int oif, u8 tos, __be32 label, + const struct in6_addr *daddr, + struct in6_addr *saddr, + __be16 dport, __be16 sport, + struct dst_cache *dst_cache, + const struct ip_tunnel_info *info, + bool use_cache); + +static inline struct dst_entry *ip6_tnl_get_route(struct net_device *dev, + struct sk_buff *skb, struct sock *sk, u8 proto, + int oif, u8 tos, __be32 label, + const struct in6_addr *daddr, + struct in6_addr *saddr, + __be16 dport, __be16 sport, + struct dst_cache *dst_cache, + const struct ip_tunnel_info *info) +{ + bool use_cache = (ip_tunnel_dst_cache_usable(skb, info) && + (!tos || info)); + + if (use_cache) { + struct dst_entry *ndst = dst_cache_get_ip6(dst_cache, saddr); + + if (ndst) + return ndst; + } + + return __ip6_tnl_get_route(dev, skb, sk, proto, oif, tos, label, + daddr, saddr, dport, sport, dst_cache, + info, use_cache); +} static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, struct net_device *dev) diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 992652856fe8..91d5150a1044 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -284,6 +284,39 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[], struct ip_tunnel_parm *p, __u32 fwmark); void ip_tunnel_setup(struct net_device *dev, unsigned int net_id); +struct rtable *__ip_tunnel_get_route(struct net_device *dev, + struct sk_buff *skb, u8 proto, + int oif, u8 tos, + __be32 daddr, __be32 *saddr, + __be16 dport, __be16 sport, + struct dst_cache *dst_cache, + const struct ip_tunnel_info *info, + bool use_cache); + +static inline struct rtable *ip_tunnel_get_route(struct net_device *dev, + struct sk_buff *skb, u8 proto, + int oif, u8 tos, + __be32 daddr, __be32 *saddr, + __be16 dport, __be16 sport, + struct dst_cache *dst_cache, + const struct ip_tunnel_info *info) +{ + bool use_cache = (ip_tunnel_dst_cache_usable(skb, info) && + (!tos || info)); + + if (use_cache) { + struct rtable *rt; + + rt = dst_cache_get_ip4(dst_cache, saddr); + if (rt) + return rt; + } + + return __ip_tunnel_get_route(dev, skb, proto, oif, tos, + daddr, saddr, dport, sport, + dst_cache, info, use_cache); +} + struct ip_tunnel_encap_ops { size_t (*encap_hlen)(struct ip_tunnel_encap *e); int (*build_header)(struct sk_buff *skb, struct ip_tunnel_encap *e, diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index e9805ad664ac..f0f35333febd 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -935,6 +935,47 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) } EXPORT_SYMBOL_GPL(ip_tunnel_ioctl); +struct rtable *__ip_tunnel_get_route(struct net_device *dev, + struct sk_buff *skb, u8 proto, + int oif, u8 tos, + __be32 daddr, __be32 *saddr, + __be16 dport, __be16 sport, + struct dst_cache *dst_cache, + const struct ip_tunnel_info *info, + bool use_cache) +{ + struct rtable *rt = NULL; + struct flowi4 fl4; + + memset(&fl4, 0, sizeof(fl4)); + fl4.flowi4_oif = oif; + fl4.flowi4_tos = RT_TOS(tos); + fl4.flowi4_mark = skb->mark; + fl4.flowi4_proto = proto; + fl4.daddr = daddr; + fl4.saddr = *saddr; + fl4.fl4_dport = dport; + fl4.fl4_sport = sport; + + rt = ip_route_output_key(dev_net(dev), &fl4); + if (likely(!IS_ERR(rt))) { + if (rt->dst.dev == dev) { + netdev_dbg(dev, "circular route to %pI4\n", &daddr); + ip_rt_put(rt); + return ERR_PTR(-ELOOP); + } + + *saddr = fl4.saddr; + if (use_cache) + dst_cache_set_ip4(dst_cache, &rt->dst, fl4.saddr); + } else { + netdev_dbg(dev, "no route to %pI4\n", &daddr); + return ERR_PTR(-ENETUNREACH); + } + return rt; +} +EXPORT_SYMBOL_GPL(__ip_tunnel_get_route); + int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict) { struct ip_tunnel *tunnel = netdev_priv(dev); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index ae73164559d5..9a02b62c808b 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1663,6 +1663,49 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return err; } +struct dst_entry *__ip6_tnl_get_route(struct net_device *dev, + struct sk_buff *skb, struct sock *sk, + u8 proto, int oif, u8 tos, __be32 label, + const struct in6_addr *daddr, + struct in6_addr *saddr, + __be16 dport, __be16 sport, + struct dst_cache *dst_cache, + const struct ip_tunnel_info *info, + bool use_cache) +{ + struct dst_entry *ndst; + struct flowi6 fl6; + int err; + + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_oif = oif; + fl6.daddr = *daddr; + fl6.saddr = *saddr; + fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label); + fl6.flowi6_mark = skb->mark; + fl6.flowi6_proto = proto; + fl6.fl6_dport = dport; + fl6.fl6_sport = sport; + + err = ipv6_stub->ipv6_dst_lookup(dev_net(dev), sk, &ndst, &fl6); + if (unlikely(err < 0)) { + netdev_dbg(dev, "no route to %pI6\n", daddr); + return ERR_PTR(-ENETUNREACH); + } + + if (unlikely(ndst->dev == dev)) { + netdev_dbg(dev, "circular route to %pI6\n", daddr); + dst_release(ndst); + return ERR_PTR(-ELOOP); + } + + *saddr = fl6.saddr; + if (use_cache) + dst_cache_set_ip6(dst_cache, ndst, saddr); + return ndst; +} +EXPORT_SYMBOL_GPL(__ip6_tnl_get_route); + /** * ip6_tnl_change_mtu - change mtu manually for tunnel device * @dev: virtual device associated with tunnel