aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c91
1 files changed, 68 insertions, 23 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 00aa80e93243..87f68e787d0c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -257,6 +257,7 @@
257#include <linux/fs.h> 257#include <linux/fs.h>
258#include <linux/random.h> 258#include <linux/random.h>
259#include <linux/bootmem.h> 259#include <linux/bootmem.h>
260#include <linux/cache.h>
260 261
261#include <net/icmp.h> 262#include <net/icmp.h>
262#include <net/tcp.h> 263#include <net/tcp.h>
@@ -275,9 +276,9 @@ atomic_t tcp_orphan_count = ATOMIC_INIT(0);
275 276
276EXPORT_SYMBOL_GPL(tcp_orphan_count); 277EXPORT_SYMBOL_GPL(tcp_orphan_count);
277 278
278int sysctl_tcp_mem[3]; 279int sysctl_tcp_mem[3] __read_mostly;
279int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; 280int sysctl_tcp_wmem[3] __read_mostly;
280int sysctl_tcp_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; 281int sysctl_tcp_rmem[3] __read_mostly;
281 282
282EXPORT_SYMBOL(sysctl_tcp_mem); 283EXPORT_SYMBOL(sysctl_tcp_mem);
283EXPORT_SYMBOL(sysctl_tcp_rmem); 284EXPORT_SYMBOL(sysctl_tcp_rmem);
@@ -365,7 +366,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
365 if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) 366 if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE)
366 mask |= POLLHUP; 367 mask |= POLLHUP;
367 if (sk->sk_shutdown & RCV_SHUTDOWN) 368 if (sk->sk_shutdown & RCV_SHUTDOWN)
368 mask |= POLLIN | POLLRDNORM; 369 mask |= POLLIN | POLLRDNORM | POLLRDHUP;
369 370
370 /* Connected? */ 371 /* Connected? */
371 if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) { 372 if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) {
@@ -1687,18 +1688,14 @@ int tcp_disconnect(struct sock *sk, int flags)
1687/* 1688/*
1688 * Socket option code for TCP. 1689 * Socket option code for TCP.
1689 */ 1690 */
1690int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, 1691static int do_tcp_setsockopt(struct sock *sk, int level,
1691 int optlen) 1692 int optname, char __user *optval, int optlen)
1692{ 1693{
1693 struct tcp_sock *tp = tcp_sk(sk); 1694 struct tcp_sock *tp = tcp_sk(sk);
1694 struct inet_connection_sock *icsk = inet_csk(sk); 1695 struct inet_connection_sock *icsk = inet_csk(sk);
1695 int val; 1696 int val;
1696 int err = 0; 1697 int err = 0;
1697 1698
1698 if (level != SOL_TCP)
1699 return icsk->icsk_af_ops->setsockopt(sk, level, optname,
1700 optval, optlen);
1701
1702 /* This is a string value all the others are int's */ 1699 /* This is a string value all the others are int's */
1703 if (optname == TCP_CONGESTION) { 1700 if (optname == TCP_CONGESTION) {
1704 char name[TCP_CA_NAME_MAX]; 1701 char name[TCP_CA_NAME_MAX];
@@ -1871,6 +1868,30 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
1871 return err; 1868 return err;
1872} 1869}
1873 1870
1871int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
1872 int optlen)
1873{
1874 struct inet_connection_sock *icsk = inet_csk(sk);
1875
1876 if (level != SOL_TCP)
1877 return icsk->icsk_af_ops->setsockopt(sk, level, optname,
1878 optval, optlen);
1879 return do_tcp_setsockopt(sk, level, optname, optval, optlen);
1880}
1881
1882#ifdef CONFIG_COMPAT
1883int compat_tcp_setsockopt(struct sock *sk, int level, int optname,
1884 char __user *optval, int optlen)
1885{
1886 if (level != SOL_TCP)
1887 return inet_csk_compat_setsockopt(sk, level, optname,
1888 optval, optlen);
1889 return do_tcp_setsockopt(sk, level, optname, optval, optlen);
1890}
1891
1892EXPORT_SYMBOL(compat_tcp_setsockopt);
1893#endif
1894
1874/* Return information about state of tcp endpoint in API format. */ 1895/* Return information about state of tcp endpoint in API format. */
1875void tcp_get_info(struct sock *sk, struct tcp_info *info) 1896void tcp_get_info(struct sock *sk, struct tcp_info *info)
1876{ 1897{
@@ -1931,17 +1952,13 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
1931 1952
1932EXPORT_SYMBOL_GPL(tcp_get_info); 1953EXPORT_SYMBOL_GPL(tcp_get_info);
1933 1954
1934int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, 1955static int do_tcp_getsockopt(struct sock *sk, int level,
1935 int __user *optlen) 1956 int optname, char __user *optval, int __user *optlen)
1936{ 1957{
1937 struct inet_connection_sock *icsk = inet_csk(sk); 1958 struct inet_connection_sock *icsk = inet_csk(sk);
1938 struct tcp_sock *tp = tcp_sk(sk); 1959 struct tcp_sock *tp = tcp_sk(sk);
1939 int val, len; 1960 int val, len;
1940 1961
1941 if (level != SOL_TCP)
1942 return icsk->icsk_af_ops->getsockopt(sk, level, optname,
1943 optval, optlen);
1944
1945 if (get_user(len, optlen)) 1962 if (get_user(len, optlen))
1946 return -EFAULT; 1963 return -EFAULT;
1947 1964
@@ -2025,6 +2042,29 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
2025 return 0; 2042 return 0;
2026} 2043}
2027 2044
2045int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
2046 int __user *optlen)
2047{
2048 struct inet_connection_sock *icsk = inet_csk(sk);
2049
2050 if (level != SOL_TCP)
2051 return icsk->icsk_af_ops->getsockopt(sk, level, optname,
2052 optval, optlen);
2053 return do_tcp_getsockopt(sk, level, optname, optval, optlen);
2054}
2055
2056#ifdef CONFIG_COMPAT
2057int compat_tcp_getsockopt(struct sock *sk, int level, int optname,
2058 char __user *optval, int __user *optlen)
2059{
2060 if (level != SOL_TCP)
2061 return inet_csk_compat_getsockopt(sk, level, optname,
2062 optval, optlen);
2063 return do_tcp_getsockopt(sk, level, optname, optval, optlen);
2064}
2065
2066EXPORT_SYMBOL(compat_tcp_getsockopt);
2067#endif
2028 2068
2029extern void __skb_cb_too_small_for_tcp(int, int); 2069extern void __skb_cb_too_small_for_tcp(int, int);
2030extern struct tcp_congestion_ops tcp_reno; 2070extern struct tcp_congestion_ops tcp_reno;
@@ -2042,7 +2082,8 @@ __setup("thash_entries=", set_thash_entries);
2042void __init tcp_init(void) 2082void __init tcp_init(void)
2043{ 2083{
2044 struct sk_buff *skb = NULL; 2084 struct sk_buff *skb = NULL;
2045 int order, i; 2085 unsigned long limit;
2086 int order, i, max_share;
2046 2087
2047 if (sizeof(struct tcp_skb_cb) > sizeof(skb->cb)) 2088 if (sizeof(struct tcp_skb_cb) > sizeof(skb->cb))
2048 __skb_cb_too_small_for_tcp(sizeof(struct tcp_skb_cb), 2089 __skb_cb_too_small_for_tcp(sizeof(struct tcp_skb_cb),
@@ -2116,12 +2157,16 @@ void __init tcp_init(void)
2116 sysctl_tcp_mem[1] = 1024 << order; 2157 sysctl_tcp_mem[1] = 1024 << order;
2117 sysctl_tcp_mem[2] = 1536 << order; 2158 sysctl_tcp_mem[2] = 1536 << order;
2118 2159
2119 if (order < 3) { 2160 limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7);
2120 sysctl_tcp_wmem[2] = 64 * 1024; 2161 max_share = min(4UL*1024*1024, limit);
2121 sysctl_tcp_rmem[0] = PAGE_SIZE; 2162
2122 sysctl_tcp_rmem[1] = 43689; 2163 sysctl_tcp_wmem[0] = SK_STREAM_MEM_QUANTUM;
2123 sysctl_tcp_rmem[2] = 2 * 43689; 2164 sysctl_tcp_wmem[1] = 16*1024;
2124 } 2165 sysctl_tcp_wmem[2] = max(64*1024, max_share);
2166
2167 sysctl_tcp_rmem[0] = SK_STREAM_MEM_QUANTUM;
2168 sysctl_tcp_rmem[1] = 87380;
2169 sysctl_tcp_rmem[2] = max(87380, max_share);
2125 2170
2126 printk(KERN_INFO "TCP: Hash tables configured " 2171 printk(KERN_INFO "TCP: Hash tables configured "
2127 "(established %d bind %d)\n", 2172 "(established %d bind %d)\n",