const struct flow *);
static bool facet_revalidate(struct ofproto_dpif *, struct facet *);
+static bool execute_controller_action(struct ofproto_dpif *,
+ const struct flow *,
+ const struct nlattr *odp_actions,
+ size_t actions_len,
+ struct ofpbuf *packet);
static void facet_execute(struct ofproto_dpif *, struct facet *,
struct ofpbuf *packet);
free(facet);
}
-/* 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_dpif *ofproto, const struct flow *flow,
- const struct nlattr *odp_actions, size_t actions_len,
- struct ofpbuf *packet)
-{
- struct odputil_keybuf keybuf;
- struct ofpbuf key;
- int error;
-
- if (actions_len == 0) {
- return true;
- } else if (odp_actions->nla_type == OVS_ACTION_ATTR_USERSPACE
- && NLA_ALIGN(odp_actions->nla_len) == actions_len) {
+execute_controller_action(struct ofproto_dpif *ofproto,
+ const struct flow *flow,
+ const struct nlattr *odp_actions, size_t actions_len,
+ struct ofpbuf *packet)
+{
+ if (actions_len
+ && odp_actions->nla_type == OVS_ACTION_ATTR_USERSPACE
+ && NLA_ALIGN(odp_actions->nla_len) == actions_len) {
/* 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.
send_packet_in_action(ofproto, packet, nl_attr_get_u64(nla), flow,
false);
return true;
+ } else {
+ return false;
+ }
+}
+
+/* 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_dpif *ofproto, const struct flow *flow,
+ const struct nlattr *odp_actions, size_t actions_len,
+ struct ofpbuf *packet)
+{
+ struct odputil_keybuf keybuf;
+ struct ofpbuf key;
+ int error;
+
+ if (execute_controller_action(ofproto, flow, odp_actions, actions_len,
+ packet)) {
+ return true;
}
ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);