Commit 06706542 authored by Geliang Tang's avatar Geliang Tang Committed by Jakub Kicinski

mptcp: add the outgoing MP_PRIO support

This patch added the outgoing MP_PRIO logic:

In mptcp_pm_nl_mp_prio_send_ack, find the related subflow and subsocket
according to the input parameter addr. Save the input priority value to
suflow's backup, then set subflow's send_mp_prio flag to true, and save
the input priority value to suflow's request_bkup. Finally, send out a
pure ACK on the related subsocket.

In mptcp_established_options_mp_prio, check whether the subflow's
send_mp_prio is set. If it is, this is the packet for sending MP_PRIO.
So save subflow->request_bkup value to mptcp_out_options's backup, and
change the option type to OPTION_MPTCP_PRIO.

In mptcp_write_options, clear the send_mp_prio flag and send out the
MP_PRIO suboption with mptcp_out_options's backup value.
Signed-off-by: default avatarGeliang Tang <geliangtang@gmail.com>
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent dc8eb10e
...@@ -679,6 +679,28 @@ static bool mptcp_established_options_rm_addr(struct sock *sk, ...@@ -679,6 +679,28 @@ static bool mptcp_established_options_rm_addr(struct sock *sk,
return true; return true;
} }
static bool mptcp_established_options_mp_prio(struct sock *sk,
unsigned int *size,
unsigned int remaining,
struct mptcp_out_options *opts)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
if (!subflow->send_mp_prio)
return false;
if (remaining < TCPOLEN_MPTCP_PRIO)
return false;
*size = TCPOLEN_MPTCP_PRIO;
opts->suboptions |= OPTION_MPTCP_PRIO;
opts->backup = subflow->request_bkup;
pr_debug("prio=%d", opts->backup);
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)
...@@ -721,6 +743,12 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, ...@@ -721,6 +743,12 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
ret = true; ret = true;
} }
if (mptcp_established_options_mp_prio(sk, &opt_size, remaining, opts)) {
*size += opt_size;
remaining -= opt_size;
ret = true;
}
return ret; return ret;
} }
...@@ -1168,6 +1196,18 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, ...@@ -1168,6 +1196,18 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
0, opts->rm_id); 0, opts->rm_id);
} }
if (OPTION_MPTCP_PRIO & opts->suboptions) {
const struct sock *ssk = (const struct sock *)tp;
struct mptcp_subflow_context *subflow;
subflow = mptcp_subflow_ctx(ssk);
subflow->send_mp_prio = 0;
*ptr++ = mptcp_option(MPTCPOPT_MP_PRIO,
TCPOLEN_MPTCP_PRIO,
opts->backup, TCPOPT_NOP);
}
if (OPTION_MPTCP_MPJ_SYN & opts->suboptions) { if (OPTION_MPTCP_MPJ_SYN & opts->suboptions) {
*ptr++ = mptcp_option(MPTCPOPT_MP_JOIN, *ptr++ = mptcp_option(MPTCPOPT_MP_JOIN,
TCPOLEN_MPTCP_MPJ_SYN, TCPOLEN_MPTCP_MPJ_SYN,
......
...@@ -442,6 +442,39 @@ void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk) ...@@ -442,6 +442,39 @@ void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk)
} }
} }
int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
struct mptcp_addr_info *addr,
u8 bkup)
{
struct mptcp_subflow_context *subflow;
pr_debug("bkup=%d", bkup);
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
struct mptcp_addr_info local;
local_address((struct sock_common *)ssk, &local);
if (!addresses_equal(&local, addr, addr->port))
continue;
subflow->backup = bkup;
subflow->send_mp_prio = 1;
subflow->request_bkup = bkup;
spin_unlock_bh(&msk->pm.lock);
pr_debug("send ack for mp_prio");
lock_sock(ssk);
tcp_send_ack(ssk);
release_sock(ssk);
spin_lock_bh(&msk->pm.lock);
return 0;
}
return -EINVAL;
}
void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk) void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
{ {
struct mptcp_subflow_context *subflow, *tmp; struct mptcp_subflow_context *subflow, *tmp;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define OPTION_MPTCP_ADD_ADDR6 BIT(7) #define OPTION_MPTCP_ADD_ADDR6 BIT(7)
#define OPTION_MPTCP_RM_ADDR BIT(8) #define OPTION_MPTCP_RM_ADDR BIT(8)
#define OPTION_MPTCP_FASTCLOSE BIT(9) #define OPTION_MPTCP_FASTCLOSE BIT(9)
#define OPTION_MPTCP_PRIO BIT(10)
/* MPTCP option subtypes */ /* MPTCP option subtypes */
#define MPTCPOPT_MP_CAPABLE 0 #define MPTCPOPT_MP_CAPABLE 0
...@@ -59,6 +60,7 @@ ...@@ -59,6 +60,7 @@
#define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT 24 #define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT 24
#define TCPOLEN_MPTCP_PORT_LEN 4 #define TCPOLEN_MPTCP_PORT_LEN 4
#define TCPOLEN_MPTCP_RM_ADDR_BASE 4 #define TCPOLEN_MPTCP_RM_ADDR_BASE 4
#define TCPOLEN_MPTCP_PRIO 4
#define TCPOLEN_MPTCP_FASTCLOSE 12 #define TCPOLEN_MPTCP_FASTCLOSE 12
/* MPTCP MP_JOIN flags */ /* MPTCP MP_JOIN flags */
...@@ -396,6 +398,7 @@ struct mptcp_subflow_context { ...@@ -396,6 +398,7 @@ struct mptcp_subflow_context {
map_valid : 1, map_valid : 1,
mpc_map : 1, mpc_map : 1,
backup : 1, backup : 1,
send_mp_prio : 1,
rx_eof : 1, rx_eof : 1,
can_ack : 1, /* only after processing the remote a key */ can_ack : 1, /* only after processing the remote a key */
disposable : 1; /* ctx can be free at ulp release time */ disposable : 1; /* ctx can be free at ulp release time */
...@@ -550,6 +553,9 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk, ...@@ -550,6 +553,9 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
const struct mptcp_addr_info *addr); const struct mptcp_addr_info *addr);
void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk); void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk);
void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id); void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id);
int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
struct mptcp_addr_info *addr,
u8 bkup);
void mptcp_pm_free_anno_list(struct mptcp_sock *msk); void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
struct mptcp_pm_add_entry * struct mptcp_pm_add_entry *
mptcp_pm_del_add_timer(struct mptcp_sock *msk, mptcp_pm_del_add_timer(struct mptcp_sock *msk,
......
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