Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35a256fe authored by Tom Herbert's avatar Tom Herbert Committed by David S. Miller
Browse files

ipv6: Nonlocal bind



Add support to allow non-local binds similar to how this was done for IPv4.
Non-local binds are very useful in emulating the Internet in a box, etc.

This add the ip_nonlocal_bind sysctl under ipv6.

Testing:

Set up nonlocal binding and receive routing on a host, e.g.:

ip -6 rule add from ::/0 iif eth0 lookup 200
ip -6 route add local 2001:0:0:1::/64 dev lo proto kernel scope host table 200
sysctl -w net.ipv6.ip_nonlocal_bind=1

Set up routing to 2001:0:0:1::/64 on peer to go to first host

ping6 -I 2001:0:0:1::1 peer-address -- to verify

Signed-off-by: default avatarTom Herbert <tom@herbertland.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5a10ecec
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1435,6 +1435,11 @@ mtu - INTEGER
	Default Maximum Transfer Unit
	Default: 1280 (IPv6 required minimum)

ip_nonlocal_bind - BOOLEAN
	If set, allows processes to bind() to non-local IPv6 addresses,
	which can be quite useful - but may break some applications.
	Default: 0

router_probe_interval - INTEGER
	Minimum interval (in seconds) between Router Probing described
	in RFC4191.
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct netns_sysctl_ipv6 {
	int auto_flowlabels;
	int icmpv6_time;
	int anycast_src_echo_reply;
	int ip_nonlocal_bind;
	int fwmark_reflect;
	int idgen_retries;
	int idgen_delay;
+2 −1
Original line number Diff line number Diff line
@@ -363,7 +363,8 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
						    scoped);
		rcu_read_unlock();

		if (!(isk->freebind || isk->transparent || has_addr ||
		if (!(net->ipv6.sysctl.ip_nonlocal_bind ||
		      isk->freebind || isk->transparent || has_addr ||
		      addr_type == IPV6_ADDR_ANY))
			return -EADDRNOTAVAIL;

+2 −1
Original line number Diff line number Diff line
@@ -342,7 +342,8 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
			 */
			v4addr = LOOPBACK4_IPV6;
			if (!(addr_type & IPV6_ADDR_MULTICAST))	{
				if (!(inet->freebind || inet->transparent) &&
				if (!net->ipv6.sysctl.ip_nonlocal_bind &&
				    !(inet->freebind || inet->transparent) &&
				    !ipv6_chk_addr(net, &addr->sin6_addr,
						   dev, 0)) {
					err = -EADDRNOTAVAIL;
+2 −1
Original line number Diff line number Diff line
@@ -295,7 +295,8 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
		 * unspecified and mapped address have a v4 equivalent.
		 */
		v4addr = LOOPBACK4_IPV6;
		if (!(addr_type & IPV6_ADDR_MULTICAST))	{
		if (!(addr_type & IPV6_ADDR_MULTICAST) &&
		    !sock_net(sk)->ipv6.sysctl.ip_nonlocal_bind) {
			err = -EADDRNOTAVAIL;
			if (!ipv6_chk_addr(sock_net(sk), &addr->sin6_addr,
					   dev, 0)) {
Loading