sysctl_net_ipv4.c 19.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10
/*
 * sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem.
 *
 * Begun April 1, 1996, Mike Shaver.
 * Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS]
 */

#include <linux/mm.h>
#include <linux/module.h>
#include <linux/sysctl.h>
11
#include <linux/igmp.h>
12
#include <linux/inetdevice.h>
13
#include <linux/seqlock.h>
14
#include <linux/init.h>
15
#include <linux/slab.h>
16
#include <linux/nsproxy.h>
G
Glauber Costa 已提交
17
#include <linux/swap.h>
L
Linus Torvalds 已提交
18
#include <net/snmp.h>
19
#include <net/icmp.h>
L
Linus Torvalds 已提交
20 21 22
#include <net/ip.h>
#include <net/route.h>
#include <net/tcp.h>
H
Hideo Aoki 已提交
23
#include <net/udp.h>
P
Paul Moore 已提交
24
#include <net/cipso_ipv4.h>
25
#include <net/inet_frag.h>
26
#include <net/ping.h>
L
Linus Torvalds 已提交
27

H
Herbert Xu 已提交
28
static int zero;
29
static int tcp_retr1_max = 255;
L
Linus Torvalds 已提交
30 31
static int ip_local_port_range_min[] = { 1, 1 };
static int ip_local_port_range_max[] = { 65535, 65535 };
32 33
static int tcp_adv_win_scale_min = -31;
static int tcp_adv_win_scale_max = 31;
E
Eric Dumazet 已提交
34 35
static int ip_ttl_min = 1;
static int ip_ttl_max = 255;
36 37
static int ip_ping_group_range_min[] = { 0, 0 };
static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX };
L
Linus Torvalds 已提交
38

39 40 41
/* Update system visible IP port range */
static void set_local_port_range(int range[2])
{
E
Eric Dumazet 已提交
42 43 44 45
	write_seqlock(&sysctl_local_ports.lock);
	sysctl_local_ports.range[0] = range[0];
	sysctl_local_ports.range[1] = range[1];
	write_sequnlock(&sysctl_local_ports.lock);
46 47 48
}

/* Validate changes from /proc interface. */
49
static int ipv4_local_port_range(ctl_table *table, int write,
50 51 52 53
				 void __user *buffer,
				 size_t *lenp, loff_t *ppos)
{
	int ret;
E
Eric Dumazet 已提交
54
	int range[2];
55 56 57 58 59 60 61 62
	ctl_table tmp = {
		.data = &range,
		.maxlen = sizeof(range),
		.mode = table->mode,
		.extra1 = &ip_local_port_range_min,
		.extra2 = &ip_local_port_range_max,
	};

E
Eric Dumazet 已提交
63
	inet_get_local_port_range(range, range + 1);
64
	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
65 66

	if (write && ret == 0) {
67
		if (range[1] < range[0])
68 69 70 71 72 73 74 75
			ret = -EINVAL;
		else
			set_local_port_range(range);
	}

	return ret;
}

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

void inet_get_ping_group_range_table(struct ctl_table *table, gid_t *low, gid_t *high)
{
	gid_t *data = table->data;
	unsigned seq;
	do {
		seq = read_seqbegin(&sysctl_local_ports.lock);

		*low = data[0];
		*high = data[1];
	} while (read_seqretry(&sysctl_local_ports.lock, seq));
}

/* Update system visible IP port range */
static void set_ping_group_range(struct ctl_table *table, int range[2])
{
	gid_t *data = table->data;
	write_seqlock(&sysctl_local_ports.lock);
	data[0] = range[0];
	data[1] = range[1];
	write_sequnlock(&sysctl_local_ports.lock);
}

/* Validate changes from /proc interface. */
static int ipv4_ping_group_range(ctl_table *table, int write,
				 void __user *buffer,
				 size_t *lenp, loff_t *ppos)
{
	int ret;
	gid_t range[2];
	ctl_table tmp = {
		.data = &range,
		.maxlen = sizeof(range),
		.mode = table->mode,
		.extra1 = &ip_ping_group_range_min,
		.extra2 = &ip_ping_group_range_max,
	};

	inet_get_ping_group_range_table(table, range, range + 1);
	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);

	if (write && ret == 0)
		set_ping_group_range(table, range);

	return ret;
}

123
static int proc_tcp_congestion_control(ctl_table *ctl, int write,
124 125 126 127 128 129 130 131 132 133 134
				       void __user *buffer, size_t *lenp, loff_t *ppos)
{
	char val[TCP_CA_NAME_MAX];
	ctl_table tbl = {
		.data = val,
		.maxlen = TCP_CA_NAME_MAX,
	};
	int ret;

	tcp_get_default_congestion_control(val);

135
	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
136 137 138 139 140
	if (write && ret == 0)
		ret = tcp_set_default_congestion_control(val);
	return ret;
}

141
static int proc_tcp_available_congestion_control(ctl_table *ctl,
142
						 int write,
143 144 145 146 147 148 149 150 151 152
						 void __user *buffer, size_t *lenp,
						 loff_t *ppos)
{
	ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX, };
	int ret;

	tbl.data = kmalloc(tbl.maxlen, GFP_USER);
	if (!tbl.data)
		return -ENOMEM;
	tcp_get_available_congestion_control(tbl.data, TCP_CA_BUF_MAX);
153
	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
154 155 156 157
	kfree(tbl.data);
	return ret;
}

158
static int proc_allowed_congestion_control(ctl_table *ctl,
159
					   int write,
160 161 162 163 164 165 166 167 168 169 170
					   void __user *buffer, size_t *lenp,
					   loff_t *ppos)
{
	ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX };
	int ret;

	tbl.data = kmalloc(tbl.maxlen, GFP_USER);
	if (!tbl.data)
		return -ENOMEM;

	tcp_get_allowed_congestion_control(tbl.data, tbl.maxlen);
171
	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
172 173 174 175 176 177
	if (write && ret == 0)
		ret = tcp_set_allowed_congestion_control(tbl.data);
	kfree(tbl.data);
	return ret;
}

G
Glauber Costa 已提交
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
static int ipv4_tcp_mem(ctl_table *ctl, int write,
			   void __user *buffer, size_t *lenp,
			   loff_t *ppos)
{
	int ret;
	unsigned long vec[3];
	struct net *net = current->nsproxy->net_ns;

	ctl_table tmp = {
		.data = &vec,
		.maxlen = sizeof(vec),
		.mode = ctl->mode,
	};

	if (!write) {
		ctl->data = &net->ipv4.sysctl_tcp_mem;
		return proc_doulongvec_minmax(ctl, write, buffer, lenp, ppos);
	}

	ret = proc_doulongvec_minmax(&tmp, write, buffer, lenp, ppos);
	if (ret)
		return ret;

	net->ipv4.sysctl_tcp_mem[0] = vec[0];
	net->ipv4.sysctl_tcp_mem[1] = vec[1];
	net->ipv4.sysctl_tcp_mem[2] = vec[2];

	return 0;
}

