What can I help you with?
NVIDIA DPDK Documentation MLNX_DPDK_22.11_2310.5.1 LTS

Index-based Insertion Flow Rule

Flow rules can be inserted by calculating the hash value for the pattern or inserted by index via new a rte_flow_async_create_by_index() API. The index-based insertion enable the user to avoid additional match and simply execute predefined actions after jumping to the index in the table.

  • Specify special tag[255] as a pattern to jump to a particular index

    Copy
    Copied!
                

    flow pattern_template 0 create pattern_template_id 1 ingress template tag index is 255 / end

  • Select queue based on the index

    Copy
    Copied!
                

    flow actions_template 0 create actions_template_id 1 template queue / end queue / end

  • Create a table with linear hash distribution and insertion by index type

    Copy
    Copied!
                

    flow template_table 0 create table_id 1 group 10 priority 0 ingress rules_number 65000 insertion_type index hash_func linear pattern_template 1 actions_template 1

  • Distribute packets according to the index in tag[255]

    Copy
    Copied!
                

    flow queue 0 create 0 template_table 1 rule_index 0 actions_template 0 postpone no pattern end actions queue index 0 / end flow queue 0 create 0 template_table 1 rule_index 1 actions_template 0 postpone no pattern end actions queue index 1 / end flow queue 0 create 0 template_table 1 rule_index 2 actions_template 0 postpone no pattern end actions queue index 2 / end flow queue 0 create 0 template_table 1 rule_index 3 actions_template 0 postpone no pattern end actions queue index 3 / end

Copy
Copied!
            

struct rte_flow_pattern_template * create_pattern_template(uint16_t port_id, struct rte_flow_error *error) {                const struct rte_flow_item_tag tag_mask = {                                .data = 0,                                .index = MLX5_LINEAR_HASH_TAG_INDEX,                };                struct rte_flow_item pattern[] = {                 {                 .type = RTE_FLOW_ITEM_TYPE_TAG,                 .mask = &tag_mask,                 },                 {                 .type = RTE_FLOW_ITEM_TYPE_END,                 },                };                const struct rte_flow_pattern_template_attr pt_attr = {                 .relaxed_matching = 0,                 .ingress = 1,                };                return rte_flow_pattern_template_create(port_id,                                                                                                &pt_attr, pattern, &error); }   struct rte_flow_actions_template * create_actions_template(uint16_t port_id, struct rte_flow_error *error) {                struct rte_flow_action_queue queue_v = {                                .index = 0                };                struct rte_flow_action_queue queue_m = {                                .index = UINT16_MAX                };                struct rte_flow_action actions[] = {                                [0] = { /* queue action. */                                .type = RTE_FLOW_ACTION_TYPE_QUEUE,                                .conf = &queue_v },                                [1] = { /* end action mast be the last action. */                                .type = RTE_FLOW_ACTION_TYPE_END,},                };                struct rte_flow_action masks[] = {                                [0] = { /* queue action. */                                .type = RTE_FLOW_ACTION_TYPE_QUEUE,                                .conf = &queue_m },                                [1] = { /* end action mast be the last action. */                                .type = RTE_FLOW_ACTION_TYPE_END,},                };                const struct rte_flow_actions_template_attr at_attr = {                                .ingress = 1,                };                return rte_flow_actions_template_create(port_id, &at_attr,                                                                                actions, masks, error);   }   struct rte_flow_template_table * create_table(uint16_t port_id, struct rte_flow_error *error) {                struct rte_flow_pattern_template *pt;                struct rte_flow_actions_template *at;                const struct rte_flow_template_table_attr tbl_attr = {                                .flow_attr = {                                                .group = 1,                                                .priority = 0,                                                .ingress = 1,                                },                                .nb_flows = 4,                                .insertion_type = RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,                                .hash_func = RTE_FLOW_TABLE_HASH_FUNC_LINEAR,                                  };                struc                pt = create_pattern_template(port_id, error);                if (pt == NULL) {                                printf("Failed to create pattern template: %s (%d) \n",                                                                error.message, rte_errno);                                return NULL;                }                at = create_actions_template(port_id, error);                if (at == NULL) {                                printf("Failed to create actions template: %s (%d)\n",                                                error.message, rte_errno);                                return NULL;                }                   return rte_flow_template_table_create(port_id, &tbl_attr,                                                                                &pt, 1, &at, 1, error); }   void custom_hash_example(void) {                uint32_t idx;                uint16_t port_id = PORT_ID;                uint32_t queue_id = QUEUE_ID;                struct rte_flow_error error = { 0 };                struct rte_flow_op_attr attr = {                                .postpone = 0,                };                struct rte_flow_action_queue queue = {                                .index = 0                };                struct rte_flow_action actions[] = {                                [0] = { /* queue action. */                                .type = RTE_FLOW_ACTION_TYPE_QUEUE,                                .conf = &queue },                                [1] = { /* end action mast be the last action. */                                .type = RTE_FLOW_ACTION_TYPE_END,},                };                struct rte_flow_template_table * table;                struct rte_flow *flow;                   table = create_table(port_id, &error);                if (table == NULL) {                                printf("Failed to create template table: %s (%d)\n",                                                error.message, rte_errno);                                rte_exit(EXIT_FAILURE, "Exiting");                }                   for (idx = 0, idx < 4, idx++) {                                queue.index = idx;                                flow = rte_flow_async_create_by_index(port_id, queue_id,                                                                                &attr, table, idx, actions, 0, NULL, &error);                                if (flow == NULL) {                                                printf("Failed to enqueue flow create operation: %s (%d) \n",                                                                                error.message, rte_errno);                                                rte_exit(EXIT_FAILURE, "Exiting");                                };                } }

© Copyright 2024, NVIDIA. Last updated on Jan 9, 2025.