<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt, branch c9s</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>passt-repair: Correct off-by-one error verifying name</title>
<updated>2025-04-02T04:45:16+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-04-02T04:28:04+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=8fed562e63f3bf7ab2ddabaf1b31de49e03c4083'/>
<id>8fed562e63f3bf7ab2ddabaf1b31de49e03c4083</id>
<content type='text'>
passt-repair will generate an error if the name it gets from the kernel is
too long or not NUL terminated.  Downstream testing has reported
occasionally seeing this error in practice.

In turns out there is a trivial off-by-one error in the check: ev-&gt;len is
the length of the name, including terminating \0 characters, so to check
for a \0 at the end of the buffer we need to check ev-&gt;name[len - 1] not
ev-&gt;name[len].

Fixes: 42a854a52 ("pasta, passt-repair: Support multiple events per...")

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
passt-repair will generate an error if the name it gets from the kernel is
too long or not NUL terminated.  Downstream testing has reported
occasionally seeing this error in practice.

In turns out there is a trivial off-by-one error in the check: ev-&gt;len is
the length of the name, including terminating \0 characters, so to check
for a \0 at the end of the buffer we need to check ev-&gt;name[len - 1] not
ev-&gt;name[len].

Fixes: 42a854a52 ("pasta, passt-repair: Support multiple events per...")

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>migrate, tcp: bind() migrated sockets in repair mode</title>
<updated>2025-04-02T03:33:35+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-04-02T02:51:22+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=dadf2aa2691976219b8272276860926427b97c04'/>
<id>dadf2aa2691976219b8272276860926427b97c04</id>
<content type='text'>
Currently on a migration target, we create then immediately bind() new
sockets for the TCP connections we're reconstructing.  Mostly, this works,
since a socket() that is bound but hasn't had listen() or connect() called
is essentially passive.  However, this bind() is subject to the usual
address conflict checking.  In particular that means if we already have
a listening socket on that port, we'll get an EADDRINUSE.  This will happen
for every connection we try to migrate that was initiated from outside to
the guest, since we necessarily created a listening socket for that case.

We set SO_REUSEADDR on the socket in an attempt to avoid this, but that's
not sufficient; even with SO_REUSEADDR address conflicts are still
prohibited for listening sockets.  Of course once these incoming sockets
are fully repaired and connect()ed they'll no longer conflict, but that
doesn't help us if we fail at the bind().

We can avoid this by not calling bind() until we're already in repair mode
which suppresses this transient conflict.  Because of the batching of
setting repair mode, to do that we need to move the bind to a step in
tcp_flow_migrate_target_ext().

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[dwg: Fix trivial conflict for RHEL backport]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently on a migration target, we create then immediately bind() new
sockets for the TCP connections we're reconstructing.  Mostly, this works,
since a socket() that is bound but hasn't had listen() or connect() called
is essentially passive.  However, this bind() is subject to the usual
address conflict checking.  In particular that means if we already have
a listening socket on that port, we'll get an EADDRINUSE.  This will happen
for every connection we try to migrate that was initiated from outside to
the guest, since we necessarily created a listening socket for that case.

We set SO_REUSEADDR on the socket in an attempt to avoid this, but that's
not sufficient; even with SO_REUSEADDR address conflicts are still
prohibited for listening sockets.  Of course once these incoming sockets
are fully repaired and connect()ed they'll no longer conflict, but that
doesn't help us if we fail at the bind().

We can avoid this by not calling bind() until we're already in repair mode
which suppresses this transient conflict.  Because of the batching of
setting repair mode, to do that we need to move the bind to a step in
tcp_flow_migrate_target_ext().

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[dwg: Fix trivial conflict for RHEL backport]
</pre>
</div>
</content>
</entry>
<entry>
<title>pasta, passt-repair: Support multiple events per read() in inotify handlers</title>
<updated>2025-04-02T03:32:10+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-03-28T00:39:58+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=d9a7f1b008b39e03361f812f50e3704e3ac0932a'/>
<id>d9a7f1b008b39e03361f812f50e3704e3ac0932a</id>
<content type='text'>
The current code assumes that we'll get one event per read() on
inotify descriptors, but that's not the case, not from documentation,
and not from reports.

