[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 2/2] net: introduce command to query mac-table in
From: |
Amos Kong |
Subject: |
[Qemu-devel] [PATCH v2 2/2] net: introduce command to query mac-table information |
Date: |
Thu, 16 May 2013 19:07:25 +0800 |
We want to implement mac programming over macvtap through Libvirt.
The previous patch adds QMP event to notify management of mac-table
change. This patch adds a monitor command to query rx mode information
of mac-tables.
(qemu) info mac-table vnet0
vnet0:
\ promisc: on
\ allmulti: off
\ alluni: off
\ nomulti: off
\ nouni: off
\ nobcast: off
\ multi_overflow: off
\ uni_overflow: off
\ multicast:
01:00:5e:00:00:01
33:33:00:00:00:01
33:33:ff:12:34:56
Signed-off-by: Amos Kong <address@hidden>
---
hmp-commands.hx | 2 ++
hmp.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++
hmp.h | 1 +
hw/net/virtio-net.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++
include/net/net.h | 2 ++
monitor.c | 8 ++++++
net/net.c | 38 ++++++++++++++++++++++++++++
qapi-schema.json | 57 ++++++++++++++++++++++++++++++++++++++++++
qmp-commands.hx | 53 +++++++++++++++++++++++++++++++++++++++
9 files changed, 295 insertions(+)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 9cea415..e5c1b14 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1639,6 +1639,8 @@ show qdev device model list
show roms
@item info tpm
show the TPM device
address@hidden info mac-table [net client name]
+show the mac-table information for all nics (or for the given nic)
@end table
ETEXI
diff --git a/hmp.c b/hmp.c
index 4fb76ec..3e19df0 100644
--- a/hmp.c
+++ b/hmp.c
@@ -653,6 +653,77 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
qapi_free_TPMInfoList(info_list);
}
+void hmp_info_mac_table(Monitor *mon, const QDict *qdict)
+{
+ MacTableInfoList *table_list, *entry;
+ strList *str_entry;
+ bool has_name = qdict_haskey(qdict, "name");
+ const char *name = NULL;
+
+ if (has_name) {
+ name = qdict_get_str(qdict, "name");
+ }
+
+ table_list = qmp_query_mac_table(has_name, name, NULL);
+ entry = table_list;
+
+ while (entry) {
+ monitor_printf(mon, "%s:\n", entry->value->name);
+ if (entry->value->has_promisc) {
+ monitor_printf(mon, " \\ promisc: %s\n",
+ entry->value->promisc ? "on" : "off");
+ }
+ if (entry->value->has_allmulti) {
+ monitor_printf(mon, " \\ allmulti: %s\n",
+ entry->value->allmulti ? "on" : "off");
+ }
+ if (entry->value->has_alluni) {
+ monitor_printf(mon, " \\ alluni: %s\n",
+ entry->value->alluni ? "on" : "off");
+ }
+ if (entry->value->has_nomulti) {
+ monitor_printf(mon, " \\ nomulti: %s\n",
+ entry->value->nomulti ? "on" : "off");
+ }
+ if (entry->value->has_nouni) {
+ monitor_printf(mon, " \\ nouni: %s\n",
+ entry->value->nouni ? "on" : "off");
+ }
+ if (entry->value->has_nobcast) {
+ monitor_printf(mon, " \\ nobcast: %s\n",
+ entry->value->nobcast ? "on" : "off");
+ }
+ if (entry->value->has_multi_overflow) {
+ monitor_printf(mon, " \\ multi_overflow: %s\n",
+ entry->value->multi_overflow ? "on" : "off");
+ }
+ if (entry->value->has_uni_overflow) {
+ monitor_printf(mon, " \\ uni_overflow: %s\n",
+ entry->value->uni_overflow ? "on" : "off");
+ }
+
+ if (entry->value->has_unicast) {
+ str_entry = entry->value->unicast;
+ monitor_printf(mon, " \\ unicast:\n");
+ while (str_entry) {
+ monitor_printf(mon, " %s\n", str_entry->value);
+ str_entry = str_entry->next;
+ }
+ }
+ if (entry->value->has_multicast) {
+ str_entry = entry->value->multicast;
+ monitor_printf(mon, " \\ multicast:\n");
+ while (str_entry) {
+ monitor_printf(mon, " %s\n", str_entry->value);
+ str_entry = str_entry->next;
+ }
+ }
+
+ entry = entry->next;
+ }
+ qapi_free_MacTableInfoList(table_list);
+}
+
void hmp_quit(Monitor *mon, const QDict *qdict)
{
monitor_suspend(mon);
diff --git a/hmp.h b/hmp.h
index 95fe76e..278c722 100644
--- a/hmp.h
+++ b/hmp.h
@@ -37,6 +37,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict);
void hmp_info_pci(Monitor *mon, const QDict *qdict);
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
void hmp_info_tpm(Monitor *mon, const QDict *qdict);
+void hmp_info_mac_table(Monitor *mon, const QDict *qdict);
void hmp_quit(Monitor *mon, const QDict *qdict);
void hmp_stop(Monitor *mon, const QDict *qdict);
void hmp_system_reset(Monitor *mon, const QDict *qdict);
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index a9b8f53..e4b2358 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -194,6 +194,68 @@ static void virtio_net_set_link_status(NetClientState *nc)
virtio_net_set_status(vdev, vdev->status);
}
+static MacTableInfo *virtio_net_query_mactable(NetClientState *nc)
+{
+ VirtIONet *n = qemu_get_nic_opaque(nc);
+ MacTableInfo *info;
+ strList *str_list = NULL;
+ strList *entry;
+ int i;
+
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup(nc->name);
+
+ info->promisc = n->promisc;
+ info->has_promisc = true;
+ info->allmulti = n->allmulti;
+ info->has_allmulti = true;
+ info->alluni = n->alluni;
+ info->has_alluni = true;
+ info->nomulti = n->nomulti;
+ info->has_nomulti = true;
+ info->nouni = n->nouni;
+ info->has_nouni = true;
+ info->nobcast = n->nobcast;
+ info->has_nobcast = true;
+ info->multi_overflow = n->mac_table.multi_overflow;
+ info->has_multi_overflow = true;
+ info->uni_overflow = n->mac_table.uni_overflow;
+ info->has_uni_overflow = true;
+
+ for (i = 0; i < n->mac_table.first_multi; i++) {
+ info->has_unicast = true;
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = g_strdup_printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
+ n->mac_table.macs[i * ETH_ALEN],
+ n->mac_table.macs[i * ETH_ALEN + 1],
+ n->mac_table.macs[i * ETH_ALEN + 2],
+ n->mac_table.macs[i * ETH_ALEN + 3],
+ n->mac_table.macs[i * ETH_ALEN + 4],
+ n->mac_table.macs[i * ETH_ALEN + 5]);
+ entry->next = str_list;
+ str_list = entry;
+ }
+ info->unicast = str_list;
+
+ str_list = NULL;
+ for (i = n->mac_table.first_multi; i < n->mac_table.in_use; i++) {
+ info->has_multicast = true;
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = g_strdup_printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
+ n->mac_table.macs[i * ETH_ALEN],
+ n->mac_table.macs[i * ETH_ALEN + 1],
+ n->mac_table.macs[i * ETH_ALEN + 2],
+ n->mac_table.macs[i * ETH_ALEN + 3],
+ n->mac_table.macs[i * ETH_ALEN + 4],
+ n->mac_table.macs[i * ETH_ALEN + 5]);
+ entry->next = str_list;
+ str_list = entry;
+ }
+ info->multicast = str_list;
+
+ return info;
+}
+
static void virtio_net_reset(VirtIODevice *vdev)
{
VirtIONet *n = VIRTIO_NET(vdev);
@@ -1255,6 +1317,7 @@ static NetClientInfo net_virtio_info = {
.receive = virtio_net_receive,
.cleanup = virtio_net_cleanup,
.link_status_changed = virtio_net_set_link_status,
+ .query_mac_table = virtio_net_query_mactable,
};
static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
diff --git a/include/net/net.h b/include/net/net.h
index 43d85a1..c3ca4ea 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -49,6 +49,7 @@ typedef ssize_t (NetReceiveIOV)(NetClientState *, const
struct iovec *, int);
typedef void (NetCleanup) (NetClientState *);
typedef void (LinkStatusChanged)(NetClientState *);
typedef void (NetClientDestructor)(NetClientState *);
+typedef MacTableInfo *(QueryMacTable)(NetClientState *);
typedef struct NetClientInfo {
NetClientOptionsKind type;
@@ -59,6 +60,7 @@ typedef struct NetClientInfo {
NetCanReceive *can_receive;
NetCleanup *cleanup;
LinkStatusChanged *link_status_changed;
+ QueryMacTable *query_mac_table;
NetPoll *poll;
} NetClientInfo;
diff --git a/monitor.c b/monitor.c
index 9e51545..a01cdbd 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2765,6 +2765,14 @@ static mon_cmd_t info_cmds[] = {
.mhandler.cmd = hmp_info_tpm,
},
{
+ .name = "mac-table",
+ .args_type = "name:s?",
+ .params = "[net client name]",
+ .help = "show the mac-table information for all nics (or"
+ " for the given nic)",
+ .mhandler.cmd = hmp_info_mac_table,
+ },
+ {
.name = NULL,
},
};
diff --git a/net/net.c b/net/net.c
index 43a74e4..9ff3006 100644
--- a/net/net.c
+++ b/net/net.c
@@ -961,6 +961,44 @@ void print_net_client(Monitor *mon, NetClientState *nc)
nc->info_str);
}
+MacTableInfoList *qmp_query_mac_table(bool has_name, const char *name,
+ Error **errp)
+{
+ NetClientState *nc;
+ MacTableInfoList *table_list = NULL, *last_entry = NULL;
+
+ QTAILQ_FOREACH(nc, &net_clients, next) {
+ MacTableInfoList *entry;
+ MacTableInfo *info;
+
+ if (nc->info->type != NET_CLIENT_OPTIONS_KIND_NIC) {
+ continue;
+ }
+ if (has_name && strcmp(nc->name, name) != 0) {
+ continue;
+ }
+
+ if (nc->info->query_mac_table) {
+ info = nc->info->query_mac_table(nc);
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+
+ if (!table_list) {
+ table_list = entry;
+ } else {
+ last_entry->next = entry;
+ }
+ last_entry = entry;
+ }
+ }
+
+ if (table_list == NULL) {
+ error_setg(errp, "invalid net client name: %s", name);
+ }
+
+ return table_list;
+}
+
void do_info_network(Monitor *mon, const QDict *qdict)
{
NetClientState *nc, *peer;
diff --git a/qapi-schema.json b/qapi-schema.json
index 199744a..866650c 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3619,3 +3619,60 @@
'*cpuid-input-ecx': 'int',
'cpuid-register': 'X86CPURegister32',
'features': 'int' } }
+
+# @MacTableInfo:
+#
+# Rx-mode information of mac-table for a net client.
+#
+# @name: the net client name
+#
+# @promisc: #optional promiscuous mode (default: false)
+#
+# @allmulti: #optional all multicast mode (default: false)
+#
+# @alluni: #optional all unicast mode (default: false)
+#
+# @nomulti: #optional no multicast mode (default: false)
+#
+# @nouni: #optional no unicast mode (default: false)
+#
+# @nobcast: #optional no broadcast mode (default: false)
+#
+# @multi_overflow: #optional multicast overflow mode (default: false)
+#
+# @uni_overflow: #optional unicast overflow mode (default: false)
+#
+# @unicast: #optional a list of unicast macaddr string
+#
+# @multicast: #optional a list of multicast macaddr string
+#
+# Since 1.6
+##
+{ 'type': 'MacTableInfo',
+ 'data': {
+ 'name': 'str',
+ '*promisc': 'bool',
+ '*allmulti': 'bool',
+ '*alluni': 'bool',
+ '*nomulti': 'bool',
+ '*nouni': 'bool',
+ '*nobcast': 'bool',
+ '*multi-overflow': 'bool',
+ '*uni-overflow': 'bool',
+ '*unicast': ['str'],
+ '*multicast': ['str'] }}
+
+##
+# @query-mac-table:
+#
+# Return mac-table information for all nics (or for the given nic).
+#
+# @name: #optional net client name
+#
+# Returns: list of @MacTableInfo for all nics (or for the given nic).
+# Returns an error if the given @name doesn't exist.
+#
+# Since: 1.6
+##
+{ 'command': 'query-mac-table', 'data': { '*name': 'str' },
+ 'returns': ['MacTableInfo'] }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ffd130e..66826ab 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2932,3 +2932,56 @@ Example:
<- { "return": {} }
EQMP
+ {
+ .name = "query-mac-table",
+ .args_type = "name:s?",
+ .mhandler.cmd_new = qmp_marshal_input_query_mac_table,
+ },
+
+SQMP
+query-mac-table
+---------------
+
+Show mac-table information.
+
+Returns a json-array of mac-table information for all nics (or for the
+given nic), returning an error if the given nic doesn't exist.
+
+Each array entry contains the following:
+
+- "name": net client name (jaso-string)
+- "promisc": promiscuous mode (json-bool, optional)
+- "allmulti": all multicast mode (json-bool, optional)
+- "alluni": all unicast mode (json-bool, optional)
+- "nomulti":no multicast mode (json-bool, optional)
+- "nouni": no unicast mode (json-bool, optional)
+- "nobcast": no broadcast mode (json-bool, optional)
+- "multi-overflow": multicast overflow mode (json-bool, optional)
+- "uni-overflow": unicast overflow mode (json-bool, optional)
+- "unicast": a jason-array of unicast macaddr string (optional)
+- "multicast": a jason-array of multicast macaddr string (optional)
+
+Example:
+
+-> { "execute": "query-mac-table", "arguments": { "name": "vnet0" }}
+<- { "return": [
+ {
+ "multi-overflow": false,
+ "name": "vnet0",
+ "uni-overflow": false,
+ "nobcast": false,
+ "promisc": true,
+ "multicast": [
+ "01:00:5e:00:00:01",
+ "33:33:00:00:00:01",
+ "33:33:ff:12:34:56"
+ ],
+ "nouni": false,
+ "nomulti": false,
+ "allmulti": false,
+ "alluni": false
+ }
+ ]
+ }
+
+EQMP
--
1.8.1.4
- Re: [Qemu-devel] [PATCH v2 1/2] net: introduce MAC_TABLE_CHANGED event, (continued)
- Re: [Qemu-devel] [PATCH v2 1/2] net: introduce MAC_TABLE_CHANGED event, Amos Kong, 2013/05/27
- Re: [Qemu-devel] [PATCH v2 1/2] net: introduce MAC_TABLE_CHANGED event, Luiz Capitulino, 2013/05/27
- Re: [Qemu-devel] [PATCH v2 1/2] net: introduce MAC_TABLE_CHANGED event, Luiz Capitulino, 2013/05/27
- Re: [Qemu-devel] [PATCH v2 1/2] net: introduce MAC_TABLE_CHANGED event, Amos Kong, 2013/05/27
- Re: [Qemu-devel] [PATCH v2 1/2] net: introduce MAC_TABLE_CHANGED event, Luiz Capitulino, 2013/05/28
- Re: [Qemu-devel] [PATCH v2 1/2] net: introduce MAC_TABLE_CHANGED event, Amos Kong, 2013/05/21
- Re: [Qemu-devel] [PATCH v2 1/2] net: introduce MAC_TABLE_CHANGED event, Michael S. Tsirkin, 2013/05/21
- Re: [Qemu-devel] [PATCH v2 1/2] net: introduce MAC_TABLE_CHANGED event, Amos Kong, 2013/05/23
Re: [Qemu-devel] [PATCH v2 1/2] net: introduce MAC_TABLE_CHANGED event, Eric Blake, 2013/05/16
[Qemu-devel] [PATCH v2 2/2] net: introduce command to query mac-table information,
Amos Kong <=
Re: [Qemu-devel] [PATCH v2 2/2] net: introduce command to query mac-table information, Jason Wang, 2013/05/29