hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/sctp/ulpqueue.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* SCTP kernel implementation
23 * (C) Copyright IBM Corp. 2001, 2004
34 * Copyright (c) 1999-2000 Cisco, Inc.
....@@ -7,22 +8,6 @@
78 * Copyright (c) 2001 La Monte H.P. Yarroll
89 *
910 * This abstraction carries sctp events to the ULP (sockets).
10
- *
11
- * This SCTP implementation is free software;
12
- * you can redistribute it and/or modify it under the terms of
13
- * the GNU General Public License as published by
14
- * the Free Software Foundation; either version 2, or (at your option)
15
- * any later version.
16
- *
17
- * This SCTP implementation is distributed in the hope that it
18
- * will be useful, but WITHOUT ANY WARRANTY; without even the implied
19
- * ************************
20
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21
- * See the GNU General Public License for more details.
22
- *
23
- * You should have received a copy of the GNU General Public License
24
- * along with GNU CC; see the file COPYING. If not, see
25
- * <http://www.gnu.org/licenses/>.
2611 *
2712 * Please send any bug reports or fixes you make to the
2813 * email address(es):
....@@ -116,12 +101,13 @@
116101 event = sctp_ulpq_reasm(ulpq, event);
117102
118103 /* Do ordering if needed. */
119
- if ((event) && (event->msg_flags & MSG_EOR)) {
104
+ if (event) {
120105 /* Create a temporary list to collect chunks on. */
121106 skb_queue_head_init(&temp);
122107 __skb_queue_tail(&temp, sctp_event2skb(event));
123108
124
- event = sctp_ulpq_order(ulpq, event);
109
+ if (event->msg_flags & MSG_EOR)
110
+ event = sctp_ulpq_order(ulpq, event);
125111 }
126112
127113 /* Send event to the ULP. 'event' is the sctp_ulpevent for
....@@ -129,7 +115,7 @@
129115 */
130116 if (event) {
131117 event_eor = (event->msg_flags & MSG_EOR) ? 1 : 0;
132
- sctp_ulpq_tail_event(ulpq, event);
118
+ sctp_ulpq_tail_event(ulpq, &temp);
133119 }
134120
135121 return event_eor;
....@@ -193,18 +179,17 @@
193179 return sctp_clear_pd(ulpq->asoc->base.sk, ulpq->asoc);
194180 }
195181
196
-/* If the SKB of 'event' is on a list, it is the first such member
197
- * of that list.
198
- */
199
-int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
182
+int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sk_buff_head *skb_list)
200183 {
201184 struct sock *sk = ulpq->asoc->base.sk;
202185 struct sctp_sock *sp = sctp_sk(sk);
203
- struct sk_buff_head *queue, *skb_list;
204
- struct sk_buff *skb = sctp_event2skb(event);
186
+ struct sctp_ulpevent *event;
187
+ struct sk_buff_head *queue;
188
+ struct sk_buff *skb;
205189 int clear_pd = 0;
206190
207
- skb_list = (struct sk_buff_head *) skb->prev;
191
+ skb = __skb_peek(skb_list);
192
+ event = sctp_skb2event(skb);
208193
209194 /* If the socket is just going to throw this away, do not
210195 * even try to deliver it.
....@@ -219,7 +204,7 @@
219204 sk_incoming_cpu_update(sk);
220205 }
221206 /* Check if the user wishes to receive this event. */
222
- if (!sctp_ulpevent_is_enabled(event, &sp->subscribe))
207
+ if (!sctp_ulpevent_is_enabled(event, ulpq->asoc->subscribe))
223208 goto out_free;
224209
225210 /* If we are in partial delivery mode, post to the lobby until
....@@ -257,13 +242,7 @@
257242 }
258243 }
259244
260
- /* If we are harvesting multiple skbs they will be
261
- * collected on a list.
262
- */
263
- if (skb_list)
264
- skb_queue_splice_tail_init(skb_list, queue);
265
- else
266
- __skb_queue_tail(queue, skb);
245
+ skb_queue_splice_tail_init(skb_list, queue);
267246
268247 /* Did we just complete partial delivery and need to get
269248 * rolling again? Move pending data to the receive
....@@ -459,7 +438,7 @@
459438 * element in the queue, then count it towards
460439 * possible PD.
461440 */
462
- if (pos == ulpq->reasm.next) {
441
+ if (skb_queue_is_first(&ulpq->reasm, pos)) {
463442 pd_first = pos;
464443 pd_last = pos;
465444 pd_len = pos->len;
....@@ -507,10 +486,9 @@
507486 cevent = sctp_skb2event(pd_first);
508487 pd_point = sctp_sk(asoc->base.sk)->pd_point;
509488 if (pd_point && pd_point <= pd_len) {
510
- retval = sctp_make_reassembled_event(sock_net(asoc->base.sk),
489
+ retval = sctp_make_reassembled_event(asoc->base.net,
511490 &ulpq->reasm,
512
- pd_first,
513
- pd_last);
491
+ pd_first, pd_last);
514492 if (retval)
515493 sctp_ulpq_set_pd(ulpq);
516494 }
....@@ -518,7 +496,7 @@
518496 done:
519497 return retval;
520498 found:
521
- retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
499
+ retval = sctp_make_reassembled_event(ulpq->asoc->base.net,
522500 &ulpq->reasm, first_frag, pos);
523501 if (retval)
524502 retval->msg_flags |= MSG_EOR;
....@@ -584,8 +562,8 @@
584562 * further.
585563 */
586564 done:
587
- retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
588
- &ulpq->reasm, first_frag, last_frag);
565
+ retval = sctp_make_reassembled_event(ulpq->asoc->base.net, &ulpq->reasm,
566
+ first_frag, last_frag);
589567 if (retval && is_last)
590568 retval->msg_flags |= MSG_EOR;
591569
....@@ -685,8 +663,8 @@
685663 * further.
686664 */
687665 done:
688
- retval = sctp_make_reassembled_event(sock_net(ulpq->asoc->base.sk),
689
- &ulpq->reasm, first_frag, last_frag);
666
+ retval = sctp_make_reassembled_event(ulpq->asoc->base.net, &ulpq->reasm,
667
+ first_frag, last_frag);
690668 return retval;
691669 }
692670
....@@ -738,31 +716,31 @@
738716 static void sctp_ulpq_reasm_drain(struct sctp_ulpq *ulpq)
739717 {
740718 struct sctp_ulpevent *event = NULL;
741
- struct sk_buff_head temp;
742719
743720 if (skb_queue_empty(&ulpq->reasm))
744721 return;
745722
746723 while ((event = sctp_ulpq_retrieve_reassembled(ulpq)) != NULL) {
747
- /* Do ordering if needed. */
748
- if ((event) && (event->msg_flags & MSG_EOR)) {
749
- skb_queue_head_init(&temp);
750
- __skb_queue_tail(&temp, sctp_event2skb(event));
724
+ struct sk_buff_head temp;
751725
726
+ skb_queue_head_init(&temp);
727
+ __skb_queue_tail(&temp, sctp_event2skb(event));
728
+
729
+ /* Do ordering if needed. */
730
+ if (event->msg_flags & MSG_EOR)
752731 event = sctp_ulpq_order(ulpq, event);
753
- }
754732
755733 /* Send event to the ULP. 'event' is the
756734 * sctp_ulpevent for very first SKB on the temp' list.
757735 */
758736 if (event)
759
- sctp_ulpq_tail_event(ulpq, event);
737
+ sctp_ulpq_tail_event(ulpq, &temp);
760738 }
761739 }
762740
763741
764742 /* Helper function to gather skbs that have possibly become
765
- * ordered by an an incoming chunk.
743
+ * ordered by an incoming chunk.
766744 */
767745 static void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
768746 struct sctp_ulpevent *event)
....@@ -956,7 +934,7 @@
956934 if (event) {
957935 /* see if we have more ordered that we can deliver */
958936 sctp_ulpq_retrieve_ordered(ulpq, event);
959
- sctp_ulpq_tail_event(ulpq, event);
937
+ sctp_ulpq_tail_event(ulpq, &temp);
960938 }
961939 }
962940
....@@ -1082,7 +1060,11 @@
10821060 event = sctp_ulpq_retrieve_first(ulpq);
10831061 /* Send event to the ULP. */
10841062 if (event) {
1085
- sctp_ulpq_tail_event(ulpq, event);
1063
+ struct sk_buff_head temp;
1064
+
1065
+ skb_queue_head_init(&temp);
1066
+ __skb_queue_tail(&temp, sctp_event2skb(event));
1067
+ sctp_ulpq_tail_event(ulpq, &temp);
10861068 sctp_ulpq_set_pd(ulpq);
10871069 return;
10881070 }
....@@ -1106,7 +1088,8 @@
11061088 freed += sctp_ulpq_renege_frags(ulpq, needed - freed);
11071089 }
11081090 /* If able to free enough room, accept this chunk. */
1109
- if (freed >= needed) {
1091
+ if (sk_rmem_schedule(asoc->base.sk, chunk->skb, needed) &&
1092
+ freed >= needed) {
11101093 int retval = sctp_ulpq_tail_data(ulpq, chunk, gfp);
11111094 /*
11121095 * Enter partial delivery if chunk has not been
....@@ -1129,16 +1112,16 @@
11291112 void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp)
11301113 {
11311114 struct sctp_ulpevent *ev = NULL;
1132
- struct sock *sk;
11331115 struct sctp_sock *sp;
1116
+ struct sock *sk;
11341117
11351118 if (!ulpq->pd_mode)
11361119 return;
11371120
11381121 sk = ulpq->asoc->base.sk;
11391122 sp = sctp_sk(sk);
1140
- if (sctp_ulpevent_type_enabled(SCTP_PARTIAL_DELIVERY_EVENT,
1141
- &sctp_sk(sk)->subscribe))
1123
+ if (sctp_ulpevent_type_enabled(ulpq->asoc->subscribe,
1124
+ SCTP_PARTIAL_DELIVERY_EVENT))
11421125 ev = sctp_ulpevent_make_pdapi(ulpq->asoc,
11431126 SCTP_PARTIAL_DELIVERY_ABORTED,
11441127 0, 0, 0, gfp);