@@ -592,6 +592,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
592
592
dss_size = map_size ;
593
593
if (skb && snd_data_fin_enable )
594
594
mptcp_write_data_fin (subflow , skb , & opts -> ext_copy );
595
+ opts -> suboptions = OPTION_MPTCP_DSS ;
595
596
ret = true;
596
597
}
597
598
@@ -615,6 +616,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
615
616
opts -> ext_copy .ack64 = 0 ;
616
617
}
617
618
opts -> ext_copy .use_ack = 1 ;
619
+ opts -> suboptions = OPTION_MPTCP_DSS ;
618
620
WRITE_ONCE (msk -> old_wspace , __mptcp_space ((struct sock * )msk ));
619
621
620
622
/* Add kind/length/subtype/flag overhead if mapping is not populated */
@@ -686,8 +688,13 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
686
688
if (drop_other_suboptions ) {
687
689
pr_debug ("drop other suboptions" );
688
690
opts -> suboptions = 0 ;
689
- opts -> ext_copy .use_ack = 0 ;
690
- opts -> ext_copy .use_map = 0 ;
691
+
692
+ /* note that e.g. DSS could have written into the memory
693
+ * aliased by ahmac, we must reset the field here
694
+ * to avoid appending the hmac even for ADD_ADDR echo
695
+ * options
696
+ */
697
+ opts -> ahmac = 0 ;
691
698
* size -= opt_size ;
692
699
}
693
700
opts -> suboptions |= OPTION_MPTCP_ADD_ADDR ;
@@ -739,7 +746,12 @@ static bool mptcp_established_options_mp_prio(struct sock *sk,
739
746
{
740
747
struct mptcp_subflow_context * subflow = mptcp_subflow_ctx (sk );
741
748
742
- if (!subflow -> send_mp_prio )
749
+ /* can't send MP_PRIO with MPC, as they share the same option space:
750
+ * 'backup'. Also it makes no sense at all
751
+ */
752
+ if (!subflow -> send_mp_prio ||
753
+ ((OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_SYNACK |
754
+ OPTION_MPTCP_MPC_ACK ) & opts -> suboptions ))
743
755
return false;
744
756
745
757
/* account for the trailing 'nop' option */
@@ -1198,8 +1210,74 @@ static u16 mptcp_make_csum(const struct mptcp_ext *mpext)
1198
1210
void mptcp_write_options (__be32 * ptr , const struct tcp_sock * tp ,
1199
1211
struct mptcp_out_options * opts )
1200
1212
{
1201
- if ((OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_SYNACK |
1202
- OPTION_MPTCP_MPC_ACK ) & opts -> suboptions ) {
1213
+ /* RST is mutually exclusive with everything else */
1214
+ if (unlikely (OPTION_MPTCP_RST & opts -> suboptions )) {
1215
+ * ptr ++ = mptcp_option (MPTCPOPT_RST ,
1216
+ TCPOLEN_MPTCP_RST ,
1217
+ opts -> reset_transient ,
1218
+ opts -> reset_reason );
1219
+ return ;
1220
+ }
1221
+
1222
+ /* DSS, MPC, MPJ and ADD_ADDR are mutually exclusive, see
1223
+ * mptcp_established_options*()
1224
+ */
1225
+ if (likely (OPTION_MPTCP_DSS & opts -> suboptions )) {
1226
+ struct mptcp_ext * mpext = & opts -> ext_copy ;
1227
+ u8 len = TCPOLEN_MPTCP_DSS_BASE ;
1228
+ u8 flags = 0 ;
1229
+
1230
+ if (mpext -> use_ack ) {
1231
+ flags = MPTCP_DSS_HAS_ACK ;
1232
+ if (mpext -> ack64 ) {
1233
+ len += TCPOLEN_MPTCP_DSS_ACK64 ;
1234
+ flags |= MPTCP_DSS_ACK64 ;
1235
+ } else {
1236
+ len += TCPOLEN_MPTCP_DSS_ACK32 ;
1237
+ }
1238
+ }
1239
+
1240
+ if (mpext -> use_map ) {
1241
+ len += TCPOLEN_MPTCP_DSS_MAP64 ;
1242
+
1243
+ /* Use only 64-bit mapping flags for now, add
1244
+ * support for optional 32-bit mappings later.
1245
+ */
1246
+ flags |= MPTCP_DSS_HAS_MAP | MPTCP_DSS_DSN64 ;
1247
+ if (mpext -> data_fin )
1248
+ flags |= MPTCP_DSS_DATA_FIN ;
1249
+
1250
+ if (opts -> csum_reqd )
1251
+ len += TCPOLEN_MPTCP_DSS_CHECKSUM ;
1252
+ }
1253
+
1254
+ * ptr ++ = mptcp_option (MPTCPOPT_DSS , len , 0 , flags );
1255
+
1256
+ if (mpext -> use_ack ) {
1257
+ if (mpext -> ack64 ) {
1258
+ put_unaligned_be64 (mpext -> data_ack , ptr );
1259
+ ptr += 2 ;
1260
+ } else {
1261
+ put_unaligned_be32 (mpext -> data_ack32 , ptr );
1262
+ ptr += 1 ;
1263
+ }
1264
+ }
1265
+
1266
+ if (mpext -> use_map ) {
1267
+ put_unaligned_be64 (mpext -> data_seq , ptr );
1268
+ ptr += 2 ;
1269
+ put_unaligned_be32 (mpext -> subflow_seq , ptr );
1270
+ ptr += 1 ;
1271
+ if (opts -> csum_reqd ) {
1272
+ put_unaligned_be32 (mpext -> data_len << 16 |
1273
+ mptcp_make_csum (mpext ), ptr );
1274
+ } else {
1275
+ put_unaligned_be32 (mpext -> data_len << 16 |
1276
+ TCPOPT_NOP << 8 | TCPOPT_NOP , ptr );
1277
+ }
1278
+ }
1279
+ } else if ((OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_SYNACK |
1280
+ OPTION_MPTCP_MPC_ACK ) & opts -> suboptions ) {
1203
1281
u8 len , flag = MPTCP_CAP_HMAC_SHA256 ;
1204
1282
1205
1283
if (OPTION_MPTCP_MPC_SYN & opts -> suboptions ) {
@@ -1246,10 +1324,31 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
1246
1324
TCPOPT_NOP << 8 | TCPOPT_NOP , ptr );
1247
1325
}
1248
1326
ptr += 1 ;
1249
- }
1250
1327
1251
- mp_capable_done :
1252
- if (OPTION_MPTCP_ADD_ADDR & opts -> suboptions ) {
1328
+ /* MPC is additionally mutually exclusive with MP_PRIO */
1329
+ goto mp_capable_done ;
1330
+ } else if (OPTION_MPTCP_MPJ_SYN & opts -> suboptions ) {
1331
+ * ptr ++ = mptcp_option (MPTCPOPT_MP_JOIN ,
1332
+ TCPOLEN_MPTCP_MPJ_SYN ,
1333
+ opts -> backup , opts -> join_id );
1334
+ put_unaligned_be32 (opts -> token , ptr );
1335
+ ptr += 1 ;
1336
+ put_unaligned_be32 (opts -> nonce , ptr );
1337
+ ptr += 1 ;
1338
+ } else if (OPTION_MPTCP_MPJ_SYNACK & opts -> suboptions ) {
1339
+ * ptr ++ = mptcp_option (MPTCPOPT_MP_JOIN ,
1340
+ TCPOLEN_MPTCP_MPJ_SYNACK ,
1341
+ opts -> backup , opts -> join_id );
1342
+ put_unaligned_be64 (opts -> thmac , ptr );
1343
+ ptr += 2 ;
1344
+ put_unaligned_be32 (opts -> nonce , ptr );
1345
+ ptr += 1 ;
1346
+ } else if (OPTION_MPTCP_MPJ_ACK & opts -> suboptions ) {
1347
+ * ptr ++ = mptcp_option (MPTCPOPT_MP_JOIN ,
1348
+ TCPOLEN_MPTCP_MPJ_ACK , 0 , 0 );
1349
+ memcpy (ptr , opts -> hmac , MPTCPOPT_HMAC_LEN );
1350
+ ptr += 5 ;
1351
+ } else if (OPTION_MPTCP_ADD_ADDR & opts -> suboptions ) {
1253
1352
u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE ;
1254
1353
u8 echo = MPTCP_ADDR_ECHO ;
1255
1354
@@ -1307,6 +1406,19 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
1307
1406
}
1308
1407
}
1309
1408
1409
+ if (OPTION_MPTCP_PRIO & opts -> suboptions ) {
1410
+ const struct sock * ssk = (const struct sock * )tp ;
1411
+ struct mptcp_subflow_context * subflow ;
1412
+
1413
+ subflow = mptcp_subflow_ctx (ssk );
1414
+ subflow -> send_mp_prio = 0 ;
1415
+
1416
+ * ptr ++ = mptcp_option (MPTCPOPT_MP_PRIO ,
1417
+ TCPOLEN_MPTCP_PRIO ,
1418
+ opts -> backup , TCPOPT_NOP );
1419
+ }
1420
+
1421
+ mp_capable_done :
1310
1422
if (OPTION_MPTCP_RM_ADDR & opts -> suboptions ) {
1311
1423
u8 i = 1 ;
1312
1424
@@ -1327,107 +1439,6 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
1327
1439
}
1328
1440
}
1329
1441
1330
- if (OPTION_MPTCP_PRIO & opts -> suboptions ) {
1331
- const struct sock * ssk = (const struct sock * )tp ;
1332
- struct mptcp_subflow_context * subflow ;
1333
-
1334
- subflow = mptcp_subflow_ctx (ssk );
1335
- subflow -> send_mp_prio = 0 ;
1336
-
1337
- * ptr ++ = mptcp_option (MPTCPOPT_MP_PRIO ,
1338
- TCPOLEN_MPTCP_PRIO ,
1339
- opts -> backup , TCPOPT_NOP );
1340
- }
1341
-
1342
- if (OPTION_MPTCP_MPJ_SYN & opts -> suboptions ) {
1343
- * ptr ++ = mptcp_option (MPTCPOPT_MP_JOIN ,
1344
- TCPOLEN_MPTCP_MPJ_SYN ,
1345
- opts -> backup , opts -> join_id );
1346
- put_unaligned_be32 (opts -> token , ptr );
1347
- ptr += 1 ;
1348
- put_unaligned_be32 (opts -> nonce , ptr );
1349
- ptr += 1 ;
1350
- }
1351
-
1352
- if (OPTION_MPTCP_MPJ_SYNACK & opts -> suboptions ) {
1353
- * ptr ++ = mptcp_option (MPTCPOPT_MP_JOIN ,
1354
- TCPOLEN_MPTCP_MPJ_SYNACK ,
1355
- opts -> backup , opts -> join_id );
1356
- put_unaligned_be64 (opts -> thmac , ptr );
1357
- ptr += 2 ;
1358
- put_unaligned_be32 (opts -> nonce , ptr );
1359
- ptr += 1 ;
1360
- }
1361
-
1362
- if (OPTION_MPTCP_MPJ_ACK & opts -> suboptions ) {
1363
- * ptr ++ = mptcp_option (MPTCPOPT_MP_JOIN ,
1364
- TCPOLEN_MPTCP_MPJ_ACK , 0 , 0 );
1365
- memcpy (ptr , opts -> hmac , MPTCPOPT_HMAC_LEN );
1366
- ptr += 5 ;
1367
- }
1368
-
1369
- if (OPTION_MPTCP_RST & opts -> suboptions )
1370
- * ptr ++ = mptcp_option (MPTCPOPT_RST ,
1371
- TCPOLEN_MPTCP_RST ,
1372
- opts -> reset_transient ,
1373
- opts -> reset_reason );
1374
-
1375
- if (opts -> ext_copy .use_ack || opts -> ext_copy .use_map ) {
1376
- struct mptcp_ext * mpext = & opts -> ext_copy ;
1377
- u8 len = TCPOLEN_MPTCP_DSS_BASE ;
1378
- u8 flags = 0 ;
1379
-
1380
- if (mpext -> use_ack ) {
1381
- flags = MPTCP_DSS_HAS_ACK ;
1382
- if (mpext -> ack64 ) {
1383
- len += TCPOLEN_MPTCP_DSS_ACK64 ;
1384
- flags |= MPTCP_DSS_ACK64 ;
1385
- } else {
1386
- len += TCPOLEN_MPTCP_DSS_ACK32 ;
1387
- }
1388
- }
1389
-
1390
- if (mpext -> use_map ) {
1391
- len += TCPOLEN_MPTCP_DSS_MAP64 ;
1392
-
1393
- /* Use only 64-bit mapping flags for now, add
1394
- * support for optional 32-bit mappings later.
1395
- */
1396
- flags |= MPTCP_DSS_HAS_MAP | MPTCP_DSS_DSN64 ;
1397
- if (mpext -> data_fin )
1398
- flags |= MPTCP_DSS_DATA_FIN ;
1399
-
1400
- if (opts -> csum_reqd )
1401
- len += TCPOLEN_MPTCP_DSS_CHECKSUM ;
1402
- }
1403
-
1404
- * ptr ++ = mptcp_option (MPTCPOPT_DSS , len , 0 , flags );
1405
-
1406
- if (mpext -> use_ack ) {
1407
- if (mpext -> ack64 ) {
1408
- put_unaligned_be64 (mpext -> data_ack , ptr );
1409
- ptr += 2 ;
1410
- } else {
1411
- put_unaligned_be32 (mpext -> data_ack32 , ptr );
1412
- ptr += 1 ;
1413
- }
1414
- }
1415
-
1416
- if (mpext -> use_map ) {
1417
- put_unaligned_be64 (mpext -> data_seq , ptr );
1418
- ptr += 2 ;
1419
- put_unaligned_be32 (mpext -> subflow_seq , ptr );
1420
- ptr += 1 ;
1421
- if (opts -> csum_reqd ) {
1422
- put_unaligned_be32 (mpext -> data_len << 16 |
1423
- mptcp_make_csum (mpext ), ptr );
1424
- } else {
1425
- put_unaligned_be32 (mpext -> data_len << 16 |
1426
- TCPOPT_NOP << 8 | TCPOPT_NOP , ptr );
1427
- }
1428
- }
1429
- }
1430
-
1431
1442
if (tp )
1432
1443
mptcp_set_rwin (tp );
1433
1444
}
0 commit comments