@@ -27,12 +27,13 @@
#include "openvswitch/vlog.h"
VLOG_DEFINE_THIS_MODULE(odp_execute_impl);
+static int active_action_impl_index;
static struct odp_execute_action_impl action_impls[] = {
[ACTION_IMPL_SCALAR] = {
.available = false,
.name = "scalar",
- .init_func = NULL,
+ .init_func = odp_action_scalar_init,
},
};
@@ -45,6 +46,21 @@ action_impl_copy_funcs(struct odp_execute_action_impl *src,
}
}
+int
+odp_execute_action_set(const char *name,
+ struct odp_execute_action_impl *active)
+{
+ for (int i = 0; i < ACTION_IMPL_MAX; i++) {
+ /* String compare, and set ptrs atomically. */
+ if (!strcmp(action_impls[i].name, name)) {
+ action_impl_copy_funcs(active, &action_impls[i]);;
+ active_action_impl_index = i;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
void
odp_execute_action_init(void)
{
@@ -71,4 +71,12 @@ BUILD_ASSERT_DECL(ACTION_IMPL_SCALAR == 0);
*/
void odp_execute_action_init(void);
+/* Init functions for the action implementations. Initializes the function
+ * pointers for optimized action types.
+ */
+int odp_action_scalar_init(struct odp_execute_action_impl *self);
+
+int odp_execute_action_set(const char *name,
+ struct odp_execute_action_impl *active);
+
#endif /* ODP_EXTRACT_PRIVATE */
@@ -834,6 +834,30 @@ requires_datapath_assistance(const struct nlattr *a)
return false;
}
+static void
+action_pop_vlan(struct dp_packet_batch *batch,
+ const struct nlattr *a OVS_UNUSED)
+{
+ struct dp_packet *packet;
+
+ DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
+ eth_pop_vlan(packet);
+ }
+}
+
+/* Implementation of the scalar actions impl init function. Build up the
+ * array of func ptrs here.
+ */
+int
+odp_action_scalar_init(struct odp_execute_action_impl *self)
+{
+ /* Set function pointers for actions that can be applied directly, these
+ * are identified by OVS_ACTION_ATTR_*. */
+ self->funcs[OVS_ACTION_ATTR_POP_VLAN] = action_pop_vlan;
+
+ return 0;
+}
+
/* The active function pointers on the datapath. ISA optimized implementations
* are enabled by plugging them into this static arary, which is consulted when
* applying actions on the datapath.
@@ -846,10 +870,22 @@ odp_execute_init(void)
static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
if (ovsthread_once_start(&once)) {
odp_execute_action_init();
+ odp_actions_impl_set("scalar");
ovsthread_once_done(&once);
}
}
+int
+odp_actions_impl_set(const char *name)
+{
+
+ int err = odp_execute_action_set(name, &actions_active_impl);
+ if (err) {
+ VLOG_ERR("Failed setting action implementation to %s, error %d",
+ name, err);
+ }
+ return err;
+}
/* Executes all of the 'actions_len' bytes of datapath actions in 'actions' on
* the packets in 'batch'. If 'steal' is true, possibly modifies and
@@ -964,12 +1000,6 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,
break;
}
- case OVS_ACTION_ATTR_POP_VLAN:
- DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
- eth_pop_vlan(packet);
- }
- break;
-
case OVS_ACTION_ATTR_PUSH_MPLS: {
const struct ovs_action_push_mpls *mpls = nl_attr_get(a);
@@ -1120,6 +1150,8 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,
case OVS_ACTION_ATTR_CT:
case OVS_ACTION_ATTR_UNSPEC:
case __OVS_ACTION_ATTR_MAX:
+ /* The following actions are handled by the scalar implementation. */
+ case OVS_ACTION_ATTR_POP_VLAN:
OVS_NOT_REACHED();
}
@@ -35,6 +35,8 @@ void odp_execute_init(void);
typedef void (*odp_execute_action_cb)(struct dp_packet_batch *batch,
const struct nlattr *action);
+int odp_actions_impl_set(const char *name);
+
typedef void (*odp_execute_cb)(void *dp, struct dp_packet_batch *batch,
const struct nlattr *action, bool should_steal);