qemu上跑的代码要操作网卡通信,所以
1.本质上是qemu 模拟了一个虚拟网卡
2.并且该网卡的数据最后要通到 真实网卡
基于这个考虑,目前是这种技术
前端(对应1),负责 接收 qemu上的代码 传递的数据
模拟了什么型号的网卡(Network Interface Card)
我们 用 -net nic,model=xxx 或者 -device xxx 来 选中 qemu 可以模拟的网卡,比如他可以是一张螃蟹卡
-net nic,model=rtl8139
xxx 可以 从 qemu-system-arm -M vexpress-a9 -device help
后端(对应2),负责 把nic(Network Interface Card)的数据包发到宿主机的网络
我们可以用 -net zzz 或者 -netdev zzz 来表示 这种后端技术
zzz 可取 user、tap、bridge、socket、vde 等
而 user 就是 下面说的 "Usermode Networking"
而 bridge 就是下面说的 "Bridged Networking"
配置kvm/qemu的网络有两种方法。
其一,默认方式为用户模式网络(Usermode Networking),数据包由NAT方式通过主机的接口进行传送。
其二,使用桥接方式(Bridged Networking),外部的机器可以直接联通到虚拟机,就像联通到你的主机一样。
该文介绍了三种方法,第一种没走通,以下是第二种在 ubuntu 2204 qemu-system-arm 上的实现
文章中也列举了 1604 的操作
我认为这三种技术分别为 // 好像第一种和第二种是一样的
虚拟网桥 + tap虚拟网卡 , 属于 -net bridge , 效果是 Bridged Networking
虚拟网桥 + tap0 , 属于 -net tap , 效果等同于 前者,Bridged Networking // tap0 和 tap 虚拟网卡有什么区别呢?
tap0 only , 属于 -net tap
0.环境准备(安装驱动和工具包)
1.创建 虚拟网桥
2.创建 tap0 设备
3.绑定 tap0 和 网桥
qemu启动的时候 /etc/qemu-ifup 做的
tap 的名称(ifname的值) 被 传给 /etc/qemu-ifup 当做 $1
4.绑定 虚拟网桥 和 真实网卡(在我这里是enp3s0)
ubuntu2204 采用的是 netplan 管理的网络,用的是 yaml 语法
ubuntu1604, 是 用/etc/network/interfaces 做的
5.重启网络
6.启动qemu-system-arm
7. 数据流流向
qemu 上的跑的代码
|
qemu 仿真的 网卡
|
qemu 进程
|
内核tap0 ------------ 内核bridge ------- 内核真实网卡驱动
|
真实网卡
|
PHY----------------->外界网络
$ modprobe bridge
$ lsmod |grep bridge
bridge 331776 0
stp 16384 1 bridge
llc 16384 2 bridge,stp
sudo apt install -y bridge-utils uml-utilities
sudo brctl addbr virbr0
sudo brctl stp virbr0 on
brctl show
sudo ip tuntap add dev tap0 mode tap
//sudo ip link set tap0 up
/etc/qemu-ifup 原生支持
其实本质上做了下面的事情
ifconfig tap0 up
brctl addif virbr0 tap0
// 注意缩进
// TODO 将 enp3s0 换为你的真实网卡名
// TODO 修改 macaddress
$ cat /etc/netplan/virbr0.yaml
network:
version: 2
renderer: networkd
ethernets:
enp3s0:
dhcp4: false
dhcp6: false
bridges:
virbr0:
macaddress: d8:cb:8a:5c:66:86
dhcp4: no
dhcp6: no
addresses:
- 192.168.1.250/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses:
- 192.168.1.1
interfaces:
- enp3s0
$ cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
# 可以 man 5 interfaces 查看 语法
# Lines beginning with the word "auto" are used to identify the physical interfaces to be brought up when ifup is run with the -a option.
# Stanzas defining logical interfaces start with a line consisting of the word "iface" followed by the name of the logical interface.
# This will be "inet" for TCP/IP networking
# The loopback Method may be used to define the IPv4 loopback interface.
# The dhcp Method may be used to obtain an address via DHCP with any of the tools: dhclient, pump, udhcpc, dhcpcd.
# For compatibility with bridge-utils package, if bridge_ports option is specified, VLAN interface configuration is not performed.
auto lo
iface lo inet loopback
auto enp3s0
auto virbr0
iface virbr0 inet dhcp
bridge_ports enp3s0
sudo systemctl restart NetworkManager.service // 等同于 sudo /etc/init.d/network-manager restart
sudo qemu-system-arm -M vexpress-a9 -m 512M -kernel ../u-boot/u-boot -nographic \
-net nic \
-net tap,ifname=tap0