net/ipv4: bind ip_nonlocal_bind to current netns
authorVincent Bernat <vincent@bernat.im>
Fri, 5 Sep 2014 13:09:03 +0000 (15:09 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 9 Sep 2014 18:27:09 +0000 (11:27 -0700)
net.ipv4.ip_nonlocal_bind sysctl was global to all network
namespaces. This patch allows to set a different value for each
network namespace.

Signed-off-by: Vincent Bernat <vincent@bernat.im>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ip.h
include/net/netns/ipv4.h
net/ipv4/af_inet.c
net/ipv4/ping.c
net/ipv4/sysctl_net_ipv4.c
net/ipv6/af_inet6.c
net/sctp/protocol.c

index c8fd6112bd0b49f772557b4ec56c3737ad65594e..14bfc8e1bcf9c374f836145151706182f0544ac7 100644 (file)
@@ -229,8 +229,6 @@ static inline int inet_is_local_reserved_port(struct net *net, int port)
 }
 #endif
 
-extern int sysctl_ip_nonlocal_bind;
-
 /* From inetpeer.c */
 extern int inet_peer_threshold;
 extern int inet_peer_minttl;
index aec5e12f9f19f1a6c506e47f60cc3056d7ce2a3d..24945cefc4fde6bfaf9c4560080c91b2e3b12d0d 100644 (file)
@@ -76,6 +76,7 @@ struct netns_ipv4 {
        int sysctl_tcp_ecn;
        int sysctl_ip_no_pmtu_disc;
        int sysctl_ip_fwd_use_pmtu;
+       int sysctl_ip_nonlocal_bind;
 
        int sysctl_fwmark_reflect;
        int sysctl_tcp_fwmark_accept;
index d156b3c5f3631f169f179bfdd534b69ce5070b82..b537bd94906c3b61285e00a4a31ce06cf611e56f 100644 (file)
@@ -418,10 +418,6 @@ int inet_release(struct socket *sock)
 }
 EXPORT_SYMBOL(inet_release);
 
-/* It is off by default, see below. */
-int sysctl_ip_nonlocal_bind __read_mostly;
-EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
-
 int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
        struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
@@ -461,7 +457,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
         *  is temporarily down)
         */
        err = -EADDRNOTAVAIL;
-       if (!sysctl_ip_nonlocal_bind &&
+       if (!net->ipv4.sysctl_ip_nonlocal_bind &&
            !(inet->freebind || inet->transparent) &&
            addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
            chk_addr_ret != RTN_LOCAL &&
index a3c59a077a5f0574f02584b0068de0703d5cb3dc..57f7c98041394998fe390735aa5b8cd2602b3f90 100644 (file)
@@ -311,7 +311,7 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
                if (addr->sin_addr.s_addr == htonl(INADDR_ANY))
                        chk_addr_ret = RTN_LOCAL;
 
-               if ((sysctl_ip_nonlocal_bind == 0 &&
+               if ((net->ipv4.sysctl_ip_nonlocal_bind == 0 &&
                    isk->freebind == 0 && isk->transparent == 0 &&
                     chk_addr_ret != RTN_LOCAL) ||
                    chk_addr_ret == RTN_MULTICAST ||
index 45d156dacd61cec096afe0b41940c8babff89971..1599966f4639259799fbb8a3cbd7f61d276cd7ef 100644 (file)
@@ -285,13 +285,6 @@ static struct ctl_table ipv4_table[] = {
                .extra1         = &ip_ttl_min,
                .extra2         = &ip_ttl_max,
        },
-       {
-               .procname       = "ip_nonlocal_bind",
-               .data           = &sysctl_ip_nonlocal_bind,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = proc_dointvec
-       },
        {
                .procname       = "tcp_syn_retries",
                .data           = &sysctl_tcp_syn_retries,
@@ -848,6 +841,13 @@ static struct ctl_table ipv4_net_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
+       {
+               .procname       = "ip_nonlocal_bind",
+               .data           = &init_net.ipv4.sysctl_ip_nonlocal_bind,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec
+       },
        {
                .procname       = "fwmark_reflect",
                .data           = &init_net.ipv4.sysctl_fwmark_reflect,
index b9393e6a21fe0ae99cffad643cfe2a49e5472b35..e4865a3ebe1d776c7463cfa8a75b7332e9b1d445 100644 (file)
@@ -302,7 +302,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                /* Reproduce AF_INET checks to make the bindings consistent */
                v4addr = addr->sin6_addr.s6_addr32[3];
                chk_addr_ret = inet_addr_type(net, v4addr);
-               if (!sysctl_ip_nonlocal_bind &&
+               if (!net->ipv4.sysctl_ip_nonlocal_bind &&
                    !(inet->freebind || inet->transparent) &&
                    v4addr != htonl(INADDR_ANY) &&
                    chk_addr_ret != RTN_LOCAL &&
index 6240834f4b95255a054c2017497d9b07b06b71f7..9d2c6c9facb6a4f4dabee29d8430aaf55b323636 100644 (file)
@@ -366,7 +366,7 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
        if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) &&
           ret != RTN_LOCAL &&
           !sp->inet.freebind &&
-          !sysctl_ip_nonlocal_bind)
+          !net->ipv4.sysctl_ip_nonlocal_bind)
                return 0;
 
        if (ipv6_only_sock(sctp_opt2sk(sp)))