On Tue, Sep 15, 2026 at 05:47:02PM +0200, Stefano Garzarella wrote: > On Wed, Sep 02, 2026 at 04:00:49PM -0700, Bobby Eshleman wrote: > > From: Bobby Eshleman <[email protected]> > > > > virtio-vsock did not have namespace support (the device was always > > accessible to any global namespace). > > > > Make the virtio-vsock device assignable to a namespace and initialize it > > to init_net. Because virtio-vsock and init_net are both hardcoded to > > global mode, nothing changes until the assign ioctl is issued. > > > > When the device's local-mode namespace is being destroyed, received > > packets are reset until new valid a namespace has been assigned and/or > > automatically returned to, and the next RX batch begins (in > > virtio_transport_rx_work). They are reset rather than dropped because > > vsock does not retransmit, so a silent drop would leave the host waiting > > for a timeout, and a connection request arriving in that window has no > > socket whose teardown would tell it otherwise. This requires making > > virtio_transport_reset_no_sock() available outside of the common code. > > > > When a device is assigned to a namespace, every already established > > vsock socket that is no longer able to reach the device is forcibly > > reset. For that reason, adding new sockets to the connected table must > > be performed atomically with regards to namespace assignment. This > > ensures that when the socket is added to the connected table that it > > actually passes the new reachability conditions set by ns assignment. If > > it wins the race to the table and does NOT pass the reachability tests, > > then the reset sweep will correctly catch it. This is the purpose > > of the new helper 'vsock_maybe_set_connected()'. > > > > Signed-off-by: Bobby Eshleman <[email protected]> > > --- > > include/linux/virtio_vsock.h | 2 ++ > > net/vmw_vsock/virtio_transport.c | 28 ++++++++++++++++++++++------ > > net/vmw_vsock/virtio_transport_common.c | 28 +++++++++++++++++++++------- > > 3 files changed, 45 insertions(+), 13 deletions(-) > > > > diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h > > index f91704731057..9c68ce1d7fb4 100644 > > --- a/include/linux/virtio_vsock.h > > +++ b/include/linux/virtio_vsock.h > > @@ -286,6 +286,8 @@ void virtio_transport_inc_tx_pkt(struct > > virtio_vsock_sock *vvs, struct sk_buff * > > u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 wanted); > > void virtio_transport_put_credit(struct virtio_vsock_sock *vvs, u32 credit); > > void virtio_transport_deliver_tap_pkt(struct sk_buff *skb); > > +int virtio_transport_reset_no_sock(const struct virtio_transport *t, > > + struct sk_buff *skb, struct net *net); > > int virtio_transport_purge_skbs(void *vsk, struct sk_buff_head *list); > > int virtio_transport_read_skb(struct vsock_sock *vsk, skb_read_actor_t > > read_actor); > > int virtio_transport_notify_set_rcvlowat(struct vsock_sock *vsk, int val); > > diff --git a/net/vmw_vsock/virtio_transport.c > > b/net/vmw_vsock/virtio_transport.c > > index 4f9aa9c4c3aa..a453a4f828dc 100644 > > --- a/net/vmw_vsock/virtio_transport.c > > +++ b/net/vmw_vsock/virtio_transport.c > > @@ -540,9 +540,14 @@ static bool virtio_transport_msgzerocopy_allow(void) > > return true; > > } > > > > +static bool virtio_transport_netns_assign_allow(void) > > +{ > > + return true; > > +} > > + > > bool virtio_transport_stream_allow(struct vsock_sock *vsk, u32 cid, u32 > > port) > > { > > - return vsock_net_mode_global(vsk); > > + return vsock_g2h_net_reachable(sock_net(sk_vsock(vsk))); > > } > > > > static bool virtio_transport_seqpacket_allow(struct vsock_sock *vsk, > > @@ -587,6 +592,7 @@ static struct virtio_transport virtio_transport = { > > .seqpacket_has_data = virtio_transport_seqpacket_has_data, > > > > .msgzerocopy_allow = virtio_transport_msgzerocopy_allow, > > + .netns_assign_allow = virtio_transport_netns_assign_allow, > > > > .notify_poll_in = virtio_transport_notify_poll_in, > > .notify_poll_out = virtio_transport_notify_poll_out, > > @@ -616,7 +622,7 @@ virtio_transport_seqpacket_allow(struct vsock_sock > > *vsk, u32 remote_cid) > > struct virtio_vsock *vsock; > > bool seqpacket_allow; > > > > - if (!vsock_net_mode_global(vsk)) > > + if (!vsock_g2h_net_reachable(sock_net(sk_vsock(vsk)))) > > return false; > > > > seqpacket_allow = false; > > @@ -634,6 +640,9 @@ static void virtio_transport_rx_work(struct work_struct > > *work) > > struct virtio_vsock *vsock = > > container_of(work, struct virtio_vsock, rx_work); > > struct virtqueue *vq; > > + struct net *net; > > + > > + net = vsock_g2h_net_get(); > > > > mutex_lock(&vsock->rx_lock); > > > > @@ -682,10 +691,14 @@ static void virtio_transport_rx_work(struct > > work_struct *work) > > > > virtio_transport_deliver_tap_pkt(skb); > > > > - /* Force virtio-transport into global mode since it > > - * does not yet support local-mode namespacing. > > - */ > > - virtio_transport_recv_pkt(&virtio_transport, skb, NULL); > > + if (unlikely(!net)) { > > + virtio_transport_reset_no_sock( > > + &virtio_transport, skb, &init_net); > > Why init_net?
This parameter is actually unused by virtio_transport_reset_no_sock(), its call to virtio_transport_send_pkt(), and even the eventual call to virtio_transport_deliver_tap_pkt()... so maybe NULL w/ a comment would be better? > > > + kfree_skb(skb); > > + continue; > > + } > > + > > + virtio_transport_recv_pkt(&virtio_transport, skb, net); > > } > > } while (!virtqueue_enable_cb(vq)); > > > > @@ -694,6 +707,9 @@ static void virtio_transport_rx_work(struct work_struct > > *work) > > virtio_vsock_rx_fill(vsock); > > out_nofill: > > mutex_unlock(&vsock->rx_lock); > > + > > + if (net) > > + put_net(net); > > put_net() should handle NULL net, right? It does, and somehow I forgot that. Thanks, Bobby

