summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2014-11-20 12:01:49 +0300
committerSteffen Klassert <steffen.klassert@secunet.com>2014-11-20 12:03:07 +0300
commitfbe68ee87522f6eaa10f9076c0a7117e1613f2f7 (patch)
tree585974ec31a819318a119b5e92b7cf800465c019
parent12bfa8bdba05700e437479dcb6d53b5ca582fa49 (diff)
downloadlinux-fbe68ee87522f6eaa10f9076c0a7117e1613f2f7.tar.xz
vti6: Add a lookup method for tunnels with wildcard endpoints.
Currently we can't lookup tunnels with wildcard endpoints. This patch adds a method to lookup these tunnels in the receive path. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r--net/ipv6/ip6_vti.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index d440bb585524..61019199c84b 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -95,6 +95,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
unsigned int hash = HASH(remote, local);
struct ip6_tnl *t;
struct vti6_net *ip6n = net_generic(net, vti6_net_id);
+ struct in6_addr any;
for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
if (ipv6_addr_equal(local, &t->parms.laddr) &&
@@ -102,6 +103,22 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
(t->dev->flags & IFF_UP))
return t;
}
+
+ memset(&any, 0, sizeof(any));
+ hash = HASH(&any, local);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(local, &t->parms.laddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+
+ hash = HASH(remote, &any);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(remote, &t->parms.raddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+
t = rcu_dereference(ip6n->tnls_wc[0]);
if (t && (t->dev->flags & IFF_UP))
return t;