qemu-bridge
在 qemu 中使用桥接网络只需要如下简单配置即可(当然,前提是已经有了可用的桥接口)。
-netdev bridge
-netdev bridge,br=br0,id=net0 \
-device virtio-net-pci,netdev=net0
如果 -netdev
不指定 helper=
参数,则使用默认的 qemu-bridge-helper
程序。
#define DEFAULT_BRIDGE_HELPER CONFIG_QEMU_HELPERDIR "/qemu-bridge-helper"
// qemu/net/tap.c
net_init_bridge
fd = net_bridge_run_helper(helper, br, errp);
helper = default_helper = get_relocated_path(DEFAULT_BRIDGE_HELPER);
net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr);
net_init_tap
if (tap->fd) {
net_init_tap_one(fd)
} else if (tap->fds) {
for (i = 0; i < nfds; i++) {
net_init_tap_one(fd)
}
} else if (tap->helper) {
fd = net_bridge_run_helper
net_init_tap_one(fd)
} else {
fd = net_tap_init(ifname)
net_init_tap_one(fd)
}
net_init_tap_one
net_tap_fd_init
qemu_set_info_str
https://github.com/qemu/qemu/blob/v8.0.2/net/tap.c
从上面的代码可以看到 -netdev bridge
只是 -netdev tap
的简化写法,qemu-bridge-helper
在背后替我们做了 tap 设备创建以及将 tap 设备加入桥接口的所有事情。
qemu-bridge-helper
qemu-bridge-helper
会对 br=
参数进行 acl 检测。
❯ sudo vi /etc/qemu/bridge.conf
allow all
// qemu/qemu-bridge-helper.c
#define DEFAULT_ACL_FILE CONFIG_QEMU_CONFDIR "/bridge.conf"
enum {
ACL_ALLOW = 0,
ACL_ALLOW_ALL,
ACL_DENY,
ACL_DENY_ALL,
};
main
QSIMPLEQ_FOREACH(acl_rule, &acl_list, entry) {
switch (acl_rule->type) {
case ACL_ALLOW_ALL:
access_allowed = 1;
break;
case ACL_ALLOW:
if (strcmp(bridge, acl_rule->iface) == 0) {
access_allowed = 1;
}
break;
case ACL_DENY_ALL:
access_denied = 1;
break;
case ACL_DENY:
if (strcmp(bridge, acl_rule->iface) == 0) {
access_denied = 1;
}
break;
}
}
if ((access_allowed == 0) || (access_denied == 1)) {
fprintf(stderr, "access denied by acl file\n");
ret = EXIT_FAILURE;
goto cleanup;
}
https://github.com/qemu/qemu/blob/v8.0.2/qemu-bridge-helper.c
完整示例
❯ sudo qemu-system-x86_64 -M q35 -cpu host \
-enable-kvm -smp 2 -m 1024 -nodefaults \
-drive if=pflash,format=raw,file=/usr/share/edk2/x64/OVMF.4m.fd \
-device qemu-xhci,bus=pcie.0,addr=1 \
-device usb-kbd -device usb-mouse -device usb-tablet \
-serial mon:stdio \
-chardev socket,id=qmp,path=mon.qmp,server=on,wait=off \
-device virtio-gpu-pci,bus=pcie.0,addr=2 \
-netdev user,id=net0 \
-device virtio-net-pci,bus=pcie.0,addr=3,netdev=net0 \
-netdev bridge,br=docker0,id=net1 \
-device virtio-net-pci,bus=pcie.0,addr=4,netdev=net1 \
-device virtio-scsi-pci,id=scsi0,bus=pcie.0,addr=5 \
-drive if=none,file=ubuntu.qcow2,id=hd1,format=qcow2 \
-device scsi-hd,bus=scsi0.0,drive=hd1,bootindex=1 \
-display gtk
其中 -netdev user
中的 hostfwd
端口映射语法如下:
hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport,hostfwd=,hostfwd=,...
参考资料
Configuring QEMU bridge helper after “access denied by acl file” error https://blog.christophersmart.com/2016/08/31/configuring-qemu-bridge-helper-after-access-denied-by-acl-file-error/
最后修改于 2023-06-17