mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 23:22:31 +02:00
Merge branch 'mptcp-various-small-and-unrelated-improvements'
Matthieu Baerts says: ==================== mptcp: various small and unrelated improvements Here are various unrelated patches: - Patch 1: sched: remove unused structure. - Patch 2: sched: split the validation part, a preparation for later. - Patch 3: pm: clarify code, not to think there is a possible UaF. Note: a previous version has already been sent individually to Netdev. - Patch 4: subflow: simplify subflow_hmac_valid by passing subflow_req. - Patch 5: mib: add counter for MPJoin rejected by the PM. - Patch 6: selftests: validate this new MPJoinRejected counter. - Patch 7: selftests: define nlh variable only where needed. - Patch 8: selftests: show how to use IPPROTO_MPTCP with getaddrinfo. Note: a previous version has already been sent individually to Netdev. v1: https://lore.kernel.org/20250411-net-next-mptcp-sched-mib-sft-misc-v1-0-85ac8c6654c3@kernel.org ==================== Link: https://patch.msgid.link/20250413-net-next-mptcp-sched-mib-sft-misc-v2-0-0f83a4350150@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
cd6d627f73
|
|
@ -101,18 +101,9 @@ struct mptcp_out_options {
|
|||
#define MPTCP_SCHED_MAX 128
|
||||
#define MPTCP_SCHED_BUF_MAX (MPTCP_SCHED_NAME_MAX * MPTCP_SCHED_MAX)
|
||||
|
||||
#define MPTCP_SUBFLOWS_MAX 8
|
||||
|
||||
struct mptcp_sched_data {
|
||||
u8 subflows;
|
||||
struct mptcp_subflow_context *contexts[MPTCP_SUBFLOWS_MAX];
|
||||
};
|
||||
|
||||
struct mptcp_sched_ops {
|
||||
int (*get_send)(struct mptcp_sock *msk,
|
||||
struct mptcp_sched_data *data);
|
||||
int (*get_retrans)(struct mptcp_sock *msk,
|
||||
struct mptcp_sched_data *data);
|
||||
int (*get_send)(struct mptcp_sock *msk);
|
||||
int (*get_retrans)(struct mptcp_sock *msk);
|
||||
|
||||
char name[MPTCP_SCHED_NAME_MAX];
|
||||
struct module *owner;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
|
|||
SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC),
|
||||
SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX),
|
||||
SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
|
||||
SNMP_MIB_ITEM("MPJoinRejected", MPTCP_MIB_JOINREJECTED),
|
||||
SNMP_MIB_ITEM("MPJoinSynTx", MPTCP_MIB_JOINSYNTX),
|
||||
SNMP_MIB_ITEM("MPJoinSynTxCreatSkErr", MPTCP_MIB_JOINSYNTXCREATSKERR),
|
||||
SNMP_MIB_ITEM("MPJoinSynTxBindErr", MPTCP_MIB_JOINSYNTXBINDERR),
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ enum linux_mptcp_mib_field {
|
|||
MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */
|
||||
MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */
|
||||
MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */
|
||||
MPTCP_MIB_JOINREJECTED, /* The PM rejected the JOIN request */
|
||||
MPTCP_MIB_JOINSYNTX, /* Sending a SYN + MP_JOIN */
|
||||
MPTCP_MIB_JOINSYNTXCREATSKERR, /* Not able to create a socket when sending a SYN + MP_JOIN */
|
||||
MPTCP_MIB_JOINSYNTXBINDERR, /* Not able to bind() the address when sending a SYN + MP_JOIN */
|
||||
|
|
|
|||
|
|
@ -151,10 +151,13 @@ bool mptcp_remove_anno_list_by_saddr(struct mptcp_sock *msk,
|
|||
const struct mptcp_addr_info *addr)
|
||||
{
|
||||
struct mptcp_pm_add_entry *entry;
|
||||
bool ret;
|
||||
|
||||
entry = mptcp_pm_del_add_timer(msk, addr, false);
|
||||
ret = entry;
|
||||
kfree(entry);
|
||||
return entry;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk)
|
||||
|
|
|
|||
|
|
@ -3527,8 +3527,10 @@ bool mptcp_finish_join(struct sock *ssk)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!mptcp_pm_allow_new_subflow(msk))
|
||||
if (!mptcp_pm_allow_new_subflow(msk)) {
|
||||
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_JOINREJECTED);
|
||||
goto err_prohibited;
|
||||
}
|
||||
|
||||
/* If we can't acquire msk socket lock here, let the release callback
|
||||
* handle it
|
||||
|
|
|
|||
|
|
@ -744,6 +744,7 @@ void mptcp_info2sockaddr(const struct mptcp_addr_info *info,
|
|||
struct sockaddr_storage *addr,
|
||||
unsigned short family);
|
||||
struct mptcp_sched_ops *mptcp_sched_find(const char *name);
|
||||
int mptcp_validate_scheduler(struct mptcp_sched_ops *sched);
|
||||
int mptcp_register_scheduler(struct mptcp_sched_ops *sched);
|
||||
void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched);
|
||||
void mptcp_sched_init(void);
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@
|
|||
static DEFINE_SPINLOCK(mptcp_sched_list_lock);
|
||||
static LIST_HEAD(mptcp_sched_list);
|
||||
|
||||
static int mptcp_sched_default_get_send(struct mptcp_sock *msk,
|
||||
struct mptcp_sched_data *data)
|
||||
static int mptcp_sched_default_get_send(struct mptcp_sock *msk)
|
||||
{
|
||||
struct sock *ssk;
|
||||
|
||||
|
|
@ -29,8 +28,7 @@ static int mptcp_sched_default_get_send(struct mptcp_sock *msk,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mptcp_sched_default_get_retrans(struct mptcp_sock *msk,
|
||||
struct mptcp_sched_data *data)
|
||||
static int mptcp_sched_default_get_retrans(struct mptcp_sock *msk)
|
||||
{
|
||||
struct sock *ssk;
|
||||
|
||||
|
|
@ -84,10 +82,23 @@ void mptcp_get_available_schedulers(char *buf, size_t maxlen)
|
|||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
int mptcp_validate_scheduler(struct mptcp_sched_ops *sched)
|
||||
{
|
||||
if (!sched->get_send) {
|
||||
pr_err("%s does not implement required ops\n", sched->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mptcp_register_scheduler(struct mptcp_sched_ops *sched)
|
||||
{
|
||||
if (!sched->get_send)
|
||||
return -EINVAL;
|
||||
int ret;
|
||||
|
||||
ret = mptcp_validate_scheduler(sched);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spin_lock(&mptcp_sched_list_lock);
|
||||
if (mptcp_sched_find(sched->name)) {
|
||||
|
|
@ -157,7 +168,6 @@ void mptcp_subflow_set_scheduled(struct mptcp_subflow_context *subflow,
|
|||
int mptcp_sched_get_send(struct mptcp_sock *msk)
|
||||
{
|
||||
struct mptcp_subflow_context *subflow;
|
||||
struct mptcp_sched_data *data = NULL;
|
||||
|
||||
msk_owned_by_me(msk);
|
||||
|
||||
|
|
@ -178,14 +188,13 @@ int mptcp_sched_get_send(struct mptcp_sock *msk)
|
|||
}
|
||||
|
||||
if (msk->sched == &mptcp_sched_default || !msk->sched)
|
||||
return mptcp_sched_default_get_send(msk, data);
|
||||
return msk->sched->get_send(msk, data);
|
||||
return mptcp_sched_default_get_send(msk);
|
||||
return msk->sched->get_send(msk);
|
||||
}
|
||||
|
||||
int mptcp_sched_get_retrans(struct mptcp_sock *msk)
|
||||
{
|
||||
struct mptcp_subflow_context *subflow;
|
||||
struct mptcp_sched_data *data = NULL;
|
||||
|
||||
msk_owned_by_me(msk);
|
||||
|
||||
|
|
@ -199,8 +208,8 @@ int mptcp_sched_get_retrans(struct mptcp_sock *msk)
|
|||
}
|
||||
|
||||
if (msk->sched == &mptcp_sched_default || !msk->sched)
|
||||
return mptcp_sched_default_get_retrans(msk, data);
|
||||
return mptcp_sched_default_get_retrans(msk);
|
||||
if (msk->sched->get_retrans)
|
||||
return msk->sched->get_retrans(msk, data);
|
||||
return msk->sched->get_send(msk, data);
|
||||
return msk->sched->get_retrans(msk);
|
||||
return msk->sched->get_send(msk);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,6 +247,7 @@ static int subflow_check_req(struct request_sock *req,
|
|||
|
||||
if (unlikely(req->syncookie)) {
|
||||
if (!mptcp_can_accept_new_subflow(subflow_req->msk)) {
|
||||
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINREJECTED);
|
||||
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
|
||||
return -EPERM;
|
||||
}
|
||||
|
|
@ -745,15 +746,11 @@ struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *op
|
|||
EXPORT_SYMBOL(mptcp_subflow_reqsk_alloc);
|
||||
|
||||
/* validate hmac received in third ACK */
|
||||
static bool subflow_hmac_valid(const struct request_sock *req,
|
||||
static bool subflow_hmac_valid(const struct mptcp_subflow_request_sock *subflow_req,
|
||||
const struct mptcp_options_received *mp_opt)
|
||||
{
|
||||
const struct mptcp_subflow_request_sock *subflow_req;
|
||||
struct mptcp_sock *msk = subflow_req->msk;
|
||||
u8 hmac[SHA256_DIGEST_SIZE];
|
||||
struct mptcp_sock *msk;
|
||||
|
||||
subflow_req = mptcp_subflow_rsk(req);
|
||||
msk = subflow_req->msk;
|
||||
|
||||
subflow_generate_hmac(READ_ONCE(msk->remote_key),
|
||||
READ_ONCE(msk->local_key),
|
||||
|
|
@ -899,13 +896,14 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
|
|||
goto dispose_child;
|
||||
}
|
||||
|
||||
if (!subflow_hmac_valid(req, &mp_opt)) {
|
||||
if (!subflow_hmac_valid(subflow_req, &mp_opt)) {
|
||||
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
|
||||
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
|
||||
goto dispose_child;
|
||||
}
|
||||
|
||||
if (!mptcp_can_accept_new_subflow(owner)) {
|
||||
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINREJECTED);
|
||||
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
|
||||
goto dispose_child;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,13 +180,26 @@ static void xgetnameinfo(const struct sockaddr *addr, socklen_t addrlen,
|
|||
}
|
||||
|
||||
static void xgetaddrinfo(const char *node, const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo *hints,
|
||||
struct addrinfo **res)
|
||||
{
|
||||
again:
|
||||
int err = getaddrinfo(node, service, hints, res);
|
||||
|
||||
if (err) {
|
||||
const char *errstr = getxinfo_strerr(err);
|
||||
const char *errstr;
|
||||
|
||||
/* glibc starts to support MPTCP since v2.42.
|
||||
* For older versions, use IPPROTO_TCP to resolve,
|
||||
* and use TCP/MPTCP to create socket.
|
||||
* Link: https://sourceware.org/git/?p=glibc.git;a=commit;h=a8e9022e0f82
|
||||
*/
|
||||
if (err == EAI_SOCKTYPE) {
|
||||
hints->ai_protocol = IPPROTO_TCP;
|
||||
goto again;
|
||||
}
|
||||
|
||||
errstr = getxinfo_strerr(err);
|
||||
|
||||
fprintf(stderr, "Fatal: getaddrinfo(%s:%s): %s\n",
|
||||
node ? node : "", service ? service : "", errstr);
|
||||
|
|
@ -292,7 +305,7 @@ static int sock_listen_mptcp(const char * const listenaddr,
|
|||
{
|
||||
int sock = -1;
|
||||
struct addrinfo hints = {
|
||||
.ai_protocol = IPPROTO_TCP,
|
||||
.ai_protocol = IPPROTO_MPTCP,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
.ai_flags = AI_PASSIVE | AI_NUMERICHOST
|
||||
};
|
||||
|
|
@ -356,7 +369,7 @@ static int sock_connect_mptcp(const char * const remoteaddr,
|
|||
int infd, struct wstate *winfo)
|
||||
{
|
||||
struct addrinfo hints = {
|
||||
.ai_protocol = IPPROTO_TCP,
|
||||
.ai_protocol = IPPROTO_MPTCP,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
struct addrinfo *a, *addr;
|
||||
|
|
|
|||
|
|
@ -185,9 +185,10 @@ static void parse_nlmsg(struct nlmsghdr *nlh)
|
|||
}
|
||||
}
|
||||
|
||||
static void recv_nlmsg(int fd, struct nlmsghdr *nlh)
|
||||
static void recv_nlmsg(int fd)
|
||||
{
|
||||
char rcv_buff[8192];
|
||||
struct nlmsghdr *nlh = (struct nlmsghdr *)rcv_buff;
|
||||
struct sockaddr_nl rcv_nladdr = {
|
||||
.nl_family = AF_NETLINK
|
||||
};
|
||||
|
|
@ -204,7 +205,6 @@ static void recv_nlmsg(int fd, struct nlmsghdr *nlh)
|
|||
int len;
|
||||
|
||||
len = recvmsg(fd, &rcv_msg, 0);
|
||||
nlh = (struct nlmsghdr *)rcv_buff;
|
||||
|
||||
while (NLMSG_OK(nlh, len)) {
|
||||
if (nlh->nlmsg_type == NLMSG_DONE) {
|
||||
|
|
@ -225,7 +225,6 @@ static void recv_nlmsg(int fd, struct nlmsghdr *nlh)
|
|||
|
||||
static void get_mptcpinfo(__u32 token)
|
||||
{
|
||||
struct nlmsghdr *nlh = NULL;
|
||||
int fd;
|
||||
|
||||
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
|
||||
|
|
@ -233,7 +232,7 @@ static void get_mptcpinfo(__u32 token)
|
|||
die_perror("Netlink socket");
|
||||
|
||||
send_query(fd, token);
|
||||
recv_nlmsg(fd, nlh);
|
||||
recv_nlmsg(fd);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ unset sflags
|
|||
unset fastclose
|
||||
unset fullmesh
|
||||
unset speed
|
||||
unset join_syn_rej
|
||||
unset join_csum_ns1
|
||||
unset join_csum_ns2
|
||||
unset join_fail_nr
|
||||
|
|
@ -1403,6 +1404,7 @@ chk_join_nr()
|
|||
local syn_nr=$1
|
||||
local syn_ack_nr=$2
|
||||
local ack_nr=$3
|
||||
local syn_rej=${join_syn_rej:-0}
|
||||
local csum_ns1=${join_csum_ns1:-0}
|
||||
local csum_ns2=${join_csum_ns2:-0}
|
||||
local fail_nr=${join_fail_nr:-0}
|
||||
|
|
@ -1468,6 +1470,15 @@ chk_join_nr()
|
|||
fail_test "got $count JOIN[s] ack HMAC failure expected 0"
|
||||
fi
|
||||
|
||||
count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinRejected")
|
||||
if [ -z "$count" ]; then
|
||||
rc=${KSFT_SKIP}
|
||||
elif [ "$count" != "$syn_rej" ]; then
|
||||
rc=${KSFT_FAIL}
|
||||
print_check "syn rejected"
|
||||
fail_test "got $count JOIN[s] syn rejected expected $syn_rej"
|
||||
fi
|
||||
|
||||
print_results "join Rx" ${rc}
|
||||
|
||||
join_syn_tx="${join_syn_tx:-${syn_nr}}" \
|
||||
|
|
@ -1963,7 +1974,8 @@ subflows_tests()
|
|||
pm_nl_set_limits $ns2 0 1
|
||||
pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
|
||||
run_tests $ns1 $ns2 10.0.1.1
|
||||
chk_join_nr 1 1 0
|
||||
join_syn_rej=1 \
|
||||
chk_join_nr 1 1 0
|
||||
fi
|
||||
|
||||
# subflow
|
||||
|
|
@ -1992,7 +2004,8 @@ subflows_tests()
|
|||
pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
|
||||
pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
|
||||
run_tests $ns1 $ns2 10.0.1.1
|
||||
chk_join_nr 2 2 1
|
||||
join_syn_rej=1 \
|
||||
chk_join_nr 2 2 1
|
||||
fi
|
||||
|
||||
# single subflow, dev
|
||||
|
|
@ -3061,7 +3074,8 @@ syncookies_tests()
|
|||
pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
|
||||
pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
|
||||
run_tests $ns1 $ns2 10.0.1.1
|
||||
chk_join_nr 2 1 1
|
||||
join_syn_rej=1 \
|
||||
chk_join_nr 2 1 1
|
||||
fi
|
||||
|
||||
# test signal address with cookies
|
||||
|
|
@ -3545,7 +3559,8 @@ userspace_tests()
|
|||
pm_nl_set_limits $ns2 1 1
|
||||
pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
|
||||
run_tests $ns1 $ns2 10.0.1.1
|
||||
chk_join_nr 1 1 0
|
||||
join_syn_rej=1 \
|
||||
chk_join_nr 1 1 0
|
||||
fi
|
||||
|
||||
# userspace pm type does not send join
|
||||
|
|
@ -3568,7 +3583,8 @@ userspace_tests()
|
|||
pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
|
||||
sflags=backup speed=slow \
|
||||
run_tests $ns1 $ns2 10.0.1.1
|
||||
chk_join_nr 1 1 0
|
||||
join_syn_rej=1 \
|
||||
chk_join_nr 1 1 0
|
||||
chk_prio_nr 0 0 0 0
|
||||
fi
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user