Skip to content

Commit ca1a670

Browse files
committed
Merge branch 'mptcp-next'
Mat Martineau says: ==================== mptcp: New features and cleanup These patches have been tested in the MPTCP tree for a longer than usual time (thanks to holiday schedules), and are ready for the net-next branch. Changes include feature updates, small fixes, refactoring, and some selftest changes. Patch 1 fixes an OUTQ ioctl issue with TCP fallback sockets. Patches 2, 3, and 6 add support of the MPTCP fastclose option (quick shutdown of the full MPTCP connection, similar to TCP RST in regular TCP), and a related self test. Patch 4 cleans up some accept and poll code that is no longer needed after the fastclose changes. Patch 5 add userspace disconnect using AF_UNSPEC, which is used when testing fastclose and makes the MPTCP socket's handling of AF_UNSPEC in connect() more TCP-like. Patches 7-11 refactor subflow creation to make better use of multiple local endpoints and to better handle individual connection failures when creating multiple subflows. Includes self test updates. Patch 12 cleans up the way subflows are added to the MPTCP connection list, eliminating the need for calls throughout the MPTCP code that had to check the intermediate "join list" for entries to shift over to the main "connection list". Patch 13 refactors the MPTCP release_cb flags to use separate storage for values only accessed with the socket lock held (no atomic ops needed), and for values that need atomic operations. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 26abf15 + e9d09ba commit ca1a670

File tree

12 files changed

+683
-325
lines changed

12 files changed

+683
-325
lines changed

net/mptcp/options.c

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,28 @@ static noinline bool mptcp_established_options_rst(struct sock *sk, struct sk_bu
768768
return true;
769769
}
770770

771+
static bool mptcp_established_options_fastclose(struct sock *sk,
772+
unsigned int *size,
773+
unsigned int remaining,
774+
struct mptcp_out_options *opts)
775+
{
776+
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
777+
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
778+
779+
if (likely(!subflow->send_fastclose))
780+
return false;
781+
782+
if (remaining < TCPOLEN_MPTCP_FASTCLOSE)
783+
return false;
784+
785+
*size = TCPOLEN_MPTCP_FASTCLOSE;
786+
opts->suboptions |= OPTION_MPTCP_FASTCLOSE;
787+
opts->rcvr_key = msk->remote_key;
788+
789+
pr_debug("FASTCLOSE key=%llu", opts->rcvr_key);
790+
return true;
791+
}
792+
771793
static bool mptcp_established_options_mp_fail(struct sock *sk,
772794
unsigned int *size,
773795
unsigned int remaining,
@@ -806,10 +828,12 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
806828
return false;
807829

808830
if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) {
809-
if (mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts)) {
831+
if (mptcp_established_options_fastclose(sk, &opt_size, remaining, opts) ||
832+
mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts)) {
810833
*size += opt_size;
811834
remaining -= opt_size;
812835
}
836+
/* MP_RST can be used with MP_FASTCLOSE and MP_FAIL if there is room */
813837
if (mptcp_established_options_rst(sk, skb, &opt_size, remaining, opts)) {
814838
*size += opt_size;
815839
remaining -= opt_size;
@@ -1251,17 +1275,8 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
12511275
ptr += 2;
12521276
}
12531277