208
static struct ctl_table ipv4_table[] = {
209
	{
L
Linus Torvalds 已提交
210 211 212 213
		.procname	= "tcp_timestamps",
		.data		= &sysctl_tcp_timestamps,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
214
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
215
	},
216
	{
L
Linus Torvalds 已提交
217 218 219 220
		.procname	= "tcp_window_scaling",
		.data		= &sysctl_tcp_window_scaling,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
221
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
222
	},
223
	{
L
Linus Torvalds 已提交
224 225 226 227
		.procname	= "tcp_sack",
		.data		= &sysctl_tcp_sack,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
228
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
229
	},
230
	{
L
Linus Torvalds 已提交
231 232 233 234
		.procname	= "tcp_retrans_collapse",
		.data		= &sysctl_tcp_retrans_collapse,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
235
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
236
	},
237
	{
L
Linus Torvalds 已提交
238
		.procname	= "ip_default_ttl",
239
		.data		= &sysctl_ip_default_ttl,
L
Linus Torvalds 已提交
240 241
		.maxlen		= sizeof(int),
		.mode		= 0644,
E
Eric Dumazet 已提交
242 243 244
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= &ip_ttl_min,
		.extra2		= &ip_ttl_max,
L
Linus Torvalds 已提交
245
	},
246
	{
L
Linus Torvalds 已提交
247 248 249 250
		.procname	= "ip_no_pmtu_disc",
		.data		= &ipv4_config.no_pmtu_disc,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
251
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
252 253 254 255 256 257
	},
	{
		.procname	= "ip_nonlocal_bind",
		.data		= &sysctl_ip_nonlocal_bind,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
258
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
259 260 261 262 263 264
	},
	{
		.procname	= "tcp_syn_retries",
		.data		= &sysctl_tcp_syn_retries,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
265
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
266 267 268 269 270 271
	},
	{
		.procname	= "tcp_synack_retries",
		.data		= &sysctl_tcp_synack_retries,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
272
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
273 274 275 276 277 278
	},
	{
		.procname	= "tcp_max_orphans",
		.data		= &sysctl_tcp_max_orphans,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
279
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
280 281 282
	},
	{
		.procname	= "tcp_max_tw_buckets",
283
		.data		= &tcp_death_row.sysctl_max_tw_buckets,
L
Linus Torvalds 已提交
284 285
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
286
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
287 288 289 290 291 292
	},
	{
		.procname	= "ip_dynaddr",
		.data		= &sysctl_ip_dynaddr,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
293
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
294 295 296 297 298 299
	},
	{
		.procname	= "tcp_keepalive_time",
		.data		= &sysctl_tcp_keepalive_time,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
300
		.proc_handler	= proc_dointvec_jiffies,
L
Linus Torvalds 已提交
301 302 303 304 305 306
	},
	{
		.procname	= "tcp_keepalive_probes",
		.data		= &sysctl_tcp_keepalive_probes,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
307
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
308 309 310 311 312 313
	},
	{
		.procname	= "tcp_keepalive_intvl",
		.data		= &sysctl_tcp_keepalive_intvl,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
314
		.proc_handler	= proc_dointvec_jiffies,
L
Linus Torvalds 已提交
315 316 317 318 319 320
	},
	{
		.procname	= "tcp_retries1",
		.data		= &sysctl_tcp_retries1,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
321
		.proc_handler	= proc_dointvec_minmax,
L
Linus Torvalds 已提交
322 323 324 325 326 327 328
		.extra2		= &tcp_retr1_max
	},
	{
		.procname	= "tcp_retries2",
		.data		= &sysctl_tcp_retries2,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
329
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
330 331 332 333 334 335
	},
	{
		.procname	= "tcp_fin_timeout",
		.data		= &sysctl_tcp_fin_timeout,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
336
		.proc_handler	= proc_dointvec_jiffies,
L
Linus Torvalds 已提交
337 338 339 340 341 342 343
	},
#ifdef CONFIG_SYN_COOKIES
	{
		.procname	= "tcp_syncookies",
		.data		= &sysctl_tcp_syncookies,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
344
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
345 346 347 348
	},
#endif
	{
		.procname	= "tcp_tw_recycle",
349
		.data		= &tcp_death_row.sysctl_tw_recycle,
L
Linus Torvalds 已提交
350 351
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
352
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
353 354 355 356 357 358
	},
	{
		.procname	= "tcp_abort_on_overflow",
		.data		= &sysctl_tcp_abort_on_overflow,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
359
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
360 361 362 363 364 365
	},
	{
		.procname	= "tcp_stdurg",
		.data		= &sysctl_tcp_stdurg,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
366
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
367 368 369 370 371 372
	},
	{
		.procname	= "tcp_rfc1337",
		.data		= &sysctl_tcp_rfc1337,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
373
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
374 375 376 377 378 379
	},
	{
		.procname	= "tcp_max_syn_backlog",
		.data		= &sysctl_max_syn_backlog,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
380
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
381 382 383
	},
	{
		.procname	= "ip_local_port_range",
E
Eric Dumazet 已提交
384 385
		.data		= &sysctl_local_ports.range,
		.maxlen		= sizeof(sysctl_local_ports.range),
L
Linus Torvalds 已提交
386
		.mode		= 0644,
A
Alexey Dobriyan 已提交
387
		.proc_handler	= ipv4_local_port_range,
L
Linus Torvalds 已提交
388
	},
389 390 391 392 393 394 395
	{
		.procname	= "ip_local_reserved_ports",
		.data		= NULL, /* initialized in sysctl_ipv4_init */
		.maxlen		= 65536,
		.mode		= 0644,
		.proc_handler	= proc_do_large_bitmap,
	},
L
Linus Torvalds 已提交
396 397 398 399 400
	{
		.procname	= "igmp_max_memberships",
		.data		= &sysctl_igmp_max_memberships,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
401
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
402 403 404 405 406 407
	},
	{
		.procname	= "igmp_max_msf",
		.data		= &sysctl_igmp_max_msf,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
408
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
409 410 411 412 413 414
	},
	{
		.procname	= "inet_peer_threshold",
		.data		= &inet_peer_threshold,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
415
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
416 417 418 419 420 421
	},
	{
		.procname	= "inet_peer_minttl",
		.data		= &inet_peer_minttl,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
422
		.proc_handler	= proc_dointvec_jiffies,
L
Linus Torvalds 已提交
423 424 425 426 427 428
	},
	{
		.procname	= "inet_peer_maxttl",
		.data		= &inet_peer_maxttl,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
429
		.proc_handler	= proc_dointvec_jiffies,
L
Linus Torvalds 已提交
430 431 432 433 434 435
	},
	{
		.procname	= "tcp_orphan_retries",
		.data		= &sysctl_tcp_orphan_retries,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
436
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
437 438 439 440 441 442
	},
	{
		.procname	= "tcp_fack",
		.data		= &sysctl_tcp_fack,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
443
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
444 445 446 447 448 449
	},
	{
		.procname	= "tcp_reordering",
		.data		= &sysctl_tcp_reordering,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
450
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
451 452 453 454 455 456
	},
	{
		.procname	= "tcp_ecn",
		.data		= &sysctl_tcp_ecn,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
457
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
458 459 460 461 462 463
	},
	{
		.procname	= "tcp_dsack",
		.data		= &sysctl_tcp_dsack,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
464
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
465 466 467 468 469 470
	},
	{
		.procname	= "tcp_wmem",
		.data		= &sysctl_tcp_wmem,
		.maxlen		= sizeof(sysctl_tcp_wmem),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
471
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
472 473 474 475 476 477
	},
	{
		.procname	= "tcp_rmem",
		.data		= &sysctl_tcp_rmem,
		.maxlen		= sizeof(sysctl_tcp_rmem),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
478
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
479 480 481 482 483 484
	},
	{
		.procname	= "tcp_app_win",
		.data		= &sysctl_tcp_app_win,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
485
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
486 487 488 489 490 491
	},
	{
		.procname	= "tcp_adv_win_scale",
		.data		= &sysctl_tcp_adv_win_scale,
		.maxlen		= sizeof(int),
		.mode		= 0644,
492 493 494
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= &tcp_adv_win_scale_min,
		.extra2		= &tcp_adv_win_scale_max,
L
Linus Torvalds 已提交
495 496 497 498 499 500
	},
	{
		.procname	= "tcp_tw_reuse",
		.data		= &sysctl_tcp_tw_reuse,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
501
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
502 503 504 505 506 507
	},
	{
		.procname	= "tcp_frto",
		.data		= &sysctl_tcp_frto,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
508
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
509
	},
510 511 512 513 514
	{
		.procname	= "tcp_frto_response",
		.data		= &sysctl_tcp_frto_response,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
515
		.proc_handler	= proc_dointvec
516
	},
L
Linus Torvalds 已提交
517 518 519 520 521
	{
		.procname	= "tcp_low_latency",
		.data		= &sysctl_tcp_low_latency,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
522
		.proc_handler	= proc_dointvec
L
Linus Torvalds 已提交
523 524 525 526 527 528
	},
	{
		.procname	= "tcp_no_metrics_save",
		.data		= &sysctl_tcp_nometrics_save,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
529
		.proc_handler	= proc_dointvec,
L
Linus Torvalds 已提交
530 531 532 533 534 535
	},
	{
		.procname	= "tcp_moderate_rcvbuf",
		.data		= &sysctl_tcp_moderate_rcvbuf,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
536
		.proc_handler	= proc_dointvec,
L
Linus Torvalds 已提交
537 538 539 540 541 542
	},
	{
		.procname	= "tcp_tso_win_divisor",
		.data		= &sysctl_tcp_tso_win_divisor,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
543
		.proc_handler	= proc_dointvec,
L
Linus Torvalds 已提交
544 545
	},
	{
546
		.procname	= "tcp_congestion_control",
L
Linus Torvalds 已提交
547
		.mode		= 0644,
548
		.maxlen		= TCP_CA_NAME_MAX,
A
Alexey Dobriyan 已提交
549
		.proc_handler	= proc_tcp_congestion_control,
L
Linus Torvalds 已提交
550
	},
551 552 553 554 555
	{
		.procname	= "tcp_abc",
		.data		= &sysctl_tcp_abc,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
556
		.proc_handler	= proc_dointvec,
557
	},
J
John Heffner 已提交
558 559 560 561 562
	{
		.procname	= "tcp_mtu_probing",
		.data		= &sysctl_tcp_mtu_probing,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
563
		.proc_handler	= proc_dointvec,
J
John Heffner 已提交
564 565 566 567 568 569
	},
	{
		.procname	= "tcp_base_mss",
		.data		= &sysctl_tcp_base_mss,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
570
		.proc_handler	= proc_dointvec,
J
John Heffner 已提交
571
	},
572
	{
573 574 575 576
		.procname	= "tcp_workaround_signed_windows",
		.data		= &sysctl_tcp_workaround_signed_windows,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
577
		.proc_handler	= proc_dointvec
578
	},
579 580 581 582 583 584
#ifdef CONFIG_NET_DMA
	{
		.procname	= "tcp_dma_copybreak",
		.data		= &sysctl_tcp_dma_copybreak,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
585
		.proc_handler	= proc_dointvec
586 587
	},
#endif
588 589 590 591 592
	{
		.procname	= "tcp_slow_start_after_idle",
		.data		= &sysctl_tcp_slow_start_after_idle,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
593
		.proc_handler	= proc_dointvec
594
	},
P
Paul Moore 已提交
595 596 597 598 599 600
#ifdef CONFIG_NETLABEL
	{
		.procname	= "cipso_cache_enable",
		.data		= &cipso_v4_cache_enabled,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
601
		.proc_handler	= proc_dointvec,
P
Paul Moore 已提交
602 603 604 605 606 607
	},
	{
		.procname	= "cipso_cache_bucket_size",
		.data		= &cipso_v4_cache_bucketsize,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
608
		.proc_handler	= proc_dointvec,
P
Paul Moore 已提交
609 610 611 612 613 614
	},
	{
		.procname	= "cipso_rbm_optfmt",
		.data		= &cipso_v4_rbm_optfmt,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
615
		.proc_handler	= proc_dointvec,
P
Paul Moore 已提交
616 617 618 619 620 621
	},
	{
		.procname	= "cipso_rbm_strictvalid",
		.data		= &cipso_v4_rbm_strictvalid,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
622
		.proc_handler	= proc_dointvec,
P
Paul Moore 已提交
623 624
	},
#endif /* CONFIG_NETLABEL */
625 626 627 628
	{
		.procname	= "tcp_available_congestion_control",
		.maxlen		= TCP_CA_BUF_MAX,
		.mode		= 0444,
A
Alexey Dobriyan 已提交
629
		.proc_handler   = proc_tcp_available_congestion_control,
630
	},
631 632 633 634
	{
		.procname	= "tcp_allowed_congestion_control",
		.maxlen		= TCP_CA_BUF_MAX,
		.mode		= 0644,
A
Alexey Dobriyan 已提交
635
		.proc_handler   = proc_allowed_congestion_control,
636
	},
637 638 639 640 641
	{
		.procname	= "tcp_max_ssthresh",
		.data		= &sysctl_tcp_max_ssthresh,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
642
		.proc_handler	= proc_dointvec,
643
	},
644 645 646 647 648 649 650
	{
		.procname	= "tcp_cookie_size",
		.data		= &sysctl_tcp_cookie_size,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec
	},
A
Andreas Petlund 已提交
651 652 653 654 655 656 657
	{
		.procname       = "tcp_thin_linear_timeouts",
		.data           = &sysctl_tcp_thin_linear_timeouts,
		.maxlen         = sizeof(int),
		.mode           = 0644,
		.proc_handler   = proc_dointvec
	},
A
Andreas Petlund 已提交
658 659 660 661 662 663 664
        {
		.procname       = "tcp_thin_dupack",
		.data           = &sysctl_tcp_thin_dupack,
		.maxlen         = sizeof(int),
		.mode           = 0644,
		.proc_handler   = proc_dointvec
	},
H
Hideo Aoki 已提交
665 666 667 668 669
	{
		.procname	= "udp_mem",
		.data		= &sysctl_udp_mem,
		.maxlen		= sizeof(sysctl_udp_mem),
		.mode		= 0644,
E
Eric Dumazet 已提交
670
		.proc_handler	= proc_doulongvec_minmax,
H
Hideo Aoki 已提交
671 672 673 674 675 676
	},
	{
		.procname	= "udp_rmem_min",
		.data		= &sysctl_udp_rmem_min,
		.maxlen		= sizeof(sysctl_udp_rmem_min),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
677
		.proc_handler	= proc_dointvec_minmax,
H
Hideo Aoki 已提交
678 679 680 681 682 683 684
		.extra1		= &zero
	},
	{
		.procname	= "udp_wmem_min",
		.data		= &sysctl_udp_wmem_min,
		.maxlen		= sizeof(sysctl_udp_wmem_min),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
685
		.proc_handler	= proc_dointvec_minmax,
H
Hideo Aoki 已提交
686 687
		.extra1		= &zero
	},
688
	{ }
L
Linus Torvalds 已提交
689
};
690

