[dpdk-dev] [PATCH 51/62] net/sfc: support flow item IPV6 in transfer rules
Andrew Rybchenko
arybchenko at solarflare.com
Tue Oct 20 10:48:18 CEST 2020
From: Ivan Malov <ivan.malov at oktetlabs.ru>
Add support for this flow item to MAE-specific RTE flow implementation.
Signed-off-by: Ivan Malov <ivan.malov at oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
Reviewed-by: Andy Moreton <amoreton at xilinx.com>
---
doc/guides/nics/sfc_efx.rst | 3 +
drivers/net/sfc/sfc_mae.c | 106 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_mae.h | 1 +
3 files changed, 110 insertions(+)
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index e687e1cac3..8209990d23 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -205,6 +205,9 @@ Supported pattern items (***transfer*** rules):
- IPV4 (source/destination addresses, IP transport protocol,
type of service, time to live)
+- IPV6 (source/destination addresses, IP transport protocol,
+ traffic class, hop limit)
+
Supported actions (***transfer*** rules):
- OF_POP_VLAN
diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index d7c1cd784f..2b0121c0ac 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -946,6 +946,105 @@ sfc_mae_rule_parse_item_ipv4(const struct rte_flow_item *item,
ctx_mae->match_spec_action, error);
}
+static const struct sfc_mae_field_locator flocs_ipv6[] = {
+ {
+ EFX_MAE_FIELD_SRC_IP6_BE,
+ RTE_SIZEOF_FIELD(struct rte_flow_item_ipv6, hdr.src_addr),
+ offsetof(struct rte_flow_item_ipv6, hdr.src_addr),
+ },
+ {
+ EFX_MAE_FIELD_DST_IP6_BE,
+ RTE_SIZEOF_FIELD(struct rte_flow_item_ipv6, hdr.dst_addr),
+ offsetof(struct rte_flow_item_ipv6, hdr.dst_addr),
+ },
+ {
+ /*
+ * This locator is used only for building supported fields mask.
+ * The field is handled by sfc_mae_rule_process_pattern_data().
+ */
+ SFC_MAE_FIELD_HANDLING_DEFERRED,
+ RTE_SIZEOF_FIELD(struct rte_flow_item_ipv6, hdr.proto),
+ offsetof(struct rte_flow_item_ipv6, hdr.proto),
+ },
+ {
+ EFX_MAE_FIELD_IP_TTL,
+ RTE_SIZEOF_FIELD(struct rte_flow_item_ipv6, hdr.hop_limits),
+ offsetof(struct rte_flow_item_ipv6, hdr.hop_limits),
+ },
+};
+
+static int
+sfc_mae_rule_parse_item_ipv6(const struct rte_flow_item *item,
+ struct sfc_flow_parse_ctx *ctx,
+ struct rte_flow_error *error)
+{
+ rte_be16_t ethertype_ipv6_be = RTE_BE16(RTE_ETHER_TYPE_IPV6);
+ struct sfc_mae_parse_ctx *ctx_mae = ctx->mae;
+ struct sfc_mae_pattern_data *pdata = &ctx_mae->pattern_data;
+ struct rte_flow_item_ipv6 supp_mask;
+ const uint8_t *spec = NULL;
+ const uint8_t *mask = NULL;
+ rte_be32_t vtc_flow_be;
+ uint32_t vtc_flow;
+ uint8_t tc_value;
+ uint8_t tc_mask;
+ int rc;
+
+ sfc_mae_item_build_supp_mask(flocs_ipv6, RTE_DIM(flocs_ipv6),
+ &supp_mask, sizeof(supp_mask));
+
+ vtc_flow_be = RTE_BE32(RTE_IPV6_HDR_TC_MASK);
+ memcpy(&supp_mask, &vtc_flow_be, sizeof(vtc_flow_be));
+
+ rc = sfc_flow_parse_init(item,
+ (const void **)&spec, (const void **)&mask,
+ (const void *)&supp_mask,
+ &rte_flow_item_ipv6_mask,
+ sizeof(struct rte_flow_item_ipv6), error);
+ if (rc != 0)
+ return rc;
+
+ pdata->innermost_ethertype_restriction.value = ethertype_ipv6_be;
+ pdata->innermost_ethertype_restriction.mask = RTE_BE16(0xffff);
+
+ if (spec != NULL) {
+ const struct rte_flow_item_ipv6 *item_spec;
+ const struct rte_flow_item_ipv6 *item_mask;
+
+ item_spec = (const struct rte_flow_item_ipv6 *)spec;
+ item_mask = (const struct rte_flow_item_ipv6 *)mask;
+
+ pdata->l3_next_proto_value = item_spec->hdr.proto;
+ pdata->l3_next_proto_mask = item_mask->hdr.proto;
+ } else {
+ return 0;
+ }
+
+ rc = sfc_mae_parse_item(flocs_ipv6, RTE_DIM(flocs_ipv6), spec, mask,
+ ctx_mae->match_spec_action, error);
+ if (rc != 0)
+ return rc;
+
+ memcpy(&vtc_flow_be, spec, sizeof(vtc_flow_be));
+ vtc_flow = rte_be_to_cpu_32(vtc_flow_be);
+ tc_value = (vtc_flow & RTE_IPV6_HDR_TC_MASK) >> RTE_IPV6_HDR_TC_SHIFT;
+
+ memcpy(&vtc_flow_be, mask, sizeof(vtc_flow_be));
+ vtc_flow = rte_be_to_cpu_32(vtc_flow_be);
+ tc_mask = (vtc_flow & RTE_IPV6_HDR_TC_MASK) >> RTE_IPV6_HDR_TC_SHIFT;
+
+ rc = efx_mae_match_spec_field_set(ctx_mae->match_spec_action,
+ EFX_MAE_FIELD_IP_TOS,
+ sizeof(tc_value), &tc_value,
+ sizeof(tc_mask), &tc_mask);
+ if (rc != 0) {
+ return rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ITEM,
+ NULL, "Failed to process item fields");
+ }
+
+ return 0;
+}
+
static const struct sfc_flow_item sfc_flow_items[] = {
{
.type = RTE_FLOW_ITEM_TYPE_PORT_ID,
@@ -1012,6 +1111,13 @@ static const struct sfc_flow_item sfc_flow_items[] = {
.ctx_type = SFC_FLOW_PARSE_CTX_MAE,
.parse = sfc_mae_rule_parse_item_ipv4,
},
+ {
+ .type = RTE_FLOW_ITEM_TYPE_IPV6,
+ .prev_layer = SFC_FLOW_ITEM_L2,
+ .layer = SFC_FLOW_ITEM_L3,
+ .ctx_type = SFC_FLOW_PARSE_CTX_MAE,
+ .parse = sfc_mae_rule_parse_item_ipv6,
+ },
};
int
diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h
index 56be8bf917..993a377861 100644
--- a/drivers/net/sfc/sfc_mae.h
+++ b/drivers/net/sfc/sfc_mae.h
@@ -115,6 +115,7 @@ struct sfc_mae_pattern_data {
* L3 requirement for the innermost L2 item's "type" ("inner_type").
* This contains one of:
* - 0x0800/0xffff: IPV4
+ * - 0x86dd/0xffff: IPV6
* - 0x0000/0x0000: no L3 item
*/
struct sfc_mae_ethertype innermost_ethertype_restriction;
--
2.17.1
More information about the dev
mailing list