1254-
/* RST is mutually exclusive with everything else */
1255-
if (unlikely(OPTION_MPTCP_RST & opts->suboptions)) {
1256-
*ptr++ = mptcp_option(MPTCPOPT_RST,
1257-
TCPOLEN_MPTCP_RST,
1258-
opts->reset_transient,
1259-
opts->reset_reason);
1260-
return;
1261-
}
1262-
1263-
/* DSS, MPC, MPJ and ADD_ADDR are mutually exclusive, see
1264-
* mptcp_established_options*()
1278+
/* DSS, MPC, MPJ, ADD_ADDR, FASTCLOSE and RST are mutually exclusive,
1279+
* see mptcp_established_options*()
12651280
*/
12661281
if (likely(OPTION_MPTCP_DSS & opts->suboptions)) {
12671282
struct mptcp_ext *mpext = &opts->ext_copy;
@@ -1370,27 +1385,29 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
13701385

13711386
/* MPC is additionally mutually exclusive with MP_PRIO */
13721387
goto mp_capable_done;
1373-
} else if (OPTION_MPTCP_MPJ_SYN & opts->suboptions) {
1374-
*ptr++ = mptcp_option(MPTCPOPT_MP_JOIN,
1375-
TCPOLEN_MPTCP_MPJ_SYN,
1376-
opts->backup, opts->join_id);
1377-
put_unaligned_be32(opts->token, ptr);
1378-
ptr += 1;
1379-
put_unaligned_be32(opts->nonce, ptr);
1380-
ptr += 1;
1381-
} else if (OPTION_MPTCP_MPJ_SYNACK & opts->suboptions) {
1382-
*ptr++ = mptcp_option(MPTCPOPT_MP_JOIN,
1383-
TCPOLEN_MPTCP_MPJ_SYNACK,
1384-
opts->backup, opts->join_id);
1385-
put_unaligned_be64(opts->thmac, ptr);
1386-
ptr += 2;
1387-
put_unaligned_be32(opts->nonce, ptr);
1388-
ptr += 1;
1389-
} else if (OPTION_MPTCP_MPJ_ACK & opts->suboptions) {
1390-
*ptr++ = mptcp_option(MPTCPOPT_MP_JOIN,
1391-
TCPOLEN_MPTCP_MPJ_ACK, 0, 0);
1392-
memcpy(ptr, opts->hmac, MPTCPOPT_HMAC_LEN);
1393-
ptr += 5;
1388+
} else if (OPTIONS_MPTCP_MPJ & opts->suboptions) {
1389+
if (OPTION_MPTCP_MPJ_SYN & opts->suboptions) {
1390+
*ptr++ = mptcp_option(MPTCPOPT_MP_JOIN,
1391+
TCPOLEN_MPTCP_MPJ_SYN,
1392+
opts->backup, opts->join_id);
1393+
put_unaligned_be32(opts->token, ptr);
1394+
ptr += 1;
1395+
put_unaligned_be32(opts->nonce, ptr);
1396+
ptr += 1;
1397+
} else if (OPTION_MPTCP_MPJ_SYNACK & opts->suboptions) {
1398+
*ptr++ = mptcp_option(MPTCPOPT_MP_JOIN,
1399+
TCPOLEN_MPTCP_MPJ_SYNACK,
1400+
opts->backup, opts->join_id);
1401+
put_unaligned_be64(opts->thmac, ptr);
1402+
ptr += 2;
1403+
put_unaligned_be32(opts->nonce, ptr);
1404+
ptr += 1;
1405+
} else {
1406+
*ptr++ = mptcp_option(MPTCPOPT_MP_JOIN,
1407+
TCPOLEN_MPTCP_MPJ_ACK, 0, 0);
1408+
memcpy(ptr, opts->hmac, MPTCPOPT_HMAC_LEN);
1409+
ptr += 5;
1410+
}
13941411
} else if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
13951412
u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
13961413
u8 echo = MPTCP_ADDR_ECHO;
@@ -1447,6 +1464,24 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
14471464
ptr += 1;
14481465
}
14491466
}
1467+
} else if (unlikely(OPTION_MPTCP_FASTCLOSE & opts->suboptions)) {
1468+
/* FASTCLOSE is mutually exclusive with others except RST */
1469+
*ptr++ = mptcp_option(MPTCPOPT_MP_FASTCLOSE,
1470+
TCPOLEN_MPTCP_FASTCLOSE,
1471+
0, 0);
1472+
put_unaligned_be64(opts->rcvr_key, ptr);
1473+
ptr += 2;
1474+
1475+
if (OPTION_MPTCP_RST & opts->suboptions)
1476+
goto mp_rst;
1477+
return;
1478+
} else if (unlikely(OPTION_MPTCP_RST & opts->suboptions)) {
1479+
mp_rst:
1480+
*ptr++ = mptcp_option(MPTCPOPT_RST,
1481+
TCPOLEN_MPTCP_RST,
1482+
opts->reset_transient,
1483+
opts->reset_reason);
1484+
return;
14501485
}
14511486

14521487
if (OPTION_MPTCP_PRIO & opts->suboptions) {

net/mptcp/pm.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,28 @@ void mptcp_pm_subflow_established(struct mptcp_sock *msk)
172172
spin_unlock_bh(&pm->lock);
173173
}
174174

175-
void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id)
175+
void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, const struct sock *ssk,
176+
const struct mptcp_subflow_context *subflow)
176177
{
177-
pr_debug("msk=%p", msk);
178+
struct mptcp_pm_data *pm = &msk->pm;
179+
bool update_subflows;
180+
181+
update_subflows = (ssk->sk_state == TCP_CLOSE) &&
182+
(subflow->request_join || subflow->mp_join);
183+
if (!READ_ONCE(pm->work_pending) && !update_subflows)
184+
return;
185+
186+
spin_lock_bh(&pm->lock);
187+
if (update_subflows)
188+
pm->subflows--;
189+
190+
/* Even if this subflow is not really established, tell the PM to try
191+
* to pick the next ones, if possible.
192+
*/
193+
if (mptcp_pm_nl_check_work_pending(msk))
194+
mptcp_pm_schedule_work(msk, MPTCP_PM_SUBFLOW_ESTABLISHED);
195+
196+
spin_unlock_bh(&pm->lock);
178197
}
179198

180199
void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
@@ -356,7 +375,7 @@ void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk)
356375
}
357376
}
358377

359-
void mptcp_pm_data_init(struct mptcp_sock *msk)
378+
void mptcp_pm_data_reset(struct mptcp_sock *msk)
360379
{
361380
msk->pm.add_addr_signaled = 0;
362381
msk->pm.add_addr_accepted = 0;
@@ -370,11 +389,16 @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
370389
WRITE_ONCE(msk->pm.accept_subflow, false);
371390
WRITE_ONCE(msk->pm.remote_deny_join_id0, false);
372391
msk->pm.status = 0;
392+
bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
393+
394+
mptcp_pm_nl_data_init(msk);
395+
}
373396

397+
void mptcp_pm_data_init(struct mptcp_sock *msk)
398+
{
374399
spin_lock_init(&msk->pm.lock);
375400
INIT_LIST_HEAD(&msk->pm.anno_list);
376-
377-
mptcp_pm_nl_data_init(msk);
401+
mptcp_pm_data_reset(msk);
378402
}
379403

380404
void __init mptcp_pm_init(void)

0 commit comments

Comments
 (0)