691 692 693 694 695 696
static struct ctl_table ipv4_net_table[] = {
	{
		.procname	= "icmp_echo_ignore_all",
		.data		= &init_net.ipv4.sysctl_icmp_echo_ignore_all,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
697
		.proc_handler	= proc_dointvec
698 699 700 701 702 703
	},
	{
		.procname	= "icmp_echo_ignore_broadcasts",
		.data		= &init_net.ipv4.sysctl_icmp_echo_ignore_broadcasts,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
704
		.proc_handler	= proc_dointvec
705 706 707 708 709 710
	},
	{
		.procname	= "icmp_ignore_bogus_error_responses",
		.data		= &init_net.ipv4.sysctl_icmp_ignore_bogus_error_responses,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
711
		.proc_handler	= proc_dointvec
712 713 714 715 716 717
	},
	{
		.procname	= "icmp_errors_use_inbound_ifaddr",
		.data		= &init_net.ipv4.sysctl_icmp_errors_use_inbound_ifaddr,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
718
		.proc_handler	= proc_dointvec
719 720 721 722 723 724
	},
	{
		.procname	= "icmp_ratelimit",
		.data		= &init_net.ipv4.sysctl_icmp_ratelimit,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
725
		.proc_handler	= proc_dointvec_ms_jiffies,
726 727 728 729 730 731
	},
	{
		.procname	= "icmp_ratemask",
		.data		= &init_net.ipv4.sysctl_icmp_ratemask,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
732
		.proc_handler	= proc_dointvec
733
	},
734 735 736 737 738
	{
		.procname	= "rt_cache_rebuild_count",
		.data		= &init_net.ipv4.sysctl_rt_cache_rebuild_count,
		.maxlen		= sizeof(int),
		.mode		= 0644,
A
Alexey Dobriyan 已提交
739
		.proc_handler	= proc_dointvec
740
	},
741 742 743 744 745 746 747
	{
		.procname	= "ping_group_range",
		.data		= &init_net.ipv4.sysctl_ping_group_range,
		.maxlen		= sizeof(init_net.ipv4.sysctl_ping_group_range),
		.mode		= 0644,
		.proc_handler	= ipv4_ping_group_range,
	},
G
Glauber Costa 已提交
748 749 750 751 752 753
	{
		.procname	= "tcp_mem",
		.maxlen		= sizeof(init_net.ipv4.sysctl_tcp_mem),
		.mode		= 0644,
		.proc_handler	= ipv4_tcp_mem,
	},
754 755 756
	{ }
};

