目录
1. 网卡模拟
参数:
-netdev type=tap,id=eth0,ifname=tap30,script=no,downscript=no -device e1000,netdev=eth0,mac=12:03:04:05:06:08
或
-net nic,model=e1000,netdev=eth0 -netdev tap,ifname=tap30,script=no,downscript=no,id=eth0
2. 网卡参数解析
解析完的参数放到 QemuOptsList 中
net_init_clients:对网卡参数进行初始化,没类参数都有对应的解析函数
-netdev 和 -nic 都调用到 net_client_init
net_client_init,参数保存到 object对象中
net_client_init1,如果是-nic,将legacy转换为netdev,如果-netdev,什么都不做,最后根据 type 统一调用 net_client_init_fun[]
net_client_init_fun[]
net_init_nic
NICInfo: 网卡信息
nd_table, NICInfo和 (netdev) NetClientState 之间的关系
net_init_tap
tap_open:打开TAP设备
net_tap_init
net_init_tap_one
net_tap_fd_init
net_tap_info
qemu_new_net_client
qemu_net_client_setup:将新分配的NetClientState挂载到net_clients上
tap_read_poll
tap_update_fd_handler
qemu_set_fd_handler,将fd加入iohandler_ctx进行监听,并设定对应的处理函数
TAP(fd)和TAPState的关系, QEMU的TAP后端
3. qemu前端虚拟网卡设备创建
pc_init1->pc_nic_init 建立qemu虚拟网卡
pc_nic_init
pci_nic_init_nofail
qemu_find_nic_model
pci_get_bus_devfn
qdev_set_nic_properties
qdev_prop_set_macaddr
qdev_prop_set_netdev
e1000_properties
DEFINE_NIC_PROPERTIES
DEFINE_PROP_MACADDR
qdev_prop_macaddr
set_mac:把参数中的52:54:00:12:34:56地址,转换为uint8_t a[6];格式
DEFINE_PROP_NETDEV
qdev_prop_netdev
E1000State_st
NICConf
NICPeers,ncs是后端设备(TAP),每个队列对应一个,前端一个虚拟网卡,可以有多个队列
set_netdev
qemu_find_net_clients_except
e1000虚拟网卡和后端TAP设备的关系
pci_nic_init_nofail
qdev_init_nofail
下面进行实例化,e1000为例
net_e1000_info
pci_e1000_realize
qemu_new_nic
qemu_net_client_setup,设置前端incoming queue处理函数为 qemu_deliver_packet_iov,用来从TAP收报到前端设备
e1000 前后端设备关系
创建qemu虚拟网卡前端
pci_e1000_realize
net_init_tap
net_init_tap_one
net_tap_fd_init
NetClientState
NetClientInfo:网卡的注册信息和注册函数
4. 报文发送流程
e1000_send_packet,如果LOOKBACK,用receive收回;如果不是,用qemu_send_packet发送
qemu_send_packet
qemu_send_packet_async
qemu_send_packet_async_with_flags,sender->peer->incoming_queue得到后端的incoming queue进行发送
qemu_net_queue_send
qemu_net_queue_flush
qemu_net_queue_deliver
qemu_deliver_packet_iov:NetClientState *nc = opaque;是后端tap网卡,后端receive_iov接收,等于发送出去
net_tap_info
tap_receive_iov
tap_write_packet
5. 报文发送流程
tap_send:tap_read_packet 从 TAP中读取报文,qemu_send_packet_async 发送报文到qemu前端虚拟设备
set_ics: e1000中断触发函数