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