you can find this code at 4119 line of vl.c
if (net_init_clients() < 0) {
exit(1);
}
and also can find this code at 188 line of qemu/hw/i386/pc_piix.c
pc_nic_init(isa_bus, pci_bus); // network card initialization
Those two parts are key function to start initializing Network of Guest and Hypervisor.
Then, let's follow those functions.
First, we are starting with net_init_clients() function.
int net_init_clients(void)
{
QemuOptsList *net = qemu_find_opts("net");
if (default_net) {
/* if no clients, we use a default config */
qemu_opts_set(net, NULL, "type", "nic");
#ifdef CONFIG_SLIRP
qemu_opts_set(net, NULL, "type", "user");
#endif
}
QTAILQ_INIT(&net_clients);
if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1)
return -1;
if (qemu_opts_foreach(net, net_init_client, NULL, 1) == -1) {
return -1;
}
return 0;
}
those function both net_init_netdev and net_init_client are doing same thing, so we follow net_init_netdev function.( finally both will call net_client_init function.
static int net_init_netdev(QemuOpts *opts, void *dummy)
{
Error *local_err = NULL;
int ret;
ret = net_client_init(opts, 1, &local_err);
if (error_is_set(&local_err)) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
}
return ret;
}
int net_client_init(QemuOpts *opts, int is_netdev, Error **errp)
{
void *object = NULL;
Error *err = NULL;
int ret = -1;
{
OptsVisitor *ov = opts_visitor_new(opts);
net_visit(opts_get_visitor(ov), is_netdev, &object, &err);
opts_visitor_cleanup(ov);
}
if (!err) {
ret = net_client_init1(object, is_netdev, &err);
}
if (object) {
QapiDeallocVisitor *dv = qapi_dealloc_visitor_new();
net_visit(qapi_dealloc_get_visitor(dv), is_netdev, &object, NULL);
qapi_dealloc_visitor_cleanup(dv);
}
error_propagate(errp, err);
return ret;
}
static int net_client_init1(const void *object, int is_netdev, Error **errp)
{
union {
const Netdev *netdev;
const NetLegacy *net;
} u;
const NetClientOptions *opts;
const char *name;
if (is_netdev) {
u.netdev = object;
opts = u.netdev->opts;
name = u.netdev->id;
switch (opts->kind) {
#ifdef CONFIG_SLIRP
case NET_CLIENT_OPTIONS_KIND_USER:
#endif
case NET_CLIENT_OPTIONS_KIND_TAP:
case NET_CLIENT_OPTIONS_KIND_SOCKET:
#ifdef CONFIG_VDE
case NET_CLIENT_OPTIONS_KIND_VDE:
#endif
#ifdef CONFIG_NET_BRIDGE
case NET_CLIENT_OPTIONS_KIND_BRIDGE:
#endif
case NET_CLIENT_OPTIONS_KIND_HUBPORT:
break;
default:
error_set(errp, QERR_INVALID_PARAMETER_VALUE, "type",
"a netdev backend type");
return -1;
}
} else {
u.net = object;
opts = u.net->opts;
/* missing optional values have been initialized to "all bits zero" */
name = u.net->has_id ? u.net->id : u.net->name;
}
if (net_client_init_fun[opts->kind]) {
NetClientState *peer = NULL;
/* Do not add to a vlan if it's a -netdev or a nic with a netdev=
* parameter. */
if (!is_netdev &&
(opts->kind != NET_CLIENT_OPTIONS_KIND_NIC ||
!opts->nic->has_netdev)) {
peer = net_hub_add_port(u.net->has_vlan ? u.net->vlan : 0, NULL);
}
if (net_client_init_fun[opts->kind](opts, name, peer) < 0) {
/* TODO push error reporting into init() methods */
error_set(errp, QERR_DEVICE_INIT_FAILED,
NetClientOptionsKind_lookup[opts->kind]);
return -1;
}
}
return 0;
}
finally we found function pointers, here are functions for that pointer structure.
static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
const NetClientOptions *opts,
const char *name,
NetClientState *peer) = {
[NET_CLIENT_OPTIONS_KIND_NIC] = net_init_nic,
#ifdef CONFIG_SLIRP
[NET_CLIENT_OPTIONS_KIND_USER] = net_init_slirp,
#endif
[NET_CLIENT_OPTIONS_KIND_TAP] = net_init_tap,
[NET_CLIENT_OPTIONS_KIND_SOCKET] = net_init_socket,
#ifdef CONFIG_VDE
[NET_CLIENT_OPTIONS_KIND_VDE] = net_init_vde,
#endif
[NET_CLIENT_OPTIONS_KIND_DUMP] = net_init_dump,
#ifdef CONFIG_NET_BRIDGE
[NET_CLIENT_OPTIONS_KIND_BRIDGE] = net_init_bridge,
#endif
[NET_CLIENT_OPTIONS_KIND_HUBPORT] = net_init_hubport,
};
'Virtualization' 카테고리의 다른 글
KVM - QEMU Network Initialization 3 (0) | 2014.05.28 |
---|---|
KVM - QEMU Network Initialization 2 (0) | 2014.05.28 |
Initializing process for USB (0) | 2014.05.23 |
link between IDE PortIO and Drive Operation (0) | 2014.05.23 |
Process of Device Initializing in QEMU (0) | 2014.05.23 |