net/sctp/ulpqueue.c
Source file repositories/reference/linux-study-clean/net/sctp/ulpqueue.c
File Facts
- System
- Linux kernel
- Corpus path
net/sctp/ulpqueue.c- Extension
.c- Size
- 29245 bytes
- Lines
- 1127
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: implementation source
- Status
- source implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hlinux/types.hlinux/skbuff.hnet/sock.hnet/busy_poll.hnet/sctp/structs.hnet/sctp/sctp.hnet/sctp/sm.h
Detected Declarations
function sctp_ulpq_initfunction sctp_ulpq_flushfunction sctp_ulpq_freefunction sctp_ulpq_tail_datafunction sctp_clear_pdfunction PDfunction sctp_skb_for_eachfunction sctp_ulpq_set_pdfunction sctp_ulpq_clear_pdfunction sctp_ulpq_tail_eventfunction sctp_ulpq_store_reasmfunction skb_queue_walkfunction skb_queue_walkfunction sctp_ulpq_reasm_flushtsnfunction skb_queue_walk_safefunction senderfunction sctp_ulpq_reasm_drainfunction sctp_ulpq_retrieve_orderedfunction sctp_ulpq_store_orderedfunction sctp_ulpq_reap_orderedfunction sctp_ulpq_skipfunction sctp_ulpq_renege_listfunction sctp_ulpq_renege_orderfunction sctp_ulpq_renege_fragsfunction sctp_ulpq_partial_deliveryfunction sctp_ulpq_renegefunction sctp_ulpq_abort_pd
Annotated Snippet
if (!skb_queue_empty(&sp->pd_lobby)) {
skb_queue_splice_tail_init(&sp->pd_lobby,
&sk->sk_receive_queue);
return 1;
}
} else {
/* There are other associations in PD, so we only need to
* pull stuff out of the lobby that belongs to the
* associations that is exiting PD (all of its notifications
* are posted here).
*/
if (!skb_queue_empty(&sp->pd_lobby) && asoc) {
struct sk_buff *skb, *tmp;
struct sctp_ulpevent *event;
sctp_skb_for_each(skb, &sp->pd_lobby, tmp) {
event = sctp_skb2event(skb);
if (event->asoc == asoc) {
__skb_unlink(skb, &sp->pd_lobby);
__skb_queue_tail(&sk->sk_receive_queue,
skb);
}
}
}
}
return 0;
}
/* Set the pd_mode on the socket and ulpq */
static void sctp_ulpq_set_pd(struct sctp_ulpq *ulpq)
{
struct sctp_sock *sp = sctp_sk(ulpq->asoc->base.sk);
atomic_inc(&sp->pd_mode);
ulpq->pd_mode = 1;
}
/* Clear the pd_mode and restart any pending messages waiting for delivery. */
static int sctp_ulpq_clear_pd(struct sctp_ulpq *ulpq)
{
ulpq->pd_mode = 0;
sctp_ulpq_reasm_drain(ulpq);
return sctp_clear_pd(ulpq->asoc->base.sk, ulpq->asoc);
}
int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sk_buff_head *skb_list)
{
struct sock *sk = ulpq->asoc->base.sk;
struct sctp_sock *sp = sctp_sk(sk);
struct sctp_ulpevent *event;
struct sk_buff_head *queue;
struct sk_buff *skb;
int clear_pd = 0;
skb = __skb_peek(skb_list);
event = sctp_skb2event(skb);
/* If the socket is just going to throw this away, do not
* even try to deliver it.
*/
if (sk->sk_shutdown & RCV_SHUTDOWN &&
(sk->sk_shutdown & SEND_SHUTDOWN ||
!sctp_ulpevent_is_notification(event)))
goto out_free;
if (!sctp_ulpevent_is_notification(event)) {
sk_mark_napi_id(sk, skb);
sk_incoming_cpu_update(sk);
}
/* Check if the user wishes to receive this event. */
if (!sctp_ulpevent_is_enabled(event, ulpq->asoc->subscribe))
goto out_free;
/* If we are in partial delivery mode, post to the lobby until
* partial delivery is cleared, unless, of course _this_ is
* the association the cause of the partial delivery.
*/
if (atomic_read(&sp->pd_mode) == 0) {
queue = &sk->sk_receive_queue;
} else {
if (ulpq->pd_mode) {
/* If the association is in partial delivery, we
* need to finish delivering the partially processed
* packet before passing any other data. This is
* because we don't truly support stream interleaving.
*/
if ((event->msg_flags & MSG_NOTIFICATION) ||
(SCTP_DATA_NOT_FRAG ==
Annotation
- Immediate include surface: `linux/slab.h`, `linux/types.h`, `linux/skbuff.h`, `net/sock.h`, `net/busy_poll.h`, `net/sctp/structs.h`, `net/sctp/sctp.h`, `net/sctp/sm.h`.
- Detected declarations: `function sctp_ulpq_init`, `function sctp_ulpq_flush`, `function sctp_ulpq_free`, `function sctp_ulpq_tail_data`, `function sctp_clear_pd`, `function PD`, `function sctp_skb_for_each`, `function sctp_ulpq_set_pd`, `function sctp_ulpq_clear_pd`, `function sctp_ulpq_tail_event`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.