From patchwork Wed Mar 12 20:59:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bobby Eshleman X-Patchwork-Id: 14013883 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E16141EF0B1; Wed, 12 Mar 2025 20:59:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741813182; cv=none; b=QkaVBJZgYYyCAefBLAkxoKwxbsgE2GOdH3fKSSOzAdLZ8NBBcB/RezAPvrAGZMBrlq/pivdfZIttvxth1+CaGiarUF9faWtYZVWGHNG3hA/aMy/tLNVVTSPBOH9V8xPfrEEM9sB9GFEC98AODAs7ZjEyNPpfb/QWEi9x5MNRadI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741813182; c=relaxed/simple; bh=58nrTVMzaWpCXQO0MEnaL13tkgHSzsCIquB0X3ajUcU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BN8QA6qvdcD2C9KjuOsOxU8v0Lkwr9tI9Mi0+dr3OrpQhLNAVzE6qavgpgCI+M+7A+5N0uC9uQBAZ0mxtmL5EkDPmyFS5kqsJ4wRV+6m4ASEhZ53VT7nf6JfZ0gple4v2I8knSTQmYeLDBAJ2/dHdWXYyopzTcTNCv81SzD+QHE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Jd5XpD5h; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Jd5XpD5h" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-224341bbc1dso5853745ad.3; Wed, 12 Mar 2025 13:59:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741813180; x=1742417980; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=S6SV0OMMvHfQ9dNMh3vcZfmXfg4llKsen+7oez8IFsY=; b=Jd5XpD5hE3kNDbCTC3TeFq02vI6C37IeGdvTDJ3pef8QaGweBp7cEPayCQxPrIFrtG MgzpfDqSWqr78nMA8AUfjqrJYMuEdGOOtHkZ+T9kCd3tnW8eMZaOKmgMv99PeGfxJRLS Cin7JV7mNPFnRwHpr13u9ATGasy8iEZgeXZ/G2cfMBxgMa/re3spVOuFQXEx8PgJh4Pd rBQ2AhM6+ylOvLT3HlfQbaeMa5UqvylDAmjFvCQXloiFpEnX2NEiD3Qz2nYTQR+0+8Ue nAipZyg/g0bBm9nau2F78V6KSVLKslZ361qx+H455z4RzL/712B+VyO0TyyfbHMZO9Wa EF9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741813180; x=1742417980; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=S6SV0OMMvHfQ9dNMh3vcZfmXfg4llKsen+7oez8IFsY=; b=jOI5U04X8n5RcCQbvMBnDRTxT9dCTWY6fznOVuniOuzx5eLYoQMm1GlGqj2KLN2qKC BOaEC368g9YiIESzhzge3jFKCLVOEvAydmba5LvfDh+Uc/lRwx3Uk2EKxz+6YPRElgOR EtFFM5asnrJ6ZPe2pmXhUD/dzED60RzNw/kB1ZhD5wioe9qvQt4TG6GTS1yJO02K4JkS OdQt26VGcvFnDIfufPCyNdqM14zZZnvJjDVlY6ET8jQsiHrM4lr8jEIO/KwcbmdLx30N bw5QtpDKx4n6CPgoE3OR9ZngpnYkIFqPghx6C0MbQembHcvS1K7Ffrq/WzFYd0oGqNa8 J+Ww== X-Forwarded-Encrypted: i=1; AJvYcCWFhUPdi3Yj6a2ccGekOzBdQr+qmho957lc4UizUE/QM/yHiDJnN3E+MVQ2S/mIqLInPc4=@vger.kernel.org, AJvYcCWWqKO8z34piNCunaxiUlHqQw9F9YHX7h8HSJnLyOHywXAh7PVCRZagxAeFC4SoaSc808t0nOrcg2+m1xvt@vger.kernel.org, AJvYcCXBhmG3uI+AL8Fg7kLwnpwhAI9D15PaEcJeQOOW5GXMANfe+qPBjcSTO3ADq++PW88TBxlzd7BG@vger.kernel.org, AJvYcCXNH9+dTfBW8+yHbl7Ni0tw6maDjtlb5uwkS1nn0auW3Ls01ixjtgYq2Dp7i3IFmaKdUr6t1Xtn/CQymrAG@vger.kernel.org X-Gm-Message-State: AOJu0Yz7b5BsqYVEf5+qIaJf7gBB6vIR9jTP58NXYmy9jhs6xM0nA2I2 g/lSjJ3rjkOvQj1t+QNNZBrcZ4Kj1We2sBASNb8HrhwIBVHScwEt X-Gm-Gg: ASbGncvP2W79atZ1aT7+J/Io22OHCNQKTwUC05ybXelmZXyu+jGnEQjWf83vo0t2Q84 tCXQR3bttW6vqOC6hPPo8PSRp2CWlwUmVNiikjTzuFTJDxvEhuzlIX7x755Sedc9X6C7DdBv61S zh6XouuDqljHoiqIQAgRHCGPuS4hWwFbMoBWCfbOsOwIPKP1f50ObfnASoDAdRgJEbjNFPu+mcN 4OpvGSxzF8Qq5ELmaQjwLR9jlpCTfSWk+nwF9kRO0CgOXTIk9uMvleSicxCPJ/6DvPsC0BdvkrS y2UJLUz/SLjPqEoCtfnztiv2YSGzoCDGeEKQhx6Enm0= X-Google-Smtp-Source: AGHT+IEnho2DT4EvAFXOzkMi6dHuQrNeMTnsCpgaC1KC1WI9+9kok4yqlR4obktRfMVTp+vp23mIfg== X-Received: by 2002:a17:903:2308:b0:220:ce37:e31f with SMTP id d9443c01a7336-22592e2cb8emr122152785ad.17.1741813180080; Wed, 12 Mar 2025 13:59:40 -0700 (PDT) Received: from localhost ([2a03:2880:2ff:71::]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22410a7f93esm120621905ad.142.2025.03.12.13.59.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Mar 2025 13:59:39 -0700 (PDT) From: Bobby Eshleman Date: Wed, 12 Mar 2025 13:59:35 -0700 Subject: [PATCH v2 1/3] vsock: add network namespace support Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250312-vsock-netns-v2-1-84bffa1aa97a@gmail.com> References: <20250312-vsock-netns-v2-0-84bffa1aa97a@gmail.com> In-Reply-To: <20250312-vsock-netns-v2-0-84bffa1aa97a@gmail.com> To: Stefano Garzarella , Jakub Kicinski , "K. Y. Srinivasan" , Haiyang Zhang , Wei Liu , Dexuan Cui , Stefan Hajnoczi , "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , =?utf-8?q?Eugenio_P=C3=A9rez?= , Bryan Tan , Vishnu Dasa , Broadcom internal kernel review list Cc: "David S. Miller" , virtualization@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, kvm@vger.kernel.org, Bobby Eshleman X-Mailer: b4 0.14.2 X-Patchwork-Delegate: kuba@kernel.org From: Stefano Garzarella 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. This patch preserves old behavior, and does not yet bring up namespace support fully. Signed-off-by: Stefano Garzarella Signed-off-by: Bobby Eshleman --- v1 -> v2: * remove 'netns' module param * remove vsock_net_eq() * use vsock_global_net() for "global" namespace * use fallback logic in socket lookup functions, giving precedence to non-global vsock namespaces RFC -> v1 * added 'netns' module param * added 'vsock_net_eq()' to check the "net" assigned to a socket only when 'netns' support is enabled --- include/net/af_vsock.h | 7 +++-- net/vmw_vsock/af_vsock.c | 55 ++++++++++++++++++++++++--------- net/vmw_vsock/hyperv_transport.c | 2 +- net/vmw_vsock/virtio_transport_common.c | 5 +-- net/vmw_vsock/vmci_transport.c | 4 +-- 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index 9e85424c834353d016a527070dd62e15ff3bfce1..41afbc18648c953da27a93571d408de968aa7668 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -213,9 +213,10 @@ 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(struct vsock_transport *transport, void (*fn)(struct sock *sk)); @@ -255,4 +256,6 @@ static inline bool vsock_msgzerocopy_allow(const struct vsock_transport *t) { return t->msgzerocopy_allow && t->msgzerocopy_allow(); } + +struct net *vsock_global_net(void); #endif /* __AF_VSOCK_H__ */ diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 7e3db87ae4333cf63327ec105ca99253569bb9fe..d206489bf0a81cf989387c7c8063be91a7c21a7d 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -235,37 +235,60 @@ static void __vsock_remove_connected(struct vsock_sock *vsk) sock_put(&vsk->sk); } -static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr) +struct net *vsock_global_net(void) { + return NULL; +} +EXPORT_SYMBOL_GPL(vsock_global_net); + +static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr, + struct net *net) +{ + struct sock *fallback = NULL; struct vsock_sock *vsk; list_for_each_entry(vsk, vsock_bound_sockets(addr), bound_table) { - if (vsock_addr_equals_addr(addr, &vsk->local_addr)) - return sk_vsock(vsk); + if (vsock_addr_equals_addr(addr, &vsk->local_addr)) { + if (net_eq(net, sock_net(sk_vsock(vsk)))) + return sk_vsock(vsk); + if (net_eq(net, vsock_global_net())) + fallback = sk_vsock(vsk); + } if (addr->svm_port == vsk->local_addr.svm_port && (vsk->local_addr.svm_cid == VMADDR_CID_ANY || - addr->svm_cid == VMADDR_CID_ANY)) - return sk_vsock(vsk); + addr->svm_cid == VMADDR_CID_ANY)) { + if (net_eq(net, sock_net(sk_vsock(vsk)))) + return sk_vsock(vsk); + + if (net_eq(net, vsock_global_net())) + fallback = sk_vsock(vsk); + } } - return NULL; + return fallback; } static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src, - struct sockaddr_vm *dst) + struct sockaddr_vm *dst, + struct net *net) { + struct sock *fallback = NULL; 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) && dst->svm_port == vsk->local_addr.svm_port) { - return sk_vsock(vsk); + if (net_eq(net, sock_net(sk_vsock(vsk)))) + return sk_vsock(vsk); + + if (net_eq(net, vsock_global_net())) + fallback = sk_vsock(vsk); } } - return NULL; + return fallback; } static void vsock_insert_unbound(struct vsock_sock *vsk) @@ -304,12 +327,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); @@ -320,12 +343,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); @@ -644,6 +668,7 @@ static int __vsock_bind_connectible(struct vsock_sock *vsk, { static u32 port; struct sockaddr_vm new_addr; + struct net *net = sock_net(sk_vsock(vsk)); if (!port) port = get_random_u32_above(LAST_RESERVED_PORT); @@ -660,7 +685,7 @@ static int __vsock_bind_connectible(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; } @@ -677,7 +702,7 @@ static int __vsock_bind_connectible(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 31342ab502b4fc35feb812d2c94e0e35ded73771..253609898d24f8a484fcfc3296011c6f501a72a8 100644 --- a/net/vmw_vsock/hyperv_transport.c +++ b/net/vmw_vsock/hyperv_transport.c @@ -313,7 +313,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, NULL); if (!sk) return; diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index 7f7de6d8809655fe522749fbbc9025df71f071bd..256d2a4fe482b3cb938a681b6924be69b2065616 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -1590,6 +1590,7 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, struct sk_buff *skb) { struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); + struct net *net = vsock_global_net(); struct sockaddr_vm src, dst; struct vsock_sock *vsk; struct sock *sk; @@ -1617,9 +1618,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, skb); goto free_pkt; diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index b370070194fa4ac0df45a073d389ffccf69a0029..373b9fe30a26c18aaa181fbc16db840d8f839b13 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -703,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, NULL); if (!sk) { - sk = vsock_find_bound_socket(&dst); + sk = vsock_find_bound_socket(&dst, NULL); if (!sk) { /* We could not find a socket for this specified * address. If this packet is a RST, we just drop it. From patchwork Wed Mar 12 20:59:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bobby Eshleman X-Patchwork-Id: 14013884 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16F1B1F17E5; Wed, 12 Mar 2025 20:59:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741813184; cv=none; b=CvXWNvfcO2b4R+dI6cwWQQelCQvbZzy124jkTtOu9g/0jfQKcgY3KHzBAZjVqZ2ITLhGK6YaC9G5ZSajpBNSaevQYv2ZT5NDiKR/Xz0Mk8TFA6RgvU8+2lnrhQovXUosTI+nCVf++1E+MVpRC7DmewT1Jo5YexwTf5i3E8mwuck= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741813184; c=relaxed/simple; bh=jSOiqzU7LgYk7s3hBpAEWXR6XXPObJfDqvsKHjg2btI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XyAQEwIhkSNHD6RxcwY7wdUeKSBQNnuEk3fCfC0RYT8qVxJDAw8Nnq3UQrPNSoVtnSz/RKzA+QDWX8kLd9YdP5StDpIvVFcXMIdXLbyC8nnktwo/6PE1sa3qsvz/x9BMqYm65zWM5h11kwcCGBBQHfghn+ePJUo3gHYTh1gPQos= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=k67LCi76; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="k67LCi76" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-22334203781so25732505ad.0; Wed, 12 Mar 2025 13:59:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741813182; x=1742417982; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=NkAj1CKS6gC9G4Byz4nHeWNr5VsXbnbcZlq4lVa0Tbo=; b=k67LCi76KuEvdq8CPBWis56Zh9KBzZXEziXk8PF1bWK3taGeU+93QrJwchjqNa1f7V sl+JqPZs5aWKhpOJuEhyhxdrZ0hqVU1sCgr3ir2gnrpLNVX3gCMrZ3UhYDbaJON50tRc RNSKsnj0sQHj7EKkAB9dG1SUQxSYVczl8JxKKP71msz6a6d0pfJSPEvEMltA6TMbwUqT Pim4Cia5ahuhsb6unMWRljojTbQx8UuY/M3byshIZNiLBdfY1BqpaRoHLWIDfYd180rl SKYOPxwDX6UsqQGEJOavIks0Di+ZArtYv/uYtbLViiR34dz/zoMg1mk0PI4cWfiZBe+e MV1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741813182; x=1742417982; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NkAj1CKS6gC9G4Byz4nHeWNr5VsXbnbcZlq4lVa0Tbo=; b=fsGiB7YQh1swOCjUY9GOLb7OlW3qs6Twjpk7AqJnIoFhkcSYeLci+FNVrQj/zGJS8c KU+oHeJBXvvVFjsOAvtOFeRVakzpLYUdZX7N2//QiE1OzF2GEhfx9Kdf2BtlOJ6jb4nb UvKQjAA+AFA961HWPQdC7K4ozGMStjg39VBjp8PpONl3SQh/lLb6a1is2BCG8eD7bVej CC7m7+2tBZGbsA6uG6muQS1D7fZ0ymrUDY8BKHNK3x4g7S6dxJXetYCDEWMK92Gwcac+ 2GifUi6ZUXmQRtXuCYWXka8na52QRUHN0aUWe3+WZLvHXo+EpmyA0kRPzvk3jdOo/2f4 yrYQ== X-Forwarded-Encrypted: i=1; AJvYcCX/pQVhkTui5q8bJqe9m45dcYodN+6i4OZUolXhSPTDbEmPS/fbcWrbI0ZMt0A/RnsmdEGDds/e39hgBKzi@vger.kernel.org, AJvYcCXTb1ShawLouX23OB6KKNa9k/iZGmzU1yyC8Zn6J2O+Nr/RShbaAv/vCHaCZOf2cjtBCCg=@vger.kernel.org, AJvYcCXY7IpYY3JvS+1hsJIwFfydLcWlfHyISY7bkFzUc3C0Qz+jKavb5QB831cMp9evVxJ02LUtn2Se@vger.kernel.org, AJvYcCXwuxFhZVYeBJVu1BQ061HFQRDAmuwgm2ANiEguNHxFb5Ef4H/uZRtb6uVzzlOaC9qteeRrIk8/QDOoR+zM@vger.kernel.org X-Gm-Message-State: AOJu0Yy0OB9WqMP/orIz6M9C/M22erUVS59nZL6F1+qTYPt+NK1Uh8b3 I0G3lwykPq7Ghe/4HZG91rZVpzeUnXbgZ1oHGQHsKomAf/V0WdoW X-Gm-Gg: ASbGnct/iloSWvK4le99Z2mjK0Y+76GZcgxg0YY9xlN2vnGMUNUmchkotjm+2wkbSGV sISRQXRCKgezVFMYpbV6+O4Q+rArPZEo85FMCFAvlfLsCKqbwPTH63AnXHS/ylSS/4h5a8wRQtV hstNNx8C4SU1B9WV/5GIh0qoIxV6bCMdf10XCLEToWqR8FsrjK6F2tsR1c5dVGvGluOyqT1PLSM IXBentwoLXLh89FD/1Eu4/R8NZ+MWp2Jq4agTvZiS43MtKjf+kmxJ/9xnbNqgjHhaVue64Zirzb B/PvicWL3DuGRtgWb2bdt8mGmFo/X5O1/TR+FCM0sA== X-Google-Smtp-Source: AGHT+IG2WeNoJMTPTLJVZix48mNFgtFi81bCQiANCHHziaLLADPcNI7nV831oKin4G0DythBHW6eVg== X-Received: by 2002:a05:6a00:3c96:b0:736:3ea8:4813 with SMTP id d2e1a72fcca58-737106ec2fbmr40172b3a.2.1741813182223; Wed, 12 Mar 2025 13:59:42 -0700 (PDT) Received: from localhost ([2a03:2880:2ff:6::]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-736b9fe8655sm9773862b3a.2.2025.03.12.13.59.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Mar 2025 13:59:41 -0700 (PDT) From: Bobby Eshleman Date: Wed, 12 Mar 2025 13:59:36 -0700 Subject: [PATCH v2 2/3] vsock/virtio_transport_common: handle netns of received packets Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250312-vsock-netns-v2-2-84bffa1aa97a@gmail.com> References: <20250312-vsock-netns-v2-0-84bffa1aa97a@gmail.com> In-Reply-To: <20250312-vsock-netns-v2-0-84bffa1aa97a@gmail.com> To: Stefano Garzarella , Jakub Kicinski , "K. Y. Srinivasan" , Haiyang Zhang , Wei Liu , Dexuan Cui , Stefan Hajnoczi , "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , =?utf-8?q?Eugenio_P=C3=A9rez?= , Bryan Tan , Vishnu Dasa , Broadcom internal kernel review list Cc: "David S. Miller" , virtualization@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, kvm@vger.kernel.org, Bobby Eshleman X-Mailer: b4 0.14.2 X-Patchwork-Delegate: kuba@kernel.org From: Stefano Garzarella 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, still do not use this capability and preserve old behavior. Signed-off-by: Stefano Garzarella Signed-off-by: Bobby Eshleman --- V1 -> V2 * use vsock_global_net() * add net to skb->cb * forward port for skb --- drivers/vhost/vsock.c | 1 + include/linux/virtio_vsock.h | 2 ++ net/vmw_vsock/virtio_transport.c | 1 + net/vmw_vsock/virtio_transport_common.c | 11 ++++++++++- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 802153e230730bdbfbbb6f4ae263ae99502ef532..02e2a3551205a4398a74a167a82802d950c962f6 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -525,6 +525,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) continue; } + VIRTIO_VSOCK_SKB_CB(skb)->net = vsock_global_net(); total_len += sizeof(*hdr) + skb->len; /* Deliver to monitoring devices all received packets */ diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h index 0387d64e2c66c69dd7ab0cad58db5cf0682ad424..e51f89559a1d92685027bf83a62c7b05dd9e566d 100644 --- a/include/linux/virtio_vsock.h +++ b/include/linux/virtio_vsock.h @@ -12,6 +12,7 @@ struct virtio_vsock_skb_cb { bool reply; bool tap_delivered; + struct net *net; u32 offset; }; @@ -148,6 +149,7 @@ struct virtio_vsock_pkt_info { u32 remote_cid, remote_port; struct vsock_sock *vsk; struct msghdr *msg; + struct net *net; u32 pkt_len; u16 type; u16 op; diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c index f0e48e6911fc46cba87f7dafeb8dbc21421df254..163ddfc0808529ad6dda7992f9ec48837dd7337c 100644 --- a/net/vmw_vsock/virtio_transport.c +++ b/net/vmw_vsock/virtio_transport.c @@ -650,6 +650,7 @@ static void virtio_transport_rx_work(struct work_struct *work) virtio_vsock_skb_rx_put(skb); virtio_transport_deliver_tap_pkt(skb); + VIRTIO_VSOCK_SKB_CB(skb)->net = vsock_global_net(); virtio_transport_recv_pkt(&virtio_transport, skb); } } while (!virtqueue_enable_cb(vq)); diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index 256d2a4fe482b3cb938a681b6924be69b2065616..028591a5863b84059b8e8bbafd499cb997a0c863 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -314,6 +314,8 @@ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info * info->flags, zcopy); + VIRTIO_VSOCK_SKB_CB(skb)->net = info->net; + return skb; out: kfree_skb(skb); @@ -523,6 +525,7 @@ static int virtio_transport_send_credit_update(struct vsock_sock *vsk) struct virtio_vsock_pkt_info info = { .op = VIRTIO_VSOCK_OP_CREDIT_UPDATE, .vsk = vsk, + .net = sock_net(sk_vsock(vsk)), }; return virtio_transport_send_pkt_info(vsk, &info); @@ -1061,6 +1064,7 @@ int virtio_transport_connect(struct vsock_sock *vsk) struct virtio_vsock_pkt_info info = { .op = VIRTIO_VSOCK_OP_REQUEST, .vsk = vsk, + .net = sock_net(sk_vsock(vsk)), }; return virtio_transport_send_pkt_info(vsk, &info); @@ -1076,6 +1080,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); @@ -1102,6 +1107,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); @@ -1139,6 +1145,7 @@ static int virtio_transport_reset(struct vsock_sock *vsk, .op = VIRTIO_VSOCK_OP_RST, .reply = !!skb, .vsk = vsk, + .net = sock_net(sk_vsock(vsk)), }; /* Send RST only if the original pkt is not a RST pkt */ @@ -1159,6 +1166,7 @@ static int virtio_transport_reset_no_sock(const struct virtio_transport *t, .op = VIRTIO_VSOCK_OP_RST, .type = le16_to_cpu(hdr->type), .reply = true, + .net = VIRTIO_VSOCK_SKB_CB(skb)->net, }; struct sk_buff *reply; @@ -1476,6 +1484,7 @@ virtio_transport_send_response(struct vsock_sock *vsk, .remote_port = le32_to_cpu(hdr->src_port), .reply = true, .vsk = vsk, + .net = sock_net(sk_vsock(vsk)), }; return virtio_transport_send_pkt_info(vsk, &info); @@ -1590,7 +1599,7 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, struct sk_buff *skb) { struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); - struct net *net = vsock_global_net(); + struct net *net = VIRTIO_VSOCK_SKB_CB(skb)->net; struct sockaddr_vm src, dst; struct vsock_sock *vsk; struct sock *sk; From patchwork Wed Mar 12 20:59:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bobby Eshleman X-Patchwork-Id: 14013885 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99AF01F30DE; Wed, 12 Mar 2025 20:59:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741813187; cv=none; b=chhVH9BvFQKa9mIwZpwLRrcyuWDiY+BdQwq2GOQTsZ4e8iaJol2gfwuU5avBn7EtzMPlalwhlDhXFW7m/EqmMk0G06R8vkvtOhqqJazOqqKixrOl1FuO6FpGgeqIZ+yE7ommPIj5UA6poiXQud1oOMvCNtLcx+vm7HLoh5UEpc0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741813187; c=relaxed/simple; bh=Do16I5bAYzmzhFhoe8gnWsx5863bMKTjbneEuRXGaqU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Y/3KvWGIw0IbIbwzlibJ8wqi/SOCmMWM3ojiOi+WsVpxtVkdS4z3w14016Hw0Bj8K3vgGo5arJCjaRhm4FMgtqPcVORcB/BW+apbE17nkEfzaZ+IG5iq/ozb6Fru3Y1J1OQggiCJooLEkJ1CyAL6f1byuRYRNFaBRlAXPAvIwB8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=gj4ZK6zG; arc=none smtp.client-ip=209.85.216.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gj4ZK6zG" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-2ff6a98c638so750338a91.0; Wed, 12 Mar 2025 13:59:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741813185; x=1742417985; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=lCaQyn2/uqo7QNM9DADy6R5q4JezG8pI2E1+WaA9IUU=; b=gj4ZK6zGSugeybrgfdRtomS6ZkfW4Dhn57be8vBpK7RN3WgEGu/Bqc8FMnhY4DGzT2 EunArjSFiae9lpz+soy/wITxgqokF3xQgNp0I+D5M1cuTDRh1RMTkhanMuYOs7+9YbgB KkZBRelc8gg8CYU7DspNWHLTPpZp1FsiGmv9Mxtmhusk8mgvhKj9N+jgwWT2IQ46K1FC GZ96i1F2Ux6nV7RvDGYjbWfCtMt/TPNP2Pi55ujV5NqG/mz7ZX8IPI5GktWT+UMUyIpA 5ntmyXCZwmotCPW+J5KjJejcd05H2xKGfXxqRibiMf8G4Dg0GSLcJMCncyoFkE0WHtNx SrzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741813185; x=1742417985; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lCaQyn2/uqo7QNM9DADy6R5q4JezG8pI2E1+WaA9IUU=; b=uNVG/kyXe4DnXhxUO18/WFRR3TrxZHqUSLnqi9Z5TB8hWmc134noB+1PbnZiufRKJV rk7iUXV0B1NwP3C+YPOKV9u8h9sB98O6vLi2kkHgE8duLfRErwv8FXEaanrb6o+w993H 2mXByKddzTcqrBvQOMq0SsK0PHyHCLN0XZZixdkacUxadpSb7e/9TnJ0w6Q6/ZUSUuoX muE1WcCL/fYYGXhOo5IMgzobfvyQx0S/ny6uZUzv7Uev50UROPNtiW1tqkYTq+ewnBaN MuQ0VVajHTrvaTttKDL1zipOG1GhB6meZ9kWRa/vTwdY2xYCRiSZFa0xMxBuZzvhkrRS kDTw== X-Forwarded-Encrypted: i=1; AJvYcCUU/q3jHFYXpRqLyWDDJ0bKry6kua0x87H7HEpecVUabmdp5QnFFRSmcYVF2NtaLXxJfbiHaeqFFyLOfBSQ@vger.kernel.org, AJvYcCUqTjfcpYRY69de56XE3ZT2XBCVMeiR9uphjlgEV+8bNDvTdbITnRsSaYXxPokIL0ZDQn4=@vger.kernel.org, AJvYcCUuMuAzcLub50ZGBkzWLfdzYCl4QR9mAOVjZe9FiJmKw2tFjSZc9Uj2uXpGdu/j6NCF2xrWJhpD@vger.kernel.org, AJvYcCWWFEil2GaybYYfhoP8rplHqnz13HIlybO3Apn3ZMHbTzNbSHhjRWjKZUAzGsWPz4Qg+ydqlyIXNnji4m58@vger.kernel.org X-Gm-Message-State: AOJu0YyDQ0nkf7dTG7MypetShG/exyKAW/sQOAtYqdU944Ld6vsKTVGo HEyiWZhMTIM01IkPYJUXQSzZhuUxomowO137kAZpGEoTyoUkomVZ X-Gm-Gg: ASbGncvsEYA84QzvDfD0BJ0OZLsZ+gCiCedxjn3zft53vlT/bAuR7Xbpq7ShWg3DdMk 2Idfgqrf0+fdGv1QDJrsE9Mg5mZWo2gGW94B2wRsx4V4CXeD1AsitlxyK46EvrYv6k/CcP3yVOS y29DEH2p419fI2undEsseFXIlTdCrWeGFEDmXrUBdJ8CFqIFhqVTn5PGTvAADerwUT8XhUHmgYL NPXoD//4TLwvWS/cIrnjLcKFTZmlzzapdLP5b2rmaDtUY9LCUZ8wE6RYrv1gNoKgG9u3D9i1I86 WRfW/1h9OdIyXmZnIohq9ix0xdJ2cE2GN1w5xAwM3/I= X-Google-Smtp-Source: AGHT+IG8o4T4fQgM/ljNeiMXid+znFHo/f0a3WcQ7wf4lTgAMYEbvfs/XE+5hQSFsAZ5+QRpMt+LWA== X-Received: by 2002:a17:90b:1d0a:b0:2ea:83a0:47a5 with SMTP id 98e67ed59e1d1-2ff7ce457acmr33164596a91.4.1741813184517; Wed, 12 Mar 2025 13:59:44 -0700 (PDT) Received: from localhost ([2a03:2880:2ff:70::]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-301190b98ebsm2342609a91.36.2025.03.12.13.59.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Mar 2025 13:59:43 -0700 (PDT) From: Bobby Eshleman Date: Wed, 12 Mar 2025 13:59:37 -0700 Subject: [PATCH v2 3/3] vhost/vsock: use netns of process that opens the vhost-vsock-netns device Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250312-vsock-netns-v2-3-84bffa1aa97a@gmail.com> References: <20250312-vsock-netns-v2-0-84bffa1aa97a@gmail.com> In-Reply-To: <20250312-vsock-netns-v2-0-84bffa1aa97a@gmail.com> To: Stefano Garzarella , Jakub Kicinski , "K. Y. Srinivasan" , Haiyang Zhang , Wei Liu , Dexuan Cui , Stefan Hajnoczi , "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , =?utf-8?q?Eugenio_P=C3=A9rez?= , Bryan Tan , Vishnu Dasa , Broadcom internal kernel review list Cc: "David S. Miller" , virtualization@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, kvm@vger.kernel.org, Bobby Eshleman X-Mailer: b4 0.14.2 X-Patchwork-Delegate: kuba@kernel.org From: Stefano Garzarella This patch assigns the network namespace of the process that opened vhost-vsock-netns 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 having different VMs, running in different network namespace, with the same CID/port. This patch brings namespace support only to vhost-vsock, but not to virtio-vsock, hyperv, or vmci. Signed-off-by: Stefano Garzarella Signed-off-by: Bobby Eshleman --- v1 -> v2 * removed 'netns' module param * renamed vsock_default_net() to vsock_global_net() to reflect new semantics * reserved NULL net to indicate "global" vsock namespace RFC -> v1 * added 'netns' module param * added 'vsock_net_eq()' to check the "net" assigned to a socket only when 'netns' support is enabled --- drivers/vhost/vsock.c | 97 +++++++++++++++++++++++++++++++++------- include/linux/miscdevice.h | 1 + include/net/af_vsock.h | 3 +- net/vmw_vsock/af_vsock.c | 30 ++++++++++++- net/vmw_vsock/virtio_transport.c | 4 +- net/vmw_vsock/vsock_loopback.c | 4 +- 6 files changed, 117 insertions(+), 22 deletions(-) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 02e2a3551205a4398a74a167a82802d950c962f6..8702beb8238aa290b6d901e53c36481637840017 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -46,6 +46,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; @@ -67,8 +68,9 @@ 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, bool global_fallback) { + struct vhost_vsock *fallback = NULL; struct vhost_vsock *vsock; hash_for_each_possible_rcu(vhost_vsock_hash, vsock, hash, guest_cid) { @@ -78,11 +80,18 @@ static struct vhost_vsock *vhost_vsock_get(u32 guest_cid) if (other_cid == 0) continue; - if (other_cid == guest_cid) - return vsock; + if (other_cid == guest_cid) { + if (net_eq(net, vsock->net)) + return vsock; + if (net_eq(vsock->net, vsock_global_net())) + fallback = vsock; + } } + if (global_fallback) + return fallback; + return NULL; } @@ -272,13 +281,14 @@ static int vhost_transport_send_pkt(struct sk_buff *skb) { struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); + struct net *net = VIRTIO_VSOCK_SKB_CB(skb)->net; struct vhost_vsock *vsock; int len = skb->len; rcu_read_lock(); /* Find the vhost_vsock according to guest context id */ - vsock = vhost_vsock_get(le64_to_cpu(hdr->dst_cid)); + vsock = vhost_vsock_get(le64_to_cpu(hdr->dst_cid), net, true); if (!vsock) { rcu_read_unlock(); kfree_skb(skb); @@ -305,7 +315,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)), true); if (!vsock) goto out; @@ -403,7 +414,7 @@ static bool vhost_transport_msgzerocopy_allow(void) return true; } -static bool vhost_transport_seqpacket_allow(u32 remote_cid); +static bool vhost_transport_seqpacket_allow(struct vsock_sock *vsk, u32 remote_cid); static struct virtio_transport vhost_transport = { .transport = { @@ -459,13 +470,14 @@ static struct virtio_transport vhost_transport = { .send_pkt = vhost_transport_send_pkt, }; -static bool vhost_transport_seqpacket_allow(u32 remote_cid) +static bool vhost_transport_seqpacket_allow(struct vsock_sock *vsk, u32 remote_cid) { + struct net *net = sock_net(sk_vsock(vsk)); struct vhost_vsock *vsock; bool seqpacket_allow = false; rcu_read_lock(); - vsock = vhost_vsock_get(remote_cid); + vsock = vhost_vsock_get(remote_cid, net, true); if (vsock) seqpacket_allow = vsock->seqpacket_allow; @@ -525,7 +537,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) continue; } - VIRTIO_VSOCK_SKB_CB(skb)->net = vsock_global_net(); + VIRTIO_VSOCK_SKB_CB(skb)->net = vsock->net; total_len += sizeof(*hdr) + skb->len; /* Deliver to monitoring devices all received packets */ @@ -650,7 +662,7 @@ static void vhost_vsock_free(struct vhost_vsock *vsock) kvfree(vsock); } -static int vhost_vsock_dev_open(struct inode *inode, struct file *file) +static int __vhost_vsock_dev_open(struct inode *inode, struct file *file, struct net *net) { struct vhost_virtqueue **vqs; struct vhost_vsock *vsock; @@ -669,6 +681,8 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) goto out; } + vsock->net = net; + vsock->guest_cid = 0; /* no CID assigned yet */ vsock->seqpacket_allow = false; @@ -693,6 +707,22 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) return ret; } +static int vhost_vsock_dev_open(struct inode *inode, struct file *file) +{ + return __vhost_vsock_dev_open(inode, file, vsock_global_net()); +} + +static int vhost_vsock_netns_dev_open(struct inode *inode, struct file *file) +{ + struct net *net; + + net = get_net_ns_by_pid(current->pid); + if (IS_ERR(net)) + return PTR_ERR(net); + + return __vhost_vsock_dev_open(inode, file, net); +} + static void vhost_vsock_flush(struct vhost_vsock *vsock) { vhost_dev_flush(&vsock->dev); @@ -708,7 +738,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), true)) return; /* If the close timeout is pending, let it expire. This avoids races @@ -753,6 +783,8 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file) virtio_vsock_skb_queue_purge(&vsock->send_pkt_queue); vhost_dev_cleanup(&vsock->dev); + if (vsock->net) + put_net(vsock->net); kfree(vsock->dev.vqs); vhost_vsock_free(vsock); return 0; @@ -777,9 +809,15 @@ static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 guest_cid) if (vsock_find_cid(guest_cid)) return -EADDRINUSE; + /* If this namespace has already connected to this CID, then report + * that this address is already in use. + */ + if (vsock->net && vsock_net_has_connected(vsock->net, guest_cid)) + return -EADDRINUSE; + /* 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, false); if (other && other != vsock) { mutex_unlock(&vhost_vsock_mutex); return -EADDRINUSE; @@ -931,6 +969,24 @@ static struct miscdevice vhost_vsock_misc = { .fops = &vhost_vsock_fops, }; +static const struct file_operations vhost_vsock_netns_fops = { + .owner = THIS_MODULE, + .open = vhost_vsock_netns_dev_open, + .release = vhost_vsock_dev_release, + .llseek = noop_llseek, + .unlocked_ioctl = vhost_vsock_dev_ioctl, + .compat_ioctl = compat_ptr_ioctl, + .read_iter = vhost_vsock_chr_read_iter, + .write_iter = vhost_vsock_chr_write_iter, + .poll = vhost_vsock_chr_poll, +}; + +static struct miscdevice vhost_vsock_netns_misc = { + .minor = VHOST_VSOCK_NETNS_MINOR, + .name = "vhost-vsock-netns", + .fops = &vhost_vsock_netns_fops, +}; + static int __init vhost_vsock_init(void) { int ret; @@ -941,17 +997,26 @@ static int __init vhost_vsock_init(void) return ret; ret = misc_register(&vhost_vsock_misc); - if (ret) { - vsock_core_unregister(&vhost_transport.transport); - return ret; - } + if (ret) + goto out_vt; + + ret = misc_register(&vhost_vsock_netns_misc); + if (ret) + goto out_vvm; return 0; + +out_vvm: + misc_deregister(&vhost_vsock_misc); +out_vt: + vsock_core_unregister(&vhost_transport.transport); + return ret; }; static void __exit vhost_vsock_exit(void) { misc_deregister(&vhost_vsock_misc); + misc_deregister(&vhost_vsock_netns_misc); vsock_core_unregister(&vhost_transport.transport); }; diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index 69e110c2b86a9b16c1637778a25e1eebb3fd0111..a7e11b70a5398a225c4d63d50ac460e6388e022c 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -71,6 +71,7 @@ #define USERIO_MINOR 240 #define VHOST_VSOCK_MINOR 241 #define RFKILL_MINOR 242 +#define VHOST_VSOCK_NETNS_MINOR 243 #define MISC_DYNAMIC_MINOR 255 struct device; diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index 41afbc18648c953da27a93571d408de968aa7668..1e37737689a741d91e64b8c0ed0a931fc7376194 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -143,7 +143,7 @@ struct vsock_transport { int flags); int (*seqpacket_enqueue)(struct vsock_sock *vsk, struct msghdr *msg, size_t len); - bool (*seqpacket_allow)(u32 remote_cid); + bool (*seqpacket_allow)(struct vsock_sock *vsk, u32 remote_cid); u32 (*seqpacket_has_data)(struct vsock_sock *vsk); /* Notification. */ @@ -258,4 +258,5 @@ static inline bool vsock_msgzerocopy_allow(const struct vsock_transport *t) } struct net *vsock_global_net(void); +bool vsock_net_has_connected(struct net *net, u64 guest_cid); #endif /* __AF_VSOCK_H__ */ diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index d206489bf0a81cf989387c7c8063be91a7c21a7d..58fa415555d6aae5043b5ca2bfc4783af566cf28 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -391,6 +391,34 @@ void vsock_for_each_connected_socket(struct vsock_transport *transport, } EXPORT_SYMBOL_GPL(vsock_for_each_connected_socket); +bool vsock_net_has_connected(struct net *net, u64 guest_cid) +{ + bool ret = false; + int i; + + spin_lock_bh(&vsock_table_lock); + + for (i = 0; i < ARRAY_SIZE(vsock_connected_table); i++) { + struct vsock_sock *vsk; + + list_for_each_entry(vsk, &vsock_connected_table[i], + connected_table) { + if (sock_net(sk_vsock(vsk)) != net) + continue; + + if (vsk->remote_addr.svm_cid == guest_cid) { + ret = true; + goto out; + } + } + } + +out: + spin_unlock_bh(&vsock_table_lock); + return ret; +} +EXPORT_SYMBOL_GPL(vsock_net_has_connected); + void vsock_add_pending(struct sock *listener, struct sock *pending) { struct vsock_sock *vlistener; @@ -537,7 +565,7 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) if (sk->sk_type == SOCK_SEQPACKET) { if (!new_transport->seqpacket_allow || - !new_transport->seqpacket_allow(remote_cid)) { + !new_transport->seqpacket_allow(vsk, remote_cid)) { module_put(new_transport->module); return -ESOCKTNOSUPPORT; } diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c index 163ddfc0808529ad6dda7992f9ec48837dd7337c..60bf3f1f39c51d44768fd2f04df3abee9f966252 100644 --- a/net/vmw_vsock/virtio_transport.c +++ b/net/vmw_vsock/virtio_transport.c @@ -536,7 +536,7 @@ static bool virtio_transport_msgzerocopy_allow(void) return true; } -static bool virtio_transport_seqpacket_allow(u32 remote_cid); +static bool virtio_transport_seqpacket_allow(struct vsock_sock *vsk, u32 remote_cid); static struct virtio_transport virtio_transport = { .transport = { @@ -593,7 +593,7 @@ static struct virtio_transport virtio_transport = { .can_msgzerocopy = virtio_transport_can_msgzerocopy, }; -static bool virtio_transport_seqpacket_allow(u32 remote_cid) +static bool virtio_transport_seqpacket_allow(struct vsock_sock *vsk, u32 remote_cid) { struct virtio_vsock *vsock; bool seqpacket_allow; diff --git a/net/vmw_vsock/vsock_loopback.c b/net/vmw_vsock/vsock_loopback.c index 6e78927a598e07cf77386a420b9d05d3f491dc7c..1b2fab73e0d0a6c63ed60d29fc837da58f6fb121 100644 --- a/net/vmw_vsock/vsock_loopback.c +++ b/net/vmw_vsock/vsock_loopback.c @@ -46,7 +46,7 @@ static int vsock_loopback_cancel_pkt(struct vsock_sock *vsk) return 0; } -static bool vsock_loopback_seqpacket_allow(u32 remote_cid); +static bool vsock_loopback_seqpacket_allow(struct vsock_sock *vsk, u32 remote_cid); static bool vsock_loopback_msgzerocopy_allow(void) { return true; @@ -106,7 +106,7 @@ static struct virtio_transport loopback_transport = { .send_pkt = vsock_loopback_send_pkt, }; -static bool vsock_loopback_seqpacket_allow(u32 remote_cid) +static bool vsock_loopback_seqpacket_allow(struct vsock_sock *vsk, u32 remote_cid) { return true; }