Skip to content

Instantly share code, notes, and snippets.

@max-i-mil
Last active September 25, 2024 07:26
Show Gist options
  • Save max-i-mil/f44e8e6f2416d88055fc2d0f36c6173b to your computer and use it in GitHub Desktop.
Save max-i-mil/f44e8e6f2416d88055fc2d0f36c6173b to your computer and use it in GitHub Desktop.
Short summary to run Linux VMs on an Apple M1 host using QEMU, libvirt and HVF with a working network setup

Linux Virtual Machines with Private Network on an Apple M1 Device

Background

The aim was to be able to:

  1. Run multiple Linux VMs on an Apple M1/ARM device
  2. Use Apple's HVF for native performance speeds
  3. Configure VMs to allow network access to each other
  4. Configure VMs to allow access to the internet
  5. Not rely on custom modifications of software

I had originally assumed I would be up and running with the above in a few hours, but I was wrong. After looking for examples online, of which there are many. The problem was that they were seemingly all based on either Intel based Apple devices, or for MacOS < 12. I'm using a 2021 MacBookPro with an M1 Pro chip running MacOS 12.6 (Monterey). I have therefore spent a lot of time finding out what doesn't work anymore.

I was also new to some of the tools I have used including QEMU and libvirt.

After much experimentation and failure, I have a working example to meet the goals set out. A lot of the issues faced seemed to be that changes to MacOS over the past few years and the time it takes to reflect this in software, has meant a period between what used to work, things not working, and now working again with different implementations. The end result achieved using the process defined below looks similar to the following:

image

Many examples I found online to help meet goal 3 relied on TAP devices. As I understand these were not natively supported by MacOS and required kernel extensions (kexts) to enable the functionality - commonly through a tool called 'tuntaposx'. As stated on their website the project has not been maintained since 2015 and references the requirement from Apple to use notarization on all updated or new kernel extensions which tuntaposx does not have. Tunnelblick details the situation here.

There are other helper tools available from QEMU/libvirt to deal with networking like qemu-bridge-helper / libvirt virtual networks - but they too don't yet seem to be working on my device for various reasons. Some of the current open issues from these projects detail more


Requirements

I have tested this using:

  • MacOS - 12.6.1 Monterey
  • Chip - M1 Pro
  • QEMU - 7.1.0
  • libvirt - 8.9.0
  • virt-manager - 4.1.0

As it's MacOS, I have used homebrew for package management. For convenience I am also using brew services as a wrapper for launchctl

brew install qemu libvirt virt-manager

# must use sudo as it affects qemu later
sudo brew services start libvirt

For native speeds you will need an OS ISO image for AARCH64 hosts (ARM). x86 ISO files will work but because Apple M1 devices use an ARM architecture they will need QEMU to emulate the necessary hardware which is much slower, and you may need to alter the command given later to use 'tcg' instead of 'hvf'.

I went with RHEL 9 as RHEL 7/8 wont work natively due to page sizes

Basic libvirt + QEMU knowledge is also required.

The working solution relies on the latest version of QEMU (7.1.0 as of Nov 2022). Some of the functionality has been added, with the man page updated, but with the QEMU wiki docs online not yet featuring the same detail on the invocation page.


Process

With dependencies installed - you can now create a VM using a single command, and everything else will be handled automatically. You can run the same command again to create a second VM.

# create a libvirt 'domain' - specify some options using qemu command line pass through
sudo virt-install \
--name host1 \
--memory 2048 \
--vcpus 2 \
--disk size=30 \
--cdrom /path/to/ISO_files/rhel-baseos-9.0-aarch64-dvd.iso \
--os-variant rhel9.0 \
--virt-type hvf \
--qemu-commandline='-M highmem=off -netdev vmnet-shared,id=net0 -device virtio-net-device,netdev=net0,mac=54:54:00:55:54:51' \
--network user

