<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt, branch master</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>fwd, conf: Add capabilities bits to each forwarding table</title>
<updated>2026-04-21T00:09:35+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-04-17T05:05:15+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=a287375874f4f6269ed2ec833394d22ebac26a5a'/>
<id>a287375874f4f6269ed2ec833394d22ebac26a5a</id>
<content type='text'>
conf_ports_spec() and conf_ports() take the global context structure, but
their only use for it is seeing if various things are possible: which
protocols and address formats are allowed in formatting rules.  Localise
that information into the forwarding table, with a capabilities bitmap.

For now we set that caps map to the same thing for all tables, but keep it
per-table to allow for the possibility of different pif types in future
that might have different capabilities (e.g. if we add a forwarding table
for the tap interface, it won't be able to accept interface names to bind).

Use this information to remove the global context parameter from
conf_ports() and conf_ports_spec().

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-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>
conf_ports_spec() and conf_ports() take the global context structure, but
their only use for it is seeing if various things are possible: which
protocols and address formats are allowed in formatting rules.  Localise
that information into the forwarding table, with a capabilities bitmap.

For now we set that caps map to the same thing for all tables, but keep it
per-table to allow for the possibility of different pif types in future
that might have different capabilities (e.g. if we add a forwarding table
for the tap interface, it won't be able to accept interface names to bind).

Use this information to remove the global context parameter from
conf_ports() and conf_ports_spec().

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>conf: Don't pass raw commandline argument to conf_ports_spec()</title>
<updated>2026-04-21T00:09:35+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-04-17T05:05:14+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=2230d5b81a0d063aade36155f9e1846940852eb0'/>
<id>2230d5b81a0d063aade36155f9e1846940852eb0</id>
<content type='text'>
We only use the optname and optarg parameters for printing error messages,
and they're not even particularly necessary there.  Remove them.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-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>
We only use the optname and optarg parameters for printing error messages,
and they're not even particularly necessary there.  Remove them.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>conf: Move SO_BINDTODEVICE workaround to conf_ports()</title>
<updated>2026-04-21T00:09:35+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-04-17T05:05:13+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=0521f83e82295b1ac6b6704fb1b5294519090bca'/>
<id>0521f83e82295b1ac6b6704fb1b5294519090bca</id>
<content type='text'>
For historical reasons we apply our workaround for -[TU] handling when
SO_BINDTODEVICE is unavailable inside conf_ports_range_except().  We've
now removed the reasons it had to be there, so it can move to conf_ports(),
the caller's caller.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-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>
For historical reasons we apply our workaround for -[TU] handling when
SO_BINDTODEVICE is unavailable inside conf_ports_range_except().  We've
now removed the reasons it had to be there, so it can move to conf_ports(),
the caller's caller.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>conf: Allow user-specified auto-scanned port forwarding ranges</title>
<updated>2026-04-20T21:35:51+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-04-17T05:05:12+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=4e09ddf034439930685a2aa04dfe5c456581d6ba'/>
<id>4e09ddf034439930685a2aa04dfe5c456581d6ba</id>
<content type='text'>
The forwarding table now allows for arbitrary port ranges to be marked as
FWD_SCAN, meaning we don't open sockets for every port, but only those we
scan as listening on the target side.  However, there's currently no way
to create such rules, except -[tTuU] auto which always scans every port
with an unspecified listening address and interface.

Allow user-specified "auto" ranges by moving the parsing of the "auto"
keyword from conf_ports(), to conf_ports_spec() as part of the port
specified.  "auto" can be combined freely with other port ranges, e.g.
    -t 127.0.0.1/auto
    -u %lo/5000-7000,auto
    -T auto,12345
    -U auto,~1-9000

Note that any address and interface given only affects where the automatic
forwards listen, not what addresses we consider when scanning.  That is,
if the target side is listening on *any* address, we will create a forward
on the specified address.

Link: https://bugs.passt.top/show_bug.cgi?id=180
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[sbrivio: Fix extra space after if (isdigit(*p)) reported by Laurent]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The forwarding table now allows for arbitrary port ranges to be marked as
FWD_SCAN, meaning we don't open sockets for every port, but only those we
scan as listening on the target side.  However, there's currently no way
to create such rules, except -[tTuU] auto which always scans every port
with an unspecified listening address and interface.

Allow user-specified "auto" ranges by moving the parsing of the "auto"
keyword from conf_ports(), to conf_ports_spec() as part of the port
specified.  "auto" can be combined freely with other port ranges, e.g.
    -t 127.0.0.1/auto
    -u %lo/5000-7000,auto
    -T auto,12345
    -U auto,~1-9000

Note that any address and interface given only affects where the automatic
forwards listen, not what addresses we consider when scanning.  That is,
if the target side is listening on *any* address, we will create a forward
on the specified address.

Link: https://bugs.passt.top/show_bug.cgi?id=180
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[sbrivio: Fix extra space after if (isdigit(*p)) reported by Laurent]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>conf: Move "all" handling to port specifier</title>
<updated>2026-04-20T21:34:12+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-04-17T05:05:11+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=bf7eebc88dcf615817e2826d962dee147b328eca'/>
<id>bf7eebc88dcf615817e2826d962dee147b328eca</id>
<content type='text'>
Currently -[tTuU] all is handled separately in conf_ports() before calling
conf_ports_spec().  Earlier changes mean we can now move this handling to
conf_ports_spec().  This makes the code slightly simpler, but more
importantly it allows some useful combinations we couldn't previously do,
such as
	-t 127.0.0.1/all
or
	-u %eth2/all

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-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>
Currently -[tTuU] all is handled separately in conf_ports() before calling
conf_ports_spec().  Earlier changes mean we can now move this handling to
conf_ports_spec().  This makes the code slightly simpler, but more
importantly it allows some useful combinations we couldn't previously do,
such as
	-t 127.0.0.1/all
or
	-u %eth2/all

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>doc: Rework man page description of port specifiers</title>
<updated>2026-04-20T21:33:38+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-04-17T05:05:10+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=0a466eb86ecdd5a87201e0f65aaa73686a71710d'/>
<id>0a466eb86ecdd5a87201e0f65aaa73686a71710d</id>
<content type='text'>
Currently the man page describes the internal syntax of port specifiers
in prose, which isn't particularly easy to follow.  Rework it to use
more syntax "diagrams" to show how it works.  This will also allow us to
more easily update the manual page for some coming changes in syntax.

usage() output is updated similarly, though more briefly.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-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>
Currently the man page describes the internal syntax of port specifiers
in prose, which isn't particularly easy to follow.  Rework it to use
more syntax "diagrams" to show how it works.  This will also allow us to
more easily update the manual page for some coming changes in syntax.

usage() output is updated similarly, though more briefly.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tcp: Replace send buffer boost with EPOLLOUT monitoring</title>
<updated>2026-04-20T21:20:41+00:00</updated>
<author>
<name>Yumei Huang</name>
<email>yuhuang@redhat.com</email>
</author>
<published>2026-03-20T10:32:14+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=831857e9b547ac27f868b6c24049c4da435b63fe'/>
<id>831857e9b547ac27f868b6c24049c4da435b63fe</id>
<content type='text'>
Currently we use the SNDBUF boost mechanism to force TCP auto-tuning.
However, it doesn't always work, and sometimes causes a lot of
retransmissions. As a result, the throughput suffers.

This patch replaces it with monitoring EPOLLOUT when sendmsg() failure
(with EAGAIN and EWOULDBLOCK) and partial sends occur.

Tested with iperf3 inside pasta: throughput is now comparable to running
iperf3 directly on the host without pasta. However, retransmissions can
still be elevated when RTT &gt;= 50ms. For example, when RTT is between
200ms and 500ms, retransmission count varies from 30 to 120 in roughly
80% of test runs.

Link: https://bugs.passt.top/show_bug.cgi?id=138
Link: https://github.com/containers/podman/issues/28219
Suggested-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Signed-off-by: Yumei Huang &lt;yuhuang@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>
Currently we use the SNDBUF boost mechanism to force TCP auto-tuning.
However, it doesn't always work, and sometimes causes a lot of
retransmissions. As a result, the throughput suffers.

This patch replaces it with monitoring EPOLLOUT when sendmsg() failure
(with EAGAIN and EWOULDBLOCK) and partial sends occur.

Tested with iperf3 inside pasta: throughput is now comparable to running
iperf3 directly on the host without pasta. However, retransmissions can
still be elevated when RTT &gt;= 50ms. For example, when RTT is between
200ms and 500ms, retransmission count varies from 30 to 120 in roughly
80% of test runs.

Link: https://bugs.passt.top/show_bug.cgi?id=138
Link: https://github.com/containers/podman/issues/28219
Suggested-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Signed-off-by: Yumei Huang &lt;yuhuang@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>conf: Rework checking for garbage after a range</title>
<updated>2026-04-15T21:32:00+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-04-10T01:03:00+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=ea5a4bb0f2c6a869919e5105b98a45c62cfd70e6'/>
<id>ea5a4bb0f2c6a869919e5105b98a45c62cfd70e6</id>
<content type='text'>
After parsing port ranges conf_ports_spec() checks if we've reached a
chunk delimiter (',') to verify that there isn't extra garbage there.
Rework how we do this to use the recently introduced chunk-end
pointer.  This has two advantages:

1) Small, but practical: we don't need to repeat what the valid delimiters
   are, that's already handled in the chunk splitting code.

2) Large, if theoretical: this will also give an error if port parsing
   overruns a chunk boundary.  We don't really expect that to happen,
   but it would be very confusing if it did.  strtoul(3), on which
   parse_port_range() is based does say it may accept thousands
   separators based on locale which means we can't be sure it will
   only accept strings of digits.

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>
After parsing port ranges conf_ports_spec() checks if we've reached a
chunk delimiter (',') to verify that there isn't extra garbage there.
Rework how we do this to use the recently introduced chunk-end
pointer.  This has two advantages:

1) Small, but practical: we don't need to repeat what the valid delimiters
   are, that's already handled in the chunk splitting code.

2) Large, if theoretical: this will also give an error if port parsing
   overruns a chunk boundary.  We don't really expect that to happen,
   but it would be very confusing if it did.  strtoul(3), on which
   parse_port_range() is based does say it may accept thousands
   separators based on locale which means we can't be sure it will
   only accept strings of digits.

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>conf: Rework stepping through chunks of port specifiers</title>
<updated>2026-04-15T21:31:57+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-04-10T01:02:59+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=42c49e8c3bc4f8dc8cf63511201675ba6da7c1e8'/>
<id>42c49e8c3bc4f8dc8cf63511201675ba6da7c1e8</id>
<content type='text'>
Port specifier strings are made up of ',' separated chunks.  Rework the
logic we use to step through the chunks.

Specifically, maintain a pointer to the end of each chunk as well as the
start.  This is not really used yet, but will be useful in future.

This also has side effect on semantics.  Previously an empty specifier (0
chunks) was not accepted.  Now it is, and will be treated as an "exclude
only" spec which excludes only ephemeral ports.  This seems a bit odd, and
I don't expect it to be (directly) used in practice.  However, it falls
naturally out of the existing semantics, and will combine well with some
upcoming changes.

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>
Port specifier strings are made up of ',' separated chunks.  Rework the
logic we use to step through the chunks.

Specifically, maintain a pointer to the end of each chunk as well as the
start.  This is not really used yet, but will be useful in future.

This also has side effect on semantics.  Previously an empty specifier (0
chunks) was not accepted.  Now it is, and will be treated as an "exclude
only" spec which excludes only ephemeral ports.  This seems a bit odd, and
I don't expect it to be (directly) used in practice.  However, it falls
naturally out of the existing semantics, and will combine well with some
upcoming changes.

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>conf: Don't be strict about exclusivity of forwarding mode</title>
<updated>2026-04-15T21:31:54+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-04-10T01:02:58+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=d62a552c91d75f3312ec14f8138aebd5bbfe7f61'/>
<id>d62a552c91d75f3312ec14f8138aebd5bbfe7f61</id>
<content type='text'>
Currently as well as building the forwarding tables, conf() maintains a
"forwarding mode" value for each protocol and direction.  This prevents,
for example "-t all" and "-t 40000" being given on the same command line.

This restriction predates the forwarding table and is no longer really
necessary.  Remove the restriction, instead doing our best to apply all the
given options simultaneously.

 * Many combinations previously disallowed will still be disallowed because
   of conflicts between the specific generated rules, e.g.
        -t all -t 8888
   (because -t all already listens on port 8888)
 * Some new combinations are now allowed and will work, e.g.
        -t all -t 40000
   because 'all' excludes ephemeral ports (which includes 40000 on default
   Linux configurations).
 * We remove our mode variables, but keep boolean variables to track if
   any forwarding config option has been given.  This is needed in order to
   correctly default to -t auto -T auto -u auto -U auto for pasta.
 * -[tTuU] none after any other rules is still considered an error.
   However -t none *before* other rules is allowed.  This is potentially
   confusing, but is awkward to avoid for the time being.

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>
Currently as well as building the forwarding tables, conf() maintains a
"forwarding mode" value for each protocol and direction.  This prevents,
for example "-t all" and "-t 40000" being given on the same command line.

This restriction predates the forwarding table and is no longer really
necessary.  Remove the restriction, instead doing our best to apply all the
given options simultaneously.

 * Many combinations previously disallowed will still be disallowed because
   of conflicts between the specific generated rules, e.g.
        -t all -t 8888
   (because -t all already listens on port 8888)
 * Some new combinations are now allowed and will work, e.g.
        -t all -t 40000
   because 'all' excludes ephemeral ports (which includes 40000 on default
   Linux configurations).
 * We remove our mode variables, but keep boolean variables to track if
   any forwarding config option has been given.  This is needed in order to
   correctly default to -t auto -T auto -u auto -U auto for pasta.
 * -[tTuU] none after any other rules is still considered an error.
   However -t none *before* other rules is allowed.  This is potentially
   confusing, but is awkward to avoid for the time being.

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>
</feed>
