@@ -178,6 +178,71 @@ void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr,
178
178
179
179
break ;
180
180
181
+ case MPTCPOPT_ADD_ADDR :
182
+ mp_opt -> echo = (* ptr ++ ) & MPTCP_ADDR_ECHO ;
183
+ if (!mp_opt -> echo ) {
184
+ if (opsize == TCPOLEN_MPTCP_ADD_ADDR ||
185
+ opsize == TCPOLEN_MPTCP_ADD_ADDR_PORT )
186
+ mp_opt -> family = MPTCP_ADDR_IPVERSION_4 ;
187
+ #if IS_ENABLED (CONFIG_MPTCP_IPV6 )
188
+ else if (opsize == TCPOLEN_MPTCP_ADD_ADDR6 ||
189
+ opsize == TCPOLEN_MPTCP_ADD_ADDR6_PORT )
190
+ mp_opt - > family = MPTCP_ADDR_IPVERSION_6 ;
191
+ #endif
192
+ else
193
+ break ;
194
+ } else {
195
+ if (opsize == TCPOLEN_MPTCP_ADD_ADDR_BASE ||
196
+ opsize == TCPOLEN_MPTCP_ADD_ADDR_BASE_PORT )
197
+ mp_opt -> family = MPTCP_ADDR_IPVERSION_4 ;
198
+ #if IS_ENABLED (CONFIG_MPTCP_IPV6 )
199
+ else if (opsize == TCPOLEN_MPTCP_ADD_ADDR6_BASE ||
200
+ opsize == TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT )
201
+ mp_opt - > family = MPTCP_ADDR_IPVERSION_6 ;
202
+ #endif
203
+ else
204
+ break ;
205
+ }
206
+
207
+ mp_opt -> add_addr = 1 ;
208
+ mp_opt -> port = 0 ;
209
+ mp_opt -> addr_id = * ptr ++ ;
210
+ pr_debug ("ADD_ADDR: id=%d" , mp_opt -> addr_id );
211
+ if (mp_opt -> family == MPTCP_ADDR_IPVERSION_4 ) {
212
+ memcpy ((u8 * )& mp_opt -> addr .s_addr , (u8 * )ptr , 4 );
213
+ ptr += 4 ;
214
+ if (opsize == TCPOLEN_MPTCP_ADD_ADDR_PORT ||
215
+ opsize == TCPOLEN_MPTCP_ADD_ADDR_BASE_PORT ) {
216
+ mp_opt -> port = get_unaligned_be16 (ptr );
217
+ ptr += 2 ;
218
+ }
219
+ }
220
+ #if IS_ENABLED (CONFIG_MPTCP_IPV6 )
221
+ else {
222
+ memcpy (mp_opt -> addr6 .s6_addr , (u8 * )ptr , 16 );
223
+ ptr += 16 ;
224
+ if (opsize == TCPOLEN_MPTCP_ADD_ADDR6_PORT ||
225
+ opsize == TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT ) {
226
+ mp_opt -> port = get_unaligned_be16 (ptr );
227
+ ptr += 2 ;
228
+ }
229
+ }
230
+ #endif
231
+ if (!mp_opt -> echo ) {
232
+ mp_opt -> ahmac = get_unaligned_be64 (ptr );
233
+ ptr += 8 ;
234
+ }
235
+ break ;
236
+
237
+ case MPTCPOPT_RM_ADDR :
238
+ if (opsize != TCPOLEN_MPTCP_RM_ADDR_BASE )
239
+ break ;
240
+
241
+ mp_opt -> rm_addr = 1 ;
242
+ mp_opt -> rm_id = * ptr ++ ;
243
+ pr_debug ("RM_ADDR: id=%d" , mp_opt -> rm_id );
244
+ break ;
245
+
181
246
default :
182
247
break ;
183
248
}
@@ -386,13 +451,93 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
386
451
return true;
387
452
}
388
453
454
+ static u64 add_addr_generate_hmac (u64 key1 , u64 key2 , u8 addr_id ,
455
+ struct in_addr * addr )
456
+ {
457
+ u8 hmac [MPTCP_ADDR_HMAC_LEN ];
458
+ u8 msg [7 ];
459
+
460
+ msg [0 ] = addr_id ;
461
+ memcpy (& msg [1 ], & addr -> s_addr , 4 );
462
+ msg [5 ] = 0 ;
463
+ msg [6 ] = 0 ;
464
+
465
+ mptcp_crypto_hmac_sha (key1 , key2 , msg , 7 , hmac );
466
+
467
+ return get_unaligned_be64 (hmac );
468
+ }
469
+
470
+ #if IS_ENABLED (CONFIG_MPTCP_IPV6 )
471
+ static u64 add_addr6_generate_hmac (u64 key1 , u64 key2 , u8 addr_id ,
472
+ struct in6_addr * addr )
473
+ {
474
+ u8 hmac [MPTCP_ADDR_HMAC_LEN ];
475
+ u8 msg [19 ];
476
+
477
+ msg [0 ] = addr_id ;
478
+ memcpy (& msg [1 ], & addr -> s6_addr , 16 );
479
+ msg [17 ] = 0 ;
480
+ msg [18 ] = 0 ;
481
+
482
+ mptcp_crypto_hmac_sha (key1 , key2 , msg , 19 , hmac );
483
+
484
+ return get_unaligned_be64 (hmac );
485
+ }
486
+ #endif
487
+
488
+ static bool mptcp_established_options_addr (struct sock * sk ,
489
+ unsigned int * size ,
490
+ unsigned int remaining ,
491
+ struct mptcp_out_options * opts )
492
+ {
493
+ struct mptcp_subflow_context * subflow = mptcp_subflow_ctx (sk );
494
+ struct mptcp_sock * msk = mptcp_sk (subflow -> conn );
495
+ struct sockaddr_storage saddr ;
496
+ u8 id ;
497
+
498
+ id = 0 ;
499
+ memset (& saddr , 0 , sizeof (saddr ));
500
+
501
+ if (saddr .ss_family == AF_INET ) {
502
+ if (remaining < TCPOLEN_MPTCP_ADD_ADDR )
503
+ return false;
504
+ opts -> suboptions |= OPTION_MPTCP_ADD_ADDR ;
505
+ opts -> addr_id = id ;
506
+ opts -> addr = ((struct sockaddr_in * )& saddr )-> sin_addr ;
507
+ opts -> ahmac = add_addr_generate_hmac (msk -> local_key ,
508
+ msk -> remote_key ,
509
+ opts -> addr_id ,
510
+ & opts -> addr );
511
+ * size = TCPOLEN_MPTCP_ADD_ADDR ;
512
+ }
513
+ #if IS_ENABLED (CONFIG_MPTCP_IPV6 )
514
+ else if (saddr .ss_family == AF_INET6 ) {
515
+ if (remaining < TCPOLEN_MPTCP_ADD_ADDR6 )
516
+ return false;
517
+ opts -> suboptions |= OPTION_MPTCP_ADD_ADDR6 ;
518
+ opts -> addr_id = id ;
519
+ opts -> ahmac = add_addr6_generate_hmac (msk -> local_key ,
520
+ msk -> remote_key ,
521
+ opts -> addr_id ,
522
+ & opts -> addr6 );
523
+ opts -> addr6 = ((struct sockaddr_in6 * )& saddr )-> sin6_addr ;
524
+ * size = TCPOLEN_MPTCP_ADD_ADDR6 ;
525
+ }
526
+ #endif
527
+ pr_debug ("addr_id=%d, ahmac=%llu" , opts -> addr_id , opts -> ahmac );
528
+
529
+ return true;
530
+ }
531
+
389
532
bool mptcp_established_options (struct sock * sk , struct sk_buff * skb ,
390
533
unsigned int * size , unsigned int remaining ,
391
534
struct mptcp_out_options * opts )
392
535
{
393
536
unsigned int opt_size = 0 ;
394
537
bool ret = false;
395
538
539
+ opts -> suboptions = 0 ;
540
+
396
541
if (mptcp_established_options_mp (sk , skb , & opt_size , remaining , opts ))
397
542
ret = true;
398
543
else if (mptcp_established_options_dss (sk , skb , & opt_size , remaining ,
@@ -407,6 +552,11 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
407
552
408
553
* size += opt_size ;
409
554
remaining -= opt_size ;
555
+ if (mptcp_established_options_addr (sk , & opt_size , remaining , opts )) {
556
+ * size += opt_size ;
557
+ remaining -= opt_size ;
558
+ ret = true;
559
+ }
410
560
411
561
return ret ;
412
562
}
@@ -521,10 +671,9 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts)
521
671
else
522
672
len = TCPOLEN_MPTCP_MPC_ACK ;
523
673
524
- * ptr ++ = htonl ((TCPOPT_MPTCP << 24 ) | (len << 16 ) |
525
- (MPTCPOPT_MP_CAPABLE << 12 ) |
526
- (MPTCP_SUPPORTED_VERSION << 8 ) |
527
- MPTCP_CAP_HMAC_SHA256 );
674
+ * ptr ++ = mptcp_option (MPTCPOPT_MP_CAPABLE , len ,
675
+ MPTCP_SUPPORTED_VERSION ,
676
+ MPTCP_CAP_HMAC_SHA256 );
528
677
529
678
if (!((OPTION_MPTCP_MPC_SYNACK | OPTION_MPTCP_MPC_ACK ) &
530
679
opts -> suboptions ))
@@ -546,6 +695,50 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts)
546
695
}
547
696
548
697
mp_capable_done :
698
+ if (OPTION_MPTCP_ADD_ADDR & opts -> suboptions ) {
699
+ if (opts -> ahmac )
700
+ * ptr ++ = mptcp_option (MPTCPOPT_ADD_ADDR ,
701
+ TCPOLEN_MPTCP_ADD_ADDR , 0 ,
702
+ opts -> addr_id );
703
+ else
704
+ * ptr ++ = mptcp_option (MPTCPOPT_ADD_ADDR ,
705
+ TCPOLEN_MPTCP_ADD_ADDR_BASE ,
706
+ MPTCP_ADDR_ECHO ,
707
+ opts -> addr_id );
708
+ memcpy ((u8 * )ptr , (u8 * )& opts -> addr .s_addr , 4 );
709
+ ptr += 1 ;
710
+ if (opts -> ahmac ) {
711
+ put_unaligned_be64 (opts -> ahmac , ptr );
712
+ ptr += 2 ;
713
+ }
714
+ }
715
+
716
+ #if IS_ENABLED (CONFIG_MPTCP_IPV6 )
717
+ if (OPTION_MPTCP_ADD_ADDR6 & opts -> suboptions ) {
718
+ if (opts -> ahmac )
719
+ * ptr ++ = mptcp_option (MPTCPOPT_ADD_ADDR ,
720
+ TCPOLEN_MPTCP_ADD_ADDR6 , 0 ,
721
+ opts -> addr_id );
722
+ else
723
+ * ptr ++ = mptcp_option (MPTCPOPT_ADD_ADDR ,
724
+ TCPOLEN_MPTCP_ADD_ADDR6_BASE ,
725
+ MPTCP_ADDR_ECHO ,
726
+ opts -> addr_id );
727
+ memcpy ((u8 * )ptr , opts -> addr6 .s6_addr , 16 );
728
+ ptr += 4 ;
729
+ if (opts -> ahmac ) {
730
+ put_unaligned_be64 (opts -> ahmac , ptr );
731
+ ptr += 2 ;
732
+ }
733
+ }
734
+ #endif
735
+
736
+ if (OPTION_MPTCP_RM_ADDR & opts -> suboptions ) {
737
+ * ptr ++ = mptcp_option (MPTCPOPT_RM_ADDR ,
738
+ TCPOLEN_MPTCP_RM_ADDR_BASE ,
739
+ 0 , opts -> rm_id );
740
+ }
741
+
549
742
if (opts -> ext_copy .use_ack || opts -> ext_copy .use_map ) {
550
743
struct mptcp_ext * mpext = & opts -> ext_copy ;
551
744
u8 len = TCPOLEN_MPTCP_DSS_BASE ;
@@ -567,10 +760,7 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts)
567
760
flags |= MPTCP_DSS_DATA_FIN ;
568
761
}
569
762
570
- * ptr ++ = htonl ((TCPOPT_MPTCP << 24 ) |
571
- (len << 16 ) |
572
- (MPTCPOPT_DSS << 12 ) |
573
- (flags ));
763
+ * ptr ++ = mptcp_option (MPTCPOPT_DSS , len , 0 , flags );
574
764
575
765
if (mpext -> use_ack ) {
576
766
put_unaligned_be64 (mpext -> data_ack , ptr );
0 commit comments