@@ -4560,6 +4560,34 @@ static int sctp_setsockopt_auth_supported(struct sock *sk,
45604560 return retval ;
45614561}
45624562
4563+ static int sctp_setsockopt_ecn_supported (struct sock * sk ,
4564+ char __user * optval ,
4565+ unsigned int optlen )
4566+ {
4567+ struct sctp_assoc_value params ;
4568+ struct sctp_association * asoc ;
4569+ int retval = - EINVAL ;
4570+
4571+ if (optlen != sizeof (params ))
4572+ goto out ;
4573+
4574+ if (copy_from_user (& params , optval , optlen )) {
4575+ retval = - EFAULT ;
4576+ goto out ;
4577+ }
4578+
4579+ asoc = sctp_id2assoc (sk , params .assoc_id );
4580+ if (!asoc && params .assoc_id != SCTP_FUTURE_ASSOC &&
4581+ sctp_style (sk , UDP ))
4582+ goto out ;
4583+
4584+ sctp_sk (sk )-> ep -> ecn_enable = !!params .assoc_value ;
4585+ retval = 0 ;
4586+
4587+ out :
4588+ return retval ;
4589+ }
4590+
45634591/* API 6.2 setsockopt(), getsockopt()
45644592 *
45654593 * Applications use setsockopt() and getsockopt() to set or retrieve
@@ -4766,6 +4794,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
47664794 case SCTP_AUTH_SUPPORTED :
47674795 retval = sctp_setsockopt_auth_supported (sk , optval , optlen );
47684796 break ;
4797+ case SCTP_ECN_SUPPORTED :
4798+ retval = sctp_setsockopt_ecn_supported (sk , optval , optlen );
4799+ break ;
47694800 default :
47704801 retval = - ENOPROTOOPT ;
47714802 break ;
@@ -7828,6 +7859,45 @@ static int sctp_getsockopt_auth_supported(struct sock *sk, int len,
78287859 return retval ;
78297860}
78307861
7862+ static int sctp_getsockopt_ecn_supported (struct sock * sk , int len ,
7863+ char __user * optval ,
7864+ int __user * optlen )
7865+ {
7866+ struct sctp_assoc_value params ;
7867+ struct sctp_association * asoc ;
7868+ int retval = - EFAULT ;
7869+
7870+ if (len < sizeof (params )) {
7871+ retval = - EINVAL ;
7872+ goto out ;
7873+ }
7874+
7875+ len = sizeof (params );
7876+ if (copy_from_user (& params , optval , len ))
7877+ goto out ;
7878+
7879+ asoc = sctp_id2assoc (sk , params .assoc_id );
7880+ if (!asoc && params .assoc_id != SCTP_FUTURE_ASSOC &&
7881+ sctp_style (sk , UDP )) {
7882+ retval = - EINVAL ;
7883+ goto out ;
7884+ }
7885+
7886+ params .assoc_value = asoc ? asoc -> peer .ecn_capable
7887+ : sctp_sk (sk )-> ep -> ecn_enable ;
7888+
7889+ if (put_user (len , optlen ))
7890+ goto out ;
7891+
7892+ if (copy_to_user (optval , & params , len ))
7893+ goto out ;
7894+
7895+ retval = 0 ;
7896+
7897+ out :
7898+ return retval ;
7899+ }
7900+
78317901static int sctp_getsockopt (struct sock * sk , int level , int optname ,
78327902 char __user * optval , int __user * optlen )
78337903{
@@ -8037,6 +8107,9 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
80378107 retval = sctp_getsockopt_auth_supported (sk , len , optval ,
80388108 optlen );
80398109 break ;
8110+ case SCTP_ECN_SUPPORTED :
8111+ retval = sctp_getsockopt_ecn_supported (sk , len , optval , optlen );
8112+ break ;
80408113 default :
80418114 retval = - ENOPROTOOPT ;
80428115 break ;
0 commit comments