X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=net.c;h=2b0f766408b472d8b9acfe376ff84a6fa6ebb58b;hb=1660e72d4fbbd87e34eb4017d7e7c0ff4e29ca84;hp=a104976b0b65814cb217c3fd9902f6e4ac2c9b8d;hpb=48e2faf222cbf4abab7c8e4b3f44229ec98eae7f;p=qemu.git diff --git a/net.c b/net.c index a104976b0..2b0f76640 100644 --- a/net.c +++ b/net.c @@ -34,6 +34,7 @@ #include "monitor.h" #include "qemu-common.h" #include "qemu_socket.h" +#include "qmp-commands.h" #include "hw/qdev.h" #include "iov.h" @@ -150,12 +151,11 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr) static char *assign_name(VLANClientState *vc1, const char *model) { VLANState *vlan; + VLANClientState *vc; char buf[256]; int id = 0; QTAILQ_FOREACH(vlan, &vlans, next) { - VLANClientState *vc; - QTAILQ_FOREACH(vc, &vlan->clients, next) { if (vc != vc1 && strcmp(vc->model, model) == 0) { id++; @@ -163,9 +163,15 @@ static char *assign_name(VLANClientState *vc1, const char *model) } } + QTAILQ_FOREACH(vc, &non_vlan_clients, next) { + if (vc != vc1 && strcmp(vc->model, model) == 0) { + id++; + } + } + snprintf(buf, sizeof(buf), "%s.%d", model, id); - return qemu_strdup(buf); + return g_strdup(buf); } static ssize_t qemu_deliver_packet(VLANClientState *sender, @@ -189,12 +195,12 @@ VLANClientState *qemu_new_net_client(NetClientInfo *info, assert(info->size >= sizeof(VLANClientState)); - vc = qemu_mallocz(info->size); + vc = g_malloc0(info->size); vc->info = info; - vc->model = qemu_strdup(model); + vc->model = g_strdup(model); if (name) { - vc->name = qemu_strdup(name); + vc->name = g_strdup(name); } else { vc->name = assign_name(vc, model); } @@ -263,9 +269,9 @@ static void qemu_free_vlan_client(VLANClientState *vc) vc->peer->peer = NULL; } } - qemu_free(vc->name); - qemu_free(vc->model); - qemu_free(vc); + g_free(vc->name); + g_free(vc->model); + g_free(vc); } void qemu_del_vlan_client(VLANClientState *vc) @@ -635,7 +641,7 @@ VLANState *qemu_find_vlan(int id, int allocate) return NULL; } - vlan = qemu_mallocz(sizeof(VLANState)); + vlan = g_malloc0(sizeof(VLANState)); vlan->id = id; QTAILQ_INIT(&vlan->clients); @@ -653,6 +659,8 @@ VLANClientState *qemu_find_netdev(const char *id) VLANClientState *vc; QTAILQ_FOREACH(vc, &non_vlan_clients, next) { + if (vc->info->type == NET_CLIENT_TYPE_NIC) + continue; if (!strcmp(vc->name, id)) { return vc; } @@ -703,14 +711,14 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models, int i; if (!nd->model) - nd->model = qemu_strdup(default_model); + nd->model = g_strdup(default_model); for (i = 0 ; models[i]; i++) { if (strcmp(nd->model, models[i]) == 0) return i; } - error_report("qemu: Unsupported NIC model: %s", nd->model); + error_report("Unsupported NIC model: %s", nd->model); return -1; } @@ -726,12 +734,7 @@ int net_handle_fd_param(Monitor *mon, const char *param) return -1; } } else { - char *endptr = NULL; - - fd = strtol(param, &endptr, 10); - if (*endptr || (fd == 0 && param == endptr)) { - return -1; - } + fd = qemu_parse_fd(param); } return fd; @@ -767,27 +770,21 @@ static int net_init_nic(QemuOpts *opts, nd->vlan = vlan; } if (name) { - nd->name = qemu_strdup(name); + nd->name = g_strdup(name); } if (qemu_opt_get(opts, "model")) { - nd->model = qemu_strdup(qemu_opt_get(opts, "model")); + nd->model = g_strdup(qemu_opt_get(opts, "model")); } if (qemu_opt_get(opts, "addr")) { - nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr")); + nd->devaddr = g_strdup(qemu_opt_get(opts, "addr")); } - nd->macaddr[0] = 0x52; - nd->macaddr[1] = 0x54; - nd->macaddr[2] = 0x00; - nd->macaddr[3] = 0x12; - nd->macaddr[4] = 0x34; - nd->macaddr[5] = 0x56 + idx; - if (qemu_opt_get(opts, "macaddr") && - net_parse_macaddr(nd->macaddr, qemu_opt_get(opts, "macaddr")) < 0) { + net_parse_macaddr(nd->macaddr.a, qemu_opt_get(opts, "macaddr")) < 0) { error_report("invalid syntax for ethernet address"); return -1; } + qemu_macaddr_default_if_unset(&nd->macaddr); nd->nvectors = qemu_opt_get_number(opts, "vectors", DEV_NVECTORS_UNSPECIFIED); @@ -830,14 +827,15 @@ static const struct { const char *type; net_client_init_func init; QemuOptDesc desc[NET_MAX_DESC]; -} net_client_types[] = { - { +} net_client_types[NET_CLIENT_TYPE_MAX] = { + [NET_CLIENT_TYPE_NONE] = { .type = "none", .desc = { NET_COMMON_PARAMS_DESC, { /* end of list */ } }, - }, { + }, + [NET_CLIENT_TYPE_NIC] = { .type = "nic", .init = net_init_nic, .desc = { @@ -866,8 +864,9 @@ static const struct { }, { /* end of list */ } }, + }, #ifdef CONFIG_SLIRP - }, { + [NET_CLIENT_TYPE_USER] = { .type = "user", .init = net_init_slirp, .desc = { @@ -927,8 +926,9 @@ static const struct { }, { /* end of list */ } }, + }, #endif - }, { + [NET_CLIENT_TYPE_TAP] = { .type = "tap", .init = net_init_tap, .desc = { @@ -975,7 +975,8 @@ static const struct { #endif /* _WIN32 */ { /* end of list */ } }, - }, { + }, + [NET_CLIENT_TYPE_SOCKET] = { .type = "socket", .init = net_init_socket, .desc = { @@ -999,12 +1000,17 @@ static const struct { }, { .name = "localaddr", .type = QEMU_OPT_STRING, - .help = "source address for multicast packets", + .help = "source address and port for multicast and udp packets", + }, { + .name = "udp", + .type = QEMU_OPT_STRING, + .help = "UDP unicast address and port number", }, { /* end of list */ } }, + }, #ifdef CONFIG_VDE - }, { + [NET_CLIENT_TYPE_VDE] = { .type = "vde", .init = net_init_vde, .desc = { @@ -1028,8 +1034,9 @@ static const struct { }, { /* end of list */ } }, + }, #endif - }, { + [NET_CLIENT_TYPE_DUMP] = { .type = "dump", .init = net_init_dump, .desc = { @@ -1046,7 +1053,6 @@ static const struct { { /* end of list */ } }, }, - { /* end of list */ } }; int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev) @@ -1094,8 +1100,9 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev) name = qemu_opt_get(opts, "name"); } - for (i = 0; net_client_types[i].type != NULL; i++) { - if (!strcmp(net_client_types[i].type, type)) { + for (i = 0; i < NET_CLIENT_TYPE_MAX; i++) { + if (net_client_types[i].type != NULL && + !strcmp(net_client_types[i].type, type)) { VLANState *vlan = NULL; int ret; @@ -1212,7 +1219,7 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data) VLANClientState *vc; vc = qemu_find_netdev(id); - if (!vc || vc->info->type == NET_CLIENT_TYPE_NIC) { + if (!vc) { qerror_report(QERR_DEVICE_NOT_FOUND, id); return -1; } @@ -1221,34 +1228,45 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data) return 0; } +static void print_net_client(Monitor *mon, VLANClientState *vc) +{ + monitor_printf(mon, "%s: type=%s,%s\n", vc->name, + net_client_types[vc->info->type].type, vc->info_str); +} + void do_info_network(Monitor *mon) { VLANState *vlan; - VLANClientState *vc; + VLANClientState *vc, *peer; + net_client_type type; QTAILQ_FOREACH(vlan, &vlans, next) { monitor_printf(mon, "VLAN %d devices:\n", vlan->id); QTAILQ_FOREACH(vc, &vlan->clients, next) { - monitor_printf(mon, " %s: %s\n", vc->name, vc->info_str); + monitor_printf(mon, " "); + print_net_client(mon, vc); } } monitor_printf(mon, "Devices not on any VLAN:\n"); QTAILQ_FOREACH(vc, &non_vlan_clients, next) { - monitor_printf(mon, " %s: %s", vc->name, vc->info_str); - if (vc->peer) { - monitor_printf(mon, " peer=%s", vc->peer->name); + peer = vc->peer; + type = vc->info->type; + if (!peer || type == NET_CLIENT_TYPE_NIC) { + monitor_printf(mon, " "); + print_net_client(mon, vc); + } /* else it's a netdev connected to a NIC, printed with the NIC */ + if (peer && type == NET_CLIENT_TYPE_NIC) { + monitor_printf(mon, " \\ "); + print_net_client(mon, peer); } - monitor_printf(mon, "\n"); } } -int do_set_link(Monitor *mon, const QDict *qdict, QObject **ret_data) +void qmp_set_link(const char *name, bool up, Error **errp) { VLANState *vlan; VLANClientState *vc = NULL; - const char *name = qdict_get_str(qdict, "name"); - int up = qdict_get_bool(qdict, "up"); QTAILQ_FOREACH(vlan, &vlans, next) { QTAILQ_FOREACH(vc, &vlan->clients, next) { @@ -1257,12 +1275,16 @@ int do_set_link(Monitor *mon, const QDict *qdict, QObject **ret_data) } } } - vc = qemu_find_netdev(name); + QTAILQ_FOREACH(vc, &non_vlan_clients, next) { + if (!strcmp(vc->name, name)) { + goto done; + } + } done: if (!vc) { - qerror_report(QERR_DEVICE_NOT_FOUND, name); - return -1; + error_set(errp, QERR_DEVICE_NOT_FOUND, name); + return; } vc->link_down = !up; @@ -1281,7 +1303,6 @@ done: if (vc->peer && vc->peer->info->link_status_changed) { vc->peer->info->link_status_changed(vc->peer); } - return 0; } void net_cleanup(void) @@ -1326,7 +1347,7 @@ void net_check_clients(void) case NET_CLIENT_TYPE_NIC: has_nic = 1; break; - case NET_CLIENT_TYPE_SLIRP: + case NET_CLIENT_TYPE_USER: case NET_CLIENT_TYPE_TAP: case NET_CLIENT_TYPE_SOCKET: case NET_CLIENT_TYPE_VDE: