X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fsfc%2Fsfc_flow.c;h=5613d59a9cce9a3205f54f83220516511e603757;hb=c6034a20d9e221dc6125db57e4378520af3a515d;hp=2b5b831a9ebad3c7a8e81286f2a803e5c6357b6c;hpb=cc70e8f2074ef7b3ad4bccf626c1bb85ab5d5a8b;p=dpdk.git diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 2b5b831a9e..5613d59a9c 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, @@ -1552,7 +1572,7 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, rc = sfc_flow_parse_rss(sa, actions->conf, flow); if (rc != 0) { - rte_flow_error_set(error, rc, + rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_ACTION, actions, "Bad RSS action"); return -rte_errno; @@ -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; } /** @@ -1982,7 +2046,7 @@ sfc_flow_spec_filters_complete(struct sfc_adapter *sa, if (min_multiplier == UINT_MAX) { rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, - "Flow rule pattern is not supported"); + "The flow rule pattern is unsupported"); return -rte_errno; }