Add proper action verification in dpif-netdev and remove psample verification according to dpif name.
Signed-off-by: Roi Dayan <r...@nvidia.com> Reviewed-by: Eli Britstein <el...@nvidia.com> --- Notes: v2 - Fix dpif-netdev checking all actions supported instead of only the first. - Refactor dpif-netdev action support to return true for actions implemented and query odp-execute for support of the other actions not requiring datapath support. lib/dpif-netdev.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++ lib/odp-execute.c | 6 ++++ lib/odp-execute.h | 2 ++ 3 files changed, 87 insertions(+) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 87d69c46d5e0..5bb48f2e5c0c 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -4307,6 +4307,78 @@ exit: return error; } +static bool +dpif_netdev_actions_supported(const struct nlattr *actions, size_t actions_len) +{ + const struct nlattr *nla; + size_t left; + + if (!actions_len) { + return true; + } + + NL_ATTR_FOR_EACH (nla, left, actions, actions_len) { + enum ovs_action_attr type = nl_attr_type(nla); + + switch (type) { + /* Supported actions go here in order of definition. */ + case OVS_ACTION_ATTR_OUTPUT: + case OVS_ACTION_ATTR_LB_OUTPUT: + case OVS_ACTION_ATTR_TUNNEL_PUSH: + case OVS_ACTION_ATTR_TUNNEL_POP: + case OVS_ACTION_ATTR_USERSPACE: + case OVS_ACTION_ATTR_RECIRC: + case OVS_ACTION_ATTR_CT: + case OVS_ACTION_ATTR_METER: + if (nla->nla_type & NLA_F_NESTED && + !dpif_netdev_actions_supported(nl_attr_get(nla), + nl_attr_get_size(nla))) { + return false; + } + break; + ;; + case OVS_ACTION_ATTR_SET: + case OVS_ACTION_ATTR_PUSH_VLAN: + case OVS_ACTION_ATTR_POP_VLAN: + case OVS_ACTION_ATTR_SAMPLE: + case OVS_ACTION_ATTR_HASH: + case OVS_ACTION_ATTR_PUSH_MPLS: + case OVS_ACTION_ATTR_POP_MPLS: + case OVS_ACTION_ATTR_SET_MASKED: + case OVS_ACTION_ATTR_TRUNC: + case OVS_ACTION_ATTR_PUSH_ETH: + case OVS_ACTION_ATTR_POP_ETH: + case OVS_ACTION_ATTR_CT_CLEAR: + case OVS_ACTION_ATTR_PUSH_NSH: + case OVS_ACTION_ATTR_POP_NSH: + case OVS_ACTION_ATTR_CLONE: + case OVS_ACTION_ATTR_CHECK_PKT_LEN: + case OVS_ACTION_ATTR_ADD_MPLS: + case OVS_ACTION_ATTR_DEC_TTL: + case OVS_ACTION_ATTR_DROP: + if (!odp_execute_without_datapath_assistance(nla)) { + return false; + } + + if (nla->nla_type & NLA_F_NESTED && + !dpif_netdev_actions_supported(nl_attr_get(nla), + nl_attr_get_size(nla))) { + return false; + } + break; + + /* Unsupported actions go here in order of definition. */ + case OVS_ACTION_ATTR_PSAMPLE: + return false; + + case OVS_ACTION_ATTR_UNSPEC: + case __OVS_ACTION_ATTR_MAX: + OVS_NOT_REACHED(); + } + } + return true; +} + static int dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put) { @@ -4367,6 +4439,13 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put) * address mask. Installation of the flow will use the match variable. */ netdev_flow_key_init(&key, &match.flow); + /* For probe operations, verify if the individual actions are supported. + * Otherwise, assume the higher layer, ofproto, manages action support. */ + if (probe && !dpif_netdev_actions_supported(put->actions, + put->actions_len)) { + return EINVAL; + } + if (put->pmd_id == PMD_ID_NULL) { if (cmap_count(&dp->poll_threads) == 0) { return EINVAL; diff --git a/lib/odp-execute.c b/lib/odp-execute.c index 15577d5394fa..cd29ed572bd4 100644 --- a/lib/odp-execute.c +++ b/lib/odp-execute.c @@ -995,6 +995,12 @@ odp_execute_init(void) } } +bool +odp_execute_without_datapath_assistance(const struct nlattr *a) +{ + return !requires_datapath_assistance(a); +} + /* Executes all of the 'actions_len' bytes of datapath actions in 'actions' on * the packets in 'batch'. If 'steal' is true, possibly modifies and * definitely free the packets in 'batch', otherwise leaves 'batch' unchanged. diff --git a/lib/odp-execute.h b/lib/odp-execute.h index 2ba1ec5d2a1c..8e145e80c51c 100644 --- a/lib/odp-execute.h +++ b/lib/odp-execute.h @@ -38,6 +38,8 @@ typedef void (*odp_execute_action_cb)(struct dp_packet_batch *batch, typedef void (*odp_execute_cb)(void *dp, struct dp_packet_batch *batch, const struct nlattr *action, bool should_steal); +bool odp_execute_without_datapath_assistance(const struct nlattr *a); + /* Actions that need to be executed in the context of a datapath are handed * to 'dp_execute_action', if non-NULL. Currently this is called only for * actions OVS_ACTION_ATTR_OUTPUT and OVS_ACTION_ATTR_USERSPACE so -- 2.21.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev