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