1. 前言
本文主要介绍qemu下与宿主机网络通信的环境搭建步骤。其中宿主机为ubuntu18.04,目标机为qemu 5.0,运行kernel 5.10。本文主要整合了参考文档中几篇文章的内容。
主要步骤包括:
- 配置宿主机
- 配置qemu内核支持网卡
- 配置qemu创建前端和后端
- 配置qemu的IP
2. 配置宿主机
我们采用的是桥接的方式来连接宿主机与qemu的网卡。
首先我们通过如下的方式在宿主机端创建网桥:
#!/bin/sh
#sudo ifconfig eth0 down # 首先关闭宿主机网卡接口
sudo brctl addbr br0 # 添加一座名为 br0 的网桥
sudo brctl addif br0 eth0 # 在 br0 中添加一个接口
sudo brctl stp br0 off # 如果只有一个网桥,则关闭生成树协议
sudo brctl setfd br0 1 # 设置 br0 的转发延迟
sudo brctl sethello br0 1 # 设置 br0 的 hello 时间
sudo ifconfig br0 0.0.0.0 promisc up # 启用 br0 接口
sudo ifconfig eth0 0.0.0.0 promisc up # 启用网卡接口
sudo dhclient br0 # 从 dhcp 服务器获得 br0 的 IP 地址
sudo brctl show br0 # 查看虚拟网桥列表
sudo brctl showstp br0 # 查看 br0 的各接口信息
此时网桥已经得到了 IP,并且宿主机能够连接网络的网卡 eth0 也加入了网桥
运行如下的脚本,创建一个 TAP 设备,作为 QEMU 一端的接口:
#!/bin/sh
sudo tunctl -t tap0 -u root # 创建一个 tap0 接口,只允许 root 用户访问
sudo brctl addif br0 tap0 # 在虚拟网桥中增加一个 tap0 接口
sudo ifconfig tap0 0.0.0.0 promisc up # 启用 tap0 接口
sudo brctl showstp br0
此时宿主机的一端网卡与qemu一端的网卡都连入了网桥。
这里简要说明一下,qemu主要支持4种网络通信方式,其中我们采用的是TAP/bridge的通信方式,TAP 属于 LInux 内核支持的一种虚拟化网络设备,它完全由软件模拟实现,TAP 工作在数据链路层,常用于网络桥接。
经过如上,在宿主机产生的效果如下:
ubuntu@VM-0-9-ubuntu:~$ ifconfig
br0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST> mtu 1500
inet 172.17.0.9 netmask 255.255.240.0 broadcast 172.17.15.255
inet6 fe80::5054:ff:fec6:1dac prefixlen 64 scopeid 0x20<link>
ether 52:54:00:c6:1d:ac txqueuelen 1000 (Ethernet)
RX packets 97163 bytes 8327257 (8.3 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 100929 bytes 17786837 (17.7 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST> mtu 1500
inet6 fe80::5054:ff:fec6:1dac prefixlen 64 scopeid 0x20<link>
ether 52:54:00:c6:1d:ac txqueuelen 1000 (Ethernet)
RX packets 102458 bytes 13522649 (13.5 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 103875 bytes 18965827 (18.9 MB)
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 3871 bytes 328826 (328.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3871 bytes 328826 (328.8 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
tap0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::84d9:66ff:fe1b:ddb6 prefixlen 64 scopeid 0x20<link>
ether 86:d9:66:1b:dd:b6 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 13 bytes 966 (966.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
3. 配置目标机内核支持网卡
通过如下命令可以查看qemu支持的网卡:
ubuntu@VM-0-9-ubuntu$ qemu-system-aarch64 -M virt -nic model=help
Supported NIC models:
e1000
e1000-82544gc
e1000-82545em
e1000e
i82550
i82551
i82557a
i82557b
i82557c
i82558a
i82558b
i82559a
i82559b
i82559c
i82559er
i82562
i82801
ne2k_pci
pcnet
rocker
rtl8139
tulip
virtio-net-pci
virtio-net-pci-non-transitional
virtio-net-pci-transitional
vmxnet3
qemu默认支持的是e1000网卡,内核中需要开启如下的配置项来支持e1000:
Device Drivers --->
[*] Network device support --->
[*] Ethernet driver support --->
[*] Intel devices
<*> Intel(R) PRO/1000 Gigabit Ethernet support
这样会开启 CONFIG_E1000=y配置项
4. 为qemu创建前端和后端
QEMU的网络接口分成下面两部分:
- guest看到的仿真硬件,也叫作NIC。常见的有e1000 网卡,rt8139网卡,和virtio-net设备。这些统称为网络前端。
- host上的网卡后端。QEMU用来跟host上外部网络交换数据的东西。最常见的后端是“user”,用来提供NAT的主机网络访问。tap后端,可以让guest直接访问主机的网络。还有socket类型的后端,用来连接多个QEMU实例,来仿真一个共享网络。
参考QEMU新的-nic选项文章,-nic选项用非常简单的方式,非常简单的配置了qemu网络的前端和后端。只需要在qemu的启动参数中加入如下即可:
-nic tap,model=e1000
我的qemu参数配置如下:
#!/bin/bash
IMAGE_PATH=~/qemu/kernel/linux/arch/arm64/boot
ROOTFS_PATH=~/qemu/rootfs/linux_rootfs
ROOTFS=rootfs.ext4
./qemu \
-smp 2 \
-M virt \
-m 1024 \
-cpu cortex-a57 \
-kernel $IMAGE_PATH/Image \
-append 'root=/dev/vda rw console=ttyAMA0 cma=48M' \
-drive if=none,file=$ROOTFS_PATH/$ROOTFS,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-nographic \
-nic tap,model=e1000 \
$1 $2
5. 配置qemu的IP
在启动脚本rcS中加入如下内容:
ifconfig eth0 172.17.0.2 netmask 255.255.240.0
效果如下:
/ # ifconfig -a
eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56
inet addr:172.17.0.2 Bcast:172.17.15.255 Mask:255.255.240.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:60 (60.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
LOOPBACK MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
6. 实验
在qemu中ping宿主机:
/ # ping 172.17.0.9
PING 172.17.0.9 (172.17.0.9): 56 data bytes
64 bytes from 172.17.0.9: seq=0 ttl=64 time=16.348 ms
64 bytes from 172.17.0.9: seq=1 ttl=64 time=1.905 ms
64 bytes from 172.17.0.9: seq=2 ttl=64 time=1.090 ms
64 bytes from 172.17.0.9: seq=3 ttl=64 time=0.980 ms
64 bytes from 172.17.0.9: seq=4 ttl=64 time=0.978 ms
可惜ping www.baidu.com不行:<
参考文档
QEMU 网络配置
QEMU新的-nic选项
QEMU’s new -nic command line option
https://www.it610.com/article/1281227601326653440.htm