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
@ -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)))
|
||||||
|
Loading…
Reference in New Issue
Block a user