Commit 5cb104ae authored by Geliang Tang's avatar Geliang Tang Committed by David S. Miller
Browse files

mptcp: add the outgoing RM_ADDR support



This patch added a new signal named rm_addr_signal in PM. On outgoing path,
we called mptcp_pm_should_rm_signal to check if rm_addr_signal has been
set. If it has been, we sent out the RM_ADDR option.

Suggested-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Suggested-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarGeliang Tang <geliangtang@gmail.com>
Reviewed-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f643b803
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -614,6 +614,31 @@ static bool mptcp_established_options_add_addr(struct sock *sk,
	return true;
}

static bool mptcp_established_options_rm_addr(struct sock *sk,
					      unsigned int *size,
					      unsigned int remaining,
					      struct mptcp_out_options *opts)
{
	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
	u8 rm_id;

	if (!mptcp_pm_should_rm_signal(msk) ||
	    !(mptcp_pm_rm_addr_signal(msk, remaining, &rm_id)))
		return false;

	if (remaining < TCPOLEN_MPTCP_RM_ADDR_BASE)
		return false;

	*size = TCPOLEN_MPTCP_RM_ADDR_BASE;
	opts->suboptions |= OPTION_MPTCP_RM_ADDR;
	opts->rm_id = rm_id;

	pr_debug("rm_id=%d", opts->rm_id);

	return true;
}

bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
			       unsigned int *size, unsigned int remaining,
			       struct mptcp_out_options *opts)
@@ -644,6 +669,10 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
		*size += opt_size;
		remaining -= opt_size;
		ret = true;
	} else if (mptcp_established_options_rm_addr(sk, &opt_size, remaining, opts)) {
		*size += opt_size;
		remaining -= opt_size;
		ret = true;
	}

	return ret;
+25 −0
Original line number Diff line number Diff line
@@ -174,6 +174,29 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
	return ret;
}

bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
			     u8 *rm_id)
{
	int ret = false;

	spin_lock_bh(&msk->pm.lock);

	/* double check after the lock is acquired */
	if (!mptcp_pm_should_rm_signal(msk))
		goto out_unlock;

	if (remaining < TCPOLEN_MPTCP_RM_ADDR_BASE)
		goto out_unlock;

	*rm_id = msk->pm.rm_id;
	WRITE_ONCE(msk->pm.rm_addr_signal, false);
	ret = true;

out_unlock:
	spin_unlock_bh(&msk->pm.lock);
	return ret;
}

int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
{
	return mptcp_pm_nl_get_local_id(msk, skc);
@@ -185,8 +208,10 @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
	msk->pm.add_addr_accepted = 0;
	msk->pm.local_addr_used = 0;
	msk->pm.subflows = 0;
	msk->pm.rm_id = 0;
	WRITE_ONCE(msk->pm.work_pending, false);
	WRITE_ONCE(msk->pm.add_addr_signal, false);
	WRITE_ONCE(msk->pm.rm_addr_signal, false);
	WRITE_ONCE(msk->pm.accept_addr, false);
	WRITE_ONCE(msk->pm.accept_subflow, false);
	msk->pm.status = 0;
+9 −0
Original line number Diff line number Diff line
@@ -163,6 +163,7 @@ struct mptcp_pm_data {
	spinlock_t	lock;		/*protects the whole PM data */

	bool		add_addr_signal;
	bool		rm_addr_signal;
	bool		server_side;
	bool		work_pending;
	bool		accept_addr;
@@ -176,6 +177,7 @@ struct mptcp_pm_data {
	u8		local_addr_max;
	u8		subflows_max;
	u8		status;
	u8		rm_id;
};

struct mptcp_data_frag {
@@ -443,6 +445,11 @@ static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
	return READ_ONCE(msk->pm.add_addr_signal);
}

static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
{
	return READ_ONCE(msk->pm.rm_addr_signal);
}

static inline unsigned int mptcp_add_addr_len(int family)
{
	if (family == AF_INET)
@@ -452,6 +459,8 @@ static inline unsigned int mptcp_add_addr_len(int family)

bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
			      struct mptcp_addr_info *saddr);
bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
			     u8 *rm_id);
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);

void __init mptcp_pm_nl_init(void);