aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2016-07-09 07:47:41 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-11 16:25:38 -0400
commitf959fb442c35f4b61fea341401b8463dd0a1b959 (patch)
tree8e039e6a62d97bedf18d27287955446d5da5b9b3 /net/sctp/socket.c
parent28aa4c26fce2202db8d42ae76b639ca1d9a23d25 (diff)
sctp: add SCTP_DEFAULT_PRINFO into sctp sockopt
This patch adds SCTP_DEFAULT_PRINFO to sctp sockopt. It is used to set/get sctp Partially Reliable Policies' default params, which includes 3 policies (ttl, rtx, prio) and their values. Still, if we set policy params in sndinfo, we will use the params of sndinfo against chunks, instead of the default params. In this patch, we will use 5-8bit of sp/asoc->default_flags to store prsctp policies, and reuse asoc->default_timetolive to store their values. It means if we enable and set prsctp policy, prior ttl timeout in sctp will not work any more. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 7460ddebd9ce..c03fe1b76706 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3694,6 +3694,47 @@ out:
3694 return retval; 3694 return retval;
3695} 3695}
3696 3696
3697static int sctp_setsockopt_default_prinfo(struct sock *sk,
3698 char __user *optval,
3699 unsigned int optlen)
3700{
3701 struct sctp_default_prinfo info;
3702 struct sctp_association *asoc;
3703 int retval = -EINVAL;
3704
3705 if (optlen != sizeof(info))
3706 goto out;
3707
3708 if (copy_from_user(&info, optval, sizeof(info))) {
3709 retval = -EFAULT;
3710 goto out;
3711 }
3712
3713 if (info.pr_policy & ~SCTP_PR_SCTP_MASK)
3714 goto out;
3715
3716 if (info.pr_policy == SCTP_PR_SCTP_NONE)
3717 info.pr_value = 0;
3718
3719 asoc = sctp_id2assoc(sk, info.pr_assoc_id);
3720 if (asoc) {
3721 SCTP_PR_SET_POLICY(asoc->default_flags, info.pr_policy);
3722 asoc->default_timetolive = info.pr_value;
3723 } else if (!info.pr_assoc_id) {
3724 struct sctp_sock *sp = sctp_sk(sk);
3725
3726 SCTP_PR_SET_POLICY(sp->default_flags, info.pr_policy);
3727 sp->default_timetolive = info.pr_value;
3728 } else {
3729 goto out;
3730 }
3731
3732 retval = 0;
3733
3734out:
3735 return retval;
3736}
3737
3697/* API 6.2 setsockopt(), getsockopt() 3738/* API 6.2 setsockopt(), getsockopt()
3698 * 3739 *
3699 * Applications use setsockopt() and getsockopt() to set or retrieve 3740 * Applications use setsockopt() and getsockopt() to set or retrieve
@@ -3857,6 +3898,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
3857 case SCTP_PR_SUPPORTED: 3898 case SCTP_PR_SUPPORTED:
3858 retval = sctp_setsockopt_pr_supported(sk, optval, optlen); 3899 retval = sctp_setsockopt_pr_supported(sk, optval, optlen);
3859 break; 3900 break;
3901 case SCTP_DEFAULT_PRINFO:
3902 retval = sctp_setsockopt_default_prinfo(sk, optval, optlen);
3903 break;
3860 default: 3904 default:
3861 retval = -ENOPROTOOPT; 3905 retval = -ENOPROTOOPT;
3862 break; 3906 break;
@@ -6243,6 +6287,49 @@ out:
6243 return retval; 6287 return retval;
6244} 6288}
6245 6289
6290static int sctp_getsockopt_default_prinfo(struct sock *sk, int len,
6291 char __user *optval,
6292 int __user *optlen)
6293{
6294 struct sctp_default_prinfo info;
6295 struct sctp_association *asoc;
6296 int retval = -EFAULT;
6297
6298 if (len < sizeof(info)) {
6299 retval = -EINVAL;
6300 goto out;
6301 }
6302
6303 len = sizeof(info);
6304 if (copy_from_user(&info, optval, len))
6305 goto out;
6306
6307 asoc = sctp_id2assoc(sk, info.pr_assoc_id);
6308 if (asoc) {
6309 info.pr_policy = SCTP_PR_POLICY(asoc->default_flags);
6310 info.pr_value = asoc->default_timetolive;
6311 } else if (!info.pr_assoc_id) {
6312 struct sctp_sock *sp = sctp_sk(sk);
6313
6314 info.pr_policy = SCTP_PR_POLICY(sp->default_flags);
6315 info.pr_value = sp->default_timetolive;
6316 } else {
6317 retval = -EINVAL;
6318 goto out;
6319 }
6320
6321 if (put_user(len, optlen))
6322 goto out;
6323
6324 if (copy_to_user(optval, &info, len))
6325 goto out;
6326
6327 retval = 0;
6328
6329out:
6330 return retval;
6331}
6332
6246static int sctp_getsockopt(struct sock *sk, int level, int optname, 6333static int sctp_getsockopt(struct sock *sk, int level, int optname,
6247 char __user *optval, int __user *optlen) 6334 char __user *optval, int __user *optlen)
6248{ 6335{
@@ -6399,6 +6486,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
6399 case SCTP_PR_SUPPORTED: 6486 case SCTP_PR_SUPPORTED:
6400 retval = sctp_getsockopt_pr_supported(sk, len, optval, optlen); 6487 retval = sctp_getsockopt_pr_supported(sk, len, optval, optlen);
6401 break; 6488 break;
6489 case SCTP_DEFAULT_PRINFO:
6490 retval = sctp_getsockopt_default_prinfo(sk, len, optval,
6491 optlen);
6492 break;
6402 default: 6493 default:
6403 retval = -ENOPROTOOPT; 6494 retval = -ENOPROTOOPT;
6404 break; 6495 break;