virtio_transport_common.c 28.6 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-only
2 3 4 5 6 7 8 9 10
/*
 * common code for virtio vsock
 *
 * Copyright (C) 2013-2015 Red Hat, Inc.
 * Author: Asias He <asias@redhat.com>
 *         Stefan Hajnoczi <stefanha@redhat.com>
 */
#include <linux/spinlock.h>
#include <linux/module.h>
11
#include <linux/sched/signal.h>
12 13 14
#include <linux/ctype.h>
#include <linux/list.h>
#include <linux/virtio_vsock.h>
15
#include <uapi/linux/vsockmon.h>
16 17 18 19 20 21 22 23 24 25

#include <net/sock.h>
#include <net/af_vsock.h>

#define CREATE_TRACE_POINTS
#include <trace/events/vsock_virtio_transport_common.h>

/* How long to wait for graceful shutdown of a connection */
#define VSOCK_CLOSE_TIMEOUT (8 * HZ)

26 27 28
/* Threshold for detecting small packets to copy */
#define GOOD_COPY_LEN  128

29 30
static const struct virtio_transport *
virtio_transport_get_ops(struct vsock_sock *vsk)
31
{
32
	const struct vsock_transport *t = vsock_core_get_transport(vsk);
33

34 35 36
	if (WARN_ON(!t))
		return NULL;

37 38 39
	return container_of(t, struct virtio_transport, transport);
}

40
static struct virtio_vsock_pkt *
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
virtio_transport_alloc_pkt(struct virtio_vsock_pkt_info *info,
			   size_t len,
			   u32 src_cid,
			   u32 src_port,
			   u32 dst_cid,
			   u32 dst_port)
{
	struct virtio_vsock_pkt *pkt;
	int err;

	pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
	if (!pkt)
		return NULL;

	pkt->hdr.type		= cpu_to_le16(info->type);
	pkt->hdr.op		= cpu_to_le16(info->op);
	pkt->hdr.src_cid	= cpu_to_le64(src_cid);
	pkt->hdr.dst_cid	= cpu_to_le64(dst_cid);
	pkt->hdr.src_port	= cpu_to_le32(src_port);
	pkt->hdr.dst_port	= cpu_to_le32(dst_port);
	pkt->hdr.flags		= cpu_to_le32(info->flags);
	pkt->len		= len;
	pkt->hdr.len		= cpu_to_le32(len);
	pkt->reply		= info->reply;
P
Peng Tao 已提交
65
	pkt->vsk		= info->vsk;
66 67 68 69 70

	if (info->msg && len > 0) {
		pkt->buf = kmalloc(len, GFP_KERNEL);
		if (!pkt->buf)
			goto out_pkt;
71 72 73

		pkt->buf_len = len;

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
		err = memcpy_from_msg(pkt->buf, info->msg, len);
		if (err)
			goto out;
	}

	trace_virtio_transport_alloc_pkt(src_cid, src_port,
					 dst_cid, dst_port,
					 len,
					 info->type,
					 info->op,
					 info->flags);

	return pkt;

out:
	kfree(pkt->buf);
out_pkt:
	kfree(pkt);
	return NULL;
}

95 96 97 98 99 100
/* Packet capture */
static struct sk_buff *virtio_transport_build_skb(void *opaque)
{
	struct virtio_vsock_pkt *pkt = opaque;
	struct af_vsockmon_hdr *hdr;
	struct sk_buff *skb;
101 102
	size_t payload_len;
	void *payload_buf;
103

104 105 106 107 108 109 110 111
	/* A packet could be split to fit the RX buffer, so we can retrieve
	 * the payload length from the header and the buffer pointer taking
	 * care of the offset in the original packet.
	 */
	payload_len = le32_to_cpu(pkt->hdr.len);
	payload_buf = pkt->buf + pkt->off;

	skb = alloc_skb(sizeof(*hdr) + sizeof(pkt->hdr) + payload_len,
112 113 114 115
			GFP_ATOMIC);
	if (!skb)
		return NULL;

116
	hdr = skb_put(skb, sizeof(*hdr));
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148

	/* pkt->hdr is little-endian so no need to byteswap here */
	hdr->src_cid = pkt->hdr.src_cid;
	hdr->src_port = pkt->hdr.src_port;
	hdr->dst_cid = pkt->hdr.dst_cid;
	hdr->dst_port = pkt->hdr.dst_port;

	hdr->transport = cpu_to_le16(AF_VSOCK_TRANSPORT_VIRTIO);
	hdr->len = cpu_to_le16(sizeof(pkt->hdr));
	memset(hdr->reserved, 0, sizeof(hdr->reserved));

	switch (le16_to_cpu(pkt->hdr.op)) {
	case VIRTIO_VSOCK_OP_REQUEST:
	case VIRTIO_VSOCK_OP_RESPONSE:
		hdr->op = cpu_to_le16(AF_VSOCK_OP_CONNECT);
		break;
	case VIRTIO_VSOCK_OP_RST:
	case VIRTIO_VSOCK_OP_SHUTDOWN:
		hdr->op = cpu_to_le16(AF_VSOCK_OP_DISCONNECT);
		break;
	case VIRTIO_VSOCK_OP_RW:
		hdr->op = cpu_to_le16(AF_VSOCK_OP_PAYLOAD);
		break;
	case VIRTIO_VSOCK_OP_CREDIT_UPDATE:
	case VIRTIO_VSOCK_OP_CREDIT_REQUEST:
		hdr->op = cpu_to_le16(AF_VSOCK_OP_CONTROL);
		break;
	default:
		hdr->op = cpu_to_le16(AF_VSOCK_OP_UNKNOWN);
		break;
	}

149
	skb_put_data(skb, &pkt->hdr, sizeof(pkt->hdr));
150

151 152
	if (payload_len) {
		skb_put_data(skb, payload_buf, payload_len);
153 154 155 156 157 158 159
	}

