diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 91 |
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 | ||
276 | EXPORT_SYMBOL_GPL(tcp_orphan_count); | 277 | EXPORT_SYMBOL_GPL(tcp_orphan_count); |
277 | 278 | ||
278 | int sysctl_tcp_mem[3]; | 279 | int sysctl_tcp_mem[3] __read_mostly; |
279 | int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; | 280 | int sysctl_tcp_wmem[3] __read_mostly; |
280 | int sysctl_tcp_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; | 281 | int sysctl_tcp_rmem[3] __read_mostly; |
281 | 282 | ||
282 | EXPORT_SYMBOL(sysctl_tcp_mem); | 283 | EXPORT_SYMBOL(sysctl_tcp_mem); |
283 | EXPORT_SYMBOL(sysctl_tcp_rmem); | 284 | EXPORT_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 | */ |
1690 | int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, | 1691 | static 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 | ||
1871 | int 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 | ||
1883 | int 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 | |||
1892 | EXPORT_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. */ |
1875 | void tcp_get_info(struct sock *sk, struct tcp_info *info) | 1896 | void 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 | ||
1932 | EXPORT_SYMBOL_GPL(tcp_get_info); | 1953 | EXPORT_SYMBOL_GPL(tcp_get_info); |
1933 | 1954 | ||
1934 | int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, | 1955 | static 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 | ||
2045 | int 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 | ||
2057 | int 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 | |||
2066 | EXPORT_SYMBOL(compat_tcp_getsockopt); | ||
2067 | #endif | ||
2028 | 2068 | ||
2029 | extern void __skb_cb_too_small_for_tcp(int, int); | 2069 | extern void __skb_cb_too_small_for_tcp(int, int); |
2030 | extern struct tcp_congestion_ops tcp_reno; | 2070 | extern struct tcp_congestion_ops tcp_reno; |
@@ -2042,7 +2082,8 @@ __setup("thash_entries=", set_thash_entries); | |||
2042 | void __init tcp_init(void) | 2082 | void __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", |