[PATCH v3 08/19] net/ixgbe: reimplement ntuple parser
Medvedkin, Vladimir
vladimir.medvedkin at intel.com
Sat Sep 19 18:11:01 CEST 2026
On 9/16/2026 1:18 PM, Anatoly Burakov wrote:
> Use the new flow graph API and the common parsing framework to implement
> flow parser for ntuple.
>
> The 5tuple filter tracking infrastructure is moved completely inside the
> new engine and is removed from the rest of the driver.
>
> Signed-off-by: Anatoly Burakov<anatoly.burakov at intel.com>
> ---
<snip>
> +static const struct flow_graph ixgbe_ntuple_graph = {
> + .nodes = (struct flow_graph_node[]) {
> + [IXGBE_NTUPLE_NODE_START] = {
> + .name = "START",
> + },
> + [IXGBE_NTUPLE_NODE_ETH] = {
> + .name = "ETH",
> + .type = RTE_FLOW_ITEM_TYPE_ETH,
> + .constraints = FLOW_GRAPH_NODE_EXPECT_EMPTY,
legacy code accepts patterns with non null spec/mask containing all
zeros. Same for VLAN.
> + },
> + [IXGBE_NTUPLE_NODE_VLAN] = {
> + .name = "VLAN",
> + .type = RTE_FLOW_ITEM_TYPE_VLAN,
> + .constraints = FLOW_GRAPH_NODE_EXPECT_EMPTY,
> + },
> + [IXGBE_NTUPLE_NODE_IPV4] = {
> + .name = "IPV4",
> + .type = RTE_FLOW_ITEM_TYPE_IPV4,
> + .constraints = FLOW_GRAPH_NODE_EXPECT_SPEC_MASK,
mask was optional
> + .validate = ixgbe_validate_ntuple_ipv4,
> + .process = ixgbe_process_ntuple_ipv4,
> + },
> + [IXGBE_NTUPLE_NODE_TCP] = {
> + .name = "TCP",
> + .type = RTE_FLOW_ITEM_TYPE_TCP,
> + .constraints = FLOW_GRAPH_NODE_EXPECT_SPEC_MASK,
> + .validate = ixgbe_validate_ntuple_tcp,
> + .process = ixgbe_process_ntuple_tcp,
> + },
> + [IXGBE_NTUPLE_NODE_UDP] = {
> + .name = "UDP",
> + .type = RTE_FLOW_ITEM_TYPE_UDP,
> + .constraints = FLOW_GRAPH_NODE_EXPECT_SPEC_MASK,
spec and mask was optional
> + .validate = ixgbe_validate_ntuple_udp,
> + .process = ixgbe_process_ntuple_udp,
> + },
> + [IXGBE_NTUPLE_NODE_SCTP] = {
> + .name = "SCTP",
> + .type = RTE_FLOW_ITEM_TYPE_SCTP,
> + .constraints = FLOW_GRAPH_NODE_EXPECT_SPEC_MASK,
> + .validate = ixgbe_validate_ntuple_sctp,
> + .process = ixgbe_process_ntuple_sctp,
> + },
> + [IXGBE_NTUPLE_NODE_END] = {
> + .name = "END",
> + .type = RTE_FLOW_ITEM_TYPE_END,
> + },
> + },
<snip>
> + priority = RTE_MIN(IXGBE_MAX_N_TUPLE_PRIO - 1, (uint16_t)attr->priority);
> + priority = IXGBE_MAX_N_TUPLE_PRIO - 1 - priority;
> + priority += IXGBE_MIN_N_TUPLE_PRIO;
> + ntuple_ctx->ntuple.priority = priority;
priority = RTE_MIN(IXGBE_MAX_N_TUPLE_PRIO,
RTE_MAX(IXGBE_MIN_N_TUPLE_PRIO, attr->priority))
otherwise priority 0 maps to 7
> +
> + /* fixed value for ixgbe */
> + ntuple_ctx->ntuple.flags = RTE_5TUPLE_FLAGS;
> +
> + return 0;
> +}
> +
> +static enum ixgbe_5tuple_protocol
> +convert_protocol_type(uint8_t protocol_value)
> +{
> + if (protocol_value == IPPROTO_TCP)
> + return IXGBE_FILTER_PROTOCOL_TCP;
> + else if (protocol_value == IPPROTO_UDP)
> + return IXGBE_FILTER_PROTOCOL_UDP;
> + else if (protocol_value == IPPROTO_SCTP)
> + return IXGBE_FILTER_PROTOCOL_SCTP;
> + else
> + return IXGBE_FILTER_PROTOCOL_NONE;
> +}
> +
> +static int
> +ixgbe_flow_ntuple_ctx_to_flow(const struct ci_flow_engine_ctx *ctx,
> + struct ci_flow *flow,
> + struct rte_flow_error *error __rte_unused)
> +{
> + const struct ixgbe_ntuple_ctx *ntuple_ctx = (const struct ixgbe_ntuple_ctx *)ctx;
> + struct ixgbe_ntuple_flow *ntuple_flow = (struct ixgbe_ntuple_flow *)flow;
> + const struct rte_eth_ntuple_filter *ntuple = &ntuple_ctx->ntuple;
> + struct ixgbe_5tuple_filter_info *key = &ntuple_flow->key;
> +
> + /* mask shape (0 or all-ones) is already guaranteed by the graph */
> + memset(key, 0, sizeof(*key));
> +
> + key->dst_ip_mask = ntuple->dst_ip_mask == 0;
> + key->dst_ip = ntuple->dst_ip;
I'm not sure we need to copy from the flow if the corresponding mask is
set. For example, in ixgbe_process_ntuple_ipv4(), dst_ip is copied from
an item independently of the mask. Thus, a user may install two or more
semantically identical rules with different values in masked-out fields
and consume all available filters.
> + key->src_ip_mask = ntuple->src_ip_mask == 0;
> + key->src_ip = ntuple->src_ip;
> + key->dst_port_mask = ntuple->dst_port_mask == 0;
> + key->dst_port = ntuple->dst_port;
> + key->src_port_mask = ntuple->src_port_mask == 0;
> + key->src_port = ntuple->src_port;
> + key->proto_mask = ntuple->proto_mask == 0;
> + key->proto = convert_protocol_type(ntuple->proto);
> + key->priority = (uint8_t)ntuple->priority;
> +
> + ntuple_flow->queue = ntuple->queue;
> +
> + return 0;
> +}
<snip>
--
Regards,
Vladimir
More information about the dev
mailing list