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 170abdde82SPaolo Abeni static struct sock *__mptcp_tcp_fallback(struct mptcp_sock *msk) 180abdde82SPaolo Abeni { 190abdde82SPaolo Abeni sock_owned_by_me((const struct sock *)msk); 200abdde82SPaolo Abeni 210abdde82SPaolo Abeni if (likely(!__mptcp_check_fallback(msk))) 220abdde82SPaolo Abeni return NULL; 230abdde82SPaolo Abeni 240abdde82SPaolo Abeni return msk->first; 250abdde82SPaolo Abeni } 260abdde82SPaolo Abeni 27df00b087SFlorian Westphal static u32 sockopt_seq_reset(const struct sock *sk) 28df00b087SFlorian Westphal { 29df00b087SFlorian Westphal sock_owned_by_me(sk); 30df00b087SFlorian Westphal 31df00b087SFlorian Westphal /* Highbits contain state. Allows to distinguish sockopt_seq 32df00b087SFlorian Westphal * of listener and established: 33df00b087SFlorian Westphal * s0 = new_listener() 34df00b087SFlorian Westphal * sockopt(s0) - seq is 1 35df00b087SFlorian Westphal * s1 = accept(s0) - s1 inherits seq 1 if listener sk (s0) 36df00b087SFlorian Westphal * sockopt(s0) - seq increments to 2 on s0 37df00b087SFlorian Westphal * sockopt(s1) // seq increments to 2 on s1 (different option) 38df00b087SFlorian Westphal * new ssk completes join, inherits options from s0 // seq 2 39df00b087SFlorian Westphal * Needs sync from mptcp join logic, but ssk->seq == msk->seq 40df00b087SFlorian Westphal * 41df00b087SFlorian Westphal * Set High order bits to sk_state so ssk->seq == msk->seq test 42df00b087SFlorian Westphal * will fail. 43df00b087SFlorian Westphal */ 44df00b087SFlorian Westphal 45df00b087SFlorian Westphal return (u32)sk->sk_state << 24u; 46df00b087SFlorian Westphal } 47df00b087SFlorian Westphal 481b3e7edeSFlorian Westphal static void sockopt_seq_inc(struct mptcp_sock *msk) 491b3e7edeSFlorian Westphal { 501b3e7edeSFlorian Westphal u32 seq = (msk->setsockopt_seq + 1) & 0x00ffffff; 511b3e7edeSFlorian Westphal 521b3e7edeSFlorian Westphal msk->setsockopt_seq = sockopt_seq_reset((struct sock *)msk) + seq; 531b3e7edeSFlorian Westphal } 541b3e7edeSFlorian Westphal 551b3e7edeSFlorian Westphal static int mptcp_get_int_option(struct mptcp_sock *msk, sockptr_t optval, 561b3e7edeSFlorian Westphal unsigned int optlen, int *val) 571b3e7edeSFlorian Westphal { 581b3e7edeSFlorian Westphal if (optlen < sizeof(int)) 591b3e7edeSFlorian Westphal return -EINVAL; 601b3e7edeSFlorian Westphal 611b3e7edeSFlorian Westphal if (copy_from_sockptr(val, optval, sizeof(*val))) 621b3e7edeSFlorian Westphal return -EFAULT; 631b3e7edeSFlorian Westphal 641b3e7edeSFlorian Westphal return 0; 651b3e7edeSFlorian Westphal } 661b3e7edeSFlorian Westphal 671b3e7edeSFlorian Westphal static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, int val) 681b3e7edeSFlorian Westphal { 691b3e7edeSFlorian Westphal struct mptcp_subflow_context *subflow; 701b3e7edeSFlorian Westphal struct sock *sk = (struct sock *)msk; 711b3e7edeSFlorian Westphal 721b3e7edeSFlorian Westphal lock_sock(sk); 731b3e7edeSFlorian Westphal sockopt_seq_inc(msk); 741b3e7edeSFlorian Westphal 751b3e7edeSFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 761b3e7edeSFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 771b3e7edeSFlorian Westphal bool slow = lock_sock_fast(ssk); 781b3e7edeSFlorian Westphal 791b3e7edeSFlorian Westphal switch (optname) { 80a03c99b2SFlorian Westphal case SO_DEBUG: 81a03c99b2SFlorian Westphal sock_valbool_flag(ssk, SOCK_DBG, !!val); 82a03c99b2SFlorian Westphal break; 831b3e7edeSFlorian Westphal case SO_KEEPALIVE: 841b3e7edeSFlorian Westphal if (ssk->sk_prot->keepalive) 851b3e7edeSFlorian Westphal ssk->sk_prot->keepalive(ssk, !!val); 861b3e7edeSFlorian Westphal sock_valbool_flag(ssk, SOCK_KEEPOPEN, !!val); 871b3e7edeSFlorian Westphal break; 881b3e7edeSFlorian Westphal case SO_PRIORITY: 891b3e7edeSFlorian Westphal ssk->sk_priority = val; 901b3e7edeSFlorian Westphal break; 915d0a6bc8SFlorian Westphal case SO_SNDBUF: 925d0a6bc8SFlorian Westphal case SO_SNDBUFFORCE: 935d0a6bc8SFlorian Westphal ssk->sk_userlocks |= SOCK_SNDBUF_LOCK; 945d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_sndbuf, sk->sk_sndbuf); 955d0a6bc8SFlorian Westphal break; 965d0a6bc8SFlorian Westphal case SO_RCVBUF: 975d0a6bc8SFlorian Westphal case SO_RCVBUFFORCE: 985d0a6bc8SFlorian Westphal ssk->sk_userlocks |= SOCK_RCVBUF_LOCK; 995d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf); 1005d0a6bc8SFlorian Westphal break; 10136704413SFlorian Westphal case SO_MARK: 10236704413SFlorian Westphal if (READ_ONCE(ssk->sk_mark) != sk->sk_mark) { 10336704413SFlorian Westphal ssk->sk_mark = sk->sk_mark; 10436704413SFlorian Westphal sk_dst_reset(ssk); 10536704413SFlorian Westphal } 10636704413SFlorian Westphal break; 1076f0d7198SFlorian Westphal case SO_INCOMING_CPU: 1086f0d7198SFlorian Westphal WRITE_ONCE(ssk->sk_incoming_cpu, val); 1096f0d7198SFlorian Westphal break; 1101b3e7edeSFlorian Westphal } 1111b3e7edeSFlorian Westphal 1121b3e7edeSFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 1131b3e7edeSFlorian Westphal unlock_sock_fast(ssk, slow); 1141b3e7edeSFlorian Westphal } 1151b3e7edeSFlorian Westphal 1161b3e7edeSFlorian Westphal release_sock(sk); 1171b3e7edeSFlorian Westphal } 1181b3e7edeSFlorian Westphal 1191b3e7edeSFlorian Westphal static int mptcp_sol_socket_intval(struct mptcp_sock *msk, int optname, int val) 1201b3e7edeSFlorian Westphal { 1211b3e7edeSFlorian Westphal sockptr_t optval = KERNEL_SOCKPTR(&val); 1221b3e7edeSFlorian Westphal struct sock *sk = (struct sock *)msk; 1231b3e7edeSFlorian Westphal int ret; 1241b3e7edeSFlorian Westphal 1251b3e7edeSFlorian Westphal ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, 1261b3e7edeSFlorian Westphal optval, sizeof(val)); 1271b3e7edeSFlorian Westphal if (ret) 1281b3e7edeSFlorian Westphal return ret; 1291b3e7edeSFlorian Westphal 1301b3e7edeSFlorian Westphal mptcp_sol_socket_sync_intval(msk, optname, val); 1311b3e7edeSFlorian Westphal return 0; 1321b3e7edeSFlorian Westphal } 1331b3e7edeSFlorian Westphal 1346f0d7198SFlorian Westphal static void mptcp_so_incoming_cpu(struct mptcp_sock *msk, int val) 1356f0d7198SFlorian Westphal { 1366f0d7198SFlorian Westphal struct sock *sk = (struct sock *)msk; 1376f0d7198SFlorian Westphal 1386f0d7198SFlorian Westphal WRITE_ONCE(sk->sk_incoming_cpu, val); 1396f0d7198SFlorian Westphal 1406f0d7198SFlorian Westphal mptcp_sol_socket_sync_intval(msk, SO_INCOMING_CPU, val); 1416f0d7198SFlorian Westphal } 1426f0d7198SFlorian Westphal 1439061f24bSFlorian Westphal static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optname, int val) 1449061f24bSFlorian Westphal { 1459061f24bSFlorian Westphal sockptr_t optval = KERNEL_SOCKPTR(&val); 1469061f24bSFlorian Westphal struct mptcp_subflow_context *subflow; 1479061f24bSFlorian Westphal struct sock *sk = (struct sock *)msk; 1489061f24bSFlorian Westphal int ret; 1499061f24bSFlorian Westphal 1509061f24bSFlorian Westphal ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, 1519061f24bSFlorian Westphal optval, sizeof(val)); 1529061f24bSFlorian Westphal if (ret) 1539061f24bSFlorian Westphal return ret; 1549061f24bSFlorian Westphal 1559061f24bSFlorian Westphal lock_sock(sk); 1569061f24bSFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 1579061f24bSFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 1589061f24bSFlorian Westphal bool slow = lock_sock_fast(ssk); 1599061f24bSFlorian Westphal 1609061f24bSFlorian Westphal sock_set_timestamp(sk, optname, !!val); 1619061f24bSFlorian Westphal unlock_sock_fast(ssk, slow); 1629061f24bSFlorian Westphal } 1639061f24bSFlorian Westphal 1649061f24bSFlorian Westphal release_sock(sk); 1659061f24bSFlorian Westphal return 0; 1669061f24bSFlorian Westphal } 1679061f24bSFlorian Westphal 1681b3e7edeSFlorian Westphal static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname, 1696c9a0a0fSYangbo Lu sockptr_t optval, 1706c9a0a0fSYangbo Lu unsigned int optlen) 1711b3e7edeSFlorian Westphal { 1721b3e7edeSFlorian Westphal int val, ret; 1731b3e7edeSFlorian Westphal 1741b3e7edeSFlorian Westphal ret = mptcp_get_int_option(msk, optval, optlen, &val); 1751b3e7edeSFlorian Westphal if (ret) 1761b3e7edeSFlorian Westphal return ret; 1771b3e7edeSFlorian Westphal 1781b3e7edeSFlorian Westphal switch (optname) { 1791b3e7edeSFlorian Westphal case SO_KEEPALIVE: 1801b3e7edeSFlorian Westphal mptcp_sol_socket_sync_intval(msk, optname, val); 1811b3e7edeSFlorian Westphal return 0; 182a03c99b2SFlorian Westphal case SO_DEBUG: 18336704413SFlorian Westphal case SO_MARK: 1841b3e7edeSFlorian Westphal case SO_PRIORITY: 1855d0a6bc8SFlorian Westphal case SO_SNDBUF: 1865d0a6bc8SFlorian Westphal case SO_SNDBUFFORCE: 1875d0a6bc8SFlorian Westphal case SO_RCVBUF: 1885d0a6bc8SFlorian Westphal case SO_RCVBUFFORCE: 1891b3e7edeSFlorian Westphal return mptcp_sol_socket_intval(msk, optname, val); 1906f0d7198SFlorian Westphal case SO_INCOMING_CPU: 1916f0d7198SFlorian Westphal mptcp_so_incoming_cpu(msk, val); 1926f0d7198SFlorian Westphal return 0; 1939061f24bSFlorian Westphal case SO_TIMESTAMP_OLD: 1949061f24bSFlorian Westphal case SO_TIMESTAMP_NEW: 1959061f24bSFlorian Westphal case SO_TIMESTAMPNS_OLD: 1969061f24bSFlorian Westphal case SO_TIMESTAMPNS_NEW: 1979061f24bSFlorian Westphal return mptcp_setsockopt_sol_socket_tstamp(msk, optname, val); 1981b3e7edeSFlorian Westphal } 1991b3e7edeSFlorian Westphal 2001b3e7edeSFlorian Westphal return -ENOPROTOOPT; 2011b3e7edeSFlorian Westphal } 2021b3e7edeSFlorian Westphal 2036c9a0a0fSYangbo Lu static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, 2046c9a0a0fSYangbo Lu int optname, 2056c9a0a0fSYangbo Lu sockptr_t optval, 2066c9a0a0fSYangbo Lu unsigned int optlen) 2076c9a0a0fSYangbo Lu { 2086c9a0a0fSYangbo Lu struct mptcp_subflow_context *subflow; 2096c9a0a0fSYangbo Lu struct sock *sk = (struct sock *)msk; 210*d463126eSYangbo Lu struct so_timestamping timestamping; 211*d463126eSYangbo Lu int ret; 2126c9a0a0fSYangbo Lu 213*d463126eSYangbo Lu if (optlen == sizeof(timestamping)) { 214*d463126eSYangbo Lu if (copy_from_sockptr(×tamping, optval, 215*d463126eSYangbo Lu sizeof(timestamping))) 216*d463126eSYangbo Lu return -EFAULT; 217*d463126eSYangbo Lu } else if (optlen == sizeof(int)) { 218*d463126eSYangbo Lu memset(×tamping, 0, sizeof(timestamping)); 219*d463126eSYangbo Lu 220*d463126eSYangbo Lu if (copy_from_sockptr(×tamping.flags, optval, sizeof(int))) 221*d463126eSYangbo Lu return -EFAULT; 222*d463126eSYangbo Lu } else { 223*d463126eSYangbo Lu return -EINVAL; 224*d463126eSYangbo Lu } 2256c9a0a0fSYangbo Lu 2266c9a0a0fSYangbo Lu ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, 227*d463126eSYangbo Lu KERNEL_SOCKPTR(×tamping), 228*d463126eSYangbo Lu sizeof(timestamping)); 2296c9a0a0fSYangbo Lu if (ret) 2306c9a0a0fSYangbo Lu return ret; 2316c9a0a0fSYangbo Lu 2326c9a0a0fSYangbo Lu lock_sock(sk); 2336c9a0a0fSYangbo Lu 2346c9a0a0fSYangbo Lu mptcp_for_each_subflow(msk, subflow) { 2356c9a0a0fSYangbo Lu struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 2366c9a0a0fSYangbo Lu bool slow = lock_sock_fast(ssk); 2376c9a0a0fSYangbo Lu 238*d463126eSYangbo Lu sock_set_timestamping(sk, optname, timestamping); 2396c9a0a0fSYangbo Lu unlock_sock_fast(ssk, slow); 2406c9a0a0fSYangbo Lu } 2416c9a0a0fSYangbo Lu 2426c9a0a0fSYangbo Lu release_sock(sk); 2436c9a0a0fSYangbo Lu 2446c9a0a0fSYangbo Lu return 0; 2456c9a0a0fSYangbo Lu } 2466c9a0a0fSYangbo Lu 247268b1238SFlorian Westphal static int mptcp_setsockopt_sol_socket_linger(struct mptcp_sock *msk, sockptr_t optval, 248268b1238SFlorian Westphal unsigned int optlen) 249268b1238SFlorian Westphal { 250268b1238SFlorian Westphal struct mptcp_subflow_context *subflow; 251268b1238SFlorian Westphal struct sock *sk = (struct sock *)msk; 252268b1238SFlorian Westphal struct linger ling; 253268b1238SFlorian Westphal sockptr_t kopt; 254268b1238SFlorian Westphal int ret; 255268b1238SFlorian Westphal 256268b1238SFlorian Westphal if (optlen < sizeof(ling)) 257268b1238SFlorian Westphal return -EINVAL; 258268b1238SFlorian Westphal 259268b1238SFlorian Westphal if (copy_from_sockptr(&ling, optval, sizeof(ling))) 260268b1238SFlorian Westphal return -EFAULT; 261268b1238SFlorian Westphal 262268b1238SFlorian Westphal kopt = KERNEL_SOCKPTR(&ling); 263268b1238SFlorian Westphal ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, SO_LINGER, kopt, sizeof(ling)); 264268b1238SFlorian Westphal if (ret) 265268b1238SFlorian Westphal return ret; 266268b1238SFlorian Westphal 267268b1238SFlorian Westphal lock_sock(sk); 268268b1238SFlorian Westphal sockopt_seq_inc(msk); 269268b1238SFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 270268b1238SFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 271268b1238SFlorian Westphal bool slow = lock_sock_fast(ssk); 272268b1238SFlorian Westphal 273268b1238SFlorian Westphal if (!ling.l_onoff) { 274268b1238SFlorian Westphal sock_reset_flag(ssk, SOCK_LINGER); 275268b1238SFlorian Westphal } else { 276268b1238SFlorian Westphal ssk->sk_lingertime = sk->sk_lingertime; 277268b1238SFlorian Westphal sock_set_flag(ssk, SOCK_LINGER); 278268b1238SFlorian Westphal } 279268b1238SFlorian Westphal 280268b1238SFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 281268b1238SFlorian Westphal unlock_sock_fast(ssk, slow); 282268b1238SFlorian Westphal } 283268b1238SFlorian Westphal 284268b1238SFlorian Westphal release_sock(sk); 285268b1238SFlorian Westphal return 0; 286268b1238SFlorian Westphal } 287268b1238SFlorian Westphal 2880abdde82SPaolo Abeni static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname, 2890abdde82SPaolo Abeni sockptr_t optval, unsigned int optlen) 2900abdde82SPaolo Abeni { 2910abdde82SPaolo Abeni struct sock *sk = (struct sock *)msk; 2920abdde82SPaolo Abeni struct socket *ssock; 2930abdde82SPaolo Abeni int ret; 2940abdde82SPaolo Abeni 2950abdde82SPaolo Abeni switch (optname) { 2960abdde82SPaolo Abeni case SO_REUSEPORT: 2970abdde82SPaolo Abeni case SO_REUSEADDR: 2985d0a6bc8SFlorian Westphal case SO_BINDTODEVICE: 2995d0a6bc8SFlorian Westphal case SO_BINDTOIFINDEX: 3000abdde82SPaolo Abeni lock_sock(sk); 3010abdde82SPaolo Abeni ssock = __mptcp_nmpc_socket(msk); 3020abdde82SPaolo Abeni if (!ssock) { 3030abdde82SPaolo Abeni release_sock(sk); 3040abdde82SPaolo Abeni return -EINVAL; 3050abdde82SPaolo Abeni } 3060abdde82SPaolo Abeni 3070abdde82SPaolo Abeni ret = sock_setsockopt(ssock, SOL_SOCKET, optname, optval, optlen); 3080abdde82SPaolo Abeni if (ret == 0) { 3090abdde82SPaolo Abeni if (optname == SO_REUSEPORT) 3100abdde82SPaolo Abeni sk->sk_reuseport = ssock->sk->sk_reuseport; 3110abdde82SPaolo Abeni else if (optname == SO_REUSEADDR) 3120abdde82SPaolo Abeni sk->sk_reuse = ssock->sk->sk_reuse; 3135d0a6bc8SFlorian Westphal else if (optname == SO_BINDTODEVICE) 3145d0a6bc8SFlorian Westphal sk->sk_bound_dev_if = ssock->sk->sk_bound_dev_if; 3155d0a6bc8SFlorian Westphal else if (optname == SO_BINDTOIFINDEX) 3165d0a6bc8SFlorian Westphal sk->sk_bound_dev_if = ssock->sk->sk_bound_dev_if; 3170abdde82SPaolo Abeni } 3180abdde82SPaolo Abeni release_sock(sk); 3190abdde82SPaolo Abeni return ret; 3201b3e7edeSFlorian Westphal case SO_KEEPALIVE: 3211b3e7edeSFlorian Westphal case SO_PRIORITY: 3225d0a6bc8SFlorian Westphal case SO_SNDBUF: 3235d0a6bc8SFlorian Westphal case SO_SNDBUFFORCE: 3245d0a6bc8SFlorian Westphal case SO_RCVBUF: 3255d0a6bc8SFlorian Westphal case SO_RCVBUFFORCE: 32636704413SFlorian Westphal case SO_MARK: 3276f0d7198SFlorian Westphal case SO_INCOMING_CPU: 328a03c99b2SFlorian Westphal case SO_DEBUG: 3299061f24bSFlorian Westphal case SO_TIMESTAMP_OLD: 3309061f24bSFlorian Westphal case SO_TIMESTAMP_NEW: 3319061f24bSFlorian Westphal case SO_TIMESTAMPNS_OLD: 3329061f24bSFlorian Westphal case SO_TIMESTAMPNS_NEW: 3336c9a0a0fSYangbo Lu return mptcp_setsockopt_sol_socket_int(msk, optname, optval, 3346c9a0a0fSYangbo Lu optlen); 3359061f24bSFlorian Westphal case SO_TIMESTAMPING_OLD: 3369061f24bSFlorian Westphal case SO_TIMESTAMPING_NEW: 3376c9a0a0fSYangbo Lu return mptcp_setsockopt_sol_socket_timestamping(msk, optname, 3386c9a0a0fSYangbo Lu optval, optlen); 339268b1238SFlorian Westphal case SO_LINGER: 340268b1238SFlorian Westphal return mptcp_setsockopt_sol_socket_linger(msk, optval, optlen); 3417a009a70SFlorian Westphal case SO_RCVLOWAT: 3427a009a70SFlorian Westphal case SO_RCVTIMEO_OLD: 3437a009a70SFlorian Westphal case SO_RCVTIMEO_NEW: 3447a009a70SFlorian Westphal case SO_BUSY_POLL: 3457a009a70SFlorian Westphal case SO_PREFER_BUSY_POLL: 3467a009a70SFlorian Westphal case SO_BUSY_POLL_BUDGET: 3477a009a70SFlorian Westphal /* No need to copy: only relevant for msk */ 3487a009a70SFlorian Westphal return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen); 349a03c99b2SFlorian Westphal case SO_NO_CHECK: 350a03c99b2SFlorian Westphal case SO_DONTROUTE: 351a03c99b2SFlorian Westphal case SO_BROADCAST: 352a03c99b2SFlorian Westphal case SO_BSDCOMPAT: 353a03c99b2SFlorian Westphal case SO_PASSCRED: 354a03c99b2SFlorian Westphal case SO_PASSSEC: 355a03c99b2SFlorian Westphal case SO_RXQ_OVFL: 356a03c99b2SFlorian Westphal case SO_WIFI_STATUS: 357a03c99b2SFlorian Westphal case SO_NOFCS: 358a03c99b2SFlorian Westphal case SO_SELECT_ERR_QUEUE: 359a03c99b2SFlorian Westphal return 0; 3600abdde82SPaolo Abeni } 3610abdde82SPaolo Abeni 3627a009a70SFlorian Westphal /* SO_OOBINLINE is not supported, let's avoid the related mess 3637a009a70SFlorian Westphal * SO_ATTACH_FILTER, SO_ATTACH_BPF, SO_ATTACH_REUSEPORT_CBPF, 3647a009a70SFlorian Westphal * SO_DETACH_REUSEPORT_BPF, SO_DETACH_FILTER, SO_LOCK_FILTER, 3657a009a70SFlorian Westphal * we must be careful with subflows 3667a009a70SFlorian Westphal * 3677a009a70SFlorian Westphal * SO_ATTACH_REUSEPORT_EBPF is not supported, at it checks 3687a009a70SFlorian Westphal * explicitly the sk_protocol field 3697a009a70SFlorian Westphal * 3707a009a70SFlorian Westphal * SO_PEEK_OFF is unsupported, as it is for plain TCP 3717a009a70SFlorian Westphal * SO_MAX_PACING_RATE is unsupported, we must be careful with subflows 3727a009a70SFlorian Westphal * SO_CNX_ADVICE is currently unsupported, could possibly be relevant, 3737a009a70SFlorian Westphal * but likely needs careful design 3747a009a70SFlorian Westphal * 3757a009a70SFlorian Westphal * SO_ZEROCOPY is currently unsupported, TODO in sndmsg 3767a009a70SFlorian Westphal * SO_TXTIME is currently unsupported 3777a009a70SFlorian Westphal */ 3787a009a70SFlorian Westphal 3797a009a70SFlorian Westphal return -EOPNOTSUPP; 3800abdde82SPaolo Abeni } 3810abdde82SPaolo Abeni 3820abdde82SPaolo Abeni static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname, 3830abdde82SPaolo Abeni sockptr_t optval, unsigned int optlen) 3840abdde82SPaolo Abeni { 3850abdde82SPaolo Abeni struct sock *sk = (struct sock *)msk; 3860abdde82SPaolo Abeni int ret = -EOPNOTSUPP; 3870abdde82SPaolo Abeni struct socket *ssock; 3880abdde82SPaolo Abeni 3890abdde82SPaolo Abeni switch (optname) { 3900abdde82SPaolo Abeni case IPV6_V6ONLY: 3910abdde82SPaolo Abeni lock_sock(sk); 3920abdde82SPaolo Abeni ssock = __mptcp_nmpc_socket(msk); 3930abdde82SPaolo Abeni if (!ssock) { 3940abdde82SPaolo Abeni release_sock(sk); 3950abdde82SPaolo Abeni return -EINVAL; 3960abdde82SPaolo Abeni } 3970abdde82SPaolo Abeni 3980abdde82SPaolo Abeni ret = tcp_setsockopt(ssock->sk, SOL_IPV6, optname, optval, optlen); 3990abdde82SPaolo Abeni if (ret == 0) 4000abdde82SPaolo Abeni sk->sk_ipv6only = ssock->sk->sk_ipv6only; 4010abdde82SPaolo Abeni 4020abdde82SPaolo Abeni release_sock(sk); 4030abdde82SPaolo Abeni break; 4040abdde82SPaolo Abeni } 4050abdde82SPaolo Abeni 4060abdde82SPaolo Abeni return ret; 4070abdde82SPaolo Abeni } 4080abdde82SPaolo Abeni 409d9e4c129SPaolo Abeni static bool mptcp_supported_sockopt(int level, int optname) 410d9e4c129SPaolo Abeni { 411d9e4c129SPaolo Abeni if (level == SOL_IP) { 412d9e4c129SPaolo Abeni switch (optname) { 413d9e4c129SPaolo Abeni /* should work fine */ 414d9e4c129SPaolo Abeni case IP_FREEBIND: 415d9e4c129SPaolo Abeni case IP_TRANSPARENT: 416d9e4c129SPaolo Abeni 417d9e4c129SPaolo Abeni /* the following are control cmsg related */ 418d9e4c129SPaolo Abeni case IP_PKTINFO: 419d9e4c129SPaolo Abeni case IP_RECVTTL: 420d9e4c129SPaolo Abeni case IP_RECVTOS: 421d9e4c129SPaolo Abeni case IP_RECVOPTS: 422d9e4c129SPaolo Abeni case IP_RETOPTS: 423d9e4c129SPaolo Abeni case IP_PASSSEC: 424d9e4c129SPaolo Abeni case IP_RECVORIGDSTADDR: 425d9e4c129SPaolo Abeni case IP_CHECKSUM: 426d9e4c129SPaolo Abeni case IP_RECVFRAGSIZE: 427d9e4c129SPaolo Abeni 428d9e4c129SPaolo Abeni /* common stuff that need some love */ 429d9e4c129SPaolo Abeni case IP_TOS: 430d9e4c129SPaolo Abeni case IP_TTL: 431d9e4c129SPaolo Abeni case IP_BIND_ADDRESS_NO_PORT: 432d9e4c129SPaolo Abeni case IP_MTU_DISCOVER: 433d9e4c129SPaolo Abeni case IP_RECVERR: 434d9e4c129SPaolo Abeni 435d9e4c129SPaolo Abeni /* possibly less common may deserve some love */ 436d9e4c129SPaolo Abeni case IP_MINTTL: 437d9e4c129SPaolo Abeni 438d9e4c129SPaolo Abeni /* the following is apparently a no-op for plain TCP */ 439d9e4c129SPaolo Abeni case IP_RECVERR_RFC4884: 440d9e4c129SPaolo Abeni return true; 441d9e4c129SPaolo Abeni } 442d9e4c129SPaolo Abeni 443d9e4c129SPaolo Abeni /* IP_OPTIONS is not supported, needs subflow care */ 444d9e4c129SPaolo Abeni /* IP_HDRINCL, IP_NODEFRAG are not supported, RAW specific */ 445d9e4c129SPaolo Abeni /* IP_MULTICAST_TTL, IP_MULTICAST_LOOP, IP_UNICAST_IF, 446d9e4c129SPaolo Abeni * IP_ADD_MEMBERSHIP, IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_MEMBERSHIP, 447d9e4c129SPaolo Abeni * IP_DROP_SOURCE_MEMBERSHIP, IP_BLOCK_SOURCE, IP_UNBLOCK_SOURCE, 448d9e4c129SPaolo Abeni * MCAST_JOIN_GROUP, MCAST_LEAVE_GROUP MCAST_JOIN_SOURCE_GROUP, 449d9e4c129SPaolo Abeni * MCAST_LEAVE_SOURCE_GROUP, MCAST_BLOCK_SOURCE, MCAST_UNBLOCK_SOURCE, 450d9e4c129SPaolo Abeni * MCAST_MSFILTER, IP_MULTICAST_ALL are not supported, better not deal 451d9e4c129SPaolo Abeni * with mcast stuff 452d9e4c129SPaolo Abeni */ 453d9e4c129SPaolo Abeni /* IP_IPSEC_POLICY, IP_XFRM_POLICY are nut supported, unrelated here */ 454d9e4c129SPaolo Abeni return false; 455d9e4c129SPaolo Abeni } 456d9e4c129SPaolo Abeni if (level == SOL_IPV6) { 457d9e4c129SPaolo Abeni switch (optname) { 458d9e4c129SPaolo Abeni case IPV6_V6ONLY: 459d9e4c129SPaolo Abeni 460d9e4c129SPaolo Abeni /* the following are control cmsg related */ 461d9e4c129SPaolo Abeni case IPV6_RECVPKTINFO: 462d9e4c129SPaolo Abeni case IPV6_2292PKTINFO: 463d9e4c129SPaolo Abeni case IPV6_RECVHOPLIMIT: 464d9e4c129SPaolo Abeni case IPV6_2292HOPLIMIT: 465d9e4c129SPaolo Abeni case IPV6_RECVRTHDR: 466d9e4c129SPaolo Abeni case IPV6_2292RTHDR: 467d9e4c129SPaolo Abeni case IPV6_RECVHOPOPTS: 468d9e4c129SPaolo Abeni case IPV6_2292HOPOPTS: 469d9e4c129SPaolo Abeni case IPV6_RECVDSTOPTS: 470d9e4c129SPaolo Abeni case IPV6_2292DSTOPTS: 471d9e4c129SPaolo Abeni case IPV6_RECVTCLASS: 472d9e4c129SPaolo Abeni case IPV6_FLOWINFO: 473d9e4c129SPaolo Abeni case IPV6_RECVPATHMTU: 474d9e4c129SPaolo Abeni case IPV6_RECVORIGDSTADDR: 475d9e4c129SPaolo Abeni case IPV6_RECVFRAGSIZE: 476d9e4c129SPaolo Abeni 477d9e4c129SPaolo Abeni /* the following ones need some love but are quite common */ 478d9e4c129SPaolo Abeni case IPV6_TCLASS: 479d9e4c129SPaolo Abeni case IPV6_TRANSPARENT: 480d9e4c129SPaolo Abeni case IPV6_FREEBIND: 481d9e4c129SPaolo Abeni case IPV6_PKTINFO: 482d9e4c129SPaolo Abeni case IPV6_2292PKTOPTIONS: 483d9e4c129SPaolo Abeni case IPV6_UNICAST_HOPS: 484d9e4c129SPaolo Abeni case IPV6_MTU_DISCOVER: 485d9e4c129SPaolo Abeni case IPV6_MTU: 486d9e4c129SPaolo Abeni case IPV6_RECVERR: 487d9e4c129SPaolo Abeni case IPV6_FLOWINFO_SEND: 488d9e4c129SPaolo Abeni case IPV6_FLOWLABEL_MGR: 489d9e4c129SPaolo Abeni case IPV6_MINHOPCOUNT: 490d9e4c129SPaolo Abeni case IPV6_DONTFRAG: 491d9e4c129SPaolo Abeni case IPV6_AUTOFLOWLABEL: 492d9e4c129SPaolo Abeni 493d9e4c129SPaolo Abeni /* the following one is a no-op for plain TCP */ 494d9e4c129SPaolo Abeni case IPV6_RECVERR_RFC4884: 495d9e4c129SPaolo Abeni return true; 496d9e4c129SPaolo Abeni } 497d9e4c129SPaolo Abeni 498d9e4c129SPaolo Abeni /* IPV6_HOPOPTS, IPV6_RTHDRDSTOPTS, IPV6_RTHDR, IPV6_DSTOPTS are 499d9e4c129SPaolo Abeni * not supported 500d9e4c129SPaolo Abeni */ 501d9e4c129SPaolo Abeni /* IPV6_MULTICAST_HOPS, IPV6_MULTICAST_LOOP, IPV6_UNICAST_IF, 502d9e4c129SPaolo Abeni * IPV6_MULTICAST_IF, IPV6_ADDRFORM, 503d9e4c129SPaolo Abeni * IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_JOIN_ANYCAST, 504d9e4c129SPaolo Abeni * IPV6_LEAVE_ANYCAST, IPV6_MULTICAST_ALL, MCAST_JOIN_GROUP, MCAST_LEAVE_GROUP, 505d9e4c129SPaolo Abeni * MCAST_JOIN_SOURCE_GROUP, MCAST_LEAVE_SOURCE_GROUP, 506d9e4c129SPaolo Abeni * MCAST_BLOCK_SOURCE, MCAST_UNBLOCK_SOURCE, MCAST_MSFILTER 507d9e4c129SPaolo Abeni * are not supported better not deal with mcast 508d9e4c129SPaolo Abeni */ 509d9e4c129SPaolo Abeni /* IPV6_ROUTER_ALERT, IPV6_ROUTER_ALERT_ISOLATE are not supported, since are evil */ 510d9e4c129SPaolo Abeni 511d9e4c129SPaolo Abeni /* IPV6_IPSEC_POLICY, IPV6_XFRM_POLICY are not supported */ 512d9e4c129SPaolo Abeni /* IPV6_ADDR_PREFERENCES is not supported, we must be careful with subflows */ 513d9e4c129SPaolo Abeni return false; 514d9e4c129SPaolo Abeni } 515d9e4c129SPaolo Abeni if (level == SOL_TCP) { 516d9e4c129SPaolo Abeni switch (optname) { 517d9e4c129SPaolo Abeni /* the following are no-op or should work just fine */ 518d9e4c129SPaolo Abeni case TCP_THIN_DUPACK: 519d9e4c129SPaolo Abeni case TCP_DEFER_ACCEPT: 520d9e4c129SPaolo Abeni 521d9e4c129SPaolo Abeni /* the following need some love */ 522d9e4c129SPaolo Abeni case TCP_MAXSEG: 523d9e4c129SPaolo Abeni case TCP_NODELAY: 524d9e4c129SPaolo Abeni case TCP_THIN_LINEAR_TIMEOUTS: 525d9e4c129SPaolo Abeni case TCP_CONGESTION: 526d9e4c129SPaolo Abeni case TCP_ULP: 527d9e4c129SPaolo Abeni case TCP_CORK: 528d9e4c129SPaolo Abeni case TCP_KEEPIDLE: 529d9e4c129SPaolo Abeni case TCP_KEEPINTVL: 530d9e4c129SPaolo Abeni case TCP_KEEPCNT: 531d9e4c129SPaolo Abeni case TCP_SYNCNT: 532d9e4c129SPaolo Abeni case TCP_SAVE_SYN: 533d9e4c129SPaolo Abeni case TCP_LINGER2: 534d9e4c129SPaolo Abeni case TCP_WINDOW_CLAMP: 535d9e4c129SPaolo Abeni case TCP_QUICKACK: 536d9e4c129SPaolo Abeni case TCP_USER_TIMEOUT: 537d9e4c129SPaolo Abeni case TCP_TIMESTAMP: 538d9e4c129SPaolo Abeni case TCP_NOTSENT_LOWAT: 539d9e4c129SPaolo Abeni case TCP_TX_DELAY: 540d9e4c129SPaolo Abeni return true; 541d9e4c129SPaolo Abeni } 542d9e4c129SPaolo Abeni 543d9e4c129SPaolo Abeni /* TCP_MD5SIG, TCP_MD5SIG_EXT are not supported, MD5 is not compatible with MPTCP */ 544d9e4c129SPaolo Abeni 545d9e4c129SPaolo Abeni /* TCP_REPAIR, TCP_REPAIR_QUEUE, TCP_QUEUE_SEQ, TCP_REPAIR_OPTIONS, 546d9e4c129SPaolo Abeni * TCP_REPAIR_WINDOW are not supported, better avoid this mess 547d9e4c129SPaolo Abeni */ 548d9e4c129SPaolo Abeni /* TCP_FASTOPEN_KEY, TCP_FASTOPEN TCP_FASTOPEN_CONNECT, TCP_FASTOPEN_NO_COOKIE, 549d9e4c129SPaolo Abeni * are not supported fastopen is currently unsupported 550d9e4c129SPaolo Abeni */ 551d9e4c129SPaolo Abeni /* TCP_INQ is currently unsupported, needs some recvmsg work */ 552d9e4c129SPaolo Abeni } 553d9e4c129SPaolo Abeni return false; 554d9e4c129SPaolo Abeni } 555d9e4c129SPaolo Abeni 556aa1fbd94SFlorian Westphal static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t optval, 557aa1fbd94SFlorian Westphal unsigned int optlen) 558aa1fbd94SFlorian Westphal { 559aa1fbd94SFlorian Westphal struct mptcp_subflow_context *subflow; 560aa1fbd94SFlorian Westphal struct sock *sk = (struct sock *)msk; 561aa1fbd94SFlorian Westphal char name[TCP_CA_NAME_MAX]; 562aa1fbd94SFlorian Westphal bool cap_net_admin; 563aa1fbd94SFlorian Westphal int ret; 564aa1fbd94SFlorian Westphal 565aa1fbd94SFlorian Westphal if (optlen < 1) 566aa1fbd94SFlorian Westphal return -EINVAL; 567aa1fbd94SFlorian Westphal 568aa1fbd94SFlorian Westphal ret = strncpy_from_sockptr(name, optval, 569aa1fbd94SFlorian Westphal min_t(long, TCP_CA_NAME_MAX - 1, optlen)); 570aa1fbd94SFlorian Westphal if (ret < 0) 571aa1fbd94SFlorian Westphal return -EFAULT; 572aa1fbd94SFlorian Westphal 573aa1fbd94SFlorian Westphal name[ret] = 0; 574aa1fbd94SFlorian Westphal 575aa1fbd94SFlorian Westphal cap_net_admin = ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN); 576aa1fbd94SFlorian Westphal 577aa1fbd94SFlorian Westphal ret = 0; 578aa1fbd94SFlorian Westphal lock_sock(sk); 579aa1fbd94SFlorian Westphal sockopt_seq_inc(msk); 580aa1fbd94SFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 581aa1fbd94SFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 582aa1fbd94SFlorian Westphal int err; 583aa1fbd94SFlorian Westphal 584aa1fbd94SFlorian Westphal lock_sock(ssk); 585aa1fbd94SFlorian Westphal err = tcp_set_congestion_control(ssk, name, true, cap_net_admin); 586aa1fbd94SFlorian Westphal if (err < 0 && ret == 0) 587aa1fbd94SFlorian Westphal ret = err; 588aa1fbd94SFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 589aa1fbd94SFlorian Westphal release_sock(ssk); 590aa1fbd94SFlorian Westphal } 591aa1fbd94SFlorian Westphal 592aa1fbd94SFlorian Westphal if (ret == 0) 59320b5759fSPaolo Abeni strcpy(msk->ca_name, name); 594aa1fbd94SFlorian Westphal 595aa1fbd94SFlorian Westphal release_sock(sk); 596aa1fbd94SFlorian Westphal return ret; 597aa1fbd94SFlorian Westphal } 598aa1fbd94SFlorian Westphal 599aa1fbd94SFlorian Westphal static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname, 600aa1fbd94SFlorian Westphal sockptr_t optval, unsigned int optlen) 601aa1fbd94SFlorian Westphal { 602aa1fbd94SFlorian Westphal switch (optname) { 603aa1fbd94SFlorian Westphal case TCP_ULP: 604aa1fbd94SFlorian Westphal return -EOPNOTSUPP; 605aa1fbd94SFlorian Westphal case TCP_CONGESTION: 606aa1fbd94SFlorian Westphal return mptcp_setsockopt_sol_tcp_congestion(msk, optval, optlen); 607aa1fbd94SFlorian Westphal } 608aa1fbd94SFlorian Westphal 609aa1fbd94SFlorian Westphal return -EOPNOTSUPP; 610aa1fbd94SFlorian Westphal } 611aa1fbd94SFlorian Westphal 6120abdde82SPaolo Abeni int mptcp_setsockopt(struct sock *sk, int level, int optname, 6130abdde82SPaolo Abeni sockptr_t optval, unsigned int optlen) 6140abdde82SPaolo Abeni { 6150abdde82SPaolo Abeni struct mptcp_sock *msk = mptcp_sk(sk); 6160abdde82SPaolo Abeni struct sock *ssk; 6170abdde82SPaolo Abeni 6180abdde82SPaolo Abeni pr_debug("msk=%p", msk); 6190abdde82SPaolo Abeni 6200abdde82SPaolo Abeni if (level == SOL_SOCKET) 6210abdde82SPaolo Abeni return mptcp_setsockopt_sol_socket(msk, optname, optval, optlen); 6220abdde82SPaolo Abeni 6237a009a70SFlorian Westphal if (!mptcp_supported_sockopt(level, optname)) 6247a009a70SFlorian Westphal return -ENOPROTOOPT; 6257a009a70SFlorian Westphal 6260abdde82SPaolo Abeni /* @@ the meaning of setsockopt() when the socket is connected and 6270abdde82SPaolo Abeni * there are multiple subflows is not yet defined. It is up to the 6280abdde82SPaolo Abeni * MPTCP-level socket to configure the subflows until the subflow 6290abdde82SPaolo Abeni * is in TCP fallback, when TCP socket options are passed through 6300abdde82SPaolo Abeni * to the one remaining subflow. 6310abdde82SPaolo Abeni */ 6320abdde82SPaolo Abeni lock_sock(sk); 6330abdde82SPaolo Abeni ssk = __mptcp_tcp_fallback(msk); 6340abdde82SPaolo Abeni release_sock(sk); 6350abdde82SPaolo Abeni if (ssk) 6360abdde82SPaolo Abeni return tcp_setsockopt(ssk, level, optname, optval, optlen); 6370abdde82SPaolo Abeni 6380abdde82SPaolo Abeni if (level == SOL_IPV6) 6390abdde82SPaolo Abeni return mptcp_setsockopt_v6(msk, optname, optval, optlen); 6400abdde82SPaolo Abeni 641aa1fbd94SFlorian Westphal if (level == SOL_TCP) 642aa1fbd94SFlorian Westphal return mptcp_setsockopt_sol_tcp(msk, optname, optval, optlen); 643aa1fbd94SFlorian Westphal 644aa1fbd94SFlorian Westphal return -EOPNOTSUPP; 645aa1fbd94SFlorian Westphal } 646aa1fbd94SFlorian Westphal 647aa1fbd94SFlorian Westphal static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int optname, 648aa1fbd94SFlorian Westphal char __user *optval, int __user *optlen) 649aa1fbd94SFlorian Westphal { 650aa1fbd94SFlorian Westphal struct sock *sk = (struct sock *)msk; 651aa1fbd94SFlorian Westphal struct socket *ssock; 652aa1fbd94SFlorian Westphal int ret = -EINVAL; 653aa1fbd94SFlorian Westphal struct sock *ssk; 654aa1fbd94SFlorian Westphal 655aa1fbd94SFlorian Westphal lock_sock(sk); 656aa1fbd94SFlorian Westphal ssk = msk->first; 657aa1fbd94SFlorian Westphal if (ssk) { 658aa1fbd94SFlorian Westphal ret = tcp_getsockopt(ssk, level, optname, optval, optlen); 659aa1fbd94SFlorian Westphal goto out; 660aa1fbd94SFlorian Westphal } 661aa1fbd94SFlorian Westphal 662aa1fbd94SFlorian Westphal ssock = __mptcp_nmpc_socket(msk); 663aa1fbd94SFlorian Westphal if (!ssock) 664aa1fbd94SFlorian Westphal goto out; 665aa1fbd94SFlorian Westphal 666aa1fbd94SFlorian Westphal ret = tcp_getsockopt(ssock->sk, level, optname, optval, optlen); 667aa1fbd94SFlorian Westphal 668aa1fbd94SFlorian Westphal out: 669aa1fbd94SFlorian Westphal release_sock(sk); 670aa1fbd94SFlorian Westphal return ret; 671aa1fbd94SFlorian Westphal } 672aa1fbd94SFlorian Westphal 673aa1fbd94SFlorian Westphal static int mptcp_getsockopt_sol_tcp(struct mptcp_sock *msk, int optname, 674aa1fbd94SFlorian Westphal char __user *optval, int __user *optlen) 675aa1fbd94SFlorian Westphal { 676aa1fbd94SFlorian Westphal switch (optname) { 677aa1fbd94SFlorian Westphal case TCP_ULP: 678aa1fbd94SFlorian Westphal case TCP_CONGESTION: 679aa1fbd94SFlorian Westphal case TCP_INFO: 680aa1fbd94SFlorian Westphal case TCP_CC_INFO: 681aa1fbd94SFlorian Westphal return mptcp_getsockopt_first_sf_only(msk, SOL_TCP, optname, 682aa1fbd94SFlorian Westphal optval, optlen); 683aa1fbd94SFlorian Westphal } 6840abdde82SPaolo Abeni return -EOPNOTSUPP; 6850abdde82SPaolo Abeni } 6860abdde82SPaolo Abeni 6870abdde82SPaolo Abeni int mptcp_getsockopt(struct sock *sk, int level, int optname, 6880abdde82SPaolo Abeni char __user *optval, int __user *option) 6890abdde82SPaolo Abeni { 6900abdde82SPaolo Abeni struct mptcp_sock *msk = mptcp_sk(sk); 6910abdde82SPaolo Abeni struct sock *ssk; 6920abdde82SPaolo Abeni 6930abdde82SPaolo Abeni pr_debug("msk=%p", msk); 6940abdde82SPaolo Abeni 6950abdde82SPaolo Abeni /* @@ the meaning of setsockopt() when the socket is connected and 6960abdde82SPaolo Abeni * there are multiple subflows is not yet defined. It is up to the 6970abdde82SPaolo Abeni * MPTCP-level socket to configure the subflows until the subflow 6980abdde82SPaolo Abeni * is in TCP fallback, when socket options are passed through 6990abdde82SPaolo Abeni * to the one remaining subflow. 7000abdde82SPaolo Abeni */ 7010abdde82SPaolo Abeni lock_sock(sk); 7020abdde82SPaolo Abeni ssk = __mptcp_tcp_fallback(msk); 7030abdde82SPaolo Abeni release_sock(sk); 7040abdde82SPaolo Abeni if (ssk) 7050abdde82SPaolo Abeni return tcp_getsockopt(ssk, level, optname, optval, option); 7060abdde82SPaolo Abeni 707aa1fbd94SFlorian Westphal if (level == SOL_TCP) 708aa1fbd94SFlorian Westphal return mptcp_getsockopt_sol_tcp(msk, optname, optval, option); 7090abdde82SPaolo Abeni return -EOPNOTSUPP; 7100abdde82SPaolo Abeni } 7110abdde82SPaolo Abeni 7121b3e7edeSFlorian Westphal static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk) 7131b3e7edeSFlorian Westphal { 7145d0a6bc8SFlorian Westphal static const unsigned int tx_rx_locks = SOCK_RCVBUF_LOCK | SOCK_SNDBUF_LOCK; 7151b3e7edeSFlorian Westphal struct sock *sk = (struct sock *)msk; 7161b3e7edeSFlorian Westphal 7171b3e7edeSFlorian Westphal if (ssk->sk_prot->keepalive) { 7181b3e7edeSFlorian Westphal if (sock_flag(sk, SOCK_KEEPOPEN)) 7191b3e7edeSFlorian Westphal ssk->sk_prot->keepalive(ssk, 1); 7201b3e7edeSFlorian Westphal else 7211b3e7edeSFlorian Westphal ssk->sk_prot->keepalive(ssk, 0); 7221b3e7edeSFlorian Westphal } 7231b3e7edeSFlorian Westphal 7241b3e7edeSFlorian Westphal ssk->sk_priority = sk->sk_priority; 7255d0a6bc8SFlorian Westphal ssk->sk_bound_dev_if = sk->sk_bound_dev_if; 7265d0a6bc8SFlorian Westphal ssk->sk_incoming_cpu = sk->sk_incoming_cpu; 7275d0a6bc8SFlorian Westphal 7285d0a6bc8SFlorian Westphal if (sk->sk_userlocks & tx_rx_locks) { 7295d0a6bc8SFlorian Westphal ssk->sk_userlocks |= sk->sk_userlocks & tx_rx_locks; 7305d0a6bc8SFlorian Westphal if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) 7315d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_sndbuf, sk->sk_sndbuf); 7325d0a6bc8SFlorian Westphal if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) 7335d0a6bc8SFlorian Westphal WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf); 7345d0a6bc8SFlorian Westphal } 7355d0a6bc8SFlorian Westphal 7365d0a6bc8SFlorian Westphal if (sock_flag(sk, SOCK_LINGER)) { 7375d0a6bc8SFlorian Westphal ssk->sk_lingertime = sk->sk_lingertime; 7385d0a6bc8SFlorian Westphal sock_set_flag(ssk, SOCK_LINGER); 7395d0a6bc8SFlorian Westphal } else { 7405d0a6bc8SFlorian Westphal sock_reset_flag(ssk, SOCK_LINGER); 7415d0a6bc8SFlorian Westphal } 7425d0a6bc8SFlorian Westphal 7435d0a6bc8SFlorian Westphal if (sk->sk_mark != ssk->sk_mark) { 7445d0a6bc8SFlorian Westphal ssk->sk_mark = sk->sk_mark; 7455d0a6bc8SFlorian Westphal sk_dst_reset(ssk); 7465d0a6bc8SFlorian Westphal } 7475d0a6bc8SFlorian Westphal 7485d0a6bc8SFlorian Westphal sock_valbool_flag(ssk, SOCK_DBG, sock_flag(sk, SOCK_DBG)); 7495d0a6bc8SFlorian Westphal 7505d0a6bc8SFlorian Westphal if (inet_csk(sk)->icsk_ca_ops != inet_csk(ssk)->icsk_ca_ops) 75120b5759fSPaolo Abeni tcp_set_congestion_control(ssk, msk->ca_name, false, true); 7521b3e7edeSFlorian Westphal } 7531b3e7edeSFlorian Westphal 754df00b087SFlorian Westphal static void __mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk) 755df00b087SFlorian Westphal { 7561b3e7edeSFlorian Westphal bool slow = lock_sock_fast(ssk); 7571b3e7edeSFlorian Westphal 7581b3e7edeSFlorian Westphal sync_socket_options(msk, ssk); 7591b3e7edeSFlorian Westphal 7601b3e7edeSFlorian Westphal unlock_sock_fast(ssk, slow); 761df00b087SFlorian Westphal } 762df00b087SFlorian Westphal 76378962489SFlorian Westphal void mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk) 76478962489SFlorian Westphal { 765df00b087SFlorian Westphal struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); 766df00b087SFlorian Westphal 76778962489SFlorian Westphal msk_owned_by_me(msk); 768df00b087SFlorian Westphal 769df00b087SFlorian Westphal if (READ_ONCE(subflow->setsockopt_seq) != msk->setsockopt_seq) { 770df00b087SFlorian Westphal __mptcp_sockopt_sync(msk, ssk); 771df00b087SFlorian Westphal 772df00b087SFlorian Westphal subflow->setsockopt_seq = msk->setsockopt_seq; 773df00b087SFlorian Westphal } 77478962489SFlorian Westphal } 77578962489SFlorian Westphal 77678962489SFlorian Westphal void mptcp_sockopt_sync_all(struct mptcp_sock *msk) 77778962489SFlorian Westphal { 77878962489SFlorian Westphal struct mptcp_subflow_context *subflow; 779df00b087SFlorian Westphal struct sock *sk = (struct sock *)msk; 780df00b087SFlorian Westphal u32 seq; 78178962489SFlorian Westphal 782df00b087SFlorian Westphal seq = sockopt_seq_reset(sk); 78378962489SFlorian Westphal 78478962489SFlorian Westphal mptcp_for_each_subflow(msk, subflow) { 78578962489SFlorian Westphal struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 786df00b087SFlorian Westphal u32 sseq = READ_ONCE(subflow->setsockopt_seq); 78778962489SFlorian Westphal 788df00b087SFlorian Westphal if (sseq != msk->setsockopt_seq) { 789df00b087SFlorian Westphal __mptcp_sockopt_sync(msk, ssk); 790df00b087SFlorian Westphal WRITE_ONCE(subflow->setsockopt_seq, seq); 791df00b087SFlorian Westphal } else if (sseq != seq) { 792df00b087SFlorian Westphal WRITE_ONCE(subflow->setsockopt_seq, seq); 793df00b087SFlorian Westphal } 79478962489SFlorian Westphal 79578962489SFlorian Westphal cond_resched(); 79678962489SFlorian Westphal } 797df00b087SFlorian Westphal 798df00b087SFlorian Westphal msk->setsockopt_seq = seq; 79978962489SFlorian Westphal } 800