1*52cafceaSMarkus Armbruster /*
2*52cafceaSMarkus Armbruster * Human Monitor Interface commands
3*52cafceaSMarkus Armbruster *
4*52cafceaSMarkus Armbruster * Copyright IBM, Corp. 2011
5*52cafceaSMarkus Armbruster *
6*52cafceaSMarkus Armbruster * Authors:
7*52cafceaSMarkus Armbruster * Anthony Liguori <aliguori@us.ibm.com>
8*52cafceaSMarkus Armbruster *
9*52cafceaSMarkus Armbruster * This work is licensed under the terms of the GNU GPL, version 2. See
10*52cafceaSMarkus Armbruster * the COPYING file in the top-level directory.
11*52cafceaSMarkus Armbruster *
12*52cafceaSMarkus Armbruster * Contributions after 2012-01-13 are licensed under the terms of the
13*52cafceaSMarkus Armbruster * GNU GPL, version 2 or (at your option) any later version.
14*52cafceaSMarkus Armbruster */
15*52cafceaSMarkus Armbruster
16*52cafceaSMarkus Armbruster #include "qemu/osdep.h"
17*52cafceaSMarkus Armbruster #include "monitor/hmp.h"
18*52cafceaSMarkus Armbruster #include "monitor/monitor.h"
19*52cafceaSMarkus Armbruster #include "net/eth.h"
20*52cafceaSMarkus Armbruster #include "qapi/qapi-commands-rocker.h"
21*52cafceaSMarkus Armbruster #include "qapi/qmp/qdict.h"
22*52cafceaSMarkus Armbruster
hmp_rocker(Monitor * mon,const QDict * qdict)23*52cafceaSMarkus Armbruster void hmp_rocker(Monitor *mon, const QDict *qdict)
24*52cafceaSMarkus Armbruster {
25*52cafceaSMarkus Armbruster const char *name = qdict_get_str(qdict, "name");
26*52cafceaSMarkus Armbruster RockerSwitch *rocker;
27*52cafceaSMarkus Armbruster Error *err = NULL;
28*52cafceaSMarkus Armbruster
29*52cafceaSMarkus Armbruster rocker = qmp_query_rocker(name, &err);
30*52cafceaSMarkus Armbruster if (hmp_handle_error(mon, err)) {
31*52cafceaSMarkus Armbruster return;
32*52cafceaSMarkus Armbruster }
33*52cafceaSMarkus Armbruster
34*52cafceaSMarkus Armbruster monitor_printf(mon, "name: %s\n", rocker->name);
35*52cafceaSMarkus Armbruster monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id);
36*52cafceaSMarkus Armbruster monitor_printf(mon, "ports: %d\n", rocker->ports);
37*52cafceaSMarkus Armbruster
38*52cafceaSMarkus Armbruster qapi_free_RockerSwitch(rocker);
39*52cafceaSMarkus Armbruster }
40*52cafceaSMarkus Armbruster
hmp_rocker_ports(Monitor * mon,const QDict * qdict)41*52cafceaSMarkus Armbruster void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
42*52cafceaSMarkus Armbruster {
43*52cafceaSMarkus Armbruster RockerPortList *list, *port;
44*52cafceaSMarkus Armbruster const char *name = qdict_get_str(qdict, "name");
45*52cafceaSMarkus Armbruster Error *err = NULL;
46*52cafceaSMarkus Armbruster
47*52cafceaSMarkus Armbruster list = qmp_query_rocker_ports(name, &err);
48*52cafceaSMarkus Armbruster if (hmp_handle_error(mon, err)) {
49*52cafceaSMarkus Armbruster return;
50*52cafceaSMarkus Armbruster }
51*52cafceaSMarkus Armbruster
52*52cafceaSMarkus Armbruster monitor_printf(mon, " ena/ speed/ auto\n");
53*52cafceaSMarkus Armbruster monitor_printf(mon, " port link duplex neg?\n");
54*52cafceaSMarkus Armbruster
55*52cafceaSMarkus Armbruster for (port = list; port; port = port->next) {
56*52cafceaSMarkus Armbruster monitor_printf(mon, "%10s %-4s %-3s %2s %s\n",
57*52cafceaSMarkus Armbruster port->value->name,
58*52cafceaSMarkus Armbruster port->value->enabled ? port->value->link_up ?
59*52cafceaSMarkus Armbruster "up" : "down" : "!ena",
60*52cafceaSMarkus Armbruster port->value->speed == 10000 ? "10G" : "??",
61*52cafceaSMarkus Armbruster port->value->duplex ? "FD" : "HD",
62*52cafceaSMarkus Armbruster port->value->autoneg ? "Yes" : "No");
63*52cafceaSMarkus Armbruster }
64*52cafceaSMarkus Armbruster
65*52cafceaSMarkus Armbruster qapi_free_RockerPortList(list);
66*52cafceaSMarkus Armbruster }
67*52cafceaSMarkus Armbruster
hmp_rocker_of_dpa_flows(Monitor * mon,const QDict * qdict)68*52cafceaSMarkus Armbruster void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
69*52cafceaSMarkus Armbruster {
70*52cafceaSMarkus Armbruster RockerOfDpaFlowList *list, *info;
71*52cafceaSMarkus Armbruster const char *name = qdict_get_str(qdict, "name");
72*52cafceaSMarkus Armbruster uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1);
73*52cafceaSMarkus Armbruster Error *err = NULL;
74*52cafceaSMarkus Armbruster
75*52cafceaSMarkus Armbruster list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &err);
76*52cafceaSMarkus Armbruster if (hmp_handle_error(mon, err)) {
77*52cafceaSMarkus Armbruster return;
78*52cafceaSMarkus Armbruster }
79*52cafceaSMarkus Armbruster
80*52cafceaSMarkus Armbruster monitor_printf(mon, "prio tbl hits key(mask) --> actions\n");
81*52cafceaSMarkus Armbruster
82*52cafceaSMarkus Armbruster for (info = list; info; info = info->next) {
83*52cafceaSMarkus Armbruster RockerOfDpaFlow *flow = info->value;
84*52cafceaSMarkus Armbruster RockerOfDpaFlowKey *key = flow->key;
85*52cafceaSMarkus Armbruster RockerOfDpaFlowMask *mask = flow->mask;
86*52cafceaSMarkus Armbruster RockerOfDpaFlowAction *action = flow->action;
87*52cafceaSMarkus Armbruster
88*52cafceaSMarkus Armbruster if (flow->hits) {
89*52cafceaSMarkus Armbruster monitor_printf(mon, "%-4d %-3d %-4" PRIu64,
90*52cafceaSMarkus Armbruster key->priority, key->tbl_id, flow->hits);
91*52cafceaSMarkus Armbruster } else {
92*52cafceaSMarkus Armbruster monitor_printf(mon, "%-4d %-3d ",
93*52cafceaSMarkus Armbruster key->priority, key->tbl_id);
94*52cafceaSMarkus Armbruster }
95*52cafceaSMarkus Armbruster
96*52cafceaSMarkus Armbruster if (key->has_in_pport) {
97*52cafceaSMarkus Armbruster monitor_printf(mon, " pport %d", key->in_pport);
98*52cafceaSMarkus Armbruster if (mask->has_in_pport) {
99*52cafceaSMarkus Armbruster monitor_printf(mon, "(0x%x)", mask->in_pport);
100*52cafceaSMarkus Armbruster }
101*52cafceaSMarkus Armbruster }
102*52cafceaSMarkus Armbruster
103*52cafceaSMarkus Armbruster if (key->has_vlan_id) {
104*52cafceaSMarkus Armbruster monitor_printf(mon, " vlan %d",
105*52cafceaSMarkus Armbruster key->vlan_id & VLAN_VID_MASK);
106*52cafceaSMarkus Armbruster if (mask->has_vlan_id) {
107*52cafceaSMarkus Armbruster monitor_printf(mon, "(0x%x)", mask->vlan_id);
108*52cafceaSMarkus Armbruster }
109*52cafceaSMarkus Armbruster }
110*52cafceaSMarkus Armbruster
111*52cafceaSMarkus Armbruster if (key->has_tunnel_id) {
112*52cafceaSMarkus Armbruster monitor_printf(mon, " tunnel %d", key->tunnel_id);
113*52cafceaSMarkus Armbruster if (mask->has_tunnel_id) {
114*52cafceaSMarkus Armbruster monitor_printf(mon, "(0x%x)", mask->tunnel_id);
115*52cafceaSMarkus Armbruster }
116*52cafceaSMarkus Armbruster }
117*52cafceaSMarkus Armbruster
118*52cafceaSMarkus Armbruster if (key->has_eth_type) {
119*52cafceaSMarkus Armbruster switch (key->eth_type) {
120*52cafceaSMarkus Armbruster case 0x0806:
121*52cafceaSMarkus Armbruster monitor_printf(mon, " ARP");
122*52cafceaSMarkus Armbruster break;
123*52cafceaSMarkus Armbruster case 0x0800:
124*52cafceaSMarkus Armbruster monitor_printf(mon, " IP");
125*52cafceaSMarkus Armbruster break;
126*52cafceaSMarkus Armbruster case 0x86dd:
127*52cafceaSMarkus Armbruster monitor_printf(mon, " IPv6");
128*52cafceaSMarkus Armbruster break;
129*52cafceaSMarkus Armbruster case 0x8809:
130*52cafceaSMarkus Armbruster monitor_printf(mon, " LACP");
131*52cafceaSMarkus Armbruster break;
132*52cafceaSMarkus Armbruster case 0x88cc:
133*52cafceaSMarkus Armbruster monitor_printf(mon, " LLDP");
134*52cafceaSMarkus Armbruster break;
135*52cafceaSMarkus Armbruster default:
136*52cafceaSMarkus Armbruster monitor_printf(mon, " eth type 0x%04x", key->eth_type);
137*52cafceaSMarkus Armbruster break;
138*52cafceaSMarkus Armbruster }
139*52cafceaSMarkus Armbruster }
140*52cafceaSMarkus Armbruster
141*52cafceaSMarkus Armbruster if (key->eth_src) {
142*52cafceaSMarkus Armbruster if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) &&
143*52cafceaSMarkus Armbruster mask->eth_src &&
144*52cafceaSMarkus Armbruster (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
145*52cafceaSMarkus Armbruster monitor_printf(mon, " src <any mcast/bcast>");
146*52cafceaSMarkus Armbruster } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) &&
147*52cafceaSMarkus Armbruster mask->eth_src &&
148*52cafceaSMarkus Armbruster (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
149*52cafceaSMarkus Armbruster monitor_printf(mon, " src <any ucast>");
150*52cafceaSMarkus Armbruster } else {
151*52cafceaSMarkus Armbruster monitor_printf(mon, " src %s", key->eth_src);
152*52cafceaSMarkus Armbruster if (mask->eth_src) {
153*52cafceaSMarkus Armbruster monitor_printf(mon, "(%s)", mask->eth_src);
154*52cafceaSMarkus Armbruster }
155*52cafceaSMarkus Armbruster }
156*52cafceaSMarkus Armbruster }
157*52cafceaSMarkus Armbruster
158*52cafceaSMarkus Armbruster if (key->eth_dst) {
159*52cafceaSMarkus Armbruster if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) &&
160*52cafceaSMarkus Armbruster mask->eth_dst &&
161*52cafceaSMarkus Armbruster (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
162*52cafceaSMarkus Armbruster monitor_printf(mon, " dst <any mcast/bcast>");
163*52cafceaSMarkus Armbruster } else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) &&
164*52cafceaSMarkus Armbruster mask->eth_dst &&
165*52cafceaSMarkus Armbruster (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
166*52cafceaSMarkus Armbruster monitor_printf(mon, " dst <any ucast>");
167*52cafceaSMarkus Armbruster } else {
168*52cafceaSMarkus Armbruster monitor_printf(mon, " dst %s", key->eth_dst);
169*52cafceaSMarkus Armbruster if (mask->eth_dst) {
170*52cafceaSMarkus Armbruster monitor_printf(mon, "(%s)", mask->eth_dst);
171*52cafceaSMarkus Armbruster }
172*52cafceaSMarkus Armbruster }
173*52cafceaSMarkus Armbruster }
174*52cafceaSMarkus Armbruster
175*52cafceaSMarkus Armbruster if (key->has_ip_proto) {
176*52cafceaSMarkus Armbruster monitor_printf(mon, " proto %d", key->ip_proto);
177*52cafceaSMarkus Armbruster if (mask->has_ip_proto) {
178*52cafceaSMarkus Armbruster monitor_printf(mon, "(0x%x)", mask->ip_proto);
179*52cafceaSMarkus Armbruster }
180*52cafceaSMarkus Armbruster }
181*52cafceaSMarkus Armbruster
182*52cafceaSMarkus Armbruster if (key->has_ip_tos) {
183*52cafceaSMarkus Armbruster monitor_printf(mon, " TOS %d", key->ip_tos);
184*52cafceaSMarkus Armbruster if (mask->has_ip_tos) {
185*52cafceaSMarkus Armbruster monitor_printf(mon, "(0x%x)", mask->ip_tos);
186*52cafceaSMarkus Armbruster }
187*52cafceaSMarkus Armbruster }
188*52cafceaSMarkus Armbruster
189*52cafceaSMarkus Armbruster if (key->ip_dst) {
190*52cafceaSMarkus Armbruster monitor_printf(mon, " dst %s", key->ip_dst);
191*52cafceaSMarkus Armbruster }
192*52cafceaSMarkus Armbruster
193*52cafceaSMarkus Armbruster if (action->has_goto_tbl || action->has_group_id ||
194*52cafceaSMarkus Armbruster action->has_new_vlan_id) {
195*52cafceaSMarkus Armbruster monitor_printf(mon, " -->");
196*52cafceaSMarkus Armbruster }
197*52cafceaSMarkus Armbruster
198*52cafceaSMarkus Armbruster if (action->has_new_vlan_id) {
199*52cafceaSMarkus Armbruster monitor_printf(mon, " apply new vlan %d",
200*52cafceaSMarkus Armbruster ntohs(action->new_vlan_id));
201*52cafceaSMarkus Armbruster }
202*52cafceaSMarkus Armbruster
203*52cafceaSMarkus Armbruster if (action->has_group_id) {
204*52cafceaSMarkus Armbruster monitor_printf(mon, " write group 0x%08x", action->group_id);
205*52cafceaSMarkus Armbruster }
206*52cafceaSMarkus Armbruster
207*52cafceaSMarkus Armbruster if (action->has_goto_tbl) {
208*52cafceaSMarkus Armbruster monitor_printf(mon, " goto tbl %d", action->goto_tbl);
209*52cafceaSMarkus Armbruster }
210*52cafceaSMarkus Armbruster
211*52cafceaSMarkus Armbruster monitor_printf(mon, "\n");
212*52cafceaSMarkus Armbruster }
213*52cafceaSMarkus Armbruster
214*52cafceaSMarkus Armbruster qapi_free_RockerOfDpaFlowList(list);
215*52cafceaSMarkus Armbruster }
216*52cafceaSMarkus Armbruster
hmp_rocker_of_dpa_groups(Monitor * mon,const QDict * qdict)217*52cafceaSMarkus Armbruster void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
218*52cafceaSMarkus Armbruster {
219*52cafceaSMarkus Armbruster RockerOfDpaGroupList *list, *g;
220*52cafceaSMarkus Armbruster const char *name = qdict_get_str(qdict, "name");
221*52cafceaSMarkus Armbruster uint8_t type = qdict_get_try_int(qdict, "type", 9);
222*52cafceaSMarkus Armbruster Error *err = NULL;
223*52cafceaSMarkus Armbruster
224*52cafceaSMarkus Armbruster list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err);
225*52cafceaSMarkus Armbruster if (hmp_handle_error(mon, err)) {
226*52cafceaSMarkus Armbruster return;
227*52cafceaSMarkus Armbruster }
228*52cafceaSMarkus Armbruster
229*52cafceaSMarkus Armbruster monitor_printf(mon, "id (decode) --> buckets\n");
230*52cafceaSMarkus Armbruster
231*52cafceaSMarkus Armbruster for (g = list; g; g = g->next) {
232*52cafceaSMarkus Armbruster RockerOfDpaGroup *group = g->value;
233*52cafceaSMarkus Armbruster bool set = false;
234*52cafceaSMarkus Armbruster
235*52cafceaSMarkus Armbruster monitor_printf(mon, "0x%08x", group->id);
236*52cafceaSMarkus Armbruster
237*52cafceaSMarkus Armbruster monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" :
238*52cafceaSMarkus Armbruster group->type == 1 ? "L2 rewrite" :
239*52cafceaSMarkus Armbruster group->type == 2 ? "L3 unicast" :
240*52cafceaSMarkus Armbruster group->type == 3 ? "L2 multicast" :
241*52cafceaSMarkus Armbruster group->type == 4 ? "L2 flood" :
242*52cafceaSMarkus Armbruster group->type == 5 ? "L3 interface" :
243*52cafceaSMarkus Armbruster group->type == 6 ? "L3 multicast" :
244*52cafceaSMarkus Armbruster group->type == 7 ? "L3 ECMP" :
245*52cafceaSMarkus Armbruster group->type == 8 ? "L2 overlay" :
246*52cafceaSMarkus Armbruster "unknown");
247*52cafceaSMarkus Armbruster
248*52cafceaSMarkus Armbruster if (group->has_vlan_id) {
249*52cafceaSMarkus Armbruster monitor_printf(mon, " vlan %d", group->vlan_id);
250*52cafceaSMarkus Armbruster }
251*52cafceaSMarkus Armbruster
252*52cafceaSMarkus Armbruster if (group->has_pport) {
253*52cafceaSMarkus Armbruster monitor_printf(mon, " pport %d", group->pport);
254*52cafceaSMarkus Armbruster }
255*52cafceaSMarkus Armbruster
256*52cafceaSMarkus Armbruster if (group->has_index) {
257*52cafceaSMarkus Armbruster monitor_printf(mon, " index %d", group->index);
258*52cafceaSMarkus Armbruster }
259*52cafceaSMarkus Armbruster
260*52cafceaSMarkus Armbruster monitor_printf(mon, ") -->");
261*52cafceaSMarkus Armbruster
262*52cafceaSMarkus Armbruster if (group->has_set_vlan_id && group->set_vlan_id) {
263*52cafceaSMarkus Armbruster set = true;
264*52cafceaSMarkus Armbruster monitor_printf(mon, " set vlan %d",
265*52cafceaSMarkus Armbruster group->set_vlan_id & VLAN_VID_MASK);
266*52cafceaSMarkus Armbruster }
267*52cafceaSMarkus Armbruster
268*52cafceaSMarkus Armbruster if (group->set_eth_src) {
269*52cafceaSMarkus Armbruster if (!set) {
270*52cafceaSMarkus Armbruster set = true;
271*52cafceaSMarkus Armbruster monitor_printf(mon, " set");
272*52cafceaSMarkus Armbruster }
273*52cafceaSMarkus Armbruster monitor_printf(mon, " src %s", group->set_eth_src);
274*52cafceaSMarkus Armbruster }
275*52cafceaSMarkus Armbruster
276*52cafceaSMarkus Armbruster if (group->set_eth_dst) {
277*52cafceaSMarkus Armbruster if (!set) {
278*52cafceaSMarkus Armbruster monitor_printf(mon, " set");
279*52cafceaSMarkus Armbruster }
280*52cafceaSMarkus Armbruster monitor_printf(mon, " dst %s", group->set_eth_dst);
281*52cafceaSMarkus Armbruster }
282*52cafceaSMarkus Armbruster
283*52cafceaSMarkus Armbruster if (group->has_ttl_check && group->ttl_check) {
284*52cafceaSMarkus Armbruster monitor_printf(mon, " check TTL");
285*52cafceaSMarkus Armbruster }
286*52cafceaSMarkus Armbruster
287*52cafceaSMarkus Armbruster if (group->has_group_id && group->group_id) {
288*52cafceaSMarkus Armbruster monitor_printf(mon, " group id 0x%08x", group->group_id);
289*52cafceaSMarkus Armbruster }
290*52cafceaSMarkus Armbruster
291*52cafceaSMarkus Armbruster if (group->has_pop_vlan && group->pop_vlan) {
292*52cafceaSMarkus Armbruster monitor_printf(mon, " pop vlan");
293*52cafceaSMarkus Armbruster }
294*52cafceaSMarkus Armbruster
295*52cafceaSMarkus Armbruster if (group->has_out_pport) {
296*52cafceaSMarkus Armbruster monitor_printf(mon, " out pport %d", group->out_pport);
297*52cafceaSMarkus Armbruster }
298*52cafceaSMarkus Armbruster
299*52cafceaSMarkus Armbruster if (group->has_group_ids) {
300*52cafceaSMarkus Armbruster struct uint32List *id;
301*52cafceaSMarkus Armbruster
302*52cafceaSMarkus Armbruster monitor_printf(mon, " groups [");
303*52cafceaSMarkus Armbruster for (id = group->group_ids; id; id = id->next) {
304*52cafceaSMarkus Armbruster monitor_printf(mon, "0x%08x", id->value);
305*52cafceaSMarkus Armbruster if (id->next) {
306*52cafceaSMarkus Armbruster monitor_printf(mon, ",");
307*52cafceaSMarkus Armbruster }
308*52cafceaSMarkus Armbruster }
309*52cafceaSMarkus Armbruster monitor_printf(mon, "]");
310*52cafceaSMarkus Armbruster }
311*52cafceaSMarkus Armbruster
312*52cafceaSMarkus Armbruster monitor_printf(mon, "\n");
313*52cafceaSMarkus Armbruster }
314*52cafceaSMarkus Armbruster
315*52cafceaSMarkus Armbruster qapi_free_RockerOfDpaGroupList(list);
316*52cafceaSMarkus Armbruster }
317