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: Tom Herbert <tom@herbertland.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
        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.
 
        int auto_flowlabels;
        int icmpv6_time;
        int anycast_src_echo_reply;
+       int ip_nonlocal_bind;
        int fwmark_reflect;
        int idgen_retries;
        int idgen_delay;
 
                                                    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;
 
 
                         */
                        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;
 
                 * 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)) {
 
                .mode           = 0644,
                .proc_handler   = proc_dointvec
        },
+       {
+               .procname       = "ip_nonlocal_bind",
+               .data           = &init_net.ipv6.sysctl.ip_nonlocal_bind,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec
+       },
        { }
 };
 
        ipv6_table[5].data = &net->ipv6.sysctl.idgen_retries;
        ipv6_table[6].data = &net->ipv6.sysctl.idgen_delay;
        ipv6_table[7].data = &net->ipv6.sysctl.flowlabel_state_ranges;
+       ipv6_table[8].data = &net->ipv6.sysctl.ip_nonlocal_bind;
 
        ipv6_route_table = ipv6_route_sysctl_init(net);
        if (!ipv6_route_table)