+/* Executes, within 'ofproto', the 'n_actions' actions in 'actions' on
+ * 'packet', which arrived on 'in_port'.
+ *
+ * Takes ownership of 'packet'. */
+static bool
+execute_odp_actions(struct ofproto *ofproto, uint16_t in_port,
+ const union odp_action *actions, size_t n_actions,
+ struct ofpbuf *packet)
+{
+ if (n_actions == 1 && actions[0].type == ODPAT_CONTROLLER) {
+ /* As an optimization, avoid a round-trip from userspace to kernel to
+ * userspace. This also avoids possibly filling up kernel packet
+ * buffers along the way. */
+ struct odp_msg *msg;
+
+ msg = ofpbuf_push_uninit(packet, sizeof *msg);
+ msg->type = _ODPL_ACTION_NR;
+ msg->length = sizeof(struct odp_msg) + packet->size;
+ msg->port = in_port;
+ msg->reserved = 0;
+ msg->arg = actions[0].controller.arg;
+
+ send_packet_in(ofproto, packet);
+
+ return true;
+ } else {
+ int error;
+
+ error = dpif_execute(ofproto->dpif, in_port,
+ actions, n_actions, packet);
+ ofpbuf_delete(packet);
+ return !error;
+ }
+}
+