TAP interface for QEMU

593 views
Skip to first unread message

Pierre-Luc Bertrand

unread,
Sep 17, 2022, 11:35:52 PM9/17/22
to tunnelblick-discuss
Hi,

I'm on Apple M1 Monterey and I believe I've managed to get the kext working from:

plb@Pierre-Luc-MBP ~ % kextstat | grep -v com.apple                                                      
Executing: /usr/bin/kmutil showloaded
No variant specified, falling back to release
Index Refs Address            Size       Wired      Name (Version) UUID <Linked Against>
  247    0 0xfffffe0006f10920 0x4000     0x4000     net.tunnelblick.tun (5.0) 5845BB14-660C-34B4-879F-D4D6277EBE4A <7 5 4 1>
  249    0 0xfffffe0006f10000 0x4000     0x4000     net.tunnelblick.tap (5.0) 2F65AD5B-B8BE-371D-84E9-8194AAB4E815 <7 5 4 1>

I do see the tap devices:

plb@Pierre-Luc-MBP ~ % ll /dev/tap*
crw-rw----  1 root  wheel  0x27000000 Sep 17 01:43 /dev/tap0
crw-rw----  1 root  wheel  0x27000001 Sep 17 01:43 /dev/tap1
crw-rw----  1 root  wheel  0x2700000a Sep 17 01:43 /dev/tap10
crw-rw----  1 root  wheel  0x2700000b Sep 17 01:43 /dev/tap11
crw-rw----  1 root  wheel  0x2700000c Sep 17 01:43 /dev/tap12
crw-rw----  1 root  wheel  0x2700000d Sep 17 01:43 /dev/tap13
crw-rw----  1 root  wheel  0x2700000e Sep 17 01:43 /dev/tap14
crw-rw----  1 root  wheel  0x2700000f Sep 17 01:43 /dev/tap15
crw-rw----  1 root  wheel  0x27000002 Sep 17 01:43 /dev/tap2
crw-rw----  1 root  wheel  0x27000003 Sep 17 01:43 /dev/tap3
crw-rw----  1 root  wheel  0x27000004 Sep 17 01:43 /dev/tap4
crw-rw----  1 root  wheel  0x27000005 Sep 17 01:43 /dev/tap5
crw-rw----  1 root  wheel  0x27000006 Sep 17 01:43 /dev/tap6
crw-rw----  1 root  wheel  0x27000007 Sep 17 01:43 /dev/tap7
crw-rw----  1 root  wheel  0x27000008 Sep 17 01:43 /dev/tap8
crw-rw----  1 root  wheel  0x27000009 Sep 17 01:43 /dev/tap9

What I'd like to do and I'm not sure it makes sense as I don't really understand what TAP does really but I'd like to create tap0, which would list when I do ifconfig such that I can use it for QEMU guest to access my local network. Is there an explicit way to load a TAP interface or it makes no sense? I read somewhere that the interface would show up if a process was reading from /dev/tapX but I don't know how to make one of the linux module to read from that device to create the interface.

Thanks in advance for your help,

Pierre-Luc

Sandor Patocs

unread,
Nov 30, 2022, 4:22:37 PM11/30/22
to tunnelblick-discuss
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
-----------------

Sandor Patocs

unread,
Nov 30, 2022, 4:42:56 PM11/30/22
to tunnelblick-discuss
I forgot to mention you have to configure bridge1 with the network range you will assign to the host-only network interfaces inside your VM:

ifconfig bridge1 192.168.170.1/24 up

This will use addresses that start with 192.168.170 and network mask of 255.255.255.0.

On Saturday, September 17, 2022 at 8:35:52 PM UTC-7 Pierre-Luc Bertrand wrote:
Reply all
Reply to author
Forward
0 new messages