net/vmw_vsock/af_vsock.c

Source file repositories/reference/linux-study-clean/net/vmw_vsock/af_vsock.c

File Facts

System
Linux kernel
Corpus path
net/vmw_vsock/af_vsock.c
Extension
.c
Size
79545 bytes
Lines
3143
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 vsock_dgram_ops = {
	.family = PF_VSOCK,
	.owner = THIS_MODULE,
	.release = vsock_release,
	.bind = vsock_bind,
	.connect = vsock_dgram_connect,
	.socketpair = sock_no_socketpair,
	.accept = sock_no_accept,
	.getname = vsock_getname,
	.poll = vsock_poll,
	.ioctl = vsock_ioctl,
	.listen = sock_no_listen,
	.shutdown = vsock_shutdown,
	.sendmsg = vsock_dgram_sendmsg,
	.recvmsg = vsock_dgram_recvmsg,
	.mmap = sock_no_mmap,
	.read_skb = vsock_read_skb,
};

static int vsock_transport_cancel_pkt(struct vsock_sock *vsk)
{
	const struct vsock_transport *transport = vsk->transport;

	if (!transport || !transport->cancel_pkt)
		return -EOPNOTSUPP;

	return transport->cancel_pkt(vsk);
}

static void vsock_connect_timeout(struct work_struct *work)
{
	struct sock *sk;
	struct vsock_sock *vsk;

	vsk = container_of(work, struct vsock_sock, connect_work.work);
	sk = sk_vsock(vsk);

	lock_sock(sk);
	if (sk->sk_state == TCP_SYN_SENT &&
	    (sk->sk_shutdown != SHUTDOWN_MASK)) {
		sk->sk_state = TCP_CLOSE;
		sk->sk_socket->state = SS_UNCONNECTED;
		sk->sk_err = ETIMEDOUT;
		sk_error_report(sk);
		vsock_transport_cancel_pkt(vsk);
	}
	release_sock(sk);

	sock_put(sk);
}

static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
			 int addr_len, int flags)
{
	int err;
	struct sock *sk;
	struct vsock_sock *vsk;
	const struct vsock_transport *transport;
	struct sockaddr_vm *remote_addr;
	long timeout;
	DEFINE_WAIT(wait);

	err = 0;
	sk = sock->sk;
	vsk = vsock_sk(sk);

	lock_sock(sk);

	/* XXX AF_UNSPEC should make us disconnect like AF_INET. */
	switch (sock->state) {
	case SS_CONNECTED:
		err = -EISCONN;
		goto out;
	case SS_DISCONNECTING:
		err = -EINVAL;
		goto out;
	case SS_CONNECTING:
		/* This continues on so we can move sock into the SS_CONNECTED
		 * state once the connection has completed (at which point err
		 * will be set to zero also).  Otherwise, we will either wait
		 * for the connection or return -EALREADY should this be a
		 * non-blocking call.
		 */
		err = -EALREADY;
		if (flags & O_NONBLOCK)
			goto out;
		break;
	default:
		if ((sk->sk_state == TCP_LISTEN) ||
		    vsock_addr_cast(addr, addr_len, &remote_addr) != 0) {

Annotation

Implementation Notes