<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/vu_common.h, branch 2026_05_07.1afd4ed</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>vu_common: Move iovec management into vu_collect()</title>
<updated>2026-03-20T19:05:34+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-03-18T09:19:41+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=451fb7600b8dfdf6800abee613f2b4f026fbd150'/>
<id>451fb7600b8dfdf6800abee613f2b4f026fbd150</id>
<content type='text'>
Previously, callers had to pre-initialize virtqueue elements with iovec
entries using vu_set_element() or vu_init_elem() before calling
vu_collect().  This meant each element owned a fixed, pre-assigned iovec
slot.

Move the iovec array into vu_collect() as explicit parameters (in_sg,
max_in_sg, and in_total), letting it pass the remaining iovec capacity
directly to vu_queue_pop().  A running current_iov counter tracks
consumed entries across elements, so multiple elements share a single
iovec pool.  The optional in_total output parameter reports how many iovec
entries were consumed, allowing callers to track usage across multiple
vu_collect() calls.

This removes vu_set_element() and vu_init_elem() which are no longer
needed, and is a prerequisite for multi-buffer support where a single
virtqueue element can use more than one iovec entry.  For now, callers
assert the current single-iovec-per-element invariant until they are
updated to handle multiple iovecs.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, callers had to pre-initialize virtqueue elements with iovec
entries using vu_set_element() or vu_init_elem() before calling
vu_collect().  This meant each element owned a fixed, pre-assigned iovec
slot.

Move the iovec array into vu_collect() as explicit parameters (in_sg,
max_in_sg, and in_total), letting it pass the remaining iovec capacity
directly to vu_queue_pop().  A running current_iov counter tracks
consumed entries across elements, so multiple elements share a single
iovec pool.  The optional in_total output parameter reports how many iovec
entries were consumed, allowing callers to track usage across multiple
vu_collect() calls.

This removes vu_set_element() and vu_init_elem() which are no longer
needed, and is a prerequisite for multi-buffer support where a single
virtqueue element can use more than one iovec entry.  For now, callers
assert the current single-iovec-per-element invariant until they are
updated to handle multiple iovecs.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vu_common: Always set num_buffers in virtio-net header</title>
<updated>2026-03-04T17:50:49+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-03-03T15:17:34+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=71a0d6cbbb0f0c936130e28dd33d48a16894491b'/>
<id>71a0d6cbbb0f0c936130e28dd33d48a16894491b</id>
<content type='text'>
Legacy virtio used two different header formats: struct virtio_net_hdr
(10 bytes) when VIRTIO_NET_F_MRG_RXBUF was not negotiated, and
struct virtio_net_hdr_mrg_rxbuf (12 bytes) when it was.  The
num_buffers field only existed in the larger header.

Modern virtio (VIRTIO_F_VERSION_1, i.e. virtio 1.0+) always uses the
12-byte struct virtio_net_hdr_mrg_rxbuf header regardless of whether
VIRTIO_NET_F_MRG_RXBUF is negotiated, so num_buffers is always present
in the header.  passt only supports modern virtio and dies if
VIRTIO_F_VERSION_1 is not negotiated (vhost_user.c), and VNET_HLEN is
unconditionally defined as sizeof(struct virtio_net_hdr_mrg_rxbuf).

The virtio specification (v1.1, section 5.1.6) requires that:

  "The device MUST set num_buffers to 1 if VIRTIO_NET_F_MRG_RXBUF has
   not been negotiated."

vu_set_vnethdr() only set num_buffers when VIRTIO_NET_F_MRG_RXBUF was
negotiated.  When it was not, num_buffers was left uninitialised,
violating the spec.

Since vu_collect() already limits buffer collection to a single element
when VIRTIO_NET_F_MRG_RXBUF is not negotiated, num_buffers passed by
callers is guaranteed to be 1 in that case.  We can therefore
unconditionally set num_buffers, which makes the vdev parameter
unnecessary.

Drop the vdev parameter from vu_set_vnethdr() and update all callers.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Legacy virtio used two different header formats: struct virtio_net_hdr
(10 bytes) when VIRTIO_NET_F_MRG_RXBUF was not negotiated, and
struct virtio_net_hdr_mrg_rxbuf (12 bytes) when it was.  The
num_buffers field only existed in the larger header.

