@@ -592,6 +592,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
592592 dss_size = map_size ;
593593 if (skb && snd_data_fin_enable )
594594 mptcp_write_data_fin (subflow , skb , & opts -> ext_copy );
595+ opts -> suboptions = OPTION_MPTCP_DSS ;
595596 ret = true;
596597 }
597598
@@ -615,6 +616,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
615616 opts -> ext_copy .ack64 = 0 ;
616617 }
617618 opts -> ext_copy .use_ack = 1 ;
619+ opts -> suboptions = OPTION_MPTCP_DSS ;
618620 WRITE_ONCE (msk -> old_wspace , __mptcp_space ((struct sock * )msk ));
619621
620622 /* 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 *
686688 if (drop_other_suboptions ) {
687689 pr_debug ("drop other suboptions" );
688690 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 ;
691698 * size -= opt_size ;
692699 }
693700 opts -> suboptions |= OPTION_MPTCP_ADD_ADDR ;
@@ -739,7 +746,12 @@ static bool mptcp_established_options_mp_prio(struct sock *sk,
739746{
740747 struct mptcp_subflow_context * subflow = mptcp_subflow_ctx (sk );
741748
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 ))
743755 return false;
744756
745757 /* account for the trailing 'nop' option */
@@ -1198,8 +1210,74 @@ static u16 mptcp_make_csum(const struct mptcp_ext *mpext)
11981210void mptcp_write_options (__be32 * ptr , const struct tcp_sock * tp ,
11991211 struct mptcp_out_options * opts )
12001212{
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 ) {
12031281 u8 len , flag = MPTCP_CAP_HMAC_SHA256 ;
12041282
12051283 if (OPTION_MPTCP_MPC_SYN & opts -> suboptions ) {
@@ -1246,10 +1324,31 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
12461324 TCPOPT_NOP << 8 | TCPOPT_NOP , ptr );
12471325 }
12481326 ptr += 1 ;
1249- }
12501327
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 ) {
12531352 u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE ;
12541353 u8 echo = MPTCP_ADDR_ECHO ;
12551354
@@ -1307,6 +1406,19 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
13071406 }
13081407 }
13091408
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 :
13101422 if (OPTION_MPTCP_RM_ADDR & opts -> suboptions ) {
13111423 u8 i = 1 ;
13121424
@@ -1327,107 +1439,6 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
13271439 }
13281440 }
13291441
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-
14311442 if (tp )
14321443 mptcp_set_rwin (tp );
14331444}
0 commit comments