Now that we have a transport that can handle the local communication, we can use it when it is loaded. A socket will use the local transport (loopback) when the remote CID is: - equal to VMADDR_CID_LOCAL - or equal to transport_g2h->get_local_cid(), if transport_g2h is loaded (this allows us to keep the same behavior implemented by virtio and vmci transports) - or equal to VMADDR_CID_HOST, if transport_g2h is not loaded
Unified · Split
| @@ -388,6 +388,21 @@ void vsock_enqueue_accept(struct sock *listener, struct sock *connected) · 387 unmodified lines | ||
| 388 | 388 | } |
| 389 | 389 | EXPORT_SYMBOL_GPL(vsock_enqueue_accept); |
| 390 | 390 | |
| 391 | +static bool vsock_use_local_transport(unsigned int remote_cid) | |
| 392 | +{ | |
| 393 | + if (!transport_local) | |
| 394 | + return false; | |
| 395 | + | |
| 396 | + if (remote_cid == VMADDR_CID_LOCAL) | |
| 397 | + return true; | |
| 398 | + | |
| 399 | + if (transport_g2h) { | |
| 400 | + return remote_cid == transport_g2h->get_local_cid(); | |
| 401 | + } else { | |
| 402 | + return remote_cid == VMADDR_CID_HOST; | |
| 403 | + } | |
| 404 | +} | |
| 405 | + | |
| 391 | 406 | static void vsock_deassign_transport(struct vsock_sock *vsk) |
| 392 | 407 | { |
| 393 | 408 | if (!vsk->transport) |
| @@ -404,9 +419,9 @@ static void vsock_deassign_transport(struct vsock_sock *vsk) · 10 unmodified lines | ||
| 404 | 419 | * (e.g. during the connect() or when a connection request on a listener |
| 405 | 420 | * socket is received). |
| 406 | 421 | * The vsk->remote_addr is used to decide which transport to use: |
| 422 | + * - remote CID == VMADDR_CID_LOCAL or g2h->local_cid or VMADDR_CID_HOST if | |
| 423 | + * g2h is not loaded, will use local transport; | |
| 407 | 424 | * - remote CID <= VMADDR_CID_HOST will use guest->host transport; |
| 408 | − * - remote CID == local_cid (guest->host transport) will use guest->host | |
| 409 | − * transport for loopback (host->guest transports don't support loopback); | |
| 410 | 425 | * - remote CID > VMADDR_CID_HOST will use host->guest transport; |
| 411 | 426 | */ |
| 412 | 427 | int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) |
| @@ -421,9 +436,9 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) · 8 unmodified lines | ||
| 421 | 436 | new_transport = transport_dgram; |
| 422 | 437 | break; |
| 423 | 438 | case SOCK_STREAM: |
| 424 | − if (remote_cid <= VMADDR_CID_HOST || | |
| 425 | − (transport_g2h && | |
| 426 | − remote_cid == transport_g2h->get_local_cid())) | |
| 439 | + if (vsock_use_local_transport(remote_cid)) | |
| 440 | + new_transport = transport_local; | |
| 441 | + else if (remote_cid <= VMADDR_CID_HOST) | |
| 427 | 442 | new_transport = transport_g2h; |
| 428 | 443 | else |
| 429 | 444 | new_transport = transport_h2g; |
| @@ -466,6 +481,9 @@ bool vsock_find_cid(unsigned int cid) · 36 unmodified lines | ||
| 466 | 481 | if (transport_h2g && cid == VMADDR_CID_HOST) |
| 467 | 482 | return true; |
| 468 | 483 | |
| 484 | + if (transport_local && cid == VMADDR_CID_LOCAL) | |
| 485 | + return true; | |
| 486 | + | |
| 469 | 487 | return false; |
| 470 | 488 | } |
| 471 | 489 | EXPORT_SYMBOL_GPL(vsock_find_cid); |