Commit 237c3851 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'mptcp-close-subflow-when-receiving-tcp-fin-and-misc'

Matthieu Baerts says:

====================
mptcp: close subflow when receiving TCP+FIN and misc.

Here are different fixes:

Patch 1 closes the subflow after having received a FIN, instead
of leaving it half-closed until the end of the MPTCP connection.
A fix for v5.12.

Patch 2 validates the previous patch.

Patch 3 is a fix for a recent fix to check both directions for the
backup flag. It can follow the 'Fixes' commit and be backported up
to v5.7.

Patch 4 adds a missing \n at the end of pr_debug(), causing debug
messages to be displayed with a delay, which confuses the debugger.
A fix for v5.6.
====================

Link: https://patch.msgid.link/20240826-net-mptcp-close-extra-sf-fin-v1-0-905199fe1172@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents bac76cf8 cb41b195
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -68,12 +68,12 @@ void __mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflo
	skb = skb_peek_tail(&sk->sk_receive_queue);
	if (skb) {
		WARN_ON_ONCE(MPTCP_SKB_CB(skb)->end_seq);
		pr_debug("msk %p moving seq %llx -> %llx end_seq %llx -> %llx", sk,
		pr_debug("msk %p moving seq %llx -> %llx end_seq %llx -> %llx\n", sk,
			 MPTCP_SKB_CB(skb)->map_seq, MPTCP_SKB_CB(skb)->map_seq + msk->ack_seq,
			 MPTCP_SKB_CB(skb)->end_seq, MPTCP_SKB_CB(skb)->end_seq + msk->ack_seq);
		MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq;
		MPTCP_SKB_CB(skb)->end_seq += msk->ack_seq;
	}

	pr_debug("msk=%p ack_seq=%llx", msk, msk->ack_seq);
	pr_debug("msk=%p ack_seq=%llx\n", msk, msk->ack_seq);
}
+25 −25
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
			mp_opt->suboptions |= OPTION_MPTCP_CSUMREQD;
			ptr += 2;
		}
		pr_debug("MP_CAPABLE version=%x, flags=%x, optlen=%d sndr=%llu, rcvr=%llu len=%d csum=%u",
		pr_debug("MP_CAPABLE version=%x, flags=%x, optlen=%d sndr=%llu, rcvr=%llu len=%d csum=%u\n",
			 version, flags, opsize, mp_opt->sndr_key,
			 mp_opt->rcvr_key, mp_opt->data_len, mp_opt->csum);
		break;
@@ -131,7 +131,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
			ptr += 4;
			mp_opt->nonce = get_unaligned_be32(ptr);
			ptr += 4;
			pr_debug("MP_JOIN bkup=%u, id=%u, token=%u, nonce=%u",
			pr_debug("MP_JOIN bkup=%u, id=%u, token=%u, nonce=%u\n",
				 mp_opt->backup, mp_opt->join_id,
				 mp_opt->token, mp_opt->nonce);
		} else if (opsize == TCPOLEN_MPTCP_MPJ_SYNACK) {
@@ -142,19 +142,19 @@ static void mptcp_parse_option(const struct sk_buff *skb,
			ptr += 8;
			mp_opt->nonce = get_unaligned_be32(ptr);
			ptr += 4;
			pr_debug("MP_JOIN bkup=%u, id=%u, thmac=%llu, nonce=%u",
			pr_debug("MP_JOIN bkup=%u, id=%u, thmac=%llu, nonce=%u\n",
				 mp_opt->backup, mp_opt->join_id,
				 mp_opt->thmac, mp_opt->nonce);
		} else if (opsize == TCPOLEN_MPTCP_MPJ_ACK) {
			mp_opt->suboptions |= OPTION_MPTCP_MPJ_ACK;
			ptr += 2;
			memcpy(mp_opt->hmac, ptr, MPTCPOPT_HMAC_LEN);
			pr_debug("MP_JOIN hmac");
			pr_debug("MP_JOIN hmac\n");
		}
		break;

	case MPTCPOPT_DSS:
		pr_debug("DSS");
		pr_debug("DSS\n");
		ptr++;

		/* we must clear 'mpc_map' be able to detect MP_CAPABLE
@@ -169,7 +169,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
		mp_opt->ack64 = (flags & MPTCP_DSS_ACK64) != 0;
		mp_opt->use_ack = (flags & MPTCP_DSS_HAS_ACK);

		pr_debug("data_fin=%d dsn64=%d use_map=%d ack64=%d use_ack=%d",
		pr_debug("data_fin=%d dsn64=%d use_map=%d ack64=%d use_ack=%d\n",
			 mp_opt->data_fin, mp_opt->dsn64,
			 mp_opt->use_map, mp_opt->ack64,
			 mp_opt->use_ack);
@@ -207,7 +207,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
				ptr += 4;
			}

			pr_debug("data_ack=%llu", mp_opt->data_ack);
			pr_debug("data_ack=%llu\n", mp_opt->data_ack);
		}

		if (mp_opt->use_map) {
@@ -231,7 +231,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
				ptr += 2;
			}

			pr_debug("data_seq=%llu subflow_seq=%u data_len=%u csum=%d:%u",
			pr_debug("data_seq=%llu subflow_seq=%u data_len=%u csum=%d:%u\n",
				 mp_opt->data_seq, mp_opt->subflow_seq,
				 mp_opt->data_len, !!(mp_opt->suboptions & OPTION_MPTCP_CSUMREQD),
				 mp_opt->csum);
@@ -293,7 +293,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
			mp_opt->ahmac = get_unaligned_be64(ptr);
			ptr += 8;
		}
		pr_debug("ADD_ADDR%s: id=%d, ahmac=%llu, echo=%d, port=%d",
		pr_debug("ADD_ADDR%s: id=%d, ahmac=%llu, echo=%d, port=%d\n",
			 (mp_opt->addr.family == AF_INET6) ? "6" : "",
			 mp_opt->addr.id, mp_opt->ahmac, mp_opt->echo, ntohs(mp_opt->addr.port));
		break;
@@ -309,7 +309,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
		mp_opt->rm_list.nr = opsize - TCPOLEN_MPTCP_RM_ADDR_BASE;
		for (i = 0; i < mp_opt->rm_list.nr; i++)
			mp_opt->rm_list.ids[i] = *ptr++;
		pr_debug("RM_ADDR: rm_list_nr=%d", mp_opt->rm_list.nr);
		pr_debug("RM_ADDR: rm_list_nr=%d\n", mp_opt->rm_list.nr);
		break;

	case MPTCPOPT_MP_PRIO:
@@ -318,7 +318,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,

		mp_opt->suboptions |= OPTION_MPTCP_PRIO;
		mp_opt->backup = *ptr++ & MPTCP_PRIO_BKUP;
		pr_debug("MP_PRIO: prio=%d", mp_opt->backup);
		pr_debug("MP_PRIO: prio=%d\n", mp_opt->backup);
		break;

	case MPTCPOPT_MP_FASTCLOSE:
@@ -329,7 +329,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
		mp_opt->rcvr_key = get_unaligned_be64(ptr);
		ptr += 8;
		mp_opt->suboptions |= OPTION_MPTCP_FASTCLOSE;
		pr_debug("MP_FASTCLOSE: recv_key=%llu", mp_opt->rcvr_key);
		pr_debug("MP_FASTCLOSE: recv_key=%llu\n", mp_opt->rcvr_key);
		break;

	case MPTCPOPT_RST:
@@ -343,7 +343,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
		flags = *ptr++;
		mp_opt->reset_transient = flags & MPTCP_RST_TRANSIENT;
		mp_opt->reset_reason = *ptr;
		pr_debug("MP_RST: transient=%u reason=%u",
		pr_debug("MP_RST: transient=%u reason=%u\n",
			 mp_opt->reset_transient, mp_opt->reset_reason);
		break;

@@ -354,7 +354,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
		ptr += 2;
		mp_opt->suboptions |= OPTION_MPTCP_FAIL;
		mp_opt->fail_seq = get_unaligned_be64(ptr);
		pr_debug("MP_FAIL: data_seq=%llu", mp_opt->fail_seq);
		pr_debug("MP_FAIL: data_seq=%llu\n", mp_opt->fail_seq);
		break;

	default:
@@ -417,7 +417,7 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
		*size = TCPOLEN_MPTCP_MPC_SYN;
		return true;
	} else if (subflow->request_join) {
		pr_debug("remote_token=%u, nonce=%u", subflow->remote_token,
		pr_debug("remote_token=%u, nonce=%u\n", subflow->remote_token,
			 subflow->local_nonce);
		opts->suboptions = OPTION_MPTCP_MPJ_SYN;
		opts->join_id = subflow->local_id;
@@ -500,7 +500,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
			*size = TCPOLEN_MPTCP_MPC_ACK;
		}

		pr_debug("subflow=%p, local_key=%llu, remote_key=%llu map_len=%d",
		pr_debug("subflow=%p, local_key=%llu, remote_key=%llu map_len=%d\n",
			 subflow, subflow->local_key, subflow->remote_key,
			 data_len);

@@ -509,7 +509,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
		opts->suboptions = OPTION_MPTCP_MPJ_ACK;
		memcpy(opts->hmac, subflow->hmac, MPTCPOPT_HMAC_LEN);
		*size = TCPOLEN_MPTCP_MPJ_ACK;
		pr_debug("subflow=%p", subflow);
		pr_debug("subflow=%p\n", subflow);

		/* we can use the full delegate action helper only from BH context
		 * If we are in process context - sk is flushing the backlog at
@@ -675,7 +675,7 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *

	*size = len;
	if (drop_other_suboptions) {
		pr_debug("drop other suboptions");
		pr_debug("drop other suboptions\n");
		opts->suboptions = 0;

		/* note that e.g. DSS could have written into the memory
@@ -695,7 +695,7 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
	} else {
		MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ECHOADDTX);
	}
	pr_debug("addr_id=%d, ahmac=%llu, echo=%d, port=%d",
	pr_debug("addr_id=%d, ahmac=%llu, echo=%d, port=%d\n",
		 opts->addr.id, opts->ahmac, echo, ntohs(opts->addr.port));

	return true;
@@ -726,7 +726,7 @@ static bool mptcp_established_options_rm_addr(struct sock *sk,
	opts->rm_list = rm_list;

	for (i = 0; i < opts->rm_list.nr; i++)
		pr_debug("rm_list_ids[%d]=%d", i, opts->rm_list.ids[i]);
		pr_debug("rm_list_ids[%d]=%d\n", i, opts->rm_list.ids[i]);
	MPTCP_ADD_STATS(sock_net(sk), MPTCP_MIB_RMADDRTX, opts->rm_list.nr);
	return true;
}
@@ -752,7 +752,7 @@ static bool mptcp_established_options_mp_prio(struct sock *sk,
	opts->suboptions |= OPTION_MPTCP_PRIO;
	opts->backup = subflow->request_bkup;

	pr_debug("prio=%d", opts->backup);
	pr_debug("prio=%d\n", opts->backup);

	return true;
}
@@ -794,7 +794,7 @@ static bool mptcp_established_options_fastclose(struct sock *sk,
	opts->suboptions |= OPTION_MPTCP_FASTCLOSE;
	opts->rcvr_key = READ_ONCE(msk->remote_key);

	pr_debug("FASTCLOSE key=%llu", opts->rcvr_key);
	pr_debug("FASTCLOSE key=%llu\n", opts->rcvr_key);
	MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFASTCLOSETX);
	return true;
}
@@ -816,7 +816,7 @@ static bool mptcp_established_options_mp_fail(struct sock *sk,
	opts->suboptions |= OPTION_MPTCP_FAIL;
	opts->fail_seq = subflow->map_seq;

	pr_debug("MP_FAIL fail_seq=%llu", opts->fail_seq);
	pr_debug("MP_FAIL fail_seq=%llu\n", opts->fail_seq);
	MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILTX);

	return true;
@@ -904,7 +904,7 @@ bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
		opts->csum_reqd = subflow_req->csum_reqd;
		opts->allow_join_id0 = subflow_req->allow_join_id0;
		*size = TCPOLEN_MPTCP_MPC_SYNACK;
		pr_debug("subflow_req=%p, local_key=%llu",
		pr_debug("subflow_req=%p, local_key=%llu\n",
			 subflow_req, subflow_req->local_key);
		return true;
	} else if (subflow_req->mp_join) {
@@ -913,7 +913,7 @@ bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
		opts->join_id = subflow_req->local_id;
		opts->thmac = subflow_req->thmac;
		opts->nonce = subflow_req->local_nonce;
		pr_debug("req=%p, bkup=%u, id=%u, thmac=%llu, nonce=%u",
		pr_debug("req=%p, bkup=%u, id=%u, thmac=%llu, nonce=%u\n",
			 subflow_req, opts->backup, opts->join_id,
			 opts->thmac, opts->nonce);
		*size = TCPOLEN_MPTCP_MPJ_SYNACK;
+14 −14
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
{
	u8 add_addr = READ_ONCE(msk->pm.addr_signal);

	pr_debug("msk=%p, local_id=%d, echo=%d", msk, addr->id, echo);
	pr_debug("msk=%p, local_id=%d, echo=%d\n", msk, addr->id, echo);

	lockdep_assert_held(&msk->pm.lock);

@@ -45,7 +45,7 @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_
{
	u8 rm_addr = READ_ONCE(msk->pm.addr_signal);

	pr_debug("msk=%p, rm_list_nr=%d", msk, rm_list->nr);
	pr_debug("msk=%p, rm_list_nr=%d\n", msk, rm_list->nr);

	if (rm_addr) {
		MPTCP_ADD_STATS(sock_net((struct sock *)msk),
@@ -66,7 +66,7 @@ void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int
{
	struct mptcp_pm_data *pm = &msk->pm;

	pr_debug("msk=%p, token=%u side=%d", msk, READ_ONCE(msk->token), server_side);
	pr_debug("msk=%p, token=%u side=%d\n", msk, READ_ONCE(msk->token), server_side);

	WRITE_ONCE(pm->server_side, server_side);
	mptcp_event(MPTCP_EVENT_CREATED, msk, ssk, GFP_ATOMIC);
@@ -90,7 +90,7 @@ bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk)

	subflows_max = mptcp_pm_get_subflows_max(msk);

	pr_debug("msk=%p subflows=%d max=%d allow=%d", msk, pm->subflows,
	pr_debug("msk=%p subflows=%d max=%d allow=%d\n", msk, pm->subflows,
		 subflows_max, READ_ONCE(pm->accept_subflow));

	/* try to avoid acquiring the lock below */
@@ -114,7 +114,7 @@ bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk)
static bool mptcp_pm_schedule_work(struct mptcp_sock *msk,
				   enum mptcp_pm_status new_status)
{
	pr_debug("msk=%p status=%x new=%lx", msk, msk->pm.status,
	pr_debug("msk=%p status=%x new=%lx\n", msk, msk->pm.status,
		 BIT(new_status));
	if (msk->pm.status & BIT(new_status))
		return false;
@@ -129,7 +129,7 @@ void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk)
	struct mptcp_pm_data *pm = &msk->pm;
	bool announce = false;

	pr_debug("msk=%p", msk);
	pr_debug("msk=%p\n", msk);

	spin_lock_bh(&pm->lock);

@@ -153,14 +153,14 @@ void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk)

void mptcp_pm_connection_closed(struct mptcp_sock *msk)
{
	pr_debug("msk=%p", msk);
	pr_debug("msk=%p\n", msk);
}

void mptcp_pm_subflow_established(struct mptcp_sock *msk)
{
	struct mptcp_pm_data *pm = &msk->pm;

	pr_debug("msk=%p", msk);
	pr_debug("msk=%p\n", msk);

	if (!READ_ONCE(pm->work_pending))
		return;
@@ -212,7 +212,7 @@ void mptcp_pm_add_addr_received(const struct sock *ssk,
	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
	struct mptcp_pm_data *pm = &msk->pm;

	pr_debug("msk=%p remote_id=%d accept=%d", msk, addr->id,
	pr_debug("msk=%p remote_id=%d accept=%d\n", msk, addr->id,
		 READ_ONCE(pm->accept_addr));

	mptcp_event_addr_announced(ssk, addr);
@@ -243,7 +243,7 @@ void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk,
{
	struct mptcp_pm_data *pm = &msk->pm;

	pr_debug("msk=%p", msk);
	pr_debug("msk=%p\n", msk);

	spin_lock_bh(&pm->lock);

@@ -267,7 +267,7 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
	struct mptcp_pm_data *pm = &msk->pm;
	u8 i;

	pr_debug("msk=%p remote_ids_nr=%d", msk, rm_list->nr);
	pr_debug("msk=%p remote_ids_nr=%d\n", msk, rm_list->nr);

	for (i = 0; i < rm_list->nr; i++)
		mptcp_event_addr_removed(msk, rm_list->ids[i]);
@@ -299,19 +299,19 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
	struct mptcp_sock *msk = mptcp_sk(subflow->conn);

	pr_debug("fail_seq=%llu", fail_seq);
	pr_debug("fail_seq=%llu\n", fail_seq);

	if (!READ_ONCE(msk->allow_infinite_fallback))
		return;

	if (!subflow->fail_tout) {
		pr_debug("send MP_FAIL response and infinite map");
		pr_debug("send MP_FAIL response and infinite map\n");

		subflow->send_mp_fail = 1;
		subflow->send_infinite_map = 1;
		tcp_send_ack(sk);
	} else {
		pr_debug("MP_FAIL response received");
		pr_debug("MP_FAIL response received\n");
		WRITE_ONCE(subflow->fail_tout, 0);
	}
}
+10 −10
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
	struct mptcp_sock *msk = entry->sock;
	struct sock *sk = (struct sock *)msk;

	pr_debug("msk=%p", msk);
	pr_debug("msk=%p\n", msk);

	if (!msk)
		return;
@@ -306,7 +306,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
	spin_lock_bh(&msk->pm.lock);

	if (!mptcp_pm_should_add_signal_addr(msk)) {
		pr_debug("retransmit ADD_ADDR id=%d", entry->addr.id);
		pr_debug("retransmit ADD_ADDR id=%d\n", entry->addr.id);
		mptcp_pm_announce_addr(msk, &entry->addr, false);
		mptcp_pm_add_addr_send_ack(msk);
		entry->retrans_times++;
@@ -387,7 +387,7 @@ void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
	struct sock *sk = (struct sock *)msk;
	LIST_HEAD(free_list);

	pr_debug("msk=%p", msk);
	pr_debug("msk=%p\n", msk);

	spin_lock_bh(&msk->pm.lock);
	list_splice_init(&msk->pm.anno_list, &free_list);
@@ -473,7 +473,7 @@ static void __mptcp_pm_send_ack(struct mptcp_sock *msk, struct mptcp_subflow_con
	struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
	bool slow;

	pr_debug("send ack for %s",
	pr_debug("send ack for %s\n",
		 prio ? "mp_prio" : (mptcp_pm_should_add_signal(msk) ? "add_addr" : "rm_addr"));

	slow = lock_sock_fast(ssk);
@@ -708,7 +708,7 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
	add_addr_accept_max = mptcp_pm_get_add_addr_accept_max(msk);
	subflows_max = mptcp_pm_get_subflows_max(msk);

	pr_debug("accepted %d:%d remote family %d",
	pr_debug("accepted %d:%d remote family %d\n",
		 msk->pm.add_addr_accepted, add_addr_accept_max,
		 msk->pm.remote.family);

@@ -767,7 +767,7 @@ int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
{
	struct mptcp_subflow_context *subflow;

	pr_debug("bkup=%d", bkup);
	pr_debug("bkup=%d\n", bkup);

	mptcp_for_each_subflow(msk, subflow) {
		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
@@ -803,7 +803,7 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
	struct sock *sk = (struct sock *)msk;
	u8 i;

	pr_debug("%s rm_list_nr %d",
	pr_debug("%s rm_list_nr %d\n",
		 rm_type == MPTCP_MIB_RMADDR ? "address" : "subflow", rm_list->nr);

	msk_owned_by_me(msk);
@@ -832,7 +832,7 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
			if (rm_type == MPTCP_MIB_RMSUBFLOW && !mptcp_local_id_match(msk, id, rm_id))
				continue;

			pr_debug(" -> %s rm_list_ids[%d]=%u local_id=%u remote_id=%u mpc_id=%u",
			pr_debug(" -> %s rm_list_ids[%d]=%u local_id=%u remote_id=%u mpc_id=%u\n",
				 rm_type == MPTCP_MIB_RMADDR ? "address" : "subflow",
				 i, rm_id, id, remote_id, msk->mpc_endpoint_id);
			spin_unlock_bh(&msk->pm.lock);
@@ -889,7 +889,7 @@ void mptcp_pm_nl_work(struct mptcp_sock *msk)

	spin_lock_bh(&msk->pm.lock);

	pr_debug("msk=%p status=%x", msk, pm->status);
	pr_debug("msk=%p status=%x\n", msk, pm->status);
	if (pm->status & BIT(MPTCP_PM_ADD_ADDR_RECEIVED)) {
		pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED);
		mptcp_pm_nl_add_addr_received(msk);
@@ -1476,7 +1476,7 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
	long s_slot = 0, s_num = 0;
	struct mptcp_sock *msk;

	pr_debug("remove_id=%d", addr->id);
	pr_debug("remove_id=%d\n", addr->id);

	list.ids[list.nr++] = addr->id;

+31 −28
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ static bool mptcp_try_coalesce(struct sock *sk, struct sk_buff *to,
	    !skb_try_coalesce(to, from, &fragstolen, &delta))
		return false;

	pr_debug("colesced seq %llx into %llx new len %d new end seq %llx",
	pr_debug("colesced seq %llx into %llx new len %d new end seq %llx\n",
		 MPTCP_SKB_CB(from)->map_seq, MPTCP_SKB_CB(to)->map_seq,
		 to->len, MPTCP_SKB_CB(from)->end_seq);
	MPTCP_SKB_CB(to)->end_seq = MPTCP_SKB_CB(from)->end_seq;
@@ -217,7 +217,7 @@ static void mptcp_data_queue_ofo(struct mptcp_sock *msk, struct sk_buff *skb)
	end_seq = MPTCP_SKB_CB(skb)->end_seq;
	max_seq = atomic64_read(&msk->rcv_wnd_sent);

	pr_debug("msk=%p seq=%llx limit=%llx empty=%d", msk, seq, max_seq,
	pr_debug("msk=%p seq=%llx limit=%llx empty=%d\n", msk, seq, max_seq,
		 RB_EMPTY_ROOT(&msk->out_of_order_queue));
	if (after64(end_seq, max_seq)) {
		/* out of window */
@@ -643,7 +643,7 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
		}
	}

	pr_debug("msk=%p ssk=%p", msk, ssk);
	pr_debug("msk=%p ssk=%p\n", msk, ssk);
	tp = tcp_sk(ssk);
	do {
		u32 map_remaining, offset;
@@ -724,7 +724,7 @@ static bool __mptcp_ofo_queue(struct mptcp_sock *msk)
	u64 end_seq;

	p = rb_first(&msk->out_of_order_queue);
	pr_debug("msk=%p empty=%d", msk, RB_EMPTY_ROOT(&msk->out_of_order_queue));
	pr_debug("msk=%p empty=%d\n", msk, RB_EMPTY_ROOT(&msk->out_of_order_queue));
	while (p) {
		skb = rb_to_skb(p);
		if (after64(MPTCP_SKB_CB(skb)->map_seq, msk->ack_seq))
@@ -746,7 +746,7 @@ static bool __mptcp_ofo_queue(struct mptcp_sock *msk)
			int delta = msk->ack_seq - MPTCP_SKB_CB(skb)->map_seq;

			/* skip overlapping data, if any */
			pr_debug("uncoalesced seq=%llx ack seq=%llx delta=%d",
			pr_debug("uncoalesced seq=%llx ack seq=%llx delta=%d\n",
				 MPTCP_SKB_CB(skb)->map_seq, msk->ack_seq,
				 delta);
			MPTCP_SKB_CB(skb)->offset += delta;
@@ -1240,7 +1240,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
	size_t copy;
	int i;

	pr_debug("msk=%p ssk=%p sending dfrag at seq=%llu len=%u already sent=%u",
	pr_debug("msk=%p ssk=%p sending dfrag at seq=%llu len=%u already sent=%u\n",
		 msk, ssk, dfrag->data_seq, dfrag->data_len, info->sent);

	if (WARN_ON_ONCE(info->sent > info->limit ||
@@ -1341,7 +1341,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
	mpext->use_map = 1;
	mpext->dsn64 = 1;

	pr_debug("data_seq=%llu subflow_seq=%u data_len=%u dsn64=%d",
	pr_debug("data_seq=%llu subflow_seq=%u data_len=%u dsn64=%d\n",
		 mpext->data_seq, mpext->subflow_seq, mpext->data_len,
		 mpext->dsn64);

@@ -1892,7 +1892,7 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
			if (!msk->first_pending)
				WRITE_ONCE(msk->first_pending, dfrag);
		}
		pr_debug("msk=%p dfrag at seq=%llu len=%u sent=%u new=%d", msk,
		pr_debug("msk=%p dfrag at seq=%llu len=%u sent=%u new=%d\n", msk,
			 dfrag->data_seq, dfrag->data_len, dfrag->already_sent,
			 !dfrag_collapsed);

@@ -2248,7 +2248,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
			}
		}

		pr_debug("block timeout %ld", timeo);
		pr_debug("block timeout %ld\n", timeo);
		sk_wait_data(sk, &timeo, NULL);
	}

@@ -2264,7 +2264,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
		}
	}

	pr_debug("msk=%p rx queue empty=%d:%d copied=%d",
	pr_debug("msk=%p rx queue empty=%d:%d copied=%d\n",
		 msk, skb_queue_empty_lockless(&sk->sk_receive_queue),
		 skb_queue_empty(&msk->receive_queue), copied);
	if (!(flags & MSG_PEEK))
@@ -2326,7 +2326,7 @@ struct sock *mptcp_subflow_get_retrans(struct mptcp_sock *msk)
			continue;
		}

		if (subflow->backup) {
		if (subflow->backup || subflow->request_bkup) {
			if (!backup)
				backup = ssk;
			continue;
@@ -2533,8 +2533,11 @@ static void __mptcp_close_subflow(struct sock *sk)

	mptcp_for_each_subflow_safe(msk, subflow, tmp) {
		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
		int ssk_state = inet_sk_state_load(ssk);

		if (inet_sk_state_load(ssk) != TCP_CLOSE)
		if (ssk_state != TCP_CLOSE &&
		    (ssk_state != TCP_CLOSE_WAIT ||
		     inet_sk_state_load(sk) != TCP_ESTABLISHED))
			continue;

		/* 'subflow_data_ready' will re-sched once rx queue is empty */
@@ -2714,7 +2717,7 @@ static void mptcp_mp_fail_no_response(struct mptcp_sock *msk)
	if (!ssk)
		return;

	pr_debug("MP_FAIL doesn't respond, reset the subflow");
	pr_debug("MP_FAIL doesn't respond, reset the subflow\n");

	slow = lock_sock_fast(ssk);
	mptcp_subflow_reset(ssk);
@@ -2888,7 +2891,7 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how)
		break;
	default:
		if (__mptcp_check_fallback(mptcp_sk(sk))) {
			pr_debug("Fallback");
			pr_debug("Fallback\n");
			ssk->sk_shutdown |= how;
			tcp_shutdown(ssk, how);

@@ -2898,7 +2901,7 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how)
			WRITE_ONCE(mptcp_sk(sk)->snd_una, mptcp_sk(sk)->snd_nxt);
			mptcp_schedule_work(sk);
		} else {
			pr_debug("Sending DATA_FIN on subflow %p", ssk);
			pr_debug("Sending DATA_FIN on subflow %p\n", ssk);
			tcp_send_ack(ssk);
			if (!mptcp_rtx_timer_pending(sk))
				mptcp_reset_rtx_timer(sk);
@@ -2964,7 +2967,7 @@ static void mptcp_check_send_data_fin(struct sock *sk)
	struct mptcp_subflow_context *subflow;
	struct mptcp_sock *msk = mptcp_sk(sk);

	pr_debug("msk=%p snd_data_fin_enable=%d pending=%d snd_nxt=%llu write_seq=%llu",
	pr_debug("msk=%p snd_data_fin_enable=%d pending=%d snd_nxt=%llu write_seq=%llu\n",
		 msk, msk->snd_data_fin_enable, !!mptcp_send_head(sk),
		 msk->snd_nxt, msk->write_seq);

@@ -2988,7 +2991,7 @@ static void __mptcp_wr_shutdown(struct sock *sk)
{
	struct mptcp_sock *msk = mptcp_sk(sk);

	pr_debug("msk=%p snd_data_fin_enable=%d shutdown=%x state=%d pending=%d",
	pr_debug("msk=%p snd_data_fin_enable=%d shutdown=%x state=%d pending=%d\n",
		 msk, msk->snd_data_fin_enable, sk->sk_shutdown, sk->sk_state,
		 !!mptcp_send_head(sk));

@@ -3003,7 +3006,7 @@ static void __mptcp_destroy_sock(struct sock *sk)
{
	struct mptcp_sock *msk = mptcp_sk(sk);

	pr_debug("msk=%p", msk);
	pr_debug("msk=%p\n", msk);

	might_sleep();

@@ -3111,7 +3114,7 @@ bool __mptcp_close(struct sock *sk, long timeout)
		mptcp_set_state(sk, TCP_CLOSE);

	sock_hold(sk);
	pr_debug("msk=%p state=%d", sk, sk->sk_state);
	pr_debug("msk=%p state=%d\n", sk, sk->sk_state);
	if (msk->token)
		mptcp_event(MPTCP_EVENT_CLOSED, msk, NULL, GFP_KERNEL);

@@ -3543,7 +3546,7 @@ static int mptcp_get_port(struct sock *sk, unsigned short snum)
{
	struct mptcp_sock *msk = mptcp_sk(sk);

	pr_debug("msk=%p, ssk=%p", msk, msk->first);
	pr_debug("msk=%p, ssk=%p\n", msk, msk->first);
	if (WARN_ON_ONCE(!msk->first))
		return -EINVAL;

@@ -3560,7 +3563,7 @@ void mptcp_finish_connect(struct sock *ssk)
	sk = subflow->conn;
	msk = mptcp_sk(sk);

	pr_debug("msk=%p, token=%u", sk, subflow->token);
	pr_debug("msk=%p, token=%u\n", sk, subflow->token);

	subflow->map_seq = subflow->iasn;
	subflow->map_subflow_seq = 1;
@@ -3589,7 +3592,7 @@ bool mptcp_finish_join(struct sock *ssk)
	struct sock *parent = (void *)msk;
	bool ret = true;

	pr_debug("msk=%p, subflow=%p", msk, subflow);
	pr_debug("msk=%p, subflow=%p\n", msk, subflow);

	/* mptcp socket already closing? */
	if (!mptcp_is_fully_established(parent)) {
@@ -3635,7 +3638,7 @@ bool mptcp_finish_join(struct sock *ssk)

static void mptcp_shutdown(struct sock *sk, int how)
{
	pr_debug("sk=%p, how=%d", sk, how);
	pr_debug("sk=%p, how=%d\n", sk, how);

	if ((how & SEND_SHUTDOWN) && mptcp_close_state(sk))
		__mptcp_wr_shutdown(sk);
@@ -3856,7 +3859,7 @@ static int mptcp_listen(struct socket *sock, int backlog)
	struct sock *ssk;
	int err;

	pr_debug("msk=%p", msk);
	pr_debug("msk=%p\n", msk);

	lock_sock(sk);

@@ -3895,7 +3898,7 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
	struct mptcp_sock *msk = mptcp_sk(sock->sk);
	struct sock *ssk, *newsk;

	pr_debug("msk=%p", msk);
	pr_debug("msk=%p\n", msk);

	/* Buggy applications can call accept on socket states other then LISTEN
	 * but no need to allocate the first subflow just to error out.
@@ -3904,12 +3907,12 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
	if (!ssk)
		return -EINVAL;

	pr_debug("ssk=%p, listener=%p", ssk, mptcp_subflow_ctx(ssk));
	pr_debug("ssk=%p, listener=%p\n", ssk, mptcp_subflow_ctx(ssk));
	newsk = inet_csk_accept(ssk, arg);
	if (!newsk)
		return arg->err;

	pr_debug("newsk=%p, subflow is mptcp=%d", newsk, sk_is_mptcp(newsk));
	pr_debug("newsk=%p, subflow is mptcp=%d\n", newsk, sk_is_mptcp(newsk));
	if (sk_is_mptcp(newsk)) {
		struct mptcp_subflow_context *subflow;
		struct sock *new_mptcp_sock;
@@ -4002,7 +4005,7 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
	sock_poll_wait(file, sock, wait);

	state = inet_sk_state_load(sk);
	pr_debug("msk=%p state=%d flags=%lx", msk, state, msk->flags);
	pr_debug("msk=%p state=%d flags=%lx\n", msk, state, msk->flags);
	if (state == TCP_LISTEN) {
		struct sock *ssk = READ_ONCE(msk->first);

Loading