aboutsummaryrefslogtreecommitdiffstats
path: root/net/vmw_vsock/vmci_transport.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-04-03 01:31:54 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-03 01:31:54 -0400
commitd66248326410ed0d3e813ebe974b3e6638df0717 (patch)
treea1dbe86f5540596a70c6f3b9aab051d37f37daf5 /net/vmw_vsock/vmci_transport.c
parent8facd5fb73c6e960555e5913743dfbb6c3d984a5 (diff)
parentda241efcd9c3da2af6ba20055c7e158ec725005c (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull net into net-next to get the synchronize_net() bug fix in bonding. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/vmw_vsock/vmci_transport.c')
-rw-r--r--net/vmw_vsock/vmci_transport.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index faf81b8c1a3a..9caa91c0bdaf 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -472,19 +472,16 @@ static struct sock *vmci_transport_get_pending(
472 struct vsock_sock *vlistener; 472 struct vsock_sock *vlistener;
473 struct vsock_sock *vpending; 473 struct vsock_sock *vpending;
474 struct sock *pending; 474 struct sock *pending;
475 struct sockaddr_vm src;
476
477 vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port);
475 478
476 vlistener = vsock_sk(listener); 479 vlistener = vsock_sk(listener);
477 480
478 list_for_each_entry(vpending, &vlistener->pending_links, 481 list_for_each_entry(vpending, &vlistener->pending_links,
479 pending_links) { 482 pending_links) {
480 struct sockaddr_vm src;
481 struct sockaddr_vm dst;
482
483 vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port);
484 vsock_addr_init(&dst, pkt->dg.dst.context, pkt->dst_port);
485
486 if (vsock_addr_equals_addr(&src, &vpending->remote_addr) && 483 if (vsock_addr_equals_addr(&src, &vpending->remote_addr) &&
487 vsock_addr_equals_addr(&dst, &vpending->local_addr)) { 484 pkt->dst_port == vpending->local_addr.svm_port) {
488 pending = sk_vsock(vpending); 485 pending = sk_vsock(vpending);
489 sock_hold(pending); 486 sock_hold(pending);
490 goto found; 487 goto found;
@@ -749,10 +746,15 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
749 */ 746 */
750 bh_lock_sock(sk); 747 bh_lock_sock(sk);
751 748
752 if (!sock_owned_by_user(sk) && sk->sk_state == SS_CONNECTED) 749 if (!sock_owned_by_user(sk)) {
753 vmci_trans(vsk)->notify_ops->handle_notify_pkt( 750 /* The local context ID may be out of date, update it. */
754 sk, pkt, true, &dst, &src, 751 vsk->local_addr.svm_cid = dst.svm_cid;
755 &bh_process_pkt); 752
753 if (sk->sk_state == SS_CONNECTED)
754 vmci_trans(vsk)->notify_ops->handle_notify_pkt(
755 sk, pkt, true, &dst, &src,
756 &bh_process_pkt);
757 }
756 758
757 bh_unlock_sock(sk); 759 bh_unlock_sock(sk);
758 760
@@ -912,6 +914,9 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work)
912 914
913 lock_sock(sk); 915 lock_sock(sk);
914 916
917 /* The local context ID may be out of date. */
918 vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context;
919
915 switch (sk->sk_state) { 920 switch (sk->sk_state) {
916 case SS_LISTEN: 921 case SS_LISTEN:
917 vmci_transport_recv_listen(sk, pkt); 922 vmci_transport_recv_listen(sk, pkt);
@@ -968,6 +973,10 @@ static int vmci_transport_recv_listen(struct sock *sk,
968 pending = vmci_transport_get_pending(sk, pkt); 973 pending = vmci_transport_get_pending(sk, pkt);
969 if (pending) { 974 if (pending) {
970 lock_sock(pending); 975 lock_sock(pending);
976
977 /* The local context ID may be out of date. */
978 vsock_sk(pending)->local_addr.svm_cid = pkt->dg.dst.context;
979
971 switch (pending->sk_state) { 980 switch (pending->sk_state) {
972 case SS_CONNECTING: 981 case SS_CONNECTING:
973 err = vmci_transport_recv_connecting_server(sk, 982 err = vmci_transport_recv_connecting_server(sk,