@@ -3356,6 +3356,46 @@ static int sctp_setsockopt_del_key(struct sock *sk,
33563356
33573357}
33583358
3359+ /*
3360+ * 8.1.23 SCTP_AUTO_ASCONF
3361+ *
3362+ * This option will enable or disable the use of the automatic generation of
3363+ * ASCONF chunks to add and delete addresses to an existing association. Note
3364+ * that this option has two caveats namely: a) it only affects sockets that
3365+ * are bound to all addresses available to the SCTP stack, and b) the system
3366+ * administrator may have an overriding control that turns the ASCONF feature
3367+ * off no matter what setting the socket option may have.
3368+ * This option expects an integer boolean flag, where a non-zero value turns on
3369+ * the option, and a zero value turns off the option.
3370+ * Note. In this implementation, socket operation overrides default parameter
3371+ * being set by sysctl as well as FreeBSD implementation
3372+ */
3373+ static int sctp_setsockopt_auto_asconf (struct sock * sk , char __user * optval ,
3374+ unsigned int optlen )
3375+ {
3376+ int val ;
3377+ struct sctp_sock * sp = sctp_sk (sk );
3378+
3379+ if (optlen < sizeof (int ))
3380+ return - EINVAL ;
3381+ if (get_user (val , (int __user * )optval ))
3382+ return - EFAULT ;
3383+ if (!sctp_is_ep_boundall (sk ) && val )
3384+ return - EINVAL ;
3385+ if ((val && sp -> do_auto_asconf ) || (!val && !sp -> do_auto_asconf ))
3386+ return 0 ;
3387+
3388+ if (val == 0 && sp -> do_auto_asconf ) {
3389+ list_del (& sp -> auto_asconf_list );
3390+ sp -> do_auto_asconf = 0 ;
3391+ } else if (val && !sp -> do_auto_asconf ) {
3392+ list_add_tail (& sp -> auto_asconf_list ,
3393+ & sctp_auto_asconf_splist );
3394+ sp -> do_auto_asconf = 1 ;
3395+ }
3396+ return 0 ;
3397+ }
3398+
33593399
33603400/* API 6.2 setsockopt(), getsockopt()
33613401 *
@@ -3503,6 +3543,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
35033543 case SCTP_AUTH_DELETE_KEY :
35043544 retval = sctp_setsockopt_del_key (sk , optval , optlen );
35053545 break ;
3546+ case SCTP_AUTO_ASCONF :
3547+ retval = sctp_setsockopt_auto_asconf (sk , optval , optlen );
3548+ break ;
35063549 default :
35073550 retval = - ENOPROTOOPT ;
35083551 break ;
@@ -5308,6 +5351,28 @@ static int sctp_getsockopt_assoc_number(struct sock *sk, int len,
53085351 return 0 ;
53095352}
53105353
5354+ /*
5355+ * 8.1.23 SCTP_AUTO_ASCONF
5356+ * See the corresponding setsockopt entry as description
5357+ */
5358+ static int sctp_getsockopt_auto_asconf (struct sock * sk , int len ,
5359+ char __user * optval , int __user * optlen )
5360+ {
5361+ int val = 0 ;
5362+
5363+ if (len < sizeof (int ))
5364+ return - EINVAL ;
5365+
5366+ len = sizeof (int );
5367+ if (sctp_sk (sk )-> do_auto_asconf && sctp_is_ep_boundall (sk ))
5368+ val = 1 ;
5369+ if (put_user (len , optlen ))
5370+ return - EFAULT ;
5371+ if (copy_to_user (optval , & val , len ))
5372+ return - EFAULT ;
5373+ return 0 ;
5374+ }
5375+
53115376/*
53125377 * 8.2.6. Get the Current Identifiers of Associations
53135378 * (SCTP_GET_ASSOC_ID_LIST)
@@ -5492,6 +5557,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
54925557 case SCTP_GET_ASSOC_ID_LIST :
54935558 retval = sctp_getsockopt_assoc_ids (sk , len , optval , optlen );
54945559 break ;
5560+ case SCTP_AUTO_ASCONF :
5561+ retval = sctp_getsockopt_auto_asconf (sk , len , optval , optlen );
5562+ break ;
54955563 default :
54965564 retval = - ENOPROTOOPT ;
54975565 break ;
0 commit comments