qemu network backend的初始化

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,然后再释放自己。


你可能感兴趣的:(qemu network backend的初始化)