diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-11-09 19:32:06 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:21:48 -0500 |
commit | 3ff825b28d3345ef381eceae22bf9d92231f23dc (patch) | |
tree | c3ca6ec1888ff912e0434f6621ecb2e46e8826f3 /net | |
parent | b68dbcab1dc70938fa5516d0ee82c0bf94e9a768 (diff) |
[TCP]: Add tcp_available_congestion_control sysctl.
Create /proc/sys/net/ipv4/tcp_available_congestion_control
that reflects currently available TCP choices.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 24 | ||||
-rw-r--r-- | net/ipv4/tcp_cong.c | 16 |
2 files changed, 40 insertions, 0 deletions
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 | { |