aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index c03fe1b76706..c3167c43a9c1 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -6330,6 +6330,64 @@ out:
6330 return retval; 6330 return retval;
6331} 6331}
6332 6332
6333static int sctp_getsockopt_pr_assocstatus(struct sock *sk, int len,
6334 char __user *optval,
6335 int __user *optlen)
6336{
6337 struct sctp_prstatus params;
6338 struct sctp_association *asoc;
6339 int policy;
6340 int retval = -EINVAL;
6341
6342 if (len < sizeof(params))
6343 goto out;
6344
6345 len = sizeof(params);
6346 if (copy_from_user(&params, optval, len)) {
6347 retval = -EFAULT;
6348 goto out;
6349 }
6350
6351 policy = params.sprstat_policy;
6352 if (policy & ~SCTP_PR_SCTP_MASK)
6353 goto out;
6354
6355 asoc = sctp_id2assoc(sk, params.sprstat_assoc_id);
6356 if (!asoc)
6357 goto out;
6358
6359 if (policy == SCTP_PR_SCTP_NONE) {
6360 params.sprstat_abandoned_unsent = 0;
6361 params.sprstat_abandoned_sent = 0;
6362 for (policy = 0; policy <= SCTP_PR_INDEX(MAX); policy++) {
6363 params.sprstat_abandoned_unsent +=
6364 asoc->abandoned_unsent[policy];
6365 params.sprstat_abandoned_sent +=
6366 asoc->abandoned_sent[policy];
6367 }
6368 } else {
6369 params.sprstat_abandoned_unsent =
6370 asoc->abandoned_unsent[__SCTP_PR_INDEX(policy)];
6371 params.sprstat_abandoned_sent =
6372 asoc->abandoned_sent[__SCTP_PR_INDEX(policy)];
6373 }
6374
6375 if (put_user(len, optlen)) {
6376 retval = -EFAULT;
6377 goto out;
6378 }
6379
6380 if (copy_to_user(optval, &params, len)) {
6381 retval = -EFAULT;
6382 goto out;
6383 }
6384
6385 retval = 0;
6386
6387out:
6388 return retval;
6389}
6390
6333static int sctp_getsockopt(struct sock *sk, int level, int optname, 6391static int sctp_getsockopt(struct sock *sk, int level, int optname,
6334 char __user *optval, int __user *optlen) 6392 char __user *optval, int __user *optlen)
6335{ 6393{
@@ -6490,6 +6548,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
6490 retval = sctp_getsockopt_default_prinfo(sk, len, optval, 6548 retval = sctp_getsockopt_default_prinfo(sk, len, optval,
6491 optlen); 6549 optlen);
6492 break; 6550 break;
6551 case SCTP_PR_ASSOC_STATUS:
6552 retval = sctp_getsockopt_pr_assocstatus(sk, len, optval,
6553 optlen);
6554 break;
6493 default: 6555 default:
6494 retval = -ENOPROTOOPT; 6556 retval = -ENOPROTOOPT;
6495 break; 6557 break;