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

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
...@@ -614,6 +614,31 @@ static bool mptcp_established_options_add_addr(struct sock *sk, ...@@ -614,6 +614,31 @@ static bool mptcp_established_options_add_addr(struct sock *sk,
return true; 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, bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
unsigned int *size, unsigned int remaining, unsigned int *size, unsigned int remaining,
struct mptcp_out_options *opts) struct mptcp_out_options *opts)
...@@ -644,6 +669,10 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, ...@@ -644,6 +669,10 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
*size += opt_size; *size += opt_size;
remaining -= opt_size; remaining -= opt_size;
ret = true; ret = true;
} else if (mptcp_established_options_rm_addr(sk, &opt_size, remaining, opts)) {
*size += opt_size;
remaining -= opt_size;
ret = true;
} }
return ret; return ret;
......
...@@ -174,6 +174,29 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining, ...@@ -174,6 +174,29 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
return ret; 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) int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
{ {
return mptcp_pm_nl_get_local_id(msk, skc); return mptcp_pm_nl_get_local_id(msk, skc);
...@@ -185,8 +208,10 @@ void mptcp_pm_data_init(struct mptcp_sock *msk) ...@@ -185,8 +208,10 @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
msk->pm.add_addr_accepted = 0; msk->pm.add_addr_accepted = 0;
msk->pm.local_addr_used = 0; msk->pm.local_addr_used = 0;
msk->pm.subflows = 0; msk->pm.subflows = 0;
msk->pm.rm_id = 0;
WRITE_ONCE(msk->pm.work_pending, false); WRITE_ONCE(msk->pm.work_pending, false);
WRITE_ONCE(msk->pm.add_addr_signal, 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_addr, false);
WRITE_ONCE(msk->pm.accept_subflow, false); WRITE_ONCE(msk->pm.accept_subflow, false);
msk->pm.status = 0; msk->pm.status = 0;
......
...@@ -163,6 +163,7 @@ struct mptcp_pm_data { ...@@ -163,6 +163,7 @@ struct mptcp_pm_data {
spinlock_t lock; /*protects the whole PM data */ spinlock_t lock; /*protects the whole PM data */
bool add_addr_signal; bool add_addr_signal;
bool rm_addr_signal;
bool server_side; bool server_side;
bool work_pending; bool work_pending;
bool accept_addr; bool accept_addr;
...@@ -176,6 +177,7 @@ struct mptcp_pm_data { ...@@ -176,6 +177,7 @@ struct mptcp_pm_data {
u8 local_addr_max; u8 local_addr_max;
u8 subflows_max; u8 subflows_max;
u8 status; u8 status;
u8 rm_id;
}; };
struct mptcp_data_frag { struct mptcp_data_frag {
...@@ -443,6 +445,11 @@ static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk) ...@@ -443,6 +445,11 @@ static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
return READ_ONCE(msk->pm.add_addr_signal); 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) static inline unsigned int mptcp_add_addr_len(int family)
{ {
if (family == AF_INET) if (family == AF_INET)
...@@ -452,6 +459,8 @@ static inline unsigned int mptcp_add_addr_len(int family) ...@@ -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, bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
struct mptcp_addr_info *saddr); 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); int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
void __init mptcp_pm_nl_init(void); void __init mptcp_pm_nl_init(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment