struct sctp_stream_out {
        __u16   ssn;
        __u8    state;
+       __u64   abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
+       __u64   abandoned_sent[SCTP_PR_INDEX(MAX) + 1];
 };
 
 struct sctp_stream_in {
 
 #define SCTP_PR_SUPPORTED      113
 #define SCTP_DEFAULT_PRINFO    114
 #define SCTP_PR_ASSOC_STATUS   115
+#define SCTP_PR_STREAM_STATUS  116
 #define SCTP_RECONFIG_SUPPORTED        117
 #define SCTP_ENABLE_STREAM_RESET       118
 #define SCTP_RESET_STREAMS     119
 
 
        if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
            time_after(jiffies, chunk->msg->expires_at)) {
-               if (chunk->sent_count)
+               struct sctp_stream_out *streamout =
+                       &chunk->asoc->stream->out[chunk->sinfo.sinfo_stream];
+
+               if (chunk->sent_count) {
                        chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++;
-               else
+                       streamout->abandoned_sent[SCTP_PR_INDEX(TTL)]++;
+               } else {
                        chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
+                       streamout->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
+               }
                return 1;
        } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
                   chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
+               struct sctp_stream_out *streamout =
+                       &chunk->asoc->stream->out[chunk->sinfo.sinfo_stream];
+
                chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
+               streamout->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
                return 1;
        } else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) &&
                   chunk->msg->expires_at &&
 
        struct sctp_chunk *chk, *temp;
 
        list_for_each_entry_safe(chk, temp, queue, transmitted_list) {
+               struct sctp_stream_out *streamout;
+
                if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
                    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
                        continue;
                sctp_insert_list(&asoc->outqueue.abandoned,
                                 &chk->transmitted_list);
 
+               streamout = &asoc->stream->out[chk->sinfo.sinfo_stream];
                asoc->sent_cnt_removable--;
                asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
+               streamout->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
 
                if (!chk->tsn_gap_acked) {
                        if (chk->transport)
                q->out_qlen -= chk->skb->len;
                asoc->sent_cnt_removable--;
                asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
+               if (chk->sinfo.sinfo_stream < asoc->stream->outcnt) {
+                       struct sctp_stream_out *streamout =
+                               &asoc->stream->out[chk->sinfo.sinfo_stream];
+
+                       streamout->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
+               }
 
                msg_len -= SCTP_DATA_SNDSIZE(chk) +
                           sizeof(struct sk_buff) +
 
        return retval;
 }
 
+static int sctp_getsockopt_pr_streamstatus(struct sock *sk, int len,
+                                          char __user *optval,
+                                          int __user *optlen)
+{
+       struct sctp_stream_out *streamout;
+       struct sctp_association *asoc;
+       struct sctp_prstatus params;
+       int retval = -EINVAL;
+       int policy;
+
+       if (len < sizeof(params))
+               goto out;
+
+       len = sizeof(params);
+       if (copy_from_user(¶ms, optval, len)) {
+               retval = -EFAULT;
+               goto out;
+       }
+
+       policy = params.sprstat_policy;
+       if (policy & ~SCTP_PR_SCTP_MASK)
+               goto out;
+
+       asoc = sctp_id2assoc(sk, params.sprstat_assoc_id);
+       if (!asoc || params.sprstat_sid >= asoc->stream->outcnt)
+               goto out;
+
+       streamout = &asoc->stream->out[params.sprstat_sid];
+       if (policy == SCTP_PR_SCTP_NONE) {
+               params.sprstat_abandoned_unsent = 0;
+               params.sprstat_abandoned_sent = 0;
+               for (policy = 0; policy <= SCTP_PR_INDEX(MAX); policy++) {
+                       params.sprstat_abandoned_unsent +=
+                               streamout->abandoned_unsent[policy];
+                       params.sprstat_abandoned_sent +=
+                               streamout->abandoned_sent[policy];
+               }
+       } else {
+               params.sprstat_abandoned_unsent =
+                       streamout->abandoned_unsent[__SCTP_PR_INDEX(policy)];
+               params.sprstat_abandoned_sent =
+                       streamout->abandoned_sent[__SCTP_PR_INDEX(policy)];
+       }
+
+       if (put_user(len, optlen) || copy_to_user(optval, ¶ms, len)) {
+               retval = -EFAULT;
+               goto out;
+       }
+
+       retval = 0;
+
+out:
+       return retval;
+}
+
 static int sctp_getsockopt_reconfig_supported(struct sock *sk, int len,
                                              char __user *optval,
                                              int __user *optlen)
                retval = sctp_getsockopt_pr_assocstatus(sk, len, optval,
                                                        optlen);
                break;
+       case SCTP_PR_STREAM_STATUS:
+               retval = sctp_getsockopt_pr_streamstatus(sk, len, optval,
+                                                        optlen);
+               break;
        case SCTP_RECONFIG_SUPPORTED:
                retval = sctp_getsockopt_reconfig_supported(sk, len, optval,
                                                            optlen);