diff --git a/net/mptcp/options.c b/net/mptcp/options.c index ce0de02f5a3a..c2f4d7bd080c 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -374,10 +374,10 @@ static void mptcp_parse_option(const struct sk_buff *skb, break; ptr += 2; - mp_opt->rcvr_key = get_unaligned_be64(ptr); + mp_opt->fc_recv_key = get_unaligned_be64(ptr); ptr += 8; mp_opt->suboptions |= OPTION_MPTCP_FASTCLOSE; - pr_debug("MP_FASTCLOSE: recv_key=%llu\n", mp_opt->rcvr_key); + pr_debug("MP_FASTCLOSE: recv_key=%llu\n", mp_opt->fc_recv_key); break; case MPTCPOPT_RST: @@ -1258,7 +1258,7 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) if (unlikely(mp_opt.suboptions != OPTION_MPTCP_DSS)) { if ((mp_opt.suboptions & OPTION_MPTCP_FASTCLOSE) && - READ_ONCE(msk->local_key) == mp_opt.rcvr_key) { + READ_ONCE(msk->local_key) == mp_opt.fc_recv_key) { WRITE_ONCE(msk->rcv_fastclose, true); mptcp_schedule_work((struct sock *)msk); MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFASTCLOSERX); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 0384d6a023f9..29b03275a59e 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -145,13 +145,13 @@ static inline bool before64(__u64 seq1, __u64 seq2) #define after64(seq2, seq1) before64(seq1, seq2) struct mptcp_options_received { - u64 sndr_key; - u64 rcvr_key; - u64 data_ack; - u64 data_seq; - u32 subflow_seq; - u16 data_len; - __sum16 csum; + struct { /* DSS, also used by MP_CAPABLE with data */ + u64 data_ack; + u64 data_seq; + u32 subflow_seq; + u16 data_len; + __sum16 csum; + }; struct_group(status, u16 suboptions; u16 use_map:1, @@ -167,15 +167,29 @@ struct mptcp_options_received { deny_join_id0:1, __unused:2; ); - u8 join_id; - u32 token; - u32 nonce; - u64 thmac; - u8 hmac[MPTCPOPT_HMAC_LEN]; - struct mptcp_addr_info addr; struct mptcp_rm_list rm_list; - u64 ahmac; - u64 fail_seq; + /* Options below are mutually exclusive, see mptcp_parse_option() */ + union { + struct { /* MP_CAPABLE */ + u64 sndr_key; + u64 rcvr_key; + }; + struct { /* MP_JOIN */ + u32 nonce; + u8 join_id; + union { + u32 token; /* SYN */ + u64 thmac; /* SYN + ACK */ + u8 hmac[MPTCPOPT_HMAC_LEN]; /* ACK */ + }; + }; + struct { /* ADD_ADDR */ + struct mptcp_addr_info addr; + u64 ahmac; + }; + u64 fail_seq; /* MP_FAIL */ + u64 fc_recv_key; /* MP_FASTCLOSE */ + }; }; static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field) @@ -593,7 +607,6 @@ struct mptcp_subflow_context { bool fully_established; /* path validated */ u32 lent_mem_frag; u32 remote_nonce; - u64 thmac; u32 local_nonce; u32 remote_token; union { diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index f0a6725d2c37..14aa82647c3d 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -408,20 +408,21 @@ static struct dst_entry *subflow_v6_route_req(const struct sock *sk, #endif /* validate received truncated hmac and create hmac for third ACK */ -static bool subflow_thmac_valid(struct mptcp_subflow_context *subflow) +static bool subflow_thmac_valid(struct mptcp_subflow_context *subflow, + u64 thmac) { u8 hmac[SHA256_DIGEST_SIZE]; - u64 thmac; + u64 expected_thmac; subflow_generate_hmac(subflow->remote_key, subflow->local_key, subflow->remote_nonce, subflow->local_nonce, hmac); - thmac = get_unaligned_be64(hmac); - pr_debug("subflow=%p, token=%u, thmac=%llu, subflow->thmac=%llu\n", - subflow, subflow->token, thmac, subflow->thmac); + expected_thmac = get_unaligned_be64(hmac); + pr_debug("subflow=%p, token=%u, expected_thmac=%llu, thmac=%llu\n", + subflow, subflow->token, expected_thmac, thmac); - return thmac == subflow->thmac; + return expected_thmac == thmac; } void mptcp_subflow_reset(struct sock *ssk) @@ -575,14 +576,13 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) } subflow->backup = mp_opt.backup; - subflow->thmac = mp_opt.thmac; subflow->remote_nonce = mp_opt.nonce; WRITE_ONCE(subflow->remote_id, mp_opt.join_id); pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u backup=%d\n", - subflow, subflow->thmac, subflow->remote_nonce, + subflow, mp_opt.thmac, subflow->remote_nonce, subflow->backup); - if (!subflow_thmac_valid(subflow)) { + if (!subflow_thmac_valid(subflow, mp_opt.thmac)) { MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKMAC); subflow->reset_reason = MPTCP_RST_EMPTCP; goto do_reset;