# create a second libvirt 'domain' - ensure the friendly name and MAC address of the net device are unique and run the same command again
sudo virt-install \
--name host2 \
--memory 2048 \
--vcpus 2 \
--disk size=30 \
--cdrom /path/to/ISO_files/rhel-baseos-9.0-aarch64-dvd.iso \
--os-variant rhel9.0 \
--virt-type hvf \
--qemu-commandline='-M highmem=off -netdev vmnet-shared,id=net0 -device virtio-net-device,netdev=net0,mac=54:54:00:55:54:52' \
--network user

# create Nth libvirt domain - just keep name and MAC address unique
sudo virt-install \
--name hostN \
--memory 2048 \
--vcpus 2 \
--disk size=30 \
--cdrom /path/to/ISO_files/rhel-baseos-9.0-aarch64-dvd.iso \
--os-variant rhel9.0 \
--virt-type hvf \
--qemu-commandline='-M highmem=off -netdev vmnet-shared,id=net0 -device virtio-net-device,netdev=net0,mac=NN:NN:NN:NN:NN:NN' \
--network user

Notable flags are:

--virt-type hvf tell QEMU to use the Apple Hypervisor Framework instead of an alternative such as TCG. This enables the native speeds
--network user enable QEMU user mode networking, which gives us access to the host and the internet. Alternative is 'none' which removes access to both. Other named libvirt networks do not seem to work on the current version for my device i.e. '--network name=default'

From the --qemu-commandline flag

-netdev vmnet-shared tells QEMU to use the vmnet APIs provided by Apple as part of HVF. This is the alternative to managing our own bridge/TAP devices commonly used in the past. Flag alternatives are vmnet-host and vmnet-bridged
-device mac=XX:YY... defines the MAC address used for the virtual device that will be attached to our VM. Must be unique per VM for DHCP

I wasn't able to find virt-install equivalents for 'vmnet-*' netdev options yet hence the qemu-commandline workaround but this may come in a future release

In my case I connected to each VM via the console to complete the installation process before continuing.

This has now done a few things in the background:

On the Apple host:

  • A bridge device has been created called 'bridge100' (sequential from 100 if you start multiple vmnet types at once)
  • A vmenet device has been created for each VM requested, and then attached to the bridge
  • An internal macOS DHCP service (bootpd) has been started to assign IP addresses to each VM (and the bridge)
  • The QEMU user mode network (SLIRP) has been created which gives internet access over the default gateway 10.0.2.2
# some output omitted
root@apple-host$ ifconfig
...
vmenet0: flags=8b63<UP,BROADCAST,SMART,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
        ether aa:70:70:52:86:d4 
        media: autoselect
        status: active
# bridge100 has IP 192.168.64.1 assigned
# vmenet0 and vmenet1 are members
bridge100: flags=8a63<UP,BROADCAST,SMART,RUNNING,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
        options=3<RXCSUM,TXCSUM>
        ether be:d0:74:61:f6:64 
        inet 192.168.64.1 netmask 0xffffff00 broadcast 192.168.64.255
        ...
        Configuration:
        ...
        member: vmenet0 flags=3<LEARNING,DISCOVER>
                ifmaxaddr 0 port 29 priority 0 path cost 0
        member: vmenet1 flags=3<LEARNING,DISCOVER>
                ifmaxaddr 0 port 31 priority 0 path cost 0
        ...
        status: active
vmenet1: flags=8b63<UP,BROADCAST,SMART,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
        ether b6:69:a5:54:74:45 
        media: autoselect
        status: active
<!-- Contents of /etc/bootpd.plist after creating VMs 
    dhcp_domain_name_server is same IP as bridge100-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Subnets</key>
        <array>
                <dict>
                        <key>_creator</key>
                        <string>com.apple.NetworkSharing</string>
                        <key>allocate</key>
                        <true/>
                        <key>dhcp_domain_name_server</key>
                        <array>
                                <string>192.168.64.1</string>
                        </array>
                        <key>dhcp_router</key>
                        <string>192.168.64.1</string>
                        <key>interface</key>
                        <string>bridge100</string>
                        <key>lease_max</key>
                        <integer>86400</integer>
                        <key>lease_min</key>
                        <integer>86400</integer>
                        <key>name</key>
                        <string>192.168.64/24</string>
                        <key>net_address</key>
                        <string>192.168.64.0</string>
                        <key>net_mask</key>
                        <string>255.255.255.0</string>
                        <key>net_range</key>
                        <array>
                                <string>192.168.64.2</string>
                                <string>192.168.64.254</string>
                        </array>
                </dict>
        </array>
