1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <linux/slab.h>
45#include <linux/types.h>
46#include <linux/skbuff.h>
47#include <net/sock.h>
48#include <net/sctp/structs.h>
49#include <net/sctp/sctp.h>
50#include <net/sctp/sm.h>
51
52
53static struct sctp_ulpevent * sctp_ulpq_reasm(struct sctp_ulpq *ulpq,
54 struct sctp_ulpevent *);
55static struct sctp_ulpevent * sctp_ulpq_order(struct sctp_ulpq *,
56 struct sctp_ulpevent *);
57static void sctp_ulpq_reasm_drain(struct sctp_ulpq *ulpq);
58
59
60
61
62struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *ulpq,
63 struct sctp_association *asoc)
64{
65 memset(ulpq, 0, sizeof(struct sctp_ulpq));
66
67 ulpq->asoc = asoc;
68 skb_queue_head_init(&ulpq->reasm);
69 skb_queue_head_init(&ulpq->lobby);
70 ulpq->pd_mode = 0;
71 ulpq->malloced = 0;
72
73 return ulpq;
74}
75
76
77
78void sctp_ulpq_flush(struct sctp_ulpq *ulpq)
79{
80 struct sk_buff *skb;
81 struct sctp_ulpevent *event;
82
83 while ((skb = __skb_dequeue(&ulpq->lobby)) != NULL) {
84 event = sctp_skb2event(skb);
85 sctp_ulpevent_free(event);
86 }
87
88 while ((skb = __skb_dequeue(&ulpq->reasm)) != NULL) {
89 event = sctp_skb2event(skb);
90 sctp_ulpevent_free(event);
91 }
92
93}
94
95
96void sctp_ulpq_free(struct sctp_ulpq *ulpq)
97{
98 sctp_ulpq_flush(ulpq);
99 if (ulpq->malloced)
100 kfree(ulpq);
101}
102
103
104int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
105 gfp_t gfp)
106{
107 struct sk_buff_head temp;
108 struct sctp_ulpevent *event;
109
110
111 event = sctp_ulpevent_make_rcvmsg(chunk->asoc, chunk, gfp);
112 if (!event)
113 return -ENOMEM;
114
115
116 event = sctp_ulpq_reasm(ulpq, event);
117
118
119 if ((event) && (event->msg_flags & MSG_EOR)){
120
121 skb_queue_head_init(&temp);
122 __skb_queue_tail(&temp, sctp_event2skb(event));
123
124 event = sctp_ulpq_order(ulpq, event);
125 }
126
127
128
129
130 if (event)
131 sctp_ulpq_tail_event(ulpq, event);
132
133 return 0;
134}
135
136
137
138
139
140int sctp_clear_pd(struct sock *sk, struct sctp_association *asoc)
141{
142 struct sctp_sock *sp = sctp_sk(sk);
143
144 if (atomic_dec_and_test(&sp->pd_mode)) {
145
146
147
148 if (!skb_queue_empty(&sp->pd_lobby)) {
149 struct list_head *list;
150 sctp_skb_list_tail(&sp->pd_lobby, &sk->sk_receive_queue);
151 list = (struct list_head *)&sctp_sk(sk)->pd_lobby;
152 INIT_LIST_HEAD(list);
153 return 1;
154 }
155 } else {
156
157
158
159
160
161 if (!skb_queue_empty(&sp->pd_lobby) && asoc) {
162 struct sk_buff *skb, *tmp;
163 struct sctp_ulpevent *event;
164
165 sctp_skb_for_each(skb, &sp->pd_lobby, tmp) {
166 event = sctp_skb2event(skb);
167 if (event->asoc == asoc) {
168 __skb_unlink(skb, &sp->pd_lobby);
169 __skb_queue_tail(&sk->sk_receive_queue,
170 skb);
171 }
172 }
173 }
174 }
175
176 return 0;
177}
178
179
180static void sctp_ulpq_set_pd(struct sctp_ulpq *ulpq)
181{
182 struct sctp_sock *sp = sctp_sk(ulpq->asoc->base.sk);
183
184 atomic_inc(&sp->pd_mode);
185 ulpq->pd_mode = 1;
186}
187
188
189static int sctp_ulpq_clear_pd(struct sctp_ulpq *ulpq)
190{
191 ulpq->pd_mode = 0;
192 sctp_ulpq_reasm_drain(ulpq);
193 return sctp_clear_pd(ulpq->asoc->base.sk, ulpq->asoc);
194}
195
196
197
198
199int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
200{
201 struct sock *sk = ulpq->asoc->base.sk;
202 struct sk_buff_head *queue, *skb_list;
203 struct sk_buff *skb = sctp_event2skb(event);
204 int clear_pd = 0;
205
206 skb_list = (struct sk_buff_head *) skb->prev;
207
208
209
210
211 if (sock_flag(sk, SOCK_DEAD) || (sk->sk_shutdown & RCV_SHUTDOWN))
212 goto out_free;
213
214
215 if (!sctp_ulpevent_is_enabled(event, &sctp_sk(sk)->subscribe))
216 goto out_free;
217
218
219
220
221
222
223 if (atomic_read(&sctp_sk(sk)->pd_mode) == 0) {
224 queue = &sk->sk_receive_queue;
225 } else {
226 if (ulpq->pd_mode) {
227
228
229
230
231
232 if ((event->msg_flags & MSG_NOTIFICATION) ||
233 (SCTP_DATA_NOT_FRAG ==
234 (event->msg_flags & SCTP_DATA_FRAG_MASK)))
235 queue = &sctp_sk(sk)->pd_lobby;
236 else {
237 clear_pd = event->msg_flags & MSG_EOR;
238 queue = &sk->sk_receive_queue;
239 }
240 } else {
241
242
243
244
245
246 if (sctp_sk(sk)->frag_interleave)
247 queue = &sk->sk_receive_queue;
248 else
249 queue = &sctp_sk(sk)->pd_lobby;
250 }
251 }
252
253
254
255
256 if (skb_list)
257 sctp_skb_list_tail(skb_list, queue);
258 else
259 __skb_queue_tail(queue, skb);
260
261
262
263
264
265 if (clear_pd)
266 sctp_ulpq_clear_pd(ulpq);
267
268 if (queue == &sk->sk_receive_queue)
269 sk->sk_data_ready(sk, 0);
270 return 1;
271
272out_free:
273 if (skb_list)
274 sctp_queue_purge_ulpevents(skb_list);
275 else
276 sctp_ulpevent_free(event);
277
278 return 0;
279}
280
281
282
283
284static void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq,
285 struct sctp_ulpevent *event)
286{
287 struct sk_buff *pos;
288 struct sctp_ulpevent *cevent;
289 __u32 tsn, ctsn;
290
291 tsn = event->tsn;
292
293
294 pos = skb_peek_tail(&ulpq->reasm);
295 if (!pos) {
296 __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event));
297 return;
298 }
299
300
301 cevent = sctp_skb2event(pos);
302 ctsn = cevent->tsn;
303 if (TSN_lt(ctsn, tsn)) {
304 __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event));
305 return;
306 }
307
308
309 skb_queue_walk(&ulpq->reasm, pos) {
310 cevent = sctp_skb2event(pos);
311 ctsn = cevent->tsn;
312
313 if (TSN_lt(tsn, ctsn))
314 break;
315 }
316
317
318 __skb_queue_before(&ulpq->reasm, pos, sctp_event2skb(event));
319
320}
321
322
323
324
325
326
327
328
329static struct sctp_ulpevent *sctp_make_reassembled_event(struct net *net,
330 struct sk_buff_head *queue, struct sk_buff *f_frag,
331 struct sk_buff *l_frag)
332{
333 struct sk_buff *pos;
334 struct sk_buff *new = NULL;
335 struct sctp_ulpevent *event;
336 struct sk_buff *pnext, *last;
337 struct sk_buff *list = skb_shinfo(f_frag)->frag_list;
338
339
340 if (f_frag == l_frag)
341 pos = NULL;
342 else
343 pos = f_frag->next;
344
345
346 for (last = list; list; last = list, list = list->next);
347
348
349
350
351 if (last)
352 last->next = pos;
353 else {
354 if (skb_cloned(f_frag)) {
355
356
357
358
359
360 new = skb_copy(f_frag, GFP_ATOMIC);
361 if (!new)
362 return NULL;
363
364 sctp_skb_set_owner_r(new, f_frag->sk);
365
366 skb_shinfo(new)->frag_list = pos;
367 } else
368 skb_shinfo(f_frag)->frag_list = pos;
369 }
370
371
372 __skb_unlink(f_frag, queue);
373
374
375 if (new) {
376 kfree_skb(f_frag);
377 f_frag = new;
378 }
379
380 while (pos) {
381
382 pnext = pos->next;
383
384
385 f_frag->len += pos->len;
386 f_frag->data_len += pos->len;
387
388
389 __skb_unlink(pos, queue);
390
391
392 if (pos == l_frag)
393 break;
394 pos->next = pnext;
395 pos = pnext;
396 }
397
398 event = sctp_skb2event(f_frag);
399 SCTP_INC_STATS(net, SCTP_MIB_REASMUSRMSGS);
400
401 return event;
402}
403
404
405
406
407
408static struct sctp_ulpevent *sctp_ulpq_retrieve_reassembled(struct sctp_ulpq *ulpq)
409{
410 struct sk_buff *pos;
411 struct sctp_ulpevent *cevent;
412 struct sk_buff *first_frag = NULL;
413 __u32 ctsn, next_tsn;
414 struct sctp_ulpevent *retval = NULL;
415 struct sk_buff *pd_first = NULL;
416 struct sk_buff *pd_last = NULL;
417 size_t pd_len = 0;
418 struct sctp_association *asoc;
419 u32 pd_point;
420
421
422
423
424
425 next_tsn = 0;
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440 skb_queue_walk(&ulpq->reasm, pos) {
441 cevent = sctp_skb2event(pos);
442 ctsn = cevent->tsn;
443
444 switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
445 case SCTP_DATA_FIRST_FRAG:
446
447
448
449
450 if (pos == ulpq->reasm.next) {
451 pd_first = pos;
452 pd_last = pos;
453 pd_len = pos->len;
454 } else {
455 pd_first = NULL;
456 pd_last = NULL;
457 pd_len = 0;
458 }
459
460 first_frag = pos;
461 next_tsn = ctsn + 1;
462 break;
463
464 case SCTP_DATA_MIDDLE_FRAG:
465 if ((first_frag) && (ctsn == next_tsn)) {
466 next_tsn++;
467 if (pd_first) {
468 pd_last = pos;
469 pd_len += pos->len;
470 }
471 } else
472 first_frag = NULL;
473 break;
474
475 case SCTP_DATA_LAST_FRAG:
476 if (first_frag && (ctsn == next_tsn))
477 goto found;
478 else
479 first_frag = NULL;
480 break;
481 }
482 }
483
484 asoc = ulpq->asoc;
485 if (pd_first) {
486
487
488
489
490
491 if (!sctp_sk(asoc->base.sk)->frag_interleave &&
492 atomic_read(&sctp_sk(asoc->base.sk)->pd_mode))
493 goto done;
494
495 cevent = sctp_skb2event(pd_first);
496 pd_point = sctp_sk(asoc->base.sk)->pd_point;
497 if (pd_point && pd_point <= pd_len) {
498 retval = sctp_make_reassembled_event(sock_net(asoc->base.sk),
499 &ulpq->reasm,
500 pd_first,
501 pd_last);
502 if (retval)
503 sctp_ulpq_set_pd(ulpq);
504 }
505 }
506done:
507 return retval;
508found:
509 retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
510 &ulpq->reasm, first_frag, pos);
511 if (retval)
512 retval->msg_flags |= MSG_EOR;
513 goto done;
514}
515
516
517static struct sctp_ulpevent *sctp_ulpq_retrieve_partial(struct sctp_ulpq *ulpq)
518{
519 struct sk_buff *pos, *last_frag, *first_frag;
520 struct sctp_ulpevent *cevent;
521 __u32 ctsn, next_tsn;
522 int is_last;
523 struct sctp_ulpevent *retval;
524
525
526
527
528
529
530 if (skb_queue_empty(&ulpq->reasm))
531 return NULL;
532
533 last_frag = first_frag = NULL;
534 retval = NULL;
535 next_tsn = 0;
536 is_last = 0;
537
538 skb_queue_walk(&ulpq->reasm, pos) {
539 cevent = sctp_skb2event(pos);
540 ctsn = cevent->tsn;
541
542 switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
543 case SCTP_DATA_MIDDLE_FRAG:
544 if (!first_frag) {
545 first_frag = pos;
546 next_tsn = ctsn + 1;
547 last_frag = pos;
548 } else if (next_tsn == ctsn)
549 next_tsn++;
550 else
551 goto done;
552 break;
553 case SCTP_DATA_LAST_FRAG:
554 if (!first_frag)
555 first_frag = pos;
556 else if (ctsn != next_tsn)
557 goto done;
558 last_frag = pos;
559 is_last = 1;
560 goto done;
561 default:
562 return NULL;
563 }
564 }
565
566
567
568
569done:
570 retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
571 &ulpq->reasm, first_frag, last_frag);
572 if (retval && is_last)
573 retval->msg_flags |= MSG_EOR;
574
575 return retval;
576}
577
578
579
580
581
582static struct sctp_ulpevent *sctp_ulpq_reasm(struct sctp_ulpq *ulpq,
583 struct sctp_ulpevent *event)
584{
585 struct sctp_ulpevent *retval = NULL;
586
587
588 if (SCTP_DATA_NOT_FRAG == (event->msg_flags & SCTP_DATA_FRAG_MASK)) {
589 event->msg_flags |= MSG_EOR;
590 return event;
591 }
592
593 sctp_ulpq_store_reasm(ulpq, event);
594 if (!ulpq->pd_mode)
595 retval = sctp_ulpq_retrieve_reassembled(ulpq);
596 else {
597 __u32 ctsn, ctsnap;
598
599
600
601
602 ctsn = event->tsn;
603 ctsnap = sctp_tsnmap_get_ctsn(&ulpq->asoc->peer.tsn_map);
604 if (TSN_lte(ctsn, ctsnap))
605 retval = sctp_ulpq_retrieve_partial(ulpq);
606 }
607
608 return retval;
609}
610
611
612static struct sctp_ulpevent *sctp_ulpq_retrieve_first(struct sctp_ulpq *ulpq)
613{
614 struct sk_buff *pos, *last_frag, *first_frag;
615 struct sctp_ulpevent *cevent;
616 __u32 ctsn, next_tsn;
617 struct sctp_ulpevent *retval;
618
619
620
621
622
623
624 if (skb_queue_empty(&ulpq->reasm))
625 return NULL;
626
627 last_frag = first_frag = NULL;
628 retval = NULL;
629 next_tsn = 0;
630
631 skb_queue_walk(&ulpq->reasm, pos) {
632 cevent = sctp_skb2event(pos);
633 ctsn = cevent->tsn;
634
635 switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
636 case SCTP_DATA_FIRST_FRAG:
637 if (!first_frag) {
638 first_frag = pos;
639 next_tsn = ctsn + 1;
640 last_frag = pos;
641 } else
642 goto done;
643 break;
644
645 case SCTP_DATA_MIDDLE_FRAG:
646 if (!first_frag)
647 return NULL;
648 if (ctsn == next_tsn) {
649 next_tsn++;
650 last_frag = pos;
651 } else
652 goto done;
653 break;
654 default:
655 return NULL;
656 }
657 }
658
659
660
661
662done:
663 retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
664 &ulpq->reasm, first_frag, last_frag);
665 return retval;
666}
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682void sctp_ulpq_reasm_flushtsn(struct sctp_ulpq *ulpq, __u32 fwd_tsn)
683{
684 struct sk_buff *pos, *tmp;
685 struct sctp_ulpevent *event;
686 __u32 tsn;
687
688 if (skb_queue_empty(&ulpq->reasm))
689 return;
690
691 skb_queue_walk_safe(&ulpq->reasm, pos, tmp) {
692 event = sctp_skb2event(pos);
693 tsn = event->tsn;
694
695
696
697
698
699
700 if (TSN_lte(tsn, fwd_tsn)) {
701 __skb_unlink(pos, &ulpq->reasm);
702 sctp_ulpevent_free(event);
703 } else
704 break;
705 }
706}
707
708
709
710
711
712
713static void sctp_ulpq_reasm_drain(struct sctp_ulpq *ulpq)
714{
715 struct sctp_ulpevent *event = NULL;
716 struct sk_buff_head temp;
717
718 if (skb_queue_empty(&ulpq->reasm))
719 return;
720
721 while ((event = sctp_ulpq_retrieve_reassembled(ulpq)) != NULL) {
722
723 if ((event) && (event->msg_flags & MSG_EOR)){
724 skb_queue_head_init(&temp);
725 __skb_queue_tail(&temp, sctp_event2skb(event));
726
727 event = sctp_ulpq_order(ulpq, event);
728 }
729
730
731
732
733 if (event)
734 sctp_ulpq_tail_event(ulpq, event);
735 }
736}
737
738
739
740
741
742static void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
743 struct sctp_ulpevent *event)
744{
745 struct sk_buff_head *event_list;
746 struct sk_buff *pos, *tmp;
747 struct sctp_ulpevent *cevent;
748 struct sctp_stream *in;
749 __u16 sid, csid, cssn;
750
751 sid = event->stream;
752 in = &ulpq->asoc->ssnmap->in;
753
754 event_list = (struct sk_buff_head *) sctp_event2skb(event)->prev;
755
756
757 sctp_skb_for_each(pos, &ulpq->lobby, tmp) {
758 cevent = (struct sctp_ulpevent *) pos->cb;
759 csid = cevent->stream;
760 cssn = cevent->ssn;
761
762
763 if (csid > sid)
764 break;
765
766
767 if (csid < sid)
768 continue;
769
770 if (cssn != sctp_ssn_peek(in, sid))
771 break;
772
773
774 sctp_ssn_next(in, sid);
775
776 __skb_unlink(pos, &ulpq->lobby);
777
778
779 __skb_queue_tail(event_list, pos);
780 }
781}
782
783
784static void sctp_ulpq_store_ordered(struct sctp_ulpq *ulpq,
785 struct sctp_ulpevent *event)
786{
787 struct sk_buff *pos;
788 struct sctp_ulpevent *cevent;
789 __u16 sid, csid;
790 __u16 ssn, cssn;
791
792 pos = skb_peek_tail(&ulpq->lobby);
793 if (!pos) {
794 __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event));
795 return;
796 }
797
798 sid = event->stream;
799 ssn = event->ssn;
800
801 cevent = (struct sctp_ulpevent *) pos->cb;
802 csid = cevent->stream;
803 cssn = cevent->ssn;
804 if (sid > csid) {
805 __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event));
806 return;
807 }
808
809 if ((sid == csid) && SSN_lt(cssn, ssn)) {
810 __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event));
811 return;
812 }
813
814
815
816
817 skb_queue_walk(&ulpq->lobby, pos) {
818 cevent = (struct sctp_ulpevent *) pos->cb;
819 csid = cevent->stream;
820 cssn = cevent->ssn;
821
822 if (csid > sid)
823 break;
824 if (csid == sid && SSN_lt(ssn, cssn))
825 break;
826 }
827
828
829
830 __skb_queue_before(&ulpq->lobby, pos, sctp_event2skb(event));
831}
832
833static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
834 struct sctp_ulpevent *event)
835{
836 __u16 sid, ssn;
837 struct sctp_stream *in;
838
839
840 if (SCTP_DATA_UNORDERED & event->msg_flags)
841 return event;
842
843
844 sid = event->stream;
845 ssn = event->ssn;
846 in = &ulpq->asoc->ssnmap->in;
847
848
849 if (ssn != sctp_ssn_peek(in, sid)) {
850
851
852
853 sctp_ulpq_store_ordered(ulpq, event);
854 return NULL;
855 }
856
857
858 sctp_ssn_next(in, sid);
859
860
861
862
863 sctp_ulpq_retrieve_ordered(ulpq, event);
864
865 return event;
866}
867
868
869
870
871static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
872{
873 struct sk_buff *pos, *tmp;
874 struct sctp_ulpevent *cevent;
875 struct sctp_ulpevent *event;
876 struct sctp_stream *in;
877 struct sk_buff_head temp;
878 struct sk_buff_head *lobby = &ulpq->lobby;
879 __u16 csid, cssn;
880
881 in = &ulpq->asoc->ssnmap->in;
882
883
884 skb_queue_head_init(&temp);
885 event = NULL;
886 sctp_skb_for_each(pos, lobby, tmp) {
887 cevent = (struct sctp_ulpevent *) pos->cb;
888 csid = cevent->stream;
889 cssn = cevent->ssn;
890
891
892 if (csid > sid)
893 break;
894
895
896 if (csid < sid)
897 continue;
898
899
900 if (!SSN_lt(cssn, sctp_ssn_peek(in, csid)))
901 break;
902
903 __skb_unlink(pos, lobby);
904 if (!event)
905
906 event = sctp_skb2event(pos);
907
908
909 __skb_queue_tail(&temp, pos);
910 }
911
912
913
914
915 if (event == NULL && pos != (struct sk_buff *)lobby) {
916 cevent = (struct sctp_ulpevent *) pos->cb;
917 csid = cevent->stream;
918 cssn = cevent->ssn;
919
920 if (csid == sid && cssn == sctp_ssn_peek(in, csid)) {
921 sctp_ssn_next(in, csid);
922 __skb_unlink(pos, lobby);
923 __skb_queue_tail(&temp, pos);
924 event = sctp_skb2event(pos);
925 }
926 }
927
928
929
930
931 if (event) {
932
933 sctp_ulpq_retrieve_ordered(ulpq, event);
934 sctp_ulpq_tail_event(ulpq, event);
935 }
936}
937
938
939
940
941void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn)
942{
943 struct sctp_stream *in;
944
945
946 in = &ulpq->asoc->ssnmap->in;
947
948
949 if (SSN_lt(ssn, sctp_ssn_peek(in, sid)))
950 return;
951
952
953 sctp_ssn_skip(in, sid, ssn);
954
955
956
957
958 sctp_ulpq_reap_ordered(ulpq, sid);
959}
960
961static __u16 sctp_ulpq_renege_list(struct sctp_ulpq *ulpq,
962 struct sk_buff_head *list, __u16 needed)
963{
964 __u16 freed = 0;
965 __u32 tsn;
966 struct sk_buff *skb;
967 struct sctp_ulpevent *event;
968 struct sctp_tsnmap *tsnmap;
969
970 tsnmap = &ulpq->asoc->peer.tsn_map;
971
972 while ((skb = __skb_dequeue_tail(list)) != NULL) {
973 freed += skb_headlen(skb);
974 event = sctp_skb2event(skb);
975 tsn = event->tsn;
976
977 sctp_ulpevent_free(event);
978 sctp_tsnmap_renege(tsnmap, tsn);
979 if (freed >= needed)
980 return freed;
981 }
982
983 return freed;
984}
985
986
987static __u16 sctp_ulpq_renege_order(struct sctp_ulpq *ulpq, __u16 needed)
988{
989 return sctp_ulpq_renege_list(ulpq, &ulpq->lobby, needed);
990}
991
992
993static __u16 sctp_ulpq_renege_frags(struct sctp_ulpq *ulpq, __u16 needed)
994{
995 return sctp_ulpq_renege_list(ulpq, &ulpq->reasm, needed);
996}
997
998
999void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq,
1000 struct sctp_chunk *chunk,
1001 gfp_t gfp)
1002{
1003 struct sctp_ulpevent *event;
1004 struct sctp_association *asoc;
1005 struct sctp_sock *sp;
1006
1007 asoc = ulpq->asoc;
1008 sp = sctp_sk(asoc->base.sk);
1009
1010
1011
1012
1013 if (ulpq->pd_mode)
1014 return;
1015
1016
1017
1018
1019
1020
1021 if (sp->frag_interleave || atomic_read(&sp->pd_mode) == 0) {
1022
1023 event = sctp_ulpq_retrieve_first(ulpq);
1024
1025 if (event) {
1026 sctp_ulpq_tail_event(ulpq, event);
1027 sctp_ulpq_set_pd(ulpq);
1028 return;
1029 }
1030 }
1031}
1032
1033
1034void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
1035 gfp_t gfp)
1036{
1037 struct sctp_association *asoc;
1038 __u16 needed, freed;
1039
1040 asoc = ulpq->asoc;
1041
1042 if (chunk) {
1043 needed = ntohs(chunk->chunk_hdr->length);
1044 needed -= sizeof(sctp_data_chunk_t);
1045 } else
1046 needed = SCTP_DEFAULT_MAXWINDOW;
1047
1048 freed = 0;
1049
1050 if (skb_queue_empty(&asoc->base.sk->sk_receive_queue)) {
1051 freed = sctp_ulpq_renege_order(ulpq, needed);
1052 if (freed < needed) {
1053 freed += sctp_ulpq_renege_frags(ulpq, needed - freed);
1054 }
1055 }
1056
1057 if (chunk && (freed >= needed)) {
1058 __u32 tsn;
1059 tsn = ntohl(chunk->subh.data_hdr->tsn);
1060 sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport);
1061 sctp_ulpq_tail_data(ulpq, chunk, gfp);
1062
1063 sctp_ulpq_partial_delivery(ulpq, chunk, gfp);
1064 }
1065
1066 sk_mem_reclaim(asoc->base.sk);
1067}
1068
1069
1070
1071
1072
1073
1074void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp)
1075{
1076 struct sctp_ulpevent *ev = NULL;
1077 struct sock *sk;
1078
1079 if (!ulpq->pd_mode)
1080 return;
1081
1082 sk = ulpq->asoc->base.sk;
1083 if (sctp_ulpevent_type_enabled(SCTP_PARTIAL_DELIVERY_EVENT,
1084 &sctp_sk(sk)->subscribe))
1085 ev = sctp_ulpevent_make_pdapi(ulpq->asoc,
1086 SCTP_PARTIAL_DELIVERY_ABORTED,
1087 gfp);
1088 if (ev)
1089 __skb_queue_tail(&sk->sk_receive_queue, sctp_event2skb(ev));
1090
1091
1092 if (sctp_ulpq_clear_pd(ulpq) || ev)
1093 sk->sk_data_ready(sk, 0);
1094}
1095