Add the corresponding logics to support the offload of IPv6 NVGRE item. Signed-off-by: Chaoyong He <chaoyong...@corigine.com> Reviewed-by: Niklas Söderlund <niklas.soderl...@corigine.com> --- drivers/net/nfp/nfp_flow.c | 73 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 14 deletions(-)
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c index 0a43bf3..6f21c86 100644 --- a/drivers/net/nfp/nfp_flow.c +++ b/drivers/net/nfp/nfp_flow.c @@ -822,8 +822,9 @@ struct nfp_pre_tun_entry { break; case RTE_FLOW_ITEM_TYPE_GRE: PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_GRE detected"); - /* Clear IPv4 bits */ + /* Clear IPv4 and IPv6 bits */ key_ls->key_layer &= ~NFP_FLOWER_LAYER_IPV4; + key_ls->key_layer &= ~NFP_FLOWER_LAYER_IPV6; 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; @@ -835,6 +836,17 @@ struct nfp_pre_tun_entry { * in `struct nfp_flower_ipv4_gre_tun` */ key_ls->key_size -= sizeof(struct nfp_flower_ipv4); + } else if (outer_ip6_flag) { + key_ls->key_layer_two |= NFP_FLOWER_LAYER2_TUN_IPV6; + key_ls->key_size += sizeof(struct nfp_flower_ipv6_gre_tun); + /* + * The outer l3 layer information is + * in `struct nfp_flower_ipv6_gre_tun` + */ + key_ls->key_size -= sizeof(struct nfp_flower_ipv6); + } else { + PMD_DRV_LOG(ERR, "No outer IP layer for GRE tunnel."); + return -1; } break; case RTE_FLOW_ITEM_TYPE_GRE_KEY: @@ -1562,38 +1574,59 @@ struct nfp_pre_tun_entry { static int nfp_flow_merge_gre(__rte_unused struct nfp_app_fw_flower *app_fw_flower, - __rte_unused struct rte_flow *nfp_flow, + 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_meta_tci *meta_tci; + struct nfp_flower_ext_meta *ext_meta; struct nfp_flower_ipv4_gre_tun *tun4; + struct nfp_flower_ipv6_gre_tun *tun6; + + meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data; + ext_meta = (struct nfp_flower_ext_meta *)(meta_tci + 1); /* 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); + if (rte_be_to_cpu_32(ext_meta->nfp_flow_key_layer2) & + NFP_FLOWER_LAYER2_TUN_IPV6) { + tun6 = (struct nfp_flower_ipv6_gre_tun *)*mbuf_off; + if (is_mask) + tun6->ethertype = rte_cpu_to_be_16(~0); + else + tun6->ethertype = rte_cpu_to_be_16(0x6558); + } else { + 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, + struct rte_flow *nfp_flow, char **mbuf_off, const struct rte_flow_item *item, - __rte_unused const struct nfp_flow_item_proc *proc, + 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_meta_tci *meta_tci; + struct nfp_flower_ext_meta *ext_meta; struct nfp_flower_ipv4_gre_tun *tun4; + struct nfp_flower_ipv6_gre_tun *tun6; + + meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data; + ext_meta = (struct nfp_flower_ext_meta *)(meta_tci + 1); spec = item->spec; if (spec == NULL) { @@ -1604,12 +1637,23 @@ struct nfp_pre_tun_entry { 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); + if (rte_be_to_cpu_32(ext_meta->nfp_flow_key_layer2) & + NFP_FLOWER_LAYER2_TUN_IPV6) { + tun6 = (struct nfp_flower_ipv6_gre_tun *)*mbuf_off; + tun6->tun_key = tun_key; + tun6->tun_flags = rte_cpu_to_be_16(NFP_FL_GRE_FLAG_KEY); + } else { + 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); + if (rte_be_to_cpu_32(ext_meta->nfp_flow_key_layer2) & + NFP_FLOWER_LAYER2_TUN_IPV6) + *mbuf_off += sizeof(struct nfp_flower_ipv6_gre_tun); + else + *mbuf_off += sizeof(struct nfp_flower_ipv4_gre_tun); return 0; } @@ -1675,7 +1719,8 @@ struct nfp_pre_tun_entry { [RTE_FLOW_ITEM_TYPE_IPV6] = { .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_ipv6){ .hdr = { .vtc_flow = RTE_BE32(0x0ff00000), -- 1.8.3.1