diff options
Diffstat (limited to 'net/ipv4/sysctl_net_ipv4.c')
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 75 |
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 | ||
93 | extern seqlock_t sysctl_port_range_lock; | ||
94 | extern int sysctl_local_port_range[2]; | ||
95 | |||
96 | /* Update system visible IP port range */ | ||
97 | static 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. */ | ||
106 | static 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. */ | ||
134 | static 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 | |||
92 | static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file * filp, | 161 | static 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, |