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 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 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 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 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