diff options
Diffstat (limited to 'net/vmw_vsock/vmci_transport.c')
-rw-r--r-- | net/vmw_vsock/vmci_transport.c | 31 |
1 files changed, 20 insertions, 11 deletions
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, |