QEMU 无法在 Windows 10 主机中打开 Tap 设备

QEMU Cannot Open Tap Device in Windows 10 Host

我正在尝试将我的 QEMU VM 桥接到我的 Windows 10 主机中的本地适配器,但 QEMU 抱怨 ifname 选项提供的接口名称到 -netdev 参数无法打开。我遵循了 https://superuser.com/questions/1317652/how-to-set-up-nat-for-qemu-with-tap-backend-windows-10 中的答案,但没有成功。我已经从源代码交叉编译 QEMU 来调试此行为,以确定是否可以检测到接口名称,显然 QEMU 可以找到适配器的名称,但不能找到 TAP 设备文件。为了进一步解释我的观点,这里有一段来自 QEMU 4.2.0 源代码(撰写本文时的最新版本)net/tap-win32.c:595 的代码片段,特别是 tap_win32_open 函数,我将突出显示失败的地方在此函数中(查找 // THIS IS WHERE IT WILL FAIL. 评论):

  1. 正在使用正确的现有网络接口进行测试:
static int tap_win32_open(tap_win32_overlapped_t **phandle,
                          const char *preferred_name)
{
    ...

    rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer));
    if (rc)
        return -1;

    snprintf (device_path, sizeof(device_path), "%s%s%s",
              USERMODEDEVICEDIR,
              device_guid,
              TAPSUFFIX);

    handle = CreateFile (
        device_path,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
        0 );

    if (handle == INVALID_HANDLE_VALUE) {
        return -1; // THIS IS WHERE IT WILL FAIL.
    }

    ...
  1. 使用不正确(不存在)的网络接口进行测试:
static int tap_win32_open(tap_win32_overlapped_t **phandle,
                          const char *preferred_name)
{
    ...

    rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer));
    if (rc)
        return -1; // THIS IS WHERE IT WILL FAIL.

    snprintf (device_path, sizeof(device_path), "%s%s%s",
              USERMODEDEVICEDIR,
              device_guid,
              TAPSUFFIX);

    handle = CreateFile (
        device_path,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
        0 );

    if (handle == INVALID_HANDLE_VALUE) {
        return -1;
    }

    ...

QEMU 使用设备 GUID 的前缀 USERMODEDEVICEDIR,即 \.\Global\ 和后缀 .tap,在 Windows 中创建设备路径。例如,我正在处理的网络适配器在以下设备路径中产生:\.\Global\{990DA322-3986-4854-AE93-1D6FB0BFA137}.tap。知道为什么 CreateFile 总是在设备路径上导致 INVALID_HANDLE_VALUE 吗?顺便说一句,GetLastError() returns 2,其中docs.microsoft.com的意思如下:

...
ERROR_FILE_NOT_FOUND

2 (0x2)

The system cannot find the file specified.
...

对不起。我连接到一个非 TAP 适配器,认为它会从中获取地址,就像 VirtualBox 一样。我之前在 QEMU 中并不完全理解桥接的概念,但现在我应该附加到一个 TAP 适配器,并将该适配器桥接到另一个首选适配器。