12030ca36SMarkus Armbruster /*
22030ca36SMarkus Armbruster * Human Monitor Interface commands
32030ca36SMarkus Armbruster *
42030ca36SMarkus Armbruster * Copyright IBM, Corp. 2011
52030ca36SMarkus Armbruster *
62030ca36SMarkus Armbruster * Authors:
72030ca36SMarkus Armbruster * Anthony Liguori <aliguori@us.ibm.com>
82030ca36SMarkus Armbruster *
92030ca36SMarkus Armbruster * This work is licensed under the terms of the GNU GPL, version 2. See
102030ca36SMarkus Armbruster * the COPYING file in the top-level directory.
112030ca36SMarkus Armbruster *
122030ca36SMarkus Armbruster * Contributions after 2012-01-13 are licensed under the terms of the
132030ca36SMarkus Armbruster * GNU GPL, version 2 or (at your option) any later version.
142030ca36SMarkus Armbruster */
152030ca36SMarkus Armbruster
162030ca36SMarkus Armbruster #include "qemu/osdep.h"
172030ca36SMarkus Armbruster #include "migration/misc.h"
182030ca36SMarkus Armbruster #include "monitor/hmp.h"
19*ae71d13dSMarkus Armbruster #include "monitor/monitor.h"
202030ca36SMarkus Armbruster #include "net/net.h"
21*ae71d13dSMarkus Armbruster #include "net/hub.h"
222030ca36SMarkus Armbruster #include "qapi/clone-visitor.h"
232030ca36SMarkus Armbruster #include "qapi/qapi-commands-net.h"
242030ca36SMarkus Armbruster #include "qapi/qapi-visit-net.h"
252030ca36SMarkus Armbruster #include "qapi/qmp/qdict.h"
262030ca36SMarkus Armbruster #include "qemu/config-file.h"
272030ca36SMarkus Armbruster #include "qemu/help_option.h"
282030ca36SMarkus Armbruster #include "qemu/option.h"
292030ca36SMarkus Armbruster
hmp_info_network(Monitor * mon,const QDict * qdict)30*ae71d13dSMarkus Armbruster void hmp_info_network(Monitor *mon, const QDict *qdict)
31*ae71d13dSMarkus Armbruster {
32*ae71d13dSMarkus Armbruster NetClientState *nc, *peer;
33*ae71d13dSMarkus Armbruster NetClientDriver type;
34*ae71d13dSMarkus Armbruster
35*ae71d13dSMarkus Armbruster net_hub_info(mon);
36*ae71d13dSMarkus Armbruster
37*ae71d13dSMarkus Armbruster QTAILQ_FOREACH(nc, &net_clients, next) {
38*ae71d13dSMarkus Armbruster peer = nc->peer;
39*ae71d13dSMarkus Armbruster type = nc->info->type;
40*ae71d13dSMarkus Armbruster
41*ae71d13dSMarkus Armbruster /* Skip if already printed in hub info */
42*ae71d13dSMarkus Armbruster if (net_hub_id_for_client(nc, NULL) == 0) {
43*ae71d13dSMarkus Armbruster continue;
44*ae71d13dSMarkus Armbruster }
45*ae71d13dSMarkus Armbruster
46*ae71d13dSMarkus Armbruster if (!peer || type == NET_CLIENT_DRIVER_NIC) {
47*ae71d13dSMarkus Armbruster print_net_client(mon, nc);
48*ae71d13dSMarkus Armbruster } /* else it's a netdev connected to a NIC, printed with the NIC */
49*ae71d13dSMarkus Armbruster if (peer && type == NET_CLIENT_DRIVER_NIC) {
50*ae71d13dSMarkus Armbruster monitor_printf(mon, " \\ ");
51*ae71d13dSMarkus Armbruster print_net_client(mon, peer);
52*ae71d13dSMarkus Armbruster }
53*ae71d13dSMarkus Armbruster }
54*ae71d13dSMarkus Armbruster }
55*ae71d13dSMarkus Armbruster
hmp_set_link(Monitor * mon,const QDict * qdict)562030ca36SMarkus Armbruster void hmp_set_link(Monitor *mon, const QDict *qdict)
572030ca36SMarkus Armbruster {
582030ca36SMarkus Armbruster const char *name = qdict_get_str(qdict, "name");
592030ca36SMarkus Armbruster bool up = qdict_get_bool(qdict, "up");
602030ca36SMarkus Armbruster Error *err = NULL;
612030ca36SMarkus Armbruster
622030ca36SMarkus Armbruster qmp_set_link(name, up, &err);
632030ca36SMarkus Armbruster hmp_handle_error(mon, err);
642030ca36SMarkus Armbruster }
652030ca36SMarkus Armbruster
662030ca36SMarkus Armbruster
hmp_announce_self(Monitor * mon,const QDict * qdict)672030ca36SMarkus Armbruster void hmp_announce_self(Monitor *mon, const QDict *qdict)
682030ca36SMarkus Armbruster {
692030ca36SMarkus Armbruster const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
702030ca36SMarkus Armbruster const char *id = qdict_get_try_str(qdict, "id");
712030ca36SMarkus Armbruster AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
722030ca36SMarkus Armbruster migrate_announce_params());
732030ca36SMarkus Armbruster
742030ca36SMarkus Armbruster qapi_free_strList(params->interfaces);
752030ca36SMarkus Armbruster params->interfaces = hmp_split_at_comma(interfaces_str);
762030ca36SMarkus Armbruster params->has_interfaces = params->interfaces != NULL;
772030ca36SMarkus Armbruster params->id = g_strdup(id);
782030ca36SMarkus Armbruster qmp_announce_self(params, NULL);
792030ca36SMarkus Armbruster qapi_free_AnnounceParameters(params);
802030ca36SMarkus Armbruster }
812030ca36SMarkus Armbruster
hmp_netdev_add(Monitor * mon,const QDict * qdict)822030ca36SMarkus Armbruster void hmp_netdev_add(Monitor *mon, const QDict *qdict)
832030ca36SMarkus Armbruster {
842030ca36SMarkus Armbruster Error *err = NULL;
852030ca36SMarkus Armbruster QemuOpts *opts;
862030ca36SMarkus Armbruster const char *type = qdict_get_try_str(qdict, "type");
872030ca36SMarkus Armbruster
882030ca36SMarkus Armbruster if (type && is_help_option(type)) {
892030ca36SMarkus Armbruster show_netdevs();
902030ca36SMarkus Armbruster return;
912030ca36SMarkus Armbruster }
922030ca36SMarkus Armbruster opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
932030ca36SMarkus Armbruster if (err) {
942030ca36SMarkus Armbruster goto out;
952030ca36SMarkus Armbruster }
962030ca36SMarkus Armbruster
972030ca36SMarkus Armbruster netdev_add(opts, &err);
982030ca36SMarkus Armbruster if (err) {
992030ca36SMarkus Armbruster qemu_opts_del(opts);
1002030ca36SMarkus Armbruster }
1012030ca36SMarkus Armbruster
1022030ca36SMarkus Armbruster out:
1032030ca36SMarkus Armbruster hmp_handle_error(mon, err);
1042030ca36SMarkus Armbruster }
1052030ca36SMarkus Armbruster
hmp_netdev_del(Monitor * mon,const QDict * qdict)1062030ca36SMarkus Armbruster void hmp_netdev_del(Monitor *mon, const QDict *qdict)
1072030ca36SMarkus Armbruster {
1082030ca36SMarkus Armbruster const char *id = qdict_get_str(qdict, "id");
1092030ca36SMarkus Armbruster Error *err = NULL;
1102030ca36SMarkus Armbruster
1112030ca36SMarkus Armbruster qmp_netdev_del(id, &err);
1122030ca36SMarkus Armbruster hmp_handle_error(mon, err);
1132030ca36SMarkus Armbruster }
1142030ca36SMarkus Armbruster
1152030ca36SMarkus Armbruster
netdev_add_completion(ReadLineState * rs,int nb_args,const char * str)1162030ca36SMarkus Armbruster void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str)
1172030ca36SMarkus Armbruster {
1182030ca36SMarkus Armbruster size_t len;
1192030ca36SMarkus Armbruster int i;
1202030ca36SMarkus Armbruster
1212030ca36SMarkus Armbruster if (nb_args != 2) {
1222030ca36SMarkus Armbruster return;
1232030ca36SMarkus Armbruster }
1242030ca36SMarkus Armbruster len = strlen(str);
1252030ca36SMarkus Armbruster readline_set_completion_index(rs, len);
1262030ca36SMarkus Armbruster for (i = 0; i < NET_CLIENT_DRIVER__MAX; i++) {
1272030ca36SMarkus Armbruster readline_add_completion_of(rs, str, NetClientDriver_str(i));
1282030ca36SMarkus Armbruster }
1292030ca36SMarkus Armbruster }
1302030ca36SMarkus Armbruster
set_link_completion(ReadLineState * rs,int nb_args,const char * str)1312030ca36SMarkus Armbruster void set_link_completion(ReadLineState *rs, int nb_args, const char *str)
1322030ca36SMarkus Armbruster {
1332030ca36SMarkus Armbruster size_t len;
1342030ca36SMarkus Armbruster
1352030ca36SMarkus Armbruster len = strlen(str);
1362030ca36SMarkus Armbruster readline_set_completion_index(rs, len);
1372030ca36SMarkus Armbruster if (nb_args == 2) {
1382030ca36SMarkus Armbruster NetClientState *ncs[MAX_QUEUE_NUM];
1392030ca36SMarkus Armbruster int count, i;
1402030ca36SMarkus Armbruster count = qemu_find_net_clients_except(NULL, ncs,
1412030ca36SMarkus Armbruster NET_CLIENT_DRIVER_NONE,
1422030ca36SMarkus Armbruster MAX_QUEUE_NUM);
1432030ca36SMarkus Armbruster for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
1442030ca36SMarkus Armbruster readline_add_completion_of(rs, str, ncs[i]->name);
1452030ca36SMarkus Armbruster }
1462030ca36SMarkus Armbruster } else if (nb_args == 3) {
1472030ca36SMarkus Armbruster readline_add_completion_of(rs, str, "on");
1482030ca36SMarkus Armbruster readline_add_completion_of(rs, str, "off");
1492030ca36SMarkus Armbruster }
1502030ca36SMarkus Armbruster }
1512030ca36SMarkus Armbruster
netdev_del_completion(ReadLineState * rs,int nb_args,const char * str)1522030ca36SMarkus Armbruster void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
1532030ca36SMarkus Armbruster {
1542030ca36SMarkus Armbruster int len, count, i;
1552030ca36SMarkus Armbruster NetClientState *ncs[MAX_QUEUE_NUM];
1562030ca36SMarkus Armbruster
1572030ca36SMarkus Armbruster if (nb_args != 2) {
1582030ca36SMarkus Armbruster return;
1592030ca36SMarkus Armbruster }
1602030ca36SMarkus Armbruster
1612030ca36SMarkus Armbruster len = strlen(str);
1622030ca36SMarkus Armbruster readline_set_completion_index(rs, len);
1632030ca36SMarkus Armbruster count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_DRIVER_NIC,
1642030ca36SMarkus Armbruster MAX_QUEUE_NUM);
1652030ca36SMarkus Armbruster for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
1662030ca36SMarkus Armbruster if (ncs[i]->is_netdev) {
1672030ca36SMarkus Armbruster readline_add_completion_of(rs, str, ncs[i]->name);
1682030ca36SMarkus Armbruster }
1692030ca36SMarkus Armbruster }
1702030ca36SMarkus Armbruster }
171