Add loops in the two inotify handlers we have, in pasta-specific code
and passt-repair, to go through all the events we receive.

Link: https://bugs.passt.top/show_bug.cgi?id=119
[dwg: Remove unnecessary buffer expansion, use strnlen instead of strlen
 to make Coverity happier]
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Add additional check on ev-&gt;name and ev-&gt;len in passt-repair]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The current code assumes that we'll get one event per read() on
inotify descriptors, but that's not the case, not from documentation,
and not from reports.

Add loops in the two inotify handlers we have, in pasta-specific code
and passt-repair, to go through all the events we receive.

Link: https://bugs.passt.top/show_bug.cgi?id=119
[dwg: Remove unnecessary buffer expansion, use strnlen instead of strlen
 to make Coverity happier]
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Add additional check on ev-&gt;name and ev-&gt;len in passt-repair]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tcp: Flush socket before checking for more data in active close state</title>
<updated>2025-04-02T03:32:10+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-03-19T16:57:45+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=37550961ea10daa05336b4f93e03e2a44e71e40e'/>
<id>37550961ea10daa05336b4f93e03e2a44e71e40e</id>
<content type='text'>
Otherwise, if all the pending data is acknowledged:

- tcp_update_seqack_from_tap() updates the current tap-side ACK
  sequence (conn-&gt;seq_ack_from_tap)

- next, we compare the sequence we sent (conn-&gt;seq_to_tap) to the
  ACK sequence (conn-&gt;seq_ack_from_tap) in tcp_data_from_sock() to
  understand if there's more data we can send.

  If they match, we conclude that we haven't sent any of that data,
  and keep re-sending it.

We need, instead, to flush the socket (drop acknowledged data) before
calling tcp_update_seqack_from_tap(), so that once we update
conn-&gt;seq_ack_from_tap, we can be sure that all data until there is
gone from the socket.

Link: https://bugs.passt.top/show_bug.cgi?id=114
Reported-by: Marek Marczykowski-Górecki &lt;marmarek@invisiblethingslab.com&gt;
Fixes: 30f1e082c3c0 ("tcp: Keep updating window and checking for socket data after FIN from guest")
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
(cherry picked from commit ebdd46367ce1acba235013d97e362b8677b538d5)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Otherwise, if all the pending data is acknowledged:

- tcp_update_seqack_from_tap() updates the current tap-side ACK
  sequence (conn-&gt;seq_ack_from_tap)

- next, we compare the sequence we sent (conn-&gt;seq_to_tap) to the
  ACK sequence (conn-&gt;seq_ack_from_tap) in tcp_data_from_sock() to
  understand if there's more data we can send.

  If they match, we conclude that we haven't sent any of that data,
  and keep re-sending it.

We need, instead, to flush the socket (drop acknowledged data) before
calling tcp_update_seqack_from_tap(), so that once we update
conn-&gt;seq_ack_from_tap, we can be sure that all data until there is
gone from the socket.

Link: https://bugs.passt.top/show_bug.cgi?id=114
Reported-by: Marek Marczykowski-Górecki &lt;marmarek@invisiblethingslab.com&gt;
Fixes: 30f1e082c3c0 ("tcp: Keep updating window and checking for socket data after FIN from guest")
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
(cherry picked from commit ebdd46367ce1acba235013d97e362b8677b538d5)
</pre>
</div>
</content>
</entry>
<entry>
<title>migrate: Bump migration version number</title>
<updated>2025-04-02T03:32:10+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-03-19T05:14:23+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=53f2ed715e68848451353addb795c3f09992df48'/>
<id>53f2ed715e68848451353addb795c3f09992df48</id>
<content type='text'>
v1 of the migration stream format, had some flaws: it didn't properly
handle endianness of the MSS field, and it didn't transfer the RFC7323
timestamp.  We've now fixed those bugs, but it requires incompatible
changes to the stream format.