...

On the guest Linux VMs:

# IP config of first VM - some output omitted

# enp1s0 is on the QEMU SLIRP network and has access to host + internet
# eth1 is attached to bridge100 and has IP 192.160.64.2 assigned via DHCP - has access via bridge to other VMs we create
# eth1 MAC address matches that defined by 'virt-install'
[root@localhost ~] ip a s
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:d1:d1:8d brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute enp1s0
       valid_lft 84794sec preferred_lft 84794sec
    ...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 54:54:00:55:54:51 brd ff:ff:ff:ff:ff:ff
    inet 192.168.64.2/24 brd 192.168.64.255 scope global dynamic noprefixroute eth1
       valid_lft 84794sec preferred_lft 84794sec
    ...
# IP config of second VM - some output omitted

# enp1s0 has same IP as VM1 as the SLIRP network for each VM is independent so it isn't clashing
# eth1 has IP 192.168.64.3 assigned
[root@localhost ~] ip a s
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:ae:7e:5c brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute enp1s0
       valid_lft 85064sec preferred_lft 85064sec
    ...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 54:54:00:55:54:52 brd ff:ff:ff:ff:ff:ff
    inet 192.168.64.3/24 brd 192.168.64.255 scope global dynamic noprefixroute eth1
       valid_lft 85064sec preferred_lft 85064sec
    ...
# Routing tables used by both VMs
[root@localhost ~] ip route
default via 10.0.2.2 dev enp1s0 proto dhcp metric 100 
default via 192.168.64.1 dev eth1 proto dhcp metric 101 
10.0.2.0/24 dev enp1s0 proto kernel scope link src 10.0.2.15 metric 100 
192.168.64.0/24 dev eth1 proto kernel scope link src <host_specific_IP> metric 101

Each VM can now ping the other VMs that share the same bridge (all started with the same vmnet parameter). Each VM can also make outbound internet connections via the SLIRP network.

If you pass --network none to virt-install then you will not have the enp1s0 device attached within your VM and it will have no internet access, but it will still be able to access the other VMs using eth1


Result

With everything configured as above the setup allows the following:

Access VM from Host

# Run from Apple host
user@apple-host$ ping 192.168.64.2
PING 192.168.64.2 (192.168.64.2): 56 data bytes
64 bytes from 192.168.64.2: icmp_seq=0 ttl=64 time=1.713 ms

--- 192.168.64.2 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.713/1.713/1.713/0.000 ms

Access VM from VM

# Run from VM1 with IP 192.168.64.2
[root@localhost ~] ping 192.168.64.3
PING 192.168.64.3 (192.168.64.3) 56(84) bytes of data.
64 bytes from 192.168.64.3: icmp_seq=1 ttl=64 time=2.34 ms

--- 192.168.64.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.342/2.342/2.342/0.000 ms

Access Host from VM

# Run from VM1
[root@localhost ~] ping 10.0.2.2
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.
64 bytes from 10.0.2.2: icmp_seq=1 ttl=255 time=0.868 ms

--- 10.0.2.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.868/0.868/0.868/0.000 ms

Fixes

Some errors I encountered along the way but not sure if they would be consistent for everyone

1 - Add default URI for libvirt connections

When running virt-install

Error:

error: failed to connect to the hypervisor
error: Operation not supported: Cannot use direct socket mode if no URI is set

Fix:

echo 'uri = qemu:///system' >> /opt/homebrew/etc/libvirt/libvirt.conf

brew services restart libvirt

This provides the default URI to connections to QEMU system instances

2 - Manually start virtlogd

When starting libvirt - the expectation was that libvirt would manage virtlogd, which is used to manage logs from VMs as an alternative to writing them all to a file which need manual disk management.

Error:

