diff options
Diffstat (limited to 'net/ipv4/sysctl_net_ipv4.c')
| -rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 570 | 
1 files changed, 314 insertions, 256 deletions
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 9684af02e0a5..9b8a6db7a66b 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -6,32 +6,20 @@   * Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS]   */ -#include <linux/mm.h> -#include <linux/module.h>  #include <linux/sysctl.h> -#include <linux/igmp.h> -#include <linux/inetdevice.h>  #include <linux/seqlock.h>  #include <linux/init.h>  #include <linux/slab.h> -#include <linux/nsproxy.h> -#include <linux/swap.h> -#include <net/snmp.h>  #include <net/icmp.h>  #include <net/ip.h> -#include <net/route.h> +#include <net/ip_fib.h>  #include <net/tcp.h>  #include <net/udp.h>  #include <net/cipso_ipv4.h> -#include <net/inet_frag.h>  #include <net/ping.h>  #include <net/protocol.h>  #include <net/netevent.h> -static int two = 2; -static int four = 4; -static int thousand = 1000; -static int gso_max_segs = GSO_MAX_SEGS;  static int tcp_retr1_max = 255;  static int ip_local_port_range_min[] = { 1, 1 };  static int ip_local_port_range_max[] = { 65535, 65535 }; @@ -47,9 +35,11 @@ static int tcp_syn_retries_min = 1;  static int tcp_syn_retries_max = MAX_TCP_SYNCNT;  static int ip_ping_group_range_min[] = { 0, 0 };  static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX }; -static int comp_sack_nr_max = 255;  static u32 u32_max_div_HZ = UINT_MAX / HZ;  static int one_day_secs = 24 * 3600; +static u32 fib_multipath_hash_fields_all_mask __maybe_unused = +	FIB_MULTIPATH_HASH_FIELD_ALL_MASK; +static unsigned int tcp_child_ehash_entries_max = 16 * 1024 * 1024;  /* obsolete */  static int sysctl_tcp_low_latency __read_mostly; @@ -71,8 +61,7 @@ static void set_local_port_range(struct net *net, int range[2])  /* Validate changes from /proc interface. */  static int ipv4_local_port_range(struct ctl_table *table, int write, -				 void __user *buffer, -				 size_t *lenp, loff_t *ppos) +				 void *buffer, size_t *lenp, loff_t *ppos)  {  	struct net *net =  		container_of(table->data, struct net, ipv4.ip_local_ports.range); @@ -96,7 +85,7 @@ static int ipv4_local_port_range(struct ctl_table *table, int write,  		 * port limit.  		 */  		if ((range[1] < range[0]) || -		    (range[0] < net->ipv4.sysctl_ip_prot_sock)) +		    (range[0] < READ_ONCE(net->ipv4.sysctl_ip_prot_sock)))  			ret = -EINVAL;  		else  			set_local_port_range(net, range); @@ -107,7 +96,7 @@ static int ipv4_local_port_range(struct ctl_table *table, int write,  /* Validate changes from /proc interface. */  static int ipv4_privileged_ports(struct ctl_table *table, int write, -				void __user *buffer, size_t *lenp, loff_t *ppos) +				void *buffer, size_t *lenp, loff_t *ppos)  {  	struct net *net = container_of(table->data, struct net,  	    ipv4.sysctl_ip_prot_sock); @@ -122,7 +111,7 @@ static int ipv4_privileged_ports(struct ctl_table *table, int write,  		.extra2 = &ip_privileged_port_max,  	}; -	pports = net->ipv4.sysctl_ip_prot_sock; +	pports = READ_ONCE(net->ipv4.sysctl_ip_prot_sock);  	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); @@ -134,7 +123,7 @@ static int ipv4_privileged_ports(struct ctl_table *table, int write,  		if (range[0] < pports)  			ret = -EINVAL;  		else -			net->ipv4.sysctl_ip_prot_sock = pports; +			WRITE_ONCE(net->ipv4.sysctl_ip_prot_sock, pports);  	}  	return ret; @@ -168,8 +157,7 @@ static void set_ping_group_range(struct ctl_table *table, kgid_t low, kgid_t hig  /* Validate changes from /proc interface. */  static int ipv4_ping_group_range(struct ctl_table *table, int write, -				 void __user *buffer, -				 size_t *lenp, loff_t *ppos) +				 void *buffer, size_t *lenp, loff_t *ppos)  {  	struct user_namespace *user_ns = current_user_ns();  	int ret; @@ -204,15 +192,14 @@ static int ipv4_ping_group_range(struct ctl_table *table, int write,  }  static int ipv4_fwd_update_priority(struct ctl_table *table, int write, -				    void __user *buffer, -				    size_t *lenp, loff_t *ppos) +				    void *buffer, size_t *lenp, loff_t *ppos)  {  	struct net *net;  	int ret;  	net = container_of(table->data, struct net,  			   ipv4.sysctl_ip_fwd_update_priority); -	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); +	ret = proc_dou8vec_minmax(table, write, buffer, lenp, ppos);  	if (write && ret == 0)  		call_netevent_notifiers(NETEVENT_IPV4_FWD_UPDATE_PRIORITY_UPDATE,  					net); @@ -221,7 +208,7 @@ static int ipv4_fwd_update_priority(struct ctl_table *table, int write,  }  static int proc_tcp_congestion_control(struct ctl_table *ctl, int write, -				       void __user *buffer, size_t *lenp, loff_t *ppos) +				       void *buffer, size_t *lenp, loff_t *ppos)  {  	struct net *net = container_of(ctl->data, struct net,  				       ipv4.tcp_congestion_control); @@ -241,9 +228,8 @@ static int proc_tcp_congestion_control(struct ctl_table *ctl, int write,  }  static int proc_tcp_available_congestion_control(struct ctl_table *ctl, -						 int write, -						 void __user *buffer, size_t *lenp, -						 loff_t *ppos) +						 int write, void *buffer, +						 size_t *lenp, loff_t *ppos)  {  	struct ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX, };  	int ret; @@ -258,9 +244,8 @@ static int proc_tcp_available_congestion_control(struct ctl_table *ctl,  }  static int proc_allowed_congestion_control(struct ctl_table *ctl, -					   int write, -					   void __user *buffer, size_t *lenp, -					   loff_t *ppos) +					   int write, void *buffer, +					   size_t *lenp, loff_t *ppos)  {  	struct ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX };  	int ret; @@ -296,8 +281,7 @@ static int sscanf_key(char *buf, __le32 *key)  }  static int proc_tcp_fastopen_key(struct ctl_table *table, int write, -				 void __user *buffer, size_t *lenp, -				 loff_t *ppos) +				 void *buffer, size_t *lenp, loff_t *ppos)  {  	struct net *net = container_of(table->data, struct net,  	    ipv4.sysctl_tcp_fastopen); @@ -307,24 +291,16 @@ static int proc_tcp_fastopen_key(struct ctl_table *table, int write,  	struct ctl_table tbl = { .maxlen = ((TCP_FASTOPEN_KEY_LENGTH *  					    2 * TCP_FASTOPEN_KEY_MAX) +  					    (TCP_FASTOPEN_KEY_MAX * 5)) }; -	struct tcp_fastopen_context *ctx; -	u32 user_key[TCP_FASTOPEN_KEY_MAX * 4]; -	__le32 key[TCP_FASTOPEN_KEY_MAX * 4]; +	u32 user_key[TCP_FASTOPEN_KEY_BUF_LENGTH / sizeof(u32)]; +	__le32 key[TCP_FASTOPEN_KEY_BUF_LENGTH / sizeof(__le32)];  	char *backup_data; -	int ret, i = 0, off = 0, n_keys = 0; +	int ret, i = 0, off = 0, n_keys;  	tbl.data = kmalloc(tbl.maxlen, GFP_KERNEL);  	if (!tbl.data)  		return -ENOMEM; -	rcu_read_lock(); -	ctx = rcu_dereference(net->ipv4.tcp_fastopen_ctx); -	if (ctx) { -		n_keys = tcp_fastopen_context_len(ctx); -		memcpy(&key[0], &ctx->key[0], TCP_FASTOPEN_KEY_LENGTH * n_keys); -	} -	rcu_read_unlock(); - +	n_keys = tcp_fastopen_get_cipher(net, NULL, (u64 *)key);  	if (!n_keys) {  		memset(&key[0], 0, TCP_FASTOPEN_KEY_LENGTH);  		n_keys = 1; @@ -375,64 +351,8 @@ bad_key:  	return ret;  } -static void proc_configure_early_demux(int enabled, int protocol) -{ -	struct net_protocol *ipprot; -#if IS_ENABLED(CONFIG_IPV6) -	struct inet6_protocol *ip6prot; -#endif - -	rcu_read_lock(); - -	ipprot = rcu_dereference(inet_protos[protocol]); -	if (ipprot) -		ipprot->early_demux = enabled ? ipprot->early_demux_handler : -						NULL; - -#if IS_ENABLED(CONFIG_IPV6) -	ip6prot = rcu_dereference(inet6_protos[protocol]); -	if (ip6prot) -		ip6prot->early_demux = enabled ? ip6prot->early_demux_handler : -						 NULL; -#endif -	rcu_read_unlock(); -} - -static int proc_tcp_early_demux(struct ctl_table *table, int write, -				void __user *buffer, size_t *lenp, loff_t *ppos) -{ -	int ret = 0; - -	ret = proc_dointvec(table, write, buffer, lenp, ppos); - -	if (write && !ret) { -		int enabled = init_net.ipv4.sysctl_tcp_early_demux; - -		proc_configure_early_demux(enabled, IPPROTO_TCP); -	} - -	return ret; -} - -static int proc_udp_early_demux(struct ctl_table *table, int write, -				void __user *buffer, size_t *lenp, loff_t *ppos) -{ -	int ret = 0; - -	ret = proc_dointvec(table, write, buffer, lenp, ppos); - -	if (write && !ret) { -		int enabled = init_net.ipv4.sysctl_udp_early_demux; - -		proc_configure_early_demux(enabled, IPPROTO_UDP); -	} - -	return ret; -} -  static int proc_tfo_blackhole_detect_timeout(struct ctl_table *table, -					     int write, -					     void __user *buffer, +					     int write, void *buffer,  					     size_t *lenp, loff_t *ppos)  {  	struct net *net = container_of(table->data, struct net, @@ -447,8 +367,7 @@ static int proc_tfo_blackhole_detect_timeout(struct ctl_table *table,  }  static int proc_tcp_available_ulp(struct ctl_table *ctl, -				  int write, -				  void __user *buffer, size_t *lenp, +				  int write, void *buffer, size_t *lenp,  				  loff_t *ppos)  {  	struct ctl_table tbl = { .maxlen = TCP_ULP_BUF_MAX, }; @@ -464,16 +383,55 @@ static int proc_tcp_available_ulp(struct ctl_table *ctl,  	return ret;  } +static int proc_tcp_ehash_entries(struct ctl_table *table, int write, +				  void *buffer, size_t *lenp, loff_t *ppos) +{ +	struct net *net = container_of(table->data, struct net, +				       ipv4.sysctl_tcp_child_ehash_entries); +	struct inet_hashinfo *hinfo = net->ipv4.tcp_death_row.hashinfo; +	int tcp_ehash_entries; +	struct ctl_table tbl; + +	tcp_ehash_entries = hinfo->ehash_mask + 1; + +	/* A negative number indicates that the child netns +	 * shares the global ehash. +	 */ +	if (!net_eq(net, &init_net) && !hinfo->pernet) +		tcp_ehash_entries *= -1; + +	tbl.data = &tcp_ehash_entries; +	tbl.maxlen = sizeof(int); + +	return proc_dointvec(&tbl, write, buffer, lenp, ppos); +} +  #ifdef CONFIG_IP_ROUTE_MULTIPATH  static int proc_fib_multipath_hash_policy(struct ctl_table *table, int write, -					  void __user *buffer, size_t *lenp, +					  void *buffer, size_t *lenp,  					  loff_t *ppos)  {  	struct net *net = container_of(table->data, struct net,  	    ipv4.sysctl_fib_multipath_hash_policy);  	int ret; -	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); +	ret = proc_dou8vec_minmax(table, write, buffer, lenp, ppos); +	if (write && ret == 0) +		call_netevent_notifiers(NETEVENT_IPV4_MPATH_HASH_UPDATE, net); + +	return ret; +} + +static int proc_fib_multipath_hash_fields(struct ctl_table *table, int write, +					  void *buffer, size_t *lenp, +					  loff_t *ppos) +{ +	struct net *net; +	int ret; + +	net = container_of(table->data, struct net, +			   ipv4.sysctl_fib_multipath_hash_fields); +	ret = proc_douintvec_minmax(table, write, buffer, lenp, ppos);  	if (write && ret == 0)  		call_netevent_notifiers(NETEVENT_IPV4_MPATH_HASH_UPDATE, net); @@ -555,18 +513,6 @@ static struct ctl_table ipv4_table[] = {  	},  #endif /* CONFIG_NETLABEL */  	{ -		.procname	= "tcp_available_congestion_control", -		.maxlen		= TCP_CA_BUF_MAX, -		.mode		= 0444, -		.proc_handler   = proc_tcp_available_congestion_control, -	}, -	{ -		.procname	= "tcp_allowed_congestion_control", -		.maxlen		= TCP_CA_BUF_MAX, -		.mode		= 0644, -		.proc_handler   = proc_allowed_congestion_control, -	}, -	{  		.procname	= "tcp_available_ulp",  		.maxlen		= TCP_ULP_BUF_MAX,  		.mode		= 0444, @@ -604,49 +550,61 @@ static struct ctl_table ipv4_table[] = {  		.extra1		= &sysctl_fib_sync_mem_min,  		.extra2		= &sysctl_fib_sync_mem_max,  	}, -	{ -		.procname	= "tcp_rx_skb_cache", -		.data		= &tcp_rx_skb_cache_key.key, -		.mode		= 0644, -		.proc_handler	= proc_do_static_key, -	}, -	{ -		.procname	= "tcp_tx_skb_cache", -		.data		= &tcp_tx_skb_cache_key.key, -		.mode		= 0644, -		.proc_handler	= proc_do_static_key, -	},  	{ }  };  static struct ctl_table ipv4_net_table[] = {  	{ -		.procname	= "icmp_echo_ignore_all", -		.data		= &init_net.ipv4.sysctl_icmp_echo_ignore_all, +		.procname	= "tcp_max_tw_buckets", +		.data		= &init_net.ipv4.tcp_death_row.sysctl_max_tw_buckets,  		.maxlen		= sizeof(int),  		.mode		= 0644,  		.proc_handler	= proc_dointvec  	},  	{ +		.procname	= "icmp_echo_ignore_all", +		.data		= &init_net.ipv4.sysctl_icmp_echo_ignore_all, +		.maxlen		= sizeof(u8), +		.mode		= 0644, +		.proc_handler	= proc_dou8vec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_ONE +	}, +	{ +		.procname	= "icmp_echo_enable_probe", +		.data		= &init_net.ipv4.sysctl_icmp_echo_enable_probe, +		.maxlen		= sizeof(u8), +		.mode		= 0644, +		.proc_handler	= proc_dou8vec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_ONE +	}, +	{  		.procname	= "icmp_echo_ignore_broadcasts",  		.data		= &init_net.ipv4.sysctl_icmp_echo_ignore_broadcasts, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_ONE  	},  	{  		.procname	= "icmp_ignore_bogus_error_responses",  		.data		= &init_net.ipv4.sysctl_icmp_ignore_bogus_error_responses, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_ONE  	},  	{  		.procname	= "icmp_errors_use_inbound_ifaddr",  		.data		= &init_net.ipv4.sysctl_icmp_errors_use_inbound_ifaddr, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_ONE  	},  	{  		.procname	= "icmp_ratelimit", @@ -673,9 +631,9 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "raw_l3mdev_accept",  		.data		= &init_net.ipv4.sysctl_raw_l3mdev_accept, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= SYSCTL_ZERO,  		.extra2		= SYSCTL_ONE,  	}, @@ -683,51 +641,64 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_ecn",  		.data		= &init_net.ipv4.sysctl_tcp_ecn, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_TWO,  	},  	{  		.procname	= "tcp_ecn_fallback",  		.data		= &init_net.ipv4.sysctl_tcp_ecn_fallback, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_ONE,  	},  	{  		.procname	= "ip_dynaddr",  		.data		= &init_net.ipv4.sysctl_ip_dynaddr, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "ip_early_demux",  		.data		= &init_net.ipv4.sysctl_ip_early_demux, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname       = "udp_early_demux",  		.data           = &init_net.ipv4.sysctl_udp_early_demux, -		.maxlen         = sizeof(int), +		.maxlen         = sizeof(u8),  		.mode           = 0644, -		.proc_handler   = proc_udp_early_demux +		.proc_handler   = proc_dou8vec_minmax,  	},  	{  		.procname       = "tcp_early_demux",  		.data           = &init_net.ipv4.sysctl_tcp_early_demux, -		.maxlen         = sizeof(int), +		.maxlen         = sizeof(u8), +		.mode           = 0644, +		.proc_handler   = proc_dou8vec_minmax, +	}, +	{ +		.procname       = "nexthop_compat_mode", +		.data           = &init_net.ipv4.sysctl_nexthop_compat_mode, +		.maxlen         = sizeof(u8),  		.mode           = 0644, -		.proc_handler   = proc_tcp_early_demux +		.proc_handler   = proc_dou8vec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_ONE,  	},  	{  		.procname	= "ip_default_ttl",  		.data		= &init_net.ipv4.sysctl_ip_default_ttl, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= &ip_ttl_min,  		.extra2		= &ip_ttl_max,  	}, @@ -748,21 +719,21 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "ip_no_pmtu_disc",  		.data		= &init_net.ipv4.sysctl_ip_no_pmtu_disc, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "ip_forward_use_pmtu",  		.data		= &init_net.ipv4.sysctl_ip_fwd_use_pmtu, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec, +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "ip_forward_update_priority",  		.data		= &init_net.ipv4.sysctl_ip_fwd_update_priority, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644,  		.proc_handler   = ipv4_fwd_update_priority,  		.extra1		= SYSCTL_ZERO, @@ -771,31 +742,40 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "ip_nonlocal_bind",  		.data		= &init_net.ipv4.sysctl_ip_nonlocal_bind, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax, +	}, +	{ +		.procname	= "ip_autobind_reuse", +		.data		= &init_net.ipv4.sysctl_ip_autobind_reuse, +		.maxlen		= sizeof(u8), +		.mode		= 0644, +		.proc_handler	= proc_dou8vec_minmax, +		.extra1         = SYSCTL_ZERO, +		.extra2         = SYSCTL_ONE,  	},  	{  		.procname	= "fwmark_reflect",  		.data		= &init_net.ipv4.sysctl_fwmark_reflect, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec, +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_fwmark_accept",  		.data		= &init_net.ipv4.sysctl_tcp_fwmark_accept, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec, +		.proc_handler	= proc_dou8vec_minmax,  	},  #ifdef CONFIG_NET_L3_MASTER_DEV  	{  		.procname	= "tcp_l3mdev_accept",  		.data		= &init_net.ipv4.sysctl_tcp_l3mdev_accept, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= SYSCTL_ZERO,  		.extra2		= SYSCTL_ONE,  	}, @@ -803,9 +783,9 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_mtu_probing",  		.data		= &init_net.ipv4.sysctl_tcp_mtu_probing, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec, +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_base_mss", @@ -850,9 +830,9 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "igmp_link_local_mcast_reports",  		.data		= &init_net.ipv4.sysctl_igmp_llm_reports, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "igmp_max_memberships", @@ -886,6 +866,18 @@ static struct ctl_table ipv4_net_table[] = {  		.proc_handler	= proc_tcp_congestion_control,  	},  	{ +		.procname	= "tcp_available_congestion_control", +		.maxlen		= TCP_CA_BUF_MAX, +		.mode		= 0444, +		.proc_handler   = proc_tcp_available_congestion_control, +	}, +	{ +		.procname	= "tcp_allowed_congestion_control", +		.maxlen		= TCP_CA_BUF_MAX, +		.mode		= 0644, +		.proc_handler   = proc_allowed_congestion_control, +	}, +	{  		.procname	= "tcp_keepalive_time",  		.data		= &init_net.ipv4.sysctl_tcp_keepalive_time,  		.maxlen		= sizeof(int), @@ -895,9 +887,9 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_keepalive_probes",  		.data		= &init_net.ipv4.sysctl_tcp_keepalive_probes, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_keepalive_intvl", @@ -909,29 +901,38 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_syn_retries",  		.data		= &init_net.ipv4.sysctl_tcp_syn_retries, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= &tcp_syn_retries_min,  		.extra2		= &tcp_syn_retries_max  	},  	{  		.procname	= "tcp_synack_retries",  		.data		= &init_net.ipv4.sysctl_tcp_synack_retries, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  #ifdef CONFIG_SYN_COOKIES  	{  		.procname	= "tcp_syncookies",  		.data		= &init_net.ipv4.sysctl_tcp_syncookies, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  #endif  	{ +		.procname	= "tcp_migrate_req", +		.data		= &init_net.ipv4.sysctl_tcp_migrate_req, +		.maxlen		= sizeof(u8), +		.mode		= 0644, +		.proc_handler	= proc_dou8vec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_ONE +	}, +	{  		.procname	= "tcp_reordering",  		.data		= &init_net.ipv4.sysctl_tcp_reordering,  		.maxlen		= sizeof(int), @@ -941,24 +942,24 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_retries1",  		.data		= &init_net.ipv4.sysctl_tcp_retries1, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra2		= &tcp_retr1_max  	},  	{  		.procname	= "tcp_retries2",  		.data		= &init_net.ipv4.sysctl_tcp_retries2, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_orphan_retries",  		.data		= &init_net.ipv4.sysctl_tcp_orphan_retries, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_fin_timeout", @@ -977,18 +978,11 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_tw_reuse",  		.data		= &init_net.ipv4.sysctl_tcp_tw_reuse, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= SYSCTL_ZERO, -		.extra2		= &two, -	}, -	{ -		.procname	= "tcp_max_tw_buckets", -		.data		= &init_net.ipv4.tcp_death_row.sysctl_max_tw_buckets, -		.maxlen		= sizeof(int), -		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.extra2		= SYSCTL_TWO,  	},  	{  		.procname	= "tcp_max_syn_backlog", @@ -1028,20 +1022,29 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "fib_multipath_use_neigh",  		.data		= &init_net.ipv4.sysctl_fib_multipath_use_neigh, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= SYSCTL_ZERO,  		.extra2		= SYSCTL_ONE,  	},  	{  		.procname	= "fib_multipath_hash_policy",  		.data		= &init_net.ipv4.sysctl_fib_multipath_hash_policy, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644,  		.proc_handler	= proc_fib_multipath_hash_policy,  		.extra1		= SYSCTL_ZERO, -		.extra2		= &two, +		.extra2		= SYSCTL_THREE, +	}, +	{ +		.procname	= "fib_multipath_hash_fields", +		.data		= &init_net.ipv4.sysctl_fib_multipath_hash_fields, +		.maxlen		= sizeof(u32), +		.mode		= 0644, +		.proc_handler	= proc_fib_multipath_hash_fields, +		.extra1		= SYSCTL_ONE, +		.extra2		= &fib_multipath_hash_fields_all_mask,  	},  #endif  	{ @@ -1055,9 +1058,9 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "udp_l3mdev_accept",  		.data		= &init_net.ipv4.sysctl_udp_l3mdev_accept, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= SYSCTL_ZERO,  		.extra2		= SYSCTL_ONE,  	}, @@ -1065,88 +1068,88 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_sack",  		.data		= &init_net.ipv4.sysctl_tcp_sack, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_window_scaling",  		.data		= &init_net.ipv4.sysctl_tcp_window_scaling, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_timestamps",  		.data		= &init_net.ipv4.sysctl_tcp_timestamps, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_early_retrans",  		.data		= &init_net.ipv4.sysctl_tcp_early_retrans, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= SYSCTL_ZERO, -		.extra2		= &four, +		.extra2		= SYSCTL_FOUR,  	},  	{  		.procname	= "tcp_recovery",  		.data		= &init_net.ipv4.sysctl_tcp_recovery, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec, +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname       = "tcp_thin_linear_timeouts",  		.data           = &init_net.ipv4.sysctl_tcp_thin_linear_timeouts, -		.maxlen         = sizeof(int), +		.maxlen         = sizeof(u8),  		.mode           = 0644, -		.proc_handler   = proc_dointvec +		.proc_handler   = proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_slow_start_after_idle",  		.data		= &init_net.ipv4.sysctl_tcp_slow_start_after_idle, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_retrans_collapse",  		.data		= &init_net.ipv4.sysctl_tcp_retrans_collapse, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_stdurg",  		.data		= &init_net.ipv4.sysctl_tcp_stdurg, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_rfc1337",  		.data		= &init_net.ipv4.sysctl_tcp_rfc1337, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_abort_on_overflow",  		.data		= &init_net.ipv4.sysctl_tcp_abort_on_overflow, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_fack",  		.data		= &init_net.ipv4.sysctl_tcp_fack, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_max_reordering", @@ -1158,16 +1161,16 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_dsack",  		.data		= &init_net.ipv4.sysctl_tcp_dsack, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_app_win",  		.data		= &init_net.ipv4.sysctl_tcp_app_win, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_adv_win_scale", @@ -1181,46 +1184,46 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_frto",  		.data		= &init_net.ipv4.sysctl_tcp_frto, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_no_metrics_save",  		.data		= &init_net.ipv4.sysctl_tcp_nometrics_save, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec, +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_no_ssthresh_metrics_save",  		.data		= &init_net.ipv4.sysctl_tcp_no_ssthresh_metrics_save, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= SYSCTL_ZERO,  		.extra2		= SYSCTL_ONE,  	},  	{  		.procname	= "tcp_moderate_rcvbuf",  		.data		= &init_net.ipv4.sysctl_tcp_moderate_rcvbuf, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec, +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_tso_win_divisor",  		.data		= &init_net.ipv4.sysctl_tcp_tso_win_divisor, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec, +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_workaround_signed_windows",  		.data		= &init_net.ipv4.sysctl_tcp_workaround_signed_windows, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_limit_output_bytes", @@ -1239,11 +1242,17 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_min_tso_segs",  		.data		= &init_net.ipv4.sysctl_tcp_min_tso_segs, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= SYSCTL_ONE, -		.extra2		= &gso_max_segs, +	}, +	{ +		.procname	= "tcp_tso_rtt_log", +		.data		= &init_net.ipv4.sysctl_tcp_tso_rtt_log, +		.maxlen		= sizeof(u8), +		.mode		= 0644, +		.proc_handler	= proc_dou8vec_minmax,  	},  	{  		.procname	= "tcp_min_rtt_wlen", @@ -1257,9 +1266,9 @@ static struct ctl_table ipv4_net_table[] = {  	{  		.procname	= "tcp_autocorking",  		.data		= &init_net.ipv4.sysctl_tcp_autocorking, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= SYSCTL_ZERO,  		.extra2		= SYSCTL_ONE,  	}, @@ -1277,7 +1286,7 @@ static struct ctl_table ipv4_net_table[] = {  		.mode		= 0644,  		.proc_handler	= proc_dointvec_minmax,  		.extra1		= SYSCTL_ZERO, -		.extra2		= &thousand, +		.extra2		= SYSCTL_ONE_THOUSAND,  	},  	{  		.procname	= "tcp_pacing_ca_ratio", @@ -1286,7 +1295,7 @@ static struct ctl_table ipv4_net_table[] = {  		.mode		= 0644,  		.proc_handler	= proc_dointvec_minmax,  		.extra1		= SYSCTL_ZERO, -		.extra2		= &thousand, +		.extra2		= SYSCTL_ONE_THOUSAND,  	},  	{  		.procname	= "tcp_wmem", @@ -1312,13 +1321,43 @@ static struct ctl_table ipv4_net_table[] = {  		.proc_handler	= proc_doulongvec_minmax,  	},  	{ +		.procname	= "tcp_comp_sack_slack_ns", +		.data		= &init_net.ipv4.sysctl_tcp_comp_sack_slack_ns, +		.maxlen		= sizeof(unsigned long), +		.mode		= 0644, +		.proc_handler	= proc_doulongvec_minmax, +	}, +	{  		.procname	= "tcp_comp_sack_nr",  		.data		= &init_net.ipv4.sysctl_tcp_comp_sack_nr, -		.maxlen		= sizeof(int), +		.maxlen		= sizeof(u8),  		.mode		= 0644, -		.proc_handler	= proc_dointvec_minmax, +		.proc_handler	= proc_dou8vec_minmax,  		.extra1		= SYSCTL_ZERO, -		.extra2		= &comp_sack_nr_max, +	}, +	{ +		.procname       = "tcp_reflect_tos", +		.data           = &init_net.ipv4.sysctl_tcp_reflect_tos, +		.maxlen         = sizeof(u8), +		.mode           = 0644, +		.proc_handler   = proc_dou8vec_minmax, +		.extra1         = SYSCTL_ZERO, +		.extra2         = SYSCTL_ONE, +	}, +	{ +		.procname	= "tcp_ehash_entries", +		.data		= &init_net.ipv4.sysctl_tcp_child_ehash_entries, +		.mode		= 0444, +		.proc_handler	= proc_tcp_ehash_entries, +	}, +	{ +		.procname	= "tcp_child_ehash_entries", +		.data		= &init_net.ipv4.sysctl_tcp_child_ehash_entries, +		.maxlen		= sizeof(unsigned int), +		.mode		= 0644, +		.proc_handler	= proc_douintvec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= &tcp_child_ehash_entries_max,  	},  	{  		.procname	= "udp_rmem_min", @@ -1336,6 +1375,15 @@ static struct ctl_table ipv4_net_table[] = {  		.proc_handler	= proc_dointvec_minmax,  		.extra1		= SYSCTL_ONE  	}, +	{ +		.procname	= "fib_notify_on_flag_change", +		.data		= &init_net.ipv4.sysctl_fib_notify_on_flag_change, +		.maxlen		= sizeof(u8), +		.mode		= 0644, +		.proc_handler	= proc_dou8vec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_TWO, +	},  	{ }  }; @@ -1351,9 +1399,19 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)  		if (!table)  			goto err_alloc; -		/* Update the variables to point into the current struct net */ -		for (i = 0; i < ARRAY_SIZE(ipv4_net_table) - 1; i++) -			table[i].data += (void *)net - (void *)&init_net; +		for (i = 0; i < ARRAY_SIZE(ipv4_net_table) - 1; i++) { +			if (table[i].data) { +				/* Update the variables to point into +				 * the current struct net +				 */ +				table[i].data += (void *)net - (void *)&init_net; +			} else { +				/* Entries without data pointer are global; +				 * Make them read-only in non-init_net ns +				 */ +				table[i].mode &= ~0222; +			} +		}  	}  	net->ipv4.ipv4_hdr = register_net_sysctl(net, "net/ipv4", table);  | 
