Commit c0d8bab6ae518cedfb5246e99ece43fe51d79b56
Committed by
David S. Miller
1 parent
11ae76e67a
sctp: add get and set sockopt for reconf_enable
This patchset is to add SCTP_RECONFIG_SUPPORTED sockopt, it would set and get asoc reconf_enable value when asoc_id is set, or it would set and get ep reconf_enalbe value if asoc_id is 0. It is also to add sysctl interface for users to set the default value for reconf_enable. After this patch, stream reconf will work. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 3 changed files with 89 additions and 0 deletions Side-by-side Diff
include/uapi/linux/sctp.h
... | ... | @@ -115,6 +115,7 @@ |
115 | 115 | #define SCTP_PR_SUPPORTED 113 |
116 | 116 | #define SCTP_DEFAULT_PRINFO 114 |
117 | 117 | #define SCTP_PR_ASSOC_STATUS 115 |
118 | +#define SCTP_RECONFIG_SUPPORTED 117 | |
118 | 119 | #define SCTP_ENABLE_STREAM_RESET 118 |
119 | 120 | #define SCTP_RESET_STREAMS 119 |
120 | 121 | #define SCTP_RESET_ASSOC 120 |
net/sctp/socket.c
... | ... | @@ -3758,6 +3758,39 @@ |
3758 | 3758 | return retval; |
3759 | 3759 | } |
3760 | 3760 | |
3761 | +static int sctp_setsockopt_reconfig_supported(struct sock *sk, | |
3762 | + char __user *optval, | |
3763 | + unsigned int optlen) | |
3764 | +{ | |
3765 | + struct sctp_assoc_value params; | |
3766 | + struct sctp_association *asoc; | |
3767 | + int retval = -EINVAL; | |
3768 | + | |
3769 | + if (optlen != sizeof(params)) | |
3770 | + goto out; | |
3771 | + | |
3772 | + if (copy_from_user(¶ms, optval, optlen)) { | |
3773 | + retval = -EFAULT; | |
3774 | + goto out; | |
3775 | + } | |
3776 | + | |
3777 | + asoc = sctp_id2assoc(sk, params.assoc_id); | |
3778 | + if (asoc) { | |
3779 | + asoc->reconf_enable = !!params.assoc_value; | |
3780 | + } else if (!params.assoc_id) { | |
3781 | + struct sctp_sock *sp = sctp_sk(sk); | |
3782 | + | |
3783 | + sp->ep->reconf_enable = !!params.assoc_value; | |
3784 | + } else { | |
3785 | + goto out; | |
3786 | + } | |
3787 | + | |
3788 | + retval = 0; | |
3789 | + | |
3790 | +out: | |
3791 | + return retval; | |
3792 | +} | |
3793 | + | |
3761 | 3794 | static int sctp_setsockopt_enable_strreset(struct sock *sk, |
3762 | 3795 | char __user *optval, |
3763 | 3796 | unsigned int optlen) |
... | ... | @@ -4038,6 +4071,9 @@ |
4038 | 4071 | case SCTP_DEFAULT_PRINFO: |
4039 | 4072 | retval = sctp_setsockopt_default_prinfo(sk, optval, optlen); |
4040 | 4073 | break; |
4074 | + case SCTP_RECONFIG_SUPPORTED: | |
4075 | + retval = sctp_setsockopt_reconfig_supported(sk, optval, optlen); | |
4076 | + break; | |
4041 | 4077 | case SCTP_ENABLE_STREAM_RESET: |
4042 | 4078 | retval = sctp_setsockopt_enable_strreset(sk, optval, optlen); |
4043 | 4079 | break; |
... | ... | @@ -6540,6 +6576,47 @@ |
6540 | 6576 | return retval; |
6541 | 6577 | } |
6542 | 6578 | |
6579 | +static int sctp_getsockopt_reconfig_supported(struct sock *sk, int len, | |
6580 | + char __user *optval, | |
6581 | + int __user *optlen) | |
6582 | +{ | |
6583 | + struct sctp_assoc_value params; | |
6584 | + struct sctp_association *asoc; | |
6585 | + int retval = -EFAULT; | |
6586 | + | |
6587 | + if (len < sizeof(params)) { | |
6588 | + retval = -EINVAL; | |
6589 | + goto out; | |
6590 | + } | |
6591 | + | |
6592 | + len = sizeof(params); | |
6593 | + if (copy_from_user(¶ms, optval, len)) | |
6594 | + goto out; | |
6595 | + | |
6596 | + asoc = sctp_id2assoc(sk, params.assoc_id); | |
6597 | + if (asoc) { | |
6598 | + params.assoc_value = asoc->reconf_enable; | |
6599 | + } else if (!params.assoc_id) { | |
6600 | + struct sctp_sock *sp = sctp_sk(sk); | |
6601 | + | |
6602 | + params.assoc_value = sp->ep->reconf_enable; | |
6603 | + } else { | |
6604 | + retval = -EINVAL; | |
6605 | + goto out; | |
6606 | + } | |
6607 | + | |
6608 | + if (put_user(len, optlen)) | |
6609 | + goto out; | |
6610 | + | |
6611 | + if (copy_to_user(optval, ¶ms, len)) | |
6612 | + goto out; | |
6613 | + | |
6614 | + retval = 0; | |
6615 | + | |
6616 | +out: | |
6617 | + return retval; | |
6618 | +} | |
6619 | + | |
6543 | 6620 | static int sctp_getsockopt_enable_strreset(struct sock *sk, int len, |
6544 | 6621 | char __user *optval, |
6545 | 6622 | int __user *optlen) |
... | ... | @@ -6747,6 +6824,10 @@ |
6747 | 6824 | case SCTP_PR_ASSOC_STATUS: |
6748 | 6825 | retval = sctp_getsockopt_pr_assocstatus(sk, len, optval, |
6749 | 6826 | optlen); |
6827 | + break; | |
6828 | + case SCTP_RECONFIG_SUPPORTED: | |
6829 | + retval = sctp_getsockopt_reconfig_supported(sk, len, optval, | |
6830 | + optlen); | |
6750 | 6831 | break; |
6751 | 6832 | case SCTP_ENABLE_STREAM_RESET: |
6752 | 6833 | retval = sctp_getsockopt_enable_strreset(sk, len, optval, |
net/sctp/sysctl.c
... | ... | @@ -275,6 +275,13 @@ |
275 | 275 | .proc_handler = proc_dointvec, |
276 | 276 | }, |
277 | 277 | { |
278 | + .procname = "reconf_enable", | |
279 | + .data = &init_net.sctp.reconf_enable, | |
280 | + .maxlen = sizeof(int), | |
281 | + .mode = 0644, | |
282 | + .proc_handler = proc_dointvec, | |
283 | + }, | |
284 | + { | |
278 | 285 | .procname = "auth_enable", |
279 | 286 | .data = &init_net.sctp.auth_enable, |
280 | 287 | .maxlen = sizeof(int), |