error: failed to connect to the hypervisor
error: Failed to connect socket to '/opt/homebrew/var/run/libvirt/virtlogd-sock': No such file or directory

Fix:

sudo /opt/homebrew/sbin/virtlogd -d

This will start virlodg as a daemon process manually

3 - Hanging when running virt-install

I have seen some inconsistent behaviour when running virt-install which means the command hangs. I have had to send 'Ctrl + C' - wait for the process to exit (which can take up to a few minutes) then re-run the same command a second time and it works without issue.

Trying to run the same in a new terminal resulted in it hanging again, so running twice in the same session was what worked for me.

Follow On

Now that this is working, my next steps to make it more usable are:

  • Automate the OS installer, or see if disk images can be used
  • Configure domains via XML template
  • Wrap it with Vagrant to provision everything in one go
@amkgi
Copy link

amkgi commented Nov 22, 2022

Great, I knew about qemucommandline, but for some reason didn't think to use it before and kept looking for a way to use libvirt with virtual networks on Mac M1. That's a great job. Thank you.

@aw-engineer
Copy link

Thank you for your excellent work and writeup!

@cattyhouse
Copy link

cattyhouse commented Jan 24, 2024

my 2 cents:

  • if you have vmnet-shared, you don't need --network user, because vmnet-shared alone will be able to do the 3. and 4. jobs for you. (see below log)

  • also to use vmnet-shared, you need sudo, but --network user does not need sudo.

  • ip a ; printf '\n\n' ; curl -IL google.com

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: enp0s1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    inet 192.168.64.25/24 metric 1024 brd 192.168.64.255 scope global dynamic enp0s1
       valid_lft 86201sec preferred_lft 86201sec
    inet6 fdc4:9929:e440:2fcd:5054:ff:fe12:3456/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 2591935sec preferred_lft 604735sec
    inet6 fe80::5054:ff:fe12:3456/64 scope link
       valid_lft forever preferred_lft forever

HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-mBJ0m0Q8WK-CtiFJG9tPuQ' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
Date: Wed, 24 Jan 2024 03:25:09 GMT
Expires: Fri, 23 Feb 2024 03:25:09 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN

HTTP/1.1 200 OK
Content-Type: text/html; charset=ISO-8859-1
Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-dU-nYl7I475rebqVkYeygA' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Date: Wed, 24 Jan 2024 03:25:09 GMT
Server: gws
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Transfer-Encoding: chunked
Expires: Wed, 24 Jan 2024 03:25:09 GMT
Cache-Control: private
Set-Cookie: 1P_JAR=2024-01-24-03; expires=Fri, 23-Feb-2024 03:25:09 GMT; path=/; domain=.google.com; Secure
Set-Cookie: AEC=Ae3NU9Oe1hK9p83G4l_DOQV3VYlGvPiiqrfJC4igmZT0y1E-93nn88FfAi8; expires=Mon, 22-Jul-2024 03:25:09 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
Set-Cookie: NID=511=oaPRFBDhekNpq9NJ7Jx_BzYfg9Z6ftlMWNHLzgVglTY0i05L-WHTPUaO3Zxc4zjpy5cDSWoo3LDWHlQI2fV4-KIUoqWow7PF1NA5ODRAcLUiKrAPcN3TkLOFPi6RJbwf1Foo_MdWpOE6mwH99CF0D4JJShQ69WGaN4z3hd6iZDc; expires=Thu, 25-Jul-2024 03:25:09 GMT; path=/; domain=.google.com; HttpOnly

question

  • have you tried to connect to wireguard from host to vm when using vmnet-shared? i can't make it work, vmnet-bridged works though.

@4WvgqJu
Copy link

4WvgqJu commented Aug 23, 2024

It's working for me, with some issues.

MacOS Sonomia, M2

sudo brew services start libvirt

