From: Danylo Vodopianov <dvo-...@napatech.com> flow filter ops and inline API was exnteded with next APIs: 1. flow pattern template create 2. flow pattern template destroy 3. flow actions template create 4. flow actions template destroy 5. flow template table create 6. flow template table destroy
Signed-off-by: Danylo Vodopianov <dvo-...@napatech.com> --- drivers/net/ntnic/include/flow_api_engine.h | 1 + drivers/net/ntnic/nthw/flow_api/flow_api.c | 104 ++++++++ .../profile_inline/flow_api_profile_inline.c | 225 ++++++++++++++++++ .../profile_inline/flow_api_profile_inline.h | 28 +++ drivers/net/ntnic/ntnic_mod_reg.h | 30 +++ 5 files changed, 388 insertions(+) diff --git a/drivers/net/ntnic/include/flow_api_engine.h b/drivers/net/ntnic/include/flow_api_engine.h index 6935ff483a..8604dde995 100644 --- a/drivers/net/ntnic/include/flow_api_engine.h +++ b/drivers/net/ntnic/include/flow_api_engine.h @@ -350,6 +350,7 @@ struct flow_handle { }; struct flow_pattern_template { + struct nic_flow_def *fd; }; struct flow_actions_template { diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c index 420f081178..111129a9ac 100644 --- a/drivers/net/ntnic/nthw/flow_api/flow_api.c +++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c @@ -1119,6 +1119,104 @@ static int flow_configure(struct flow_eth_dev *dev, uint8_t caller_id, * Flow Asynchronous operation API */ +static struct flow_pattern_template * +flow_pattern_template_create(struct flow_eth_dev *dev, + const struct rte_flow_pattern_template_attr *template_attr, uint16_t caller_id, + const struct rte_flow_item pattern[], struct rte_flow_error *error) +{ + const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops(); + + if (profile_inline_ops == NULL) { + NT_LOG_DBGX(ERR, FILTER, "profile_inline module uninitialized"); + return NULL; + } + + return profile_inline_ops->flow_pattern_template_create_profile_inline(dev, template_attr, + caller_id, pattern, error); +} + +static int flow_pattern_template_destroy(struct flow_eth_dev *dev, + struct flow_pattern_template *pattern_template, + struct rte_flow_error *error) +{ + const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops(); + + if (profile_inline_ops == NULL) { + NT_LOG_DBGX(ERR, FILTER, "profile_inline module uninitialized"); + return -1; + } + + return profile_inline_ops->flow_pattern_template_destroy_profile_inline(dev, + pattern_template, + error); +} + +static struct flow_actions_template * +flow_actions_template_create(struct flow_eth_dev *dev, + const struct rte_flow_actions_template_attr *template_attr, uint16_t caller_id, + const struct rte_flow_action actions[], const struct rte_flow_action masks[], + struct rte_flow_error *error) +{ + const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops(); + + if (profile_inline_ops == NULL) { + NT_LOG_DBGX(ERR, FILTER, "profile_inline module uninitialized"); + return NULL; + } + + return profile_inline_ops->flow_actions_template_create_profile_inline(dev, template_attr, + caller_id, actions, masks, error); +} + +static int flow_actions_template_destroy(struct flow_eth_dev *dev, + struct flow_actions_template *actions_template, + struct rte_flow_error *error) +{ + const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops(); + + if (profile_inline_ops == NULL) { + NT_LOG_DBGX(ERR, FILTER, "profile_inline module uninitialized"); + return -1; + } + + return profile_inline_ops->flow_actions_template_destroy_profile_inline(dev, + actions_template, + error); +} + +static struct flow_template_table *flow_template_table_create(struct flow_eth_dev *dev, + const struct rte_flow_template_table_attr *table_attr, uint16_t forced_vlan_vid, + uint16_t caller_id, struct flow_pattern_template *pattern_templates[], + uint8_t nb_pattern_templates, struct flow_actions_template *actions_templates[], + uint8_t nb_actions_templates, struct rte_flow_error *error) +{ + const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops(); + + if (profile_inline_ops == NULL) { + NT_LOG_DBGX(ERR, FILTER, "profile_inline module uninitialized"); + return NULL; + } + + return profile_inline_ops->flow_template_table_create_profile_inline(dev, table_attr, + forced_vlan_vid, caller_id, pattern_templates, nb_pattern_templates, + actions_templates, nb_actions_templates, error); +} + +static int flow_template_table_destroy(struct flow_eth_dev *dev, + struct flow_template_table *template_table, + struct rte_flow_error *error) +{ + const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops(); + + if (profile_inline_ops == NULL) { + NT_LOG_DBGX(ERR, FILTER, "profile_inline module uninitialized"); + return -1; + } + + return profile_inline_ops->flow_template_table_destroy_profile_inline(dev, template_table, + error); +} + static struct flow_handle * flow_async_create(struct flow_eth_dev *dev, uint32_t queue_id, const struct rte_flow_op_attr *op_attr, struct flow_template_table *template_table, @@ -1188,6 +1286,12 @@ static const struct flow_filter_ops ops = { */ .flow_info_get = flow_info_get, .flow_configure = flow_configure, + .flow_pattern_template_create = flow_pattern_template_create, + .flow_pattern_template_destroy = flow_pattern_template_destroy, + .flow_actions_template_create = flow_actions_template_create, + .flow_actions_template_destroy = flow_actions_template_destroy, + .flow_template_table_create = flow_template_table_create, + .flow_template_table_destroy = flow_template_table_destroy, .flow_async_create = flow_async_create, .flow_async_destroy = flow_async_destroy, diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c index d97206614b..89e7041350 100644 --- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c @@ -5507,6 +5507,223 @@ int flow_configure_profile_inline(struct flow_eth_dev *dev, uint8_t caller_id, return -1; } +struct flow_pattern_template *flow_pattern_template_create_profile_inline(struct flow_eth_dev *dev, + const struct rte_flow_pattern_template_attr *template_attr, uint16_t caller_id, + const struct rte_flow_item pattern[], struct rte_flow_error *error) +{ + (void)template_attr; + (void)caller_id; + uint32_t port_id = 0; + uint32_t packet_data[10]; + uint32_t packet_mask[10]; + struct flm_flow_key_def_s key_def; + + struct nic_flow_def *fd = allocate_nic_flow_def(); + + flow_nic_set_error(ERR_SUCCESS, error); + + if (fd == NULL) { + error->type = RTE_FLOW_ERROR_TYPE_UNSPECIFIED; + error->message = "Failed to allocate flow_def"; + return NULL; + } + + /* Note that forced_vlan_vid is unavailable at this point in time */ + int res = interpret_flow_elements(dev, pattern, fd, error, 0, &port_id, packet_data, + packet_mask, &key_def); + + if (res) { + free(fd); + return NULL; + } + + struct flow_pattern_template *template = calloc(1, sizeof(struct flow_pattern_template)); + + template->fd = fd; + + return template; +} + +int flow_pattern_template_destroy_profile_inline(struct flow_eth_dev *dev, + struct flow_pattern_template *pattern_template, + struct rte_flow_error *error) +{ + (void)dev; + flow_nic_set_error(ERR_SUCCESS, error); + + free(pattern_template->fd); + free(pattern_template); + + return 0; +} + +struct flow_actions_template * +flow_actions_template_create_profile_inline(struct flow_eth_dev *dev, + const struct rte_flow_actions_template_attr *template_attr, uint16_t caller_id, + const struct rte_flow_action actions[], + const struct rte_flow_action masks[], + struct rte_flow_error *error) +{ + (void)template_attr; + int res; + + uint32_t num_dest_port = 0; + uint32_t num_queues = 0; + + struct nic_flow_def *fd = allocate_nic_flow_def(); + + flow_nic_set_error(ERR_SUCCESS, error); + + if (fd == NULL) { + error->type = RTE_FLOW_ERROR_TYPE_UNSPECIFIED; + error->message = "Failed to allocate flow_def"; + return NULL; + } + + res = interpret_flow_actions(dev, actions, masks, fd, error, &num_dest_port, &num_queues); + + if (res) { + free(fd); + return NULL; + } + + /* Translate group IDs */ + if (fd->jump_to_group != UINT32_MAX) { + rte_spinlock_lock(&dev->ndev->mtx); + res = flow_group_translate_get(dev->ndev->group_handle, caller_id, + dev->port, fd->jump_to_group, &fd->jump_to_group); + rte_spinlock_unlock(&dev->ndev->mtx); + + if (res) { + NT_LOG(ERR, FILTER, "ERROR: Could not get group resource"); + flow_nic_set_error(ERR_MATCH_RESOURCE_EXHAUSTION, error); + free(fd); + return NULL; + } + } + + struct flow_actions_template *template = calloc(1, sizeof(struct flow_actions_template)); + + template->fd = fd; + template->num_dest_port = num_dest_port; + template->num_queues = num_queues; + + return template; +} + +int flow_actions_template_destroy_profile_inline(struct flow_eth_dev *dev, + struct flow_actions_template *actions_template, + struct rte_flow_error *error) +{ + (void)dev; + flow_nic_set_error(ERR_SUCCESS, error); + + free(actions_template->fd); + free(actions_template); + + return 0; +} + +struct flow_template_table *flow_template_table_create_profile_inline(struct flow_eth_dev *dev, + const struct rte_flow_template_table_attr *table_attr, uint16_t forced_vlan_vid, + uint16_t caller_id, + struct flow_pattern_template *pattern_templates[], uint8_t nb_pattern_templates, + struct flow_actions_template *actions_templates[], uint8_t nb_actions_templates, + struct rte_flow_error *error) +{ + flow_nic_set_error(ERR_SUCCESS, error); + + struct flow_template_table *template_table = calloc(1, sizeof(struct flow_template_table)); + + if (template_table == NULL) { + error->type = RTE_FLOW_ERROR_TYPE_UNSPECIFIED; + error->message = "Failed to allocate template_table"; + goto error_out; + } + + template_table->pattern_templates = + malloc(sizeof(struct flow_pattern_template *) * nb_pattern_templates); + template_table->actions_templates = + malloc(sizeof(struct flow_actions_template *) * nb_actions_templates); + template_table->pattern_action_pairs = + calloc((uint32_t)nb_pattern_templates * nb_actions_templates, + sizeof(struct flow_template_table_cell)); + + if (template_table->pattern_templates == NULL || + template_table->actions_templates == NULL || + template_table->pattern_action_pairs == NULL) { + error->type = RTE_FLOW_ERROR_TYPE_UNSPECIFIED; + error->message = "Failed to allocate template_table variables"; + goto error_out; + } + + template_table->attr.priority = table_attr->flow_attr.priority; + template_table->attr.group = table_attr->flow_attr.group; + template_table->forced_vlan_vid = forced_vlan_vid; + template_table->caller_id = caller_id; + + template_table->nb_pattern_templates = nb_pattern_templates; + template_table->nb_actions_templates = nb_actions_templates; + + memcpy(template_table->pattern_templates, pattern_templates, + sizeof(struct flow_pattern_template *) * nb_pattern_templates); + memcpy(template_table->actions_templates, actions_templates, + sizeof(struct rte_flow_actions_template *) * nb_actions_templates); + + rte_spinlock_lock(&dev->ndev->mtx); + int res = + flow_group_translate_get(dev->ndev->group_handle, caller_id, dev->port, + template_table->attr.group, &template_table->attr.group); + rte_spinlock_unlock(&dev->ndev->mtx); + + /* Translate group IDs */ + if (res) { + NT_LOG(ERR, FILTER, "ERROR: Could not get group resource"); + flow_nic_set_error(ERR_MATCH_RESOURCE_EXHAUSTION, error); + goto error_out; + } + + return template_table; + +error_out: + + if (template_table) { + free(template_table->pattern_templates); + free(template_table->actions_templates); + free(template_table->pattern_action_pairs); + free(template_table); + } + + return NULL; +} + +int flow_template_table_destroy_profile_inline(struct flow_eth_dev *dev, + struct flow_template_table *template_table, + struct rte_flow_error *error) +{ + flow_nic_set_error(ERR_SUCCESS, error); + + const uint32_t nb_cells = + template_table->nb_pattern_templates * template_table->nb_actions_templates; + + for (uint32_t i = 0; i < nb_cells; ++i) { + struct flow_template_table_cell *cell = &template_table->pattern_action_pairs[i]; + + if (cell->flm_db_idx_counter > 0) { + hw_db_inline_deref_idxs(dev->ndev, dev->ndev->hw_db_handle, + (struct hw_db_idx *)cell->flm_db_idxs, + cell->flm_db_idx_counter); + } + } + + free(template_table->pattern_templates); + free(template_table->actions_templates); + free(template_table->pattern_action_pairs); + free(template_table); + + return 0; +} + struct flow_handle *flow_async_create_profile_inline(struct flow_eth_dev *dev, uint32_t queue_id, const struct rte_flow_op_attr *op_attr, @@ -5757,6 +5974,14 @@ static const struct profile_inline_ops ops = { .flow_get_flm_stats_profile_inline = flow_get_flm_stats_profile_inline, .flow_info_get_profile_inline = flow_info_get_profile_inline, .flow_configure_profile_inline = flow_configure_profile_inline, + .flow_pattern_template_create_profile_inline = flow_pattern_template_create_profile_inline, + .flow_pattern_template_destroy_profile_inline = + flow_pattern_template_destroy_profile_inline, + .flow_actions_template_create_profile_inline = flow_actions_template_create_profile_inline, + .flow_actions_template_destroy_profile_inline = + flow_actions_template_destroy_profile_inline, + .flow_template_table_create_profile_inline = flow_template_table_create_profile_inline, + .flow_template_table_destroy_profile_inline = flow_template_table_destroy_profile_inline, .flow_async_create_profile_inline = flow_async_create_profile_inline, .flow_async_destroy_profile_inline = flow_async_destroy_profile_inline, /* diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h index b548142342..0dc89085ec 100644 --- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h @@ -73,6 +73,34 @@ int flow_get_flm_stats_profile_inline(struct flow_nic_dev *ndev, uint64_t *data, * RTE flow asynchronous operations functions */ +struct flow_pattern_template *flow_pattern_template_create_profile_inline(struct flow_eth_dev *dev, + const struct rte_flow_pattern_template_attr *template_attr, uint16_t caller_id, + const struct rte_flow_item pattern[], struct rte_flow_error *error); + +int flow_pattern_template_destroy_profile_inline(struct flow_eth_dev *dev, + struct flow_pattern_template *pattern_template, + struct rte_flow_error *error); + +struct flow_actions_template *flow_actions_template_create_profile_inline(struct flow_eth_dev *dev, + const struct rte_flow_actions_template_attr *template_attr, uint16_t caller_id, + const struct rte_flow_action actions[], const struct rte_flow_action masks[], + struct rte_flow_error *error); + +int flow_actions_template_destroy_profile_inline(struct flow_eth_dev *dev, + struct flow_actions_template *actions_template, + struct rte_flow_error *error); + +struct flow_template_table *flow_template_table_create_profile_inline(struct flow_eth_dev *dev, + const struct rte_flow_template_table_attr *table_attr, uint16_t forced_vlan_vid, + uint16_t caller_id, + struct flow_pattern_template *pattern_templates[], uint8_t nb_pattern_templates, + struct flow_actions_template *actions_templates[], uint8_t nb_actions_templates, + struct rte_flow_error *error); + +int flow_template_table_destroy_profile_inline(struct flow_eth_dev *dev, + struct flow_template_table *template_table, + struct rte_flow_error *error); + struct flow_handle *flow_async_create_profile_inline(struct flow_eth_dev *dev, uint32_t queue_id, const struct rte_flow_op_attr *op_attr, struct flow_template_table *template_table, const struct rte_flow_item pattern[], diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h index e8e7090661..eb764356eb 100644 --- a/drivers/net/ntnic/ntnic_mod_reg.h +++ b/drivers/net/ntnic/ntnic_mod_reg.h @@ -314,6 +314,36 @@ struct profile_inline_ops { * RTE flow asynchronous operations functions */ + struct flow_pattern_template *(*flow_pattern_template_create_profile_inline) + (struct flow_eth_dev *dev, + const struct rte_flow_pattern_template_attr *template_attr, uint16_t caller_id, + const struct rte_flow_item pattern[], struct rte_flow_error *error); + + int (*flow_pattern_template_destroy_profile_inline)(struct flow_eth_dev *dev, + struct flow_pattern_template *pattern_template, + struct rte_flow_error *error); + + struct flow_actions_template *(*flow_actions_template_create_profile_inline) + (struct flow_eth_dev *dev, + const struct rte_flow_actions_template_attr *template_attr, + uint16_t caller_id, const struct rte_flow_action actions[], + const struct rte_flow_action masks[], struct rte_flow_error *error); + + int (*flow_actions_template_destroy_profile_inline)(struct flow_eth_dev *dev, + struct flow_actions_template *actions_template, + struct rte_flow_error *error); + + struct flow_template_table *(*flow_template_table_create_profile_inline) + (struct flow_eth_dev *dev, const struct rte_flow_template_table_attr *table_attr, + uint16_t forced_vlan_vid, uint16_t caller_id, + struct flow_pattern_template *pattern_templates[], uint8_t nb_pattern_templates, + struct flow_actions_template *actions_templates[], uint8_t nb_actions_templates, + struct rte_flow_error *error); + + int (*flow_template_table_destroy_profile_inline)(struct flow_eth_dev *dev, + struct flow_template_table *template_table, + struct rte_flow_error *error); + struct flow_handle *(*flow_async_create_profile_inline)(struct flow_eth_dev *dev, uint32_t queue_id, const struct rte_flow_op_attr *op_attr, struct flow_template_table *template_table, const struct rte_flow_item pattern[], -- 2.45.0