Skip to content

Commit ea3dc96

Browse files
klassertdavem330
authored andcommitted
ip6_tunnel: Add support for wildcard tunnel endpoints.
This patch adds support for tunnels with local or remote wildcard endpoints. With this we get a NBMA tunnel mode like we have it for ipv4 and sit tunnels. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent d500514 commit ea3dc96

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

net/ipv6/ip6_tunnel.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,30 @@ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_
183183
unsigned int hash = HASH(remote, local);
184184
struct ip6_tnl *t;
185185
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
186+
struct in6_addr any;
186187

187188
for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
188189
if (ipv6_addr_equal(local, &t->parms.laddr) &&
189190
ipv6_addr_equal(remote, &t->parms.raddr) &&
190191
(t->dev->flags & IFF_UP))
191192
return t;
192193
}
194+
195+
memset(&any, 0, sizeof(any));
196+
hash = HASH(&any, local);
197+
for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
198+
if (ipv6_addr_equal(local, &t->parms.laddr) &&
199+
(t->dev->flags & IFF_UP))
200+
return t;
201+
}
202+
203+
hash = HASH(remote, &any);
204+
for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
205+
if (ipv6_addr_equal(remote, &t->parms.raddr) &&
206+
(t->dev->flags & IFF_UP))
207+
return t;
208+
}
209+
193210
t = rcu_dereference(ip6n->tnls_wc[0]);
194211
if (t && (t->dev->flags & IFF_UP))
195212
return t;
@@ -979,7 +996,29 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
979996
u8 proto;
980997
int err = -1;
981998

982-
if (!fl6->flowi6_mark)
999+
/* NBMA tunnel */
1000+
if (ipv6_addr_any(&t->parms.raddr)) {
1001+
struct in6_addr *addr6;
1002+
struct neighbour *neigh;
1003+
int addr_type;
1004+
1005+
if (!skb_dst(skb))
1006+
goto tx_err_link_failure;
1007+
1008+
neigh = dst_neigh_lookup(skb_dst(skb),
1009+
&ipv6_hdr(skb)->daddr);
1010+
if (!neigh)
1011+
goto tx_err_link_failure;
1012+
1013+
addr6 = (struct in6_addr *)&neigh->primary_key;
1014+
addr_type = ipv6_addr_type(addr6);
1015+
1016+
if (addr_type == IPV6_ADDR_ANY)
1017+
addr6 = &ipv6_hdr(skb)->daddr;
1018+
1019+
memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr));
1020+
neigh_release(neigh);
1021+
} else if (!fl6->flowi6_mark)
9831022
dst = ip6_tnl_dst_check(t);
9841023

9851024
if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr))

0 commit comments

Comments
 (0)