	return skb;
}

void virtio_transport_deliver_tap_pkt(struct virtio_vsock_pkt *pkt)
{
160 161 162
	if (pkt->tap_delivered)
		return;

163
	vsock_deliver_tap(virtio_transport_build_skb, pkt);
164
	pkt->tap_delivered = true;
165 166 167
}
EXPORT_SYMBOL_GPL(virtio_transport_deliver_tap_pkt);

168 169 170 171 172
/* This function can only be used on connecting/connected sockets,
 * since a socket assigned to a transport is required.
 *
 * Do not use on listener sockets!
 */
173 174 175 176
static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
					  struct virtio_vsock_pkt_info *info)
{
	u32 src_cid, src_port, dst_cid, dst_port;
177
	const struct virtio_transport *t_ops;
178 179 180 181
	struct virtio_vsock_sock *vvs;
	struct virtio_vsock_pkt *pkt;
	u32 pkt_len = info->pkt_len;

182 183 184 185 186
	t_ops = virtio_transport_get_ops(vsk);
	if (unlikely(!t_ops))
		return -EFAULT;

	src_cid = t_ops->transport.get_local_cid();
187 188 189 190 191 192 193 194 195 196 197 198
	src_port = vsk->local_addr.svm_port;
	if (!info->remote_cid) {
		dst_cid	= vsk->remote_addr.svm_cid;
		dst_port = vsk->remote_addr.svm_port;
	} else {
		dst_cid = info->remote_cid;
		dst_port = info->remote_port;
	}

	vvs = vsk->trans;

	/* we can send less than pkt_len bytes */
199 200
	if (pkt_len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE)
		pkt_len = VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218

	/* virtio_transport_get_credit might return less than pkt_len credit */
	pkt_len = virtio_transport_get_credit(vvs, pkt_len);

	/* Do not send zero length OP_RW pkt */
	if (pkt_len == 0 && info->op == VIRTIO_VSOCK_OP_RW)
		return pkt_len;

	pkt = virtio_transport_alloc_pkt(info, pkt_len,
					 src_cid, src_port,
					 dst_cid, dst_port);
	if (!pkt) {
		virtio_transport_put_credit(vvs, pkt_len);
		return -ENOMEM;
	}

	virtio_transport_inc_tx_pkt(vvs, pkt);

219
	return t_ops->send_pkt(pkt);
220 221
}

222
static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
223 224
					struct virtio_vsock_pkt *pkt)
{
225 226 227
	if (vvs->rx_bytes + pkt->len > vvs->buf_alloc)
		return false;

228
	vvs->rx_bytes += pkt->len;
229
	return true;
230 231 232 233 234 235 236 237 238 239 240
}

static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs,
					struct virtio_vsock_pkt *pkt)
{
	vvs->rx_bytes -= pkt->len;
	vvs->fwd_cnt += pkt->len;
}

void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct virtio_vsock_pkt *pkt)
{
241
	spin_lock_bh(&vvs->rx_lock);
242
	vvs->last_fwd_cnt = vvs->fwd_cnt;
243 244
	pkt->hdr.fwd_cnt = cpu_to_le32(vvs->fwd_cnt);
	pkt->hdr.buf_alloc = cpu_to_le32(vvs->buf_alloc);
245
	spin_unlock_bh(&vvs->rx_lock);
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
}
EXPORT_SYMBOL_GPL(virtio_transport_inc_tx_pkt);

