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