From patchwork Thu Nov 28 17:15:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Garzarella X-Patchwork-Id: 11266427 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F064C921 for ; Thu, 28 Nov 2019 17:15:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BE18F217AB for ; Thu, 28 Nov 2019 17:15:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="WoZ35YLm" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727005AbfK1RPh (ORCPT ); Thu, 28 Nov 2019 12:15:37 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:23778 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726937AbfK1RPg (ORCPT ); Thu, 28 Nov 2019 12:15:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1574961334; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EJ8wmKVAVGzwQy9RJeA/HRES3+N97aoUgTm4JmySAyU=; b=WoZ35YLmpIA4mLtYJWzHwdpbUazCzX7k9wt8k+F7+0OucWXABbt+wb6PJJuvqHvzQTbvUl kHwe3ugfUK7zk/I5Z2Rgs7reiXmOSVHHDp9LLWg08tYEtlkID1LywYMsnhmgHxUu4taSLc bmiScLYcPl+Q9QDSrF4uGORWBjSMnhw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-2--QKnLjt9PjOK2AeJ3ke5Mw-1; Thu, 28 Nov 2019 12:15:32 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2B7C3107ACC4; Thu, 28 Nov 2019 17:15:31 +0000 (UTC) Received: from steredhat.redhat.com (ovpn-117-168.ams2.redhat.com [10.36.117.168]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9CB89600C8; Thu, 28 Nov 2019 17:15:28 +0000 (UTC) From: Stefano Garzarella To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, virtualization@lists.linux-foundation.org, kvm@vger.kernel.org, "Michael S. Tsirkin" , Stefano Garzarella , "David S. Miller" , Dexuan Cui , Jason Wang , Stefan Hajnoczi , Jorgen Hansen Subject: [RFC PATCH 1/3] vsock: add network namespace support Date: Thu, 28 Nov 2019 18:15:17 +0100 Message-Id: <20191128171519.203979-2-sgarzare@redhat.com> In-Reply-To: <20191128171519.203979-1-sgarzare@redhat.com> References: <20191128171519.203979-1-sgarzare@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-MC-Unique: -QKnLjt9PjOK2AeJ3ke5Mw-1 X-Mimecast-Spam-Score: 0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This patch adds a check of the "net" assigned to a socket during the vsock_find_bound_socket() and vsock_find_connected_socket() to support network namespace, allowing to share the same address (cid, port) across different network namespaces. G2H transports will use the default network namepsace (init_net). H2G transports can use different network namespace for different VMs. This patch uses default network namepsace (init_net) in all transports. Signed-off-by: Stefano Garzarella --- include/net/af_vsock.h | 6 +++-- net/vmw_vsock/af_vsock.c | 31 ++++++++++++++++++------- net/vmw_vsock/hyperv_transport.c | 5 ++-- net/vmw_vsock/virtio_transport_common.c | 5 ++-- net/vmw_vsock/vmci_transport.c | 5 ++-- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index b1c717286993..fb7dcf73af5b 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -193,13 +193,15 @@ void vsock_enqueue_accept(struct sock *listener, struct sock *connected); void vsock_insert_connected(struct vsock_sock *vsk); void vsock_remove_bound(struct vsock_sock *vsk); void vsock_remove_connected(struct vsock_sock *vsk); -struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr); +struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr, struct net *net); struct sock *vsock_find_connected_socket(struct sockaddr_vm *src, - struct sockaddr_vm *dst); + struct sockaddr_vm *dst, + struct net *net); void vsock_remove_sock(struct vsock_sock *vsk); void vsock_for_each_connected_socket(void (*fn)(struct sock *sk)); int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk); bool vsock_find_cid(unsigned int cid); +struct net *vsock_default_net(void); /**** TAP ****/ diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 9c5b2a91baad..b485b4a4e3e9 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -226,15 +226,18 @@ static void __vsock_remove_connected(struct vsock_sock *vsk) sock_put(&vsk->sk); } -static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr) +static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr, + struct net *net) { struct vsock_sock *vsk; list_for_each_entry(vsk, vsock_bound_sockets(addr), bound_table) { - if (vsock_addr_equals_addr(addr, &vsk->local_addr)) + if (vsock_addr_equals_addr(addr, &vsk->local_addr) && + net_eq(net, sock_net(sk_vsock(vsk)))) return sk_vsock(vsk); if (addr->svm_port == vsk->local_addr.svm_port && + net_eq(net, sock_net(sk_vsock(vsk))) && (vsk->local_addr.svm_cid == VMADDR_CID_ANY || addr->svm_cid == VMADDR_CID_ANY)) return sk_vsock(vsk); @@ -244,13 +247,15 @@ static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr) } static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src, - struct sockaddr_vm *dst) + struct sockaddr_vm *dst, + struct net *net) { struct vsock_sock *vsk; list_for_each_entry(vsk, vsock_connected_sockets(src, dst), connected_table) { if (vsock_addr_equals_addr(src, &vsk->remote_addr) && + net_eq(net, sock_net(sk_vsock(vsk))) && dst->svm_port == vsk->local_addr.svm_port) { return sk_vsock(vsk); } @@ -295,12 +300,12 @@ void vsock_remove_connected(struct vsock_sock *vsk) } EXPORT_SYMBOL_GPL(vsock_remove_connected); -struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr) +struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr, struct net *net) { struct sock *sk; spin_lock_bh(&vsock_table_lock); - sk = __vsock_find_bound_socket(addr); + sk = __vsock_find_bound_socket(addr, net); if (sk) sock_hold(sk); @@ -311,12 +316,13 @@ struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr) EXPORT_SYMBOL_GPL(vsock_find_bound_socket); struct sock *vsock_find_connected_socket(struct sockaddr_vm *src, - struct sockaddr_vm *dst) + struct sockaddr_vm *dst, + struct net *net) { struct sock *sk; spin_lock_bh(&vsock_table_lock); - sk = __vsock_find_connected_socket(src, dst); + sk = __vsock_find_connected_socket(src, dst, net); if (sk) sock_hold(sk); @@ -488,6 +494,12 @@ bool vsock_find_cid(unsigned int cid) } EXPORT_SYMBOL_GPL(vsock_find_cid); +struct net *vsock_default_net(void) +{ + return &init_net; +} +EXPORT_SYMBOL_GPL(vsock_default_net); + static struct sock *vsock_dequeue_accept(struct sock *listener) { struct vsock_sock *vlistener; @@ -586,6 +598,7 @@ static int __vsock_bind_stream(struct vsock_sock *vsk, { static u32 port; struct sockaddr_vm new_addr; + struct net *net = sock_net(sk_vsock(vsk)); if (!port) port = LAST_RESERVED_PORT + 1 + @@ -603,7 +616,7 @@ static int __vsock_bind_stream(struct vsock_sock *vsk, new_addr.svm_port = port++; - if (!__vsock_find_bound_socket(&new_addr)) { + if (!__vsock_find_bound_socket(&new_addr, net)) { found = true; break; } @@ -620,7 +633,7 @@ static int __vsock_bind_stream(struct vsock_sock *vsk, return -EACCES; } - if (__vsock_find_bound_socket(&new_addr)) + if (__vsock_find_bound_socket(&new_addr, net)) return -EADDRINUSE; } diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c index 3c7d07a99fc5..fc48a861a0bc 100644 --- a/net/vmw_vsock/hyperv_transport.c +++ b/net/vmw_vsock/hyperv_transport.c @@ -201,7 +201,8 @@ static void hvs_remote_addr_init(struct sockaddr_vm *remote, remote->svm_port = host_ephemeral_port++; - sk = vsock_find_connected_socket(remote, local); + sk = vsock_find_connected_socket(remote, local, + vsock_default_net()); if (!sk) { /* Found an available ephemeral port */ return; @@ -350,7 +351,7 @@ static void hvs_open_connection(struct vmbus_channel *chan) return; hvs_addr_init(&addr, conn_from_host ? if_type : if_instance); - sk = vsock_find_bound_socket(&addr); + sk = vsock_find_bound_socket(&addr, vsock_default_net()); if (!sk) return; diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index 0e20b0f6eb65..10a8cbe39f61 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -1075,6 +1075,7 @@ virtio_transport_recv_listen(struct sock *sk, struct virtio_vsock_pkt *pkt, void virtio_transport_recv_pkt(struct virtio_transport *t, struct virtio_vsock_pkt *pkt) { + struct net *net = vsock_default_net(); struct sockaddr_vm src, dst; struct vsock_sock *vsk; struct sock *sk; @@ -1102,9 +1103,9 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, /* The socket must be in connected or bound table * otherwise send reset back */ - sk = vsock_find_connected_socket(&src, &dst); + sk = vsock_find_connected_socket(&src, &dst, net); if (!sk) { - sk = vsock_find_bound_socket(&dst); + sk = vsock_find_bound_socket(&dst, net); if (!sk) { (void)virtio_transport_reset_no_sock(t, pkt); goto free_pkt; diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 4b8b1150a738..3ad15d51b30b 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -669,6 +669,7 @@ static bool vmci_transport_stream_allow(u32 cid, u32 port) static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg) { + struct net *net = vsock_default_net(); struct sock *sk; struct sockaddr_vm dst; struct sockaddr_vm src; @@ -702,9 +703,9 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg) vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); vsock_addr_init(&dst, pkt->dg.dst.context, pkt->dst_port); - sk = vsock_find_connected_socket(&src, &dst); + sk = vsock_find_connected_socket(&src, &dst, net); if (!sk) { - sk = vsock_find_bound_socket(&dst); + sk = vsock_find_bound_socket(&dst, net); if (!sk) { /* We could not find a socket for this specified * address. If this packet is a RST, we just drop it. From patchwork Thu Nov 28 17:15:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Garzarella X-Patchwork-Id: 11266431 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 40E46921 for ; Thu, 28 Nov 2019 17:15:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 189A221771 for ; Thu, 28 Nov 2019 17:15:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Gme6DFps" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727111AbfK1RPv (ORCPT ); Thu, 28 Nov 2019 12:15:51 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:22180 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727016AbfK1RPj (ORCPT ); Thu, 28 Nov 2019 12:15:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1574961338; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5auX1CvYbu3yZRsbt+Lmj7tuXc5Und38I/LjU8EXijg=; b=Gme6DFpsmRq90pucWX4aOMaMgl31v9cybP0/xu8Gh1mpREG/GQ0hM7j87fTYqwygqAtXmh gZnDQKTMvOzx9RyJIVxochWg3OuDpHcwoerPByyzi329lbx41MnNDg6069PWfFPBCH153P MBqVv3YRgI5e5jqfXhwg/zs59QnSo/8= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-191-j_2Yy6OxNziUa1CniJMwSw-1; Thu, 28 Nov 2019 12:15:35 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id DDD8D107ACC4; Thu, 28 Nov 2019 17:15:33 +0000 (UTC) Received: from steredhat.redhat.com (ovpn-117-168.ams2.redhat.com [10.36.117.168]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7723B600C8; Thu, 28 Nov 2019 17:15:31 +0000 (UTC) From: Stefano Garzarella To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, virtualization@lists.linux-foundation.org, kvm@vger.kernel.org, "Michael S. Tsirkin" , Stefano Garzarella , "David S. Miller" , Dexuan Cui , Jason Wang , Stefan Hajnoczi , Jorgen Hansen Subject: [RFC PATCH 2/3] vsock/virtio_transport_common: handle netns of received packets Date: Thu, 28 Nov 2019 18:15:18 +0100 Message-Id: <20191128171519.203979-3-sgarzare@redhat.com> In-Reply-To: <20191128171519.203979-1-sgarzare@redhat.com> References: <20191128171519.203979-1-sgarzare@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-MC-Unique: j_2Yy6OxNziUa1CniJMwSw-1 X-Mimecast-Spam-Score: 0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This patch allows transports that use virtio_transport_common to specify the network namespace where a received packet is to be delivered. virtio_transport and vhost_transport, for now, use the default network namespace. vsock_loopback uses the same network namespace of the trasmitter. Signed-off-by: Stefano Garzarella --- drivers/vhost/vsock.c | 1 + include/linux/virtio_vsock.h | 2 ++ net/vmw_vsock/virtio_transport.c | 2 ++ net/vmw_vsock/virtio_transport_common.c | 13 ++++++++++--- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index dde392b91bb3..31b0f3608752 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -474,6 +474,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) continue; } + pkt->net = vsock_default_net(); len = pkt->len; /* Deliver to monitoring devices all received packets */ diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h index 71c81e0dc8f2..a025d105a456 100644 --- a/include/linux/virtio_vsock.h +++ b/include/linux/virtio_vsock.h @@ -43,6 +43,7 @@ struct virtio_vsock_pkt { struct list_head list; /* socket refcnt not held, only use for cancellation */ struct vsock_sock *vsk; + struct net *net; void *buf; u32 buf_len; u32 len; @@ -53,6 +54,7 @@ struct virtio_vsock_pkt { struct virtio_vsock_pkt_info { u32 remote_cid, remote_port; struct vsock_sock *vsk; + struct net *net; struct msghdr *msg; u32 pkt_len; u16 type; diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c index dfbaf6bd8b1c..fb03a1535c21 100644 --- a/net/vmw_vsock/virtio_transport.c +++ b/net/vmw_vsock/virtio_transport.c @@ -527,6 +527,8 @@ static void virtio_transport_rx_work(struct work_struct *work) } pkt->len = len - sizeof(pkt->hdr); + pkt->net = vsock_default_net(); + virtio_transport_deliver_tap_pkt(pkt); virtio_transport_recv_pkt(&virtio_transport, pkt); } diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index 10a8cbe39f61..f249dc099c38 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -60,6 +60,7 @@ virtio_transport_alloc_pkt(struct virtio_vsock_pkt_info *info, pkt->hdr.len = cpu_to_le32(len); pkt->reply = info->reply; pkt->vsk = info->vsk; + pkt->net = info->net; if (info->msg && len > 0) { pkt->buf = kmalloc(len, GFP_KERNEL); @@ -260,6 +261,7 @@ static int virtio_transport_send_credit_update(struct vsock_sock *vsk, .op = VIRTIO_VSOCK_OP_CREDIT_UPDATE, .type = type, .vsk = vsk, + .net = sock_net(sk_vsock(vsk)), }; return virtio_transport_send_pkt_info(vsk, &info); @@ -609,6 +611,7 @@ int virtio_transport_connect(struct vsock_sock *vsk) .op = VIRTIO_VSOCK_OP_REQUEST, .type = VIRTIO_VSOCK_TYPE_STREAM, .vsk = vsk, + .net = sock_net(sk_vsock(vsk)), }; return virtio_transport_send_pkt_info(vsk, &info); @@ -625,6 +628,7 @@ int virtio_transport_shutdown(struct vsock_sock *vsk, int mode) (mode & SEND_SHUTDOWN ? VIRTIO_VSOCK_SHUTDOWN_SEND : 0), .vsk = vsk, + .net = sock_net(sk_vsock(vsk)), }; return virtio_transport_send_pkt_info(vsk, &info); @@ -652,6 +656,7 @@ virtio_transport_stream_enqueue(struct vsock_sock *vsk, .msg = msg, .pkt_len = len, .vsk = vsk, + .net = sock_net(sk_vsock(vsk)), }; return virtio_transport_send_pkt_info(vsk, &info); @@ -674,6 +679,7 @@ static int virtio_transport_reset(struct vsock_sock *vsk, .type = VIRTIO_VSOCK_TYPE_STREAM, .reply = !!pkt, .vsk = vsk, + .net = sock_net(sk_vsock(vsk)), }; /* Send RST only if the original pkt is not a RST pkt */ @@ -694,6 +700,7 @@ static int virtio_transport_reset_no_sock(const struct virtio_transport *t, .op = VIRTIO_VSOCK_OP_RST, .type = le16_to_cpu(pkt->hdr.type), .reply = true, + .net = pkt->net, }; /* Send RST only if the original pkt is not a RST pkt */ @@ -978,6 +985,7 @@ virtio_transport_send_response(struct vsock_sock *vsk, .remote_port = le32_to_cpu(pkt->hdr.src_port), .reply = true, .vsk = vsk, + .net = sock_net(sk_vsock(vsk)), }; return virtio_transport_send_pkt_info(vsk, &info); @@ -1075,7 +1083,6 @@ virtio_transport_recv_listen(struct sock *sk, struct virtio_vsock_pkt *pkt, void virtio_transport_recv_pkt(struct virtio_transport *t, struct virtio_vsock_pkt *pkt) { - struct net *net = vsock_default_net(); struct sockaddr_vm src, dst; struct vsock_sock *vsk; struct sock *sk; @@ -1103,9 +1110,9 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, /* The socket must be in connected or bound table * otherwise send reset back */ - sk = vsock_find_connected_socket(&src, &dst, net); + sk = vsock_find_connected_socket(&src, &dst, pkt->net); if (!sk) { - sk = vsock_find_bound_socket(&dst, net); + sk = vsock_find_bound_socket(&dst, pkt->net); if (!sk) { (void)virtio_transport_reset_no_sock(t, pkt); goto free_pkt; From patchwork Thu Nov 28 17:15:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Garzarella X-Patchwork-Id: 11266429 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3202F921 for ; Thu, 28 Nov 2019 17:15:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 08F5A21787 for ; Thu, 28 Nov 2019 17:15:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="AfHoQJ3o" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727086AbfK1RPn (ORCPT ); Thu, 28 Nov 2019 12:15:43 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:30097 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727026AbfK1RPk (ORCPT ); Thu, 28 Nov 2019 12:15:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1574961339; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=i43hEG8t6TDOi2Mge5CT+4KErjH/1IrCl/OdUkMsEKc=; b=AfHoQJ3oweaELN1IzMvpJ9xyE47T7/jYKuDlBX526G3Q2emnjUmjJSKntNk0OIJa2FQExw BVYY7QWkkj5z+51kYpeI2tDwmlk+0Q2NgnJuQ3/2tHM1QuDvwQjfZcrK7XUsiYQ6kRWVDm PpNbamGKGIXF5IDWLI4mrWl5h984kxo= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-94-V9_Me1OjMuqt2wlDS8MvuQ-1; Thu, 28 Nov 2019 12:15:38 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9A2E380183C; Thu, 28 Nov 2019 17:15:36 +0000 (UTC) Received: from steredhat.redhat.com (ovpn-117-168.ams2.redhat.com [10.36.117.168]) by smtp.corp.redhat.com (Postfix) with ESMTP id 35E0E600C8; Thu, 28 Nov 2019 17:15:34 +0000 (UTC) From: Stefano Garzarella To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, virtualization@lists.linux-foundation.org, kvm@vger.kernel.org, "Michael S. Tsirkin" , Stefano Garzarella , "David S. Miller" , Dexuan Cui , Jason Wang , Stefan Hajnoczi , Jorgen Hansen Subject: [RFC PATCH 3/3] vhost/vsock: use netns of process that opens the vhost-vsock device Date: Thu, 28 Nov 2019 18:15:19 +0100 Message-Id: <20191128171519.203979-4-sgarzare@redhat.com> In-Reply-To: <20191128171519.203979-1-sgarzare@redhat.com> References: <20191128171519.203979-1-sgarzare@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-MC-Unique: V9_Me1OjMuqt2wlDS8MvuQ-1 X-Mimecast-Spam-Score: 0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This patch assigns the network namespace of the process that opened vhost-vsock device (e.g. VMM) to the packets coming from the guest, allowing only host sockets in the same network namespace to communicate with the guest. This patch also allows to have different VMs, running in different network namespace, with the same CID. Signed-off-by: Stefano Garzarella --- drivers/vhost/vsock.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 31b0f3608752..e162b3604302 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -40,6 +40,7 @@ static DEFINE_READ_MOSTLY_HASHTABLE(vhost_vsock_hash, 8); struct vhost_vsock { struct vhost_dev dev; struct vhost_virtqueue vqs[2]; + struct net *net; /* Link to global vhost_vsock_hash, writes use vhost_vsock_mutex */ struct hlist_node hash; @@ -61,7 +62,7 @@ static u32 vhost_transport_get_local_cid(void) /* Callers that dereference the return value must hold vhost_vsock_mutex or the * RCU read lock. */ -static struct vhost_vsock *vhost_vsock_get(u32 guest_cid) +static struct vhost_vsock *vhost_vsock_get(u32 guest_cid, struct net *net) { struct vhost_vsock *vsock; @@ -72,7 +73,7 @@ static struct vhost_vsock *vhost_vsock_get(u32 guest_cid) if (other_cid == 0) continue; - if (other_cid == guest_cid) + if (other_cid == guest_cid && net_eq(net, vsock->net)) return vsock; } @@ -245,7 +246,7 @@ vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt) rcu_read_lock(); /* Find the vhost_vsock according to guest context id */ - vsock = vhost_vsock_get(le64_to_cpu(pkt->hdr.dst_cid)); + vsock = vhost_vsock_get(le64_to_cpu(pkt->hdr.dst_cid), pkt->net); if (!vsock) { rcu_read_unlock(); virtio_transport_free_pkt(pkt); @@ -277,7 +278,8 @@ vhost_transport_cancel_pkt(struct vsock_sock *vsk) rcu_read_lock(); /* Find the vhost_vsock according to guest context id */ - vsock = vhost_vsock_get(vsk->remote_addr.svm_cid); + vsock = vhost_vsock_get(vsk->remote_addr.svm_cid, + sock_net(sk_vsock(vsk))); if (!vsock) goto out; @@ -474,7 +476,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) continue; } - pkt->net = vsock_default_net(); + pkt->net = vsock->net; len = pkt->len; /* Deliver to monitoring devices all received packets */ @@ -606,7 +608,14 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) vqs = kmalloc_array(ARRAY_SIZE(vsock->vqs), sizeof(*vqs), GFP_KERNEL); if (!vqs) { ret = -ENOMEM; - goto out; + goto out_vsock; + } + + /* Derive the network namespace from the pid opening the device */ + vsock->net = get_net_ns_by_pid(current->pid); + if (IS_ERR(vsock->net)) { + ret = PTR_ERR(vsock->net); + goto out_vqs; } vsock->guest_cid = 0; /* no CID assigned yet */ @@ -628,7 +637,9 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) vhost_work_init(&vsock->send_pkt_work, vhost_transport_send_pkt_work); return 0; -out: +out_vqs: + kfree(vqs); +out_vsock: vhost_vsock_free(vsock); return ret; } @@ -653,7 +664,7 @@ static void vhost_vsock_reset_orphans(struct sock *sk) */ /* If the peer is still valid, no need to reset connection */ - if (vhost_vsock_get(vsk->remote_addr.svm_cid)) + if (vhost_vsock_get(vsk->remote_addr.svm_cid, sock_net(sk))) return; /* If the close timeout is pending, let it expire. This avoids races @@ -701,6 +712,7 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file) spin_unlock_bh(&vsock->send_pkt_list_lock); vhost_dev_cleanup(&vsock->dev); + put_net(vsock->net); kfree(vsock->dev.vqs); vhost_vsock_free(vsock); return 0; @@ -727,7 +739,7 @@ static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 guest_cid) /* Refuse if CID is already in use */ mutex_lock(&vhost_vsock_mutex); - other = vhost_vsock_get(guest_cid); + other = vhost_vsock_get(guest_cid, vsock->net); if (other && other != vsock) { mutex_unlock(&vhost_vsock_mutex); return -EADDRINUSE;