aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-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 16a7e81e3f99..ace10d0b3aac 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,
95 unsigned int hash = HASH(remote, local); 95 unsigned int hash = HASH(remote, local);
96 struct ip6_tnl *t; 96 struct ip6_tnl *t;
97 struct vti6_net *ip6n = net_generic(net, vti6_net_id); 97 struct vti6_net *ip6n = net_generic(net, vti6_net_id);
98 struct in6_addr any;
98 99
99 for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) { 100 for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
100 if (ipv6_addr_equal(local, &t->parms.laddr) && 101 if (ipv6_addr_equal(local, &t->parms.laddr) &&
@@ -102,6 +103,22 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
102 (t->dev->flags & IFF_UP)) 103 (t->dev->flags & IFF_UP))
103 return t; 104 return t;
104 } 105 }
106
107 memset(&any, 0, sizeof(any));
108 hash = HASH(&any, local);
109 for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
110 if (ipv6_addr_equal(local, &t->parms.laddr) &&
111 (t->dev->flags & IFF_UP))
112 return t;
113 }
114
115 hash = HASH(remote, &any);
116 for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
117 if (ipv6_addr_equal(remote, &t->parms.raddr) &&
118 (t->dev->flags & IFF_UP))
119 return t;
120 }
121
105 t = rcu_dereference(ip6n->tnls_wc[0]); 122 t = rcu_dereference(ip6n->tnls_wc[0]);
106 if (t && (t->dev->flags & IFF_UP)) 123 if (t && (t->dev->flags & IFF_UP))
107 return t; 124 return t;