u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 credit)
{
	u32 ret;

	spin_lock_bh(&vvs->tx_lock);
	ret = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);
	if (ret > credit)
		ret = credit;
	vvs->tx_cnt += ret;
	spin_unlock_bh(&vvs->tx_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(virtio_transport_get_credit);

void virtio_transport_put_credit(struct virtio_vsock_sock *vvs, u32 credit)
{
	spin_lock_bh(&vvs->tx_lock);
	vvs->tx_cnt -= credit;
	spin_unlock_bh(&vvs->tx_lock);
}
EXPORT_SYMBOL_GPL(virtio_transport_put_credit);

static int virtio_transport_send_credit_update(struct vsock_sock *vsk,
					       int type,
					       struct virtio_vsock_hdr *hdr)
{
	struct virtio_vsock_pkt_info info = {
		.op = VIRTIO_VSOCK_OP_CREDIT_UPDATE,
		.type = type,
P
Peng Tao 已提交
279
		.vsk = vsk,
280 281 282 283 284
	};

	return virtio_transport_send_pkt_info(vsk, &info);
}

285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
static ssize_t
virtio_transport_stream_do_peek(struct vsock_sock *vsk,
				struct msghdr *msg,
				size_t len)
{
	struct virtio_vsock_sock *vvs = vsk->trans;
	struct virtio_vsock_pkt *pkt;
	size_t bytes, total = 0, off;
	int err = -EFAULT;

	spin_lock_bh(&vvs->rx_lock);

	list_for_each_entry(pkt, &vvs->rx_queue, list) {
		off = pkt->off;

		if (total == len)
			break;

		while (total < len && off < pkt->len) {
			bytes = len - total;
			if (bytes > pkt->len - off)
				bytes = pkt->len - off;

			/* sk_lock is held by caller so no one else can dequeue.
			 * Unlock rx_lock since memcpy_to_msg() may sleep.
			 */
			spin_unlock_bh(&vvs->rx_lock);

			err = memcpy_to_msg(msg, pkt->buf + off, bytes);
			if (err)
				goto out;

			spin_lock_bh(&vvs->rx_lock);

			total += bytes;
			off += bytes;
		}
	}

	spin_unlock_bh(&vvs->rx_lock);

	return total;

out:
	if (total)
		err = total;
	return err;
}

334 335 336 337 338 339 340 341
static ssize_t
virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
				   struct msghdr *msg,
				   size_t len)
{
	struct virtio_vsock_sock *vvs = vsk->trans;
	struct virtio_vsock_pkt *pkt;
	size_t bytes, total = 0;
342
	u32 free_space;
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
	int err = -EFAULT;

	spin_lock_bh(&vvs->rx_lock);
	while (total < len && !list_empty(&vvs->rx_queue)) {
		pkt = list_first_entry(&vvs->rx_queue,
				       struct virtio_vsock_pkt, list);

		bytes = len - total;
		if (bytes > pkt->len - pkt->off)
			bytes = pkt->len - pkt->off;

		/* sk_lock is held by caller so no one else can dequeue.
		 * Unlock rx_lock since memcpy_to_msg() may sleep.
		 */
		spin_unlock_bh(&vvs->rx_lock);

		err = memcpy_to_msg(msg, pkt->buf + pkt->off, bytes);
		if (err)
			goto out;

		spin_lock_bh(&vvs->rx_lock);

		total += bytes;
		pkt->off += bytes;
		if (pkt->off == pkt->len) {
			virtio_transport_dec_rx_pkt(vvs, pkt);
			list_del(&pkt->list);
			virtio_transport_free_pkt(pkt);
		}
	}
373 374 375

	free_space = vvs->buf_alloc - (vvs->fwd_cnt - vvs->last_fwd_cnt);

376 377
	spin_unlock_bh(&vvs->rx_lock);

378 379 380 381 382 383 384
	/* To reduce the number of credit update messages,
	 * don't update credits as long as lots of space is available.
	 * Note: the limit chosen here is arbitrary. Setting the limit
	 * too high causes extra messages. Too low causes transmitter
	 * stalls. As stalls are in theory more expensive than extra
	 * messages, we set the limit to a high value. TODO: experiment
	 * with different values.
385 386 387 388 389 390
	 */
	if (free_space < VIRTIO_VSOCK_MAX_PKT_BUF_SIZE) {
		virtio_transport_send_credit_update(vsk,
						    VIRTIO_VSOCK_TYPE_STREAM,
						    NULL);
	}
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405

	return total;

out:
	if (total)
		err = total;
	return err;
}

ssize_t
virtio_transport_stream_dequeue(struct vsock_sock *vsk,
				struct msghdr *msg,
				size_t len, int flags)
{
	if (flags & MSG_PEEK)
406 407 408
		return virtio_transport_stream_do_peek(vsk, msg, len);
	else
		return virtio_transport_stream_do_dequeue(vsk, msg, len);
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469
}
EXPORT_SYMBOL_GPL(virtio_transport_stream_dequeue);

int
virtio_transport_dgram_dequeue(struct vsock_sock *vsk,
			       struct msghdr *msg,
			       size_t len, int flags)
{
	return -EOPNOTSUPP;
}
EXPORT_SYMBOL_GPL(virtio_transport_dgram_dequeue);

s64 virtio_transport_stream_has_data(struct vsock_sock *vsk)
{
	struct virtio_vsock_sock *vvs = vsk->trans;
	s64 bytes;

	spin_lock_bh(&vvs->rx_lock);
	bytes = vvs->rx_bytes;
	spin_unlock_bh(&vvs->rx_lock);

	return bytes;
}
EXPORT_SYMBOL_GPL(virtio_transport_stream_has_data);

static s64 virtio_transport_has_space(struct vsock_sock *vsk)
{
	struct virtio_vsock_sock *vvs = vsk->trans;
	s64 bytes;

	bytes = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);
	if (bytes < 0)
		bytes = 0;

	return bytes;
}

s64 virtio_transport_stream_has_space(struct vsock_sock *vsk)
{
	struct virtio_vsock_sock *vvs = vsk->trans;
	s64 bytes;

	spin_lock_bh(&vvs->tx_lock);
	bytes = virtio_transport_has_space(vsk);
	spin_unlock_bh(&vvs->tx_lock);

	return bytes;
}
EXPORT_SYMBOL_GPL(virtio_transport_stream_has_space);

int virtio_transport_do_socket_init(struct vsock_sock *vsk,
				    struct vsock_sock *psk)
{
	struct virtio_vsock_sock *vvs;

