dpdk

DPDK rte_flow E810


I'm trying to create the queue rule through rte_flow based on tcp port.

Got some problem in rte_flow_create() it returns: "ice_flow_create(): Failed to create flow". But rte_flow_validate() returns 0.

What the problem?

    struct rte_flow_attr attr;
    struct rte_flow_item pattern[4];
    struct rte_flow_action action[2];
    struct rte_flow_action_queue queue;
    struct rte_flow_item_eth eth_spec;
    struct rte_flow_item_eth eth_mask;
    struct rte_flow_item_ipv4 ip_spec;
    struct rte_flow_item_ipv4 ip_mask;
    struct rte_flow_item_tcp tcp_spec;
    struct rte_flow_item_tcp tcp_mask;
    struct rte_flow_error error;

    // Rule attribute (ingress)
    memset(&attr, 0, sizeof(struct rte_flow_attr));
    attr.ingress = 1;

    memset(pattern, 0, sizeof(pattern));
    memset(action, 0, sizeof(action));

    // Action sequence
    queue.index = rx_q;
    action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
    action[0].conf = &queue;
    action[1].type = RTE_FLOW_ACTION_TYPE_END;

    // First level of the pattern (eth)
    memset(&eth_spec, 0, sizeof(struct rte_flow_item_eth));
    memset(&eth_mask, 0, sizeof(struct rte_flow_item_eth));
    pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
    pattern[0].spec = &eth_spec;
    pattern[0].mask = &eth_mask;

    // Second level of the pattern (IPv4)
    memset(&ip_spec, 0, sizeof(struct rte_flow_item_ipv4));
    memset(&ip_mask, 0, sizeof(struct rte_flow_item_ipv4));
    pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
    pattern[1].spec = &ip_spec;
    pattern[1].mask = &ip_mask;

    // Third level of the pattern (TCP)
    memset(&tcp_spec, 0, sizeof(struct rte_flow_item_tcp));
    memset(&tcp_mask, 0, sizeof(struct rte_flow_item_tcp));
    tcp_spec.hdr.dst_port = rte_cpu_to_be_16(listen_port);
    tcp_mask.hdr.dst_port = 0xFFFF;
    pattern[2].type = RTE_FLOW_ITEM_TYPE_TCP;
    pattern[2].spec = &tcp_spec;
    pattern[2].mask = &tcp_mask;

    // Final level
    pattern[3].type = RTE_FLOW_ITEM_TYPE_END;

    if (rte_flow_validate(port_id, &attr, pattern, action, &error) != 0)
        printf(...);

    rte_flow_create(port_id, &attr, pattern, action, &error);

Solution

  • Based on the prior review, it seems like the flow parsing goes to the "hash" engine. By the looks of it, this engine requires that all item specifications and masks be NULL, which contradicts the intention to match on TCP DST.

    According to the guide (see "Generic Flow Pipeline Mode Support"), one may want to enable the two-stage pipeline by means of the pipeline-mode-support=1 argument. As per the argument description, the flow in question most likely belongs in the "distribution stage" of the pipeline.

    So, provided that the two-stage pipeline has been enabled, it pays to modify the flow specification so that it a) has attr.priority = 1; and b) includes an exact match on ETH DST in its L2 pattern item.

    Doing so should take parsing to the "fdir" engine and thus eliminate the failure.