Modern virtio (VIRTIO_F_VERSION_1, i.e. virtio 1.0+) always uses the
12-byte struct virtio_net_hdr_mrg_rxbuf header regardless of whether
VIRTIO_NET_F_MRG_RXBUF is negotiated, so num_buffers is always present
in the header.  passt only supports modern virtio and dies if
VIRTIO_F_VERSION_1 is not negotiated (vhost_user.c), and VNET_HLEN is
unconditionally defined as sizeof(struct virtio_net_hdr_mrg_rxbuf).

The virtio specification (v1.1, section 5.1.6) requires that:

  "The device MUST set num_buffers to 1 if VIRTIO_NET_F_MRG_RXBUF has
   not been negotiated."

vu_set_vnethdr() only set num_buffers when VIRTIO_NET_F_MRG_RXBUF was
negotiated.  When it was not, num_buffers was left uninitialised,
violating the spec.

Since vu_collect() already limits buffer collection to a single element
when VIRTIO_NET_F_MRG_RXBUF is not negotiated, num_buffers passed by
callers is guaranteed to be 1 in that case.  We can therefore
unconditionally set num_buffers, which makes the vdev parameter
unnecessary.

Drop the vdev parameter from vu_set_vnethdr() and update all callers.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Add missing includes to headers</title>
<updated>2026-03-04T16:39:57+00:00</updated>
<author>
<name>Peter Foley</name>
<email>pefoley@google.com</email>
</author>
<published>2026-02-23T18:11:19+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=adbf5c135f19db5b6751393b7f5cbf516031bde8'/>
<id>adbf5c135f19db5b6751393b7f5cbf516031bde8</id>
<content type='text'>
Support build systems like bazel that check that headers are
self-contained.

Also update includes so that clang-include-cleaner succeeds.

Tested with:
clang-include-cleaner-19 --extra-arg=-D_GNU_SOURCE --extra-arg=-DPAGE_SIZE=4096 --extra-arg=-DVERSION=\"git\" --extra-arg=-DHAS_GETRANDOM *.h *.c

Signed-off-by: Peter Foley &lt;pefoley@google.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Support build systems like bazel that check that headers are
self-contained.

Also update includes so that clang-include-cleaner succeeds.

Tested with:
clang-include-cleaner-19 --extra-arg=-D_GNU_SOURCE --extra-arg=-DPAGE_SIZE=4096 --extra-arg=-DVERSION=\"git\" --extra-arg=-DHAS_GETRANDOM *.h *.c

Signed-off-by: Peter Foley &lt;pefoley@google.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>virtio: Introduce VNET_HLEN macro for virtio net header length</title>
<updated>2026-02-15T01:52:51+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-02-12T11:39:31+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=02af38d4177550c086bae54246fc3aaa33ddc018'/>
<id>02af38d4177550c086bae54246fc3aaa33ddc018</id>
<content type='text'>
Replace all open-coded sizeof(struct virtio_net_hdr_mrg_rxbuf) with a
VNET_HLEN macro.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Replace all open-coded sizeof(struct virtio_net_hdr_mrg_rxbuf) with a
VNET_HLEN macro.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>treewide: Fix places where we incorrectly indented with spaces</title>
<updated>2026-01-11T00:31:50+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-01-09T04:09:22+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=b973f4a6cc50571f8375c60a7e511a77bcf5c202'/>
<id>b973f4a6cc50571f8375c60a7e511a77bcf5c202</id>
<content type='text'>
Had a moment to address this trivial issue.

The passt convention is to indent code with tabs (K&amp;R / kernel style).
However there were a handful of places where we used spaces instead.  Fix
them.

Link: https://bugs.passt.top/show_bug.cgi?id=135
Reported-by: Xun Gu &lt;xugu@redhat.com&gt;
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Had a moment to address this trivial issue.

The passt convention is to indent code with tabs (K&amp;R / kernel style).
However there were a handful of places where we used spaces instead.  Fix
them.

Link: https://bugs.passt.top/show_bug.cgi?id=135
Reported-by: Xun Gu &lt;xugu@redhat.com&gt;
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tcp, udp: Pad batched frames for vhost-user modes to 60 bytes (802.3 minimum)</title>
<updated>2025-12-08T03:47:46+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-11-03T10:16:12+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=0cb8f90036540527133ad55a5976d2f639cce8da'/>
<id>0cb8f90036540527133ad55a5976d2f639cce8da</id>
<content type='text'>
For both TCP and UDP, instead of just expecting the first provided
buffer to be large enough to contain the headers we need (from 42
bytes for UDP data over IPv4 to 82 bytes for TCP with options over
IPv6), change that assumption to make sure that buffers are anyway
at least ETH_ZLEN-sized buffers (60 bytes).

