aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Bernat <vincent@bernat.im>2014-09-05 09:09:03 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-09 14:27:09 -0400
commit49a601589caaf0e93194c0cc9b4ecddbe75dd2d5 (patch)
treecb4486c3522885f9b6bb61f10960e3b7b27a5b4f
parentafddacc3ccd048c49c7f4f0ad0b6a40730c74715 (diff)
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>
-rw-r--r--include/net/ip.h2
-rw-r--r--include/net/netns/ipv4.h1
-rw-r--r--net/ipv4/af_inet.c6
-rw-r--r--net/ipv4/ping.c2
-rw-r--r--net/ipv4/sysctl_net_ipv4.c14
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/sctp/protocol.c2
7 files changed, 12 insertions, 17 deletions
diff --git a/include/net/ip.h b/include/net/ip.h
index c8fd6112bd0b..14bfc8e1bcf9 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -229,8 +229,6 @@ static inline int inet_is_local_reserved_port(struct net *net, int port)
229} 229}
230#endif 230#endif
231 231
232extern int sysctl_ip_nonlocal_bind;
233
234/* From inetpeer.c */ 232/* From inetpeer.c */
235extern int inet_peer_threshold; 233extern int inet_peer_threshold;
236extern int inet_peer_minttl; 234extern int inet_peer_minttl;
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index aec5e12f9f19..24945cefc4fd 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -76,6 +76,7 @@ struct netns_ipv4 {
76 int sysctl_tcp_ecn; 76 int sysctl_tcp_ecn;
77 int sysctl_ip_no_pmtu_disc; 77 int sysctl_ip_no_pmtu_disc;
78 int sysctl_ip_fwd_use_pmtu; 78 int sysctl_ip_fwd_use_pmtu;
79 int sysctl_ip_nonlocal_bind;
79 80
80 int sysctl_fwmark_reflect; 81 int sysctl_fwmark_reflect;
81 int sysctl_tcp_fwmark_accept; 82 int sysctl_tcp_fwmark_accept;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index d156b3c5f363..b537bd94906c 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -418,10 +418,6 @@ int inet_release(struct socket *sock)
418} 418}
419EXPORT_SYMBOL(inet_release); 419EXPORT_SYMBOL(inet_release);
420 420
421/* It is off by default, see below. */
422int sysctl_ip_nonlocal_bind __read_mostly;
423EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
424
425int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 421int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
426{ 422{
427 struct sockaddr_in *addr = (struct sockaddr_in *)uaddr; 423 struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
@@ -461,7 +457,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
461 * is temporarily down) 457 * is temporarily down)
462 */ 458 */
463 err = -EADDRNOTAVAIL; 459 err = -EADDRNOTAVAIL;
464 if (!sysctl_ip_nonlocal_bind && 460 if (!net->ipv4.sysctl_ip_nonlocal_bind &&
465 !(inet->freebind || inet->transparent) && 461 !(inet->freebind || inet->transparent) &&
466 addr->sin_addr.s_addr != htonl(INADDR_ANY) && 462 addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
467 chk_addr_ret != RTN_LOCAL && 463 chk_addr_ret != RTN_LOCAL &&
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index a3c59a077a5f..57f7c9804139 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -311,7 +311,7 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
311 if (addr->sin_addr.s_addr == htonl(INADDR_ANY)) 311 if (addr->sin_addr.s_addr == htonl(INADDR_ANY))
312 chk_addr_ret = RTN_LOCAL; 312 chk_addr_ret = RTN_LOCAL;
313 313
314 if ((sysctl_ip_nonlocal_bind == 0 && 314 if ((net->ipv4.sysctl_ip_nonlocal_bind == 0 &&
315 isk->freebind == 0 && isk->transparent == 0 && 315 isk->freebind == 0 && isk->transparent == 0 &&
316 chk_addr_ret != RTN_LOCAL) || 316 chk_addr_ret != RTN_LOCAL) ||
317 chk_addr_ret == RTN_MULTICAST || 317 chk_addr_ret == RTN_MULTICAST ||
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 45d156dacd61..1599966f4639 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -286,13 +286,6 @@ static struct ctl_table ipv4_table[] = {
286 .extra2 = &ip_ttl_max, 286 .extra2 = &ip_ttl_max,
287 }, 287 },
288 { 288 {
289 .procname = "ip_nonlocal_bind",
290 .data = &sysctl_ip_nonlocal_bind,
291 .maxlen = sizeof(int),
292 .mode = 0644,
293 .proc_handler = proc_dointvec
294 },
295 {
296 .procname = "tcp_syn_retries", 289 .procname = "tcp_syn_retries",
297 .data = &sysctl_tcp_syn_retries, 290 .data = &sysctl_tcp_syn_retries,
298 .maxlen = sizeof(int), 291 .maxlen = sizeof(int),
@@ -849,6 +842,13 @@ static struct ctl_table ipv4_net_table[] = {
849 .proc_handler = proc_dointvec, 842 .proc_handler = proc_dointvec,
850 }, 843 },
851 { 844 {
845 .procname = "ip_nonlocal_bind",
846 .data = &init_net.ipv4.sysctl_ip_nonlocal_bind,
847 .maxlen = sizeof(int),
848 .mode = 0644,
849 .proc_handler = proc_dointvec
850 },
851 {
852 .procname = "fwmark_reflect", 852 .procname = "fwmark_reflect",
853 .data = &init_net.ipv4.sysctl_fwmark_reflect, 853 .data = &init_net.ipv4.sysctl_fwmark_reflect,
854 .maxlen = sizeof(int), 854 .maxlen = sizeof(int),
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index b9393e6a21fe..e4865a3ebe1d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -302,7 +302,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
302 /* Reproduce AF_INET checks to make the bindings consistent */ 302 /* Reproduce AF_INET checks to make the bindings consistent */
303 v4addr = addr->sin6_addr.s6_addr32[3]; 303 v4addr = addr->sin6_addr.s6_addr32[3];
304 chk_addr_ret = inet_addr_type(net, v4addr); 304 chk_addr_ret = inet_addr_type(net, v4addr);
305 if (!sysctl_ip_nonlocal_bind && 305 if (!net->ipv4.sysctl_ip_nonlocal_bind &&
306 !(inet->freebind || inet->transparent) && 306 !(inet->freebind || inet->transparent) &&
307 v4addr != htonl(INADDR_ANY) && 307 v4addr != htonl(INADDR_ANY) &&
308 chk_addr_ret != RTN_LOCAL && 308 chk_addr_ret != RTN_LOCAL &&
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 6240834f4b95..9d2c6c9facb6 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -366,7 +366,7 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
366 if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) && 366 if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) &&
367 ret != RTN_LOCAL && 367 ret != RTN_LOCAL &&
368 !sp->inet.freebind && 368 !sp->inet.freebind &&
369 !sysctl_ip_nonlocal_bind) 369 !net->ipv4.sysctl_ip_nonlocal_bind)
370 return 0; 370 return 0;
371 371
372 if (ipv6_only_sock(sctp_opt2sk(sp))) 372 if (ipv6_only_sock(sctp_opt2sk(sp)))