aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/ip-sysctl.txt6
-rw-r--r--include/linux/sysctl.h1
-rw-r--r--include/net/tcp.h4
-rw-r--r--net/ipv4/sysctl_net_ipv4.c24
-rw-r--r--net/ipv4/tcp_cong.c16
5 files changed, 51 insertions, 0 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index fd3c0c012351..db4280856588 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -351,10 +351,16 @@ tcp_frto - BOOLEAN
351 where packet loss is typically due to random radio interference 351 where packet loss is typically due to random radio interference
352 rather than intermediate router congestion. 352 rather than intermediate router congestion.
353 353
354tcp_available_congestion_control - STRING
355 Shows the available congestion control choices that are registered.
356 More congestion control algorithms may be available as modules,
357 but not loaded.
358
354tcp_congestion_control - STRING 359tcp_congestion_control - STRING
355 Set the congestion control algorithm to be used for new 360 Set the congestion control algorithm to be used for new
356 connections. The algorithm "reno" is always available, but 361 connections. The algorithm "reno" is always available, but
357 additional choices may be available based on kernel configuration. 362 additional choices may be available based on kernel configuration.
363 Default is set as part of kernel configuration.
358 364
359somaxconn - INTEGER 365somaxconn - INTEGER
360 Limit of socket listen() backlog, known in userspace as SOMAXCONN. 366 Limit of socket listen() backlog, known in userspace as SOMAXCONN.
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index d98562f1df76..28a48279654d 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -426,6 +426,7 @@ enum
426 NET_CIPSOV4_CACHE_BUCKET_SIZE=119, 426 NET_CIPSOV4_CACHE_BUCKET_SIZE=119,
427 NET_CIPSOV4_RBM_OPTFMT=120, 427 NET_CIPSOV4_RBM_OPTFMT=120,
428 NET_CIPSOV4_RBM_STRICTVALID=121, 428 NET_CIPSOV4_RBM_STRICTVALID=121,
429 NET_TCP_AVAIL_CONG_CONTROL=122,
429}; 430};
430 431
431enum { 432enum {
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 246916c2321e..6af4baf5b769 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -620,6 +620,9 @@ enum tcp_ca_event {
620 * Interface for adding new TCP congestion control handlers 620 * Interface for adding new TCP congestion control handlers
621 */ 621 */
622#define TCP_CA_NAME_MAX 16 622#define TCP_CA_NAME_MAX 16
623#define TCP_CA_MAX 128
624#define TCP_CA_BUF_MAX (TCP_CA_NAME_MAX*TCP_CA_MAX)
625
623struct tcp_congestion_ops { 626struct tcp_congestion_ops {
624 struct list_head list; 627 struct list_head list;
625 628
@@ -659,6 +662,7 @@ extern void tcp_init_congestion_control(struct sock *sk);
659extern void tcp_cleanup_congestion_control(struct sock *sk); 662extern void tcp_cleanup_congestion_control(struct sock *sk);
660extern int tcp_set_default_congestion_control(const char *name); 663extern int tcp_set_default_congestion_control(const char *name);
661extern void tcp_get_default_congestion_control(char *name); 664extern void tcp_get_default_congestion_control(char *name);
665extern void tcp_get_available_congestion_control(char *buf, size_t len);
662extern int tcp_set_congestion_control(struct sock *sk, const char *name); 666extern int tcp_set_congestion_control(struct sock *sk, const char *name);
663extern void tcp_slow_start(struct tcp_sock *tp); 667extern void tcp_slow_start(struct tcp_sock *tp);
664 668
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 15061b314411..2e770f45d829 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -129,6 +129,23 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name,
129 return ret; 129 return ret;
130} 130}
131 131
132static int proc_tcp_available_congestion_control(ctl_table *ctl,
133 int write, struct file * filp,
134 void __user *buffer, size_t *lenp,
135 loff_t *ppos)
136{
137 ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX, };
138 int ret;
139
140 tbl.data = kmalloc(tbl.maxlen, GFP_USER);
141 if (!tbl.data)
142 return -ENOMEM;
143 tcp_get_available_congestion_control(tbl.data, TCP_CA_BUF_MAX);
144 ret = proc_dostring(&tbl, write, filp, buffer, lenp, ppos);
145 kfree(tbl.data);
146 return ret;
147}
148
132ctl_table ipv4_table[] = { 149ctl_table ipv4_table[] = {
133 { 150 {
134 .ctl_name = NET_IPV4_TCP_TIMESTAMPS, 151 .ctl_name = NET_IPV4_TCP_TIMESTAMPS,
@@ -731,6 +748,13 @@ ctl_table ipv4_table[] = {
731 .proc_handler = &proc_dointvec, 748 .proc_handler = &proc_dointvec,
732 }, 749 },
733#endif /* CONFIG_NETLABEL */ 750#endif /* CONFIG_NETLABEL */
751 {
752 .ctl_name = NET_TCP_AVAIL_CONG_CONTROL,
753 .procname = "tcp_available_congestion_control",
754 .maxlen = TCP_CA_BUF_MAX,
755 .mode = 0444,
756 .proc_handler = &proc_tcp_available_congestion_control,
757 },
734 { .ctl_name = 0 } 758 { .ctl_name = 0 }
735}; 759};
736 760
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 1e2982f4acd4..d846d7b95e1f 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -139,6 +139,22 @@ static int __init tcp_congestion_default(void)
139late_initcall(tcp_congestion_default); 139late_initcall(tcp_congestion_default);
140 140
141 141
142/* Build string with list of available congestion control values */
143void tcp_get_available_congestion_control(char *buf, size_t maxlen)
144{
145 struct tcp_congestion_ops *ca;
146 size_t offs = 0;
147
148 rcu_read_lock();
149 list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
150 offs += snprintf(buf + offs, maxlen - offs,
151 "%s%s",
152 offs == 0 ? "" : " ", ca->name);
153
154 }
155 rcu_read_unlock();
156}
157
142/* Get current default congestion control */ 158/* Get current default congestion control */
143void tcp_get_default_congestion_control(char *name) 159void tcp_get_default_congestion_control(char *name)
144{ 160{