sudo brew services                         
Password:
Name    Status     User File
black   none            
dbus    none            
dnsmasq started    root /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
libvirt started    root /Library/LaunchDaemons/homebrew.mxcl.libvirt.plist
podman  none            
unbound error  256 root /Library/LaunchDaemons/homebrew.mxcl.unbound.plist
sudo lsof -U -a
COMMAND     PID                  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
libvirtd  28224                  root    8u  unix 0xaec205cd574793a1      0t0      /opt/local/var/run/libvirt/libvirt-sock
libvirtd  28224                  root    9u  unix 0x21a53450510a0838      0t0      /opt/local/var/run/libvirt/libvirt-sock-ro
libvirtd  28224                  root   10u  unix 0x2309e5107ed54d44      0t0      /opt/local/var/run/libvirt/libvirt-admin-sock
ifconfig                                                                                
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
	inet 127.0.0.1 netmask 0xff000000
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	nd6 options=201<PERFORMNUD,DAD>
...
vmenet0: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
	options=60<TSO4,TSO6>
	ether e2:20:b0:c7:ec:d3
	media: autoselect
	status: active
bridge100: flags=8a63<UP,BROADCAST,SMART,RUNNING,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
	options=63<RXCSUM,TXCSUM,TSO4,TSO6>
	ether a6:cf:99:65:02:64
	inet 192.168.66.1 netmask 0xffffff00 broadcast 192.168.66.255
	inet6 fe80::a4cf:99ff:fe65:264%bridge100 prefixlen 64 scopeid 0x17 
	inet6 fd4b:7038:8a5d:66e0:1cf2:6a41:71a:d09c prefixlen 64 autoconf secured 
	Configuration:
		id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
		maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
		root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
		ipfilter disabled flags 0x0
	member: vmenet0 flags=10803<LEARNING,DISCOVER,PRIVATE,CSUM>
	        ifmaxaddr 0 port 22 priority 0 path cost 0
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active
...
#!/bin/sh

sudo virt-install \
--name host1 \
--memory 2048 \
--vcpus 2 \
--disk size=30 \
--cdrom /Users/fm/coreos/fedora-coreos-40.20240728.3.0-live.aarch64.iso \
--os-variant fedora40 \
--virt-type hvf \
--qemu-commandline='-M highmem=off -netdev vmnet-shared,id=vmenet0 -device virtio-net-device,netdev=vmenet0,mac=54:54:00:55:54:51' \
--network user

ERROR Socket-Erstellung zu '/opt/homebrew/var/run/libvirt/virtqemud-sock' fehlgeschlagen: No such file or directory

Next test with some changes.

sudo brew services stop libvirt

