From: Wei Yongjun weiyongjun1@huawei.com
hulk inclusion category: feature bugzilla: NA CVE: NA
-------------------------------------------------
Add sysctl interface for enable/disable tcp compression by ports.
Example:
$ echo 4000 > /proc/sys/net/ipv4/tcp_compression_ports will enable port 4000 for tcp compression
$ echo 4000,5000 > /proc/sys/net/ipv4/tcp_compression_ports will enable both port 4000 and 5000 for tcp compression
$ echo > /proc/sys/net/ipv4/tcp_compression_ports will disable tcp compression.
Signed-off-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Wang Yufen wangyufen@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- include/net/tcp.h | 3 +++ net/ipv4/sysctl_net_ipv4.c | 33 +++++++++++++++++++++++++++++++++ net/ipv4/tcp_comp.c | 4 ++++ 3 files changed, 40 insertions(+)
diff --git a/include/net/tcp.h b/include/net/tcp.h index 110ca98aa3e97..d3961e3e368e0 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -2212,6 +2212,9 @@ void clean_acked_data_disable(struct inet_connection_sock *icsk);
#if IS_ENABLED(CONFIG_TCP_COMP) extern struct static_key_false tcp_have_comp; + +extern unsigned long *sysctl_tcp_compression_ports; + bool tcp_syn_comp_enabled(const struct tcp_sock *tp); void tcp_init_compression(struct sock *sk); void tcp_cleanup_compression(struct sock *sk); diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index fdd166ee80f34..8317a2dbcbe90 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -438,6 +438,30 @@ static int proc_fib_multipath_hash_policy(struct ctl_table *table, int write, } #endif
+#if IS_ENABLED(CONFIG_TCP_COMP) +static int proc_tcp_compression_ports(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + unsigned long *bitmap = *(unsigned long **)table->data; + unsigned long bitmap_len = table->maxlen; + int ret; + + ret = proc_do_large_bitmap(table, write, buffer, lenp, ppos); + if (write && ret == 0) { + if (bitmap_empty(bitmap, bitmap_len)) { + if (static_key_enabled(&tcp_have_comp)) + static_branch_disable(&tcp_have_comp); + } else { + if (!static_key_enabled(&tcp_have_comp)) + static_branch_enable(&tcp_have_comp); + } + } + + return ret; +} +#endif + static struct ctl_table ipv4_table[] = { { .procname = "tcp_max_orphans", @@ -560,6 +584,15 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_doulongvec_minmax, }, +#if IS_ENABLED(CONFIG_TCP_COMP) + { + .procname = "tcp_compression_ports", + .data = &sysctl_tcp_compression_ports, + .maxlen = 65536, + .mode = 0644, + .proc_handler = proc_tcp_compression_ports, + }, +#endif { } };
diff --git a/net/ipv4/tcp_comp.c b/net/ipv4/tcp_comp.c index 067d48b724296..3493255d34dfd 100644 --- a/net/ipv4/tcp_comp.c +++ b/net/ipv4/tcp_comp.c @@ -7,6 +7,10 @@
#include <net/tcp.h>
+static unsigned long tcp_compression_ports[65536 / 8]; + +unsigned long *sysctl_tcp_compression_ports = tcp_compression_ports; + bool tcp_syn_comp_enabled(const struct tcp_sock *tp) { return true;