net/rxrpc/oob.c

Source file repositories/reference/linux-study-clean/net/rxrpc/oob.c

File Facts

System
Linux kernel
Corpus path
net/rxrpc/oob.c
Extension
.c
Size
9321 bytes
Lines
380
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rxrpc_oob_params {
	u64			oob_id;		/* ID number of message if reply */
	s32			abort_code;
	enum rxrpc_oob_command	command;
	bool			have_oob_id:1;
};

/*
 * Post an out-of-band message for attention by the socket or kernel service
 * associated with a reference call.
 */
void rxrpc_notify_socket_oob(struct rxrpc_call *call, struct sk_buff *skb)
{
	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
	struct rxrpc_sock *rx;
	struct sock *sk;

	rcu_read_lock();

	rx = rcu_dereference(call->socket);
	if (rx) {
		sk = &rx->sk;
		spin_lock_irq(&rx->recvmsg_lock);

		if (sk->sk_state < RXRPC_CLOSE) {
			skb->skb_mstamp_ns = rx->oob_id_counter++;
			rxrpc_get_skb(skb, rxrpc_skb_get_post_oob);
			skb_queue_tail(&rx->recvmsg_oobq, skb);

			trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial);
			if (rx->app_ops)
				rx->app_ops->notify_oob(sk, skb);
		}

		spin_unlock_irq(&rx->recvmsg_lock);
		if (!rx->app_ops && !sock_flag(sk, SOCK_DEAD))
			sk->sk_data_ready(sk);
	}

	rcu_read_unlock();
}

/*
 * Locate the OOB message to respond to by its ID.
 */
static struct sk_buff *rxrpc_find_pending_oob(struct rxrpc_sock *rx, u64 oob_id)
{
	struct rb_node *p;
	struct sk_buff *skb;

	p = rx->pending_oobq.rb_node;
	while (p) {
		skb = rb_entry(p, struct sk_buff, rbnode);

		if (oob_id < skb->skb_mstamp_ns)
			p = p->rb_left;
		else if (oob_id > skb->skb_mstamp_ns)
			p = p->rb_right;
		else
			return skb;
	}

	return NULL;
}

/*
 * Add an OOB message into the pending-response set.  We always assign the next
 * value from a 64-bit counter to the oob_id, so just assume we're always going
 * to be on the right-hand edge of the tree and that the counter won't wrap.
 * The tree is also given a ref to the message.
 */
void rxrpc_add_pending_oob(struct rxrpc_sock *rx, struct sk_buff *skb)
{
	struct rb_node **pp = &rx->pending_oobq.rb_node, *p = NULL;

	while (*pp) {
		p = *pp;
		pp = &(*pp)->rb_right;
	}

	rb_link_node(&skb->rbnode, p, pp);
	rb_insert_color(&skb->rbnode, &rx->pending_oobq);
}

/*
 * Extract control messages from the sendmsg() control buffer.
 */
static int rxrpc_sendmsg_oob_cmsg(struct msghdr *msg, struct rxrpc_oob_params *p)
{
	struct cmsghdr *cmsg;

Annotation

Implementation Notes