aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/sysctl_net_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/sysctl_net_ipv4.c')
-rw-r--r--net/ipv4/sysctl_net_ipv4.c75
1 files changed, 71 insertions, 4 deletions
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 53ef0f4bbdaa..eb286abcf5dc 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -12,6 +12,7 @@
12#include <linux/sysctl.h> 12#include <linux/sysctl.h>
13#include <linux/igmp.h> 13#include <linux/igmp.h>
14#include <linux/inetdevice.h> 14#include <linux/inetdevice.h>
15#include <linux/seqlock.h>
15#include <net/snmp.h> 16#include <net/snmp.h>
16#include <net/icmp.h> 17#include <net/icmp.h>
17#include <net/ip.h> 18#include <net/ip.h>
@@ -89,6 +90,74 @@ static int ipv4_sysctl_forward_strategy(ctl_table *table,
89 return 1; 90 return 1;
90} 91}
91 92
93extern seqlock_t sysctl_port_range_lock;
94extern int sysctl_local_port_range[2];
95
96/* Update system visible IP port range */
97static void set_local_port_range(int range[2])
98{
99 write_seqlock(&sysctl_port_range_lock);
100 sysctl_local_port_range[0] = range[0];
101 sysctl_local_port_range[1] = range[1];
102 write_sequnlock(&sysctl_port_range_lock);
103}
104
105/* Validate changes from /proc interface. */
106static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
107 void __user *buffer,
108 size_t *lenp, loff_t *ppos)
109{
110 int ret;
111 int range[2] = { sysctl_local_port_range[0],
112 sysctl_local_port_range[1] };
113 ctl_table tmp = {
114 .data = &range,
115 .maxlen = sizeof(range),
116 .mode = table->mode,
117 .extra1 = &ip_local_port_range_min,
118 .extra2 = &ip_local_port_range_max,
119 };
120
121 ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos);
122
123 if (write && ret == 0) {
124 if (range[1] <= range[0])
125 ret = -EINVAL;
126 else
127 set_local_port_range(range);
128 }
129
130 return ret;
131}
132
133/* Validate changes from sysctl interface. */
134static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
135 int nlen, void __user *oldval,
136 size_t __user *oldlenp,
137 void __user *newval, size_t newlen)
138{
139 int ret;
140 int range[2] = { sysctl_local_port_range[0],
141 sysctl_local_port_range[1] };
142 ctl_table tmp = {
143 .data = &range,
144 .maxlen = sizeof(range),
145 .mode = table->mode,
146 .extra1 = &ip_local_port_range_min,
147 .extra2 = &ip_local_port_range_max,
148 };
149
150 ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen);
151 if (ret == 0 && newval && newlen) {
152 if (range[1] <= range[0])
153 ret = -EINVAL;
154 else
155 set_local_port_range(range);
156 }
157 return ret;
158}
159
160
92static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file * filp, 161static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file * filp,
93 void __user *buffer, size_t *lenp, loff_t *ppos) 162 void __user *buffer, size_t *lenp, loff_t *ppos)
94{ 163{
@@ -427,10 +496,8 @@ ctl_table ipv4_table[] = {
427 .data = &sysctl_local_port_range, 496 .data = &sysctl_local_port_range,
428 .maxlen = sizeof(sysctl_local_port_range), 497 .maxlen = sizeof(sysctl_local_port_range),
429 .mode = 0644, 498 .mode = 0644,
430 .proc_handler = &proc_dointvec_minmax, 499 .proc_handler = &ipv4_local_port_range,
431 .strategy = &sysctl_intvec, 500 .strategy = &ipv4_sysctl_local_port_range,
432 .extra1 = ip_local_port_range_min,
433 .extra2 = ip_local_port_range_max
434 }, 501 },
435 { 502 {
436 .ctl_name = NET_IPV4_ICMP_ECHO_IGNORE_ALL, 503 .ctl_name = NET_IPV4_ICMP_ECHO_IGNORE_ALL,