diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 77 |
1 files changed, 65 insertions, 12 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 00aa80e93243..31b0123a9699 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,35 @@ 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, | ||
1883 | int optname, char __user *optval, int optlen) | ||
1884 | { | ||
1885 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
1886 | |||
1887 | if (level != SOL_TCP) { | ||
1888 | if (icsk->icsk_af_ops->compat_setsockopt) | ||
1889 | return icsk->icsk_af_ops->compat_setsockopt(sk, | ||
1890 | level, optname, optval, optlen); | ||
1891 | else | ||
1892 | return icsk->icsk_af_ops->setsockopt(sk, | ||
1893 | level, optname, optval, optlen); | ||
1894 | } | ||
1895 | return do_tcp_setsockopt(sk, level, optname, optval, optlen); | ||
1896 | } | ||
1897 | #endif | ||
1898 | |||
1874 | /* Return information about state of tcp endpoint in API format. */ | 1899 | /* Return information about state of tcp endpoint in API format. */ |
1875 | void tcp_get_info(struct sock *sk, struct tcp_info *info) | 1900 | void tcp_get_info(struct sock *sk, struct tcp_info *info) |
1876 | { | 1901 | { |
@@ -1931,17 +1956,13 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) | |||
1931 | 1956 | ||
1932 | EXPORT_SYMBOL_GPL(tcp_get_info); | 1957 | EXPORT_SYMBOL_GPL(tcp_get_info); |
1933 | 1958 | ||
1934 | int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, | 1959 | static int do_tcp_getsockopt(struct sock *sk, int level, |
1935 | int __user *optlen) | 1960 | int optname, char __user *optval, int __user *optlen) |
1936 | { | 1961 | { |
1937 | struct inet_connection_sock *icsk = inet_csk(sk); | 1962 | struct inet_connection_sock *icsk = inet_csk(sk); |
1938 | struct tcp_sock *tp = tcp_sk(sk); | 1963 | struct tcp_sock *tp = tcp_sk(sk); |
1939 | int val, len; | 1964 | int val, len; |
1940 | 1965 | ||
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)) | 1966 | if (get_user(len, optlen)) |
1946 | return -EFAULT; | 1967 | return -EFAULT; |
1947 | 1968 | ||
@@ -2025,6 +2046,34 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, | |||
2025 | return 0; | 2046 | return 0; |
2026 | } | 2047 | } |
2027 | 2048 | ||
2049 | int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, | ||
2050 | int __user *optlen) | ||
2051 | { | ||
2052 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
2053 | |||
2054 | if (level != SOL_TCP) | ||
2055 | return icsk->icsk_af_ops->getsockopt(sk, level, optname, | ||
2056 | optval, optlen); | ||
2057 | return do_tcp_getsockopt(sk, level, optname, optval, optlen); | ||
2058 | } | ||
2059 | |||
2060 | #ifdef CONFIG_COMPAT | ||
2061 | int compat_tcp_getsockopt(struct sock *sk, int level, | ||
2062 | int optname, char __user *optval, int __user *optlen) | ||
2063 | { | ||
2064 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
2065 | |||
2066 | if (level != SOL_TCP) { | ||
2067 | if (icsk->icsk_af_ops->compat_getsockopt) | ||
2068 | return icsk->icsk_af_ops->compat_getsockopt(sk, | ||
2069 | level, optname, optval, optlen); | ||
2070 | else | ||
2071 | return icsk->icsk_af_ops->getsockopt(sk, | ||
2072 | level, optname, optval, optlen); | ||
2073 | } | ||
2074 | return do_tcp_getsockopt(sk, level, optname, optval, optlen); | ||
2075 | } | ||
2076 | #endif | ||
2028 | 2077 | ||
2029 | extern void __skb_cb_too_small_for_tcp(int, int); | 2078 | extern void __skb_cb_too_small_for_tcp(int, int); |
2030 | extern struct tcp_congestion_ops tcp_reno; | 2079 | extern struct tcp_congestion_ops tcp_reno; |
@@ -2142,3 +2191,7 @@ EXPORT_SYMBOL(tcp_sendpage); | |||
2142 | EXPORT_SYMBOL(tcp_setsockopt); | 2191 | EXPORT_SYMBOL(tcp_setsockopt); |
2143 | EXPORT_SYMBOL(tcp_shutdown); | 2192 | EXPORT_SYMBOL(tcp_shutdown); |
2144 | EXPORT_SYMBOL(tcp_statistics); | 2193 | EXPORT_SYMBOL(tcp_statistics); |
2194 | #ifdef CONFIG_COMPAT | ||
2195 | EXPORT_SYMBOL(compat_tcp_setsockopt); | ||
2196 | EXPORT_SYMBOL(compat_tcp_getsockopt); | ||
2197 | #endif | ||