	vvs = kzalloc(sizeof(*vvs), GFP_KERNEL);
	if (!vvs)
		return -ENOMEM;

	vsk->trans = vvs;
	vvs->vsk = vsk;
470
	if (psk && psk->trans) {
471 472 473 474 475
		struct virtio_vsock_sock *ptrans = psk->trans;

		vvs->peer_buf_alloc = ptrans->peer_buf_alloc;
	}

476 477 478 479
	if (vsk->buffer_size > VIRTIO_VSOCK_MAX_BUF_SIZE)
		vsk->buffer_size = VIRTIO_VSOCK_MAX_BUF_SIZE;

	vvs->buf_alloc = vsk->buffer_size;
480 481 482 483 484 485 486 487 488

	spin_lock_init(&vvs->rx_lock);
	spin_lock_init(&vvs->tx_lock);
	INIT_LIST_HEAD(&vvs->rx_queue);

	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_do_socket_init);

489 490
/* sk_lock held by the caller */
void virtio_transport_notify_buffer_size(struct vsock_sock *vsk, u64 *val)
491 492 493
{
	struct virtio_vsock_sock *vvs = vsk->trans;

494 495
	if (*val > VIRTIO_VSOCK_MAX_BUF_SIZE)
		*val = VIRTIO_VSOCK_MAX_BUF_SIZE;
496

497
	vvs->buf_alloc = *val;
498 499 500

	virtio_transport_send_credit_update(vsk, VIRTIO_VSOCK_TYPE_STREAM,
					    NULL);
501
}
502
EXPORT_SYMBOL_GPL(virtio_transport_notify_buffer_size);
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593

int
virtio_transport_notify_poll_in(struct vsock_sock *vsk,
				size_t target,
				bool *data_ready_now)
{
	if (vsock_stream_has_data(vsk))
		*data_ready_now = true;
	else
		*data_ready_now = false;

	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_notify_poll_in);

int
virtio_transport_notify_poll_out(struct vsock_sock *vsk,
				 size_t target,
				 bool *space_avail_now)
{
	s64 free_space;

	free_space = vsock_stream_has_space(vsk);
	if (free_space > 0)
		*space_avail_now = true;
	else if (free_space == 0)
		*space_avail_now = false;

	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_notify_poll_out);

int virtio_transport_notify_recv_init(struct vsock_sock *vsk,
	size_t target, struct vsock_transport_recv_notify_data *data)
{
	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_notify_recv_init);

int virtio_transport_notify_recv_pre_block(struct vsock_sock *vsk,
	size_t target, struct vsock_transport_recv_notify_data *data)
{
	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_notify_recv_pre_block);

int virtio_transport_notify_recv_pre_dequeue(struct vsock_sock *vsk,
	size_t target, struct vsock_transport_recv_notify_data *data)
{
	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_notify_recv_pre_dequeue);

int virtio_transport_notify_recv_post_dequeue(struct vsock_sock *vsk,
	size_t target, ssize_t copied, bool data_read,
	struct vsock_transport_recv_notify_data *data)
{
	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_notify_recv_post_dequeue);

int virtio_transport_notify_send_init(struct vsock_sock *vsk,
	struct vsock_transport_send_notify_data *data)
{
	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_notify_send_init);

int virtio_transport_notify_send_pre_block(struct vsock_sock *vsk,
	struct vsock_transport_send_notify_data *data)
{
	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_notify_send_pre_block);

int virtio_transport_notify_send_pre_enqueue(struct vsock_sock *vsk,
	struct vsock_transport_send_notify_data *data)
{
	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_notify_send_pre_enqueue);

int virtio_transport_notify_send_post_enqueue(struct vsock_sock *vsk,
	ssize_t written, struct vsock_transport_send_notify_data *data)
{
	return 0;
}
EXPORT_SYMBOL_GPL(virtio_transport_notify_send_post_enqueue);

u64 virtio_transport_stream_rcvhiwat(struct vsock_sock *vsk)
{
594
	return vsk->buffer_size;
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
}
EXPORT_SYMBOL_GPL(virtio_transport_stream_rcvhiwat);

bool virtio_transport_stream_is_active(struct vsock_sock *vsk)
{
	return true;
}
EXPORT_SYMBOL_GPL(virtio_transport_stream_is_active);

bool virtio_transport_stream_allow(u32 cid, u32 port)
{
	return true;
}
EXPORT_SYMBOL_GPL(virtio_transport_stream_allow);

int virtio_transport_dgram_bind(struct vsock_sock *vsk,
				struct sockaddr_vm *addr)
{
	return -EOPNOTSUPP;
}
EXPORT_SYMBOL_GPL(virtio_transport_dgram_bind);

bool virtio_transport_dgram_allow(u32 cid, u32 port)
{
	return false;
}
EXPORT_SYMBOL_GPL(virtio_transport_dgram_allow);

int virtio_transport_connect(struct vsock_sock *vsk)
{
	struct virtio_vsock_pkt_info info = {
		.op = VIRTIO_VSOCK_OP_REQUEST,
		.type = VIRTIO_VSOCK_TYPE_STREAM,
P
Peng Tao 已提交
628
		.vsk = vsk,
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
	};

	return virtio_transport_send_pkt_info(vsk, &info);
}
EXPORT_SYMBOL_GPL(virtio_transport_connect);

