diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 00aa80e93243..4b0272c92d66 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1687,18 +1687,14 @@ int tcp_disconnect(struct sock *sk, int flags) | |||
1687 | /* | 1687 | /* |
1688 | * Socket option code for TCP. | 1688 | * Socket option code for TCP. |
1689 | */ | 1689 | */ |
1690 | int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, | 1690 | static int do_tcp_setsockopt(struct sock *sk, int level, |
1691 | int optlen) | 1691 | int optname, char __user *optval, int optlen) |
1692 | { | 1692 | { |
1693 | struct tcp_sock *tp = tcp_sk(sk); | 1693 | struct tcp_sock *tp = tcp_sk(sk); |
1694 | struct inet_connection_sock *icsk = inet_csk(sk); | 1694 | struct inet_connection_sock *icsk = inet_csk(sk); |
1695 | int val; | 1695 | int val; |
1696 | int err = 0; | 1696 | int err = 0; |
1697 | 1697 | ||
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 */ | 1698 | /* This is a string value all the others are int's */ |
1703 | if (optname == TCP_CONGESTION) { | 1699 | if (optname == TCP_CONGESTION) { |
1704 | char name[TCP_CA_NAME_MAX]; | 1700 | char name[TCP_CA_NAME_MAX]; |
@@ -1871,6 +1867,30 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, | |||
1871 | return err; | 1867 | return err; |
1872 | } | 1868 | } |
1873 | 1869 | ||
1870 | int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, | ||
1871 | int optlen) | ||
1872 | { | ||
1873 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
1874 | |||
1875 | if (level != SOL_TCP) | ||
1876 | return icsk->icsk_af_ops->setsockopt(sk, level, optname, | ||
1877 | optval, optlen); | ||
1878 | return do_tcp_setsockopt(sk, level, optname, optval, optlen); | ||
1879 | } | ||
1880 | |||
1881 | #ifdef CONFIG_COMPAT | ||
1882 | int compat_tcp_setsockopt(struct sock *sk, int level, int optname, | ||
1883 | char __user *optval, int optlen) | ||
1884 | { | ||
1885 | if (level != SOL_TCP) | ||
1886 | return inet_csk_compat_setsockopt(sk, level, optname, | ||
1887 | optval, optlen); | ||
1888 | return do_tcp_setsockopt(sk, level, optname, optval, optlen); | ||
1889 | } | ||
1890 | |||
1891 | EXPORT_SYMBOL(compat_tcp_setsockopt); | ||
1892 | #endif | ||
1893 | |||
1874 | /* Return information about state of tcp endpoint in API format. */ | 1894 | /* Return information about state of tcp endpoint in API format. */ |
1875 | void tcp_get_info(struct sock *sk, struct tcp_info *info) | 1895 | void tcp_get_info(struct sock *sk, struct tcp_info *info) |
1876 | { | 1896 | { |
@@ -1931,17 +1951,13 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) | |||
1931 | 1951 | ||
1932 | EXPORT_SYMBOL_GPL(tcp_get_info); | 1952 | EXPORT_SYMBOL_GPL(tcp_get_info); |
1933 | 1953 | ||
1934 | int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, | 1954 | static int do_tcp_getsockopt(struct sock *sk, int level, |
1935 | int __user *optlen) | 1955 | int optname, char __user *optval, int __user *optlen) |
1936 | { | 1956 | { |
1937 | struct inet_connection_sock *icsk = inet_csk(sk); | 1957 | struct inet_connection_sock *icsk = inet_csk(sk); |
1938 | struct tcp_sock *tp = tcp_sk(sk); | 1958 | struct tcp_sock *tp = tcp_sk(sk); |
1939 | int val, len; | 1959 | int val, len; |
1940 | 1960 | ||
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)) | 1961 | if (get_user(len, optlen)) |
1946 | return -EFAULT; | 1962 | return -EFAULT; |
1947 | 1963 | ||
@@ -2025,6 +2041,29 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, | |||
2025 | return 0; | 2041 | return 0; |
2026 | } | 2042 | } |
2027 | 2043 | ||
2044 | int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, | ||
2045 | int __user *optlen) | ||
2046 | { | ||
2047 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
2048 | |||
2049 | if (level != SOL_TCP) | ||
2050 | return icsk->icsk_af_ops->getsockopt(sk, level, optname, | ||
2051 | optval, optlen); | ||
2052 | return do_tcp_getsockopt(sk, level, optname, optval, optlen); | ||
2053 | } | ||
2054 | |||
2055 | #ifdef CONFIG_COMPAT | ||
2056 | int compat_tcp_getsockopt(struct sock *sk, int level, int optname, | ||
2057 | char __user *optval, int __user *optlen) | ||
2058 | { | ||
2059 | if (level != SOL_TCP) | ||
2060 | return inet_csk_compat_getsockopt(sk, level, optname, | ||
2061 | optval, optlen); | ||
2062 | return do_tcp_getsockopt(sk, level, optname, optval, optlen); | ||
2063 | } | ||
2064 | |||
2065 | EXPORT_SYMBOL(compat_tcp_getsockopt); | ||
2066 | #endif | ||
2028 | 2067 | ||
2029 | extern void __skb_cb_too_small_for_tcp(int, int); | 2068 | extern void __skb_cb_too_small_for_tcp(int, int); |
2030 | extern struct tcp_congestion_ops tcp_reno; | 2069 | extern struct tcp_congestion_ops tcp_reno; |