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 | EXPORT_SYMBOL_GPL(vsock_enqueue_accept); | 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 | static void vsock_deassign_transport(struct vsock_sock *vsk) | 406 | static void vsock_deassign_transport(struct vsock_sock *vsk) |
| 392 | { | 407 | { |
| 393 | if (!vsk->transport) | 408 | if (!vsk->transport) |
| @@ -404,9 +419,9 @@ static void vsock_deassign_transport(struct vsock_sock *vsk) · 10 unmodified lines | |||
| 404 | * (e.g. during the connect() or when a connection request on a listener | 419 | * (e.g. during the connect() or when a connection request on a listener |
| 405 | * socket is received). | 420 | * socket is received). |
| 406 | * The vsk->remote_addr is used to decide which transport to use: | 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 | * - remote CID <= VMADDR_CID_HOST will use guest->host transport; | 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 | * - remote CID > VMADDR_CID_HOST will use host->guest transport; | 425 | * - remote CID > VMADDR_CID_HOST will use host->guest transport; |
| 411 | */ | 426 | */ |
| 412 | int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) | 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 | new_transport = transport_dgram; | 436 | new_transport = transport_dgram; |
| 422 | break; | 437 | break; |
| 423 | case SOCK_STREAM: | 438 | case SOCK_STREAM: |
| 424 | if (remote_cid <= VMADDR_CID_HOST || | 439 | if (vsock_use_local_transport(remote_cid)) |
| 425 | (transport_g2h && | 440 | new_transport = transport_local; |
| 426 | remote_cid == transport_g2h->get_local_cid())) | 441 | else if (remote_cid <= VMADDR_CID_HOST) |
| 427 | new_transport = transport_g2h; | 442 | new_transport = transport_g2h; |
| 428 | else | 443 | else |
| 429 | new_transport = transport_h2g; | 444 | new_transport = transport_h2g; |
| @@ -466,6 +481,9 @@ bool vsock_find_cid(unsigned int cid) · 36 unmodified lines | |||
| 466 | if (transport_h2g && cid == VMADDR_CID_HOST) | 481 | if (transport_h2g && cid == VMADDR_CID_HOST) |
| 467 | return true; | 482 | return true; |
| 468 | 483 | ||
| 484 | if (transport_local && cid == VMADDR_CID_LOCAL) | ||
| 485 | return true; | ||
| 486 | |||
| 469 | return false; | 487 | return false; |
| 470 | } | 488 | } |
| 471 | EXPORT_SYMBOL_GPL(vsock_find_cid); | 489 | EXPORT_SYMBOL_GPL(vsock_find_cid); |