int virtio_transport_shutdown(struct vsock_sock *vsk, int mode)
{
	struct virtio_vsock_pkt_info info = {
		.op = VIRTIO_VSOCK_OP_SHUTDOWN,
		.type = VIRTIO_VSOCK_TYPE_STREAM,
		.flags = (mode & RCV_SHUTDOWN ?
			  VIRTIO_VSOCK_SHUTDOWN_RCV : 0) |
			 (mode & SEND_SHUTDOWN ?
			  VIRTIO_VSOCK_SHUTDOWN_SEND : 0),
P
Peng Tao 已提交
644
		.vsk = vsk,
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
	};

	return virtio_transport_send_pkt_info(vsk, &info);
}
EXPORT_SYMBOL_GPL(virtio_transport_shutdown);

int
virtio_transport_dgram_enqueue(struct vsock_sock *vsk,
			       struct sockaddr_vm *remote_addr,
			       struct msghdr *msg,
			       size_t dgram_len)
{
	return -EOPNOTSUPP;
}
EXPORT_SYMBOL_GPL(virtio_transport_dgram_enqueue);

ssize_t
virtio_transport_stream_enqueue(struct vsock_sock *vsk,
				struct msghdr *msg,
				size_t len)
{
	struct virtio_vsock_pkt_info info = {
		.op = VIRTIO_VSOCK_OP_RW,
		.type = VIRTIO_VSOCK_TYPE_STREAM,
		.msg = msg,
		.pkt_len = len,
P
Peng Tao 已提交
671
		.vsk = vsk,
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
	};

	return virtio_transport_send_pkt_info(vsk, &info);
}
EXPORT_SYMBOL_GPL(virtio_transport_stream_enqueue);

void virtio_transport_destruct(struct vsock_sock *vsk)
{
	struct virtio_vsock_sock *vvs = vsk->trans;

	kfree(vvs);
}
EXPORT_SYMBOL_GPL(virtio_transport_destruct);

static int virtio_transport_reset(struct vsock_sock *vsk,
				  struct virtio_vsock_pkt *pkt)
{
	struct virtio_vsock_pkt_info info = {
		.op = VIRTIO_VSOCK_OP_RST,
		.type = VIRTIO_VSOCK_TYPE_STREAM,
		.reply = !!pkt,
P
Peng Tao 已提交
693
		.vsk = vsk,
694 695 696 697 698 699 700 701 702 703 704 705
	};

	/* Send RST only if the original pkt is not a RST pkt */
	if (pkt && le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST)
		return 0;

	return virtio_transport_send_pkt_info(vsk, &info);
}

/* Normally packets are associated with a socket.  There may be no socket if an
 * attempt was made to connect to a socket that does not exist.
 */
706 707
static int virtio_transport_reset_no_sock(const struct virtio_transport *t,
					  struct virtio_vsock_pkt *pkt)
708
{
709
	struct virtio_vsock_pkt *reply;
710 711 712 713 714 715 716 717 718 719
	struct virtio_vsock_pkt_info info = {
		.op = VIRTIO_VSOCK_OP_RST,
		.type = le16_to_cpu(pkt->hdr.type),
		.reply = true,
	};

	/* Send RST only if the original pkt is not a RST pkt */
	if (le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST)
		return 0;

720 721 722 723 724 725
	reply = virtio_transport_alloc_pkt(&info, 0,
					   le64_to_cpu(pkt->hdr.dst_cid),
					   le32_to_cpu(pkt->hdr.dst_port),
					   le64_to_cpu(pkt->hdr.src_cid),
					   le32_to_cpu(pkt->hdr.src_port));
	if (!reply)
726 727
		return -ENOMEM;

728 729 730 731 732 733
	if (!t) {
		virtio_transport_free_pkt(reply);
		return -ENOTCONN;
	}

	return t->send_pkt(reply);
734 735
}

736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
/* This function should be called with sk_lock held and SOCK_DONE set */
static void virtio_transport_remove_sock(struct vsock_sock *vsk)
{
	struct virtio_vsock_sock *vvs = vsk->trans;
	struct virtio_vsock_pkt *pkt, *tmp;

	/* We don't need to take rx_lock, as the socket is closing and we are
	 * removing it.
	 */
	list_for_each_entry_safe(pkt, tmp, &vvs->rx_queue, list) {
		list_del(&pkt->list);
		virtio_transport_free_pkt(pkt);
	}

	vsock_remove_sock(vsk);
}

753 754 755
static void virtio_transport_wait_close(struct sock *sk, long timeout)
{
	if (timeout) {
W
WANG Cong 已提交
756 757 758
		DEFINE_WAIT_FUNC(wait, woken_wake_function);

		add_wait_queue(sk_sleep(sk), &wait);
759 760 761

		do {
			if (sk_wait_event(sk, &timeout,
W
WANG Cong 已提交
762
					  sock_flag(sk, SOCK_DONE), &wait))
763 764 765
				break;
		} while (!signal_pending(current) && timeout);

W
WANG Cong 已提交
766
		remove_wait_queue(sk_sleep(sk), &wait);
767 768 769 770 771 772 773 774 775 776 777
	}
}

