return error;
}
-/* Parses 'datapath name', which is of the form type@name into its
- * component pieces. 'name' and 'type' must be freed by the caller. */
+/* Parses 'datapath_name_', which is of the form [type@]name into its
+ * component pieces. 'name' and 'type' must be freed by the caller.
+ *
+ * The returned 'type' is normalized, as if by dpif_normalize_type(). */
void
dp_parse_name(const char *datapath_name_, char **name, char **type)
{
if (separator) {
*separator = '\0';
*type = datapath_name;
- *name = xstrdup(separator + 1);
+ *name = xstrdup(dpif_normalize_type(separator + 1));
} else {
*name = datapath_name;
- *type = NULL;
+ *type = xstrdup(dpif_normalize_type(NULL));
}
}
dst->name = xstrdup(src->name);
dst->type = xstrdup(src->type);
dst->port_no = src->port_no;
+ dst->stats = src->stats;
}
/* Frees memory allocated to members of 'dpif_port'.
}
/* Causes 'dpif' to perform the 'actions_len' bytes of actions in 'actions' on
- * the Ethernet frame specified in 'packet'.
+ * the Ethernet frame specified in 'packet' taken from the flow specified in
+ * the 'key_len' bytes of 'key'. ('key' is mostly redundant with 'packet', but
+ * it contains some metadata that cannot be recovered from 'packet', such as
+ * tun_id and in_port.)
*
* Returns 0 if successful, otherwise a positive errno value. */
int
dpif_execute(struct dpif *dpif,
+ const struct nlattr *key, size_t key_len,
const struct nlattr *actions, size_t actions_len,
const struct ofpbuf *buf)
{
COVERAGE_INC(dpif_execute);
if (actions_len > 0) {
- error = dpif->dpif_class->execute(dpif, actions, actions_len, buf);
+ error = dpif->dpif_class->execute(dpif, key, key_len,
+ actions, actions_len, buf);
} else {
error = 0;
}
return error;
}
+/* Returns a string that represents 'type', for use in log messages. */
+const char *
+dpif_upcall_type_to_string(enum dpif_upcall_type type)
+{
+ switch (type) {
+ case DPIF_UC_MISS: return "miss";
+ case DPIF_UC_ACTION: return "action";
+ case DPIF_UC_SAMPLE: return "sample";
+ case DPIF_N_UC_TYPES: default: return "<unknown>";
+ }
+}
+
static bool OVS_UNUSED
is_valid_listen_mask(int listen_mask)
{
{
int error = dpif->dpif_class->recv(dpif, upcall);
if (!error && !VLOG_DROP_DBG(&dpmsg_rl)) {
- struct flow flow;
- char *s;
-
- s = ofp_packet_to_string(upcall->packet->data,
- upcall->packet->size, upcall->packet->size);
- odp_flow_key_to_flow(upcall->key, upcall->key_len, &flow);
-
- VLOG_DBG("%s: %s upcall on port %"PRIu16": %s", dpif_name(dpif),
- (upcall->type == DPIF_UC_MISS ? "miss"
- : upcall->type == DPIF_UC_ACTION ? "action"
- : upcall->type == DPIF_UC_SAMPLE ? "sample"
- : "<unknown>"),
- flow.in_port, s);
- free(s);
+ struct ds flow;
+ char *packet;
+
+ packet = ofp_packet_to_string(upcall->packet->data,
+ upcall->packet->size,
+ upcall->packet->size);
+
+ ds_init(&flow);
+ odp_flow_key_format(upcall->key, upcall->key_len, &flow);
+
+ VLOG_DBG("%s: %s upcall:\n%s\n%s",
+ dpif_name(dpif), dpif_upcall_type_to_string(upcall->type),
+ ds_cstr(&flow), packet);
+
+ ds_destroy(&flow);
+ free(packet);
}
return error;
}