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 1806f15ceeSFlorian Westphal 190abdde82SPaolo Abeni static struct sock *__mptcp_tcp_fallback(struct mptcp_sock *msk) 200abdde82SPaolo Abeni { 210abdde82SPaolo Abeni sock_owned_by_me((const struct sock *)msk); 220abdde82SPaolo Abeni 230abdde82SPaolo Abeni if (likely(!__mptcp_check_fallback(msk))) 240abdde82SPaolo Abeni return NULL; 250abdde82SPaolo Abeni 260abdde82SPaolo Abeni return msk->first; 270abdde82SPaolo Abeni } 280abdde82SPaolo Abeni 29df00b087SFlorian Westphal static u32 sockopt_seq_reset(const struct sock *sk) 30df00b087SFlorian Westphal { 31df00b087SFlorian Westphal sock_owned_by_me(sk); 32df00b087SFlorian Westphal 33df00b087SFlorian Westphal /* Highbits contain state. Allows to distinguish sockopt_seq 34df00b087SFlorian Westphal * of listener and established: 35df00b087SFlorian Westphal * s0 = new_listener() 36df00b087SFlorian Westphal * sockopt(s0) - seq is 1 37df00b087SFlorian Westphal * s1 = accept(s0) - s1 inherits seq 1 if listener sk (s0) 38df00b087SFlorian Westphal * sockopt(s0) - seq increments to 2 on s0 39df00b087SFlorian Westphal * sockopt(s1) // seq increments to 2 on s1 (different option) 40df00b087SFlorian Westphal * new ssk completes join, inherits options from s0 // seq 2 41df00b087SFlorian Westphal * Needs sync from mptcp join logic, but ssk->seq == msk->seq 42df00b087SFlorian Westphal * 43df00b087SFlorian Westphal * Set High order bits to sk_state so ssk->seq == msk->seq test 44df00b087SFlorian Westphal * will fail. 45df00b087SFlorian Westphal */ 46df00b087SFlorian Westphal 47df00b087SFlorian Westphal return (u32)sk->sk_state << 24u; 48df00b087SFlorian Westphal } 49df00b087SFlorian Westphal 501b3e7edeSFlorian Westphal static void sockopt_seq_inc(struct mptcp_sock *msk) 511b3e7edeSFlorian Westphal { 521b3e7edeSFlorian Westphal u32 seq = (msk->setsockopt_seq + 1) & 0x00ffffff; 531b3e7edeSFlorian Westphal 541b3e7edeSFlorian Westphal msk->setsockopt_seq = sockopt_seq_reset((struct sock *)msk) + seq; 551b3e7edeSFlorian Westphal } 561b3e7edeSFlorian Westphal 571b3e7edeSFlorian Westphal static int mptcp_get_int_option(struct mptcp_sock *msk, sockptr_t optval, 581b3e7edeSFlorian Westphal unsigned int optlen, int *val) 591b3e7edeSFlorian Westphal { 601b3e7edeSFlorian Westphal if (optlen < sizeof(int)) 611b3e7edeSFlorian Westphal return -EINVAL; 621b3e7edeSFlorian Westphal 631b3e7edeSFlorian Westphal if (copy_from_sockptr(val, optval, sizeof(*val))) 641b3e7edeSFlorian Westphal return -EFAULT; 651b3e7edeSFlorian Westphal 661b3e7edeSFlorian Westphal return 0; 671b3e7edeSFlorian Westphal } 681b3e7edeSFlorian Westphal 691b3e7edeSFlorian Westphal static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, int val) 701b3e7edeSFlorian Westphal { 711b3e7edeSFlorian Westphal struct mptcp_subflow_context *subflow; 721b3e7edeSFlorian Westphal struct sock *sk = (struct sock *)msk; 731b3e7edeSFlorian Westphal 741b3e7edeSFlorian Westphal lock_sock(sk); 751b3e7edeSFlorian Westphal sockopt_seq_inc(msk); 761b3e7edeSFlorian Westphal 771b3e7edeSFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 781b3e7edeSFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 791b3e7edeSFlorian Westphal bool slow = lock_sock_fast(ssk); 801b3e7edeSFlorian Westphal 811b3e7edeSFlorian Westphal switch (optname) { 82a03c99b2SFlorian Westphal case SO_DEBUG: 83a03c99b2SFlorian Westphal sock_valbool_flag(ssk, SOCK_DBG, !!val); 84a03c99b2SFlorian Westphal break; 851b3e7edeSFlorian Westphal case SO_KEEPALIVE: 861b3e7edeSFlorian Westphal if (ssk->sk_prot->keepalive) 871b3e7edeSFlorian Westphal ssk->sk_prot->keepalive(ssk, !!val); 881b3e7edeSFlorian Westphal sock_valbool_flag(ssk, SOCK_KEEPOPEN, !!val); 891b3e7edeSFlorian Westphal break; 901b3e7edeSFlorian Westphal case SO_PRIORITY: 911b3e7edeSFlorian Westphal ssk->sk_priority = val; 921b3e7edeSFlorian Westphal break; 935d0a6bc8SFlorian Westphal case SO_SNDBUF: 945d0a6bc8SFlorian Westphal case SO_SNDBUFFORCE: 955d0a6bc8SFlorian Westphal ssk->sk_userlocks |= SOCK_SNDBUF_LOCK; 965d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_sndbuf, sk->sk_sndbuf); 975d0a6bc8SFlorian Westphal break; 985d0a6bc8SFlorian Westphal case SO_RCVBUF: 995d0a6bc8SFlorian Westphal case SO_RCVBUFFORCE: 1005d0a6bc8SFlorian Westphal ssk->sk_userlocks |= SOCK_RCVBUF_LOCK; 1015d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf); 1025d0a6bc8SFlorian Westphal break; 10336704413SFlorian Westphal case SO_MARK: 10436704413SFlorian Westphal if (READ_ONCE(ssk->sk_mark) != sk->sk_mark) { 10536704413SFlorian Westphal ssk->sk_mark = sk->sk_mark; 10636704413SFlorian Westphal sk_dst_reset(ssk); 10736704413SFlorian Westphal } 10836704413SFlorian Westphal break; 1096f0d7198SFlorian Westphal case SO_INCOMING_CPU: 1106f0d7198SFlorian Westphal WRITE_ONCE(ssk->sk_incoming_cpu, val); 1116f0d7198SFlorian Westphal break; 1121b3e7edeSFlorian Westphal } 1131b3e7edeSFlorian Westphal 1141b3e7edeSFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 1151b3e7edeSFlorian Westphal unlock_sock_fast(ssk, slow); 1161b3e7edeSFlorian Westphal } 1171b3e7edeSFlorian Westphal 1181b3e7edeSFlorian Westphal release_sock(sk); 1191b3e7edeSFlorian Westphal } 1201b3e7edeSFlorian Westphal 1211b3e7edeSFlorian Westphal static int mptcp_sol_socket_intval(struct mptcp_sock *msk, int optname, int val) 1221b3e7edeSFlorian Westphal { 1231b3e7edeSFlorian Westphal sockptr_t optval = KERNEL_SOCKPTR(&val); 1241b3e7edeSFlorian Westphal struct sock *sk = (struct sock *)msk; 1251b3e7edeSFlorian Westphal int ret; 1261b3e7edeSFlorian Westphal 1271b3e7edeSFlorian Westphal ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, 1281b3e7edeSFlorian Westphal optval, sizeof(val)); 1291b3e7edeSFlorian Westphal if (ret) 1301b3e7edeSFlorian Westphal return ret; 1311b3e7edeSFlorian Westphal 1321b3e7edeSFlorian Westphal mptcp_sol_socket_sync_intval(msk, optname, val); 1331b3e7edeSFlorian Westphal return 0; 1341b3e7edeSFlorian Westphal } 1351b3e7edeSFlorian Westphal 1366f0d7198SFlorian Westphal static void mptcp_so_incoming_cpu(struct mptcp_sock *msk, int val) 1376f0d7198SFlorian Westphal { 1386f0d7198SFlorian Westphal struct sock *sk = (struct sock *)msk; 1396f0d7198SFlorian Westphal 1406f0d7198SFlorian Westphal WRITE_ONCE(sk->sk_incoming_cpu, val); 1416f0d7198SFlorian Westphal 1426f0d7198SFlorian Westphal mptcp_sol_socket_sync_intval(msk, SO_INCOMING_CPU, val); 1436f0d7198SFlorian Westphal } 1446f0d7198SFlorian Westphal 1459061f24bSFlorian Westphal static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optname, int val) 1469061f24bSFlorian Westphal { 1479061f24bSFlorian Westphal sockptr_t optval = KERNEL_SOCKPTR(&val); 1489061f24bSFlorian Westphal struct mptcp_subflow_context *subflow; 1499061f24bSFlorian Westphal struct sock *sk = (struct sock *)msk; 1509061f24bSFlorian Westphal int ret; 1519061f24bSFlorian Westphal 1529061f24bSFlorian Westphal ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, 1539061f24bSFlorian Westphal optval, sizeof(val)); 1549061f24bSFlorian Westphal if (ret) 1559061f24bSFlorian Westphal return ret; 1569061f24bSFlorian Westphal 1579061f24bSFlorian Westphal lock_sock(sk); 1589061f24bSFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 1599061f24bSFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 1609061f24bSFlorian Westphal bool slow = lock_sock_fast(ssk); 1619061f24bSFlorian Westphal 1629061f24bSFlorian Westphal sock_set_timestamp(sk, optname, !!val); 1639061f24bSFlorian Westphal unlock_sock_fast(ssk, slow); 1649061f24bSFlorian Westphal } 1659061f24bSFlorian Westphal 1669061f24bSFlorian Westphal release_sock(sk); 1679061f24bSFlorian Westphal return 0; 1689061f24bSFlorian Westphal } 1699061f24bSFlorian Westphal 1701b3e7edeSFlorian Westphal static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname, 1716c9a0a0fSYangbo Lu sockptr_t optval, 1726c9a0a0fSYangbo Lu unsigned int optlen) 1731b3e7edeSFlorian Westphal { 1741b3e7edeSFlorian Westphal int val, ret; 1751b3e7edeSFlorian Westphal 1761b3e7edeSFlorian Westphal ret = mptcp_get_int_option(msk, optval, optlen, &val); 1771b3e7edeSFlorian Westphal if (ret) 1781b3e7edeSFlorian Westphal return ret; 1791b3e7edeSFlorian Westphal 1801b3e7edeSFlorian Westphal switch (optname) { 1811b3e7edeSFlorian Westphal case SO_KEEPALIVE: 1821b3e7edeSFlorian Westphal mptcp_sol_socket_sync_intval(msk, optname, val); 1831b3e7edeSFlorian Westphal return 0; 184a03c99b2SFlorian Westphal case SO_DEBUG: 18536704413SFlorian Westphal case SO_MARK: 1861b3e7edeSFlorian Westphal case SO_PRIORITY: 1875d0a6bc8SFlorian Westphal case SO_SNDBUF: 1885d0a6bc8SFlorian Westphal case SO_SNDBUFFORCE: 1895d0a6bc8SFlorian Westphal case SO_RCVBUF: 1905d0a6bc8SFlorian Westphal case SO_RCVBUFFORCE: 1911b3e7edeSFlorian Westphal return mptcp_sol_socket_intval(msk, optname, val); 1926f0d7198SFlorian Westphal case SO_INCOMING_CPU: 1936f0d7198SFlorian Westphal mptcp_so_incoming_cpu(msk, val); 1946f0d7198SFlorian Westphal return 0; 1959061f24bSFlorian Westphal case SO_TIMESTAMP_OLD: 1969061f24bSFlorian Westphal case SO_TIMESTAMP_NEW: 1979061f24bSFlorian Westphal case SO_TIMESTAMPNS_OLD: 1989061f24bSFlorian Westphal case SO_TIMESTAMPNS_NEW: 1999061f24bSFlorian Westphal return mptcp_setsockopt_sol_socket_tstamp(msk, optname, val); 2001b3e7edeSFlorian Westphal } 2011b3e7edeSFlorian Westphal 2021b3e7edeSFlorian Westphal return -ENOPROTOOPT; 2031b3e7edeSFlorian Westphal } 2041b3e7edeSFlorian Westphal 2056c9a0a0fSYangbo Lu static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, 2066c9a0a0fSYangbo Lu int optname, 2076c9a0a0fSYangbo Lu sockptr_t optval, 2086c9a0a0fSYangbo Lu unsigned int optlen) 2096c9a0a0fSYangbo Lu { 2106c9a0a0fSYangbo Lu struct mptcp_subflow_context *subflow; 2116c9a0a0fSYangbo Lu struct sock *sk = (struct sock *)msk; 212d463126eSYangbo Lu struct so_timestamping timestamping; 213d463126eSYangbo Lu int ret; 2146c9a0a0fSYangbo Lu 215d463126eSYangbo Lu if (optlen == sizeof(timestamping)) { 216d463126eSYangbo Lu if (copy_from_sockptr(×tamping, optval, 217d463126eSYangbo Lu sizeof(timestamping))) 218d463126eSYangbo Lu return -EFAULT; 219d463126eSYangbo Lu } else if (optlen == sizeof(int)) { 220d463126eSYangbo Lu memset(×tamping, 0, sizeof(timestamping)); 221d463126eSYangbo Lu 222d463126eSYangbo Lu if (copy_from_sockptr(×tamping.flags, optval, sizeof(int))) 223d463126eSYangbo Lu return -EFAULT; 224d463126eSYangbo Lu } else { 225d463126eSYangbo Lu return -EINVAL; 226d463126eSYangbo Lu } 2276c9a0a0fSYangbo Lu 2286c9a0a0fSYangbo Lu ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, 229d463126eSYangbo Lu KERNEL_SOCKPTR(×tamping), 230d463126eSYangbo Lu sizeof(timestamping)); 2316c9a0a0fSYangbo Lu if (ret) 2326c9a0a0fSYangbo Lu return ret; 2336c9a0a0fSYangbo Lu 2346c9a0a0fSYangbo Lu lock_sock(sk); 2356c9a0a0fSYangbo Lu 2366c9a0a0fSYangbo Lu mptcp_for_each_subflow(msk, subflow) { 2376c9a0a0fSYangbo Lu struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 2386c9a0a0fSYangbo Lu bool slow = lock_sock_fast(ssk); 2396c9a0a0fSYangbo Lu 240d463126eSYangbo Lu sock_set_timestamping(sk, optname, timestamping); 2416c9a0a0fSYangbo Lu unlock_sock_fast(ssk, slow); 2426c9a0a0fSYangbo Lu } 2436c9a0a0fSYangbo Lu 2446c9a0a0fSYangbo Lu release_sock(sk); 2456c9a0a0fSYangbo Lu 2466c9a0a0fSYangbo Lu return 0; 2476c9a0a0fSYangbo Lu } 2486c9a0a0fSYangbo Lu 249268b1238SFlorian Westphal static int mptcp_setsockopt_sol_socket_linger(struct mptcp_sock *msk, sockptr_t optval, 250268b1238SFlorian Westphal unsigned int optlen) 251268b1238SFlorian Westphal { 252268b1238SFlorian Westphal struct mptcp_subflow_context *subflow; 253268b1238SFlorian Westphal struct sock *sk = (struct sock *)msk; 254268b1238SFlorian Westphal struct linger ling; 255268b1238SFlorian Westphal sockptr_t kopt; 256268b1238SFlorian Westphal int ret; 257268b1238SFlorian Westphal 258268b1238SFlorian Westphal if (optlen < sizeof(ling)) 259268b1238SFlorian Westphal return -EINVAL; 260268b1238SFlorian Westphal 261268b1238SFlorian Westphal if (copy_from_sockptr(&ling, optval, sizeof(ling))) 262268b1238SFlorian Westphal return -EFAULT; 263268b1238SFlorian Westphal 264268b1238SFlorian Westphal kopt = KERNEL_SOCKPTR(&ling); 265268b1238SFlorian Westphal ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, SO_LINGER, kopt, sizeof(ling)); 266268b1238SFlorian Westphal if (ret) 267268b1238SFlorian Westphal return ret; 268268b1238SFlorian Westphal 269268b1238SFlorian Westphal lock_sock(sk); 270268b1238SFlorian Westphal sockopt_seq_inc(msk); 271268b1238SFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 272268b1238SFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 273268b1238SFlorian Westphal bool slow = lock_sock_fast(ssk); 274268b1238SFlorian Westphal 275268b1238SFlorian Westphal if (!ling.l_onoff) { 276268b1238SFlorian Westphal sock_reset_flag(ssk, SOCK_LINGER); 277268b1238SFlorian Westphal } else { 278268b1238SFlorian Westphal ssk->sk_lingertime = sk->sk_lingertime; 279268b1238SFlorian Westphal sock_set_flag(ssk, SOCK_LINGER); 280268b1238SFlorian Westphal } 281268b1238SFlorian Westphal 282268b1238SFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 283268b1238SFlorian Westphal unlock_sock_fast(ssk, slow); 284268b1238SFlorian Westphal } 285268b1238SFlorian Westphal 286268b1238SFlorian Westphal release_sock(sk); 287268b1238SFlorian Westphal return 0; 288268b1238SFlorian Westphal } 289268b1238SFlorian Westphal 2900abdde82SPaolo Abeni static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname, 2910abdde82SPaolo Abeni sockptr_t optval, unsigned int optlen) 2920abdde82SPaolo Abeni { 2930abdde82SPaolo Abeni struct sock *sk = (struct sock *)msk; 2940abdde82SPaolo Abeni struct socket *ssock; 2950abdde82SPaolo Abeni int ret; 2960abdde82SPaolo Abeni 2970abdde82SPaolo Abeni switch (optname) { 2980abdde82SPaolo Abeni case SO_REUSEPORT: 2990abdde82SPaolo Abeni case SO_REUSEADDR: 3005d0a6bc8SFlorian Westphal case SO_BINDTODEVICE: 3015d0a6bc8SFlorian Westphal case SO_BINDTOIFINDEX: 3020abdde82SPaolo Abeni lock_sock(sk); 3030abdde82SPaolo Abeni ssock = __mptcp_nmpc_socket(msk); 3040abdde82SPaolo Abeni if (!ssock) { 3050abdde82SPaolo Abeni release_sock(sk); 3060abdde82SPaolo Abeni return -EINVAL; 3070abdde82SPaolo Abeni } 3080abdde82SPaolo Abeni 3090abdde82SPaolo Abeni ret = sock_setsockopt(ssock, SOL_SOCKET, optname, optval, optlen); 3100abdde82SPaolo Abeni if (ret == 0) { 3110abdde82SPaolo Abeni if (optname == SO_REUSEPORT) 3120abdde82SPaolo Abeni sk->sk_reuseport = ssock->sk->sk_reuseport; 3130abdde82SPaolo Abeni else if (optname == SO_REUSEADDR) 3140abdde82SPaolo Abeni sk->sk_reuse = ssock->sk->sk_reuse; 3155d0a6bc8SFlorian Westphal else if (optname == SO_BINDTODEVICE) 3165d0a6bc8SFlorian Westphal sk->sk_bound_dev_if = ssock->sk->sk_bound_dev_if; 3175d0a6bc8SFlorian Westphal else if (optname == SO_BINDTOIFINDEX) 3185d0a6bc8SFlorian Westphal sk->sk_bound_dev_if = ssock->sk->sk_bound_dev_if; 3190abdde82SPaolo Abeni } 3200abdde82SPaolo Abeni release_sock(sk); 3210abdde82SPaolo Abeni return ret; 3221b3e7edeSFlorian Westphal case SO_KEEPALIVE: 3231b3e7edeSFlorian Westphal case SO_PRIORITY: 3245d0a6bc8SFlorian Westphal case SO_SNDBUF: 3255d0a6bc8SFlorian Westphal case SO_SNDBUFFORCE: 3265d0a6bc8SFlorian Westphal case SO_RCVBUF: 3275d0a6bc8SFlorian Westphal case SO_RCVBUFFORCE: 32836704413SFlorian Westphal case SO_MARK: 3296f0d7198SFlorian Westphal case SO_INCOMING_CPU: 330a03c99b2SFlorian Westphal case SO_DEBUG: 3319061f24bSFlorian Westphal case SO_TIMESTAMP_OLD: 3329061f24bSFlorian Westphal case SO_TIMESTAMP_NEW: 3339061f24bSFlorian Westphal case SO_TIMESTAMPNS_OLD: 3349061f24bSFlorian Westphal case SO_TIMESTAMPNS_NEW: 3356c9a0a0fSYangbo Lu return mptcp_setsockopt_sol_socket_int(msk, optname, optval, 3366c9a0a0fSYangbo Lu optlen); 3379061f24bSFlorian Westphal case SO_TIMESTAMPING_OLD: 3389061f24bSFlorian Westphal case SO_TIMESTAMPING_NEW: 3396c9a0a0fSYangbo Lu return mptcp_setsockopt_sol_socket_timestamping(msk, optname, 3406c9a0a0fSYangbo Lu optval, optlen); 341268b1238SFlorian Westphal case SO_LINGER: 342268b1238SFlorian Westphal return mptcp_setsockopt_sol_socket_linger(msk, optval, optlen); 3437a009a70SFlorian Westphal case SO_RCVLOWAT: 3447a009a70SFlorian Westphal case SO_RCVTIMEO_OLD: 3457a009a70SFlorian Westphal case SO_RCVTIMEO_NEW: 3467a009a70SFlorian Westphal case SO_BUSY_POLL: 3477a009a70SFlorian Westphal case SO_PREFER_BUSY_POLL: 3487a009a70SFlorian Westphal case SO_BUSY_POLL_BUDGET: 3497a009a70SFlorian Westphal /* No need to copy: only relevant for msk */ 3507a009a70SFlorian Westphal return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen); 351a03c99b2SFlorian Westphal case SO_NO_CHECK: 352a03c99b2SFlorian Westphal case SO_DONTROUTE: 353a03c99b2SFlorian Westphal case SO_BROADCAST: 354a03c99b2SFlorian Westphal case SO_BSDCOMPAT: 355a03c99b2SFlorian Westphal case SO_PASSCRED: 356a03c99b2SFlorian Westphal case SO_PASSSEC: 357a03c99b2SFlorian Westphal case SO_RXQ_OVFL: 358a03c99b2SFlorian Westphal case SO_WIFI_STATUS: 359a03c99b2SFlorian Westphal case SO_NOFCS: 360a03c99b2SFlorian Westphal case SO_SELECT_ERR_QUEUE: 361a03c99b2SFlorian Westphal return 0; 3620abdde82SPaolo Abeni } 3630abdde82SPaolo Abeni 3647a009a70SFlorian Westphal /* SO_OOBINLINE is not supported, let's avoid the related mess 3657a009a70SFlorian Westphal * SO_ATTACH_FILTER, SO_ATTACH_BPF, SO_ATTACH_REUSEPORT_CBPF, 3667a009a70SFlorian Westphal * SO_DETACH_REUSEPORT_BPF, SO_DETACH_FILTER, SO_LOCK_FILTER, 3677a009a70SFlorian Westphal * we must be careful with subflows 3687a009a70SFlorian Westphal * 3697a009a70SFlorian Westphal * SO_ATTACH_REUSEPORT_EBPF is not supported, at it checks 3707a009a70SFlorian Westphal * explicitly the sk_protocol field 3717a009a70SFlorian Westphal * 3727a009a70SFlorian Westphal * SO_PEEK_OFF is unsupported, as it is for plain TCP 3737a009a70SFlorian Westphal * SO_MAX_PACING_RATE is unsupported, we must be careful with subflows 3747a009a70SFlorian Westphal * SO_CNX_ADVICE is currently unsupported, could possibly be relevant, 3757a009a70SFlorian Westphal * but likely needs careful design 3767a009a70SFlorian Westphal * 3777a009a70SFlorian Westphal * SO_ZEROCOPY is currently unsupported, TODO in sndmsg 3787a009a70SFlorian Westphal * SO_TXTIME is currently unsupported 3797a009a70SFlorian Westphal */ 3807a009a70SFlorian Westphal 3817a009a70SFlorian Westphal return -EOPNOTSUPP; 3820abdde82SPaolo Abeni } 3830abdde82SPaolo Abeni 3840abdde82SPaolo Abeni static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname, 3850abdde82SPaolo Abeni sockptr_t optval, unsigned int optlen) 3860abdde82SPaolo Abeni { 3870abdde82SPaolo Abeni struct sock *sk = (struct sock *)msk; 3880abdde82SPaolo Abeni int ret = -EOPNOTSUPP; 3890abdde82SPaolo Abeni struct socket *ssock; 3900abdde82SPaolo Abeni 3910abdde82SPaolo Abeni switch (optname) { 3920abdde82SPaolo Abeni case IPV6_V6ONLY: 393c9406a23SFlorian Westphal case IPV6_TRANSPARENT: 394c9406a23SFlorian Westphal case IPV6_FREEBIND: 3950abdde82SPaolo Abeni lock_sock(sk); 3960abdde82SPaolo Abeni ssock = __mptcp_nmpc_socket(msk); 3970abdde82SPaolo Abeni if (!ssock) { 3980abdde82SPaolo Abeni release_sock(sk); 3990abdde82SPaolo Abeni return -EINVAL; 4000abdde82SPaolo Abeni } 4010abdde82SPaolo Abeni 4020abdde82SPaolo Abeni ret = tcp_setsockopt(ssock->sk, SOL_IPV6, optname, optval, optlen); 403c9406a23SFlorian Westphal if (ret != 0) { 404c9406a23SFlorian Westphal release_sock(sk); 405c9406a23SFlorian Westphal return ret; 406c9406a23SFlorian Westphal } 407c9406a23SFlorian Westphal 408c9406a23SFlorian Westphal sockopt_seq_inc(msk); 409c9406a23SFlorian Westphal 410c9406a23SFlorian Westphal switch (optname) { 411c9406a23SFlorian Westphal case IPV6_V6ONLY: 4120abdde82SPaolo Abeni sk->sk_ipv6only = ssock->sk->sk_ipv6only; 413c9406a23SFlorian Westphal break; 414c9406a23SFlorian Westphal case IPV6_TRANSPARENT: 415c9406a23SFlorian Westphal inet_sk(sk)->transparent = inet_sk(ssock->sk)->transparent; 416c9406a23SFlorian Westphal break; 417c9406a23SFlorian Westphal case IPV6_FREEBIND: 418c9406a23SFlorian Westphal inet_sk(sk)->freebind = inet_sk(ssock->sk)->freebind; 419c9406a23SFlorian Westphal break; 420c9406a23SFlorian Westphal } 4210abdde82SPaolo Abeni 4220abdde82SPaolo Abeni release_sock(sk); 4230abdde82SPaolo Abeni break; 4240abdde82SPaolo Abeni } 4250abdde82SPaolo Abeni 4260abdde82SPaolo Abeni return ret; 4270abdde82SPaolo Abeni } 4280abdde82SPaolo Abeni 429d9e4c129SPaolo Abeni static bool mptcp_supported_sockopt(int level, int optname) 430d9e4c129SPaolo Abeni { 431d9e4c129SPaolo Abeni if (level == SOL_IP) { 432d9e4c129SPaolo Abeni switch (optname) { 433d9e4c129SPaolo Abeni /* should work fine */ 434d9e4c129SPaolo Abeni case IP_FREEBIND: 435d9e4c129SPaolo Abeni case IP_TRANSPARENT: 436d9e4c129SPaolo Abeni 437d9e4c129SPaolo Abeni /* the following are control cmsg related */ 438d9e4c129SPaolo Abeni case IP_PKTINFO: 439d9e4c129SPaolo Abeni case IP_RECVTTL: 440d9e4c129SPaolo Abeni case IP_RECVTOS: 441d9e4c129SPaolo Abeni case IP_RECVOPTS: 442d9e4c129SPaolo Abeni case IP_RETOPTS: 443d9e4c129SPaolo Abeni case IP_PASSSEC: 444d9e4c129SPaolo Abeni case IP_RECVORIGDSTADDR: 445d9e4c129SPaolo Abeni case IP_CHECKSUM: 446d9e4c129SPaolo Abeni case IP_RECVFRAGSIZE: 447d9e4c129SPaolo Abeni 448d9e4c129SPaolo Abeni /* common stuff that need some love */ 449d9e4c129SPaolo Abeni case IP_TOS: 450d9e4c129SPaolo Abeni case IP_TTL: 451d9e4c129SPaolo Abeni case IP_BIND_ADDRESS_NO_PORT: 452d9e4c129SPaolo Abeni case IP_MTU_DISCOVER: 453d9e4c129SPaolo Abeni case IP_RECVERR: 454d9e4c129SPaolo Abeni 455d9e4c129SPaolo Abeni /* possibly less common may deserve some love */ 456d9e4c129SPaolo Abeni case IP_MINTTL: 457d9e4c129SPaolo Abeni 458d9e4c129SPaolo Abeni /* the following is apparently a no-op for plain TCP */ 459d9e4c129SPaolo Abeni case IP_RECVERR_RFC4884: 460d9e4c129SPaolo Abeni return true; 461d9e4c129SPaolo Abeni } 462d9e4c129SPaolo Abeni 463d9e4c129SPaolo Abeni /* IP_OPTIONS is not supported, needs subflow care */ 464d9e4c129SPaolo Abeni /* IP_HDRINCL, IP_NODEFRAG are not supported, RAW specific */ 465d9e4c129SPaolo Abeni /* IP_MULTICAST_TTL, IP_MULTICAST_LOOP, IP_UNICAST_IF, 466d9e4c129SPaolo Abeni * IP_ADD_MEMBERSHIP, IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_MEMBERSHIP, 467d9e4c129SPaolo Abeni * IP_DROP_SOURCE_MEMBERSHIP, IP_BLOCK_SOURCE, IP_UNBLOCK_SOURCE, 468d9e4c129SPaolo Abeni * MCAST_JOIN_GROUP, MCAST_LEAVE_GROUP MCAST_JOIN_SOURCE_GROUP, 469d9e4c129SPaolo Abeni * MCAST_LEAVE_SOURCE_GROUP, MCAST_BLOCK_SOURCE, MCAST_UNBLOCK_SOURCE, 470d9e4c129SPaolo Abeni * MCAST_MSFILTER, IP_MULTICAST_ALL are not supported, better not deal 471d9e4c129SPaolo Abeni * with mcast stuff 472d9e4c129SPaolo Abeni */ 473d9e4c129SPaolo Abeni /* IP_IPSEC_POLICY, IP_XFRM_POLICY are nut supported, unrelated here */ 474d9e4c129SPaolo Abeni return false; 475d9e4c129SPaolo Abeni } 476d9e4c129SPaolo Abeni if (level == SOL_IPV6) { 477d9e4c129SPaolo Abeni switch (optname) { 478d9e4c129SPaolo Abeni case IPV6_V6ONLY: 479d9e4c129SPaolo Abeni 480d9e4c129SPaolo Abeni /* the following are control cmsg related */ 481d9e4c129SPaolo Abeni case IPV6_RECVPKTINFO: 482d9e4c129SPaolo Abeni case IPV6_2292PKTINFO: 483d9e4c129SPaolo Abeni case IPV6_RECVHOPLIMIT: 484d9e4c129SPaolo Abeni case IPV6_2292HOPLIMIT: 485d9e4c129SPaolo Abeni case IPV6_RECVRTHDR: 486d9e4c129SPaolo Abeni case IPV6_2292RTHDR: 487d9e4c129SPaolo Abeni case IPV6_RECVHOPOPTS: 488d9e4c129SPaolo Abeni case IPV6_2292HOPOPTS: 489d9e4c129SPaolo Abeni case IPV6_RECVDSTOPTS: 490d9e4c129SPaolo Abeni case IPV6_2292DSTOPTS: 491d9e4c129SPaolo Abeni case IPV6_RECVTCLASS: 492d9e4c129SPaolo Abeni case IPV6_FLOWINFO: 493d9e4c129SPaolo Abeni case IPV6_RECVPATHMTU: 494d9e4c129SPaolo Abeni case IPV6_RECVORIGDSTADDR: 495d9e4c129SPaolo Abeni case IPV6_RECVFRAGSIZE: 496d9e4c129SPaolo Abeni 497d9e4c129SPaolo Abeni /* the following ones need some love but are quite common */ 498d9e4c129SPaolo Abeni case IPV6_TCLASS: 499d9e4c129SPaolo Abeni case IPV6_TRANSPARENT: 500d9e4c129SPaolo Abeni case IPV6_FREEBIND: 501d9e4c129SPaolo Abeni case IPV6_PKTINFO: 502d9e4c129SPaolo Abeni case IPV6_2292PKTOPTIONS: 503d9e4c129SPaolo Abeni case IPV6_UNICAST_HOPS: 504d9e4c129SPaolo Abeni case IPV6_MTU_DISCOVER: 505d9e4c129SPaolo Abeni case IPV6_MTU: 506d9e4c129SPaolo Abeni case IPV6_RECVERR: 507d9e4c129SPaolo Abeni case IPV6_FLOWINFO_SEND: 508d9e4c129SPaolo Abeni case IPV6_FLOWLABEL_MGR: 509d9e4c129SPaolo Abeni case IPV6_MINHOPCOUNT: 510d9e4c129SPaolo Abeni case IPV6_DONTFRAG: 511d9e4c129SPaolo Abeni case IPV6_AUTOFLOWLABEL: 512d9e4c129SPaolo Abeni 513d9e4c129SPaolo Abeni /* the following one is a no-op for plain TCP */ 514d9e4c129SPaolo Abeni case IPV6_RECVERR_RFC4884: 515d9e4c129SPaolo Abeni return true; 516d9e4c129SPaolo Abeni } 517d9e4c129SPaolo Abeni 518d9e4c129SPaolo Abeni /* IPV6_HOPOPTS, IPV6_RTHDRDSTOPTS, IPV6_RTHDR, IPV6_DSTOPTS are 519d9e4c129SPaolo Abeni * not supported 520d9e4c129SPaolo Abeni */ 521d9e4c129SPaolo Abeni /* IPV6_MULTICAST_HOPS, IPV6_MULTICAST_LOOP, IPV6_UNICAST_IF, 522d9e4c129SPaolo Abeni * IPV6_MULTICAST_IF, IPV6_ADDRFORM, 523d9e4c129SPaolo Abeni * IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_JOIN_ANYCAST, 524d9e4c129SPaolo Abeni * IPV6_LEAVE_ANYCAST, IPV6_MULTICAST_ALL, MCAST_JOIN_GROUP, MCAST_LEAVE_GROUP, 525d9e4c129SPaolo Abeni * MCAST_JOIN_SOURCE_GROUP, MCAST_LEAVE_SOURCE_GROUP, 526d9e4c129SPaolo Abeni * MCAST_BLOCK_SOURCE, MCAST_UNBLOCK_SOURCE, MCAST_MSFILTER 527d9e4c129SPaolo Abeni * are not supported better not deal with mcast 528d9e4c129SPaolo Abeni */ 529d9e4c129SPaolo Abeni /* IPV6_ROUTER_ALERT, IPV6_ROUTER_ALERT_ISOLATE are not supported, since are evil */ 530d9e4c129SPaolo Abeni 531d9e4c129SPaolo Abeni /* IPV6_IPSEC_POLICY, IPV6_XFRM_POLICY are not supported */ 532d9e4c129SPaolo Abeni /* IPV6_ADDR_PREFERENCES is not supported, we must be careful with subflows */ 533d9e4c129SPaolo Abeni return false; 534d9e4c129SPaolo Abeni } 535d9e4c129SPaolo Abeni if (level == SOL_TCP) { 536d9e4c129SPaolo Abeni switch (optname) { 537d9e4c129SPaolo Abeni /* the following are no-op or should work just fine */ 538d9e4c129SPaolo Abeni case TCP_THIN_DUPACK: 539d9e4c129SPaolo Abeni case TCP_DEFER_ACCEPT: 540d9e4c129SPaolo Abeni 541d9e4c129SPaolo Abeni /* the following need some love */ 542d9e4c129SPaolo Abeni case TCP_MAXSEG: 543d9e4c129SPaolo Abeni case TCP_NODELAY: 544d9e4c129SPaolo Abeni case TCP_THIN_LINEAR_TIMEOUTS: 545d9e4c129SPaolo Abeni case TCP_CONGESTION: 546d9e4c129SPaolo Abeni case TCP_CORK: 547d9e4c129SPaolo Abeni case TCP_KEEPIDLE: 548d9e4c129SPaolo Abeni case TCP_KEEPINTVL: 549d9e4c129SPaolo Abeni case TCP_KEEPCNT: 550d9e4c129SPaolo Abeni case TCP_SYNCNT: 551d9e4c129SPaolo Abeni case TCP_SAVE_SYN: 552d9e4c129SPaolo Abeni case TCP_LINGER2: 553d9e4c129SPaolo Abeni case TCP_WINDOW_CLAMP: 554d9e4c129SPaolo Abeni case TCP_QUICKACK: 555d9e4c129SPaolo Abeni case TCP_USER_TIMEOUT: 556d9e4c129SPaolo Abeni case TCP_TIMESTAMP: 557d9e4c129SPaolo Abeni case TCP_NOTSENT_LOWAT: 558d9e4c129SPaolo Abeni case TCP_TX_DELAY: 5592c9e7765SFlorian Westphal case TCP_INQ: 560d9e4c129SPaolo Abeni return true; 561d9e4c129SPaolo Abeni } 562d9e4c129SPaolo Abeni 563d9e4c129SPaolo Abeni /* TCP_MD5SIG, TCP_MD5SIG_EXT are not supported, MD5 is not compatible with MPTCP */ 564d9e4c129SPaolo Abeni 565d9e4c129SPaolo Abeni /* TCP_REPAIR, TCP_REPAIR_QUEUE, TCP_QUEUE_SEQ, TCP_REPAIR_OPTIONS, 566d9e4c129SPaolo Abeni * TCP_REPAIR_WINDOW are not supported, better avoid this mess 567d9e4c129SPaolo Abeni */ 568d9e4c129SPaolo Abeni /* TCP_FASTOPEN_KEY, TCP_FASTOPEN TCP_FASTOPEN_CONNECT, TCP_FASTOPEN_NO_COOKIE, 569d9e4c129SPaolo Abeni * are not supported fastopen is currently unsupported 570d9e4c129SPaolo Abeni */ 571d9e4c129SPaolo Abeni } 572d9e4c129SPaolo Abeni return false; 573d9e4c129SPaolo Abeni } 574d9e4c129SPaolo Abeni 575aa1fbd94SFlorian Westphal static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t optval, 576aa1fbd94SFlorian Westphal unsigned int optlen) 577aa1fbd94SFlorian Westphal { 578aa1fbd94SFlorian Westphal struct mptcp_subflow_context *subflow; 579aa1fbd94SFlorian Westphal struct sock *sk = (struct sock *)msk; 580aa1fbd94SFlorian Westphal char name[TCP_CA_NAME_MAX]; 581aa1fbd94SFlorian Westphal bool cap_net_admin; 582aa1fbd94SFlorian Westphal int ret; 583aa1fbd94SFlorian Westphal 584aa1fbd94SFlorian Westphal if (optlen < 1) 585aa1fbd94SFlorian Westphal return -EINVAL; 586aa1fbd94SFlorian Westphal 587aa1fbd94SFlorian Westphal ret = strncpy_from_sockptr(name, optval, 588aa1fbd94SFlorian Westphal min_t(long, TCP_CA_NAME_MAX - 1, optlen)); 589aa1fbd94SFlorian Westphal if (ret < 0) 590aa1fbd94SFlorian Westphal return -EFAULT; 591aa1fbd94SFlorian Westphal 592aa1fbd94SFlorian Westphal name[ret] = 0; 593aa1fbd94SFlorian Westphal 594aa1fbd94SFlorian Westphal cap_net_admin = ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN); 595aa1fbd94SFlorian Westphal 596aa1fbd94SFlorian Westphal ret = 0; 597aa1fbd94SFlorian Westphal lock_sock(sk); 598aa1fbd94SFlorian Westphal sockopt_seq_inc(msk); 599aa1fbd94SFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 600aa1fbd94SFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 601aa1fbd94SFlorian Westphal int err; 602aa1fbd94SFlorian Westphal 603aa1fbd94SFlorian Westphal lock_sock(ssk); 604aa1fbd94SFlorian Westphal err = tcp_set_congestion_control(ssk, name, true, cap_net_admin); 605aa1fbd94SFlorian Westphal if (err < 0 && ret == 0) 606aa1fbd94SFlorian Westphal ret = err; 607aa1fbd94SFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 608aa1fbd94SFlorian Westphal release_sock(ssk); 609aa1fbd94SFlorian Westphal } 610aa1fbd94SFlorian Westphal 611aa1fbd94SFlorian Westphal if (ret == 0) 61220b5759fSPaolo Abeni strcpy(msk->ca_name, name); 613aa1fbd94SFlorian Westphal 614aa1fbd94SFlorian Westphal release_sock(sk); 615aa1fbd94SFlorian Westphal return ret; 616aa1fbd94SFlorian Westphal } 617aa1fbd94SFlorian Westphal 6184f6e14bdSMaxim Galaganov static int mptcp_setsockopt_sol_tcp_cork(struct mptcp_sock *msk, sockptr_t optval, 6194f6e14bdSMaxim Galaganov unsigned int optlen) 6204f6e14bdSMaxim Galaganov { 6214f6e14bdSMaxim Galaganov struct mptcp_subflow_context *subflow; 6224f6e14bdSMaxim Galaganov struct sock *sk = (struct sock *)msk; 6234f6e14bdSMaxim Galaganov int val; 6244f6e14bdSMaxim Galaganov 6254f6e14bdSMaxim Galaganov if (optlen < sizeof(int)) 6264f6e14bdSMaxim Galaganov return -EINVAL; 6274f6e14bdSMaxim Galaganov 6284f6e14bdSMaxim Galaganov if (copy_from_sockptr(&val, optval, sizeof(val))) 6294f6e14bdSMaxim Galaganov return -EFAULT; 6304f6e14bdSMaxim Galaganov 6314f6e14bdSMaxim Galaganov lock_sock(sk); 6324f6e14bdSMaxim Galaganov sockopt_seq_inc(msk); 6334f6e14bdSMaxim Galaganov msk->cork = !!val; 6344f6e14bdSMaxim Galaganov mptcp_for_each_subflow(msk, subflow) { 6354f6e14bdSMaxim Galaganov struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 6364f6e14bdSMaxim Galaganov 6374f6e14bdSMaxim Galaganov lock_sock(ssk); 6384f6e14bdSMaxim Galaganov __tcp_sock_set_cork(ssk, !!val); 6394f6e14bdSMaxim Galaganov release_sock(ssk); 6404f6e14bdSMaxim Galaganov } 6414f6e14bdSMaxim Galaganov if (!val) 6424f6e14bdSMaxim Galaganov mptcp_check_and_set_pending(sk); 6434f6e14bdSMaxim Galaganov release_sock(sk); 6444f6e14bdSMaxim Galaganov 6454f6e14bdSMaxim Galaganov return 0; 6464f6e14bdSMaxim Galaganov } 6474f6e14bdSMaxim Galaganov 6484f6e14bdSMaxim Galaganov static int mptcp_setsockopt_sol_tcp_nodelay(struct mptcp_sock *msk, sockptr_t optval, 6494f6e14bdSMaxim Galaganov unsigned int optlen) 6504f6e14bdSMaxim Galaganov { 6514f6e14bdSMaxim Galaganov struct mptcp_subflow_context *subflow; 6524f6e14bdSMaxim Galaganov struct sock *sk = (struct sock *)msk; 6534f6e14bdSMaxim Galaganov int val; 6544f6e14bdSMaxim Galaganov 6554f6e14bdSMaxim Galaganov if (optlen < sizeof(int)) 6564f6e14bdSMaxim Galaganov return -EINVAL; 6574f6e14bdSMaxim Galaganov 6584f6e14bdSMaxim Galaganov if (copy_from_sockptr(&val, optval, sizeof(val))) 6594f6e14bdSMaxim Galaganov return -EFAULT; 6604f6e14bdSMaxim Galaganov 6614f6e14bdSMaxim Galaganov lock_sock(sk); 6624f6e14bdSMaxim Galaganov sockopt_seq_inc(msk); 6634f6e14bdSMaxim Galaganov msk->nodelay = !!val; 6644f6e14bdSMaxim Galaganov mptcp_for_each_subflow(msk, subflow) { 6654f6e14bdSMaxim Galaganov struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 6664f6e14bdSMaxim Galaganov 6674f6e14bdSMaxim Galaganov lock_sock(ssk); 6684f6e14bdSMaxim Galaganov __tcp_sock_set_nodelay(ssk, !!val); 6694f6e14bdSMaxim Galaganov release_sock(ssk); 6704f6e14bdSMaxim Galaganov } 6714f6e14bdSMaxim Galaganov if (val) 6724f6e14bdSMaxim Galaganov mptcp_check_and_set_pending(sk); 6734f6e14bdSMaxim Galaganov release_sock(sk); 6744f6e14bdSMaxim Galaganov 6754f6e14bdSMaxim Galaganov return 0; 6764f6e14bdSMaxim Galaganov } 6774f6e14bdSMaxim Galaganov 678c9406a23SFlorian Westphal static int mptcp_setsockopt_sol_ip_set_transparent(struct mptcp_sock *msk, int optname, 679c9406a23SFlorian Westphal sockptr_t optval, unsigned int optlen) 680c9406a23SFlorian Westphal { 681c9406a23SFlorian Westphal struct sock *sk = (struct sock *)msk; 682c9406a23SFlorian Westphal struct inet_sock *issk; 683c9406a23SFlorian Westphal struct socket *ssock; 684c9406a23SFlorian Westphal int err; 685c9406a23SFlorian Westphal 686c9406a23SFlorian Westphal err = ip_setsockopt(sk, SOL_IP, optname, optval, optlen); 687c9406a23SFlorian Westphal if (err != 0) 688c9406a23SFlorian Westphal return err; 689c9406a23SFlorian Westphal 690c9406a23SFlorian Westphal lock_sock(sk); 691c9406a23SFlorian Westphal 692c9406a23SFlorian Westphal ssock = __mptcp_nmpc_socket(msk); 693c9406a23SFlorian Westphal if (!ssock) { 694c9406a23SFlorian Westphal release_sock(sk); 695c9406a23SFlorian Westphal return -EINVAL; 696c9406a23SFlorian Westphal } 697c9406a23SFlorian Westphal 698c9406a23SFlorian Westphal issk = inet_sk(ssock->sk); 699c9406a23SFlorian Westphal 700c9406a23SFlorian Westphal switch (optname) { 701c9406a23SFlorian Westphal case IP_FREEBIND: 702c9406a23SFlorian Westphal issk->freebind = inet_sk(sk)->freebind; 703c9406a23SFlorian Westphal break; 704c9406a23SFlorian Westphal case IP_TRANSPARENT: 705c9406a23SFlorian Westphal issk->transparent = inet_sk(sk)->transparent; 706c9406a23SFlorian Westphal break; 707c9406a23SFlorian Westphal default: 708c9406a23SFlorian Westphal release_sock(sk); 709c9406a23SFlorian Westphal WARN_ON_ONCE(1); 710c9406a23SFlorian Westphal return -EOPNOTSUPP; 711c9406a23SFlorian Westphal } 712c9406a23SFlorian Westphal 713c9406a23SFlorian Westphal sockopt_seq_inc(msk); 714c9406a23SFlorian Westphal release_sock(sk); 715c9406a23SFlorian Westphal return 0; 716c9406a23SFlorian Westphal } 717c9406a23SFlorian Westphal 718ffcacff8SPoorva Sonparote static int mptcp_setsockopt_v4_set_tos(struct mptcp_sock *msk, int optname, 719ffcacff8SPoorva Sonparote sockptr_t optval, unsigned int optlen) 720ffcacff8SPoorva Sonparote { 721ffcacff8SPoorva Sonparote struct mptcp_subflow_context *subflow; 722ffcacff8SPoorva Sonparote struct sock *sk = (struct sock *)msk; 723ffcacff8SPoorva Sonparote int err, val; 724ffcacff8SPoorva Sonparote 725ffcacff8SPoorva Sonparote err = ip_setsockopt(sk, SOL_IP, optname, optval, optlen); 726ffcacff8SPoorva Sonparote 727ffcacff8SPoorva Sonparote if (err != 0) 728ffcacff8SPoorva Sonparote return err; 729ffcacff8SPoorva Sonparote 730ffcacff8SPoorva Sonparote lock_sock(sk); 731ffcacff8SPoorva Sonparote sockopt_seq_inc(msk); 732ffcacff8SPoorva Sonparote val = inet_sk(sk)->tos; 733ffcacff8SPoorva Sonparote mptcp_for_each_subflow(msk, subflow) { 734ffcacff8SPoorva Sonparote struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 735ffcacff8SPoorva Sonparote 736ffcacff8SPoorva Sonparote __ip_sock_set_tos(ssk, val); 737ffcacff8SPoorva Sonparote } 738ffcacff8SPoorva Sonparote release_sock(sk); 739ffcacff8SPoorva Sonparote 740ffcacff8SPoorva Sonparote return err; 741ffcacff8SPoorva Sonparote } 742ffcacff8SPoorva Sonparote 743ffcacff8SPoorva Sonparote static int mptcp_setsockopt_v4(struct mptcp_sock *msk, int optname, 744ffcacff8SPoorva Sonparote sockptr_t optval, unsigned int optlen) 745ffcacff8SPoorva Sonparote { 746ffcacff8SPoorva Sonparote switch (optname) { 747c9406a23SFlorian Westphal case IP_FREEBIND: 748c9406a23SFlorian Westphal case IP_TRANSPARENT: 749c9406a23SFlorian Westphal return mptcp_setsockopt_sol_ip_set_transparent(msk, optname, optval, optlen); 750ffcacff8SPoorva Sonparote case IP_TOS: 751ffcacff8SPoorva Sonparote return mptcp_setsockopt_v4_set_tos(msk, optname, optval, optlen); 752ffcacff8SPoorva Sonparote } 753ffcacff8SPoorva Sonparote 754ffcacff8SPoorva Sonparote return -EOPNOTSUPP; 755ffcacff8SPoorva Sonparote } 756ffcacff8SPoorva Sonparote 757aa1fbd94SFlorian Westphal static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname, 758aa1fbd94SFlorian Westphal sockptr_t optval, unsigned int optlen) 759aa1fbd94SFlorian Westphal { 7602c9e7765SFlorian Westphal struct sock *sk = (void *)msk; 7612c9e7765SFlorian Westphal int ret, val; 7622c9e7765SFlorian Westphal 763aa1fbd94SFlorian Westphal switch (optname) { 7642c9e7765SFlorian Westphal case TCP_INQ: 7652c9e7765SFlorian Westphal ret = mptcp_get_int_option(msk, optval, optlen, &val); 7662c9e7765SFlorian Westphal if (ret) 7672c9e7765SFlorian Westphal return ret; 7682c9e7765SFlorian Westphal if (val < 0 || val > 1) 7692c9e7765SFlorian Westphal return -EINVAL; 7702c9e7765SFlorian Westphal 7712c9e7765SFlorian Westphal lock_sock(sk); 7722c9e7765SFlorian Westphal msk->recvmsg_inq = !!val; 7732c9e7765SFlorian Westphal release_sock(sk); 7742c9e7765SFlorian Westphal return 0; 775aa1fbd94SFlorian Westphal case TCP_ULP: 776aa1fbd94SFlorian Westphal return -EOPNOTSUPP; 777aa1fbd94SFlorian Westphal case TCP_CONGESTION: 778aa1fbd94SFlorian Westphal return mptcp_setsockopt_sol_tcp_congestion(msk, optval, optlen); 7794f6e14bdSMaxim Galaganov case TCP_CORK: 7804f6e14bdSMaxim Galaganov return mptcp_setsockopt_sol_tcp_cork(msk, optval, optlen); 7814f6e14bdSMaxim Galaganov case TCP_NODELAY: 7824f6e14bdSMaxim Galaganov return mptcp_setsockopt_sol_tcp_nodelay(msk, optval, optlen); 783aa1fbd94SFlorian Westphal } 784aa1fbd94SFlorian Westphal 785aa1fbd94SFlorian Westphal return -EOPNOTSUPP; 786aa1fbd94SFlorian Westphal } 787aa1fbd94SFlorian Westphal 7880abdde82SPaolo Abeni int mptcp_setsockopt(struct sock *sk, int level, int optname, 7890abdde82SPaolo Abeni sockptr_t optval, unsigned int optlen) 7900abdde82SPaolo Abeni { 7910abdde82SPaolo Abeni struct mptcp_sock *msk = mptcp_sk(sk); 7920abdde82SPaolo Abeni struct sock *ssk; 7930abdde82SPaolo Abeni 7940abdde82SPaolo Abeni pr_debug("msk=%p", msk); 7950abdde82SPaolo Abeni 7960abdde82SPaolo Abeni if (level == SOL_SOCKET) 7970abdde82SPaolo Abeni return mptcp_setsockopt_sol_socket(msk, optname, optval, optlen); 7980abdde82SPaolo Abeni 7997a009a70SFlorian Westphal if (!mptcp_supported_sockopt(level, optname)) 8007a009a70SFlorian Westphal return -ENOPROTOOPT; 8017a009a70SFlorian Westphal 8020abdde82SPaolo Abeni /* @@ the meaning of setsockopt() when the socket is connected and 8030abdde82SPaolo Abeni * there are multiple subflows is not yet defined. It is up to the 8040abdde82SPaolo Abeni * MPTCP-level socket to configure the subflows until the subflow 8050abdde82SPaolo Abeni * is in TCP fallback, when TCP socket options are passed through 8060abdde82SPaolo Abeni * to the one remaining subflow. 8070abdde82SPaolo Abeni */ 8080abdde82SPaolo Abeni lock_sock(sk); 8090abdde82SPaolo Abeni ssk = __mptcp_tcp_fallback(msk); 8100abdde82SPaolo Abeni release_sock(sk); 8110abdde82SPaolo Abeni if (ssk) 8120abdde82SPaolo Abeni return tcp_setsockopt(ssk, level, optname, optval, optlen); 8130abdde82SPaolo Abeni 814ffcacff8SPoorva Sonparote if (level == SOL_IP) 815ffcacff8SPoorva Sonparote return mptcp_setsockopt_v4(msk, optname, optval, optlen); 816ffcacff8SPoorva Sonparote 8170abdde82SPaolo Abeni if (level == SOL_IPV6) 8180abdde82SPaolo Abeni return mptcp_setsockopt_v6(msk, optname, optval, optlen); 8190abdde82SPaolo Abeni 820aa1fbd94SFlorian Westphal if (level == SOL_TCP) 821aa1fbd94SFlorian Westphal return mptcp_setsockopt_sol_tcp(msk, optname, optval, optlen); 822aa1fbd94SFlorian Westphal 823aa1fbd94SFlorian Westphal return -EOPNOTSUPP; 824aa1fbd94SFlorian Westphal } 825aa1fbd94SFlorian Westphal 826aa1fbd94SFlorian Westphal static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int optname, 827aa1fbd94SFlorian Westphal char __user *optval, int __user *optlen) 828aa1fbd94SFlorian Westphal { 829aa1fbd94SFlorian Westphal struct sock *sk = (struct sock *)msk; 830aa1fbd94SFlorian Westphal struct socket *ssock; 831aa1fbd94SFlorian Westphal int ret = -EINVAL; 832aa1fbd94SFlorian Westphal struct sock *ssk; 833aa1fbd94SFlorian Westphal 834aa1fbd94SFlorian Westphal lock_sock(sk); 835aa1fbd94SFlorian Westphal ssk = msk->first; 836aa1fbd94SFlorian Westphal if (ssk) { 837aa1fbd94SFlorian Westphal ret = tcp_getsockopt(ssk, level, optname, optval, optlen); 838aa1fbd94SFlorian Westphal goto out; 839aa1fbd94SFlorian Westphal } 840aa1fbd94SFlorian Westphal 841aa1fbd94SFlorian Westphal ssock = __mptcp_nmpc_socket(msk); 842aa1fbd94SFlorian Westphal if (!ssock) 843aa1fbd94SFlorian Westphal goto out; 844aa1fbd94SFlorian Westphal 845aa1fbd94SFlorian Westphal ret = tcp_getsockopt(ssock->sk, level, optname, optval, optlen); 846aa1fbd94SFlorian Westphal 847aa1fbd94SFlorian Westphal out: 848aa1fbd94SFlorian Westphal release_sock(sk); 849aa1fbd94SFlorian Westphal return ret; 850aa1fbd94SFlorian Westphal } 851aa1fbd94SFlorian Westphal 85261bc6e82SFlorian Westphal void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info) 85361bc6e82SFlorian Westphal { 85461bc6e82SFlorian Westphal struct sock *sk = &msk->sk.icsk_inet.sk; 85561bc6e82SFlorian Westphal u32 flags = 0; 85655c42fa7SFlorian Westphal bool slow; 85761bc6e82SFlorian Westphal u8 val; 85861bc6e82SFlorian Westphal 85955c42fa7SFlorian Westphal memset(info, 0, sizeof(*info)); 86055c42fa7SFlorian Westphal 86155c42fa7SFlorian Westphal slow = lock_sock_fast(sk); 86255c42fa7SFlorian Westphal 86361bc6e82SFlorian Westphal info->mptcpi_subflows = READ_ONCE(msk->pm.subflows); 86461bc6e82SFlorian Westphal info->mptcpi_add_addr_signal = READ_ONCE(msk->pm.add_addr_signaled); 86561bc6e82SFlorian Westphal info->mptcpi_add_addr_accepted = READ_ONCE(msk->pm.add_addr_accepted); 86661bc6e82SFlorian Westphal info->mptcpi_local_addr_used = READ_ONCE(msk->pm.local_addr_used); 86761bc6e82SFlorian Westphal info->mptcpi_subflows_max = mptcp_pm_get_subflows_max(msk); 86861bc6e82SFlorian Westphal val = mptcp_pm_get_add_addr_signal_max(msk); 86961bc6e82SFlorian Westphal info->mptcpi_add_addr_signal_max = val; 87061bc6e82SFlorian Westphal val = mptcp_pm_get_add_addr_accept_max(msk); 87161bc6e82SFlorian Westphal info->mptcpi_add_addr_accepted_max = val; 87261bc6e82SFlorian Westphal info->mptcpi_local_addr_max = mptcp_pm_get_local_addr_max(msk); 87361bc6e82SFlorian Westphal if (test_bit(MPTCP_FALLBACK_DONE, &msk->flags)) 87461bc6e82SFlorian Westphal flags |= MPTCP_INFO_FLAG_FALLBACK; 87561bc6e82SFlorian Westphal if (READ_ONCE(msk->can_ack)) 87661bc6e82SFlorian Westphal flags |= MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED; 87761bc6e82SFlorian Westphal info->mptcpi_flags = flags; 87861bc6e82SFlorian Westphal info->mptcpi_token = READ_ONCE(msk->token); 87961bc6e82SFlorian Westphal info->mptcpi_write_seq = READ_ONCE(msk->write_seq); 88061bc6e82SFlorian Westphal info->mptcpi_snd_una = READ_ONCE(msk->snd_una); 88161bc6e82SFlorian Westphal info->mptcpi_rcv_nxt = READ_ONCE(msk->ack_seq); 88261bc6e82SFlorian Westphal info->mptcpi_csum_enabled = READ_ONCE(msk->csum_enabled); 88361bc6e82SFlorian Westphal 88461bc6e82SFlorian Westphal unlock_sock_fast(sk, slow); 88561bc6e82SFlorian Westphal } 88661bc6e82SFlorian Westphal EXPORT_SYMBOL_GPL(mptcp_diag_fill_info); 88761bc6e82SFlorian Westphal 88855c42fa7SFlorian Westphal static int mptcp_getsockopt_info(struct mptcp_sock *msk, char __user *optval, int __user *optlen) 88955c42fa7SFlorian Westphal { 89055c42fa7SFlorian Westphal struct mptcp_info m_info; 89155c42fa7SFlorian Westphal int len; 89255c42fa7SFlorian Westphal 89355c42fa7SFlorian Westphal if (get_user(len, optlen)) 89455c42fa7SFlorian Westphal return -EFAULT; 89555c42fa7SFlorian Westphal 89655c42fa7SFlorian Westphal len = min_t(unsigned int, len, sizeof(struct mptcp_info)); 89755c42fa7SFlorian Westphal 89855c42fa7SFlorian Westphal mptcp_diag_fill_info(msk, &m_info); 89955c42fa7SFlorian Westphal 90055c42fa7SFlorian Westphal if (put_user(len, optlen)) 90155c42fa7SFlorian Westphal return -EFAULT; 90255c42fa7SFlorian Westphal 90355c42fa7SFlorian Westphal if (copy_to_user(optval, &m_info, len)) 90455c42fa7SFlorian Westphal return -EFAULT; 90555c42fa7SFlorian Westphal 90655c42fa7SFlorian Westphal return 0; 90755c42fa7SFlorian Westphal } 90855c42fa7SFlorian Westphal 90906f15ceeSFlorian Westphal static int mptcp_put_subflow_data(struct mptcp_subflow_data *sfd, 91006f15ceeSFlorian Westphal char __user *optval, 91106f15ceeSFlorian Westphal u32 copied, 91206f15ceeSFlorian Westphal int __user *optlen) 91306f15ceeSFlorian Westphal { 91406f15ceeSFlorian Westphal u32 copylen = min_t(u32, sfd->size_subflow_data, sizeof(*sfd)); 91506f15ceeSFlorian Westphal 91606f15ceeSFlorian Westphal if (copied) 91706f15ceeSFlorian Westphal copied += sfd->size_subflow_data; 91806f15ceeSFlorian Westphal else 91906f15ceeSFlorian Westphal copied = copylen; 92006f15ceeSFlorian Westphal 92106f15ceeSFlorian Westphal if (put_user(copied, optlen)) 92206f15ceeSFlorian Westphal return -EFAULT; 92306f15ceeSFlorian Westphal 92406f15ceeSFlorian Westphal if (copy_to_user(optval, sfd, copylen)) 92506f15ceeSFlorian Westphal return -EFAULT; 92606f15ceeSFlorian Westphal 92706f15ceeSFlorian Westphal return 0; 92806f15ceeSFlorian Westphal } 92906f15ceeSFlorian Westphal 93006f15ceeSFlorian Westphal static int mptcp_get_subflow_data(struct mptcp_subflow_data *sfd, 93106f15ceeSFlorian Westphal char __user *optval, int __user *optlen) 93206f15ceeSFlorian Westphal { 93306f15ceeSFlorian Westphal int len, copylen; 93406f15ceeSFlorian Westphal 93506f15ceeSFlorian Westphal if (get_user(len, optlen)) 93606f15ceeSFlorian Westphal return -EFAULT; 93706f15ceeSFlorian Westphal 93806f15ceeSFlorian Westphal /* if mptcp_subflow_data size is changed, need to adjust 93906f15ceeSFlorian Westphal * this function to deal with programs using old version. 94006f15ceeSFlorian Westphal */ 94106f15ceeSFlorian Westphal BUILD_BUG_ON(sizeof(*sfd) != MIN_INFO_OPTLEN_SIZE); 94206f15ceeSFlorian Westphal 94306f15ceeSFlorian Westphal if (len < MIN_INFO_OPTLEN_SIZE) 94406f15ceeSFlorian Westphal return -EINVAL; 94506f15ceeSFlorian Westphal 94606f15ceeSFlorian Westphal memset(sfd, 0, sizeof(*sfd)); 94706f15ceeSFlorian Westphal 94806f15ceeSFlorian Westphal copylen = min_t(unsigned int, len, sizeof(*sfd)); 94906f15ceeSFlorian Westphal if (copy_from_user(sfd, optval, copylen)) 95006f15ceeSFlorian Westphal return -EFAULT; 95106f15ceeSFlorian Westphal 95206f15ceeSFlorian Westphal /* size_subflow_data is u32, but len is signed */ 95306f15ceeSFlorian Westphal if (sfd->size_subflow_data > INT_MAX || 95406f15ceeSFlorian Westphal sfd->size_user > INT_MAX) 95506f15ceeSFlorian Westphal return -EINVAL; 95606f15ceeSFlorian Westphal 95706f15ceeSFlorian Westphal if (sfd->size_subflow_data < MIN_INFO_OPTLEN_SIZE || 95806f15ceeSFlorian Westphal sfd->size_subflow_data > len) 95906f15ceeSFlorian Westphal return -EINVAL; 96006f15ceeSFlorian Westphal 96106f15ceeSFlorian Westphal if (sfd->num_subflows || sfd->size_kernel) 96206f15ceeSFlorian Westphal return -EINVAL; 96306f15ceeSFlorian Westphal 96406f15ceeSFlorian Westphal return len - sfd->size_subflow_data; 96506f15ceeSFlorian Westphal } 96606f15ceeSFlorian Westphal 96706f15ceeSFlorian Westphal static int mptcp_getsockopt_tcpinfo(struct mptcp_sock *msk, char __user *optval, 96806f15ceeSFlorian Westphal int __user *optlen) 96906f15ceeSFlorian Westphal { 97006f15ceeSFlorian Westphal struct mptcp_subflow_context *subflow; 97106f15ceeSFlorian Westphal struct sock *sk = &msk->sk.icsk_inet.sk; 97206f15ceeSFlorian Westphal unsigned int sfcount = 0, copied = 0; 97306f15ceeSFlorian Westphal struct mptcp_subflow_data sfd; 97406f15ceeSFlorian Westphal char __user *infoptr; 97506f15ceeSFlorian Westphal int len; 97606f15ceeSFlorian Westphal 97706f15ceeSFlorian Westphal len = mptcp_get_subflow_data(&sfd, optval, optlen); 97806f15ceeSFlorian Westphal if (len < 0) 97906f15ceeSFlorian Westphal return len; 98006f15ceeSFlorian Westphal 98106f15ceeSFlorian Westphal sfd.size_kernel = sizeof(struct tcp_info); 98206f15ceeSFlorian Westphal sfd.size_user = min_t(unsigned int, sfd.size_user, 98306f15ceeSFlorian Westphal sizeof(struct tcp_info)); 98406f15ceeSFlorian Westphal 98506f15ceeSFlorian Westphal infoptr = optval + sfd.size_subflow_data; 98606f15ceeSFlorian Westphal 98706f15ceeSFlorian Westphal lock_sock(sk); 98806f15ceeSFlorian Westphal 98906f15ceeSFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 99006f15ceeSFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 99106f15ceeSFlorian Westphal 99206f15ceeSFlorian Westphal ++sfcount; 99306f15ceeSFlorian Westphal 99406f15ceeSFlorian Westphal if (len && len >= sfd.size_user) { 99506f15ceeSFlorian Westphal struct tcp_info info; 99606f15ceeSFlorian Westphal 99706f15ceeSFlorian Westphal tcp_get_info(ssk, &info); 99806f15ceeSFlorian Westphal 99906f15ceeSFlorian Westphal if (copy_to_user(infoptr, &info, sfd.size_user)) { 100006f15ceeSFlorian Westphal release_sock(sk); 100106f15ceeSFlorian Westphal return -EFAULT; 100206f15ceeSFlorian Westphal } 100306f15ceeSFlorian Westphal 100406f15ceeSFlorian Westphal infoptr += sfd.size_user; 100506f15ceeSFlorian Westphal copied += sfd.size_user; 100606f15ceeSFlorian Westphal len -= sfd.size_user; 100706f15ceeSFlorian Westphal } 100806f15ceeSFlorian Westphal } 100906f15ceeSFlorian Westphal 101006f15ceeSFlorian Westphal release_sock(sk); 101106f15ceeSFlorian Westphal 101206f15ceeSFlorian Westphal sfd.num_subflows = sfcount; 101306f15ceeSFlorian Westphal 101406f15ceeSFlorian Westphal if (mptcp_put_subflow_data(&sfd, optval, copied, optlen)) 101506f15ceeSFlorian Westphal return -EFAULT; 101606f15ceeSFlorian Westphal 101706f15ceeSFlorian Westphal return 0; 101806f15ceeSFlorian Westphal } 101906f15ceeSFlorian Westphal 1020c11c5906SFlorian Westphal static void mptcp_get_sub_addrs(const struct sock *sk, struct mptcp_subflow_addrs *a) 1021c11c5906SFlorian Westphal { 1022c11c5906SFlorian Westphal struct inet_sock *inet = inet_sk(sk); 1023c11c5906SFlorian Westphal 1024c11c5906SFlorian Westphal memset(a, 0, sizeof(*a)); 1025c11c5906SFlorian Westphal 1026c11c5906SFlorian Westphal if (sk->sk_family == AF_INET) { 1027c11c5906SFlorian Westphal a->sin_local.sin_family = AF_INET; 1028c11c5906SFlorian Westphal a->sin_local.sin_port = inet->inet_sport; 1029c11c5906SFlorian Westphal a->sin_local.sin_addr.s_addr = inet->inet_rcv_saddr; 1030c11c5906SFlorian Westphal 1031c11c5906SFlorian Westphal if (!a->sin_local.sin_addr.s_addr) 1032c11c5906SFlorian Westphal a->sin_local.sin_addr.s_addr = inet->inet_saddr; 1033c11c5906SFlorian Westphal 1034c11c5906SFlorian Westphal a->sin_remote.sin_family = AF_INET; 1035c11c5906SFlorian Westphal a->sin_remote.sin_port = inet->inet_dport; 1036c11c5906SFlorian Westphal a->sin_remote.sin_addr.s_addr = inet->inet_daddr; 1037c11c5906SFlorian Westphal #if IS_ENABLED(CONFIG_IPV6) 1038c11c5906SFlorian Westphal } else if (sk->sk_family == AF_INET6) { 1039c11c5906SFlorian Westphal const struct ipv6_pinfo *np = inet6_sk(sk); 1040c11c5906SFlorian Westphal 104129211e7dSTim Gardner if (WARN_ON_ONCE(!np)) 104229211e7dSTim Gardner return; 104329211e7dSTim Gardner 1044c11c5906SFlorian Westphal a->sin6_local.sin6_family = AF_INET6; 1045c11c5906SFlorian Westphal a->sin6_local.sin6_port = inet->inet_sport; 1046c11c5906SFlorian Westphal 1047c11c5906SFlorian Westphal if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) 1048c11c5906SFlorian Westphal a->sin6_local.sin6_addr = np->saddr; 1049c11c5906SFlorian Westphal else 1050c11c5906SFlorian Westphal a->sin6_local.sin6_addr = sk->sk_v6_rcv_saddr; 1051c11c5906SFlorian Westphal 1052c11c5906SFlorian Westphal a->sin6_remote.sin6_family = AF_INET6; 1053c11c5906SFlorian Westphal a->sin6_remote.sin6_port = inet->inet_dport; 1054c11c5906SFlorian Westphal a->sin6_remote.sin6_addr = sk->sk_v6_daddr; 1055c11c5906SFlorian Westphal #endif 1056c11c5906SFlorian Westphal } 1057c11c5906SFlorian Westphal } 1058c11c5906SFlorian Westphal 1059c11c5906SFlorian Westphal static int mptcp_getsockopt_subflow_addrs(struct mptcp_sock *msk, char __user *optval, 1060c11c5906SFlorian Westphal int __user *optlen) 1061c11c5906SFlorian Westphal { 1062c11c5906SFlorian Westphal struct sock *sk = &msk->sk.icsk_inet.sk; 1063c11c5906SFlorian Westphal struct mptcp_subflow_context *subflow; 1064c11c5906SFlorian Westphal unsigned int sfcount = 0, copied = 0; 1065c11c5906SFlorian Westphal struct mptcp_subflow_data sfd; 1066c11c5906SFlorian Westphal char __user *addrptr; 1067c11c5906SFlorian Westphal int len; 1068c11c5906SFlorian Westphal 1069c11c5906SFlorian Westphal len = mptcp_get_subflow_data(&sfd, optval, optlen); 1070c11c5906SFlorian Westphal if (len < 0) 1071c11c5906SFlorian Westphal return len; 1072c11c5906SFlorian Westphal 1073c11c5906SFlorian Westphal sfd.size_kernel = sizeof(struct mptcp_subflow_addrs); 1074c11c5906SFlorian Westphal sfd.size_user = min_t(unsigned int, sfd.size_user, 1075c11c5906SFlorian Westphal sizeof(struct mptcp_subflow_addrs)); 1076c11c5906SFlorian Westphal 1077c11c5906SFlorian Westphal addrptr = optval + sfd.size_subflow_data; 1078c11c5906SFlorian Westphal 1079c11c5906SFlorian Westphal lock_sock(sk); 1080c11c5906SFlorian Westphal 1081c11c5906SFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 1082c11c5906SFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 1083c11c5906SFlorian Westphal 1084c11c5906SFlorian Westphal ++sfcount; 1085c11c5906SFlorian Westphal 1086c11c5906SFlorian Westphal if (len && len >= sfd.size_user) { 1087c11c5906SFlorian Westphal struct mptcp_subflow_addrs a; 1088c11c5906SFlorian Westphal 1089c11c5906SFlorian Westphal mptcp_get_sub_addrs(ssk, &a); 1090c11c5906SFlorian Westphal 1091c11c5906SFlorian Westphal if (copy_to_user(addrptr, &a, sfd.size_user)) { 1092c11c5906SFlorian Westphal release_sock(sk); 1093c11c5906SFlorian Westphal return -EFAULT; 1094c11c5906SFlorian Westphal } 1095c11c5906SFlorian Westphal 1096c11c5906SFlorian Westphal addrptr += sfd.size_user; 1097c11c5906SFlorian Westphal copied += sfd.size_user; 1098c11c5906SFlorian Westphal len -= sfd.size_user; 1099c11c5906SFlorian Westphal } 1100c11c5906SFlorian Westphal } 1101c11c5906SFlorian Westphal 1102c11c5906SFlorian Westphal release_sock(sk); 1103c11c5906SFlorian Westphal 1104c11c5906SFlorian Westphal sfd.num_subflows = sfcount; 1105c11c5906SFlorian Westphal 1106c11c5906SFlorian Westphal if (mptcp_put_subflow_data(&sfd, optval, copied, optlen)) 1107c11c5906SFlorian Westphal return -EFAULT; 1108c11c5906SFlorian Westphal 1109c11c5906SFlorian Westphal return 0; 1110c11c5906SFlorian Westphal } 1111c11c5906SFlorian Westphal 11122c9e7765SFlorian Westphal static int mptcp_put_int_option(struct mptcp_sock *msk, char __user *optval, 11132c9e7765SFlorian Westphal int __user *optlen, int val) 11142c9e7765SFlorian Westphal { 11152c9e7765SFlorian Westphal int len; 11162c9e7765SFlorian Westphal 11172c9e7765SFlorian Westphal if (get_user(len, optlen)) 11182c9e7765SFlorian Westphal return -EFAULT; 11192c9e7765SFlorian Westphal if (len < 0) 11202c9e7765SFlorian Westphal return -EINVAL; 11212c9e7765SFlorian Westphal 11223b1e21ebSFlorian Westphal if (len < sizeof(int) && len > 0 && val >= 0 && val <= 255) { 11233b1e21ebSFlorian Westphal unsigned char ucval = (unsigned char)val; 11243b1e21ebSFlorian Westphal 11253b1e21ebSFlorian Westphal len = 1; 11263b1e21ebSFlorian Westphal if (put_user(len, optlen)) 11273b1e21ebSFlorian Westphal return -EFAULT; 11283b1e21ebSFlorian Westphal if (copy_to_user(optval, &ucval, 1)) 11293b1e21ebSFlorian Westphal return -EFAULT; 11303b1e21ebSFlorian Westphal } else { 11313b1e21ebSFlorian Westphal len = min_t(unsigned int, len, sizeof(int)); 11322c9e7765SFlorian Westphal if (put_user(len, optlen)) 11332c9e7765SFlorian Westphal return -EFAULT; 11342c9e7765SFlorian Westphal if (copy_to_user(optval, &val, len)) 11352c9e7765SFlorian Westphal return -EFAULT; 11363b1e21ebSFlorian Westphal } 11372c9e7765SFlorian Westphal 11382c9e7765SFlorian Westphal return 0; 11392c9e7765SFlorian Westphal } 11402c9e7765SFlorian Westphal 1141aa1fbd94SFlorian Westphal static int mptcp_getsockopt_sol_tcp(struct mptcp_sock *msk, int optname, 1142aa1fbd94SFlorian Westphal char __user *optval, int __user *optlen) 1143aa1fbd94SFlorian Westphal { 1144aa1fbd94SFlorian Westphal switch (optname) { 1145aa1fbd94SFlorian Westphal case TCP_ULP: 1146aa1fbd94SFlorian Westphal case TCP_CONGESTION: 1147aa1fbd94SFlorian Westphal case TCP_INFO: 1148aa1fbd94SFlorian Westphal case TCP_CC_INFO: 1149aa1fbd94SFlorian Westphal return mptcp_getsockopt_first_sf_only(msk, SOL_TCP, optname, 1150aa1fbd94SFlorian Westphal optval, optlen); 11512c9e7765SFlorian Westphal case TCP_INQ: 11522c9e7765SFlorian Westphal return mptcp_put_int_option(msk, optval, optlen, msk->recvmsg_inq); 11534f6e14bdSMaxim Galaganov case TCP_CORK: 11544f6e14bdSMaxim Galaganov return mptcp_put_int_option(msk, optval, optlen, msk->cork); 11554f6e14bdSMaxim Galaganov case TCP_NODELAY: 11564f6e14bdSMaxim Galaganov return mptcp_put_int_option(msk, optval, optlen, msk->nodelay); 1157aa1fbd94SFlorian Westphal } 11580abdde82SPaolo Abeni return -EOPNOTSUPP; 11590abdde82SPaolo Abeni } 11600abdde82SPaolo Abeni 11613b1e21ebSFlorian Westphal static int mptcp_getsockopt_v4(struct mptcp_sock *msk, int optname, 11623b1e21ebSFlorian Westphal char __user *optval, int __user *optlen) 11633b1e21ebSFlorian Westphal { 11643b1e21ebSFlorian Westphal struct sock *sk = (void *)msk; 11653b1e21ebSFlorian Westphal 11663b1e21ebSFlorian Westphal switch (optname) { 11673b1e21ebSFlorian Westphal case IP_TOS: 11683b1e21ebSFlorian Westphal return mptcp_put_int_option(msk, optval, optlen, inet_sk(sk)->tos); 11693b1e21ebSFlorian Westphal } 11703b1e21ebSFlorian Westphal 11713b1e21ebSFlorian Westphal return -EOPNOTSUPP; 11723b1e21ebSFlorian Westphal } 11733b1e21ebSFlorian Westphal 117455c42fa7SFlorian Westphal static int mptcp_getsockopt_sol_mptcp(struct mptcp_sock *msk, int optname, 117555c42fa7SFlorian Westphal char __user *optval, int __user *optlen) 117655c42fa7SFlorian Westphal { 117755c42fa7SFlorian Westphal switch (optname) { 117855c42fa7SFlorian Westphal case MPTCP_INFO: 117955c42fa7SFlorian Westphal return mptcp_getsockopt_info(msk, optval, optlen); 118006f15ceeSFlorian Westphal case MPTCP_TCPINFO: 118106f15ceeSFlorian Westphal return mptcp_getsockopt_tcpinfo(msk, optval, optlen); 1182c11c5906SFlorian Westphal case MPTCP_SUBFLOW_ADDRS: 1183c11c5906SFlorian Westphal return mptcp_getsockopt_subflow_addrs(msk, optval, optlen); 118455c42fa7SFlorian Westphal } 118555c42fa7SFlorian Westphal 118655c42fa7SFlorian Westphal return -EOPNOTSUPP; 118755c42fa7SFlorian Westphal } 118855c42fa7SFlorian Westphal 11890abdde82SPaolo Abeni int mptcp_getsockopt(struct sock *sk, int level, int optname, 11900abdde82SPaolo Abeni char __user *optval, int __user *option) 11910abdde82SPaolo Abeni { 11920abdde82SPaolo Abeni struct mptcp_sock *msk = mptcp_sk(sk); 11930abdde82SPaolo Abeni struct sock *ssk; 11940abdde82SPaolo Abeni 11950abdde82SPaolo Abeni pr_debug("msk=%p", msk); 11960abdde82SPaolo Abeni 11970abdde82SPaolo Abeni /* @@ the meaning of setsockopt() when the socket is connected and 11980abdde82SPaolo Abeni * there are multiple subflows is not yet defined. It is up to the 11990abdde82SPaolo Abeni * MPTCP-level socket to configure the subflows until the subflow 12000abdde82SPaolo Abeni * is in TCP fallback, when socket options are passed through 12010abdde82SPaolo Abeni * to the one remaining subflow. 12020abdde82SPaolo Abeni */ 12030abdde82SPaolo Abeni lock_sock(sk); 12040abdde82SPaolo Abeni ssk = __mptcp_tcp_fallback(msk); 12050abdde82SPaolo Abeni release_sock(sk); 12060abdde82SPaolo Abeni if (ssk) 12070abdde82SPaolo Abeni return tcp_getsockopt(ssk, level, optname, optval, option); 12080abdde82SPaolo Abeni 12093b1e21ebSFlorian Westphal if (level == SOL_IP) 12103b1e21ebSFlorian Westphal return mptcp_getsockopt_v4(msk, optname, optval, option); 1211aa1fbd94SFlorian Westphal if (level == SOL_TCP) 1212aa1fbd94SFlorian Westphal return mptcp_getsockopt_sol_tcp(msk, optname, optval, option); 121355c42fa7SFlorian Westphal if (level == SOL_MPTCP) 121455c42fa7SFlorian Westphal return mptcp_getsockopt_sol_mptcp(msk, optname, optval, option); 12150abdde82SPaolo Abeni return -EOPNOTSUPP; 12160abdde82SPaolo Abeni } 12170abdde82SPaolo Abeni 12181b3e7edeSFlorian Westphal static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk) 12191b3e7edeSFlorian Westphal { 12205d0a6bc8SFlorian Westphal static const unsigned int tx_rx_locks = SOCK_RCVBUF_LOCK | SOCK_SNDBUF_LOCK; 12211b3e7edeSFlorian Westphal struct sock *sk = (struct sock *)msk; 12221b3e7edeSFlorian Westphal 12231b3e7edeSFlorian Westphal if (ssk->sk_prot->keepalive) { 12241b3e7edeSFlorian Westphal if (sock_flag(sk, SOCK_KEEPOPEN)) 12251b3e7edeSFlorian Westphal ssk->sk_prot->keepalive(ssk, 1); 12261b3e7edeSFlorian Westphal else 12271b3e7edeSFlorian Westphal ssk->sk_prot->keepalive(ssk, 0); 12281b3e7edeSFlorian Westphal } 12291b3e7edeSFlorian Westphal 12301b3e7edeSFlorian Westphal ssk->sk_priority = sk->sk_priority; 12315d0a6bc8SFlorian Westphal ssk->sk_bound_dev_if = sk->sk_bound_dev_if; 12325d0a6bc8SFlorian Westphal ssk->sk_incoming_cpu = sk->sk_incoming_cpu; 1233ffcacff8SPoorva Sonparote __ip_sock_set_tos(ssk, inet_sk(sk)->tos); 12345d0a6bc8SFlorian Westphal 12355d0a6bc8SFlorian Westphal if (sk->sk_userlocks & tx_rx_locks) { 12365d0a6bc8SFlorian Westphal ssk->sk_userlocks |= sk->sk_userlocks & tx_rx_locks; 12375d0a6bc8SFlorian Westphal if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) 12385d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_sndbuf, sk->sk_sndbuf); 12395d0a6bc8SFlorian Westphal if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) 12405d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf); 12415d0a6bc8SFlorian Westphal } 12425d0a6bc8SFlorian Westphal 12435d0a6bc8SFlorian Westphal if (sock_flag(sk, SOCK_LINGER)) { 12445d0a6bc8SFlorian Westphal ssk->sk_lingertime = sk->sk_lingertime; 12455d0a6bc8SFlorian Westphal sock_set_flag(ssk, SOCK_LINGER); 12465d0a6bc8SFlorian Westphal } else { 12475d0a6bc8SFlorian Westphal sock_reset_flag(ssk, SOCK_LINGER); 12485d0a6bc8SFlorian Westphal } 12495d0a6bc8SFlorian Westphal 12505d0a6bc8SFlorian Westphal if (sk->sk_mark != ssk->sk_mark) { 12515d0a6bc8SFlorian Westphal ssk->sk_mark = sk->sk_mark; 12525d0a6bc8SFlorian Westphal sk_dst_reset(ssk); 12535d0a6bc8SFlorian Westphal } 12545d0a6bc8SFlorian Westphal 12555d0a6bc8SFlorian Westphal sock_valbool_flag(ssk, SOCK_DBG, sock_flag(sk, SOCK_DBG)); 12565d0a6bc8SFlorian Westphal 12575d0a6bc8SFlorian Westphal if (inet_csk(sk)->icsk_ca_ops != inet_csk(ssk)->icsk_ca_ops) 125820b5759fSPaolo Abeni tcp_set_congestion_control(ssk, msk->ca_name, false, true); 12594f6e14bdSMaxim Galaganov __tcp_sock_set_cork(ssk, !!msk->cork); 12604f6e14bdSMaxim Galaganov __tcp_sock_set_nodelay(ssk, !!msk->nodelay); 1261c9406a23SFlorian Westphal 1262c9406a23SFlorian Westphal inet_sk(ssk)->transparent = inet_sk(sk)->transparent; 1263c9406a23SFlorian Westphal inet_sk(ssk)->freebind = inet_sk(sk)->freebind; 12641b3e7edeSFlorian Westphal } 12651b3e7edeSFlorian Westphal 1266df00b087SFlorian Westphal static void __mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk) 1267df00b087SFlorian Westphal { 12681b3e7edeSFlorian Westphal bool slow = lock_sock_fast(ssk); 12691b3e7edeSFlorian Westphal 12701b3e7edeSFlorian Westphal sync_socket_options(msk, ssk); 12711b3e7edeSFlorian Westphal 12721b3e7edeSFlorian Westphal unlock_sock_fast(ssk, slow); 1273df00b087SFlorian Westphal } 1274df00b087SFlorian Westphal 127578962489SFlorian Westphal void mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk) 127678962489SFlorian Westphal { 1277df00b087SFlorian Westphal struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); 1278df00b087SFlorian Westphal 127978962489SFlorian Westphal msk_owned_by_me(msk); 1280df00b087SFlorian Westphal 1281df00b087SFlorian Westphal if (READ_ONCE(subflow->setsockopt_seq) != msk->setsockopt_seq) { 1282df00b087SFlorian Westphal __mptcp_sockopt_sync(msk, ssk); 1283df00b087SFlorian Westphal 1284df00b087SFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 1285df00b087SFlorian Westphal } 128678962489SFlorian Westphal } 128778962489SFlorian Westphal 1288*3e501490SPaolo Abeni void mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk) 128978962489SFlorian Westphal { 1290*3e501490SPaolo Abeni struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); 129178962489SFlorian Westphal 1292*3e501490SPaolo Abeni msk_owned_by_me(msk); 129378962489SFlorian Westphal 1294*3e501490SPaolo Abeni if (READ_ONCE(subflow->setsockopt_seq) != msk->setsockopt_seq) { 1295*3e501490SPaolo Abeni sync_socket_options(msk, ssk); 129678962489SFlorian Westphal 1297*3e501490SPaolo Abeni subflow->setsockopt_seq = msk->setsockopt_seq; 1298df00b087SFlorian Westphal } 129978962489SFlorian Westphal } 1300