static void virtio_transport_do_close(struct vsock_sock *vsk,
				      bool cancel_timeout)
{
	struct sock *sk = sk_vsock(vsk);

	sock_set_flag(sk, SOCK_DONE);
	vsk->peer_shutdown = SHUTDOWN_MASK;
	if (vsock_stream_has_data(vsk) <= 0)
778
		sk->sk_state = TCP_CLOSING;
779 780 781 782 783 784
	sk->sk_state_change(sk);

	if (vsk->close_work_scheduled &&
	    (!cancel_timeout || cancel_delayed_work(&vsk->close_work))) {
		vsk->close_work_scheduled = false;

785
		virtio_transport_remove_sock(vsk);
786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817

		/* Release refcnt obtained when we scheduled the timeout */
		sock_put(sk);
	}
}

static void virtio_transport_close_timeout(struct work_struct *work)
{
	struct vsock_sock *vsk =
		container_of(work, struct vsock_sock, close_work.work);
	struct sock *sk = sk_vsock(vsk);

	sock_hold(sk);
	lock_sock(sk);

	if (!sock_flag(sk, SOCK_DONE)) {
		(void)virtio_transport_reset(vsk, NULL);

		virtio_transport_do_close(vsk, false);
	}

	vsk->close_work_scheduled = false;

	release_sock(sk);
	sock_put(sk);
}

/* User context, vsk->sk is locked */
static bool virtio_transport_close(struct vsock_sock *vsk)
{
	struct sock *sk = &vsk->sk;

818 819
	if (!(sk->sk_state == TCP_ESTABLISHED ||
	      sk->sk_state == TCP_CLOSING))
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852
		return true;

	/* Already received SHUTDOWN from peer, reply with RST */
	if ((vsk->peer_shutdown & SHUTDOWN_MASK) == SHUTDOWN_MASK) {
		(void)virtio_transport_reset(vsk, NULL);
		return true;
	}

	if ((sk->sk_shutdown & SHUTDOWN_MASK) != SHUTDOWN_MASK)
		(void)virtio_transport_shutdown(vsk, SHUTDOWN_MASK);

	if (sock_flag(sk, SOCK_LINGER) && !(current->flags & PF_EXITING))
		virtio_transport_wait_close(sk, sk->sk_lingertime);

	if (sock_flag(sk, SOCK_DONE)) {
		return true;
	}

	sock_hold(sk);
	INIT_DELAYED_WORK(&vsk->close_work,
			  virtio_transport_close_timeout);
	vsk->close_work_scheduled = true;
	schedule_delayed_work(&vsk->close_work, VSOCK_CLOSE_TIMEOUT);
	return false;
}

void virtio_transport_release(struct vsock_sock *vsk)
{
	struct sock *sk = &vsk->sk;
	bool remove_sock = true;

	if (sk->sk_type == SOCK_STREAM)
		remove_sock = virtio_transport_close(vsk);
853

854 855
	if (remove_sock) {
		sock_set_flag(sk, SOCK_DONE);
856
		virtio_transport_remove_sock(vsk);
857
	}
858 859 860 861 862 863 864 865 866 867 868 869 870
}
EXPORT_SYMBOL_GPL(virtio_transport_release);

static int
virtio_transport_recv_connecting(struct sock *sk,
				 struct virtio_vsock_pkt *pkt)
{
	struct vsock_sock *vsk = vsock_sk(sk);
	int err;
	int skerr;

	switch (le16_to_cpu(pkt->hdr.op)) {
	case VIRTIO_VSOCK_OP_RESPONSE:
871
		sk->sk_state = TCP_ESTABLISHED;
872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890
		sk->sk_socket->state = SS_CONNECTED;
		vsock_insert_connected(vsk);
		sk->sk_state_change(sk);
		break;
	case VIRTIO_VSOCK_OP_INVALID:
		break;
	case VIRTIO_VSOCK_OP_RST:
		skerr = ECONNRESET;
		err = 0;
		goto destroy;
	default:
		skerr = EPROTO;
		err = -EINVAL;
		goto destroy;
	}
	return 0;

destroy:
	virtio_transport_reset(vsk, pkt);
891
	sk->sk_state = TCP_CLOSE;
892 893 894 895 896
	sk->sk_err = skerr;
	sk->sk_error_report(sk);
	return err;
}

897 898 899 900 901
static void
virtio_transport_recv_enqueue(struct vsock_sock *vsk,
			      struct virtio_vsock_pkt *pkt)
{
	struct virtio_vsock_sock *vvs = vsk->trans;
902
	bool can_enqueue, free_pkt = false;
903 904 905 906 907 908

	pkt->len = le32_to_cpu(pkt->hdr.len);
	pkt->off = 0;

	spin_lock_bh(&vvs->rx_lock);

909 910 911 912 913
	can_enqueue = virtio_transport_inc_rx_pkt(vvs, pkt);
	if (!can_enqueue) {
		free_pkt = true;
		goto out;
	}
914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944

	/* Try to copy small packets into the buffer of last packet queued,
	 * to avoid wasting memory queueing the entire buffer with a small
	 * payload.
	 */
	if (pkt->len <= GOOD_COPY_LEN && !list_empty(&vvs->rx_queue)) {
		struct virtio_vsock_pkt *last_pkt;

		last_pkt = list_last_entry(&vvs->rx_queue,
					   struct virtio_vsock_pkt, list);

		/* If there is space in the last packet queued, we copy the
		 * new packet in its buffer.
		 */
		if (pkt->len <= last_pkt->buf_len - last_pkt->len) {
			memcpy(last_pkt->buf + last_pkt->len, pkt->buf,
			       pkt->len);
			last_pkt->len += pkt->len;
			free_pkt = true;
			goto out;
		}
	}

