@@ -390,6 +390,8 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
390
390
391
391
switch (optname ) {
392
392
case IPV6_V6ONLY :
393
+ case IPV6_TRANSPARENT :
394
+ case IPV6_FREEBIND :
393
395
lock_sock (sk );
394
396
ssock = __mptcp_nmpc_socket (msk );
395
397
if (!ssock ) {
@@ -398,8 +400,24 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
398
400
}
399
401
400
402
ret = tcp_setsockopt (ssock -> sk , SOL_IPV6 , optname , optval , optlen );
401
- if (ret == 0 )
403
+ if (ret != 0 ) {
404
+ release_sock (sk );
405
+ return ret ;
406
+ }
407
+
408
+ sockopt_seq_inc (msk );
409
+
410
+ switch (optname ) {
411
+ case IPV6_V6ONLY :
402
412
sk -> sk_ipv6only = ssock -> sk -> sk_ipv6only ;
413
+ break ;
414
+ case IPV6_TRANSPARENT :
415
+ inet_sk (sk )-> transparent = inet_sk (ssock -> sk )-> transparent ;
416
+ break ;
417
+ case IPV6_FREEBIND :
418
+ inet_sk (sk )-> freebind = inet_sk (ssock -> sk )-> freebind ;
419
+ break ;
420
+ }
403
421
404
422
release_sock (sk );
405
423
break ;
@@ -598,6 +616,46 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t
598
616
return ret ;
599
617
}
600
618
619
+ static int mptcp_setsockopt_sol_ip_set_transparent (struct mptcp_sock * msk , int optname ,
620
+ sockptr_t optval , unsigned int optlen )
621
+ {
622
+ struct sock * sk = (struct sock * )msk ;
623
+ struct inet_sock * issk ;
624
+ struct socket * ssock ;
625
+ int err ;
626
+
627
+ err = ip_setsockopt (sk , SOL_IP , optname , optval , optlen );
628
+ if (err != 0 )
629
+ return err ;
630
+
631
+ lock_sock (sk );
632
+
633
+ ssock = __mptcp_nmpc_socket (msk );
634
+ if (!ssock ) {
635
+ release_sock (sk );
636
+ return - EINVAL ;
637
+ }
638
+
639
+ issk = inet_sk (ssock -> sk );
640
+
641
+ switch (optname ) {
642
+ case IP_FREEBIND :
643
+ issk -> freebind = inet_sk (sk )-> freebind ;
644
+ break ;
645
+ case IP_TRANSPARENT :
646
+ issk -> transparent = inet_sk (sk )-> transparent ;
647
+ break ;
648
+ default :
649
+ release_sock (sk );
650
+ WARN_ON_ONCE (1 );
651
+ return - EOPNOTSUPP ;
652
+ }
653
+
654
+ sockopt_seq_inc (msk );
655
+ release_sock (sk );
656
+ return 0 ;
657
+ }
658
+
601
659
static int mptcp_setsockopt_v4_set_tos (struct mptcp_sock * msk , int optname ,
602
660
sockptr_t optval , unsigned int optlen )
603
661
{
@@ -627,6 +685,9 @@ static int mptcp_setsockopt_v4(struct mptcp_sock *msk, int optname,
627
685
sockptr_t optval , unsigned int optlen )
628
686
{
629
687
switch (optname ) {
688
+ case IP_FREEBIND :
689
+ case IP_TRANSPARENT :
690
+ return mptcp_setsockopt_sol_ip_set_transparent (msk , optname , optval , optlen );
630
691
case IP_TOS :
631
692
return mptcp_setsockopt_v4_set_tos (msk , optname , optval , optlen );
632
693
}
@@ -1068,6 +1129,9 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
1068
1129
1069
1130
if (inet_csk (sk )-> icsk_ca_ops != inet_csk (ssk )-> icsk_ca_ops )
1070
1131
tcp_set_congestion_control (ssk , msk -> ca_name , false, true);
1132
+
1133
+ inet_sk (ssk )-> transparent = inet_sk (sk )-> transparent ;
1134
+ inet_sk (ssk )-> freebind = inet_sk (sk )-> freebind ;
1071
1135
}
1072
1136
1073
1137
static void __mptcp_sockopt_sync (struct mptcp_sock * msk , struct sock * ssk )
0 commit comments