+/* Dump the megaflow (facet) cache. This is useful to check the
+ * correctness of flow wildcarding, since the same mechanism is used for
+ * both xlate caching and kernel wildcarding.
+ *
+ * It's important to note that in the output the flow description uses
+ * OpenFlow (OFP) ports, but the actions use datapath (ODP) ports.
+ *
+ * This command is only needed for advanced debugging, so it's not
+ * documented in the man page. */
+static void
+ofproto_unixctl_dpif_dump_megaflows(struct unixctl_conn *conn,
+ int argc OVS_UNUSED, const char *argv[],
+ void *aux OVS_UNUSED)
+{
+ struct ds ds = DS_EMPTY_INITIALIZER;
+ const struct ofproto_dpif *ofproto;
+ long long int now = time_msec();
+ struct cls_cursor cursor;
+ struct facet *facet;
+
+ ofproto = ofproto_dpif_lookup(argv[1]);
+ if (!ofproto) {
+ unixctl_command_reply_error(conn, "no such bridge");
+ return;
+ }
+
+ cls_cursor_init(&cursor, &ofproto->facets, NULL);
+ CLS_CURSOR_FOR_EACH (facet, cr, &cursor) {
+ cls_rule_format(&facet->cr, &ds);
+ ds_put_cstr(&ds, ", ");
+ ds_put_format(&ds, "n_subfacets:%"PRIu64", ",
+ list_size(&facet->subfacets));
+ ds_put_format(&ds, "used:%.3fs, ", (now - facet->used) / 1000.0);
+ ds_put_cstr(&ds, "Datapath actions: ");
+ format_odp_actions(&ds, facet->xout.odp_actions.data,
+ facet->xout.odp_actions.size);
+ ds_put_cstr(&ds, "\n");
+ }
+
+ ds_chomp(&ds, '\n');
+ unixctl_command_reply(conn, ds_cstr(&ds));
+ ds_destroy(&ds);
+}
+