757
struct ctl_path net_ipv4_ctl_path[] = {
758 759
	{ .procname = "net", },
	{ .procname = "ipv4", },
760 761
	{ },
};
762
EXPORT_SYMBOL_GPL(net_ipv4_ctl_path);
763

764 765
static __net_init int ipv4_sysctl_init_net(struct net *net)
{
766
	struct ctl_table *table;
G
Glauber Costa 已提交
767
	unsigned long limit;
768 769

	table = ipv4_net_table;
O
Octavian Purdila 已提交
770
	if (!net_eq(net, &init_net)) {
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786
		table = kmemdup(table, sizeof(ipv4_net_table), GFP_KERNEL);
		if (table == NULL)
			goto err_alloc;

		table[0].data =
			&net->ipv4.sysctl_icmp_echo_ignore_all;
		table[1].data =
			&net->ipv4.sysctl_icmp_echo_ignore_broadcasts;
		table[2].data =
			&net->ipv4.sysctl_icmp_ignore_bogus_error_responses;
		table[3].data =
			&net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr;
		table[4].data =
			&net->ipv4.sysctl_icmp_ratelimit;
		table[5].data =
			&net->ipv4.sysctl_icmp_ratemask;
787 788
		table[6].data =
			&net->ipv4.sysctl_rt_cache_rebuild_count;
789 790 791
		table[7].data =
			&net->ipv4.sysctl_ping_group_range;

792 793
	}

794 795 796 797 798 799 800
	/*
	 * Sane defaults - nobody may create ping sockets.
	 * Boot scripts should set this to distro-specific group.
	 */
	net->ipv4.sysctl_ping_group_range[0] = 1;
	net->ipv4.sysctl_ping_group_range[1] = 0;

801 802
	net->ipv4.sysctl_rt_cache_rebuild_count = 4;

G
Glauber Costa 已提交
803 804 805 806 807 808
	limit = nr_free_buffer_pages() / 8;
	limit = max(limit, 128UL);
	net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3;
	net->ipv4.sysctl_tcp_mem[1] = limit;
	net->ipv4.sysctl_tcp_mem[2] = net->ipv4.sysctl_tcp_mem[0] * 2;

809 810 811 812 813
	net->ipv4.ipv4_hdr = register_net_sysctl_table(net,
			net_ipv4_ctl_path, table);
	if (net->ipv4.ipv4_hdr == NULL)
		goto err_reg;

814
	return 0;
815 816

err_reg:
O
Octavian Purdila 已提交
817
	if (!net_eq(net, &init_net))
818 819 820
		kfree(table);
err_alloc:
	return -ENOMEM;
821 822 823 824
}