	list_add_tail(&pkt->list, &vvs->rx_queue);

out:
	spin_unlock_bh(&vvs->rx_lock);
	if (free_pkt)
		virtio_transport_free_pkt(pkt);
}

945 946 947 948 949 950 951 952 953
static int
virtio_transport_recv_connected(struct sock *sk,
				struct virtio_vsock_pkt *pkt)
{
	struct vsock_sock *vsk = vsock_sk(sk);
	int err = 0;

	switch (le16_to_cpu(pkt->hdr.op)) {
	case VIRTIO_VSOCK_OP_RW:
954
		virtio_transport_recv_enqueue(vsk, pkt);
955 956 957 958 959 960 961 962 963 964 965
		sk->sk_data_ready(sk);
		return err;
	case VIRTIO_VSOCK_OP_CREDIT_UPDATE:
		sk->sk_write_space(sk);
		break;
	case VIRTIO_VSOCK_OP_SHUTDOWN:
		if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SHUTDOWN_RCV)
			vsk->peer_shutdown |= RCV_SHUTDOWN;
		if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SHUTDOWN_SEND)
			vsk->peer_shutdown |= SEND_SHUTDOWN;
		if (vsk->peer_shutdown == SHUTDOWN_MASK &&
966 967 968 969 970
		    vsock_stream_has_data(vsk) <= 0 &&
		    !sock_flag(sk, SOCK_DONE)) {
			(void)virtio_transport_reset(vsk, NULL);

			virtio_transport_do_close(vsk, true);
971
		}
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003
		if (le32_to_cpu(pkt->hdr.flags))
			sk->sk_state_change(sk);
		break;
	case VIRTIO_VSOCK_OP_RST:
		virtio_transport_do_close(vsk, true);
		break;
	default:
		err = -EINVAL;
		break;
	}

	virtio_transport_free_pkt(pkt);
	return err;
}

static void
virtio_transport_recv_disconnecting(struct sock *sk,
				    struct virtio_vsock_pkt *pkt)
{
	struct vsock_sock *vsk = vsock_sk(sk);

	if (le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST)
		virtio_transport_do_close(vsk, true);
}

static int
virtio_transport_send_response(struct vsock_sock *vsk,
			       struct virtio_vsock_pkt *pkt)
{
	struct virtio_vsock_pkt_info info = {
		.op = VIRTIO_VSOCK_OP_RESPONSE,
		.type = VIRTIO_VSOCK_TYPE_STREAM,
1004
		.remote_cid = le64_to_cpu(pkt->hdr.src_cid),
1005 1006
		.remote_port = le32_to_cpu(pkt->hdr.src_port),
		.reply = true,
P
Peng Tao 已提交
1007
		.vsk = vsk,
1008 1009 1010 1011 1012
	};

	return virtio_transport_send_pkt_info(vsk, &info);
}

1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
static bool virtio_transport_space_update(struct sock *sk,
					  struct virtio_vsock_pkt *pkt)
{
	struct vsock_sock *vsk = vsock_sk(sk);
	struct virtio_vsock_sock *vvs = vsk->trans;
	bool space_available;

	/* Listener sockets are not associated with any transport, so we are
	 * not able to take the state to see if there is space available in the
	 * remote peer, but since they are only used to receive requests, we
	 * can assume that there is always space available in the other peer.
	 */
	if (!vvs)
		return true;

	/* buf_alloc and fwd_cnt is always included in the hdr */
	spin_lock_bh(&vvs->tx_lock);
	vvs->peer_buf_alloc = le32_to_cpu(pkt->hdr.buf_alloc);
	vvs->peer_fwd_cnt = le32_to_cpu(pkt->hdr.fwd_cnt);
	space_available = virtio_transport_has_space(vsk);
	spin_unlock_bh(&vvs->tx_lock);
	return space_available;
}

1037 1038
/* Handle server socket */
static int
1039 1040
virtio_transport_recv_listen(struct sock *sk, struct virtio_vsock_pkt *pkt,
			     struct virtio_transport *t)