Because of the timestamps in particular, v1 is not really usable, so there
is little point maintaining compatible support for it.  However, v1 is in
released packages, both upstream and downstream (RHEL at least).  Just
updating the stream format without bumping the version would lead to very
cryptic errors if anyone did attempt to migrate between an old and new
passt.

So, bump the migration version to v2, so we'll get a clear error message if
anyone attempts this.  We don't attempt to maintain backwards compatibility
with v1, however: we'll simply fail if given a v1 stream.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
(cherry picked from commit c250ffc5c11385d9618b3a8165e676d68d5cbfa2)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
v1 of the migration stream format, had some flaws: it didn't properly
handle endianness of the MSS field, and it didn't transfer the RFC7323
timestamp.  We've now fixed those bugs, but it requires incompatible
changes to the stream format.

Because of the timestamps in particular, v1 is not really usable, so there
is little point maintaining compatible support for it.  However, v1 is in
released packages, both upstream and downstream (RHEL at least).  Just
updating the stream format without bumping the version would lead to very
cryptic errors if anyone did attempt to migrate between an old and new
passt.

So, bump the migration version to v2, so we'll get a clear error message if
anyone attempts this.  We don't attempt to maintain backwards compatibility
with v1, however: we'll simply fail if given a v1 stream.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
(cherry picked from commit c250ffc5c11385d9618b3a8165e676d68d5cbfa2)
</pre>
</div>
</content>
</entry>
<entry>
<title>migrate, tcp: Migrate RFC 7323 timestamp</title>
<updated>2025-04-02T03:32:10+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-03-19T05:14:22+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=8c5727bd9b490283f4cdee3b44dae1911f36e5be'/>
<id>8c5727bd9b490283f4cdee3b44dae1911f36e5be</id>
<content type='text'>
Currently our migration of the state of TCP sockets omits the RFC 7323
timestamp.  In some circumstances that can result in data sent from the
target machine not being received, because it is discarded on the peer due
to PAWS checking.

Add code to dump and restore the timestamp across migration.

Link: https://bugs.passt.top/show_bug.cgi?id=115
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Minor style fixes]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
(cherry picked from commit cfb3740568ab291d7be00e457658c45ce9367ed5)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently our migration of the state of TCP sockets omits the RFC 7323
timestamp.  In some circumstances that can result in data sent from the
target machine not being received, because it is discarded on the peer due
to PAWS checking.

Add code to dump and restore the timestamp across migration.

Link: https://bugs.passt.top/show_bug.cgi?id=115
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Minor style fixes]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
(cherry picked from commit cfb3740568ab291d7be00e457658c45ce9367ed5)
</pre>
</div>
</content>
</entry>
<entry>
<title>flow: Add flow_perror() helper</title>
<updated>2025-04-02T03:32:10+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-02-18T08:59:24+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=4c6b69f359981be71099153fd882f53bd4ac8511'/>
<id>4c6b69f359981be71099153fd882f53bd4ac8511</id>
<content type='text'>
Our general logging helpers include a number of _perror() variants which,
like perror(3) include the description of the current errno.  We didn't
have those for our flow specific logging helpers, though.  Fill this gap
with flow_perror() and flow_dbg_perror(), and use them where it's useful.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
(cherry picked from commit adb46c11d0ea67824cf8c4ef2113ec0b2c563c0e)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Our general logging helpers include a number of _perror() variants which,
like perror(3) include the description of the current errno.  We didn't
have those for our flow specific logging helpers, though.  Fill this gap
with flow_perror() and flow_dbg_perror(), and use them where it's useful.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
(cherry picked from commit adb46c11d0ea67824cf8c4ef2113ec0b2c563c0e)
</pre>
</div>
</content>
</entry>
<entry>
<title>migrate, tcp: More careful marshalling of mss parameter during migration</title>
<updated>2025-04-02T03:32:10+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-03-19T05:14:21+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=8a938c5a2c403759b932984e8eadfd602574d040'/>
<id>8a938c5a2c403759b932984e8eadfd602574d040</id>
<content type='text'>
During migration we extract the limit on segment size using TCP_MAXSEG,
and set it on the other side with TCP_REPAIR_OPTIONS.  However, unlike most
32-bit values we transfer we transfer it in native endian, not network
endian.  This is not correct; add it to the list of endian fixups we make.

In addition, while MAXSEG will be 32-bits in practice, and is given as such
to TCP_REPAIR_OPTIONS, the TCP_MAXSEG sockopt treats it as an 'int'.  It's
not strictly safe to pass a uint32_t to a getsockopt() expecting an int,
although we'll get away with it on most (maybe all) platforms.  Correct
this as well.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Minor coding style fix]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
(cherry picked from commit 28772ee91a60b34786023496ea17c2c2f4e5f7f5)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
During migration we extract the limit on segment size using TCP_MAXSEG,
and set it on the other side with TCP_REPAIR_OPTIONS.  However, unlike most
32-bit values we transfer we transfer it in native endian, not network
endian.  This is not correct; add it to the list of endian fixups we make.

In addition, while MAXSEG will be 32-bits in practice, and is given as such
to TCP_REPAIR_OPTIONS, the TCP_MAXSEG sockopt treats it as an 'int'.  It's
not strictly safe to pass a uint32_t to a getsockopt() expecting an int,
although we'll get away with it on most (maybe all) platforms.  Correct
this as well.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Minor coding style fix]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
(cherry picked from commit 28772ee91a60b34786023496ea17c2c2f4e5f7f5)
</pre>
</div>
</content>
</entry>
<entry>
<title>passt-repair: Fix build with -Werror=format-security</title>
<updated>2025-04-02T03:32:10+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-03-18T16:18:47+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=f45aac7aed2a3b8886fe88f39709e4e9893dbe99'/>
<id>f45aac7aed2a3b8886fe88f39709e4e9893dbe99</id>
<content type='text'>
Fixes: 04701702471e ("passt-repair: Add directory watch")
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
(cherry picked from commit 51f3c071a76bd20677e72b49007b822dca71e755)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes: 04701702471e ("passt-repair: Add directory watch")
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
(cherry picked from commit 51f3c071a76bd20677e72b49007b822dca71e755)
</pre>
</div>
</content>
</entry>
<entry>
<title>flow, repair: Wait for a short while for passt-repair to connect</title>
<updated>2025-04-02T03:32:10+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-03-06T19:00:51+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=283b18f6b10f26651f9274b9431e0c424f8d45c6'/>
<id>283b18f6b10f26651f9274b9431e0c424f8d45c6</id>
<content type='text'>
...and time out after that. This will be needed because of an upcoming
change to passt-repair enabling it to start before passt is started,
on both source and target, by means of an inotify watch.

Once the inotify watch triggers, passt-repair will connect right away,
but we have no guarantees that the connection completes before we
start the migration process, so wait for it (for a reasonable amount
of time).

Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
(cherry picked from commit c8b520c0625b440d0dcd588af085d35cf46aae2c)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
...and time out after that. This will be needed because of an upcoming
change to passt-repair enabling it to start before passt is started,
on both source and target, by means of an inotify watch.

Once the inotify watch triggers, passt-repair will connect right away,
but we have no guarantees that the connection completes before we
start the migration process, so wait for it (for a reasonable amount
of time).

Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
(cherry picked from commit c8b520c0625b440d0dcd588af085d35cf46aae2c)
</pre>
</div>
</content>
</entry>
</feed>
