Add the corresponding logics to support the offload of IPv4 NVGRE item. Signed-off-by: Chaoyong He <chaoyong...@corigine.com> Reviewed-by: Niklas Söderlund <niklas.soderl...@corigine.com> --- doc/guides/nics/features/nfp.ini | 2 + drivers/net/nfp/nfp_flow.c | 99 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 2 deletions(-)
diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini index f6b658b..2acc809 100644 --- a/doc/guides/nics/features/nfp.ini +++ b/doc/guides/nics/features/nfp.ini @@ -29,6 +29,8 @@ Usage doc = Y [rte_flow items] eth = Y geneve = Y +gre = Y +gre_key = Y ipv4 = Y ipv6 = Y port_id = Y diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c index 26d3854..0a43bf3 100644 --- a/drivers/net/nfp/nfp_flow.c +++ b/drivers/net/nfp/nfp_flow.c @@ -820,6 +820,26 @@ struct nfp_pre_tun_entry { return -EINVAL; } break; + case RTE_FLOW_ITEM_TYPE_GRE: + PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_GRE detected"); + /* Clear IPv4 bits */ + key_ls->key_layer &= ~NFP_FLOWER_LAYER_IPV4; + key_ls->tun_type = NFP_FL_TUN_GRE; + key_ls->key_layer |= NFP_FLOWER_LAYER_EXT_META; + key_ls->key_layer_two |= NFP_FLOWER_LAYER2_GRE; + key_ls->key_size += sizeof(struct nfp_flower_ext_meta); + if (outer_ip4_flag) { + key_ls->key_size += sizeof(struct nfp_flower_ipv4_gre_tun); + /* + * The outer l3 layer information is + * in `struct nfp_flower_ipv4_gre_tun` + */ + key_ls->key_size -= sizeof(struct nfp_flower_ipv4); + } + break; + case RTE_FLOW_ITEM_TYPE_GRE_KEY: + PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_GRE_KEY detected"); + break; default: PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type); return -ENOTSUP; @@ -1540,6 +1560,62 @@ struct nfp_pre_tun_entry { return ret; } +static int +nfp_flow_merge_gre(__rte_unused struct nfp_app_fw_flower *app_fw_flower, + __rte_unused struct rte_flow *nfp_flow, + char **mbuf_off, + __rte_unused const struct rte_flow_item *item, + __rte_unused const struct nfp_flow_item_proc *proc, + bool is_mask, + __rte_unused bool is_outer_layer) +{ + struct nfp_flower_ipv4_gre_tun *tun4; + + /* NVGRE is the only supported GRE tunnel type */ + tun4 = (struct nfp_flower_ipv4_gre_tun *)*mbuf_off; + if (is_mask) + tun4->ethertype = rte_cpu_to_be_16(~0); + else + tun4->ethertype = rte_cpu_to_be_16(0x6558); + + return 0; +} + +static int +nfp_flow_merge_gre_key(__rte_unused struct nfp_app_fw_flower *app_fw_flower, + __rte_unused struct rte_flow *nfp_flow, + char **mbuf_off, + const struct rte_flow_item *item, + __rte_unused const struct nfp_flow_item_proc *proc, + bool is_mask, + __rte_unused bool is_outer_layer) +{ + rte_be32_t tun_key; + const rte_be32_t *spec; + const rte_be32_t *mask; + struct nfp_flower_ipv4_gre_tun *tun4; + + spec = item->spec; + if (spec == NULL) { + PMD_DRV_LOG(DEBUG, "nfp flow merge gre key: no item->spec!"); + goto gre_key_end; + } + + mask = item->mask ? item->mask : proc->mask_default; + tun_key = is_mask ? *mask : *spec; + + tun4 = (struct nfp_flower_ipv4_gre_tun *)*mbuf_off; + tun4->tun_key = tun_key; + tun4->tun_flags = rte_cpu_to_be_16(NFP_FL_GRE_FLAG_KEY); + +gre_key_end: + *mbuf_off += sizeof(struct nfp_flower_ipv4_gre_tun); + + return 0; +} + +const rte_be32_t nfp_flow_item_gre_key = 0xffffffff; + /* Graph of supported items and associated process function */ static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = { [RTE_FLOW_ITEM_TYPE_END] = { @@ -1580,7 +1656,8 @@ struct nfp_pre_tun_entry { [RTE_FLOW_ITEM_TYPE_IPV4] = { .next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP, RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_SCTP), + RTE_FLOW_ITEM_TYPE_SCTP, + RTE_FLOW_ITEM_TYPE_GRE), .mask_support = &(const struct rte_flow_item_ipv4){ .hdr = { .type_of_service = 0xff, @@ -1671,6 +1748,23 @@ struct nfp_pre_tun_entry { .mask_sz = sizeof(struct rte_flow_item_geneve), .merge = nfp_flow_merge_geneve, }, + [RTE_FLOW_ITEM_TYPE_GRE] = { + .next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_GRE_KEY), + .mask_support = &(const struct rte_flow_item_gre){ + .c_rsvd0_ver = RTE_BE16(0xa000), + .protocol = RTE_BE16(0xffff), + }, + .mask_default = &rte_flow_item_gre_mask, + .mask_sz = sizeof(struct rte_flow_item_gre), + .merge = nfp_flow_merge_gre, + }, + [RTE_FLOW_ITEM_TYPE_GRE_KEY] = { + .next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH), + .mask_support = &nfp_flow_item_gre_key, + .mask_default = &nfp_flow_item_gre_key, + .mask_sz = sizeof(rte_be32_t), + .merge = nfp_flow_merge_gre_key, + }, }; static int @@ -1728,7 +1822,8 @@ struct nfp_pre_tun_entry { nfp_flow_is_tun_item(const struct rte_flow_item *item) { if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN || - item->type == RTE_FLOW_ITEM_TYPE_GENEVE) + item->type == RTE_FLOW_ITEM_TYPE_GENEVE || + item->type == RTE_FLOW_ITEM_TYPE_GRE_KEY) return true; return false; -- 1.8.3.1