diff options
| -rw-r--r-- | net/vmw_vsock/af_vsock.c | 6 | ||||
| -rw-r--r-- | net/vmw_vsock/vmci_transport.c | 31 | ||||
| -rw-r--r-- | net/vmw_vsock/vsock_addr.c | 10 | ||||
| -rw-r--r-- | net/vmw_vsock/vsock_addr.h | 2 |
4 files changed, 23 insertions, 26 deletions
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index ca511c4f388a..d8079daf1bde 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
| @@ -207,7 +207,7 @@ static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr) | |||
| 207 | struct vsock_sock *vsk; | 207 | struct vsock_sock *vsk; |
| 208 | 208 | ||
| 209 | list_for_each_entry(vsk, vsock_bound_sockets(addr), bound_table) | 209 | list_for_each_entry(vsk, vsock_bound_sockets(addr), bound_table) |
| 210 | if (vsock_addr_equals_addr_any(addr, &vsk->local_addr)) | 210 | if (addr->svm_port == vsk->local_addr.svm_port) |
| 211 | return sk_vsock(vsk); | 211 | return sk_vsock(vsk); |
| 212 | 212 | ||
| 213 | return NULL; | 213 | return NULL; |
| @@ -220,8 +220,8 @@ static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src, | |||
| 220 | 220 | ||
| 221 | list_for_each_entry(vsk, vsock_connected_sockets(src, dst), | 221 | list_for_each_entry(vsk, vsock_connected_sockets(src, dst), |
| 222 | connected_table) { | 222 | connected_table) { |
| 223 | if (vsock_addr_equals_addr(src, &vsk->remote_addr) | 223 | if (vsock_addr_equals_addr(src, &vsk->remote_addr) && |
| 224 | && vsock_addr_equals_addr(dst, &vsk->local_addr)) { | 224 | dst->svm_port == vsk->local_addr.svm_port) { |
| 225 | return sk_vsock(vsk); | 225 | return sk_vsock(vsk); |
| 226 | } | 226 | } |
| 227 | } | 227 | } |
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index a70ace83a153..1f6508e249ae 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c | |||
| @@ -464,19 +464,16 @@ static struct sock *vmci_transport_get_pending( | |||
| 464 | struct vsock_sock *vlistener; | 464 | struct vsock_sock *vlistener; |
| 465 | struct vsock_sock *vpending; | 465 | struct vsock_sock *vpending; |
| 466 | struct sock *pending; | 466 | struct sock *pending; |
| 467 | struct sockaddr_vm src; | ||
| 468 | |||
| 469 | vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); | ||
| 467 | 470 | ||
| 468 | vlistener = vsock_sk(listener); | 471 | vlistener = vsock_sk(listener); |
| 469 | 472 | ||
| 470 | list_for_each_entry(vpending, &vlistener->pending_links, | 473 | list_for_each_entry(vpending, &vlistener->pending_links, |
| 471 | pending_links) { | 474 | pending_links) { |
| 472 | struct sockaddr_vm src; | ||
| 473 | struct sockaddr_vm dst; | ||
| 474 | |||
| 475 | vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); | ||
| 476 | vsock_addr_init(&dst, pkt->dg.dst.context, pkt->dst_port); | ||
| 477 | |||
| 478 | if (vsock_addr_equals_addr(&src, &vpending->remote_addr) && | 475 | if (vsock_addr_equals_addr(&src, &vpending->remote_addr) && |
| 479 | vsock_addr_equals_addr(&dst, &vpending->local_addr)) { | 476 | pkt->dst_port == vpending->local_addr.svm_port) { |
| 480 | pending = sk_vsock(vpending); | 477 | pending = sk_vsock(vpending); |
| 481 | sock_hold(pending); | 478 | sock_hold(pending); |
| 482 | goto found; | 479 | goto found; |
| @@ -739,10 +736,15 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg) | |||
| 739 | */ | 736 | */ |
| 740 | bh_lock_sock(sk); | 737 | bh_lock_sock(sk); |
| 741 | 738 | ||
| 742 | if (!sock_owned_by_user(sk) && sk->sk_state == SS_CONNECTED) | 739 | if (!sock_owned_by_user(sk)) { |
| 743 | vmci_trans(vsk)->notify_ops->handle_notify_pkt( | 740 | /* The local context ID may be out of date, update it. */ |
| 744 | sk, pkt, true, &dst, &src, | 741 | vsk->local_addr.svm_cid = dst.svm_cid; |
| 745 | &bh_process_pkt); | 742 | |
| 743 | if (sk->sk_state == SS_CONNECTED) | ||
| 744 | vmci_trans(vsk)->notify_ops->handle_notify_pkt( | ||
| 745 | sk, pkt, true, &dst, &src, | ||
| 746 | &bh_process_pkt); | ||
| 747 | } | ||
| 746 | 748 | ||
| 747 | bh_unlock_sock(sk); | 749 | bh_unlock_sock(sk); |
| 748 | 750 | ||
| @@ -902,6 +904,9 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work) | |||
| 902 | 904 | ||
| 903 | lock_sock(sk); | 905 | lock_sock(sk); |
| 904 | 906 | ||
| 907 | /* The local context ID may be out of date. */ | ||
| 908 | vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context; | ||
| 909 | |||
| 905 | switch (sk->sk_state) { | 910 | switch (sk->sk_state) { |
| 906 | case SS_LISTEN: | 911 | case SS_LISTEN: |
| 907 | vmci_transport_recv_listen(sk, pkt); | 912 | vmci_transport_recv_listen(sk, pkt); |
| @@ -958,6 +963,10 @@ static int vmci_transport_recv_listen(struct sock *sk, | |||
| 958 | pending = vmci_transport_get_pending(sk, pkt); | 963 | pending = vmci_transport_get_pending(sk, pkt); |
| 959 | if (pending) { | 964 | if (pending) { |
| 960 | lock_sock(pending); | 965 | lock_sock(pending); |
| 966 | |||
| 967 | /* The local context ID may be out of date. */ | ||
| 968 | vsock_sk(pending)->local_addr.svm_cid = pkt->dg.dst.context; | ||
| 969 | |||
| 961 | switch (pending->sk_state) { | 970 | switch (pending->sk_state) { |
| 962 | case SS_CONNECTING: | 971 | case SS_CONNECTING: |
| 963 | err = vmci_transport_recv_connecting_server(sk, | 972 | err = vmci_transport_recv_connecting_server(sk, |
diff --git a/net/vmw_vsock/vsock_addr.c b/net/vmw_vsock/vsock_addr.c index b7df1aea7c59..ec2611b4ea0e 100644 --- a/net/vmw_vsock/vsock_addr.c +++ b/net/vmw_vsock/vsock_addr.c | |||
| @@ -64,16 +64,6 @@ bool vsock_addr_equals_addr(const struct sockaddr_vm *addr, | |||
| 64 | } | 64 | } |
| 65 | EXPORT_SYMBOL_GPL(vsock_addr_equals_addr); | 65 | EXPORT_SYMBOL_GPL(vsock_addr_equals_addr); |
| 66 | 66 | ||
| 67 | bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr, | ||
| 68 | const struct sockaddr_vm *other) | ||
| 69 | { | ||
| 70 | return (addr->svm_cid == VMADDR_CID_ANY || | ||
| 71 | other->svm_cid == VMADDR_CID_ANY || | ||
| 72 | addr->svm_cid == other->svm_cid) && | ||
| 73 | addr->svm_port == other->svm_port; | ||
| 74 | } | ||
| 75 | EXPORT_SYMBOL_GPL(vsock_addr_equals_addr_any); | ||
| 76 | |||
| 77 | int vsock_addr_cast(const struct sockaddr *addr, | 67 | int vsock_addr_cast(const struct sockaddr *addr, |
| 78 | size_t len, struct sockaddr_vm **out_addr) | 68 | size_t len, struct sockaddr_vm **out_addr) |
| 79 | { | 69 | { |
diff --git a/net/vmw_vsock/vsock_addr.h b/net/vmw_vsock/vsock_addr.h index cdfbcefdf843..9ccd5316eac0 100644 --- a/net/vmw_vsock/vsock_addr.h +++ b/net/vmw_vsock/vsock_addr.h | |||
| @@ -24,8 +24,6 @@ bool vsock_addr_bound(const struct sockaddr_vm *addr); | |||
| 24 | void vsock_addr_unbind(struct sockaddr_vm *addr); | 24 | void vsock_addr_unbind(struct sockaddr_vm *addr); |
| 25 | bool vsock_addr_equals_addr(const struct sockaddr_vm *addr, | 25 | bool vsock_addr_equals_addr(const struct sockaddr_vm *addr, |
| 26 | const struct sockaddr_vm *other); | 26 | const struct sockaddr_vm *other); |
| 27 | bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr, | ||
| 28 | const struct sockaddr_vm *other); | ||
| 29 | int vsock_addr_cast(const struct sockaddr *addr, size_t len, | 27 | int vsock_addr_cast(const struct sockaddr *addr, size_t len, |
| 30 | struct sockaddr_vm **out_addr); | 28 | struct sockaddr_vm **out_addr); |
| 31 | 29 | ||
