qemu与宿主机网络通信配置

1. 前言

本文主要介绍qemu下与宿主机网络通信的环境搭建步骤。其中宿主机为ubuntu18.04,目标机为qemu 5.0,运行kernel 5.10。本文主要整合了参考文档中几篇文章的内容。
主要步骤包括:

  1. 配置宿主机
  2. 配置qemu内核支持网卡
  3. 配置qemu创建前端和后端
  4. 配置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

Guess you like

Origin blog.csdn.net/jasonactions/article/details/118931633