152cafceaSMarkus Armbruster /*
252cafceaSMarkus Armbruster * Human Monitor Interface commands
352cafceaSMarkus Armbruster *
452cafceaSMarkus Armbruster * Copyright IBM, Corp. 2011
552cafceaSMarkus Armbruster *
652cafceaSMarkus Armbruster * Authors:
752cafceaSMarkus Armbruster * Anthony Liguori <aliguori@us.ibm.com>
852cafceaSMarkus Armbruster *
952cafceaSMarkus Armbruster * This work is licensed under the terms of the GNU GPL, version 2. See
1052cafceaSMarkus Armbruster * the COPYING file in the top-level directory.
1152cafceaSMarkus Armbruster *
1252cafceaSMarkus Armbruster * Contributions after 2012-01-13 are licensed under the terms of the
1352cafceaSMarkus Armbruster * GNU GPL, version 2 or (at your option) any later version.
1452cafceaSMarkus Armbruster */
1552cafceaSMarkus Armbruster
1652cafceaSMarkus Armbruster #include "qemu/osdep.h"
1752cafceaSMarkus Armbruster #include "monitor/hmp.h"
1852cafceaSMarkus Armbruster #include "monitor/monitor.h"
1952cafceaSMarkus Armbruster #include "net/eth.h"
2052cafceaSMarkus Armbruster #include "qapi/qapi-commands-rocker.h"
21*407bc4bfSDaniel P. Berrangé #include "qobject/qdict.h"
2252cafceaSMarkus Armbruster
hmp_rocker(Monitor * mon,const QDict * qdict)2352cafceaSMarkus Armbruster void hmp_rocker(Monitor *mon, const QDict *qdict)
2452cafceaSMarkus Armbruster {
2552cafceaSMarkus Armbruster const char *name = qdict_get_str(qdict, "name");
2652cafceaSMarkus Armbruster RockerSwitch *rocker;
2752cafceaSMarkus Armbruster Error *err = NULL;
2852cafceaSMarkus Armbruster
2952cafceaSMarkus Armbruster rocker = qmp_query_rocker(name, &err);
3052cafceaSMarkus Armbruster if (hmp_handle_error(mon, err)) {
3152cafceaSMarkus Armbruster return;
3252cafceaSMarkus Armbruster }
3352cafceaSMarkus Armbruster
3452cafceaSMarkus Armbruster monitor_printf(mon, "name: %s\n", rocker->name);
3552cafceaSMarkus Armbruster monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id);
3652cafceaSMarkus Armbruster monitor_printf(mon, "ports: %d\n", rocker->ports);
3752cafceaSMarkus Armbruster
3852cafceaSMarkus Armbruster qapi_free_RockerSwitch(rocker);
3952cafceaSMarkus Armbruster }
4052cafceaSMarkus Armbruster
hmp_rocker_ports(Monitor * mon,const QDict * qdict)4152cafceaSMarkus Armbruster void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
4252cafceaSMarkus Armbruster {
4352cafceaSMarkus Armbruster RockerPortList *list, *port;
4452cafceaSMarkus Armbruster const char *name = qdict_get_str(qdict, "name");
4552cafceaSMarkus Armbruster Error *err = NULL;
4652cafceaSMarkus Armbruster
4752cafceaSMarkus Armbruster list = qmp_query_rocker_ports(name, &err);
4852cafceaSMarkus Armbruster if (hmp_handle_error(mon, err)) {
4952cafceaSMarkus Armbruster return;
5052cafceaSMarkus Armbruster }
5152cafceaSMarkus Armbruster
5252cafceaSMarkus Armbruster monitor_printf(mon, " ena/ speed/ auto\n");
5352cafceaSMarkus Armbruster monitor_printf(mon, " port link duplex neg?\n");
5452cafceaSMarkus Armbruster
5552cafceaSMarkus Armbruster for (port = list; port; port = port->next) {
5652cafceaSMarkus Armbruster monitor_printf(mon, "%10s %-4s %-3s %2s %s\n",
5752cafceaSMarkus Armbruster port->value->name,
5852cafceaSMarkus Armbruster port->value->enabled ? port->value->link_up ?
5952cafceaSMarkus Armbruster "up" : "down" : "!ena",
6052cafceaSMarkus Armbruster port->value->speed == 10000 ? "10G" : "??",
6152cafceaSMarkus Armbruster port->value->duplex ? "FD" : "HD",
6252cafceaSMarkus Armbruster port->value->autoneg ? "Yes" : "No");
6352cafceaSMarkus Armbruster }
6452cafceaSMarkus Armbruster
6552cafceaSMarkus Armbruster qapi_free_RockerPortList(list);
6652cafceaSMarkus Armbruster }
6752cafceaSMarkus Armbruster
hmp_rocker_of_dpa_flows(Monitor * mon,const QDict * qdict)6852cafceaSMarkus Armbruster void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
6952cafceaSMarkus Armbruster {
7052cafceaSMarkus Armbruster RockerOfDpaFlowList *list, *info;
7152cafceaSMarkus Armbruster const char *name = qdict_get_str(qdict, "name");
7252cafceaSMarkus Armbruster uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1);
7352cafceaSMarkus Armbruster Error *err = NULL;
7452cafceaSMarkus Armbruster
7552cafceaSMarkus Armbruster list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &err);
7652cafceaSMarkus Armbruster if (hmp_handle_error(mon, err)) {
7752cafceaSMarkus Armbruster return;
7852cafceaSMarkus Armbruster }
7952cafceaSMarkus Armbruster
8052cafceaSMarkus Armbruster monitor_printf(mon, "prio tbl hits key(mask) --> actions\n");
8152cafceaSMarkus Armbruster
8252cafceaSMarkus Armbruster for (info = list; info; info = info->next) {
8352cafceaSMarkus Armbruster RockerOfDpaFlow *flow = info->value;
8452cafceaSMarkus Armbruster RockerOfDpaFlowKey *key = flow->key;
8552cafceaSMarkus Armbruster RockerOfDpaFlowMask *mask = flow->mask;
8652cafceaSMarkus Armbruster RockerOfDpaFlowAction *action = flow->action;
8752cafceaSMarkus Armbruster
8852cafceaSMarkus Armbruster if (flow->hits) {
8952cafceaSMarkus Armbruster monitor_printf(mon, "%-4d %-3d %-4" PRIu64,
9052cafceaSMarkus Armbruster key->priority, key->tbl_id, flow->hits);
9152cafceaSMarkus Armbruster } else {
9252cafceaSMarkus Armbruster monitor_printf(mon, "%-4d %-3d ",
9352cafceaSMarkus Armbruster key->priority, key->tbl_id);
9452cafceaSMarkus Armbruster }
9552cafceaSMarkus Armbruster
9652cafceaSMarkus Armbruster if (key->has_in_pport) {
9752cafceaSMarkus Armbruster monitor_printf(mon, " pport %d", key->in_pport);
9852cafceaSMarkus Armbruster if (mask->has_in_pport) {
9952cafceaSMarkus Armbruster monitor_printf(mon, "(0x%x)", mask->in_pport);
10052cafceaSMarkus Armbruster }
10152cafceaSMarkus Armbruster }
10252cafceaSMarkus Armbruster
10352cafceaSMarkus Armbruster if (key->has_vlan_id) {
10452cafceaSMarkus Armbruster monitor_printf(mon, " vlan %d",
10552cafceaSMarkus Armbruster key->vlan_id & VLAN_VID_MASK);
10652cafceaSMarkus Armbruster if (mask->has_vlan_id) {
10752cafceaSMarkus Armbruster monitor_printf(mon, "(0x%x)", mask->vlan_id);
10852cafceaSMarkus Armbruster }
10952cafceaSMarkus Armbruster }
11052cafceaSMarkus Armbruster
11152cafceaSMarkus Armbruster if (key->has_tunnel_id) {
11252cafceaSMarkus Armbruster monitor_printf(mon, " tunnel %d", key->tunnel_id);
11352cafceaSMarkus Armbruster if (mask->has_tunnel_id) {
11452cafceaSMarkus Armbruster monitor_printf(mon, "(0x%x)", mask->tunnel_id);
11552cafceaSMarkus Armbruster }
11652cafceaSMarkus Armbruster }
11752cafceaSMarkus Armbruster
11852cafceaSMarkus Armbruster if (key->has_eth_type) {
11952cafceaSMarkus Armbruster switch (key->eth_type) {
12052cafceaSMarkus Armbruster case 0x0806:
12152cafceaSMarkus Armbruster monitor_printf(mon, " ARP");
12252cafceaSMarkus Armbruster break;
12352cafceaSMarkus Armbruster case 0x0800:
12452cafceaSMarkus Armbruster monitor_printf(mon, " IP");
12552cafceaSMarkus Armbruster break;
12652cafceaSMarkus Armbruster case 0x86dd:
12752cafceaSMarkus Armbruster monitor_printf(mon, " IPv6");
12852cafceaSMarkus Armbruster break;
12952cafceaSMarkus Armbruster case 0x8809:
13052cafceaSMarkus Armbruster monitor_printf(mon, " LACP");
13152cafceaSMarkus Armbruster break;
13252cafceaSMarkus Armbruster case 0x88cc:
13352cafceaSMarkus Armbruster monitor_printf(mon, " LLDP");
13452cafceaSMarkus Armbruster break;
13552cafceaSMarkus Armbruster default:
13652cafceaSMarkus Armbruster monitor_printf(mon, " eth type 0x%04x", key->eth_type);
13752cafceaSMarkus Armbruster break;
13852cafceaSMarkus Armbruster }
13952cafceaSMarkus Armbruster }
14052cafceaSMarkus Armbruster
14152cafceaSMarkus Armbruster if (key->eth_src) {
14252cafceaSMarkus Armbruster if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) &&
14352cafceaSMarkus Armbruster mask->eth_src &&
14452cafceaSMarkus Armbruster (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
14552cafceaSMarkus Armbruster monitor_printf(mon, " src <any mcast/bcast>");
14652cafceaSMarkus Armbruster } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) &&
14752cafceaSMarkus Armbruster mask->eth_src &&
14852cafceaSMarkus Armbruster (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
14952cafceaSMarkus Armbruster monitor_printf(mon, " src <any ucast>");
15052cafceaSMarkus Armbruster } else {
15152cafceaSMarkus Armbruster monitor_printf(mon, " src %s", key->eth_src);
15252cafceaSMarkus Armbruster if (mask->eth_src) {
15352cafceaSMarkus Armbruster monitor_printf(mon, "(%s)", mask->eth_src);
15452cafceaSMarkus Armbruster }
15552cafceaSMarkus Armbruster }
15652cafceaSMarkus Armbruster }
15752cafceaSMarkus Armbruster
15852cafceaSMarkus Armbruster if (key->eth_dst) {
15952cafceaSMarkus Armbruster if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) &&
16052cafceaSMarkus Armbruster mask->eth_dst &&
16152cafceaSMarkus Armbruster (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
16252cafceaSMarkus Armbruster monitor_printf(mon, " dst <any mcast/bcast>");
16352cafceaSMarkus Armbruster } else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) &&
16452cafceaSMarkus Armbruster mask->eth_dst &&
16552cafceaSMarkus Armbruster (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
16652cafceaSMarkus Armbruster monitor_printf(mon, " dst <any ucast>");
16752cafceaSMarkus Armbruster } else {
16852cafceaSMarkus Armbruster monitor_printf(mon, " dst %s", key->eth_dst);
16952cafceaSMarkus Armbruster if (mask->eth_dst) {
17052cafceaSMarkus Armbruster monitor_printf(mon, "(%s)", mask->eth_dst);
17152cafceaSMarkus Armbruster }
17252cafceaSMarkus Armbruster }
17352cafceaSMarkus Armbruster }
17452cafceaSMarkus Armbruster
17552cafceaSMarkus Armbruster if (key->has_ip_proto) {
17652cafceaSMarkus Armbruster monitor_printf(mon, " proto %d", key->ip_proto);
17752cafceaSMarkus Armbruster if (mask->has_ip_proto) {
17852cafceaSMarkus Armbruster monitor_printf(mon, "(0x%x)", mask->ip_proto);
17952cafceaSMarkus Armbruster }
18052cafceaSMarkus Armbruster }
18152cafceaSMarkus Armbruster
18252cafceaSMarkus Armbruster if (key->has_ip_tos) {
18352cafceaSMarkus Armbruster monitor_printf(mon, " TOS %d", key->ip_tos);
18452cafceaSMarkus Armbruster if (mask->has_ip_tos) {
18552cafceaSMarkus Armbruster monitor_printf(mon, "(0x%x)", mask->ip_tos);
18652cafceaSMarkus Armbruster }
18752cafceaSMarkus Armbruster }
18852cafceaSMarkus Armbruster
18952cafceaSMarkus Armbruster if (key->ip_dst) {
19052cafceaSMarkus Armbruster monitor_printf(mon, " dst %s", key->ip_dst);
19152cafceaSMarkus Armbruster }
19252cafceaSMarkus Armbruster
19352cafceaSMarkus Armbruster if (action->has_goto_tbl || action->has_group_id ||
19452cafceaSMarkus Armbruster action->has_new_vlan_id) {
19552cafceaSMarkus Armbruster monitor_printf(mon, " -->");
19652cafceaSMarkus Armbruster }
19752cafceaSMarkus Armbruster
19852cafceaSMarkus Armbruster if (action->has_new_vlan_id) {
19952cafceaSMarkus Armbruster monitor_printf(mon, " apply new vlan %d",
20052cafceaSMarkus Armbruster ntohs(action->new_vlan_id));
20152cafceaSMarkus Armbruster }
20252cafceaSMarkus Armbruster
20352cafceaSMarkus Armbruster if (action->has_group_id) {
20452cafceaSMarkus Armbruster monitor_printf(mon, " write group 0x%08x", action->group_id);
20552cafceaSMarkus Armbruster }
20652cafceaSMarkus Armbruster
20752cafceaSMarkus Armbruster if (action->has_goto_tbl) {
20852cafceaSMarkus Armbruster monitor_printf(mon, " goto tbl %d", action->goto_tbl);
20952cafceaSMarkus Armbruster }
21052cafceaSMarkus Armbruster
21152cafceaSMarkus Armbruster monitor_printf(mon, "\n");
21252cafceaSMarkus Armbruster }
21352cafceaSMarkus Armbruster
21452cafceaSMarkus Armbruster qapi_free_RockerOfDpaFlowList(list);
21552cafceaSMarkus Armbruster }
21652cafceaSMarkus Armbruster
hmp_rocker_of_dpa_groups(Monitor * mon,const QDict * qdict)21752cafceaSMarkus Armbruster void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
21852cafceaSMarkus Armbruster {
21952cafceaSMarkus Armbruster RockerOfDpaGroupList *list, *g;
22052cafceaSMarkus Armbruster const char *name = qdict_get_str(qdict, "name");
22152cafceaSMarkus Armbruster uint8_t type = qdict_get_try_int(qdict, "type", 9);
22252cafceaSMarkus Armbruster Error *err = NULL;
22352cafceaSMarkus Armbruster
22452cafceaSMarkus Armbruster list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err);
22552cafceaSMarkus Armbruster if (hmp_handle_error(mon, err)) {
22652cafceaSMarkus Armbruster return;
22752cafceaSMarkus Armbruster }
22852cafceaSMarkus Armbruster
22952cafceaSMarkus Armbruster monitor_printf(mon, "id (decode) --> buckets\n");
23052cafceaSMarkus Armbruster
23152cafceaSMarkus Armbruster for (g = list; g; g = g->next) {
23252cafceaSMarkus Armbruster RockerOfDpaGroup *group = g->value;
23352cafceaSMarkus Armbruster bool set = false;
23452cafceaSMarkus Armbruster
23552cafceaSMarkus Armbruster monitor_printf(mon, "0x%08x", group->id);
23652cafceaSMarkus Armbruster
23752cafceaSMarkus Armbruster monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" :
23852cafceaSMarkus Armbruster group->type == 1 ? "L2 rewrite" :
23952cafceaSMarkus Armbruster group->type == 2 ? "L3 unicast" :
24052cafceaSMarkus Armbruster group->type == 3 ? "L2 multicast" :
24152cafceaSMarkus Armbruster group->type == 4 ? "L2 flood" :
24252cafceaSMarkus Armbruster group->type == 5 ? "L3 interface" :
24352cafceaSMarkus Armbruster group->type == 6 ? "L3 multicast" :
24452cafceaSMarkus Armbruster group->type == 7 ? "L3 ECMP" :
24552cafceaSMarkus Armbruster group->type == 8 ? "L2 overlay" :
24652cafceaSMarkus Armbruster "unknown");
24752cafceaSMarkus Armbruster
24852cafceaSMarkus Armbruster if (group->has_vlan_id) {
24952cafceaSMarkus Armbruster monitor_printf(mon, " vlan %d", group->vlan_id);
25052cafceaSMarkus Armbruster }
25152cafceaSMarkus Armbruster
25252cafceaSMarkus Armbruster if (group->has_pport) {
25352cafceaSMarkus Armbruster monitor_printf(mon, " pport %d", group->pport);
25452cafceaSMarkus Armbruster }
25552cafceaSMarkus Armbruster
25652cafceaSMarkus Armbruster if (group->has_index) {
25752cafceaSMarkus Armbruster monitor_printf(mon, " index %d", group->index);
25852cafceaSMarkus Armbruster }
25952cafceaSMarkus Armbruster
26052cafceaSMarkus Armbruster monitor_printf(mon, ") -->");
26152cafceaSMarkus Armbruster
26252cafceaSMarkus Armbruster if (group->has_set_vlan_id && group->set_vlan_id) {
26352cafceaSMarkus Armbruster set = true;
26452cafceaSMarkus Armbruster monitor_printf(mon, " set vlan %d",
26552cafceaSMarkus Armbruster group->set_vlan_id & VLAN_VID_MASK);
26652cafceaSMarkus Armbruster }
26752cafceaSMarkus Armbruster
26852cafceaSMarkus Armbruster if (group->set_eth_src) {
26952cafceaSMarkus Armbruster if (!set) {
27052cafceaSMarkus Armbruster set = true;
27152cafceaSMarkus Armbruster monitor_printf(mon, " set");
27252cafceaSMarkus Armbruster }
27352cafceaSMarkus Armbruster monitor_printf(mon, " src %s", group->set_eth_src);
27452cafceaSMarkus Armbruster }
27552cafceaSMarkus Armbruster
27652cafceaSMarkus Armbruster if (group->set_eth_dst) {
27752cafceaSMarkus Armbruster if (!set) {
27852cafceaSMarkus Armbruster monitor_printf(mon, " set");
27952cafceaSMarkus Armbruster }
28052cafceaSMarkus Armbruster monitor_printf(mon, " dst %s", group->set_eth_dst);
28152cafceaSMarkus Armbruster }
28252cafceaSMarkus Armbruster
28352cafceaSMarkus Armbruster if (group->has_ttl_check && group->ttl_check) {
28452cafceaSMarkus Armbruster monitor_printf(mon, " check TTL");
28552cafceaSMarkus Armbruster }
28652cafceaSMarkus Armbruster
28752cafceaSMarkus Armbruster if (group->has_group_id && group->group_id) {
28852cafceaSMarkus Armbruster monitor_printf(mon, " group id 0x%08x", group->group_id);
28952cafceaSMarkus Armbruster }
29052cafceaSMarkus Armbruster
29152cafceaSMarkus Armbruster if (group->has_pop_vlan && group->pop_vlan) {
29252cafceaSMarkus Armbruster monitor_printf(mon, " pop vlan");
29352cafceaSMarkus Armbruster }
29452cafceaSMarkus Armbruster
29552cafceaSMarkus Armbruster if (group->has_out_pport) {
29652cafceaSMarkus Armbruster monitor_printf(mon, " out pport %d", group->out_pport);
29752cafceaSMarkus Armbruster }
29852cafceaSMarkus Armbruster
29952cafceaSMarkus Armbruster if (group->has_group_ids) {
30052cafceaSMarkus Armbruster struct uint32List *id;
30152cafceaSMarkus Armbruster
30252cafceaSMarkus Armbruster monitor_printf(mon, " groups [");
30352cafceaSMarkus Armbruster for (id = group->group_ids; id; id = id->next) {
30452cafceaSMarkus Armbruster monitor_printf(mon, "0x%08x", id->value);
30552cafceaSMarkus Armbruster if (id->next) {
30652cafceaSMarkus Armbruster monitor_printf(mon, ",");
30752cafceaSMarkus Armbruster }
30852cafceaSMarkus Armbruster }
30952cafceaSMarkus Armbruster monitor_printf(mon, "]");
31052cafceaSMarkus Armbruster }
31152cafceaSMarkus Armbruster
31252cafceaSMarkus Armbruster monitor_printf(mon, "\n");
31352cafceaSMarkus Armbruster }
31452cafceaSMarkus Armbruster
31552cafceaSMarkus Armbruster qapi_free_RockerOfDpaGroupList(list);
31652cafceaSMarkus Armbruster }
317