If you already loaded the extension, you will need to update the tap device permissions so that a non-root user can access them:
$ sudo chmod 666 /dev/tap?
You will need to add a bridge interface called "bridge1". You do this in "System Preferences | Network" by clicking the "+" button.
Then use qemu, which will use a tap device to support host-only networking:
/opt/homebrew/bin/qemu-system-x86_64 -machine q35 -accel hvf -accel tcg,thread=multi,tb-size=1024 -cpu max -smp 4 -m 1024 -device e1000,netdev=net0 -netdev user,id=net0,hostfwd=tcp::2212-:22 -drive if=virtio,format=qcow2,file=box.img -device e1000,netdev=net1,mac=52:54:00:12:34:0c -netdev tap,id=net1,script=tap_up.sh,downscript=tap_down.sh
The "net1" network device is what uses the tap device for host-only networking.
The tap_up.sh script:
------------------
TAPDEV="$1"
BRIDGEDEV="$2"
if [ ! -e "/dev/${TAPDEV}" ]; then
# only needs to be run once, after reboot
/Applications/Tunnelblick.app/Contents/Resources/openvpnstart loadKexts 2 2>&1 >>"$0.log"
# give it time to come up and allocate tap devices
echo "Loaded kernel extension for tap devices" >> "$0.log"
sleep 6
sudo chmod 666 /dev/tap?
fi
# sleep for a second so the tap device can come ready (it should be already, but making sure)
sleep 2
# allow user to override via environment
if [ "$BRIDGEDEV" == "" ]; then
BRIDGEDEV="bridge1"
echo "Use default BRIDGEDEV='${BRIDGEDEV}', TAPDEV='${TAPDEV}" >> "$0.log"
else
echo "Already set to BRIDGEDEV='${BRIDGEDEV}', TAPDEV='${TAPDEV}'" >> "$0.log"
fi
#
(sudo ifconfig "${BRIDGEDEV}" addm "${TAPDEV}") 2>&1 >> $0.log
exit 0
-----------
The tap_down.sh script:
---------
TAPDEV="$1"
BRIDGEDEV="$2"
# allow user to override via environment
if [ "$BRIDGEDEV" == "" ]; then
BRIDGEDEV="bridge1"
echo "Use default BRIDGEDEV='$BRIDGEDEV'" >> "$0.log"
else
echo "Already set to BRIDGEDEV='$BRIDGEDEV'" >> "$0.log"
fi
#
(sudo ifconfig $BRIDGEDEV deletem $TAPDEV) 2>&1 >> "$0.log"
exit 0
-----------------