rocker-hmp-cmds.c 9.9 KB

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