Skip to content

Commit

Permalink
Merge branch 'mptcp-add-mp_prio-support-and-rework-local-address-ids'
Browse files Browse the repository at this point in the history
Mat Martineau says:

====================
MPTCP: Add MP_PRIO support and rework local address IDs

Patches 1 and 2 rework the assignment of local address IDs to allow them
to be assigned by a userspace path manager, and add corresponding self
tests.

Patches 2-8 add the ability to change subflow priority after a subflow
has been established. Each subflow in a MPTCP connection has a priority
level: "regular" or "backup". Data should only be sent on backup
subflows if no regular subflows are available. The priority level can be
set when the subflow connection is established (as was already
implemented), or during the life of the connection by sending MP_PRIO in
the TCP options (as added here). Self tests are included.
====================

Link: https://lore.kernel.org/r/20210109004802.341602-1-mathew.j.martineau@linux.intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Jan 10, 2021
2 parents 43b3983 + 718eb44 commit 4988896
Showing 10 changed files with 430 additions and 22 deletions.
1 change: 1 addition & 0 deletions include/uapi/linux/mptcp.h
Original file line number Diff line number Diff line change
@@ -82,6 +82,7 @@ enum {
MPTCP_PM_CMD_FLUSH_ADDRS,
MPTCP_PM_CMD_SET_LIMITS,
MPTCP_PM_CMD_GET_LIMITS,
MPTCP_PM_CMD_SET_FLAGS,

__MPTCP_PM_CMD_AFTER_LAST
};
2 changes: 2 additions & 0 deletions net/mptcp/mib.c
Original file line number Diff line number Diff line change
@@ -31,6 +31,8 @@ static const struct snmp_mib mptcp_snmp_list[] = {
SNMP_MIB_ITEM("EchoAdd", MPTCP_MIB_ECHOADD),
SNMP_MIB_ITEM("RmAddr", MPTCP_MIB_RMADDR),
SNMP_MIB_ITEM("RmSubflow", MPTCP_MIB_RMSUBFLOW),
SNMP_MIB_ITEM("MPPrioTx", MPTCP_MIB_MPPRIOTX),
SNMP_MIB_ITEM("MPPrioRx", MPTCP_MIB_MPPRIORX),
SNMP_MIB_SENTINEL
};

2 changes: 2 additions & 0 deletions net/mptcp/mib.h
Original file line number Diff line number Diff line change
@@ -24,6 +24,8 @@ enum linux_mptcp_mib_field {
MPTCP_MIB_ECHOADD, /* Received ADD_ADDR with echo-flag=1 */
MPTCP_MIB_RMADDR, /* Received RM_ADDR */
MPTCP_MIB_RMSUBFLOW, /* Remove a subflow */
MPTCP_MIB_MPPRIOTX, /* Transmit a MP_PRIO */
MPTCP_MIB_MPPRIORX, /* Received a MP_PRIO */
__MPTCP_MIB_MAX
};

56 changes: 56 additions & 0 deletions net/mptcp/options.c
Original file line number Diff line number Diff line change
@@ -282,6 +282,15 @@ static void mptcp_parse_option(const struct sk_buff *skb,
pr_debug("RM_ADDR: id=%d", mp_opt->rm_id);
break;

case MPTCPOPT_MP_PRIO:
if (opsize != TCPOLEN_MPTCP_PRIO)
break;

mp_opt->mp_prio = 1;
mp_opt->backup = *ptr++ & MPTCP_PRIO_BKUP;
pr_debug("MP_PRIO: prio=%d", mp_opt->backup);
break;

case MPTCPOPT_MP_FASTCLOSE:
if (opsize != TCPOLEN_MPTCP_FASTCLOSE)
break;
@@ -313,6 +322,7 @@ void mptcp_get_options(const struct sk_buff *skb,
mp_opt->port = 0;
mp_opt->rm_addr = 0;
mp_opt->dss = 0;
mp_opt->mp_prio = 0;

length = (th->doff * 4) - sizeof(struct tcphdr);
ptr = (const unsigned char *)(th + 1);
@@ -679,6 +689,28 @@ static bool mptcp_established_options_rm_addr(struct sock *sk,
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,
unsigned int *size, unsigned int remaining,
struct mptcp_out_options *opts)
@@ -721,6 +753,12 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
ret = true;
}

if (mptcp_established_options_mp_prio(sk, &opt_size, remaining, opts)) {
*size += opt_size;
remaining -= opt_size;
ret = true;
}

return ret;
}

@@ -994,6 +1032,12 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
mp_opt.rm_addr = 0;
}

if (mp_opt.mp_prio) {
mptcp_pm_mp_prio_received(sk, mp_opt.backup);
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPPRIORX);
mp_opt.mp_prio = 0;
}

if (!mp_opt.dss)
return;

@@ -1168,6 +1212,18 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
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) {
*ptr++ = mptcp_option(MPTCPOPT_MP_JOIN,
TCPOLEN_MPTCP_MPJ_SYN,
8 changes: 8 additions & 0 deletions net/mptcp/pm.c
Original file line number Diff line number Diff line change
@@ -207,6 +207,14 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id)
spin_unlock_bh(&pm->lock);
}

void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);

pr_debug("subflow->backup=%d, bkup=%d\n", subflow->backup, bkup);
subflow->backup = bkup;
}

/* path manager helpers */

bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
Loading

0 comments on commit 4988896

Please sign in to comment.