aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/chunk.c11
-rw-r--r--net/sctp/outqueue.c19
-rw-r--r--net/sctp/protocol.c1
-rw-r--r--net/sctp/socket.c6
-rw-r--r--net/sctp/stream.c79
-rw-r--r--net/sctp/stream_sched.c25
-rw-r--r--net/sctp/stream_sched_prio.c7
-rw-r--r--net/sctp/stream_sched_rr.c7
8 files changed, 124 insertions, 31 deletions
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 7b261afc47b9..7f8baa48e7c2 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -53,6 +53,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg)
53 msg->send_failed = 0; 53 msg->send_failed = 0;
54 msg->send_error = 0; 54 msg->send_error = 0;
55 msg->can_delay = 1; 55 msg->can_delay = 1;
56 msg->abandoned = 0;
56 msg->expires_at = 0; 57 msg->expires_at = 0;
57 INIT_LIST_HEAD(&msg->chunks); 58 INIT_LIST_HEAD(&msg->chunks);
58} 59}
@@ -304,6 +305,13 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
304 if (!chunk->asoc->peer.prsctp_capable) 305 if (!chunk->asoc->peer.prsctp_capable)
305 return 0; 306 return 0;
306 307
308 if (chunk->msg->abandoned)
309 return 1;
310
311 if (!chunk->has_tsn &&
312 !(chunk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG))
313 return 0;
314
307 if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) && 315 if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
308 time_after(jiffies, chunk->msg->expires_at)) { 316 time_after(jiffies, chunk->msg->expires_at)) {
309 struct sctp_stream_out *streamout = 317 struct sctp_stream_out *streamout =
@@ -316,6 +324,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
316 chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; 324 chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
317 streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; 325 streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
318 } 326 }
327 chunk->msg->abandoned = 1;
319 return 1; 328 return 1;
320 } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) && 329 } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
321 chunk->sent_count > chunk->sinfo.sinfo_timetolive) { 330 chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
@@ -324,10 +333,12 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
324 333
325 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++; 334 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
326 streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++; 335 streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
336 chunk->msg->abandoned = 1;
327 return 1; 337 return 1;
328 } else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) && 338 } else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) &&
329 chunk->msg->expires_at && 339 chunk->msg->expires_at &&
330 time_after(jiffies, chunk->msg->expires_at)) { 340 time_after(jiffies, chunk->msg->expires_at)) {
341 chunk->msg->abandoned = 1;
331 return 1; 342 return 1;
332 } 343 }
333 /* PRIO policy is processed by sendmsg, not here */ 344 /* PRIO policy is processed by sendmsg, not here */
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 4db012aa25f7..7d67feeeffc1 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -364,10 +364,12 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
364 list_for_each_entry_safe(chk, temp, queue, transmitted_list) { 364 list_for_each_entry_safe(chk, temp, queue, transmitted_list) {
365 struct sctp_stream_out *streamout; 365 struct sctp_stream_out *streamout;
366 366
367 if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || 367 if (!chk->msg->abandoned &&
368 chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive) 368 (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
369 chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
369 continue; 370 continue;
370 371
372 chk->msg->abandoned = 1;
371 list_del_init(&chk->transmitted_list); 373 list_del_init(&chk->transmitted_list);
372 sctp_insert_list(&asoc->outqueue.abandoned, 374 sctp_insert_list(&asoc->outqueue.abandoned,
373 &chk->transmitted_list); 375 &chk->transmitted_list);
@@ -377,7 +379,8 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
377 asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; 379 asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
378 streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; 380 streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
379 381
380 if (!chk->tsn_gap_acked) { 382 if (queue != &asoc->outqueue.retransmit &&
383 !chk->tsn_gap_acked) {
381 if (chk->transport) 384 if (chk->transport)
382 chk->transport->flight_size -= 385 chk->transport->flight_size -=
383 sctp_data_size(chk); 386 sctp_data_size(chk);
@@ -403,10 +406,13 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
403 q->sched->unsched_all(&asoc->stream); 406 q->sched->unsched_all(&asoc->stream);
404 407
405 list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) { 408 list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
406 if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || 409 if (!chk->msg->abandoned &&
407 chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive) 410 (!(chk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG) ||
411 !SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
412 chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
408 continue; 413 continue;
409 414
415 chk->msg->abandoned = 1;
410 sctp_sched_dequeue_common(q, chk); 416 sctp_sched_dequeue_common(q, chk);
411 asoc->sent_cnt_removable--; 417 asoc->sent_cnt_removable--;
412 asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; 418 asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
@@ -1434,7 +1440,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1434 /* If this chunk has not been acked, stop 1440 /* If this chunk has not been acked, stop
1435 * considering it as 'outstanding'. 1441 * considering it as 'outstanding'.
1436 */ 1442 */
1437 if (!tchunk->tsn_gap_acked) { 1443 if (transmitted_queue != &q->retransmit &&
1444 !tchunk->tsn_gap_acked) {
1438 if (tchunk->transport) 1445 if (tchunk->transport)
1439 tchunk->transport->flight_size -= 1446 tchunk->transport->flight_size -=
1440 sctp_data_size(tchunk); 1447 sctp_data_size(tchunk);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index f5172c21349b..6a38c2503649 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1499,6 +1499,7 @@ static __init int sctp_init(void)
1499 INIT_LIST_HEAD(&sctp_address_families); 1499 INIT_LIST_HEAD(&sctp_address_families);
1500 sctp_v4_pf_init(); 1500 sctp_v4_pf_init();
1501 sctp_v6_pf_init(); 1501 sctp_v6_pf_init();
1502 sctp_sched_ops_init();
1502 1503
1503 status = register_pernet_subsys(&sctp_defaults_ops); 1504 status = register_pernet_subsys(&sctp_defaults_ops);
1504 if (status) 1505 if (status)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 3204a9b29407..014847e25648 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -188,13 +188,13 @@ static void sctp_for_each_tx_datachunk(struct sctp_association *asoc,
188 list_for_each_entry(chunk, &t->transmitted, transmitted_list) 188 list_for_each_entry(chunk, &t->transmitted, transmitted_list)
189 cb(chunk); 189 cb(chunk);
190 190
191 list_for_each_entry(chunk, &q->retransmit, list) 191 list_for_each_entry(chunk, &q->retransmit, transmitted_list)
192 cb(chunk); 192 cb(chunk);
193 193
194 list_for_each_entry(chunk, &q->sacked, list) 194 list_for_each_entry(chunk, &q->sacked, transmitted_list)
195 cb(chunk); 195 cb(chunk);
196 196
197 list_for_each_entry(chunk, &q->abandoned, list) 197 list_for_each_entry(chunk, &q->abandoned, transmitted_list)
198 cb(chunk); 198 cb(chunk);
199 199
200 list_for_each_entry(chunk, &q->out_chunk_list, list) 200 list_for_each_entry(chunk, &q->out_chunk_list, list)
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index a11db21dc8a0..76ea66be0bbe 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -64,7 +64,7 @@ static void sctp_stream_outq_migrate(struct sctp_stream *stream,
64 */ 64 */
65 65
66 /* Mark as failed send. */ 66 /* Mark as failed send. */
67 sctp_chunk_fail(ch, SCTP_ERROR_INV_STRM); 67 sctp_chunk_fail(ch, (__force __u32)SCTP_ERROR_INV_STRM);
68 if (asoc->peer.prsctp_capable && 68 if (asoc->peer.prsctp_capable &&
69 SCTP_PR_PRIO_ENABLED(ch->sinfo.sinfo_flags)) 69 SCTP_PR_PRIO_ENABLED(ch->sinfo.sinfo_flags))
70 asoc->sent_cnt_removable--; 70 asoc->sent_cnt_removable--;
@@ -254,6 +254,30 @@ static int sctp_send_reconf(struct sctp_association *asoc,
254 return retval; 254 return retval;
255} 255}
256 256
257static bool sctp_stream_outq_is_empty(struct sctp_stream *stream,
258 __u16 str_nums, __be16 *str_list)
259{
260 struct sctp_association *asoc;
261 __u16 i;
262
263 asoc = container_of(stream, struct sctp_association, stream);
264 if (!asoc->outqueue.out_qlen)
265 return true;
266
267 if (!str_nums)
268 return false;
269
270 for (i = 0; i < str_nums; i++) {
271 __u16 sid = ntohs(str_list[i]);
272
273 if (stream->out[sid].ext &&
274 !list_empty(&stream->out[sid].ext->outq))
275 return false;
276 }
277
278 return true;
279}
280
257int sctp_send_reset_streams(struct sctp_association *asoc, 281int sctp_send_reset_streams(struct sctp_association *asoc,
258 struct sctp_reset_streams *params) 282 struct sctp_reset_streams *params)
259{ 283{
@@ -317,6 +341,11 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
317 for (i = 0; i < str_nums; i++) 341 for (i = 0; i < str_nums; i++)
318 nstr_list[i] = htons(str_list[i]); 342 nstr_list[i] = htons(str_list[i]);
319 343
344 if (out && !sctp_stream_outq_is_empty(stream, str_nums, nstr_list)) {
345 retval = -EAGAIN;
346 goto out;
347 }
348
320 chunk = sctp_make_strreset_req(asoc, str_nums, nstr_list, out, in); 349 chunk = sctp_make_strreset_req(asoc, str_nums, nstr_list, out, in);
321 350
322 kfree(nstr_list); 351 kfree(nstr_list);
@@ -377,6 +406,9 @@ int sctp_send_reset_assoc(struct sctp_association *asoc)
377 if (asoc->strreset_outstanding) 406 if (asoc->strreset_outstanding)
378 return -EINPROGRESS; 407 return -EINPROGRESS;
379 408
409 if (!sctp_outq_is_empty(&asoc->outqueue))
410 return -EAGAIN;
411
380 chunk = sctp_make_strreset_tsnreq(asoc); 412 chunk = sctp_make_strreset_tsnreq(asoc);
381 if (!chunk) 413 if (!chunk)
382 return -ENOMEM; 414 return -ENOMEM;
@@ -563,7 +595,7 @@ struct sctp_chunk *sctp_process_strreset_outreq(
563 flags = SCTP_STREAM_RESET_INCOMING_SSN; 595 flags = SCTP_STREAM_RESET_INCOMING_SSN;
564 } 596 }
565 597
566 nums = (ntohs(param.p->length) - sizeof(*outreq)) / 2; 598 nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16);
567 if (nums) { 599 if (nums) {
568 str_p = outreq->list_of_streams; 600 str_p = outreq->list_of_streams;
569 for (i = 0; i < nums; i++) { 601 for (i = 0; i < nums; i++) {
@@ -627,7 +659,7 @@ struct sctp_chunk *sctp_process_strreset_inreq(
627 goto out; 659 goto out;
628 } 660 }
629 661
630 nums = (ntohs(param.p->length) - sizeof(*inreq)) / 2; 662 nums = (ntohs(param.p->length) - sizeof(*inreq)) / sizeof(__u16);
631 str_p = inreq->list_of_streams; 663 str_p = inreq->list_of_streams;
632 for (i = 0; i < nums; i++) { 664 for (i = 0; i < nums; i++) {
633 if (ntohs(str_p[i]) >= stream->outcnt) { 665 if (ntohs(str_p[i]) >= stream->outcnt) {
@@ -636,6 +668,12 @@ struct sctp_chunk *sctp_process_strreset_inreq(
636 } 668 }
637 } 669 }
638 670
671 if (!sctp_stream_outq_is_empty(stream, nums, str_p)) {
672 result = SCTP_STRRESET_IN_PROGRESS;
673 asoc->strreset_inseq--;
674 goto err;
675 }
676
639 chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0); 677 chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
640 if (!chunk) 678 if (!chunk)
641 goto out; 679 goto out;
@@ -687,12 +725,18 @@ struct sctp_chunk *sctp_process_strreset_tsnreq(
687 i = asoc->strreset_inseq - request_seq - 1; 725 i = asoc->strreset_inseq - request_seq - 1;
688 result = asoc->strreset_result[i]; 726 result = asoc->strreset_result[i];
689 if (result == SCTP_STRRESET_PERFORMED) { 727 if (result == SCTP_STRRESET_PERFORMED) {
690 next_tsn = asoc->next_tsn; 728 next_tsn = asoc->ctsn_ack_point + 1;
691 init_tsn = 729 init_tsn =
692 sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1; 730 sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1;
693 } 731 }
694 goto err; 732 goto err;
695 } 733 }
734
735 if (!sctp_outq_is_empty(&asoc->outqueue)) {
736 result = SCTP_STRRESET_IN_PROGRESS;
737 goto err;
738 }
739
696 asoc->strreset_inseq++; 740 asoc->strreset_inseq++;
697 741
698 if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ)) 742 if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ))
@@ -703,9 +747,10 @@ struct sctp_chunk *sctp_process_strreset_tsnreq(
703 goto out; 747 goto out;
704 } 748 }
705 749
706 /* G3: The same processing as though a SACK chunk with no gap report 750 /* G4: The same processing as though a FWD-TSN chunk (as defined in
707 * and a cumulative TSN ACK of the Sender's Next TSN minus 1 were 751 * [RFC3758]) with all streams affected and a new cumulative TSN
708 * received MUST be performed. 752 * ACK of the Receiver's Next TSN minus 1 were received MUST be
753 * performed.
709 */ 754 */
710 max_tsn_seen = sctp_tsnmap_get_max_tsn_seen(&asoc->peer.tsn_map); 755 max_tsn_seen = sctp_tsnmap_get_max_tsn_seen(&asoc->peer.tsn_map);
711 sctp_ulpq_reasm_flushtsn(&asoc->ulpq, max_tsn_seen); 756 sctp_ulpq_reasm_flushtsn(&asoc->ulpq, max_tsn_seen);
@@ -720,10 +765,9 @@ struct sctp_chunk *sctp_process_strreset_tsnreq(
720 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL, 765 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
721 init_tsn, GFP_ATOMIC); 766 init_tsn, GFP_ATOMIC);
722 767
723 /* G4: The same processing as though a FWD-TSN chunk (as defined in 768 /* G3: The same processing as though a SACK chunk with no gap report
724 * [RFC3758]) with all streams affected and a new cumulative TSN 769 * and a cumulative TSN ACK of the Sender's Next TSN minus 1 were
725 * ACK of the Receiver's Next TSN minus 1 were received MUST be 770 * received MUST be performed.
726 * performed.
727 */ 771 */
728 sctp_outq_free(&asoc->outqueue); 772 sctp_outq_free(&asoc->outqueue);
729 773
@@ -927,7 +971,8 @@ struct sctp_chunk *sctp_process_strreset_resp(
927 971
928 outreq = (struct sctp_strreset_outreq *)req; 972 outreq = (struct sctp_strreset_outreq *)req;
929 str_p = outreq->list_of_streams; 973 str_p = outreq->list_of_streams;
930 nums = (ntohs(outreq->param_hdr.length) - sizeof(*outreq)) / 2; 974 nums = (ntohs(outreq->param_hdr.length) - sizeof(*outreq)) /
975 sizeof(__u16);
931 976
932 if (result == SCTP_STRRESET_PERFORMED) { 977 if (result == SCTP_STRRESET_PERFORMED) {
933 if (nums) { 978 if (nums) {
@@ -956,7 +1001,8 @@ struct sctp_chunk *sctp_process_strreset_resp(
956 1001
957 inreq = (struct sctp_strreset_inreq *)req; 1002 inreq = (struct sctp_strreset_inreq *)req;
958 str_p = inreq->list_of_streams; 1003 str_p = inreq->list_of_streams;
959 nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) / 2; 1004 nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) /
1005 sizeof(__u16);
960 1006
961 *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags, 1007 *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
962 nums, str_p, GFP_ATOMIC); 1008 nums, str_p, GFP_ATOMIC);
@@ -975,6 +1021,7 @@ struct sctp_chunk *sctp_process_strreset_resp(
975 if (result == SCTP_STRRESET_PERFORMED) { 1021 if (result == SCTP_STRRESET_PERFORMED) {
976 __u32 mtsn = sctp_tsnmap_get_max_tsn_seen( 1022 __u32 mtsn = sctp_tsnmap_get_max_tsn_seen(
977 &asoc->peer.tsn_map); 1023 &asoc->peer.tsn_map);
1024 LIST_HEAD(temp);
978 1025
979 sctp_ulpq_reasm_flushtsn(&asoc->ulpq, mtsn); 1026 sctp_ulpq_reasm_flushtsn(&asoc->ulpq, mtsn);
980 sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC); 1027 sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC);
@@ -983,7 +1030,13 @@ struct sctp_chunk *sctp_process_strreset_resp(
983 SCTP_TSN_MAP_INITIAL, 1030 SCTP_TSN_MAP_INITIAL,
984 stsn, GFP_ATOMIC); 1031 stsn, GFP_ATOMIC);
985 1032
1033 /* Clean up sacked and abandoned queues only. As the
1034 * out_chunk_list may not be empty, splice it to temp,
1035 * then get it back after sctp_outq_free is done.
1036 */
1037 list_splice_init(&asoc->outqueue.out_chunk_list, &temp);
986 sctp_outq_free(&asoc->outqueue); 1038 sctp_outq_free(&asoc->outqueue);
1039 list_splice_init(&temp, &asoc->outqueue.out_chunk_list);
987 1040
988 asoc->next_tsn = rtsn; 1041 asoc->next_tsn = rtsn;
989 asoc->ctsn_ack_point = asoc->next_tsn - 1; 1042 asoc->ctsn_ack_point = asoc->next_tsn - 1;
diff --git a/net/sctp/stream_sched.c b/net/sctp/stream_sched.c
index 0b83ec51e43b..d8c162a4089c 100644
--- a/net/sctp/stream_sched.c
+++ b/net/sctp/stream_sched.c
@@ -119,16 +119,27 @@ static struct sctp_sched_ops sctp_sched_fcfs = {
119 .unsched_all = sctp_sched_fcfs_unsched_all, 119 .unsched_all = sctp_sched_fcfs_unsched_all,
120}; 120};
121 121
122static void sctp_sched_ops_fcfs_init(void)
123{
124 sctp_sched_ops_register(SCTP_SS_FCFS, &sctp_sched_fcfs);
125}
126
122/* API to other parts of the stack */ 127/* API to other parts of the stack */
123 128
124extern struct sctp_sched_ops sctp_sched_prio; 129static struct sctp_sched_ops *sctp_sched_ops[SCTP_SS_MAX + 1];
125extern struct sctp_sched_ops sctp_sched_rr;
126 130
127static struct sctp_sched_ops *sctp_sched_ops[] = { 131void sctp_sched_ops_register(enum sctp_sched_type sched,
128 &sctp_sched_fcfs, 132 struct sctp_sched_ops *sched_ops)
129 &sctp_sched_prio, 133{
130 &sctp_sched_rr, 134 sctp_sched_ops[sched] = sched_ops;
131}; 135}
136
137void sctp_sched_ops_init(void)
138{
139 sctp_sched_ops_fcfs_init();
140 sctp_sched_ops_prio_init();
141 sctp_sched_ops_rr_init();
142}
132 143
133int sctp_sched_set_sched(struct sctp_association *asoc, 144int sctp_sched_set_sched(struct sctp_association *asoc,
134 enum sctp_sched_type sched) 145 enum sctp_sched_type sched)
diff --git a/net/sctp/stream_sched_prio.c b/net/sctp/stream_sched_prio.c
index 384dbf3c8760..7997d35dd0fd 100644
--- a/net/sctp/stream_sched_prio.c
+++ b/net/sctp/stream_sched_prio.c
@@ -333,7 +333,7 @@ static void sctp_sched_prio_unsched_all(struct sctp_stream *stream)
333 sctp_sched_prio_unsched(soute); 333 sctp_sched_prio_unsched(soute);
334} 334}
335 335
336struct sctp_sched_ops sctp_sched_prio = { 336static struct sctp_sched_ops sctp_sched_prio = {
337 .set = sctp_sched_prio_set, 337 .set = sctp_sched_prio_set,
338 .get = sctp_sched_prio_get, 338 .get = sctp_sched_prio_get,
339 .init = sctp_sched_prio_init, 339 .init = sctp_sched_prio_init,
@@ -345,3 +345,8 @@ struct sctp_sched_ops sctp_sched_prio = {
345 .sched_all = sctp_sched_prio_sched_all, 345 .sched_all = sctp_sched_prio_sched_all,
346 .unsched_all = sctp_sched_prio_unsched_all, 346 .unsched_all = sctp_sched_prio_unsched_all,
347}; 347};
348
349void sctp_sched_ops_prio_init(void)
350{
351 sctp_sched_ops_register(SCTP_SS_PRIO, &sctp_sched_prio);
352}
diff --git a/net/sctp/stream_sched_rr.c b/net/sctp/stream_sched_rr.c
index 7612a438c5b9..1155692448f1 100644
--- a/net/sctp/stream_sched_rr.c
+++ b/net/sctp/stream_sched_rr.c
@@ -187,7 +187,7 @@ static void sctp_sched_rr_unsched_all(struct sctp_stream *stream)
187 sctp_sched_rr_unsched(stream, soute); 187 sctp_sched_rr_unsched(stream, soute);
188} 188}
189 189
190struct sctp_sched_ops sctp_sched_rr = { 190static struct sctp_sched_ops sctp_sched_rr = {
191 .set = sctp_sched_rr_set, 191 .set = sctp_sched_rr_set,
192 .get = sctp_sched_rr_get, 192 .get = sctp_sched_rr_get,
193 .init = sctp_sched_rr_init, 193 .init = sctp_sched_rr_init,
@@ -199,3 +199,8 @@ struct sctp_sched_ops sctp_sched_rr = {
199 .sched_all = sctp_sched_rr_sched_all, 199 .sched_all = sctp_sched_rr_sched_all,
200 .unsched_all = sctp_sched_rr_unsched_all, 200 .unsched_all = sctp_sched_rr_unsched_all,
201}; 201};
202
203void sctp_sched_ops_rr_init(void)
204{
205 sctp_sched_ops_register(SCTP_SS_RR, &sctp_sched_rr);
206}