@@ -33,7 +33,7 @@ static struct odp_execute_action_impl action_impls[] = {
[ACTION_IMPL_SCALAR] = {
.available = false,
.name = "scalar",
- .init_func = NULL,
+ .init_func = odp_action_scalar_init,
},
};
@@ -88,5 +88,19 @@ odp_execute_action_init(void)
VLOG_INFO("Action implementation %s (available: %s)",
action_impls[i].name, avail ? "Yes" : "No");
+
+ /* The following is a run-time check to make sure a scalar
+ * implementation exists for the given ISA implementation. This is to
+ * make sure the autovalidator works as expected. */
+ if (avail && i != ACTION_IMPL_SCALAR) {
+ for (int j = 0; j < __OVS_ACTION_ATTR_MAX; j++) {
+ /* No ovs_assert(), as it can be compiled out. */
+ if (action_impls[ACTION_IMPL_SCALAR].funcs[j] == NULL
+ && action_impls[i].funcs[j] != NULL) {
+ ovs_assert_failure(OVS_SOURCE_LOCATOR, __func__,
+ "Missing scalar action function!");
+ }
+ }
+ }
}
}
@@ -71,6 +71,11 @@ 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);
+
struct odp_execute_action_impl * odp_execute_action_set(const char *name);
#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.
@@ -982,12 +1006,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);
@@ -1138,6 +1156,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();
}