static __net_exit void ipv4_sysctl_exit_net(struct net *net)
{
825 826 827 828 829
	struct ctl_table *table;

	table = net->ipv4.ipv4_hdr->ctl_table_arg;
	unregister_net_sysctl_table(net->ipv4.ipv4_hdr);
	kfree(table);
830 831 832 833 834 835 836
}

static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
	.init = ipv4_sysctl_init_net,
	.exit = ipv4_sysctl_exit_net,
};

837 838 839
static __init int sysctl_ipv4_init(void)
{
	struct ctl_table_header *hdr;
840 841 842 843 844 845 846 847 848 849
	struct ctl_table *i;

	for (i = ipv4_table; i->procname; i++) {
		if (strcmp(i->procname, "ip_local_reserved_ports") == 0) {
			i->data = sysctl_local_reserved_ports;
			break;
		}
	}
	if (!i->procname)
		return -EINVAL;
850

851
	hdr = register_sysctl_paths(net_ipv4_ctl_path, ipv4_table);
852 853 854 855 856 857 858 859 860
	if (hdr == NULL)
		return -ENOMEM;

	if (register_pernet_subsys(&ipv4_sysctl_ops)) {
		unregister_sysctl_table(hdr);
		return -ENOMEM;
	}

	return 0;
861 862 863
}

__initcall(sysctl_ipv4_init);