xref: /openbmc/qemu/net/net-hmp-cmds.c (revision 579510e196a544b42bd8bca9cc61688d4d1211ac)
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