Skip to content

Commit

Permalink
ip6_tunnel: Add support for wildcard tunnel endpoints.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Steffen Klassert authored and David S. Miller committed Nov 6, 2014
1 parent d500514 commit ea3dc96
Showing 1 changed file with 40 additions and 1 deletion.
41 changes: 40 additions & 1 deletion net/ipv6/ip6_tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,30 @@ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_
unsigned int hash = HASH(remote, local);
struct ip6_tnl *t;
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
struct in6_addr any;

for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
if (ipv6_addr_equal(local, &t->parms.laddr) &&
ipv6_addr_equal(remote, &t->parms.raddr) &&
(t->dev->flags & IFF_UP))
return t;
}

memset(&any, 0, sizeof(any));
hash = HASH(&any, local);
for_each_ip6_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_ip6_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;
Expand Down Expand Up @@ -979,7 +996,29 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
u8 proto;
int err = -1;

if (!fl6->flowi6_mark)
/* NBMA tunnel */
if (ipv6_addr_any(&t->parms.raddr)) {
struct in6_addr *addr6;
struct neighbour *neigh;
int addr_type;

if (!skb_dst(skb))
goto tx_err_link_failure;

neigh = dst_neigh_lookup(skb_dst(skb),
&ipv6_hdr(skb)->daddr);
if (!neigh)
goto tx_err_link_failure;

addr6 = (struct in6_addr *)&neigh->primary_key;
addr_type = ipv6_addr_type(addr6);

if (addr_type == IPV6_ADDR_ANY)
addr6 = &ipv6_hdr(skb)->daddr;

memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr));
neigh_release(neigh);
} else if (!fl6->flowi6_mark)
dst = ip6_tnl_dst_check(t);

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

0 comments on commit ea3dc96

Please sign in to comment.