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:
parent
afddacc3cc
commit
49a601589c
7 changed files with 12 additions and 17 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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)))
|
||||
|
|
Loading…
Reference in a new issue