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.c77
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 */
1690int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, 1690static 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
1870int 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
1882int 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. */
1875void tcp_get_info(struct sock *sk, struct tcp_info *info) 1900void 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
1932EXPORT_SYMBOL_GPL(tcp_get_info); 1957EXPORT_SYMBOL_GPL(tcp_get_info);
1933 1958
1934int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, 1959static 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
2049int 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
2061int 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
2029extern void __skb_cb_too_small_for_tcp(int, int); 2078extern void __skb_cb_too_small_for_tcp(int, int);
2030extern struct tcp_congestion_ops tcp_reno; 2079extern struct tcp_congestion_ops tcp_reno;
@@ -2142,3 +2191,7 @@ EXPORT_SYMBOL(tcp_sendpage);
2142EXPORT_SYMBOL(tcp_setsockopt); 2191EXPORT_SYMBOL(tcp_setsockopt);
2143EXPORT_SYMBOL(tcp_shutdown); 2192EXPORT_SYMBOL(tcp_shutdown);
2144EXPORT_SYMBOL(tcp_statistics); 2193EXPORT_SYMBOL(tcp_statistics);
2194#ifdef CONFIG_COMPAT
2195EXPORT_SYMBOL(compat_tcp_setsockopt);
2196EXPORT_SYMBOL(compat_tcp_getsockopt);
2197#endif