现在的位置: 首页 > 综合 > 正文

qemu network backend的初始化

2017年12月22日 ⁄ 综合 ⁄ 共 2403字 ⁄ 字号 评论关闭
network backend跟类型无关的实现基本都在net.c中,
全局变量: 
vlans 所有vlan的链表,vlan使用VLANState结构表示
non_vlan_clients 不属于任何vlan的networkbackend链表。所有的netdev都在该链表上。
networkbackend的类型使用NetClientInfo结构来表示,其实例则使用VLanClientState表示。
当前一共定义了以下几类NetClient:
  typedef enum { 
   NET_CLIENT_TYPE_NONE, 
   NET_CLIENT_TYPE_NIC, 
   NET_CLIENT_TYPE_SLIRP, 
   NET_CLIENT_TYPE_TAP, 
   NET_CLIENT_TYPE_SOCKET, 
   NET_CLIENT_TYPE_VDE, 
   NET_CLIENT_TYPE_DUMP 
  } net_client_type;
qemu_new_net_client 用于创建VLANClientState结构,其实际的结构根据net clienttype的不同而不同。
实际结构和类型的对应关系如下:
NONE
NIC     NICState
SLIRP   SlirpState
TAP     TAPState
SOCKET  NetSocketState
VDE    VDEState
DUMP    DumpState
NET_CLIENT_TYPE_NIC表示Guest中的Virtual Network Card。
NIC可以有两种attach模式,一种是attach到某个vLan上面,另外一个是attach到某个netdev上面。
在dump.c/slirp.c/tap.c/socket.c/vdc.c的初始化函数中,在调用qemu_new_net_client时,
peer参数都指定为NULL。如果在之后,有NIC在初始化时将此networkbackend指定为peer,那么
也会设置该network backend的peer为该NIC。
NIC类型的虚拟网卡则调用qemu_new_nic来创建,在其中又调用了qemu_new_net_client,其中peer
参数指定为conf->peer。
下面来看下e1000虚拟网卡的创建过程:
在系统创建完pci设备之后,会调用pci_e1000_init(PCIDevice*pci_dev)来初始化,在这其中又
调用了qemu_new_nic。
来看下对应于e1000的PCIDeviceInfo:
static PCIDeviceInfo e1000_info = {
    .qdev.name = "e1000",
    .qdev.desc = "Intel Gigabit Ethernet",
    .qdev.size = sizeof(E1000State),
    .qdev.reset =qdev_e1000_reset,
    .qdev.vmsd = &vmstate_e1000,
    .init      = pci_e1000_init,
    .exit      = pci_e1000_uninit,
    .romfile   = "pxe-e1000.bin",
    .qdev.props =(Property[]) {
       DEFINE_NIC_PROPERTIES(E1000State, conf),
       DEFINE_PROP_END_OF_LIST(),
    }
};
其中DEFINE_NIC_PROPERTIES(E1000State, conf), 这个宏的定义如下:
#define DEFINE_NIC_PROPERTIES(_state, _conf)                       \
   DEFINE_PROP_MACADDR("mac",   _state,_conf.macaddr),              \
    DEFINE_PROP_VLAN("vlan",    _state, _conf.vlan),                \
   DEFINE_PROP_NETDEV("netdev", _state, _conf.peer),                \
   DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1)
可见,在qemu parse命令行参数的时候,会把netdev参数所指定的network backend对象赋予
E1000State.conf.peer。
结合命令行参数 -devicee1000,netdev=hostnet0,id=net0,mac=00:16:36:e3:f8:b9,bus=pci.0,addr=0x3,
这样就很明显了。
-------------------------------------
network backend的初始化流程如下:
                        | ->net_init_netdev --|
main -> net_init_clients -> |                  | ->net_client_init 
                        | ->net_init_client --|
-> net_client_types[i].init
net_init_client 初始化命令行上 -net 指定的network backend
net_init_netdev 初始化命令行上 -netdev 指定的network backend
qemu_del_vlan_client(vc),如果peer是NIC,那么标记peer的peer_deleted =true,并且调用qemu_cleanup_vlan_client(vc)。如果自己是NIC,如果peer_deleted ==true,那么调用qemu_free_vlan_client释放peer,然后再释放自己。

【上篇】
【下篇】

抱歉!评论已关闭.