This looks reasonable because there are no known vhost-user
hypervisor implementations that would give us smaller buffers than
that, and we would anyway hit an assertion failure with IPv6 if we
ever had less than 60 bytes per buffer.

At this point, all we need to do is to pad the first (and only)
buffer, should data and headers use less than that.

Link: https://bugs.passt.top/show_bug.cgi?id=166
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
For both TCP and UDP, instead of just expecting the first provided
buffer to be large enough to contain the headers we need (from 42
bytes for UDP data over IPv4 to 82 bytes for TCP with options over
IPv6), change that assumption to make sure that buffers are anyway
at least ETH_ZLEN-sized buffers (60 bytes).

This looks reasonable because there are no known vhost-user
hypervisor implementations that would give us smaller buffers than
that, and we would anyway hit an assertion failure with IPv6 if we
ever had less than 60 bytes per buffer.

At this point, all we need to do is to pad the first (and only)
buffer, should data and headers use less than that.

Link: https://bugs.passt.top/show_bug.cgi?id=166
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vu_common: Clarify prototype of vu_collect()</title>
<updated>2025-12-07T22:18:04+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-12-04T22:18:51+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=834982c0a35145754de38f77de6e41815cb33178'/>
<id>834982c0a35145754de38f77de6e41815cb33178</id>
<content type='text'>
The last argument of vu_collect() can't exceed @size, but this isn't
documented and it wasn't obvious to me, to the point that I actually
proposed a change to "fix" callers so that they wouldn't overrun input
buffers.

Rename @frame_size to @collected, and clarify that it can only be up
to @size bytes.

Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The last argument of vu_collect() can't exceed @size, but this isn't
documented and it wasn't obvious to me, to the point that I actually
proposed a change to "fix" callers so that they wouldn't overrun input
buffers.

Rename @frame_size to @collected, and clarify that it can only be up
to @size bytes.

Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>migrate: Skeleton of live migration logic</title>
<updated>2025-02-12T18:47:07+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-02-12T07:07:13+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=5911e08c0f53e46547e7eeb1dd824c8ab96e512e'/>
<id>5911e08c0f53e46547e7eeb1dd824c8ab96e512e</id>
<content type='text'>
Introduce facilities for guest migration on top of vhost-user
infrastructure.  Add migration facilities based on top of the current
vhost-user infrastructure, moving vu_migrate() and related functions
to migrate.c.

Versioned migration stages define function pointers to be called on
source or target, or data sections that need to be transferred.

The migration header consists of a magic number, a version number for the
encoding, and a "compat_version" which represents the oldest version which
is compatible with the current one.  We don't use it yet, but that allows
for the future possibility of backwards compatible protocol extensions.

Co-authored-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Introduce facilities for guest migration on top of vhost-user
infrastructure.  Add migration facilities based on top of the current
vhost-user infrastructure, moving vu_migrate() and related functions
to migrate.c.

Versioned migration stages define function pointers to be called on
source or target, or data sections that need to be transferred.

The migration header consists of a magic number, a version number for the
encoding, and a "compat_version" which represents the oldest version which
is compatible with the current one.  We don't use it yet, but that allows
for the future possibility of backwards compatible protocol extensions.

Co-authored-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vhost-user: add VHOST_USER_SET_DEVICE_STATE_FD command</title>
<updated>2025-01-20T18:51:24+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2024-12-19T11:13:59+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=31d70024beda1e49131d7b68dd7554bee16c79f3'/>
<id>31d70024beda1e49131d7b68dd7554bee16c79f3</id>
<content type='text'>
Set the file descriptor to use to transfer the
backend device state during migration.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[sbrivio: Fixed nits and coding style here and there]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Set the file descriptor to use to transfer the
backend device state during migration.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[sbrivio: Fixed nits and coding style here and there]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>virtio: Use const pointer for vu_dev</title>
<updated>2025-01-05T22:48:59+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2024-12-19T11:13:52+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=898e853635a79e33917bb4646ff1fb5fc3a92997'/>
<id>898e853635a79e33917bb4646ff1fb5fc3a92997</id>
<content type='text'>
We don't modify the structure in some virtio functions.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We don't modify the structure in some virtio functions.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
