1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* SCTP kernel implementation
3 * Copyright (c) 1999-2000 Cisco, Inc.
4 * Copyright (c) 1999-2001 Motorola, Inc.
5 * Copyright (c) 2002 International Business Machines, Corp.
6 *
7 * This file is part of the SCTP kernel implementation
8 *
9 * These functions are the methods for accessing the SCTP inqueue.
10 *
11 * An SCTP inqueue is a queue into which you push SCTP packets
12 * (which might be bundles or fragments of chunks) and out of which you
13 * pop SCTP whole chunks.
14 *
15 * Please send any bug reports or fixes you make to the
16 * email address(es):
17 * lksctp developers <linux-sctp@vger.kernel.org>
18 *
19 * Written or modified by:
20 * La Monte H.P. Yarroll <piggy@acm.org>
21 * Karl Knutson <karl@athena.chicago.il.us>
22 */
23
24 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26 #include <net/sctp/sctp.h>
27 #include <net/sctp/sm.h>
28 #include <linux/interrupt.h>
29 #include <linux/slab.h>
30
31 /* Initialize an SCTP inqueue. */
sctp_inq_init(struct sctp_inq * queue)32 void sctp_inq_init(struct sctp_inq *queue)
33 {
34 INIT_LIST_HEAD(&queue->in_chunk_list);
35 queue->in_progress = NULL;
36
37 /* Create a task for delivering data. */
38 INIT_WORK(&queue->immediate, NULL);
39 }
40
41 /* Properly release the chunk which is being worked on. */
sctp_inq_chunk_free(struct sctp_chunk * chunk)42 static inline void sctp_inq_chunk_free(struct sctp_chunk *chunk)
43 {
44 if (chunk->head_skb)
45 chunk->skb = chunk->head_skb;
46 sctp_chunk_free(chunk);
47 }
48
49 /* Release the memory associated with an SCTP inqueue. */
sctp_inq_free(struct sctp_inq * queue)50 void sctp_inq_free(struct sctp_inq *queue)
51 {
52 struct sctp_chunk *chunk, *tmp;
53
54 /* Empty the queue. */
55 list_for_each_entry_safe(chunk, tmp, &queue->in_chunk_list, list) {
56 list_del_init(&chunk->list);
57 sctp_chunk_free(chunk);
58 }
59
60 /* If there is a packet which is currently being worked on,
61 * free it as well.
62 */
63 if (queue->in_progress) {
64 sctp_inq_chunk_free(queue->in_progress);
65 queue->in_progress = NULL;
66 }
67 }
68
69 /* Put a new packet in an SCTP inqueue.
70 * We assume that packet->sctp_hdr is set and in host byte order.
71 */
sctp_inq_push(struct sctp_inq * q,struct sctp_chunk * chunk)72 void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *chunk)
73 {
74 /* Directly call the packet handling routine. Drop the chunk if the
75 * receiver or the transport it was looked up on is gone.
76 */
77 if (chunk->rcvr->dead ||
78 (chunk->transport && chunk->transport->dead)) {
79 sctp_chunk_free(chunk);
80 return;
81 }
82
83 /* We are now calling this either from the soft interrupt
84 * or from the backlog processing.
85 * Eventually, we should clean up inqueue to not rely
86 * on the BH related data structures.
87 */
88 list_add_tail(&chunk->list, &q->in_chunk_list);
89 if (chunk->asoc)
90 chunk->asoc->stats.ipackets++;
91 q->immediate.func(&q->immediate);
92 }
93
94 /* Peek at the next chunk on the inqeue. */
sctp_inq_peek(struct sctp_inq * queue)95 struct sctp_chunkhdr *sctp_inq_peek(struct sctp_inq *queue)
96 {
97 struct sctp_chunk *chunk;
98 struct sctp_chunkhdr *ch = NULL;
99
100 chunk = queue->in_progress;
101 /* If there is no more chunks in this packet, say so */
102 if (chunk->singleton ||
103 chunk->end_of_packet ||
104 chunk->pdiscard)
105 return NULL;
106
107 ch = (struct sctp_chunkhdr *)chunk->chunk_end;
108
109 return ch;
110 }
111
112
113 /* Extract a chunk from an SCTP inqueue.
114 *
115 * WARNING: If you need to put the chunk on another queue, you need to
116 * make a shallow copy (clone) of it.
117 */
sctp_inq_pop(struct sctp_inq * queue)118 struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
119 {
120 struct sctp_chunk *chunk;
121 struct sctp_chunkhdr *ch = NULL;
122
123 /* The assumption is that we are safe to process the chunks
124 * at this time.
125 */
126
127 chunk = queue->in_progress;
128 if (chunk) {
129 /* There is a packet that we have been working on.
130 * Any post processing work to do before we move on?
131 */
132 if (chunk->singleton ||
133 chunk->end_of_packet ||
134 chunk->pdiscard) {
135 if (chunk->head_skb == chunk->skb) {
136 chunk->skb = skb_shinfo(chunk->skb)->frag_list;
137 goto new_skb;
138 }
139 if (chunk->skb->next) {
140 chunk->skb = chunk->skb->next;
141 goto new_skb;
142 }
143
144 sctp_inq_chunk_free(chunk);
145 chunk = queue->in_progress = NULL;
146 } else {
147 /* Nothing to do. Next chunk in the packet, please. */
148 ch = (struct sctp_chunkhdr *)chunk->chunk_end;
149 /* Force chunk->skb->data to chunk->chunk_end. */
150 skb_pull(chunk->skb, chunk->chunk_end - chunk->skb->data);
151 /* We are guaranteed to pull a SCTP header. */
152 }
153 }
154
155 /* Do we need to take the next packet out of the queue to process? */
156 if (!chunk) {
157 struct list_head *entry;
158
159 next_chunk:
160 /* Is the queue empty? */
161 entry = sctp_list_dequeue(&queue->in_chunk_list);
162 if (!entry)
163 return NULL;
164
165 chunk = list_entry(entry, struct sctp_chunk, list);
166
167 if (skb_is_gso(chunk->skb) && skb_is_gso_sctp(chunk->skb)) {
168 /* GSO-marked skbs but without frags, handle
169 * them normally
170 */
171 if (skb_shinfo(chunk->skb)->frag_list)
172 chunk->head_skb = chunk->skb;
173
174 /* skbs with "cover letter" */
175 if (chunk->head_skb && chunk->skb->data_len == chunk->skb->len) {
176 if (WARN_ON(!skb_shinfo(chunk->skb)->frag_list)) {
177 __SCTP_INC_STATS(dev_net(chunk->skb->dev),
178 SCTP_MIB_IN_PKT_DISCARDS);
179 sctp_chunk_free(chunk);
180 goto next_chunk;
181 }
182 chunk->skb = skb_shinfo(chunk->skb)->frag_list;
183 }
184 }
185
186 if (chunk->asoc)
187 sock_rps_save_rxhash(chunk->asoc->base.sk, chunk->skb);
188
189 queue->in_progress = chunk;
190
191 new_skb:
192 /* This is the first chunk in the packet. */
193 ch = (struct sctp_chunkhdr *)chunk->skb->data;
194 chunk->singleton = 1;
195 chunk->data_accepted = 0;
196 chunk->pdiscard = 0;
197 chunk->auth = 0;
198 chunk->has_asconf = 0;
199 chunk->end_of_packet = 0;
200 if (chunk->head_skb) {
201 struct sctp_input_cb
202 *cb = SCTP_INPUT_CB(chunk->skb),
203 *head_cb = SCTP_INPUT_CB(chunk->head_skb);
204
205 cb->chunk = head_cb->chunk;
206 cb->af = head_cb->af;
207 cb->encap_port = head_cb->encap_port;
208 }
209 }
210
211 chunk->chunk_hdr = ch;
212 chunk->chunk_end = ((__u8 *)ch) + SCTP_PAD4(ntohs(ch->length));
213 skb_pull(chunk->skb, sizeof(*ch));
214 chunk->subh.v = NULL; /* Subheader is no longer valid. */
215 if (unlikely(ntohs(ch->length) < sizeof(*ch))) {
216 chunk->pdiscard = 1;
217 } else if (chunk->chunk_end + sizeof(*ch) <=
218 skb_tail_pointer(chunk->skb)) {
219 /* This is not a singleton */
220 chunk->singleton = 0;
221 } else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) {
222 /* Discard inside state machine. */
223 chunk->pdiscard = 1;
224 chunk->chunk_end = skb_tail_pointer(chunk->skb);
225 } else {
226 /* We are at the end of the packet, so mark the chunk
227 * in case we need to send a SACK.
228 */
229 chunk->end_of_packet = 1;
230 }
231
232 pr_debug("+++sctp_inq_pop+++ chunk:%p[%s], length:%d, skb->len:%d\n",
233 chunk, sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)),
234 ntohs(chunk->chunk_hdr->length), chunk->skb->len);
235
236 return chunk;
237 }
238
239 /* Set a top-half handler.
240 *
241 * Originally, we the top-half handler was scheduled as a BH. We now
242 * call the handler directly in sctp_inq_push() at a time that
243 * we know we are lock safe.
244 * The intent is that this routine will pull stuff out of the
245 * inqueue and process it.
246 */
sctp_inq_set_th_handler(struct sctp_inq * q,work_func_t callback)247 void sctp_inq_set_th_handler(struct sctp_inq *q, work_func_t callback)
248 {
249 INIT_WORK(&q->immediate, callback);
250 }
251