aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/structs.h3
-rw-r--r--include/uapi/linux/sctp.h12
-rw-r--r--net/sctp/socket.c62
3 files changed, 77 insertions, 0 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 07115ca9de4d..d8e464aacb20 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1853,6 +1853,9 @@ struct sctp_association {
1853 prsctp_enable:1; 1853 prsctp_enable:1;
1854 1854
1855 struct sctp_priv_assoc_stats stats; 1855 struct sctp_priv_assoc_stats stats;
1856
1857 __u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
1858 __u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1];
1856}; 1859};
1857 1860
1858 1861
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index 984cf2e9a61d..d304f4c9792c 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -114,6 +114,7 @@ typedef __s32 sctp_assoc_t;
114#define SCTP_GET_ASSOC_STATS 112 /* Read only */ 114#define SCTP_GET_ASSOC_STATS 112 /* Read only */
115#define SCTP_PR_SUPPORTED 113 115#define SCTP_PR_SUPPORTED 113
116#define SCTP_DEFAULT_PRINFO 114 116#define SCTP_DEFAULT_PRINFO 114
117#define SCTP_PR_ASSOC_STATUS 115
117 118
118/* PR-SCTP policies */ 119/* PR-SCTP policies */
119#define SCTP_PR_SCTP_NONE 0x0000 120#define SCTP_PR_SCTP_NONE 0x0000
@@ -926,6 +927,17 @@ struct sctp_paddrthlds {
926 __u16 spt_pathpfthld; 927 __u16 spt_pathpfthld;
927}; 928};
928 929
930/*
931 * Socket Option for Getting the Association/Stream-Specific PR-SCTP Status
932 */
933struct sctp_prstatus {
934 sctp_assoc_t sprstat_assoc_id;
935 __u16 sprstat_sid;
936 __u16 sprstat_policy;
937 __u64 sprstat_abandoned_unsent;
938 __u64 sprstat_abandoned_sent;
939};
940
929struct sctp_default_prinfo { 941struct sctp_default_prinfo {
930 sctp_assoc_t pr_assoc_id; 942 sctp_assoc_t pr_assoc_id;
931 __u32 pr_value; 943 __u32 pr_value;
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;