net/ipv4: bind ip_nonlocal_bind to current netns

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>
This commit is contained in:
Vincent Bernat 2014-09-05 15:09:03 +02:00 коммит произвёл David S. Miller
Родитель afddacc3cc
Коммит 49a601589c
7 изменённых файлов: 12 добавлений и 17 удалений

Просмотреть файл

@ -229,8 +229,6 @@ static inline int inet_is_local_reserved_port(struct net *net, int port)
} }
#endif #endif
extern int sysctl_ip_nonlocal_bind;
/* From inetpeer.c */ /* From inetpeer.c */
extern int inet_peer_threshold; extern int inet_peer_threshold;
extern int inet_peer_minttl; extern int inet_peer_minttl;

Просмотреть файл

@ -76,6 +76,7 @@ struct netns_ipv4 {
int sysctl_tcp_ecn; int sysctl_tcp_ecn;
int sysctl_ip_no_pmtu_disc; int sysctl_ip_no_pmtu_disc;
int sysctl_ip_fwd_use_pmtu; int sysctl_ip_fwd_use_pmtu;
int sysctl_ip_nonlocal_bind;
int sysctl_fwmark_reflect; int sysctl_fwmark_reflect;
int sysctl_tcp_fwmark_accept; int sysctl_tcp_fwmark_accept;

Просмотреть файл

@ -418,10 +418,6 @@ int inet_release(struct socket *sock)
} }
EXPORT_SYMBOL(inet_release); 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) int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{ {
struct sockaddr_in *addr = (struct sockaddr_in *)uaddr; 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) * is temporarily down)
*/ */
err = -EADDRNOTAVAIL; err = -EADDRNOTAVAIL;
if (!sysctl_ip_nonlocal_bind && if (!net->ipv4.sysctl_ip_nonlocal_bind &&
!(inet->freebind || inet->transparent) && !(inet->freebind || inet->transparent) &&
addr->sin_addr.s_addr != htonl(INADDR_ANY) && addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
chk_addr_ret != RTN_LOCAL && chk_addr_ret != RTN_LOCAL &&

Просмотреть файл

@ -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)) if (addr->sin_addr.s_addr == htonl(INADDR_ANY))
chk_addr_ret = RTN_LOCAL; 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 && isk->freebind == 0 && isk->transparent == 0 &&
chk_addr_ret != RTN_LOCAL) || chk_addr_ret != RTN_LOCAL) ||
chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_MULTICAST ||

Просмотреть файл

@ -285,13 +285,6 @@ static struct ctl_table ipv4_table[] = {
.extra1 = &ip_ttl_min, .extra1 = &ip_ttl_min,
.extra2 = &ip_ttl_max, .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", .procname = "tcp_syn_retries",
.data = &sysctl_tcp_syn_retries, .data = &sysctl_tcp_syn_retries,
@ -848,6 +841,13 @@ static struct ctl_table ipv4_net_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .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", .procname = "fwmark_reflect",
.data = &init_net.ipv4.sysctl_fwmark_reflect, .data = &init_net.ipv4.sysctl_fwmark_reflect,

Просмотреть файл

@ -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 */ /* Reproduce AF_INET checks to make the bindings consistent */
v4addr = addr->sin6_addr.s6_addr32[3]; v4addr = addr->sin6_addr.s6_addr32[3];
chk_addr_ret = inet_addr_type(net, v4addr); chk_addr_ret = inet_addr_type(net, v4addr);
if (!sysctl_ip_nonlocal_bind && if (!net->ipv4.sysctl_ip_nonlocal_bind &&
!(inet->freebind || inet->transparent) && !(inet->freebind || inet->transparent) &&
v4addr != htonl(INADDR_ANY) && v4addr != htonl(INADDR_ANY) &&
chk_addr_ret != RTN_LOCAL && chk_addr_ret != RTN_LOCAL &&

Просмотреть файл

@ -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) && if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) &&
ret != RTN_LOCAL && ret != RTN_LOCAL &&
!sp->inet.freebind && !sp->inet.freebind &&
!sysctl_ip_nonlocal_bind) !net->ipv4.sysctl_ip_nonlocal_bind)
return 0; return 0;
if (ipv6_only_sock(sctp_opt2sk(sp))) if (ipv6_only_sock(sctp_opt2sk(sp)))