Bug 2108965

Summary: RFE: libvirt: Add native integration for passt (https://passt.top)
Product: Red Hat Enterprise Linux 9 Reporter: Stefano Brivio <sbrivio>
Component: libvirtAssignee: Laine Stump <laine>
libvirt sub component: Networking QA Contact: yalzhang <yalzhang>
Status: CLOSED ERRATA Docs Contact:
Severity: low    
Priority: unspecified CC: dzheng, haizhao, jdenemar, jsuchane, laine, lvivier, rjones, virt-maint, yalzhang
Version: 9.2Keywords: FutureFeature, Triaged
Target Milestone: rcFlags: pm-rhel: mirror+
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: libvirt-9.0.0-1.el9 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2023-05-09 07:26:34 UTC Type: Feature Request
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version: 9.0.0
Embargoed:

Comment 2 Stefano Brivio 2022-07-20 07:02:47 UTC
Assigning to myself as I plan to finish the integration work I already started a long time ago (see mentioned patch, not even posted upstream though). However, I'd be more than happy if somebody wants to pick this up.

Comment 3 Stefano Brivio 2022-11-10 19:48:27 UTC
Apologies for the long time without an update here. We have done a substantial amount of work with Laine:

- instead of using the "client" type as network source, we are adding a "passt" back-end type in the "user" network interface type, given that the passt service should be managed by libvirt and we also need to add a set of possible configuration options in this section of the XML schema

- relevant domain XML parts and lifecycle details are sketched for the moment at: https://pad.passt.top/p/libvirt

- Laine is now working on parsing of the new XML schema and on the implementation that runs passt before the guest is started

Reassigning to Laine as he's working on the implementation now.

Comment 4 Laine Stump 2023-01-27 17:41:38 UTC
support for passt has been pushed to libvirt upstream, and is included in libvirt-9.0.0, which is intended to be the libvirt release used in RHEL 9.2.

Here is an example of the XML for an emulated virtio interface that uses passt

     <interface type='user'>
       <model type='virtio'/>
       <backend type='passt' logFile='/tmp/xyzzy.log'/>
       <mac address="00:11:22:33:44:55"/>
       <source dev='eth0'/>
       <ip family='ipv4' address='172.17.2.4' prefix='24'/>
       <ip family='ipv6' address='2001:db8:ac10:fd01::20'/>
       <portForward proto='tcp'>
         <range start='2022' to='22'/>
       </portForward>
       <portForward proto='udp' address='1.2.3.4'>
         <range start='5000' end='5020' to='6000'/>
         <range start='5010' end='5015' exclude='yes'/>
       </portForward>
       <portForward proto='tcp' address='2001:db8:ac10:fd01::1:10'>>
         <range start='8080' to='80'/>
         <range start='4433' to='443'/>
       </portForward>
     </interface>

Here is the commandline of the passt process that is executed (as user qemu:qemu) by libvirt:

usr/bin/passt --one-off --socket /run/libvirt/qemu/passt/1-passt-net0.socket \
              --mac-addr 00:11:22:33:44:55 \
              --interface eth0 \
              --log-file /tmp/xyzzy.log \
              --address 172.17.2.4 --netmask 24 \
              --address 2001:db8:ac10:fd01::20 \
              --tcp-ports 2022:22
              --udp-ports 1.2.3.4/5000-5020:6000-6020,~5010-5015
              --tcp-ports 2001:db8:ac10:fd01::1:10/8080:80,4433:443

Some caveats:

* installation of the passt package is only "Recommended" in the libvirt RPM, not "Required", so it will need to be explicitly installed to test

* until passt has the proper SELinux policy for /usr/bin/passt, SELinux must be set to permissive

* forwarding ports < 1024 requires special configuration of the host outside libvirt - see the passt manpage

Comment 8 yalzhang@redhat.com 2023-02-02 06:40:58 UTC
Test with packages as below, guest can start successfully, and network function and port forwarding works well.
Set the bug as verified:tested.

libvirt-9.0.0-2.el9.x86_64
qemu-kvm-7.2.0-5.el9.x86_64
passt-0^20221110.g4129764-1.el9.x86_64

1. Prepare the env and the xml, then start the vm:
$ getenforce 
Permissive

$ whoami
test

$ virsh dumpxml test --xpath //interface 
<interface type="user">
  <mac address="52:54:00:01:db:cd"/>
  <source dev="eno1"/>
  <ip address="172.100.100.5" family="ipv4" prefix="24"/>
  <ip address="2001:db8:ac10:fd01::20" family="ipv6"/>
  <portForward proto="tcp">
    <range start="2022" to="22"/>
  </portForward>
  <model type="virtio"/>
  <backend type="passt" logFile="/home/test/passt.log"/>
  <alias name="net0"/>
  <address type="pci" domain="0x0000" bus="0x10" slot="0x01" function="0x0"/>
</interface>

$ virsh start test 
Domain 'test' started

2. Check the passt process and qemu log of the vm:
Check the vm's log:
2023-02-02 05:21:46.873+0000: Starting external device: passt
/usr/bin/passt --one-off --socket /home/test/.cache/libvirt/qemu/run/passt/1-test-net0.socket --mac-addr 52:54:00:01:db:cd --interface eno1 --log-file /home/test/passt.log --address 172.100.100.5 --netmask 24 --address 2001:db8:ac10:fd01::20 --tcp-ports 2022:22
2023-02-02 05:21:46.880+0000: starting up libvirt version: 9.0.0, package: 2.el9 (Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>, 2023-01-25-04:45:27, ), qemu version: 7.2.0qemu-kvm-7.2.0-5.el9, kernel: 5.14.0-249.el9.x86_64, .......
-netdev '{"type":"stream","addr":{"type":"unix","path":"/home/test/.cache/libvirt/qemu/run/passt/1-test-net0.socket"},"server":false,"id":"hostnet0"}' \
-device '{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:01:db:cd","bus":"pci.16","addr":"0x1"}' 

Check the passt process:
$ ps aux | grep  '/usr/bin/passt' | grep -v grep
test        6971  0.0  0.0  85584 42640 ?        Ss   00:21   0:00 /usr/bin/passt --one-off --socket /home/test/.cache/libvirt/qemu/run/passt/1-test-net0.socket --mac-addr 52:54:00:01:db:cd --interface eno1 --log-file /home/test/passt.log --address 172.100.100.5 --netmask 24 --address 2001:db8:ac10:fd01::20 --tcp-ports 2022:22

3. Login the vm and check the ip address, the ipv4 and ipv6 addresses are as expected, except the ipv4 address netmask. And the namesever and default route are the same with the host, which is as expected.

# ip addr show ens1
2: ens1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65520 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:01:db:cd brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 172.100.100.5/8 brd 172.255.255.255 scope global noprefixroute ens1
       valid_lft forever preferred_lft forever
    inet6 2001:db8:ac10:fd01::20/128 scope global noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 2001:db8:ac10:fd01:ebe7:70a:36e1:43c3/64 scope global dynamic noprefixroute 
       valid_lft 2599sec preferred_lft 2599sec
    inet6 fe80::38f1:f32:9e5e:2647/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever


# cat /etc/resolv.conf 
(same with the host)

# ip route 
(default route same with the host)
172.0.0.0/8 dev ens1 proto kernel scope link src 172.100.100.5 metric 100

# ip -6  route
::1 dev lo proto kernel metric 256 pref medium
2001:db8:ac10:fd01::20 dev ens1 proto kernel metric 100 pref medium
2001:db8:ac10:fd01::/64 dev ens1 proto ra metric 100 pref medium
fe80::/64 dev ens1 proto kernel metric 1024 pref medium
default via fe80::3e8c:9302:ef60:52a1 dev ens1 proto ra metric 100 pref medium
(default route same with the host)

4. Check the network function of the guest, it works properly:
# ping -4 www.google.com -c 2
(succeed)
# yum install -y vim
(succeed)
Try to access another host from the vm:
# ssh root.xx.xx
(succeed)

5. Test port forwarding both for tcp ipv4 and ipv6, it is expected.
On local host host, try to access the guest by ssh ipv6:
# ssh -p 2022 root@localhost
The authenticity of host '[localhost]:2022 ([::1]:2022)' can't be established.
ED25519 key fingerprint is SHA256:HjpnGK0NmRVTk56n/iJLoMouik8Vr/Lalz5KSS0yFlg.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[localhost]:2022' (ED25519) to the list of known hosts.
root@localhost's password: 
Last login: Thu Feb  2 14:19:47 2023
[root@cpe-172-100-100-5 ~]# exit
logout
Connection to localhost closed.
# ssh -p 2022 -4  root@localhost
root@localhost's password: 
Last login: Thu Feb  2 14:20:58 2023 from fe80::3e8c:9302:ef60:52a1%enp1s0
[root@cpe-172-100-100-5 ~]# 

6. destroy the host, check the passt process killed
$ virsh destroy test 
Domain 'test' destroyed
$ ps aux | grep passt | grep -v grep 
(nothing)

Comment 12 yalzhang@redhat.com 2023-02-09 07:55:20 UTC
Move the bug to verified per comment 8. The network function and port forwarding works well. 
There are some questions under clarifing with developers, I will summarize it later and file new bugs if needed.

Comment 14 errata-xmlrpc 2023-05-09 07:26:34 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (libvirt bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2023:2171