net/rxrpc/af_rxrpc.c

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

File Facts

System
Linux kernel
Corpus path
net/rxrpc/af_rxrpc.c
Extension
.c
Size
27582 bytes
Lines
1147
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: operation-table or driver-model contract
Status
pattern 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

static const struct proto_ops rxrpc_rpc_ops;

/* current debugging ID */
atomic_t rxrpc_debug_id;
EXPORT_SYMBOL(rxrpc_debug_id);

/* count of skbs currently in use */
atomic_t rxrpc_n_rx_skbs;

struct workqueue_struct *rxrpc_workqueue;

static void rxrpc_sock_destructor(struct sock *);

/*
 * see if an RxRPC socket is currently writable
 */
static inline int rxrpc_writable(struct sock *sk)
{
	return refcount_read(&sk->sk_wmem_alloc) < (size_t) sk->sk_sndbuf;
}

/*
 * wait for write bufferage to become available
 */
static void rxrpc_write_space(struct sock *sk)
{
	_enter("%p", sk);
	rcu_read_lock();
	if (rxrpc_writable(sk)) {
		struct socket_wq *wq = rcu_dereference(sk->sk_wq);

		if (skwq_has_sleeper(wq))
			wake_up_interruptible(&wq->wait);
		sk_wake_async_rcu(sk, SOCK_WAKE_SPACE, POLL_OUT);
	}
	rcu_read_unlock();
}

/*
 * validate an RxRPC address
 */
static int rxrpc_validate_address(struct rxrpc_sock *rx,
				  struct sockaddr_rxrpc *srx,
				  int len)
{
	unsigned int tail;

	if (len < sizeof(struct sockaddr_rxrpc))
		return -EINVAL;

	if (srx->srx_family != AF_RXRPC)
		return -EAFNOSUPPORT;

	if (srx->transport_type != SOCK_DGRAM)
		return -ESOCKTNOSUPPORT;

	len -= offsetof(struct sockaddr_rxrpc, transport);
	if (srx->transport_len < sizeof(sa_family_t) ||
	    srx->transport_len > len)
		return -EINVAL;

	switch (srx->transport.family) {
	case AF_INET:
		if (rx->family != AF_INET &&
		    rx->family != AF_INET6)
			return -EAFNOSUPPORT;
		if (srx->transport_len < sizeof(struct sockaddr_in))
			return -EINVAL;
		tail = offsetof(struct sockaddr_rxrpc, transport.sin.__pad);
		break;

#ifdef CONFIG_AF_RXRPC_IPV6
	case AF_INET6:
		if (rx->family != AF_INET6)
			return -EAFNOSUPPORT;
		if (srx->transport_len < sizeof(struct sockaddr_in6))
			return -EINVAL;
		tail = offsetof(struct sockaddr_rxrpc, transport) +
			sizeof(struct sockaddr_in6);
		break;
#endif

	default:
		return -EAFNOSUPPORT;
	}

	if (tail < len)
		memset((void *)srx + tail, 0, len - tail);
	_debug("INET: %pISp", &srx->transport);
	return 0;

Annotation

Implementation Notes