sudo /opt/homebrew/sbin/libvirt --daemon 
sudo /opt/homebrew/sbin/virtlogd --daemon
sudo /opt/homebrew/sbin/virtqemud --daemon
sudo /opt/homebrew/sbin/virtstoraged --daemon
sudo /opt/homebrew/sbin/virtnetworkd --daemon
sudo /opt/homebrew/sbin/virtlockd --daemon
sudo /opt/homebrew/sbin/virtsecretd --daemon
virtlogd  31918                  root    6u  unix 0x333e0bff8192a182      0t0      /opt/homebrew/var/run/libvirt/virtlogd-sock
virtlogd  31918                  root    7u  unix 0x21a53450510a0838      0t0      /opt/homebrew/var/run/libvirt/virtlogd-admin-sock
virtqemud 31957                  root   10u  unix 0xb651f5306bb0b009      0t0      /opt/homebrew/var/run/libvirt/virtqemud-sock
virtqemud 31957                  root   11u  unix 0x25945f338b49eb64      0t0      /opt/homebrew/var/run/libvirt/virtqemud-sock-ro
virtqemud 31957                  root   12u  unix 0x3a92fad2f9a617cb      0t0      /opt/homebrew/var/run/libvirt/virtqemud-admin-sock
virtstora 32054                  root   10u  unix 0xeeb29605dc5d1d9e      0t0      /opt/homebrew/var/run/libvirt/virtstoraged-sock
virtstora 32054                  root   11u  unix 0x281d6bc48cb78e13      0t0      /opt/homebrew/var/run/libvirt/virtstoraged-sock-ro
virtstora 32054                  root   12u  unix 0x2309e5107ed54d44      0t0      /opt/homebrew/var/run/libvirt/virtstoraged-admin-sock
virtnetwo 32658                  root   10u  unix 0x5edc1acdba994dc2      0t0      /opt/homebrew/var/run/libvirt/virtnetworkd-sock
virtnetwo 32658                  root   11u  unix 0x5037db93d62290ac      0t0      /opt/homebrew/var/run/libvirt/virtnetworkd-sock-ro
virtnetwo 32658                  root   12u  unix 0xaec205cd574793a1      0t0      /opt/homebrew/var/run/libvirt/virtnetworkd-admin-sock
virtlockd 33333                  root    6u  unix 0x47aec5a1859cc04f      0t0      /opt/homebrew/var/run/libvirt/virtlockd-sock
virtlockd 33333                  root    7u  unix 0x99bff4d6b31a4e53      0t0      /opt/homebrew/var/run/libvirt/virtlockd-admin-sock
virtproxy 33349                  root   10u  unix 0xa12eaf8fbbe7ea26      0t0      /opt/homebrew/var/run/libvirt/libvirt-sock
virtproxy 33349                  root   11u  unix 0x943eb596c924eadf      0t0      /opt/homebrew/var/run/libvirt/libvirt-sock-ro
virtproxy 33349                  root   12u  unix 0x18470ae6c7faa64f      0t0      /opt/homebrew/var/run/libvirt/libvirt-admin-sock
virtsecre 33356                  root   10u  unix 0xba4fe408d487c97e      0t0      /opt/homebrew/var/run/libvirt/virtsecretd-sock
virtsecre 33356                  root   11u  unix 0x66aa658c0a30d188      0t0      /opt/homebrew/var/run/libvirt/virtsecretd-sock-ro
virtsecre 33356                  root   12u  unix 0xc1719473987b5d7d      0t0      /opt/homebrew/var/run/libvirt/virtsecretd-admin-sock
[core@localhost ~]$ ifconfig
enp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fec0::9470:9f16:3d3f:a539  prefixlen 64  scopeid 0x40<site>
        inet6 fe80::a570:3483:2933:dd2f  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:1f:da:d4  txqueuelen 1000  (Ethernet)
        RX packets 22  bytes 3349 (3.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 39  bytes 3666 (3.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.67.2  netmask 255.255.255.0  broadcast 192.168.67.255
        inet6 fe80::5d23:af1d:5d1a:dbfd  prefixlen 64  scopeid 0x20<link>
        inet6 fd93:7e7f:b7a1:2765:32e:14ec:1158:9e9  prefixlen 64  scopeid 0x0<global>
        ether 54:54:00:55:54:51  txqueuelen 1000  (Ethernet)
        RX packets 65  bytes 27070 (26.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 31  bytes 3022 (2.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

sudo virt-manager --connect "qemu:///system?socket=/opt/homebrew/var/run/libvirt/virtqemud-sock" --no-fork

ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
	inet 127.0.0.1 netmask 0xff000000
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	nd6 options=201<PERFORMNUD,DAD>
...
vmenet1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
	ether 96:3f:6c:8b:00:a8
	media: autoselect
	status: active
bridge101: flags=8a63<UP,BROADCAST,SMART,RUNNING,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
	options=3<RXCSUM,TXCSUM>
	ether a6:cf:99:65:02:65
	inet 192.168.67.1 netmask 0xffffff00 broadcast 192.168.67.255
	inet6 fe80::a4cf:99ff:fe65:265%bridge101 prefixlen 64 scopeid 0x1c 
	inet6 fd93:7e7f:b7a1:2765:1c13:e0fb:7ea5:4c18 prefixlen 64 autoconf secured 
	Configuration:
		id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
		maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
		root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
		ipfilter disabled flags 0x0
	member: vmenet1 flags=3<LEARNING,DISCOVER>
	        ifmaxaddr 0 port 27 priority 0 path cost 0
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active
[core@localhost ~]$ ping 192.168.67.1
PING 192.168.67.1 (192.168.67.1) 56(84) bytes of data.


--- 192.168.67.1 ping statistics ---
66 packets transmitted, 0 received, 100% packet loss, time 66585ms

[core@localhost ~]$ ping 192.168.66.1
PING 192.168.66.1 (192.168.66.1) 56(84) bytes of data.
64 bytes from 192.168.66.1: icmp_seq=1 ttl=255 time=0.553 ms
64 bytes from 192.168.66.1: icmp_seq=2 ttl=255 time=1.17 ms
64 bytes from 192.168.66.1: icmp_seq=3 ttl=255 time=1.11 ms
64 bytes from 192.168.66.1: icmp_seq=4 ttl=255 time=1.24 ms
64 bytes from 192.168.66.1: icmp_seq=5 ttl=255 time=1.16 ms
64 bytes from 192.168.66.1: icmp_seq=6 ttl=255 time=1.06 ms
64 bytes from 192.168.66.1: icmp_seq=7 ttl=255 time=0.959 ms
64 bytes from 192.168.66.1: icmp_seq=8 ttl=255 time=0.881 ms
64 bytes from 192.168.66.1: icmp_seq=9 ttl=255 time=1.12 ms

--- 192.168.66.1 ping statistics ---
9 packets transmitted, 9 received, 0% packet loss, time 8034ms
rtt min/avg/max/mdev = 0.553/1.028/1.237/0.197 ms
[core@localhost ~]$ ping google.com
PING google.com (142.250.185.142) 56(84) bytes of data.
64 bytes from fra16s50-in-f14.1e100.net (142.250.185.142): icmp_seq=1 ttl=255 time=39.9 ms
64 bytes from fra16s50-in-f14.1e100.net (142.250.185.142): icmp_seq=2 ttl=255 time=38.6 ms
64 bytes from fra16s50-in-f14.1e100.net (142.250.185.142): icmp_seq=3 ttl=255 time=45.1 ms
64 bytes from fra16s50-in-f14.1e100.net (142.250.185.142): icmp_seq=4 ttl=255 time=40.4 ms
64 bytes from fra16s50-in-f14.1e100.net (142.250.185.142): icmp_seq=5 ttl=255 time=39.4 ms
64 bytes from fra16s50-in-f14.1e100.net (142.250.185.142): icmp_seq=6 ttl=255 time=45.8 ms
64 bytes from fra16s50-in-f14.1e100.net (142.250.185.142): icmp_seq=7 ttl=255 time=31.6 ms
64 bytes from fra16s50-in-f14.1e100.net (142.250.185.142): icmp_seq=8 ttl=255 time=44.4 ms
64 bytes from fra16s50-in-f14.1e100.net (142.250.185.142): icmp_seq=9 ttl=255 time=66.1 ms

--- google.com ping statistics ---
9 packets transmitted, 9 received, 0% packet loss, time 8027ms
rtt min/avg/max/mdev = 31.584/43.475/66.050/8.959 ms
ping 192.168.66.2
PING 192.168.66.2 (192.168.66.2): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
ping: sendto: No route to host
Request timeout for icmp_seq 4
^C
--- 192.168.66.2 ping statistics ---
6 packets transmitted, 0 packets received, 100.0% packet loss

ping 192.168.67.2
PING 192.168.67.2 (192.168.67.2): 56 data bytes
64 bytes from 192.168.67.2: icmp_seq=0 ttl=64 time=1.741 ms
64 bytes from 192.168.67.2: icmp_seq=1 ttl=64 time=1.036 ms
64 bytes from 192.168.67.2: icmp_seq=2 ttl=64 time=1.280 ms
64 bytes from 192.168.67.2: icmp_seq=3 ttl=64 time=1.165 ms
64 bytes from 192.168.67.2: icmp_seq=4 ttl=64 time=1.023 ms
64 bytes from 192.168.67.2: icmp_seq=5 ttl=64 time=1.245 ms
64 bytes from 192.168.67.2: icmp_seq=6 ttl=64 time=1.512 ms
64 bytes from 192.168.67.2: icmp_seq=7 ttl=64 time=1.331 ms
^C
--- 192.168.67.2 ping statistics ---
8 packets transmitted, 8 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.023/1.292/1.741/0.226 ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment