diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-02 18:58:01 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-02 18:58:01 -0700 |
commit | da241efcd9c3da2af6ba20055c7e158ec725005c (patch) | |
tree | f104cfbd25b2b88f4b246d2da14241a4a038cd0b /net/vmw_vsock/vmci_transport.c | |
parent | 6e8517a90b41b57d66926286c0add31145c75eb6 (diff) | |
parent | 990454b5a48babde44a23c0f22bae5523f4fdf13 (diff) | |
download | linux-stable-da241efcd9c3da2af6ba20055c7e158ec725005c.tar.gz linux-stable-da241efcd9c3da2af6ba20055c7e158ec725005c.tar.bz2 linux-stable-da241efcd9c3da2af6ba20055c7e158ec725005c.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
1) Fix VSOCK layer handling of context ID changes, from Reilly Grant.
2) Now that we have a synchronize_net() in netdev_rx_handler_unregister(),
we can't let any call sites hold locks. Unfortunately bonding does,
so we have to drop the rwlock there a little bit earlier, fix from
Veaceslav Falico.
3) MAC address setting loop exits one iteration too early in mlx4
driver, from Yan Burman.
4) Restore ipv6 routes properly upon ifdown/ifup of loopback, from
Balakumaran Kannan.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
VSOCK: Handle changes to the VMCI context ID.
net IPv6 : Fix broken IPv6 routing table after loopback down-up
cbq: incorrect processing of high limits
net/mlx4_en: Fix setting initial MAC address
bonding: get netdev_rx_handler_unregister out of locks
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( struct vsock_sock *vlistener; struct vsock_sock *vpending; struct sock *pending; + struct sockaddr_vm src; + + vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); vlistener = vsock_sk(listener); list_for_each_entry(vpending, &vlistener->pending_links, pending_links) { - struct sockaddr_vm src; - struct sockaddr_vm dst; - - vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); - vsock_addr_init(&dst, pkt->dg.dst.context, pkt->dst_port); - if (vsock_addr_equals_addr(&src, &vpending->remote_addr) && - vsock_addr_equals_addr(&dst, &vpending->local_addr)) { + pkt->dst_port == vpending->local_addr.svm_port) { pending = sk_vsock(vpending); sock_hold(pending); goto found; @@ -739,10 +736,15 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg) */ bh_lock_sock(sk); - if (!sock_owned_by_user(sk) && sk->sk_state == SS_CONNECTED) - vmci_trans(vsk)->notify_ops->handle_notify_pkt( - sk, pkt, true, &dst, &src, - &bh_process_pkt); + if (!sock_owned_by_user(sk)) { + /* The local context ID may be out of date, update it. */ + vsk->local_addr.svm_cid = dst.svm_cid; + + if (sk->sk_state == SS_CONNECTED) + vmci_trans(vsk)->notify_ops->handle_notify_pkt( + sk, pkt, true, &dst, &src, + &bh_process_pkt); + } bh_unlock_sock(sk); @@ -902,6 +904,9 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work) lock_sock(sk); + /* The local context ID may be out of date. */ + vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context; + switch (sk->sk_state) { case SS_LISTEN: vmci_transport_recv_listen(sk, pkt); @@ -958,6 +963,10 @@ static int vmci_transport_recv_listen(struct sock *sk, pending = vmci_transport_get_pending(sk, pkt); if (pending) { lock_sock(pending); + + /* The local context ID may be out of date. */ + vsock_sk(pending)->local_addr.svm_cid = pkt->dg.dst.context; + switch (pending->sk_state) { case SS_CONNECTING: err = vmci_transport_recv_connecting_server(sk, |