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