From: Roman Zhukov Date: Thu, 19 Apr 2018 11:37:05 +0000 (+0100) Subject: net/sfc: support MARK and FLAG actions in flow API X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=5f78af523912;p=dpdk.git net/sfc: support MARK and FLAG actions in flow API Signed-off-by: Roman Zhukov Signed-off-by: Andrew Rybchenko --- diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst index 6b6b5e0ab1..63939ec830 100644 --- a/doc/guides/nics/sfc_efx.rst +++ b/doc/guides/nics/sfc_efx.rst @@ -201,6 +201,10 @@ Supported actions: - DROP +- FLAG (supported only with ef10_essb Rx datapath) + +- MARK (supported only with ef10_essb Rx datapath) + Validating flow rules depends on the firmware variant. Ethernet destinaton individual/group match diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 2b5b831a9e..e6b2ecff41 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -23,6 +23,7 @@ #include "sfc_filter.h" #include "sfc_flow.h" #include "sfc_log.h" +#include "sfc_dp_rx.h" /* * At now flow API is implemented in such a manner that each @@ -1500,6 +1501,22 @@ sfc_flow_filter_remove(struct sfc_adapter *sa, return rc; } +static int +sfc_flow_parse_mark(struct sfc_adapter *sa, + const struct rte_flow_action_mark *mark, + struct rte_flow *flow) +{ + const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + + if (mark == NULL || mark->id > encp->enc_filter_action_mark_max) + return EINVAL; + + flow->spec.template.efs_flags |= EFX_FILTER_FLAG_ACTION_MARK; + flow->spec.template.efs_mark = mark->id; + + return 0; +} + static int sfc_flow_parse_actions(struct sfc_adapter *sa, const struct rte_flow_action actions[], @@ -1507,10 +1524,13 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, struct rte_flow_error *error) { int rc; + const unsigned int dp_rx_features = sa->dp_rx->features; uint32_t actions_set = 0; const uint32_t fate_actions_mask = (1UL << RTE_FLOW_ACTION_TYPE_QUEUE) | (1UL << RTE_FLOW_ACTION_TYPE_RSS) | (1UL << RTE_FLOW_ACTION_TYPE_DROP); + const uint32_t mark_actions_mask = (1UL << RTE_FLOW_ACTION_TYPE_MARK) | + (1UL << RTE_FLOW_ACTION_TYPE_FLAG); if (actions == NULL) { rte_flow_error_set(error, EINVAL, @@ -1569,6 +1589,45 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, EFX_FILTER_SPEC_RX_DMAQ_ID_DROP; break; + case RTE_FLOW_ACTION_TYPE_FLAG: + SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_FLAG, + actions_set); + if ((actions_set & mark_actions_mask) != 0) + goto fail_actions_overlap; + + if ((dp_rx_features & SFC_DP_RX_FEAT_FLOW_FLAG) == 0) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "FLAG action is not supported on the current Rx datapath"); + return -rte_errno; + } + + flow->spec.template.efs_flags |= + EFX_FILTER_FLAG_ACTION_FLAG; + break; + + case RTE_FLOW_ACTION_TYPE_MARK: + SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_MARK, + actions_set); + if ((actions_set & mark_actions_mask) != 0) + goto fail_actions_overlap; + + if ((dp_rx_features & SFC_DP_RX_FEAT_FLOW_MARK) == 0) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "MARK action is not supported on the current Rx datapath"); + return -rte_errno; + } + + rc = sfc_flow_parse_mark(sa, actions->conf, flow); + if (rc != 0) { + rte_flow_error_set(error, rc, + RTE_FLOW_ERROR_TYPE_ACTION, actions, + "Bad MARK action"); + return -rte_errno; + } + break; + default: rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, actions, @@ -1593,6 +1652,11 @@ fail_fate_actions: "Cannot combine several fate-deciding actions, " "choose between QUEUE, RSS or DROP"); return -rte_errno; + +fail_actions_overlap: + rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, actions, + "Overlapping actions are not supported"); + return -rte_errno; } /**