1041 1042 1043 1044
{
	struct vsock_sock *vsk = vsock_sk(sk);
	struct vsock_sock *vchild;
	struct sock *child;
1045
	int ret;
1046 1047

	if (le16_to_cpu(pkt->hdr.op) != VIRTIO_VSOCK_OP_REQUEST) {
1048
		virtio_transport_reset_no_sock(t, pkt);
1049 1050 1051 1052
		return -EINVAL;
	}

	if (sk_acceptq_is_full(sk)) {
1053
		virtio_transport_reset_no_sock(t, pkt);
1054 1055 1056
		return -ENOMEM;
	}

1057
	child = vsock_create_connected(sk);
1058
	if (!child) {
1059
		virtio_transport_reset_no_sock(t, pkt);
1060 1061 1062
		return -ENOMEM;
	}

1063
	sk_acceptq_added(sk);
1064 1065 1066

	lock_sock_nested(child, SINGLE_DEPTH_NESTING);

1067
	child->sk_state = TCP_ESTABLISHED;
1068 1069

	vchild = vsock_sk(child);
1070
	vsock_addr_init(&vchild->local_addr, le64_to_cpu(pkt->hdr.dst_cid),
1071
			le32_to_cpu(pkt->hdr.dst_port));
1072
	vsock_addr_init(&vchild->remote_addr, le64_to_cpu(pkt->hdr.src_cid),
1073 1074
			le32_to_cpu(pkt->hdr.src_port));

1075 1076 1077 1078 1079 1080
	ret = vsock_assign_transport(vchild, vsk);
	/* Transport assigned (looking at remote_addr) must be the same
	 * where we received the request.
	 */
	if (ret || vchild->transport != &t->transport) {
		release_sock(child);
1081
		virtio_transport_reset_no_sock(t, pkt);
1082 1083 1084 1085 1086 1087 1088
		sock_put(child);
		return ret;
	}

	if (virtio_transport_space_update(child, pkt))
		child->sk_write_space(child);

1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101
	vsock_insert_connected(vchild);
	vsock_enqueue_accept(sk, child);
	virtio_transport_send_response(vchild, pkt);

	release_sock(child);

	sk->sk_data_ready(sk);
	return 0;
}

/* We are under the virtio-vsock's vsock->rx_lock or vhost-vsock's vq->mutex
 * lock.
 */
1102 1103
void virtio_transport_recv_pkt(struct virtio_transport *t,
			       struct virtio_vsock_pkt *pkt)
1104 1105 1106 1107 1108 1109
{
	struct sockaddr_vm src, dst;
	struct vsock_sock *vsk;
	struct sock *sk;
	bool space_available;

1110
	vsock_addr_init(&src, le64_to_cpu(pkt->hdr.src_cid),
1111
			le32_to_cpu(pkt->hdr.src_port));
1112
	vsock_addr_init(&dst, le64_to_cpu(pkt->hdr.dst_cid),
1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124
			le32_to_cpu(pkt->hdr.dst_port));

	trace_virtio_transport_recv_pkt(src.svm_cid, src.svm_port,
					dst.svm_cid, dst.svm_port,
					le32_to_cpu(pkt->hdr.len),
					le16_to_cpu(pkt->hdr.type),
					le16_to_cpu(pkt->hdr.op),
					le32_to_cpu(pkt->hdr.flags),
					le32_to_cpu(pkt->hdr.buf_alloc),
					le32_to_cpu(pkt->hdr.fwd_cnt));

	if (le16_to_cpu(pkt->hdr.type) != VIRTIO_VSOCK_TYPE_STREAM) {
1125
		(void)virtio_transport_reset_no_sock(t, pkt);
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135
		goto free_pkt;
	}

	/* The socket must be in connected or bound table
	 * otherwise send reset back
	 */
	sk = vsock_find_connected_socket(&src, &dst);
	if (!sk) {
		sk = vsock_find_bound_socket(&dst);
		if (!sk) {
1136
			(void)virtio_transport_reset_no_sock(t, pkt);
1137 1138 1139 1140 1141 1142 1143 1144
			goto free_pkt;
		}
	}

	vsk = vsock_sk(sk);

	lock_sock(sk);

1145 1146
	/* Check if sk has been closed before lock_sock */
	if (sock_flag(sk, SOCK_DONE)) {
1147 1148 1149 1150 1151 1152
		(void)virtio_transport_reset_no_sock(t, pkt);
		release_sock(sk);
		sock_put(sk);
		goto free_pkt;
	}

1153 1154
	space_available = virtio_transport_space_update(sk, pkt);

1155 1156 1157 1158 1159 1160 1161
	/* Update CID in case it has changed after a transport reset event */
	vsk->local_addr.svm_cid = dst.svm_cid;

	if (space_available)
		sk->sk_write_space(sk);

	switch (sk->sk_state) {
1162
	case TCP_LISTEN:
1163
		virtio_transport_recv_listen(sk, pkt, t);
1164 1165
		virtio_transport_free_pkt(pkt);
		break;
1166
	case TCP_SYN_SENT:
1167 1168 1169
		virtio_transport_recv_connecting(sk, pkt);
		virtio_transport_free_pkt(pkt);
		break;
1170
	case TCP_ESTABLISHED:
1171 1172
		virtio_transport_recv_connected(sk, pkt);
		break;
1173
	case TCP_CLOSING:
1174 1175 1176 1177
		virtio_transport_recv_disconnecting(sk, pkt);
		virtio_transport_free_pkt(pkt);
		break;
	default:
1178
		(void)virtio_transport_reset_no_sock(t, pkt);
1179 1180 1181
		virtio_transport_free_pkt(pkt);
		break;
	}
1182

1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205
	release_sock(sk);

	/* Release refcnt obtained when we fetched this socket out of the
	 * bound or connected list.
	 */
	sock_put(sk);
	return;

free_pkt:
	virtio_transport_free_pkt(pkt);
}
EXPORT_SYMBOL_GPL(virtio_transport_recv_pkt);

void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt)
{
	kfree(pkt->buf);
	kfree(pkt);
}
EXPORT_SYMBOL_GPL(virtio_transport_free_pkt);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Asias He");
MODULE_DESCRIPTION("common code for virtio vsock");