diff options
-rw-r--r-- | Documentation/networking/ip-sysctl.txt | 6 | ||||
-rw-r--r-- | include/linux/sysctl.h | 1 | ||||
-rw-r--r-- | include/net/tcp.h | 4 | ||||
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 24 | ||||
-rw-r--r-- | net/ipv4/tcp_cong.c | 16 |
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 | ||
354 | tcp_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 | |||
354 | tcp_congestion_control - STRING | 359 | tcp_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 | ||
359 | somaxconn - INTEGER | 365 | somaxconn - 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 | ||
431 | enum { | 432 | enum { |
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 | |||
623 | struct tcp_congestion_ops { | 626 | struct 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); | |||
659 | extern void tcp_cleanup_congestion_control(struct sock *sk); | 662 | extern void tcp_cleanup_congestion_control(struct sock *sk); |
660 | extern int tcp_set_default_congestion_control(const char *name); | 663 | extern int tcp_set_default_congestion_control(const char *name); |
661 | extern void tcp_get_default_congestion_control(char *name); | 664 | extern void tcp_get_default_congestion_control(char *name); |
665 | extern void tcp_get_available_congestion_control(char *buf, size_t len); | ||
662 | extern int tcp_set_congestion_control(struct sock *sk, const char *name); | 666 | extern int tcp_set_congestion_control(struct sock *sk, const char *name); |
663 | extern void tcp_slow_start(struct tcp_sock *tp); | 667 | extern 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 | ||
132 | static 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 | |||
132 | ctl_table ipv4_table[] = { | 149 | ctl_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) | |||
139 | late_initcall(tcp_congestion_default); | 139 | late_initcall(tcp_congestion_default); |
140 | 140 | ||
141 | 141 | ||
142 | /* Build string with list of available congestion control values */ | ||
143 | void 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 */ |
143 | void tcp_get_default_congestion_control(char *name) | 159 | void tcp_get_default_congestion_control(char *name) |
144 | { | 160 | { |