1 /* 2 * Human Monitor Interface commands 3 * 4 * Copyright IBM, Corp. 2011 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2. See 10 * the COPYING file in the top-level directory. 11 * 12 * Contributions after 2012-01-13 are licensed under the terms of the 13 * GNU GPL, version 2 or (at your option) any later version. 14 */ 15 16 #include "qemu/osdep.h" 17 #include "migration/misc.h" 18 #include "monitor/hmp.h" 19 #include "monitor/monitor.h" 20 #include "net/net.h" 21 #include "net/hub.h" 22 #include "qapi/clone-visitor.h" 23 #include "qapi/qapi-commands-net.h" 24 #include "qapi/qapi-visit-net.h" 25 #include "qapi/qmp/qdict.h" 26 #include "qemu/config-file.h" 27 #include "qemu/help_option.h" 28 #include "qemu/option.h" 29 30 void hmp_info_network(Monitor *mon, const QDict *qdict) 31 { 32 NetClientState *nc, *peer; 33 NetClientDriver type; 34 35 net_hub_info(mon); 36 37 QTAILQ_FOREACH(nc, &net_clients, next) { 38 peer = nc->peer; 39 type = nc->info->type; 40 41 /* Skip if already printed in hub info */ 42 if (net_hub_id_for_client(nc, NULL) == 0) { 43 continue; 44 } 45 46 if (!peer || type == NET_CLIENT_DRIVER_NIC) { 47 print_net_client(mon, nc); 48 } /* else it's a netdev connected to a NIC, printed with the NIC */ 49 if (peer && type == NET_CLIENT_DRIVER_NIC) { 50 monitor_printf(mon, " \\ "); 51 print_net_client(mon, peer); 52 } 53 } 54 } 55 56 void hmp_set_link(Monitor *mon, const QDict *qdict) 57 { 58 const char *name = qdict_get_str(qdict, "name"); 59 bool up = qdict_get_bool(qdict, "up"); 60 Error *err = NULL; 61 62 qmp_set_link(name, up, &err); 63 hmp_handle_error(mon, err); 64 } 65 66 67 void hmp_announce_self(Monitor *mon, const QDict *qdict) 68 { 69 const char *interfaces_str = qdict_get_try_str(qdict, "interfaces"); 70 const char *id = qdict_get_try_str(qdict, "id"); 71 AnnounceParameters *params = QAPI_CLONE(AnnounceParameters, 72 migrate_announce_params()); 73 74 qapi_free_strList(params->interfaces); 75 params->interfaces = hmp_split_at_comma(interfaces_str); 76 params->has_interfaces = params->interfaces != NULL; 77 params->id = g_strdup(id); 78 qmp_announce_self(params, NULL); 79 qapi_free_AnnounceParameters(params); 80 } 81 82 void hmp_netdev_add(Monitor *mon, const QDict *qdict) 83 { 84 Error *err = NULL; 85 QemuOpts *opts; 86 const char *type = qdict_get_try_str(qdict, "type"); 87 88 if (type && is_help_option(type)) { 89 show_netdevs(); 90 return; 91 } 92 opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err); 93 if (err) { 94 goto out; 95 } 96 97 netdev_add(opts, &err); 98 if (err) { 99 qemu_opts_del(opts); 100 } 101 102 out: 103 hmp_handle_error(mon, err); 104 } 105 106 void hmp_netdev_del(Monitor *mon, const QDict *qdict) 107 { 108 const char *id = qdict_get_str(qdict, "id"); 109 Error *err = NULL; 110 111 qmp_netdev_del(id, &err); 112 hmp_handle_error(mon, err); 113 } 114 115 116 void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str) 117 { 118 size_t len; 119 int i; 120 121 if (nb_args != 2) { 122 return; 123 } 124 len = strlen(str); 125 readline_set_completion_index(rs, len); 126 for (i = 0; i < NET_CLIENT_DRIVER__MAX; i++) { 127 readline_add_completion_of(rs, str, NetClientDriver_str(i)); 128 } 129 } 130 131 void set_link_completion(ReadLineState *rs, int nb_args, const char *str) 132 { 133 size_t len; 134 135 len = strlen(str); 136 readline_set_completion_index(rs, len); 137 if (nb_args == 2) { 138 NetClientState *ncs[MAX_QUEUE_NUM]; 139 int count, i; 140 count = qemu_find_net_clients_except(NULL, ncs, 141 NET_CLIENT_DRIVER_NONE, 142 MAX_QUEUE_NUM); 143 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { 144 readline_add_completion_of(rs, str, ncs[i]->name); 145 } 146 } else if (nb_args == 3) { 147 readline_add_completion_of(rs, str, "on"); 148 readline_add_completion_of(rs, str, "off"); 149 } 150 } 151 152 void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str) 153 { 154 int len, count, i; 155 NetClientState *ncs[MAX_QUEUE_NUM]; 156 157 if (nb_args != 2) { 158 return; 159 } 160 161 len = strlen(str); 162 readline_set_completion_index(rs, len); 163 count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_DRIVER_NIC, 164 MAX_QUEUE_NUM); 165 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { 166 if (ncs[i]->is_netdev) { 167 readline_add_completion_of(rs, str, ncs[i]->name); 168 } 169 } 170 } 171