diff options
| author | Steve French <sfrench@us.ibm.com> | 2006-03-30 22:35:56 -0500 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2006-03-30 22:35:56 -0500 |
| commit | d62e54abca1146981fc9f98f85ff398a113a22c2 (patch) | |
| tree | 870420dbc4c65e716dcef8a802aafdc0ef97a8b4 /net/ipv4/tcp.c | |
| parent | fd4a0b92db6a57cba8d03efbe1cebf91f9124ce0 (diff) | |
| parent | ce362c009250340358a7221f3cdb7954cbf19c01 (diff) | |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
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", |
