10abdde82SPaolo Abeni // SPDX-License-Identifier: GPL-2.0 20abdde82SPaolo Abeni /* Multipath TCP 30abdde82SPaolo Abeni * 40abdde82SPaolo Abeni * Copyright (c) 2021, Red Hat. 50abdde82SPaolo Abeni */ 60abdde82SPaolo Abeni 70abdde82SPaolo Abeni #define pr_fmt(fmt) "MPTCP: " fmt 80abdde82SPaolo Abeni 90abdde82SPaolo Abeni #include <linux/kernel.h> 100abdde82SPaolo Abeni #include <linux/module.h> 110abdde82SPaolo Abeni #include <net/sock.h> 120abdde82SPaolo Abeni #include <net/protocol.h> 130abdde82SPaolo Abeni #include <net/tcp.h> 140abdde82SPaolo Abeni #include <net/mptcp.h> 150abdde82SPaolo Abeni #include "protocol.h" 160abdde82SPaolo Abeni 1706f15ceeSFlorian Westphal #define MIN_INFO_OPTLEN_SIZE 16 1849243207SPaolo Abeni #define MIN_FULL_INFO_OPTLEN_SIZE 40 1906f15ceeSFlorian Westphal 200abdde82SPaolo Abeni static struct sock *__mptcp_tcp_fallback(struct mptcp_sock *msk) 210abdde82SPaolo Abeni { 22109cdeb8SGeliang Tang msk_owned_by_me(msk); 230abdde82SPaolo Abeni 240abdde82SPaolo Abeni if (likely(!__mptcp_check_fallback(msk))) 250abdde82SPaolo Abeni return NULL; 260abdde82SPaolo Abeni 270abdde82SPaolo Abeni return msk->first; 280abdde82SPaolo Abeni } 290abdde82SPaolo Abeni 30df00b087SFlorian Westphal static u32 sockopt_seq_reset(const struct sock *sk) 31df00b087SFlorian Westphal { 32df00b087SFlorian Westphal sock_owned_by_me(sk); 33df00b087SFlorian Westphal 34df00b087SFlorian Westphal /* Highbits contain state. Allows to distinguish sockopt_seq 35df00b087SFlorian Westphal * of listener and established: 36df00b087SFlorian Westphal * s0 = new_listener() 37df00b087SFlorian Westphal * sockopt(s0) - seq is 1 38df00b087SFlorian Westphal * s1 = accept(s0) - s1 inherits seq 1 if listener sk (s0) 39df00b087SFlorian Westphal * sockopt(s0) - seq increments to 2 on s0 40df00b087SFlorian Westphal * sockopt(s1) // seq increments to 2 on s1 (different option) 41df00b087SFlorian Westphal * new ssk completes join, inherits options from s0 // seq 2 42df00b087SFlorian Westphal * Needs sync from mptcp join logic, but ssk->seq == msk->seq 43df00b087SFlorian Westphal * 44df00b087SFlorian Westphal * Set High order bits to sk_state so ssk->seq == msk->seq test 45df00b087SFlorian Westphal * will fail. 46df00b087SFlorian Westphal */ 47df00b087SFlorian Westphal 48df00b087SFlorian Westphal return (u32)sk->sk_state << 24u; 49df00b087SFlorian Westphal } 50df00b087SFlorian Westphal 511b3e7edeSFlorian Westphal static void sockopt_seq_inc(struct mptcp_sock *msk) 521b3e7edeSFlorian Westphal { 531b3e7edeSFlorian Westphal u32 seq = (msk->setsockopt_seq + 1) & 0x00ffffff; 541b3e7edeSFlorian Westphal 551b3e7edeSFlorian Westphal msk->setsockopt_seq = sockopt_seq_reset((struct sock *)msk) + seq; 561b3e7edeSFlorian Westphal } 571b3e7edeSFlorian Westphal 581b3e7edeSFlorian Westphal static int mptcp_get_int_option(struct mptcp_sock *msk, sockptr_t optval, 591b3e7edeSFlorian Westphal unsigned int optlen, int *val) 601b3e7edeSFlorian Westphal { 611b3e7edeSFlorian Westphal if (optlen < sizeof(int)) 621b3e7edeSFlorian Westphal return -EINVAL; 631b3e7edeSFlorian Westphal 641b3e7edeSFlorian Westphal if (copy_from_sockptr(val, optval, sizeof(*val))) 651b3e7edeSFlorian Westphal return -EFAULT; 661b3e7edeSFlorian Westphal 671b3e7edeSFlorian Westphal return 0; 681b3e7edeSFlorian Westphal } 691b3e7edeSFlorian Westphal 701b3e7edeSFlorian Westphal static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, int val) 711b3e7edeSFlorian Westphal { 721b3e7edeSFlorian Westphal struct mptcp_subflow_context *subflow; 731b3e7edeSFlorian Westphal struct sock *sk = (struct sock *)msk; 741b3e7edeSFlorian Westphal 751b3e7edeSFlorian Westphal lock_sock(sk); 761b3e7edeSFlorian Westphal sockopt_seq_inc(msk); 771b3e7edeSFlorian Westphal 781b3e7edeSFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 791b3e7edeSFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 801b3e7edeSFlorian Westphal bool slow = lock_sock_fast(ssk); 811b3e7edeSFlorian Westphal 821b3e7edeSFlorian Westphal switch (optname) { 83a03c99b2SFlorian Westphal case SO_DEBUG: 84a03c99b2SFlorian Westphal sock_valbool_flag(ssk, SOCK_DBG, !!val); 85a03c99b2SFlorian Westphal break; 861b3e7edeSFlorian Westphal case SO_KEEPALIVE: 871b3e7edeSFlorian Westphal if (ssk->sk_prot->keepalive) 881b3e7edeSFlorian Westphal ssk->sk_prot->keepalive(ssk, !!val); 891b3e7edeSFlorian Westphal sock_valbool_flag(ssk, SOCK_KEEPOPEN, !!val); 901b3e7edeSFlorian Westphal break; 911b3e7edeSFlorian Westphal case SO_PRIORITY: 9210bbf165SEric Dumazet WRITE_ONCE(ssk->sk_priority, val); 931b3e7edeSFlorian Westphal break; 945d0a6bc8SFlorian Westphal case SO_SNDBUF: 955d0a6bc8SFlorian Westphal case SO_SNDBUFFORCE: 965d0a6bc8SFlorian Westphal ssk->sk_userlocks |= SOCK_SNDBUF_LOCK; 975d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_sndbuf, sk->sk_sndbuf); 988005184fSPaolo Abeni mptcp_subflow_ctx(ssk)->cached_sndbuf = sk->sk_sndbuf; 995d0a6bc8SFlorian Westphal break; 1005d0a6bc8SFlorian Westphal case SO_RCVBUF: 1015d0a6bc8SFlorian Westphal case SO_RCVBUFFORCE: 1025d0a6bc8SFlorian Westphal ssk->sk_userlocks |= SOCK_RCVBUF_LOCK; 1035d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf); 1045d0a6bc8SFlorian Westphal break; 10536704413SFlorian Westphal case SO_MARK: 10636704413SFlorian Westphal if (READ_ONCE(ssk->sk_mark) != sk->sk_mark) { 1073c5b4d69SEric Dumazet WRITE_ONCE(ssk->sk_mark, sk->sk_mark); 10836704413SFlorian Westphal sk_dst_reset(ssk); 10936704413SFlorian Westphal } 11036704413SFlorian Westphal break; 1116f0d7198SFlorian Westphal case SO_INCOMING_CPU: 1126f0d7198SFlorian Westphal WRITE_ONCE(ssk->sk_incoming_cpu, val); 1136f0d7198SFlorian Westphal break; 1141b3e7edeSFlorian Westphal } 1151b3e7edeSFlorian Westphal 1161b3e7edeSFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 1171b3e7edeSFlorian Westphal unlock_sock_fast(ssk, slow); 1181b3e7edeSFlorian Westphal } 1191b3e7edeSFlorian Westphal 1201b3e7edeSFlorian Westphal release_sock(sk); 1211b3e7edeSFlorian Westphal } 1221b3e7edeSFlorian Westphal 1231b3e7edeSFlorian Westphal static int mptcp_sol_socket_intval(struct mptcp_sock *msk, int optname, int val) 1241b3e7edeSFlorian Westphal { 1251b3e7edeSFlorian Westphal sockptr_t optval = KERNEL_SOCKPTR(&val); 1261b3e7edeSFlorian Westphal struct sock *sk = (struct sock *)msk; 1271b3e7edeSFlorian Westphal int ret; 1281b3e7edeSFlorian Westphal 1291b3e7edeSFlorian Westphal ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, 1301b3e7edeSFlorian Westphal optval, sizeof(val)); 1311b3e7edeSFlorian Westphal if (ret) 1321b3e7edeSFlorian Westphal return ret; 1331b3e7edeSFlorian Westphal 1341b3e7edeSFlorian Westphal mptcp_sol_socket_sync_intval(msk, optname, val); 1351b3e7edeSFlorian Westphal return 0; 1361b3e7edeSFlorian Westphal } 1371b3e7edeSFlorian Westphal 1386f0d7198SFlorian Westphal static void mptcp_so_incoming_cpu(struct mptcp_sock *msk, int val) 1396f0d7198SFlorian Westphal { 1406f0d7198SFlorian Westphal struct sock *sk = (struct sock *)msk; 1416f0d7198SFlorian Westphal 1426f0d7198SFlorian Westphal WRITE_ONCE(sk->sk_incoming_cpu, val); 1436f0d7198SFlorian Westphal 1446f0d7198SFlorian Westphal mptcp_sol_socket_sync_intval(msk, SO_INCOMING_CPU, val); 1456f0d7198SFlorian Westphal } 1466f0d7198SFlorian Westphal 1479061f24bSFlorian Westphal static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optname, int val) 1489061f24bSFlorian Westphal { 1499061f24bSFlorian Westphal sockptr_t optval = KERNEL_SOCKPTR(&val); 1509061f24bSFlorian Westphal struct mptcp_subflow_context *subflow; 1519061f24bSFlorian Westphal struct sock *sk = (struct sock *)msk; 1529061f24bSFlorian Westphal int ret; 1539061f24bSFlorian Westphal 1549061f24bSFlorian Westphal ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, 1559061f24bSFlorian Westphal optval, sizeof(val)); 1569061f24bSFlorian Westphal if (ret) 1579061f24bSFlorian Westphal return ret; 1589061f24bSFlorian Westphal 1599061f24bSFlorian Westphal lock_sock(sk); 1609061f24bSFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 1619061f24bSFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 1629061f24bSFlorian Westphal bool slow = lock_sock_fast(ssk); 1639061f24bSFlorian Westphal 1649061f24bSFlorian Westphal sock_set_timestamp(sk, optname, !!val); 1659061f24bSFlorian Westphal unlock_sock_fast(ssk, slow); 1669061f24bSFlorian Westphal } 1679061f24bSFlorian Westphal 1689061f24bSFlorian Westphal release_sock(sk); 1699061f24bSFlorian Westphal return 0; 1709061f24bSFlorian Westphal } 1719061f24bSFlorian Westphal 1721b3e7edeSFlorian Westphal static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname, 1736c9a0a0fSYangbo Lu sockptr_t optval, 1746c9a0a0fSYangbo Lu unsigned int optlen) 1751b3e7edeSFlorian Westphal { 1761b3e7edeSFlorian Westphal int val, ret; 1771b3e7edeSFlorian Westphal 1781b3e7edeSFlorian Westphal ret = mptcp_get_int_option(msk, optval, optlen, &val); 1791b3e7edeSFlorian Westphal if (ret) 1801b3e7edeSFlorian Westphal return ret; 1811b3e7edeSFlorian Westphal 1821b3e7edeSFlorian Westphal switch (optname) { 1831b3e7edeSFlorian Westphal case SO_KEEPALIVE: 1841b3e7edeSFlorian Westphal mptcp_sol_socket_sync_intval(msk, optname, val); 1851b3e7edeSFlorian Westphal return 0; 186a03c99b2SFlorian Westphal case SO_DEBUG: 18736704413SFlorian Westphal case SO_MARK: 1881b3e7edeSFlorian Westphal case SO_PRIORITY: 1895d0a6bc8SFlorian Westphal case SO_SNDBUF: 1905d0a6bc8SFlorian Westphal case SO_SNDBUFFORCE: 1915d0a6bc8SFlorian Westphal case SO_RCVBUF: 1925d0a6bc8SFlorian Westphal case SO_RCVBUFFORCE: 1931b3e7edeSFlorian Westphal return mptcp_sol_socket_intval(msk, optname, val); 1946f0d7198SFlorian Westphal case SO_INCOMING_CPU: 1956f0d7198SFlorian Westphal mptcp_so_incoming_cpu(msk, val); 1966f0d7198SFlorian Westphal return 0; 1979061f24bSFlorian Westphal case SO_TIMESTAMP_OLD: 1989061f24bSFlorian Westphal case SO_TIMESTAMP_NEW: 1999061f24bSFlorian Westphal case SO_TIMESTAMPNS_OLD: 2009061f24bSFlorian Westphal case SO_TIMESTAMPNS_NEW: 2019061f24bSFlorian Westphal return mptcp_setsockopt_sol_socket_tstamp(msk, optname, val); 2021b3e7edeSFlorian Westphal } 2031b3e7edeSFlorian Westphal 2041b3e7edeSFlorian Westphal return -ENOPROTOOPT; 2051b3e7edeSFlorian Westphal } 2061b3e7edeSFlorian Westphal 2076c9a0a0fSYangbo Lu static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, 2086c9a0a0fSYangbo Lu int optname, 2096c9a0a0fSYangbo Lu sockptr_t optval, 2106c9a0a0fSYangbo Lu unsigned int optlen) 2116c9a0a0fSYangbo Lu { 2126c9a0a0fSYangbo Lu struct mptcp_subflow_context *subflow; 2136c9a0a0fSYangbo Lu struct sock *sk = (struct sock *)msk; 214d463126eSYangbo Lu struct so_timestamping timestamping; 215d463126eSYangbo Lu int ret; 2166c9a0a0fSYangbo Lu 217d463126eSYangbo Lu if (optlen == sizeof(timestamping)) { 218d463126eSYangbo Lu if (copy_from_sockptr(×tamping, optval, 219d463126eSYangbo Lu sizeof(timestamping))) 220d463126eSYangbo Lu return -EFAULT; 221d463126eSYangbo Lu } else if (optlen == sizeof(int)) { 222d463126eSYangbo Lu memset(×tamping, 0, sizeof(timestamping)); 223d463126eSYangbo Lu 224d463126eSYangbo Lu if (copy_from_sockptr(×tamping.flags, optval, sizeof(int))) 225d463126eSYangbo Lu return -EFAULT; 226d463126eSYangbo Lu } else { 227d463126eSYangbo Lu return -EINVAL; 228d463126eSYangbo Lu } 2296c9a0a0fSYangbo Lu 2306c9a0a0fSYangbo Lu ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, 231d463126eSYangbo Lu KERNEL_SOCKPTR(×tamping), 232d463126eSYangbo Lu sizeof(timestamping)); 2336c9a0a0fSYangbo Lu if (ret) 2346c9a0a0fSYangbo Lu return ret; 2356c9a0a0fSYangbo Lu 2366c9a0a0fSYangbo Lu lock_sock(sk); 2376c9a0a0fSYangbo Lu 2386c9a0a0fSYangbo Lu mptcp_for_each_subflow(msk, subflow) { 2396c9a0a0fSYangbo Lu struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 2406c9a0a0fSYangbo Lu bool slow = lock_sock_fast(ssk); 2416c9a0a0fSYangbo Lu 242d463126eSYangbo Lu sock_set_timestamping(sk, optname, timestamping); 2436c9a0a0fSYangbo Lu unlock_sock_fast(ssk, slow); 2446c9a0a0fSYangbo Lu } 2456c9a0a0fSYangbo Lu 2466c9a0a0fSYangbo Lu release_sock(sk); 2476c9a0a0fSYangbo Lu 2486c9a0a0fSYangbo Lu return 0; 2496c9a0a0fSYangbo Lu } 2506c9a0a0fSYangbo Lu 251268b1238SFlorian Westphal static int mptcp_setsockopt_sol_socket_linger(struct mptcp_sock *msk, sockptr_t optval, 252268b1238SFlorian Westphal unsigned int optlen) 253268b1238SFlorian Westphal { 254268b1238SFlorian Westphal struct mptcp_subflow_context *subflow; 255268b1238SFlorian Westphal struct sock *sk = (struct sock *)msk; 256268b1238SFlorian Westphal struct linger ling; 257268b1238SFlorian Westphal sockptr_t kopt; 258268b1238SFlorian Westphal int ret; 259268b1238SFlorian Westphal 260268b1238SFlorian Westphal if (optlen < sizeof(ling)) 261268b1238SFlorian Westphal return -EINVAL; 262268b1238SFlorian Westphal 263268b1238SFlorian Westphal if (copy_from_sockptr(&ling, optval, sizeof(ling))) 264268b1238SFlorian Westphal return -EFAULT; 265268b1238SFlorian Westphal 266268b1238SFlorian Westphal kopt = KERNEL_SOCKPTR(&ling); 267268b1238SFlorian Westphal ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, SO_LINGER, kopt, sizeof(ling)); 268268b1238SFlorian Westphal if (ret) 269268b1238SFlorian Westphal return ret; 270268b1238SFlorian Westphal 271268b1238SFlorian Westphal lock_sock(sk); 272268b1238SFlorian Westphal sockopt_seq_inc(msk); 273268b1238SFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 274268b1238SFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 275268b1238SFlorian Westphal bool slow = lock_sock_fast(ssk); 276268b1238SFlorian Westphal 277268b1238SFlorian Westphal if (!ling.l_onoff) { 278268b1238SFlorian Westphal sock_reset_flag(ssk, SOCK_LINGER); 279268b1238SFlorian Westphal } else { 280268b1238SFlorian Westphal ssk->sk_lingertime = sk->sk_lingertime; 281268b1238SFlorian Westphal sock_set_flag(ssk, SOCK_LINGER); 282268b1238SFlorian Westphal } 283268b1238SFlorian Westphal 284268b1238SFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 285268b1238SFlorian Westphal unlock_sock_fast(ssk, slow); 286268b1238SFlorian Westphal } 287268b1238SFlorian Westphal 288268b1238SFlorian Westphal release_sock(sk); 289268b1238SFlorian Westphal return 0; 290268b1238SFlorian Westphal } 291268b1238SFlorian Westphal 2920abdde82SPaolo Abeni static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname, 2930abdde82SPaolo Abeni sockptr_t optval, unsigned int optlen) 2940abdde82SPaolo Abeni { 2950abdde82SPaolo Abeni struct sock *sk = (struct sock *)msk; 296f0bc514bSPaolo Abeni struct sock *ssk; 2970abdde82SPaolo Abeni int ret; 2980abdde82SPaolo Abeni 2990abdde82SPaolo Abeni switch (optname) { 3000abdde82SPaolo Abeni case SO_REUSEPORT: 3010abdde82SPaolo Abeni case SO_REUSEADDR: 3025d0a6bc8SFlorian Westphal case SO_BINDTODEVICE: 3035d0a6bc8SFlorian Westphal case SO_BINDTOIFINDEX: 3040abdde82SPaolo Abeni lock_sock(sk); 3053f326a82SPaolo Abeni ssk = __mptcp_nmpc_sk(msk); 3063f326a82SPaolo Abeni if (IS_ERR(ssk)) { 3070abdde82SPaolo Abeni release_sock(sk); 3083f326a82SPaolo Abeni return PTR_ERR(ssk); 3090abdde82SPaolo Abeni } 3100abdde82SPaolo Abeni 311f0bc514bSPaolo Abeni ret = sk_setsockopt(ssk, SOL_SOCKET, optname, optval, optlen); 3120abdde82SPaolo Abeni if (ret == 0) { 3130abdde82SPaolo Abeni if (optname == SO_REUSEPORT) 314f0bc514bSPaolo Abeni sk->sk_reuseport = ssk->sk_reuseport; 3150abdde82SPaolo Abeni else if (optname == SO_REUSEADDR) 316f0bc514bSPaolo Abeni sk->sk_reuse = ssk->sk_reuse; 3175d0a6bc8SFlorian Westphal else if (optname == SO_BINDTODEVICE) 318f0bc514bSPaolo Abeni sk->sk_bound_dev_if = ssk->sk_bound_dev_if; 3195d0a6bc8SFlorian Westphal else if (optname == SO_BINDTOIFINDEX) 320f0bc514bSPaolo Abeni sk->sk_bound_dev_if = ssk->sk_bound_dev_if; 3210abdde82SPaolo Abeni } 3220abdde82SPaolo Abeni release_sock(sk); 3230abdde82SPaolo Abeni return ret; 3241b3e7edeSFlorian Westphal case SO_KEEPALIVE: 3251b3e7edeSFlorian Westphal case SO_PRIORITY: 3265d0a6bc8SFlorian Westphal case SO_SNDBUF: 3275d0a6bc8SFlorian Westphal case SO_SNDBUFFORCE: 3285d0a6bc8SFlorian Westphal case SO_RCVBUF: 3295d0a6bc8SFlorian Westphal case SO_RCVBUFFORCE: 33036704413SFlorian Westphal case SO_MARK: 3316f0d7198SFlorian Westphal case SO_INCOMING_CPU: 332a03c99b2SFlorian Westphal case SO_DEBUG: 3339061f24bSFlorian Westphal case SO_TIMESTAMP_OLD: 3349061f24bSFlorian Westphal case SO_TIMESTAMP_NEW: 3359061f24bSFlorian Westphal case SO_TIMESTAMPNS_OLD: 3369061f24bSFlorian Westphal case SO_TIMESTAMPNS_NEW: 3376c9a0a0fSYangbo Lu return mptcp_setsockopt_sol_socket_int(msk, optname, optval, 3386c9a0a0fSYangbo Lu optlen); 3399061f24bSFlorian Westphal case SO_TIMESTAMPING_OLD: 3409061f24bSFlorian Westphal case SO_TIMESTAMPING_NEW: 3416c9a0a0fSYangbo Lu return mptcp_setsockopt_sol_socket_timestamping(msk, optname, 3426c9a0a0fSYangbo Lu optval, optlen); 343268b1238SFlorian Westphal case SO_LINGER: 344268b1238SFlorian Westphal return mptcp_setsockopt_sol_socket_linger(msk, optval, optlen); 3457a009a70SFlorian Westphal case SO_RCVLOWAT: 3467a009a70SFlorian Westphal case SO_RCVTIMEO_OLD: 3477a009a70SFlorian Westphal case SO_RCVTIMEO_NEW: 348d6ab5ea2SGeliang Tang case SO_SNDTIMEO_OLD: 349d6ab5ea2SGeliang Tang case SO_SNDTIMEO_NEW: 3507a009a70SFlorian Westphal case SO_BUSY_POLL: 3517a009a70SFlorian Westphal case SO_PREFER_BUSY_POLL: 3527a009a70SFlorian Westphal case SO_BUSY_POLL_BUDGET: 3537a009a70SFlorian Westphal /* No need to copy: only relevant for msk */ 3547a009a70SFlorian Westphal return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen); 355a03c99b2SFlorian Westphal case SO_NO_CHECK: 356a03c99b2SFlorian Westphal case SO_DONTROUTE: 357a03c99b2SFlorian Westphal case SO_BROADCAST: 358a03c99b2SFlorian Westphal case SO_BSDCOMPAT: 359a03c99b2SFlorian Westphal case SO_PASSCRED: 3605e2ff670SAlexander Mikhalitsyn case SO_PASSPIDFD: 361a03c99b2SFlorian Westphal case SO_PASSSEC: 362a03c99b2SFlorian Westphal case SO_RXQ_OVFL: 363a03c99b2SFlorian Westphal case SO_WIFI_STATUS: 364a03c99b2SFlorian Westphal case SO_NOFCS: 365a03c99b2SFlorian Westphal case SO_SELECT_ERR_QUEUE: 366a03c99b2SFlorian Westphal return 0; 3670abdde82SPaolo Abeni } 3680abdde82SPaolo Abeni 3697a009a70SFlorian Westphal /* SO_OOBINLINE is not supported, let's avoid the related mess 3707a009a70SFlorian Westphal * SO_ATTACH_FILTER, SO_ATTACH_BPF, SO_ATTACH_REUSEPORT_CBPF, 3717a009a70SFlorian Westphal * SO_DETACH_REUSEPORT_BPF, SO_DETACH_FILTER, SO_LOCK_FILTER, 3727a009a70SFlorian Westphal * we must be careful with subflows 3737a009a70SFlorian Westphal * 3747a009a70SFlorian Westphal * SO_ATTACH_REUSEPORT_EBPF is not supported, at it checks 3757a009a70SFlorian Westphal * explicitly the sk_protocol field 3767a009a70SFlorian Westphal * 3777a009a70SFlorian Westphal * SO_PEEK_OFF is unsupported, as it is for plain TCP 3787a009a70SFlorian Westphal * SO_MAX_PACING_RATE is unsupported, we must be careful with subflows 3797a009a70SFlorian Westphal * SO_CNX_ADVICE is currently unsupported, could possibly be relevant, 3807a009a70SFlorian Westphal * but likely needs careful design 3817a009a70SFlorian Westphal * 3827a009a70SFlorian Westphal * SO_ZEROCOPY is currently unsupported, TODO in sndmsg 3837a009a70SFlorian Westphal * SO_TXTIME is currently unsupported 3847a009a70SFlorian Westphal */ 3857a009a70SFlorian Westphal 3867a009a70SFlorian Westphal return -EOPNOTSUPP; 3870abdde82SPaolo Abeni } 3880abdde82SPaolo Abeni 3890abdde82SPaolo Abeni static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname, 3900abdde82SPaolo Abeni sockptr_t optval, unsigned int optlen) 3910abdde82SPaolo Abeni { 3920abdde82SPaolo Abeni struct sock *sk = (struct sock *)msk; 3930abdde82SPaolo Abeni int ret = -EOPNOTSUPP; 394f0bc514bSPaolo Abeni struct sock *ssk; 3950abdde82SPaolo Abeni 3960abdde82SPaolo Abeni switch (optname) { 3970abdde82SPaolo Abeni case IPV6_V6ONLY: 398c9406a23SFlorian Westphal case IPV6_TRANSPARENT: 399c9406a23SFlorian Westphal case IPV6_FREEBIND: 4000abdde82SPaolo Abeni lock_sock(sk); 4013f326a82SPaolo Abeni ssk = __mptcp_nmpc_sk(msk); 4023f326a82SPaolo Abeni if (IS_ERR(ssk)) { 4030abdde82SPaolo Abeni release_sock(sk); 4043f326a82SPaolo Abeni return PTR_ERR(ssk); 4050abdde82SPaolo Abeni } 4060abdde82SPaolo Abeni 407f0bc514bSPaolo Abeni ret = tcp_setsockopt(ssk, SOL_IPV6, optname, optval, optlen); 408c9406a23SFlorian Westphal if (ret != 0) { 409c9406a23SFlorian Westphal release_sock(sk); 410c9406a23SFlorian Westphal return ret; 411c9406a23SFlorian Westphal } 412c9406a23SFlorian Westphal 413c9406a23SFlorian Westphal sockopt_seq_inc(msk); 414c9406a23SFlorian Westphal 415c9406a23SFlorian Westphal switch (optname) { 416c9406a23SFlorian Westphal case IPV6_V6ONLY: 417f0bc514bSPaolo Abeni sk->sk_ipv6only = ssk->sk_ipv6only; 418c9406a23SFlorian Westphal break; 419c9406a23SFlorian Westphal case IPV6_TRANSPARENT: 4204bd0623fSEric Dumazet inet_assign_bit(TRANSPARENT, sk, 4214bd0623fSEric Dumazet inet_test_bit(TRANSPARENT, ssk)); 422c9406a23SFlorian Westphal break; 423c9406a23SFlorian Westphal case IPV6_FREEBIND: 4243f7e7532SEric Dumazet inet_assign_bit(FREEBIND, sk, 4253f7e7532SEric Dumazet inet_test_bit(FREEBIND, ssk)); 426c9406a23SFlorian Westphal break; 427c9406a23SFlorian Westphal } 4280abdde82SPaolo Abeni 4290abdde82SPaolo Abeni release_sock(sk); 4300abdde82SPaolo Abeni break; 4310abdde82SPaolo Abeni } 4320abdde82SPaolo Abeni 4330abdde82SPaolo Abeni return ret; 4340abdde82SPaolo Abeni } 4350abdde82SPaolo Abeni 436d9e4c129SPaolo Abeni static bool mptcp_supported_sockopt(int level, int optname) 437d9e4c129SPaolo Abeni { 438d9e4c129SPaolo Abeni if (level == SOL_IP) { 439d9e4c129SPaolo Abeni switch (optname) { 440d9e4c129SPaolo Abeni /* should work fine */ 441d9e4c129SPaolo Abeni case IP_FREEBIND: 442d9e4c129SPaolo Abeni case IP_TRANSPARENT: 443d9e4c129SPaolo Abeni 444d9e4c129SPaolo Abeni /* the following are control cmsg related */ 445d9e4c129SPaolo Abeni case IP_PKTINFO: 446d9e4c129SPaolo Abeni case IP_RECVTTL: 447d9e4c129SPaolo Abeni case IP_RECVTOS: 448d9e4c129SPaolo Abeni case IP_RECVOPTS: 449d9e4c129SPaolo Abeni case IP_RETOPTS: 450d9e4c129SPaolo Abeni case IP_PASSSEC: 451d9e4c129SPaolo Abeni case IP_RECVORIGDSTADDR: 452d9e4c129SPaolo Abeni case IP_CHECKSUM: 453d9e4c129SPaolo Abeni case IP_RECVFRAGSIZE: 454d9e4c129SPaolo Abeni 455d9e4c129SPaolo Abeni /* common stuff that need some love */ 456d9e4c129SPaolo Abeni case IP_TOS: 457d9e4c129SPaolo Abeni case IP_TTL: 458d9e4c129SPaolo Abeni case IP_BIND_ADDRESS_NO_PORT: 459d9e4c129SPaolo Abeni case IP_MTU_DISCOVER: 460d9e4c129SPaolo Abeni case IP_RECVERR: 461d9e4c129SPaolo Abeni 462d9e4c129SPaolo Abeni /* possibly less common may deserve some love */ 463d9e4c129SPaolo Abeni case IP_MINTTL: 464d9e4c129SPaolo Abeni 465d9e4c129SPaolo Abeni /* the following is apparently a no-op for plain TCP */ 466d9e4c129SPaolo Abeni case IP_RECVERR_RFC4884: 467d9e4c129SPaolo Abeni return true; 468d9e4c129SPaolo Abeni } 469d9e4c129SPaolo Abeni 470d9e4c129SPaolo Abeni /* IP_OPTIONS is not supported, needs subflow care */ 471d9e4c129SPaolo Abeni /* IP_HDRINCL, IP_NODEFRAG are not supported, RAW specific */ 472d9e4c129SPaolo Abeni /* IP_MULTICAST_TTL, IP_MULTICAST_LOOP, IP_UNICAST_IF, 473d9e4c129SPaolo Abeni * IP_ADD_MEMBERSHIP, IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_MEMBERSHIP, 474d9e4c129SPaolo Abeni * IP_DROP_SOURCE_MEMBERSHIP, IP_BLOCK_SOURCE, IP_UNBLOCK_SOURCE, 475d9e4c129SPaolo Abeni * MCAST_JOIN_GROUP, MCAST_LEAVE_GROUP MCAST_JOIN_SOURCE_GROUP, 476d9e4c129SPaolo Abeni * MCAST_LEAVE_SOURCE_GROUP, MCAST_BLOCK_SOURCE, MCAST_UNBLOCK_SOURCE, 477d9e4c129SPaolo Abeni * MCAST_MSFILTER, IP_MULTICAST_ALL are not supported, better not deal 478d9e4c129SPaolo Abeni * with mcast stuff 479d9e4c129SPaolo Abeni */ 480d9e4c129SPaolo Abeni /* IP_IPSEC_POLICY, IP_XFRM_POLICY are nut supported, unrelated here */ 481d9e4c129SPaolo Abeni return false; 482d9e4c129SPaolo Abeni } 483d9e4c129SPaolo Abeni if (level == SOL_IPV6) { 484d9e4c129SPaolo Abeni switch (optname) { 485d9e4c129SPaolo Abeni case IPV6_V6ONLY: 486d9e4c129SPaolo Abeni 487d9e4c129SPaolo Abeni /* the following are control cmsg related */ 488d9e4c129SPaolo Abeni case IPV6_RECVPKTINFO: 489d9e4c129SPaolo Abeni case IPV6_2292PKTINFO: 490d9e4c129SPaolo Abeni case IPV6_RECVHOPLIMIT: 491d9e4c129SPaolo Abeni case IPV6_2292HOPLIMIT: 492d9e4c129SPaolo Abeni case IPV6_RECVRTHDR: 493d9e4c129SPaolo Abeni case IPV6_2292RTHDR: 494d9e4c129SPaolo Abeni case IPV6_RECVHOPOPTS: 495d9e4c129SPaolo Abeni case IPV6_2292HOPOPTS: 496d9e4c129SPaolo Abeni case IPV6_RECVDSTOPTS: 497d9e4c129SPaolo Abeni case IPV6_2292DSTOPTS: 498d9e4c129SPaolo Abeni case IPV6_RECVTCLASS: 499d9e4c129SPaolo Abeni case IPV6_FLOWINFO: 500d9e4c129SPaolo Abeni case IPV6_RECVPATHMTU: 501d9e4c129SPaolo Abeni case IPV6_RECVORIGDSTADDR: 502d9e4c129SPaolo Abeni case IPV6_RECVFRAGSIZE: 503d9e4c129SPaolo Abeni 504d9e4c129SPaolo Abeni /* the following ones need some love but are quite common */ 505d9e4c129SPaolo Abeni case IPV6_TCLASS: 506d9e4c129SPaolo Abeni case IPV6_TRANSPARENT: 507d9e4c129SPaolo Abeni case IPV6_FREEBIND: 508d9e4c129SPaolo Abeni case IPV6_PKTINFO: 509d9e4c129SPaolo Abeni case IPV6_2292PKTOPTIONS: 510d9e4c129SPaolo Abeni case IPV6_UNICAST_HOPS: 511d9e4c129SPaolo Abeni case IPV6_MTU_DISCOVER: 512d9e4c129SPaolo Abeni case IPV6_MTU: 513d9e4c129SPaolo Abeni case IPV6_RECVERR: 514d9e4c129SPaolo Abeni case IPV6_FLOWINFO_SEND: 515d9e4c129SPaolo Abeni case IPV6_FLOWLABEL_MGR: 516d9e4c129SPaolo Abeni case IPV6_MINHOPCOUNT: 517d9e4c129SPaolo Abeni case IPV6_DONTFRAG: 518d9e4c129SPaolo Abeni case IPV6_AUTOFLOWLABEL: 519d9e4c129SPaolo Abeni 520d9e4c129SPaolo Abeni /* the following one is a no-op for plain TCP */ 521d9e4c129SPaolo Abeni case IPV6_RECVERR_RFC4884: 522d9e4c129SPaolo Abeni return true; 523d9e4c129SPaolo Abeni } 524d9e4c129SPaolo Abeni 525d9e4c129SPaolo Abeni /* IPV6_HOPOPTS, IPV6_RTHDRDSTOPTS, IPV6_RTHDR, IPV6_DSTOPTS are 526d9e4c129SPaolo Abeni * not supported 527d9e4c129SPaolo Abeni */ 528d9e4c129SPaolo Abeni /* IPV6_MULTICAST_HOPS, IPV6_MULTICAST_LOOP, IPV6_UNICAST_IF, 529d9e4c129SPaolo Abeni * IPV6_MULTICAST_IF, IPV6_ADDRFORM, 530d9e4c129SPaolo Abeni * IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_JOIN_ANYCAST, 531d9e4c129SPaolo Abeni * IPV6_LEAVE_ANYCAST, IPV6_MULTICAST_ALL, MCAST_JOIN_GROUP, MCAST_LEAVE_GROUP, 532d9e4c129SPaolo Abeni * MCAST_JOIN_SOURCE_GROUP, MCAST_LEAVE_SOURCE_GROUP, 533d9e4c129SPaolo Abeni * MCAST_BLOCK_SOURCE, MCAST_UNBLOCK_SOURCE, MCAST_MSFILTER 534d9e4c129SPaolo Abeni * are not supported better not deal with mcast 535d9e4c129SPaolo Abeni */ 536d9e4c129SPaolo Abeni /* IPV6_ROUTER_ALERT, IPV6_ROUTER_ALERT_ISOLATE are not supported, since are evil */ 537d9e4c129SPaolo Abeni 538d9e4c129SPaolo Abeni /* IPV6_IPSEC_POLICY, IPV6_XFRM_POLICY are not supported */ 539d9e4c129SPaolo Abeni /* IPV6_ADDR_PREFERENCES is not supported, we must be careful with subflows */ 540d9e4c129SPaolo Abeni return false; 541d9e4c129SPaolo Abeni } 542d9e4c129SPaolo Abeni if (level == SOL_TCP) { 543d9e4c129SPaolo Abeni switch (optname) { 544d9e4c129SPaolo Abeni /* the following are no-op or should work just fine */ 545d9e4c129SPaolo Abeni case TCP_THIN_DUPACK: 546d9e4c129SPaolo Abeni case TCP_DEFER_ACCEPT: 547d9e4c129SPaolo Abeni 548d9e4c129SPaolo Abeni /* the following need some love */ 549d9e4c129SPaolo Abeni case TCP_MAXSEG: 550d9e4c129SPaolo Abeni case TCP_NODELAY: 551d9e4c129SPaolo Abeni case TCP_THIN_LINEAR_TIMEOUTS: 552d9e4c129SPaolo Abeni case TCP_CONGESTION: 553d9e4c129SPaolo Abeni case TCP_CORK: 554d9e4c129SPaolo Abeni case TCP_KEEPIDLE: 555d9e4c129SPaolo Abeni case TCP_KEEPINTVL: 556d9e4c129SPaolo Abeni case TCP_KEEPCNT: 557d9e4c129SPaolo Abeni case TCP_SYNCNT: 558d9e4c129SPaolo Abeni case TCP_SAVE_SYN: 559d9e4c129SPaolo Abeni case TCP_LINGER2: 560d9e4c129SPaolo Abeni case TCP_WINDOW_CLAMP: 561d9e4c129SPaolo Abeni case TCP_QUICKACK: 562d9e4c129SPaolo Abeni case TCP_USER_TIMEOUT: 563d9e4c129SPaolo Abeni case TCP_TIMESTAMP: 564d9e4c129SPaolo Abeni case TCP_NOTSENT_LOWAT: 565d9e4c129SPaolo Abeni case TCP_TX_DELAY: 5662c9e7765SFlorian Westphal case TCP_INQ: 5674ffb0a02SDmytro Shytyi case TCP_FASTOPEN: 56854635bd0SBenjamin Hesmans case TCP_FASTOPEN_CONNECT: 569cb99816cSMatthieu Baerts case TCP_FASTOPEN_KEY: 570e64d4debSMatthieu Baerts case TCP_FASTOPEN_NO_COOKIE: 571d9e4c129SPaolo Abeni return true; 572d9e4c129SPaolo Abeni } 573d9e4c129SPaolo Abeni 574d9e4c129SPaolo Abeni /* TCP_MD5SIG, TCP_MD5SIG_EXT are not supported, MD5 is not compatible with MPTCP */ 575d9e4c129SPaolo Abeni 576d9e4c129SPaolo Abeni /* TCP_REPAIR, TCP_REPAIR_QUEUE, TCP_QUEUE_SEQ, TCP_REPAIR_OPTIONS, 577d9e4c129SPaolo Abeni * TCP_REPAIR_WINDOW are not supported, better avoid this mess 578d9e4c129SPaolo Abeni */ 579d9e4c129SPaolo Abeni } 580d9e4c129SPaolo Abeni return false; 581d9e4c129SPaolo Abeni } 582d9e4c129SPaolo Abeni 583aa1fbd94SFlorian Westphal static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t optval, 584aa1fbd94SFlorian Westphal unsigned int optlen) 585aa1fbd94SFlorian Westphal { 586aa1fbd94SFlorian Westphal struct mptcp_subflow_context *subflow; 587aa1fbd94SFlorian Westphal struct sock *sk = (struct sock *)msk; 588aa1fbd94SFlorian Westphal char name[TCP_CA_NAME_MAX]; 589aa1fbd94SFlorian Westphal bool cap_net_admin; 590aa1fbd94SFlorian Westphal int ret; 591aa1fbd94SFlorian Westphal 592aa1fbd94SFlorian Westphal if (optlen < 1) 593aa1fbd94SFlorian Westphal return -EINVAL; 594aa1fbd94SFlorian Westphal 595aa1fbd94SFlorian Westphal ret = strncpy_from_sockptr(name, optval, 596aa1fbd94SFlorian Westphal min_t(long, TCP_CA_NAME_MAX - 1, optlen)); 597aa1fbd94SFlorian Westphal if (ret < 0) 598aa1fbd94SFlorian Westphal return -EFAULT; 599aa1fbd94SFlorian Westphal 600aa1fbd94SFlorian Westphal name[ret] = 0; 601aa1fbd94SFlorian Westphal 602aa1fbd94SFlorian Westphal cap_net_admin = ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN); 603aa1fbd94SFlorian Westphal 604aa1fbd94SFlorian Westphal ret = 0; 605aa1fbd94SFlorian Westphal lock_sock(sk); 606aa1fbd94SFlorian Westphal sockopt_seq_inc(msk); 607aa1fbd94SFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 608aa1fbd94SFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 609aa1fbd94SFlorian Westphal int err; 610aa1fbd94SFlorian Westphal 611aa1fbd94SFlorian Westphal lock_sock(ssk); 612aa1fbd94SFlorian Westphal err = tcp_set_congestion_control(ssk, name, true, cap_net_admin); 613aa1fbd94SFlorian Westphal if (err < 0 && ret == 0) 614aa1fbd94SFlorian Westphal ret = err; 615aa1fbd94SFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 616aa1fbd94SFlorian Westphal release_sock(ssk); 617aa1fbd94SFlorian Westphal } 618aa1fbd94SFlorian Westphal 619aa1fbd94SFlorian Westphal if (ret == 0) 62020b5759fSPaolo Abeni strcpy(msk->ca_name, name); 621aa1fbd94SFlorian Westphal 622aa1fbd94SFlorian Westphal release_sock(sk); 623aa1fbd94SFlorian Westphal return ret; 624aa1fbd94SFlorian Westphal } 625aa1fbd94SFlorian Westphal 6264f6e14bdSMaxim Galaganov static int mptcp_setsockopt_sol_tcp_cork(struct mptcp_sock *msk, sockptr_t optval, 6274f6e14bdSMaxim Galaganov unsigned int optlen) 6284f6e14bdSMaxim Galaganov { 6294f6e14bdSMaxim Galaganov struct mptcp_subflow_context *subflow; 6304f6e14bdSMaxim Galaganov struct sock *sk = (struct sock *)msk; 6314f6e14bdSMaxim Galaganov int val; 6324f6e14bdSMaxim Galaganov 6334f6e14bdSMaxim Galaganov if (optlen < sizeof(int)) 6344f6e14bdSMaxim Galaganov return -EINVAL; 6354f6e14bdSMaxim Galaganov 6364f6e14bdSMaxim Galaganov if (copy_from_sockptr(&val, optval, sizeof(val))) 6374f6e14bdSMaxim Galaganov return -EFAULT; 6384f6e14bdSMaxim Galaganov 6394f6e14bdSMaxim Galaganov lock_sock(sk); 6404f6e14bdSMaxim Galaganov sockopt_seq_inc(msk); 6414f6e14bdSMaxim Galaganov msk->cork = !!val; 6424f6e14bdSMaxim Galaganov mptcp_for_each_subflow(msk, subflow) { 6434f6e14bdSMaxim Galaganov struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 6444f6e14bdSMaxim Galaganov 6454f6e14bdSMaxim Galaganov lock_sock(ssk); 6464f6e14bdSMaxim Galaganov __tcp_sock_set_cork(ssk, !!val); 6474f6e14bdSMaxim Galaganov release_sock(ssk); 6484f6e14bdSMaxim Galaganov } 6494f6e14bdSMaxim Galaganov if (!val) 6504f6e14bdSMaxim Galaganov mptcp_check_and_set_pending(sk); 6514f6e14bdSMaxim Galaganov release_sock(sk); 6524f6e14bdSMaxim Galaganov 6534f6e14bdSMaxim Galaganov return 0; 6544f6e14bdSMaxim Galaganov } 6554f6e14bdSMaxim Galaganov 6564f6e14bdSMaxim Galaganov static int mptcp_setsockopt_sol_tcp_nodelay(struct mptcp_sock *msk, sockptr_t optval, 6574f6e14bdSMaxim Galaganov unsigned int optlen) 6584f6e14bdSMaxim Galaganov { 6594f6e14bdSMaxim Galaganov struct mptcp_subflow_context *subflow; 6604f6e14bdSMaxim Galaganov struct sock *sk = (struct sock *)msk; 6614f6e14bdSMaxim Galaganov int val; 6624f6e14bdSMaxim Galaganov 6634f6e14bdSMaxim Galaganov if (optlen < sizeof(int)) 6644f6e14bdSMaxim Galaganov return -EINVAL; 6654f6e14bdSMaxim Galaganov 6664f6e14bdSMaxim Galaganov if (copy_from_sockptr(&val, optval, sizeof(val))) 6674f6e14bdSMaxim Galaganov return -EFAULT; 6684f6e14bdSMaxim Galaganov 6694f6e14bdSMaxim Galaganov lock_sock(sk); 6704f6e14bdSMaxim Galaganov sockopt_seq_inc(msk); 6714f6e14bdSMaxim Galaganov msk->nodelay = !!val; 6724f6e14bdSMaxim Galaganov mptcp_for_each_subflow(msk, subflow) { 6734f6e14bdSMaxim Galaganov struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 6744f6e14bdSMaxim Galaganov 6754f6e14bdSMaxim Galaganov lock_sock(ssk); 6764f6e14bdSMaxim Galaganov __tcp_sock_set_nodelay(ssk, !!val); 6774f6e14bdSMaxim Galaganov release_sock(ssk); 6784f6e14bdSMaxim Galaganov } 6794f6e14bdSMaxim Galaganov if (val) 6804f6e14bdSMaxim Galaganov mptcp_check_and_set_pending(sk); 6814f6e14bdSMaxim Galaganov release_sock(sk); 6824f6e14bdSMaxim Galaganov 6834f6e14bdSMaxim Galaganov return 0; 6844f6e14bdSMaxim Galaganov } 6854f6e14bdSMaxim Galaganov 686c9406a23SFlorian Westphal static int mptcp_setsockopt_sol_ip_set_transparent(struct mptcp_sock *msk, int optname, 687c9406a23SFlorian Westphal sockptr_t optval, unsigned int optlen) 688c9406a23SFlorian Westphal { 689c9406a23SFlorian Westphal struct sock *sk = (struct sock *)msk; 6903f326a82SPaolo Abeni struct sock *ssk; 691c9406a23SFlorian Westphal int err; 692c9406a23SFlorian Westphal 693c9406a23SFlorian Westphal err = ip_setsockopt(sk, SOL_IP, optname, optval, optlen); 694c9406a23SFlorian Westphal if (err != 0) 695c9406a23SFlorian Westphal return err; 696c9406a23SFlorian Westphal 697c9406a23SFlorian Westphal lock_sock(sk); 698c9406a23SFlorian Westphal 6993f326a82SPaolo Abeni ssk = __mptcp_nmpc_sk(msk); 7003f326a82SPaolo Abeni if (IS_ERR(ssk)) { 701c9406a23SFlorian Westphal release_sock(sk); 7023f326a82SPaolo Abeni return PTR_ERR(ssk); 703c9406a23SFlorian Westphal } 704c9406a23SFlorian Westphal 705c9406a23SFlorian Westphal switch (optname) { 706c9406a23SFlorian Westphal case IP_FREEBIND: 7073f7e7532SEric Dumazet inet_assign_bit(FREEBIND, ssk, inet_test_bit(FREEBIND, sk)); 708c9406a23SFlorian Westphal break; 709c9406a23SFlorian Westphal case IP_TRANSPARENT: 7104bd0623fSEric Dumazet inet_assign_bit(TRANSPARENT, ssk, 7114bd0623fSEric Dumazet inet_test_bit(TRANSPARENT, sk)); 712c9406a23SFlorian Westphal break; 713c9406a23SFlorian Westphal default: 714c9406a23SFlorian Westphal release_sock(sk); 715c9406a23SFlorian Westphal WARN_ON_ONCE(1); 716c9406a23SFlorian Westphal return -EOPNOTSUPP; 717c9406a23SFlorian Westphal } 718c9406a23SFlorian Westphal 719c9406a23SFlorian Westphal sockopt_seq_inc(msk); 720c9406a23SFlorian Westphal release_sock(sk); 721c9406a23SFlorian Westphal return 0; 722c9406a23SFlorian Westphal } 723c9406a23SFlorian Westphal 724ffcacff8SPoorva Sonparote static int mptcp_setsockopt_v4_set_tos(struct mptcp_sock *msk, int optname, 725ffcacff8SPoorva Sonparote sockptr_t optval, unsigned int optlen) 726ffcacff8SPoorva Sonparote { 727ffcacff8SPoorva Sonparote struct mptcp_subflow_context *subflow; 728ffcacff8SPoorva Sonparote struct sock *sk = (struct sock *)msk; 729ffcacff8SPoorva Sonparote int err, val; 730ffcacff8SPoorva Sonparote 731ffcacff8SPoorva Sonparote err = ip_setsockopt(sk, SOL_IP, optname, optval, optlen); 732ffcacff8SPoorva Sonparote 733ffcacff8SPoorva Sonparote if (err != 0) 734ffcacff8SPoorva Sonparote return err; 735ffcacff8SPoorva Sonparote 736ffcacff8SPoorva Sonparote lock_sock(sk); 737ffcacff8SPoorva Sonparote sockopt_seq_inc(msk); 738e08d0b3dSEric Dumazet val = READ_ONCE(inet_sk(sk)->tos); 739ffcacff8SPoorva Sonparote mptcp_for_each_subflow(msk, subflow) { 740ffcacff8SPoorva Sonparote struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 741ffcacff8SPoorva Sonparote 742878d951cSEric Dumazet __ip_sock_set_tos(ssk, val); 743ffcacff8SPoorva Sonparote } 744ffcacff8SPoorva Sonparote release_sock(sk); 745ffcacff8SPoorva Sonparote 74603e7d28cSMatthieu Baerts return 0; 747ffcacff8SPoorva Sonparote } 748ffcacff8SPoorva Sonparote 749ffcacff8SPoorva Sonparote static int mptcp_setsockopt_v4(struct mptcp_sock *msk, int optname, 750ffcacff8SPoorva Sonparote sockptr_t optval, unsigned int optlen) 751ffcacff8SPoorva Sonparote { 752ffcacff8SPoorva Sonparote switch (optname) { 753c9406a23SFlorian Westphal case IP_FREEBIND: 754c9406a23SFlorian Westphal case IP_TRANSPARENT: 755c9406a23SFlorian Westphal return mptcp_setsockopt_sol_ip_set_transparent(msk, optname, optval, optlen); 756ffcacff8SPoorva Sonparote case IP_TOS: 757ffcacff8SPoorva Sonparote return mptcp_setsockopt_v4_set_tos(msk, optname, optval, optlen); 758ffcacff8SPoorva Sonparote } 759ffcacff8SPoorva Sonparote 760ffcacff8SPoorva Sonparote return -EOPNOTSUPP; 761ffcacff8SPoorva Sonparote } 762ffcacff8SPoorva Sonparote 763d3d42904SMatthieu Baerts static int mptcp_setsockopt_first_sf_only(struct mptcp_sock *msk, int level, int optname, 764d3d42904SMatthieu Baerts sockptr_t optval, unsigned int optlen) 76554635bd0SBenjamin Hesmans { 76621e43569SPaolo Abeni struct sock *sk = (struct sock *)msk; 7673f326a82SPaolo Abeni struct sock *ssk; 768ddb1a072SPaolo Abeni int ret; 76954635bd0SBenjamin Hesmans 770d3d42904SMatthieu Baerts /* Limit to first subflow, before the connection establishment */ 77121e43569SPaolo Abeni lock_sock(sk); 7723f326a82SPaolo Abeni ssk = __mptcp_nmpc_sk(msk); 7733f326a82SPaolo Abeni if (IS_ERR(ssk)) { 7743f326a82SPaolo Abeni ret = PTR_ERR(ssk); 77521e43569SPaolo Abeni goto unlock; 776ddb1a072SPaolo Abeni } 77754635bd0SBenjamin Hesmans 7783f326a82SPaolo Abeni ret = tcp_setsockopt(ssk, level, optname, optval, optlen); 77921e43569SPaolo Abeni 78021e43569SPaolo Abeni unlock: 78121e43569SPaolo Abeni release_sock(sk); 78221e43569SPaolo Abeni return ret; 78354635bd0SBenjamin Hesmans } 78454635bd0SBenjamin Hesmans 785aa1fbd94SFlorian Westphal static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname, 786aa1fbd94SFlorian Westphal sockptr_t optval, unsigned int optlen) 787aa1fbd94SFlorian Westphal { 7882c9e7765SFlorian Westphal struct sock *sk = (void *)msk; 7892c9e7765SFlorian Westphal int ret, val; 7902c9e7765SFlorian Westphal 791aa1fbd94SFlorian Westphal switch (optname) { 7922c9e7765SFlorian Westphal case TCP_INQ: 7932c9e7765SFlorian Westphal ret = mptcp_get_int_option(msk, optval, optlen, &val); 7942c9e7765SFlorian Westphal if (ret) 7952c9e7765SFlorian Westphal return ret; 7962c9e7765SFlorian Westphal if (val < 0 || val > 1) 7972c9e7765SFlorian Westphal return -EINVAL; 7982c9e7765SFlorian Westphal 7992c9e7765SFlorian Westphal lock_sock(sk); 8002c9e7765SFlorian Westphal msk->recvmsg_inq = !!val; 8012c9e7765SFlorian Westphal release_sock(sk); 8022c9e7765SFlorian Westphal return 0; 803aa1fbd94SFlorian Westphal case TCP_ULP: 804aa1fbd94SFlorian Westphal return -EOPNOTSUPP; 805aa1fbd94SFlorian Westphal case TCP_CONGESTION: 806aa1fbd94SFlorian Westphal return mptcp_setsockopt_sol_tcp_congestion(msk, optval, optlen); 8074f6e14bdSMaxim Galaganov case TCP_CORK: 8084f6e14bdSMaxim Galaganov return mptcp_setsockopt_sol_tcp_cork(msk, optval, optlen); 8094f6e14bdSMaxim Galaganov case TCP_NODELAY: 8104f6e14bdSMaxim Galaganov return mptcp_setsockopt_sol_tcp_nodelay(msk, optval, optlen); 811ea1e301dSFlorian Westphal case TCP_DEFER_ACCEPT: 812caea6467SMatthieu Baerts /* See tcp.c: TCP_DEFER_ACCEPT does not fail */ 813caea6467SMatthieu Baerts mptcp_setsockopt_first_sf_only(msk, SOL_TCP, optname, optval, optlen); 814caea6467SMatthieu Baerts return 0; 8154ffb0a02SDmytro Shytyi case TCP_FASTOPEN: 81654635bd0SBenjamin Hesmans case TCP_FASTOPEN_CONNECT: 817cb99816cSMatthieu Baerts case TCP_FASTOPEN_KEY: 818e64d4debSMatthieu Baerts case TCP_FASTOPEN_NO_COOKIE: 819d3d42904SMatthieu Baerts return mptcp_setsockopt_first_sf_only(msk, SOL_TCP, optname, 820d3d42904SMatthieu Baerts optval, optlen); 821aa1fbd94SFlorian Westphal } 822aa1fbd94SFlorian Westphal 823aa1fbd94SFlorian Westphal return -EOPNOTSUPP; 824aa1fbd94SFlorian Westphal } 825aa1fbd94SFlorian Westphal 8260abdde82SPaolo Abeni int mptcp_setsockopt(struct sock *sk, int level, int optname, 8270abdde82SPaolo Abeni sockptr_t optval, unsigned int optlen) 8280abdde82SPaolo Abeni { 8290abdde82SPaolo Abeni struct mptcp_sock *msk = mptcp_sk(sk); 8300abdde82SPaolo Abeni struct sock *ssk; 8310abdde82SPaolo Abeni 8320abdde82SPaolo Abeni pr_debug("msk=%p", msk); 8330abdde82SPaolo Abeni 8340abdde82SPaolo Abeni if (level == SOL_SOCKET) 8350abdde82SPaolo Abeni return mptcp_setsockopt_sol_socket(msk, optname, optval, optlen); 8360abdde82SPaolo Abeni 8377a009a70SFlorian Westphal if (!mptcp_supported_sockopt(level, optname)) 8387a009a70SFlorian Westphal return -ENOPROTOOPT; 8397a009a70SFlorian Westphal 8400abdde82SPaolo Abeni /* @@ the meaning of setsockopt() when the socket is connected and 8410abdde82SPaolo Abeni * there are multiple subflows is not yet defined. It is up to the 8420abdde82SPaolo Abeni * MPTCP-level socket to configure the subflows until the subflow 8430abdde82SPaolo Abeni * is in TCP fallback, when TCP socket options are passed through 8440abdde82SPaolo Abeni * to the one remaining subflow. 8450abdde82SPaolo Abeni */ 8460abdde82SPaolo Abeni lock_sock(sk); 8470abdde82SPaolo Abeni ssk = __mptcp_tcp_fallback(msk); 8480abdde82SPaolo Abeni release_sock(sk); 8490abdde82SPaolo Abeni if (ssk) 8500abdde82SPaolo Abeni return tcp_setsockopt(ssk, level, optname, optval, optlen); 8510abdde82SPaolo Abeni 852ffcacff8SPoorva Sonparote if (level == SOL_IP) 853ffcacff8SPoorva Sonparote return mptcp_setsockopt_v4(msk, optname, optval, optlen); 854ffcacff8SPoorva Sonparote 8550abdde82SPaolo Abeni if (level == SOL_IPV6) 8560abdde82SPaolo Abeni return mptcp_setsockopt_v6(msk, optname, optval, optlen); 8570abdde82SPaolo Abeni 858aa1fbd94SFlorian Westphal if (level == SOL_TCP) 859aa1fbd94SFlorian Westphal return mptcp_setsockopt_sol_tcp(msk, optname, optval, optlen); 860aa1fbd94SFlorian Westphal 861aa1fbd94SFlorian Westphal return -EOPNOTSUPP; 862aa1fbd94SFlorian Westphal } 863aa1fbd94SFlorian Westphal 864aa1fbd94SFlorian Westphal static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int optname, 865aa1fbd94SFlorian Westphal char __user *optval, int __user *optlen) 866aa1fbd94SFlorian Westphal { 867aa1fbd94SFlorian Westphal struct sock *sk = (struct sock *)msk; 868aa1fbd94SFlorian Westphal struct sock *ssk; 869f0bc514bSPaolo Abeni int ret; 870aa1fbd94SFlorian Westphal 871aa1fbd94SFlorian Westphal lock_sock(sk); 872aa1fbd94SFlorian Westphal ssk = msk->first; 873aa1fbd94SFlorian Westphal if (ssk) { 874aa1fbd94SFlorian Westphal ret = tcp_getsockopt(ssk, level, optname, optval, optlen); 875aa1fbd94SFlorian Westphal goto out; 876aa1fbd94SFlorian Westphal } 877aa1fbd94SFlorian Westphal 8783f326a82SPaolo Abeni ssk = __mptcp_nmpc_sk(msk); 8793f326a82SPaolo Abeni if (IS_ERR(ssk)) { 8803f326a82SPaolo Abeni ret = PTR_ERR(ssk); 881aa1fbd94SFlorian Westphal goto out; 882ddb1a072SPaolo Abeni } 883aa1fbd94SFlorian Westphal 884f0bc514bSPaolo Abeni ret = tcp_getsockopt(ssk, level, optname, optval, optlen); 885aa1fbd94SFlorian Westphal 886aa1fbd94SFlorian Westphal out: 887aa1fbd94SFlorian Westphal release_sock(sk); 888aa1fbd94SFlorian Westphal return ret; 889aa1fbd94SFlorian Westphal } 890aa1fbd94SFlorian Westphal 89161bc6e82SFlorian Westphal void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info) 89261bc6e82SFlorian Westphal { 89338967f42SPaolo Abeni struct sock *sk = (struct sock *)msk; 89461bc6e82SFlorian Westphal u32 flags = 0; 89538967f42SPaolo Abeni bool slow; 89661bc6e82SFlorian Westphal 89755c42fa7SFlorian Westphal memset(info, 0, sizeof(*info)); 89855c42fa7SFlorian Westphal 89961bc6e82SFlorian Westphal info->mptcpi_subflows = READ_ONCE(msk->pm.subflows); 90061bc6e82SFlorian Westphal info->mptcpi_add_addr_signal = READ_ONCE(msk->pm.add_addr_signaled); 90161bc6e82SFlorian Westphal info->mptcpi_add_addr_accepted = READ_ONCE(msk->pm.add_addr_accepted); 90261bc6e82SFlorian Westphal info->mptcpi_local_addr_used = READ_ONCE(msk->pm.local_addr_used); 903e925a032SMatthieu Baerts 90438967f42SPaolo Abeni if (inet_sk_state_load(sk) == TCP_LISTEN) 90538967f42SPaolo Abeni return; 90638967f42SPaolo Abeni 907e925a032SMatthieu Baerts /* The following limits only make sense for the in-kernel PM */ 908e925a032SMatthieu Baerts if (mptcp_pm_is_kernel(msk)) { 909e925a032SMatthieu Baerts info->mptcpi_subflows_max = 910e925a032SMatthieu Baerts mptcp_pm_get_subflows_max(msk); 911e925a032SMatthieu Baerts info->mptcpi_add_addr_signal_max = 912e925a032SMatthieu Baerts mptcp_pm_get_add_addr_signal_max(msk); 913e925a032SMatthieu Baerts info->mptcpi_add_addr_accepted_max = 914e925a032SMatthieu Baerts mptcp_pm_get_add_addr_accept_max(msk); 915e925a032SMatthieu Baerts info->mptcpi_local_addr_max = 916e925a032SMatthieu Baerts mptcp_pm_get_local_addr_max(msk); 917e925a032SMatthieu Baerts } 918e925a032SMatthieu Baerts 919*83d580ddSGeliang Tang if (__mptcp_check_fallback(msk)) 92061bc6e82SFlorian Westphal flags |= MPTCP_INFO_FLAG_FALLBACK; 92161bc6e82SFlorian Westphal if (READ_ONCE(msk->can_ack)) 92261bc6e82SFlorian Westphal flags |= MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED; 92361bc6e82SFlorian Westphal info->mptcpi_flags = flags; 92438967f42SPaolo Abeni mptcp_data_lock(sk); 92538967f42SPaolo Abeni info->mptcpi_snd_una = msk->snd_una; 92638967f42SPaolo Abeni info->mptcpi_rcv_nxt = msk->ack_seq; 92738967f42SPaolo Abeni info->mptcpi_bytes_acked = msk->bytes_acked; 92838967f42SPaolo Abeni mptcp_data_unlock(sk); 92938967f42SPaolo Abeni 93038967f42SPaolo Abeni slow = lock_sock_fast(sk); 93138967f42SPaolo Abeni info->mptcpi_csum_enabled = msk->csum_enabled; 93238967f42SPaolo Abeni info->mptcpi_token = msk->token; 93338967f42SPaolo Abeni info->mptcpi_write_seq = msk->write_seq; 93438967f42SPaolo Abeni info->mptcpi_retransmits = inet_csk(sk)->icsk_retransmits; 93538967f42SPaolo Abeni info->mptcpi_bytes_sent = msk->bytes_sent; 93638967f42SPaolo Abeni info->mptcpi_bytes_received = msk->bytes_received; 93738967f42SPaolo Abeni info->mptcpi_bytes_retrans = msk->bytes_retrans; 93838967f42SPaolo Abeni unlock_sock_fast(sk, slow); 93961bc6e82SFlorian Westphal } 94061bc6e82SFlorian Westphal EXPORT_SYMBOL_GPL(mptcp_diag_fill_info); 94161bc6e82SFlorian Westphal 94255c42fa7SFlorian Westphal static int mptcp_getsockopt_info(struct mptcp_sock *msk, char __user *optval, int __user *optlen) 94355c42fa7SFlorian Westphal { 94455c42fa7SFlorian Westphal struct mptcp_info m_info; 94555c42fa7SFlorian Westphal int len; 94655c42fa7SFlorian Westphal 94755c42fa7SFlorian Westphal if (get_user(len, optlen)) 94855c42fa7SFlorian Westphal return -EFAULT; 94955c42fa7SFlorian Westphal 95055c42fa7SFlorian Westphal len = min_t(unsigned int, len, sizeof(struct mptcp_info)); 95155c42fa7SFlorian Westphal 95255c42fa7SFlorian Westphal mptcp_diag_fill_info(msk, &m_info); 95355c42fa7SFlorian Westphal 95455c42fa7SFlorian Westphal if (put_user(len, optlen)) 95555c42fa7SFlorian Westphal return -EFAULT; 95655c42fa7SFlorian Westphal 95755c42fa7SFlorian Westphal if (copy_to_user(optval, &m_info, len)) 95855c42fa7SFlorian Westphal return -EFAULT; 95955c42fa7SFlorian Westphal 96055c42fa7SFlorian Westphal return 0; 96155c42fa7SFlorian Westphal } 96255c42fa7SFlorian Westphal 96306f15ceeSFlorian Westphal static int mptcp_put_subflow_data(struct mptcp_subflow_data *sfd, 96406f15ceeSFlorian Westphal char __user *optval, 96506f15ceeSFlorian Westphal u32 copied, 96606f15ceeSFlorian Westphal int __user *optlen) 96706f15ceeSFlorian Westphal { 96806f15ceeSFlorian Westphal u32 copylen = min_t(u32, sfd->size_subflow_data, sizeof(*sfd)); 96906f15ceeSFlorian Westphal 97006f15ceeSFlorian Westphal if (copied) 97106f15ceeSFlorian Westphal copied += sfd->size_subflow_data; 97206f15ceeSFlorian Westphal else 97306f15ceeSFlorian Westphal copied = copylen; 97406f15ceeSFlorian Westphal 97506f15ceeSFlorian Westphal if (put_user(copied, optlen)) 97606f15ceeSFlorian Westphal return -EFAULT; 97706f15ceeSFlorian Westphal 97806f15ceeSFlorian Westphal if (copy_to_user(optval, sfd, copylen)) 97906f15ceeSFlorian Westphal return -EFAULT; 98006f15ceeSFlorian Westphal 98106f15ceeSFlorian Westphal return 0; 98206f15ceeSFlorian Westphal } 98306f15ceeSFlorian Westphal 98406f15ceeSFlorian Westphal static int mptcp_get_subflow_data(struct mptcp_subflow_data *sfd, 98549243207SPaolo Abeni char __user *optval, 98649243207SPaolo Abeni int __user *optlen) 98706f15ceeSFlorian Westphal { 98806f15ceeSFlorian Westphal int len, copylen; 98906f15ceeSFlorian Westphal 99006f15ceeSFlorian Westphal if (get_user(len, optlen)) 99106f15ceeSFlorian Westphal return -EFAULT; 99206f15ceeSFlorian Westphal 99306f15ceeSFlorian Westphal /* if mptcp_subflow_data size is changed, need to adjust 99406f15ceeSFlorian Westphal * this function to deal with programs using old version. 99506f15ceeSFlorian Westphal */ 99606f15ceeSFlorian Westphal BUILD_BUG_ON(sizeof(*sfd) != MIN_INFO_OPTLEN_SIZE); 99706f15ceeSFlorian Westphal 99806f15ceeSFlorian Westphal if (len < MIN_INFO_OPTLEN_SIZE) 99906f15ceeSFlorian Westphal return -EINVAL; 100006f15ceeSFlorian Westphal 100106f15ceeSFlorian Westphal memset(sfd, 0, sizeof(*sfd)); 100206f15ceeSFlorian Westphal 100306f15ceeSFlorian Westphal copylen = min_t(unsigned int, len, sizeof(*sfd)); 100406f15ceeSFlorian Westphal if (copy_from_user(sfd, optval, copylen)) 100506f15ceeSFlorian Westphal return -EFAULT; 100606f15ceeSFlorian Westphal 100706f15ceeSFlorian Westphal /* size_subflow_data is u32, but len is signed */ 100806f15ceeSFlorian Westphal if (sfd->size_subflow_data > INT_MAX || 100906f15ceeSFlorian Westphal sfd->size_user > INT_MAX) 101006f15ceeSFlorian Westphal return -EINVAL; 101106f15ceeSFlorian Westphal 101206f15ceeSFlorian Westphal if (sfd->size_subflow_data < MIN_INFO_OPTLEN_SIZE || 101306f15ceeSFlorian Westphal sfd->size_subflow_data > len) 101406f15ceeSFlorian Westphal return -EINVAL; 101506f15ceeSFlorian Westphal 101606f15ceeSFlorian Westphal if (sfd->num_subflows || sfd->size_kernel) 101706f15ceeSFlorian Westphal return -EINVAL; 101806f15ceeSFlorian Westphal 101906f15ceeSFlorian Westphal return len - sfd->size_subflow_data; 102006f15ceeSFlorian Westphal } 102106f15ceeSFlorian Westphal 102206f15ceeSFlorian Westphal static int mptcp_getsockopt_tcpinfo(struct mptcp_sock *msk, char __user *optval, 102306f15ceeSFlorian Westphal int __user *optlen) 102406f15ceeSFlorian Westphal { 102506f15ceeSFlorian Westphal struct mptcp_subflow_context *subflow; 102680638684SGeliang Tang struct sock *sk = (struct sock *)msk; 102706f15ceeSFlorian Westphal unsigned int sfcount = 0, copied = 0; 102806f15ceeSFlorian Westphal struct mptcp_subflow_data sfd; 102906f15ceeSFlorian Westphal char __user *infoptr; 103006f15ceeSFlorian Westphal int len; 103106f15ceeSFlorian Westphal 103206f15ceeSFlorian Westphal len = mptcp_get_subflow_data(&sfd, optval, optlen); 103306f15ceeSFlorian Westphal if (len < 0) 103406f15ceeSFlorian Westphal return len; 103506f15ceeSFlorian Westphal 103606f15ceeSFlorian Westphal sfd.size_kernel = sizeof(struct tcp_info); 103706f15ceeSFlorian Westphal sfd.size_user = min_t(unsigned int, sfd.size_user, 103806f15ceeSFlorian Westphal sizeof(struct tcp_info)); 103906f15ceeSFlorian Westphal 104006f15ceeSFlorian Westphal infoptr = optval + sfd.size_subflow_data; 104106f15ceeSFlorian Westphal 104206f15ceeSFlorian Westphal lock_sock(sk); 104306f15ceeSFlorian Westphal 104406f15ceeSFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 104506f15ceeSFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 104606f15ceeSFlorian Westphal 104706f15ceeSFlorian Westphal ++sfcount; 104806f15ceeSFlorian Westphal 104906f15ceeSFlorian Westphal if (len && len >= sfd.size_user) { 105006f15ceeSFlorian Westphal struct tcp_info info; 105106f15ceeSFlorian Westphal 105206f15ceeSFlorian Westphal tcp_get_info(ssk, &info); 105306f15ceeSFlorian Westphal 105406f15ceeSFlorian Westphal if (copy_to_user(infoptr, &info, sfd.size_user)) { 105506f15ceeSFlorian Westphal release_sock(sk); 105606f15ceeSFlorian Westphal return -EFAULT; 105706f15ceeSFlorian Westphal } 105806f15ceeSFlorian Westphal 105906f15ceeSFlorian Westphal infoptr += sfd.size_user; 106006f15ceeSFlorian Westphal copied += sfd.size_user; 106106f15ceeSFlorian Westphal len -= sfd.size_user; 106206f15ceeSFlorian Westphal } 106306f15ceeSFlorian Westphal } 106406f15ceeSFlorian Westphal 106506f15ceeSFlorian Westphal release_sock(sk); 106606f15ceeSFlorian Westphal 106706f15ceeSFlorian Westphal sfd.num_subflows = sfcount; 106806f15ceeSFlorian Westphal 106906f15ceeSFlorian Westphal if (mptcp_put_subflow_data(&sfd, optval, copied, optlen)) 107006f15ceeSFlorian Westphal return -EFAULT; 107106f15ceeSFlorian Westphal 107206f15ceeSFlorian Westphal return 0; 107306f15ceeSFlorian Westphal } 107406f15ceeSFlorian Westphal 1075c11c5906SFlorian Westphal static void mptcp_get_sub_addrs(const struct sock *sk, struct mptcp_subflow_addrs *a) 1076c11c5906SFlorian Westphal { 1077abc17a11SEric Dumazet const struct inet_sock *inet = inet_sk(sk); 1078c11c5906SFlorian Westphal 1079c11c5906SFlorian Westphal memset(a, 0, sizeof(*a)); 1080c11c5906SFlorian Westphal 1081c11c5906SFlorian Westphal if (sk->sk_family == AF_INET) { 1082c11c5906SFlorian Westphal a->sin_local.sin_family = AF_INET; 1083c11c5906SFlorian Westphal a->sin_local.sin_port = inet->inet_sport; 1084c11c5906SFlorian Westphal a->sin_local.sin_addr.s_addr = inet->inet_rcv_saddr; 1085c11c5906SFlorian Westphal 1086c11c5906SFlorian Westphal if (!a->sin_local.sin_addr.s_addr) 1087c11c5906SFlorian Westphal a->sin_local.sin_addr.s_addr = inet->inet_saddr; 1088c11c5906SFlorian Westphal 1089c11c5906SFlorian Westphal a->sin_remote.sin_family = AF_INET; 1090c11c5906SFlorian Westphal a->sin_remote.sin_port = inet->inet_dport; 1091c11c5906SFlorian Westphal a->sin_remote.sin_addr.s_addr = inet->inet_daddr; 1092c11c5906SFlorian Westphal #if IS_ENABLED(CONFIG_IPV6) 1093c11c5906SFlorian Westphal } else if (sk->sk_family == AF_INET6) { 1094c11c5906SFlorian Westphal const struct ipv6_pinfo *np = inet6_sk(sk); 1095c11c5906SFlorian Westphal 109629211e7dSTim Gardner if (WARN_ON_ONCE(!np)) 109729211e7dSTim Gardner return; 109829211e7dSTim Gardner 1099c11c5906SFlorian Westphal a->sin6_local.sin6_family = AF_INET6; 1100c11c5906SFlorian Westphal a->sin6_local.sin6_port = inet->inet_sport; 1101c11c5906SFlorian Westphal 1102c11c5906SFlorian Westphal if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) 1103c11c5906SFlorian Westphal a->sin6_local.sin6_addr = np->saddr; 1104c11c5906SFlorian Westphal else 1105c11c5906SFlorian Westphal a->sin6_local.sin6_addr = sk->sk_v6_rcv_saddr; 1106c11c5906SFlorian Westphal 1107c11c5906SFlorian Westphal a->sin6_remote.sin6_family = AF_INET6; 1108c11c5906SFlorian Westphal a->sin6_remote.sin6_port = inet->inet_dport; 1109c11c5906SFlorian Westphal a->sin6_remote.sin6_addr = sk->sk_v6_daddr; 1110c11c5906SFlorian Westphal #endif 1111c11c5906SFlorian Westphal } 1112c11c5906SFlorian Westphal } 1113c11c5906SFlorian Westphal 1114c11c5906SFlorian Westphal static int mptcp_getsockopt_subflow_addrs(struct mptcp_sock *msk, char __user *optval, 1115c11c5906SFlorian Westphal int __user *optlen) 1116c11c5906SFlorian Westphal { 1117c11c5906SFlorian Westphal struct mptcp_subflow_context *subflow; 111880638684SGeliang Tang struct sock *sk = (struct sock *)msk; 1119c11c5906SFlorian Westphal unsigned int sfcount = 0, copied = 0; 1120c11c5906SFlorian Westphal struct mptcp_subflow_data sfd; 1121c11c5906SFlorian Westphal char __user *addrptr; 1122c11c5906SFlorian Westphal int len; 1123c11c5906SFlorian Westphal 1124c11c5906SFlorian Westphal len = mptcp_get_subflow_data(&sfd, optval, optlen); 1125c11c5906SFlorian Westphal if (len < 0) 1126c11c5906SFlorian Westphal return len; 1127c11c5906SFlorian Westphal 1128c11c5906SFlorian Westphal sfd.size_kernel = sizeof(struct mptcp_subflow_addrs); 1129c11c5906SFlorian Westphal sfd.size_user = min_t(unsigned int, sfd.size_user, 1130c11c5906SFlorian Westphal sizeof(struct mptcp_subflow_addrs)); 1131c11c5906SFlorian Westphal 1132c11c5906SFlorian Westphal addrptr = optval + sfd.size_subflow_data; 1133c11c5906SFlorian Westphal 1134c11c5906SFlorian Westphal lock_sock(sk); 1135c11c5906SFlorian Westphal 1136c11c5906SFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 1137c11c5906SFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 1138c11c5906SFlorian Westphal 1139c11c5906SFlorian Westphal ++sfcount; 1140c11c5906SFlorian Westphal 1141c11c5906SFlorian Westphal if (len && len >= sfd.size_user) { 1142c11c5906SFlorian Westphal struct mptcp_subflow_addrs a; 1143c11c5906SFlorian Westphal 1144c11c5906SFlorian Westphal mptcp_get_sub_addrs(ssk, &a); 1145c11c5906SFlorian Westphal 1146c11c5906SFlorian Westphal if (copy_to_user(addrptr, &a, sfd.size_user)) { 1147c11c5906SFlorian Westphal release_sock(sk); 1148c11c5906SFlorian Westphal return -EFAULT; 1149c11c5906SFlorian Westphal } 1150c11c5906SFlorian Westphal 1151c11c5906SFlorian Westphal addrptr += sfd.size_user; 1152c11c5906SFlorian Westphal copied += sfd.size_user; 1153c11c5906SFlorian Westphal len -= sfd.size_user; 1154c11c5906SFlorian Westphal } 1155c11c5906SFlorian Westphal } 1156c11c5906SFlorian Westphal 1157c11c5906SFlorian Westphal release_sock(sk); 1158c11c5906SFlorian Westphal 1159c11c5906SFlorian Westphal sfd.num_subflows = sfcount; 1160c11c5906SFlorian Westphal 1161c11c5906SFlorian Westphal if (mptcp_put_subflow_data(&sfd, optval, copied, optlen)) 1162c11c5906SFlorian Westphal return -EFAULT; 1163c11c5906SFlorian Westphal 1164c11c5906SFlorian Westphal return 0; 1165c11c5906SFlorian Westphal } 1166c11c5906SFlorian Westphal 116749243207SPaolo Abeni static int mptcp_get_full_info(struct mptcp_full_info *mfi, 116849243207SPaolo Abeni char __user *optval, 116949243207SPaolo Abeni int __user *optlen) 117049243207SPaolo Abeni { 117149243207SPaolo Abeni int len; 117249243207SPaolo Abeni 117349243207SPaolo Abeni BUILD_BUG_ON(offsetof(struct mptcp_full_info, mptcp_info) != 117449243207SPaolo Abeni MIN_FULL_INFO_OPTLEN_SIZE); 117549243207SPaolo Abeni 117649243207SPaolo Abeni if (get_user(len, optlen)) 117749243207SPaolo Abeni return -EFAULT; 117849243207SPaolo Abeni 117949243207SPaolo Abeni if (len < MIN_FULL_INFO_OPTLEN_SIZE) 118049243207SPaolo Abeni return -EINVAL; 118149243207SPaolo Abeni 118249243207SPaolo Abeni memset(mfi, 0, sizeof(*mfi)); 118349243207SPaolo Abeni if (copy_from_user(mfi, optval, MIN_FULL_INFO_OPTLEN_SIZE)) 118449243207SPaolo Abeni return -EFAULT; 118549243207SPaolo Abeni 118649243207SPaolo Abeni if (mfi->size_tcpinfo_kernel || 118749243207SPaolo Abeni mfi->size_sfinfo_kernel || 118849243207SPaolo Abeni mfi->num_subflows) 118949243207SPaolo Abeni return -EINVAL; 119049243207SPaolo Abeni 119149243207SPaolo Abeni if (mfi->size_sfinfo_user > INT_MAX || 119249243207SPaolo Abeni mfi->size_tcpinfo_user > INT_MAX) 119349243207SPaolo Abeni return -EINVAL; 119449243207SPaolo Abeni 119549243207SPaolo Abeni return len - MIN_FULL_INFO_OPTLEN_SIZE; 119649243207SPaolo Abeni } 119749243207SPaolo Abeni 119849243207SPaolo Abeni static int mptcp_put_full_info(struct mptcp_full_info *mfi, 119949243207SPaolo Abeni char __user *optval, 120049243207SPaolo Abeni u32 copylen, 120149243207SPaolo Abeni int __user *optlen) 120249243207SPaolo Abeni { 120349243207SPaolo Abeni copylen += MIN_FULL_INFO_OPTLEN_SIZE; 120449243207SPaolo Abeni if (put_user(copylen, optlen)) 120549243207SPaolo Abeni return -EFAULT; 120649243207SPaolo Abeni 120749243207SPaolo Abeni if (copy_to_user(optval, mfi, copylen)) 120849243207SPaolo Abeni return -EFAULT; 120949243207SPaolo Abeni return 0; 121049243207SPaolo Abeni } 121149243207SPaolo Abeni 121249243207SPaolo Abeni static int mptcp_getsockopt_full_info(struct mptcp_sock *msk, char __user *optval, 121349243207SPaolo Abeni int __user *optlen) 121449243207SPaolo Abeni { 121549243207SPaolo Abeni unsigned int sfcount = 0, copylen = 0; 121649243207SPaolo Abeni struct mptcp_subflow_context *subflow; 121749243207SPaolo Abeni struct sock *sk = (struct sock *)msk; 121849243207SPaolo Abeni void __user *tcpinfoptr, *sfinfoptr; 121949243207SPaolo Abeni struct mptcp_full_info mfi; 122049243207SPaolo Abeni int len; 122149243207SPaolo Abeni 122249243207SPaolo Abeni len = mptcp_get_full_info(&mfi, optval, optlen); 122349243207SPaolo Abeni if (len < 0) 122449243207SPaolo Abeni return len; 122549243207SPaolo Abeni 122649243207SPaolo Abeni /* don't bother filling the mptcp info if there is not enough 122749243207SPaolo Abeni * user-space-provided storage 122849243207SPaolo Abeni */ 122949243207SPaolo Abeni if (len > 0) { 123049243207SPaolo Abeni mptcp_diag_fill_info(msk, &mfi.mptcp_info); 123149243207SPaolo Abeni copylen += min_t(unsigned int, len, sizeof(struct mptcp_info)); 123249243207SPaolo Abeni } 123349243207SPaolo Abeni 123449243207SPaolo Abeni mfi.size_tcpinfo_kernel = sizeof(struct tcp_info); 123549243207SPaolo Abeni mfi.size_tcpinfo_user = min_t(unsigned int, mfi.size_tcpinfo_user, 123649243207SPaolo Abeni sizeof(struct tcp_info)); 123749243207SPaolo Abeni sfinfoptr = u64_to_user_ptr(mfi.subflow_info); 123849243207SPaolo Abeni mfi.size_sfinfo_kernel = sizeof(struct mptcp_subflow_info); 123949243207SPaolo Abeni mfi.size_sfinfo_user = min_t(unsigned int, mfi.size_sfinfo_user, 124049243207SPaolo Abeni sizeof(struct mptcp_subflow_info)); 124149243207SPaolo Abeni tcpinfoptr = u64_to_user_ptr(mfi.tcp_info); 124249243207SPaolo Abeni 124349243207SPaolo Abeni lock_sock(sk); 124449243207SPaolo Abeni mptcp_for_each_subflow(msk, subflow) { 124549243207SPaolo Abeni struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 124649243207SPaolo Abeni struct mptcp_subflow_info sfinfo; 124749243207SPaolo Abeni struct tcp_info tcp_info; 124849243207SPaolo Abeni 124949243207SPaolo Abeni if (sfcount++ >= mfi.size_arrays_user) 125049243207SPaolo Abeni continue; 125149243207SPaolo Abeni 125249243207SPaolo Abeni /* fetch addr/tcp_info only if the user space buffers 125349243207SPaolo Abeni * are wide enough 125449243207SPaolo Abeni */ 125549243207SPaolo Abeni memset(&sfinfo, 0, sizeof(sfinfo)); 125649243207SPaolo Abeni sfinfo.id = subflow->subflow_id; 125749243207SPaolo Abeni if (mfi.size_sfinfo_user > 125849243207SPaolo Abeni offsetof(struct mptcp_subflow_info, addrs)) 125949243207SPaolo Abeni mptcp_get_sub_addrs(ssk, &sfinfo.addrs); 126049243207SPaolo Abeni if (copy_to_user(sfinfoptr, &sfinfo, mfi.size_sfinfo_user)) 126149243207SPaolo Abeni goto fail_release; 126249243207SPaolo Abeni 126349243207SPaolo Abeni if (mfi.size_tcpinfo_user) { 126449243207SPaolo Abeni tcp_get_info(ssk, &tcp_info); 126549243207SPaolo Abeni if (copy_to_user(tcpinfoptr, &tcp_info, 126649243207SPaolo Abeni mfi.size_tcpinfo_user)) 126749243207SPaolo Abeni goto fail_release; 126849243207SPaolo Abeni } 126949243207SPaolo Abeni 127049243207SPaolo Abeni tcpinfoptr += mfi.size_tcpinfo_user; 127149243207SPaolo Abeni sfinfoptr += mfi.size_sfinfo_user; 127249243207SPaolo Abeni } 127349243207SPaolo Abeni release_sock(sk); 127449243207SPaolo Abeni 127549243207SPaolo Abeni mfi.num_subflows = sfcount; 127649243207SPaolo Abeni if (mptcp_put_full_info(&mfi, optval, copylen, optlen)) 127749243207SPaolo Abeni return -EFAULT; 127849243207SPaolo Abeni 127949243207SPaolo Abeni return 0; 128049243207SPaolo Abeni 128149243207SPaolo Abeni fail_release: 128249243207SPaolo Abeni release_sock(sk); 128349243207SPaolo Abeni return -EFAULT; 128449243207SPaolo Abeni } 128549243207SPaolo Abeni 12862c9e7765SFlorian Westphal static int mptcp_put_int_option(struct mptcp_sock *msk, char __user *optval, 12872c9e7765SFlorian Westphal int __user *optlen, int val) 12882c9e7765SFlorian Westphal { 12892c9e7765SFlorian Westphal int len; 12902c9e7765SFlorian Westphal 12912c9e7765SFlorian Westphal if (get_user(len, optlen)) 12922c9e7765SFlorian Westphal return -EFAULT; 12932c9e7765SFlorian Westphal if (len < 0) 12942c9e7765SFlorian Westphal return -EINVAL; 12952c9e7765SFlorian Westphal 12963b1e21ebSFlorian Westphal if (len < sizeof(int) && len > 0 && val >= 0 && val <= 255) { 12973b1e21ebSFlorian Westphal unsigned char ucval = (unsigned char)val; 12983b1e21ebSFlorian Westphal 12993b1e21ebSFlorian Westphal len = 1; 13003b1e21ebSFlorian Westphal if (put_user(len, optlen)) 13013b1e21ebSFlorian Westphal return -EFAULT; 13023b1e21ebSFlorian Westphal if (copy_to_user(optval, &ucval, 1)) 13033b1e21ebSFlorian Westphal return -EFAULT; 13043b1e21ebSFlorian Westphal } else { 13053b1e21ebSFlorian Westphal len = min_t(unsigned int, len, sizeof(int)); 13062c9e7765SFlorian Westphal if (put_user(len, optlen)) 13072c9e7765SFlorian Westphal return -EFAULT; 13082c9e7765SFlorian Westphal if (copy_to_user(optval, &val, len)) 13092c9e7765SFlorian Westphal return -EFAULT; 13103b1e21ebSFlorian Westphal } 13112c9e7765SFlorian Westphal 13122c9e7765SFlorian Westphal return 0; 13132c9e7765SFlorian Westphal } 13142c9e7765SFlorian Westphal 1315aa1fbd94SFlorian Westphal static int mptcp_getsockopt_sol_tcp(struct mptcp_sock *msk, int optname, 1316aa1fbd94SFlorian Westphal char __user *optval, int __user *optlen) 1317aa1fbd94SFlorian Westphal { 1318aa1fbd94SFlorian Westphal switch (optname) { 1319aa1fbd94SFlorian Westphal case TCP_ULP: 1320aa1fbd94SFlorian Westphal case TCP_CONGESTION: 1321aa1fbd94SFlorian Westphal case TCP_INFO: 1322aa1fbd94SFlorian Westphal case TCP_CC_INFO: 1323ea1e301dSFlorian Westphal case TCP_DEFER_ACCEPT: 13244ffb0a02SDmytro Shytyi case TCP_FASTOPEN: 132554635bd0SBenjamin Hesmans case TCP_FASTOPEN_CONNECT: 1326cb99816cSMatthieu Baerts case TCP_FASTOPEN_KEY: 1327e64d4debSMatthieu Baerts case TCP_FASTOPEN_NO_COOKIE: 1328aa1fbd94SFlorian Westphal return mptcp_getsockopt_first_sf_only(msk, SOL_TCP, optname, 1329aa1fbd94SFlorian Westphal optval, optlen); 13302c9e7765SFlorian Westphal case TCP_INQ: 13312c9e7765SFlorian Westphal return mptcp_put_int_option(msk, optval, optlen, msk->recvmsg_inq); 13324f6e14bdSMaxim Galaganov case TCP_CORK: 13334f6e14bdSMaxim Galaganov return mptcp_put_int_option(msk, optval, optlen, msk->cork); 13344f6e14bdSMaxim Galaganov case TCP_NODELAY: 13354f6e14bdSMaxim Galaganov return mptcp_put_int_option(msk, optval, optlen, msk->nodelay); 1336aa1fbd94SFlorian Westphal } 13370abdde82SPaolo Abeni return -EOPNOTSUPP; 13380abdde82SPaolo Abeni } 13390abdde82SPaolo Abeni 13403b1e21ebSFlorian Westphal static int mptcp_getsockopt_v4(struct mptcp_sock *msk, int optname, 13413b1e21ebSFlorian Westphal char __user *optval, int __user *optlen) 13423b1e21ebSFlorian Westphal { 13433b1e21ebSFlorian Westphal struct sock *sk = (void *)msk; 13443b1e21ebSFlorian Westphal 13453b1e21ebSFlorian Westphal switch (optname) { 13463b1e21ebSFlorian Westphal case IP_TOS: 1347e08d0b3dSEric Dumazet return mptcp_put_int_option(msk, optval, optlen, READ_ONCE(inet_sk(sk)->tos)); 13483b1e21ebSFlorian Westphal } 13493b1e21ebSFlorian Westphal 13503b1e21ebSFlorian Westphal return -EOPNOTSUPP; 13513b1e21ebSFlorian Westphal } 13523b1e21ebSFlorian Westphal 135355c42fa7SFlorian Westphal static int mptcp_getsockopt_sol_mptcp(struct mptcp_sock *msk, int optname, 135455c42fa7SFlorian Westphal char __user *optval, int __user *optlen) 135555c42fa7SFlorian Westphal { 135655c42fa7SFlorian Westphal switch (optname) { 135755c42fa7SFlorian Westphal case MPTCP_INFO: 135855c42fa7SFlorian Westphal return mptcp_getsockopt_info(msk, optval, optlen); 135949243207SPaolo Abeni case MPTCP_FULL_INFO: 136049243207SPaolo Abeni return mptcp_getsockopt_full_info(msk, optval, optlen); 136106f15ceeSFlorian Westphal case MPTCP_TCPINFO: 136206f15ceeSFlorian Westphal return mptcp_getsockopt_tcpinfo(msk, optval, optlen); 1363c11c5906SFlorian Westphal case MPTCP_SUBFLOW_ADDRS: 1364c11c5906SFlorian Westphal return mptcp_getsockopt_subflow_addrs(msk, optval, optlen); 136555c42fa7SFlorian Westphal } 136655c42fa7SFlorian Westphal 136755c42fa7SFlorian Westphal return -EOPNOTSUPP; 136855c42fa7SFlorian Westphal } 136955c42fa7SFlorian Westphal 13700abdde82SPaolo Abeni int mptcp_getsockopt(struct sock *sk, int level, int optname, 13710abdde82SPaolo Abeni char __user *optval, int __user *option) 13720abdde82SPaolo Abeni { 13730abdde82SPaolo Abeni struct mptcp_sock *msk = mptcp_sk(sk); 13740abdde82SPaolo Abeni struct sock *ssk; 13750abdde82SPaolo Abeni 13760abdde82SPaolo Abeni pr_debug("msk=%p", msk); 13770abdde82SPaolo Abeni 13780abdde82SPaolo Abeni /* @@ the meaning of setsockopt() when the socket is connected and 13790abdde82SPaolo Abeni * there are multiple subflows is not yet defined. It is up to the 13800abdde82SPaolo Abeni * MPTCP-level socket to configure the subflows until the subflow 13810abdde82SPaolo Abeni * is in TCP fallback, when socket options are passed through 13820abdde82SPaolo Abeni * to the one remaining subflow. 13830abdde82SPaolo Abeni */ 13840abdde82SPaolo Abeni lock_sock(sk); 13850abdde82SPaolo Abeni ssk = __mptcp_tcp_fallback(msk); 13860abdde82SPaolo Abeni release_sock(sk); 13870abdde82SPaolo Abeni if (ssk) 13880abdde82SPaolo Abeni return tcp_getsockopt(ssk, level, optname, optval, option); 13890abdde82SPaolo Abeni 13903b1e21ebSFlorian Westphal if (level == SOL_IP) 13913b1e21ebSFlorian Westphal return mptcp_getsockopt_v4(msk, optname, optval, option); 1392aa1fbd94SFlorian Westphal if (level == SOL_TCP) 1393aa1fbd94SFlorian Westphal return mptcp_getsockopt_sol_tcp(msk, optname, optval, option); 139455c42fa7SFlorian Westphal if (level == SOL_MPTCP) 139555c42fa7SFlorian Westphal return mptcp_getsockopt_sol_mptcp(msk, optname, optval, option); 13960abdde82SPaolo Abeni return -EOPNOTSUPP; 13970abdde82SPaolo Abeni } 13980abdde82SPaolo Abeni 13991b3e7edeSFlorian Westphal static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk) 14001b3e7edeSFlorian Westphal { 14015d0a6bc8SFlorian Westphal static const unsigned int tx_rx_locks = SOCK_RCVBUF_LOCK | SOCK_SNDBUF_LOCK; 14021b3e7edeSFlorian Westphal struct sock *sk = (struct sock *)msk; 14031b3e7edeSFlorian Westphal 14041b3e7edeSFlorian Westphal if (ssk->sk_prot->keepalive) { 14051b3e7edeSFlorian Westphal if (sock_flag(sk, SOCK_KEEPOPEN)) 14061b3e7edeSFlorian Westphal ssk->sk_prot->keepalive(ssk, 1); 14071b3e7edeSFlorian Westphal else 14081b3e7edeSFlorian Westphal ssk->sk_prot->keepalive(ssk, 0); 14091b3e7edeSFlorian Westphal } 14101b3e7edeSFlorian Westphal 14111b3e7edeSFlorian Westphal ssk->sk_priority = sk->sk_priority; 14125d0a6bc8SFlorian Westphal ssk->sk_bound_dev_if = sk->sk_bound_dev_if; 14135d0a6bc8SFlorian Westphal ssk->sk_incoming_cpu = sk->sk_incoming_cpu; 14147e9740e0SMatthieu Baerts ssk->sk_ipv6only = sk->sk_ipv6only; 1415878d951cSEric Dumazet __ip_sock_set_tos(ssk, inet_sk(sk)->tos); 14165d0a6bc8SFlorian Westphal 14175d0a6bc8SFlorian Westphal if (sk->sk_userlocks & tx_rx_locks) { 14185d0a6bc8SFlorian Westphal ssk->sk_userlocks |= sk->sk_userlocks & tx_rx_locks; 14198005184fSPaolo Abeni if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) { 14205d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_sndbuf, sk->sk_sndbuf); 14218005184fSPaolo Abeni mptcp_subflow_ctx(ssk)->cached_sndbuf = sk->sk_sndbuf; 14228005184fSPaolo Abeni } 14235d0a6bc8SFlorian Westphal if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) 14245d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf); 14255d0a6bc8SFlorian Westphal } 14265d0a6bc8SFlorian Westphal 14275d0a6bc8SFlorian Westphal if (sock_flag(sk, SOCK_LINGER)) { 14285d0a6bc8SFlorian Westphal ssk->sk_lingertime = sk->sk_lingertime; 14295d0a6bc8SFlorian Westphal sock_set_flag(ssk, SOCK_LINGER); 14305d0a6bc8SFlorian Westphal } else { 14315d0a6bc8SFlorian Westphal sock_reset_flag(ssk, SOCK_LINGER); 14325d0a6bc8SFlorian Westphal } 14335d0a6bc8SFlorian Westphal 14345d0a6bc8SFlorian Westphal if (sk->sk_mark != ssk->sk_mark) { 14355d0a6bc8SFlorian Westphal ssk->sk_mark = sk->sk_mark; 14365d0a6bc8SFlorian Westphal sk_dst_reset(ssk); 14375d0a6bc8SFlorian Westphal } 14385d0a6bc8SFlorian Westphal 14395d0a6bc8SFlorian Westphal sock_valbool_flag(ssk, SOCK_DBG, sock_flag(sk, SOCK_DBG)); 14405d0a6bc8SFlorian Westphal 14415d0a6bc8SFlorian Westphal if (inet_csk(sk)->icsk_ca_ops != inet_csk(ssk)->icsk_ca_ops) 144220b5759fSPaolo Abeni tcp_set_congestion_control(ssk, msk->ca_name, false, true); 14434f6e14bdSMaxim Galaganov __tcp_sock_set_cork(ssk, !!msk->cork); 14444f6e14bdSMaxim Galaganov __tcp_sock_set_nodelay(ssk, !!msk->nodelay); 1445c9406a23SFlorian Westphal 14464bd0623fSEric Dumazet inet_assign_bit(TRANSPARENT, ssk, inet_test_bit(TRANSPARENT, sk)); 14473f7e7532SEric Dumazet inet_assign_bit(FREEBIND, ssk, inet_test_bit(FREEBIND, sk)); 14481b3e7edeSFlorian Westphal } 14491b3e7edeSFlorian Westphal 14503e501490SPaolo Abeni void mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk) 145178962489SFlorian Westphal { 14523e501490SPaolo Abeni struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); 145378962489SFlorian Westphal 14543e501490SPaolo Abeni msk_owned_by_me(msk); 145578962489SFlorian Westphal 14565684ab1aSPaolo Abeni ssk->sk_rcvlowat = 0; 14575684ab1aSPaolo Abeni 14589fdc7793SPaolo Abeni /* subflows must ignore any latency-related settings: will not affect 14599fdc7793SPaolo Abeni * the user-space - only the msk is relevant - but will foul the 14609fdc7793SPaolo Abeni * mptcp scheduler 14619fdc7793SPaolo Abeni */ 14629fdc7793SPaolo Abeni tcp_sk(ssk)->notsent_lowat = UINT_MAX; 14639fdc7793SPaolo Abeni 14643e501490SPaolo Abeni if (READ_ONCE(subflow->setsockopt_seq) != msk->setsockopt_seq) { 14653e501490SPaolo Abeni sync_socket_options(msk, ssk); 146678962489SFlorian Westphal 14673e501490SPaolo Abeni subflow->setsockopt_seq = msk->setsockopt_seq; 1468df00b087SFlorian Westphal } 146978962489SFlorian Westphal } 14705684ab1aSPaolo Abeni 14715684ab1aSPaolo Abeni /* unfortunately this is different enough from the tcp version so 14725684ab1aSPaolo Abeni * that we can't factor it out 14735684ab1aSPaolo Abeni */ 14745684ab1aSPaolo Abeni int mptcp_set_rcvlowat(struct sock *sk, int val) 14755684ab1aSPaolo Abeni { 14765684ab1aSPaolo Abeni struct mptcp_subflow_context *subflow; 14775684ab1aSPaolo Abeni int space, cap; 14785684ab1aSPaolo Abeni 14795684ab1aSPaolo Abeni if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) 14805684ab1aSPaolo Abeni cap = sk->sk_rcvbuf >> 1; 14815684ab1aSPaolo Abeni else 14825684ab1aSPaolo Abeni cap = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]) >> 1; 14835684ab1aSPaolo Abeni val = min(val, cap); 14845684ab1aSPaolo Abeni WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); 14855684ab1aSPaolo Abeni 14865684ab1aSPaolo Abeni /* Check if we need to signal EPOLLIN right now */ 14875684ab1aSPaolo Abeni if (mptcp_epollin_ready(sk)) 14885684ab1aSPaolo Abeni sk->sk_data_ready(sk); 14895684ab1aSPaolo Abeni 14905684ab1aSPaolo Abeni if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) 14915684ab1aSPaolo Abeni return 0; 14925684ab1aSPaolo Abeni 14935684ab1aSPaolo Abeni space = __tcp_space_from_win(mptcp_sk(sk)->scaling_ratio, val); 14945684ab1aSPaolo Abeni if (space <= sk->sk_rcvbuf) 14955684ab1aSPaolo Abeni return 0; 14965684ab1aSPaolo Abeni 14975684ab1aSPaolo Abeni /* propagate the rcvbuf changes to all the subflows */ 14985684ab1aSPaolo Abeni WRITE_ONCE(sk->sk_rcvbuf, space); 14995684ab1aSPaolo Abeni mptcp_for_each_subflow(mptcp_sk(sk), subflow) { 15005684ab1aSPaolo Abeni struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 15015684ab1aSPaolo Abeni bool slow; 15025684ab1aSPaolo Abeni 15035684ab1aSPaolo Abeni slow = lock_sock_fast(ssk); 15045684ab1aSPaolo Abeni WRITE_ONCE(ssk->sk_rcvbuf, space); 15055684ab1aSPaolo Abeni tcp_sk(ssk)->window_clamp = val; 15065684ab1aSPaolo Abeni unlock_sock_fast(ssk, slow); 15075684ab1aSPaolo Abeni } 15085684ab1aSPaolo Abeni return 0; 15095684ab1aSPaolo Abeni } 1510