diff options
author | Thomas Huth <thuth@redhat.com> | 2018-02-21 11:18:36 +0100 |
---|---|---|
committer | Jason Wang <jasowang@redhat.com> | 2018-03-05 10:30:16 +0800 |
commit | 78cd6f7bf6b196a96388a37e730706cf0c497fda (patch) | |
tree | 63e7f18c6e600323ac0689ddc68a3804e5b215e4 /net/net.c | |
parent | 7cc28cb061040cb089d29de2d9a73f404b94bc66 (diff) |
net: Add a new convenience option "--nic" to configure default/on-board NICs
The legacy "-net" option can be quite confusing for the users since most
people do not expect to get a "vlan" hub between their emulated guest
hardware and the host backend. But so far, we are also not able to get
rid of "-net" completely, since it is the only way to configure on-board
NICs that can not be instantiated via "-device" yet. It's also a little
bit shorter to type "-net nic -net tap" instead of "-device xyz,netdev=n1
-netdev tap,id=n1".
So what we need is a new convenience option that is shorter to type than
the full -device + -netdev stuff, and which can be used to configure the
on-board NICs that can not be handled via -device yet. Thus this patch now
provides such a new option "--nic": It adds an entry in the nd_table to
configure a on-board / default NIC, creates a host backend and connects
the two directly, without a confusing "vlan" hub inbetween.
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'net/net.c')
-rw-r--r-- | net/net.c | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -1462,6 +1462,67 @@ static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp) return net_client_init(opts, true, errp); } +/* For the convenience "--nic" parameter */ +static int net_param_nic(void *dummy, QemuOpts *opts, Error **errp) +{ + char *mac, *nd_id; + int idx, ret; + NICInfo *ni; + const char *type; + + type = qemu_opt_get(opts, "type"); + if (type && g_str_equal(type, "none")) { + return 0; /* Nothing to do, default_net is cleared in vl.c */ + } + + idx = nic_get_free_idx(); + if (idx == -1 || nb_nics >= MAX_NICS) { + error_setg(errp, "no more on-board/default NIC slots available"); + return -1; + } + + if (!type) { + qemu_opt_set(opts, "type", "user", &error_abort); + } + + ni = &nd_table[idx]; + memset(ni, 0, sizeof(*ni)); + ni->model = qemu_opt_get_del(opts, "model"); + + /* Create an ID if the user did not specify one */ + nd_id = g_strdup(qemu_opts_id(opts)); + if (!nd_id) { + nd_id = g_strdup_printf("__org.qemu.nic%i\n", idx); + qemu_opts_set_id(opts, nd_id); + } + + /* Handle MAC address */ + mac = qemu_opt_get_del(opts, "mac"); + if (mac) { + ret = net_parse_macaddr(ni->macaddr.a, mac); + g_free(mac); + if (ret) { + error_setg(errp, "invalid syntax for ethernet address"); + return -1; + } + if (is_multicast_ether_addr(ni->macaddr.a)) { + error_setg(errp, "NIC cannot have multicast MAC address"); + return -1; + } + } + qemu_macaddr_default_if_unset(&ni->macaddr); + + ret = net_client_init(opts, true, errp); + if (ret == 0) { + ni->netdev = qemu_find_netdev(nd_id); + ni->used = true; + nb_nics++; + } + + g_free(nd_id); + return ret; +} + int net_init_clients(Error **errp) { net_change_state_entry = @@ -1474,6 +1535,10 @@ int net_init_clients(Error **errp) return -1; } + if (qemu_opts_foreach(qemu_find_opts("nic"), net_param_nic, NULL, errp)) { + return -1; + } + if (qemu_opts_foreach(qemu_find_opts("net"), net_init_client, NULL, errp)) { return -1; } @@ -1549,6 +1614,19 @@ QemuOptsList qemu_netdev_opts = { }, }; +QemuOptsList qemu_nic_opts = { + .name = "nic", + .implied_opt_name = "type", + .head = QTAILQ_HEAD_INITIALIZER(qemu_nic_opts.head), + .desc = { + /* + * no elements => accept any params + * validation will happen later + */ + { /* end of list */ } + }, +}; + QemuOptsList qemu_net_opts = { .name = "net", .implied_opt_name = "type", |