From 735783c4146e6cbb4e996922edb2b89310cce9b3 Mon Sep 17 00:00:00 2001 From: Roman Zhukov Date: Tue, 6 Mar 2018 15:24:52 +0000 Subject: [PATCH] net/sfc: support GENEVE in flow API filters Exact match of virtual network identifier is supported by parser. IP protocol match are enforced to UDP. Only Ethernet protocol type is supported. Signed-off-by: Roman Zhukov Signed-off-by: Andrew Rybchenko Reviewed-by: Ivan Malov Reviewed-by: Andy Moreton --- doc/guides/nics/sfc_efx.rst | 3 ++ drivers/net/sfc/sfc_flow.c | 80 ++++++++++++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst index 05dacb3cea..943fe55786 100644 --- a/doc/guides/nics/sfc_efx.rst +++ b/doc/guides/nics/sfc_efx.rst @@ -168,6 +168,9 @@ Supported pattern items: - VXLAN (exact match of VXLAN network identifier) +- GENEVE (exact match of virtual network identifier, only Ethernet (0x6558) + protocol type is supported) + - NVGRE (exact match of virtual subnet ID) Supported actions: diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 1f452a7ed9..f0e883771a 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -58,6 +58,7 @@ static sfc_flow_item_parse sfc_flow_parse_ipv6; static sfc_flow_item_parse sfc_flow_parse_tcp; static sfc_flow_item_parse sfc_flow_parse_udp; static sfc_flow_item_parse sfc_flow_parse_vxlan; +static sfc_flow_item_parse sfc_flow_parse_geneve; static sfc_flow_item_parse sfc_flow_parse_nvgre; static boolean_t @@ -717,7 +718,7 @@ sfc_flow_set_match_flags_for_encap_pkts(const struct rte_flow_item *item, rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Outer IP header protocol must be UDP " - "in VxLAN pattern"); + "in VxLAN/GENEVE pattern"); return -rte_errno; case EFX_IPPROTO_GRE: @@ -730,7 +731,7 @@ sfc_flow_set_match_flags_for_encap_pkts(const struct rte_flow_item *item, default: rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, - "Only VxLAN/NVGRE tunneling patterns " + "Only VxLAN/GENEVE/NVGRE tunneling patterns " "are supported"); return -rte_errno; } @@ -831,6 +832,74 @@ sfc_flow_parse_vxlan(const struct rte_flow_item *item, return rc; } +/** + * Convert GENEVE item to EFX filter specification. + * + * @param item[in] + * Item specification. Only Virtual Network Identifier and protocol type + * fields are supported. But protocol type can be only Ethernet (0x6558). + * If the mask is NULL, default mask will be used. + * Ranging is not supported. + * @param efx_spec[in, out] + * EFX filter specification to update. + * @param[out] error + * Perform verbose error reporting if not NULL. + */ +static int +sfc_flow_parse_geneve(const struct rte_flow_item *item, + efx_filter_spec_t *efx_spec, + struct rte_flow_error *error) +{ + int rc; + const struct rte_flow_item_geneve *spec = NULL; + const struct rte_flow_item_geneve *mask = NULL; + const struct rte_flow_item_geneve supp_mask = { + .protocol = RTE_BE16(0xffff), + .vni = { 0xff, 0xff, 0xff } + }; + + rc = sfc_flow_parse_init(item, + (const void **)&spec, + (const void **)&mask, + &supp_mask, + &rte_flow_item_geneve_mask, + sizeof(struct rte_flow_item_geneve), + error); + if (rc != 0) + return rc; + + rc = sfc_flow_set_match_flags_for_encap_pkts(item, efx_spec, + EFX_IPPROTO_UDP, error); + if (rc != 0) + return rc; + + efx_spec->efs_encap_type = EFX_TUNNEL_PROTOCOL_GENEVE; + efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE; + + if (spec == NULL) + return 0; + + if (mask->protocol == supp_mask.protocol) { + if (spec->protocol != rte_cpu_to_be_16(ETHER_TYPE_TEB)) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "GENEVE encap. protocol must be Ethernet " + "(0x6558) in the GENEVE pattern item"); + return -rte_errno; + } + } else if (mask->protocol != 0) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Unsupported mask for GENEVE encap. protocol"); + return -rte_errno; + } + + rc = sfc_flow_set_efx_spec_vni_or_vsid(efx_spec, spec->vni, + mask->vni, item, error); + + return rc; +} + /** * Convert NVGRE item to EFX filter specification. * @@ -931,6 +1000,12 @@ static const struct sfc_flow_item sfc_flow_items[] = { .layer = SFC_FLOW_ITEM_START_LAYER, .parse = sfc_flow_parse_vxlan, }, + { + .type = RTE_FLOW_ITEM_TYPE_GENEVE, + .prev_layer = SFC_FLOW_ITEM_L4, + .layer = SFC_FLOW_ITEM_START_LAYER, + .parse = sfc_flow_parse_geneve, + }, { .type = RTE_FLOW_ITEM_TYPE_NVGRE, .prev_layer = SFC_FLOW_ITEM_L3, @@ -1045,6 +1120,7 @@ sfc_flow_parse_pattern(const struct rte_flow_item pattern[], break; case RTE_FLOW_ITEM_TYPE_VXLAN: + case RTE_FLOW_ITEM_TYPE_GENEVE: case RTE_FLOW_ITEM_TYPE_NVGRE: if (is_ifrm) { rte_flow_error_set(error, EINVAL, -- 2.20.1