xref: /openbmc/qemu/hw/net/rocker/rocker-hmp-cmds.c (revision 2cfb3b6c)
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 
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 
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 
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 
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