Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* SCTP kernel implementation
0003  * Copyright (c) 1999-2000 Cisco, Inc.
0004  * Copyright (c) 1999-2001 Motorola, Inc.
0005  * Copyright (c) 2002 International Business Machines, Corp.
0006  *
0007  * This file is part of the SCTP kernel implementation
0008  *
0009  * These functions are the methods for accessing the SCTP inqueue.
0010  *
0011  * An SCTP inqueue is a queue into which you push SCTP packets
0012  * (which might be bundles or fragments of chunks) and out of which you
0013  * pop SCTP whole chunks.
0014  *
0015  * Please send any bug reports or fixes you make to the
0016  * email address(es):
0017  *    lksctp developers <linux-sctp@vger.kernel.org>
0018  *
0019  * Written or modified by:
0020  *    La Monte H.P. Yarroll <piggy@acm.org>
0021  *    Karl Knutson <karl@athena.chicago.il.us>
0022  */
0023 
0024 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0025 
0026 #include <net/sctp/sctp.h>
0027 #include <net/sctp/sm.h>
0028 #include <linux/interrupt.h>
0029 #include <linux/slab.h>
0030 
0031 /* Initialize an SCTP inqueue.  */
0032 void sctp_inq_init(struct sctp_inq *queue)
0033 {
0034     INIT_LIST_HEAD(&queue->in_chunk_list);
0035     queue->in_progress = NULL;
0036 
0037     /* Create a task for delivering data.  */
0038     INIT_WORK(&queue->immediate, NULL);
0039 }
0040 
0041 /* Release the memory associated with an SCTP inqueue.  */
0042 void sctp_inq_free(struct sctp_inq *queue)
0043 {
0044     struct sctp_chunk *chunk, *tmp;
0045 
0046     /* Empty the queue.  */
0047     list_for_each_entry_safe(chunk, tmp, &queue->in_chunk_list, list) {
0048         list_del_init(&chunk->list);
0049         sctp_chunk_free(chunk);
0050     }
0051 
0052     /* If there is a packet which is currently being worked on,
0053      * free it as well.
0054      */
0055     if (queue->in_progress) {
0056         sctp_chunk_free(queue->in_progress);
0057         queue->in_progress = NULL;
0058     }
0059 }
0060 
0061 /* Put a new packet in an SCTP inqueue.
0062  * We assume that packet->sctp_hdr is set and in host byte order.
0063  */
0064 void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *chunk)
0065 {
0066     /* Directly call the packet handling routine. */
0067     if (chunk->rcvr->dead) {
0068         sctp_chunk_free(chunk);
0069         return;
0070     }
0071 
0072     /* We are now calling this either from the soft interrupt
0073      * or from the backlog processing.
0074      * Eventually, we should clean up inqueue to not rely
0075      * on the BH related data structures.
0076      */
0077     list_add_tail(&chunk->list, &q->in_chunk_list);
0078     if (chunk->asoc)
0079         chunk->asoc->stats.ipackets++;
0080     q->immediate.func(&q->immediate);
0081 }
0082 
0083 /* Peek at the next chunk on the inqeue. */
0084 struct sctp_chunkhdr *sctp_inq_peek(struct sctp_inq *queue)
0085 {
0086     struct sctp_chunk *chunk;
0087     struct sctp_chunkhdr *ch = NULL;
0088 
0089     chunk = queue->in_progress;
0090     /* If there is no more chunks in this packet, say so */
0091     if (chunk->singleton ||
0092         chunk->end_of_packet ||
0093         chunk->pdiscard)
0094             return NULL;
0095 
0096     ch = (struct sctp_chunkhdr *)chunk->chunk_end;
0097 
0098     return ch;
0099 }
0100 
0101 
0102 /* Extract a chunk from an SCTP inqueue.
0103  *
0104  * WARNING:  If you need to put the chunk on another queue, you need to
0105  * make a shallow copy (clone) of it.
0106  */
0107 struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
0108 {
0109     struct sctp_chunk *chunk;
0110     struct sctp_chunkhdr *ch = NULL;
0111 
0112     /* The assumption is that we are safe to process the chunks
0113      * at this time.
0114      */
0115 
0116     chunk = queue->in_progress;
0117     if (chunk) {
0118         /* There is a packet that we have been working on.
0119          * Any post processing work to do before we move on?
0120          */
0121         if (chunk->singleton ||
0122             chunk->end_of_packet ||
0123             chunk->pdiscard) {
0124             if (chunk->head_skb == chunk->skb) {
0125                 chunk->skb = skb_shinfo(chunk->skb)->frag_list;
0126                 goto new_skb;
0127             }
0128             if (chunk->skb->next) {
0129                 chunk->skb = chunk->skb->next;
0130                 goto new_skb;
0131             }
0132 
0133             if (chunk->head_skb)
0134                 chunk->skb = chunk->head_skb;
0135             sctp_chunk_free(chunk);
0136             chunk = queue->in_progress = NULL;
0137         } else {
0138             /* Nothing to do. Next chunk in the packet, please. */
0139             ch = (struct sctp_chunkhdr *)chunk->chunk_end;
0140             /* Force chunk->skb->data to chunk->chunk_end.  */
0141             skb_pull(chunk->skb, chunk->chunk_end - chunk->skb->data);
0142             /* We are guaranteed to pull a SCTP header. */
0143         }
0144     }
0145 
0146     /* Do we need to take the next packet out of the queue to process? */
0147     if (!chunk) {
0148         struct list_head *entry;
0149 
0150 next_chunk:
0151         /* Is the queue empty?  */
0152         entry = sctp_list_dequeue(&queue->in_chunk_list);
0153         if (!entry)
0154             return NULL;
0155 
0156         chunk = list_entry(entry, struct sctp_chunk, list);
0157 
0158         if (skb_is_gso(chunk->skb) && skb_is_gso_sctp(chunk->skb)) {
0159             /* GSO-marked skbs but without frags, handle
0160              * them normally
0161              */
0162             if (skb_shinfo(chunk->skb)->frag_list)
0163                 chunk->head_skb = chunk->skb;
0164 
0165             /* skbs with "cover letter" */
0166             if (chunk->head_skb && chunk->skb->data_len == chunk->skb->len)
0167                 chunk->skb = skb_shinfo(chunk->skb)->frag_list;
0168 
0169             if (WARN_ON(!chunk->skb)) {
0170                 __SCTP_INC_STATS(dev_net(chunk->skb->dev), SCTP_MIB_IN_PKT_DISCARDS);
0171                 sctp_chunk_free(chunk);
0172                 goto next_chunk;
0173             }
0174         }
0175 
0176         if (chunk->asoc)
0177             sock_rps_save_rxhash(chunk->asoc->base.sk, chunk->skb);
0178 
0179         queue->in_progress = chunk;
0180 
0181 new_skb:
0182         /* This is the first chunk in the packet.  */
0183         ch = (struct sctp_chunkhdr *)chunk->skb->data;
0184         chunk->singleton = 1;
0185         chunk->data_accepted = 0;
0186         chunk->pdiscard = 0;
0187         chunk->auth = 0;
0188         chunk->has_asconf = 0;
0189         chunk->end_of_packet = 0;
0190         if (chunk->head_skb) {
0191             struct sctp_input_cb
0192                 *cb = SCTP_INPUT_CB(chunk->skb),
0193                 *head_cb = SCTP_INPUT_CB(chunk->head_skb);
0194 
0195             cb->chunk = head_cb->chunk;
0196             cb->af = head_cb->af;
0197         }
0198     }
0199 
0200     chunk->chunk_hdr = ch;
0201     chunk->chunk_end = ((__u8 *)ch) + SCTP_PAD4(ntohs(ch->length));
0202     skb_pull(chunk->skb, sizeof(*ch));
0203     chunk->subh.v = NULL; /* Subheader is no longer valid.  */
0204 
0205     if (chunk->chunk_end + sizeof(*ch) <= skb_tail_pointer(chunk->skb)) {
0206         /* This is not a singleton */
0207         chunk->singleton = 0;
0208     } else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) {
0209         /* Discard inside state machine. */
0210         chunk->pdiscard = 1;
0211         chunk->chunk_end = skb_tail_pointer(chunk->skb);
0212     } else {
0213         /* We are at the end of the packet, so mark the chunk
0214          * in case we need to send a SACK.
0215          */
0216         chunk->end_of_packet = 1;
0217     }
0218 
0219     pr_debug("+++sctp_inq_pop+++ chunk:%p[%s], length:%d, skb->len:%d\n",
0220          chunk, sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)),
0221          ntohs(chunk->chunk_hdr->length), chunk->skb->len);
0222 
0223     return chunk;
0224 }
0225 
0226 /* Set a top-half handler.
0227  *
0228  * Originally, we the top-half handler was scheduled as a BH.  We now
0229  * call the handler directly in sctp_inq_push() at a time that
0230  * we know we are lock safe.
0231  * The intent is that this routine will pull stuff out of the
0232  * inqueue and process it.
0233  */
0234 void sctp_inq_set_th_handler(struct sctp_inq *q, work_func_t callback)
0235 {
0236     INIT_WORK(&q->immediate, callback);
0237 }