2024年6月10日发(作者:)

虚拟机网卡和linux bridge上tap设备的关系

1. 虚拟机进程

使用ps –ef |grep kvm可以看到虚拟机进程信息如下:

/usr/libexec/qemu-kvm -name instance-0000001d -S -machine pc-i440fx-rhel7.1.0,accel=kvm,usb=off -cpu

Broadwell,+abm,+pdpe1gb,+hypervisor,+rdrand,+f16c,+osxsave,+vmx,+ss,+ds,+vme -m 64 -realtime mlock=off -smp

1,sockets=1,cores=1,threads=1 -uuid 687fd29c-13c2-433b-941c-2414da556bdb -smbios type=1,manufacturer=Fedora

Project,product=OpenStack Nova,version=7,serial=a373d218-fea2-4c1c-b255-26714654fdbe,uuid=687fd29c-

13c2-433b-941c-2414da556bdb,family=Virtual Machine -no-user-config -nodefaults -chardev

-mon

-global

-device

kvm-

ich9-usb-

ich9-usb-

-device

-device

-device

ich9-usb-

ich9-usb-

socket,id=charmonitor,path=/var/lib/libvirt/qemu/r,server,nowait

chardev=charmonitor,id=monitor,mode=control

_tick_policy=discard -no-hpet

-rtc

-no-shutdown

base=utc,driftfix=slew

-boot

-device

strict=on

ehci1,id=usb,bus=pci.0,addr=0x5.0x7

uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5

uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1

uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x5.0x2

serial0,bus=pci.0,addr=0x6 -drive

virtio-serial-pci,id=virtio-

file=rbd:vms/687fd29c-13c2-433b-941c-

2414da556bdb_disk:id=cinder:key=AQBqCA9X18xZOxAAWVDkhAOsKZIQY6oAf9cjlg==:auth_supported=cephx;none:mon_host=1

92.168.44.130:6789,if=none,id=drive-virtio-disk0,format=raw,cache=none -device virtio-blk-

-drive pci,scsi=off,bus=pci.0,addr=0x7,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1

file=rbd:vms/687fd29c-13c2-433b-941c-

2414da556bdb_:id=cinder:key=AQBqCA9X18xZOxAAWVDkhAOsKZIQY6oAf9cjlg==:auth_supported=cephx;none:mon

_host=192.168.44.130:6789,if=none,id=drive-ide0-1-1,readonly=on,format=raw,cache=none -device ide-

cd,bus=ide.1,unit=1,drive=drive-ide0-1-1,id=ide0-1-1 -netdev tap,fd=25,id=hostnet0,vhost=on,vhostfd=26 -device

virtio-net-pci,netdev=hostnet0,id=net0,mac=fa:16:3e:36:c0:a7,bus=pci.0,addr=0x3 -chardev

file,id=charserial0,path=/var/lib/nova/instances/687fd29c-13c2-433b-941c-2414da556bdb/ -device isa-

serial,chardev=charserial0,id=serial0

serial,chardev=charserial1,id=serial1

-chardev

-chardev

pty,id=charserial1 -device isa-

-device

-chardev

spicevmc,id=charchannel0,name=vdagent

virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=.0

socket,id=charchannel1,path=/var/lib/libvirt/qemu/_,server,nowait

-device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=_agent.0 -

device usb-tablet,id=input0 -vnc 0.0.0.0:0 -k en-us -spice port=5901,addr=0.0.0.0,disable-ticketing,disable-

copy-paste,disable-agent-file-xfer,seamless-migration=on -k en-us -device qxl-

-device vga,id=video0,ram_size=67108864,vram_size=67108864,vgamem_mb=16,bus=pci.0,addr=0x2

AC97,id=sound0,bus=pci.0,addr=0x4 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 -msg timestamp=on

关注其中的网卡配置参数:

• 从HOST角度:-netdev tap,fd=25,id=hostnet0,vhost=on,vhostfd=26

• 从GUEST角度:

-device virtio-net-pci,netdev=hostnet0,id=net0,mac=fa:16:3e:36:c0:a7,bus=pci.0,addr=0x3

可以看到,host上使用tap类型的网卡,开启了vhost-net技术。

vhost-net技术是在半虚拟化技术virtio上提出的,而virtio则是基于全虚拟化技术而言的。

所以在了解vhost-net技术之前,需要先了解一下tun/tap工作原理、全虚拟化技术、virtio

技术。

2. Tap/Tun 工作原理

TUN/TAP虚拟网络设备的原理比较简单,他在Linux内核中添加了一个TUN/TAP虚拟网

络设备的驱动程序和一个与之相关连的字符设备/dev/net/tun,字符设备tun作为用户空间

和内核空间交换数据的接口。用户空间的应用程序可以通过这个设备文件来和内核中的驱动

程序进行交互,其操作方式和普通的文件操作无异。当内核将数据包发送到虚拟网络设备时,

数据包被保存在设备相关的一个队列中,直到用户空间程序通过打开的字符设备tun的描述

符读取时,它才会被拷贝到用户空间的缓冲区中,其效果就相当于,数据包直接发送到了用

户空间。通过系统调用write发送数据包时其原理与此类似。

从结构上来说,Tun/tap驱动并不单纯是实现网卡驱动,同时它还实现了字符设备驱动

部分。以字符设备的方式连接用户态和核心态。下面是示意图:

Tun/tap 驱动程序中包含两个部分,一部分是字符设备驱动,还有一部分是网卡驱动

部分。利用网卡驱动部分接收来自TCP/IP协议栈的网络分包并发送或者反过来将接收到的

网络分包传给协议栈处理,而字符驱动部分则将网络分包在内核与用户态之间传送,模拟

物理链路的数据接收和发送。Tun/tap驱动很好的实现了两种驱动的结合。

3. Tap/Tun Device在libvirt中的应用

• 将guest system的网络和host system的网络连在一起。

• 通过TUN/TAP adapter,会生成一个在host system上的虚拟网卡tap

• tun建立了point to point的网络设备,使得guest system的网卡和tap虚拟网卡成为