Commit 908d140a authored by Shmulik Ladkani's avatar Shmulik Ladkani Committed by David S. Miller

ip6_tunnel: Allow rcv/xmit even if remote address is a local address

Currently, ip6_tnl_xmit_ctl drops tunneled packets if the remote
address (outer v6 destination) is one of host's locally configured
addresses.
Same applies to ip6_tnl_rcv_ctl: it drops packets if the remote address
(outer v6 source) is a local address.

This prevents using ipxip6 (and ip6_gre) tunnels whose local/remote
endpoints are on same host; OTOH v4 tunnels (ipip or gre) allow such
configurations.

An example where this proves useful is a system where entities are
identified by their unique v6 addresses, and use tunnels to encapsulate
traffic between them. The limitation prevents placing several entities
on same host.

Introduce IP6_TNL_F_ALLOW_LOCAL_REMOTE which allows to bypass this
restriction.
Signed-off-by: default avatarShmulik Ladkani <shmulik.ladkani@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6a331e15
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#define IP6_TNL_F_RCV_DSCP_COPY 0x10 #define IP6_TNL_F_RCV_DSCP_COPY 0x10
/* copy fwmark from inner packet */ /* copy fwmark from inner packet */
#define IP6_TNL_F_USE_ORIG_FWMARK 0x20 #define IP6_TNL_F_USE_ORIG_FWMARK 0x20
/* allow remote endpoint on the local node */
#define IP6_TNL_F_ALLOW_LOCAL_REMOTE 0x40
struct ip6_tnl_parm { struct ip6_tnl_parm {
char name[IFNAMSIZ]; /* name of tunnel device */ char name[IFNAMSIZ]; /* name of tunnel device */
......
...@@ -770,7 +770,8 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t, ...@@ -770,7 +770,8 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
if ((ipv6_addr_is_multicast(laddr) || if ((ipv6_addr_is_multicast(laddr) ||
likely(ipv6_chk_addr(net, laddr, ldev, 0))) && likely(ipv6_chk_addr(net, laddr, ldev, 0))) &&
likely(!ipv6_chk_addr(net, raddr, NULL, 0))) ((p->flags & IP6_TNL_F_ALLOW_LOCAL_REMOTE) ||
likely(!ipv6_chk_addr(net, raddr, NULL, 0))))
ret = 1; ret = 1;
} }
return ret; return ret;
...@@ -1000,7 +1001,8 @@ int ip6_tnl_xmit_ctl(struct ip6_tnl *t, ...@@ -1000,7 +1001,8 @@ int ip6_tnl_xmit_ctl(struct ip6_tnl *t,
if (unlikely(!ipv6_chk_addr(net, laddr, ldev, 0))) if (unlikely(!ipv6_chk_addr(net, laddr, ldev, 0)))
pr_warn("%s xmit: Local address not yet configured!\n", pr_warn("%s xmit: Local address not yet configured!\n",
p->name); p->name);
else if (!ipv6_addr_is_multicast(raddr) && else if (!(p->flags & IP6_TNL_F_ALLOW_LOCAL_REMOTE) &&
!ipv6_addr_is_multicast(raddr) &&
unlikely(ipv6_chk_addr(net, raddr, NULL, 0))) unlikely(ipv6_chk_addr(net, raddr, NULL, 0)))
pr_warn("%s xmit: Routing loop! Remote address found on this node!\n", pr_warn("%s xmit: Routing loop! Remote address found on this node!\n",
p->name); p->name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment