There are two port forwarding modes allowed with slirp4netns. One uses slirp4netns itself: data is passed across a tap device, libslirp translates the destination address and preserves the source address.
The second one uses rootlesskitport (while slirp4netns still takes care of outbound connections): it opens sockets directly in the detached network namespace and passes data between sockets without going through the tap device. It's faster, because you avoid 1. the tap device 2. Layer-4/Layer-2 translations. But those sockets are local to the namespace, so destination and source address become loopback addresses. That might be unexpected in some cases, see also https://nvd.nist.gov/vuln/detail/CVE-2021-20199.
pasta implements both modes (it's the "tap bypass" in https://passt.top/passt/about/#pasta-pack-a-subtle-tap-abstr...), and selects the appropriate one based on the original source address, so that you don't need to choose one. Local connections skip the tap device, non-local ones go through it (you can have non-loopback source addresses only for traffic coming through a a non-loopback interface).
The second one uses rootlesskitport (while slirp4netns still takes care of outbound connections): it opens sockets directly in the detached network namespace and passes data between sockets without going through the tap device. It's faster, because you avoid 1. the tap device 2. Layer-4/Layer-2 translations. But those sockets are local to the namespace, so destination and source address become loopback addresses. That might be unexpected in some cases, see also https://nvd.nist.gov/vuln/detail/CVE-2021-20199.
pasta implements both modes (it's the "tap bypass" in https://passt.top/passt/about/#pasta-pack-a-subtle-tap-abstr...), and selects the appropriate one based on the original source address, so that you don't need to choose one. Local connections skip the tap device, non-local ones go through it (you can have non-loopback source addresses only for traffic coming through a a non-loopback interface).