ethdev: add indirect list flow action
PATCH 1/1 ethdev: add indirect list flow action
Indirect flow action provides a handler to hardware flow action object. The handler is used in flow rules for sharing hardware action object state.
Current INDIRECT flow handler can reference a single flow action type.
New INDIRECT_LIST extends existing functionality. INDIRECT_LIST flow handler can reference one or many flow actions.
testpmd example:
set raw_encap 0 \
eth src is 11:00:00:00:00:11 dst is aa:00:00:00:00:aa / \
ipv4 src is 1.1.1.1 dst is 2.2.2.2 ttl is 64 proto is 17 / \
udp src is 0x1234 dst is 4789 / vxlan vni is 0xabcd / end_set set raw_encap 1 \
eth src is 22:00:00:00:00:22 dst is bb:00:00:00:00:bb / \
ipv6 src is 2001::1111 dst is 2001::2222 proto is 17 / \
udp src is 0x1234 dst is 4789 / vxlan vni is 0xabcd / end_set
set sample_actions 0 \raw_encap index 0 / represented_port ethdev_port_id 0 / end set sample_actions 1 \raw_encap index 1 / represented_port ethdev_port_id 0 / end
flow indirect_action 0 create transfer list actions \
sample ratio 1 index 0 / \
sample ratio 1 index 1 / \
jump group 0xcaca / end
flow actions_template 0 create transfer actions_template_id 10 \
template indirect_list 0 / end mask indirect_list / end
--- app/test-pmd/cmdline_flow.c | 41 ++++++- app/test-pmd/config.c | 162 +++++++++++++++++++------ app/test-pmd/testpmd.h | 7 +- doc/guides/nics/features/default.ini | 1 + doc/guides/prog_guide/rte_flow.rst | 6 + doc/guides/rel_notes/release_23_07.rst | 4 + lib/ethdev/rte_flow.c | 92 ++++++++++++++ lib/ethdev/rte_flow.h | 149 +++++++++++++++++++++++ lib/ethdev/rte_flow_driver.h | 27 ++++- lib/ethdev/version.map | 4 + 10 files changed, 452 insertions(+), 41 deletions(-)
app/test-pmd/cmdline_flow.c +40 -1
@@ -145,6 +145,7 @@ enum index {/* Queue indirect action arguments */ QUEUE_INDIRECT_ACTION_CREATE , +QUEUE_INDIRECT_ACTION_LIST_CREATE ,QUEUE_INDIRECT_ACTION_UPDATE ,QUEUE_INDIRECT_ACTION_DESTROY , QUEUE_INDIRECT_ACTION_QUERY,
@@ -157,6 +158,7 @@ enum index {QUEUE_INDIRECT_ACTION_TRANSFER ,QUEUE_INDIRECT_ACTION_CREATE_POSTPONE ,QUEUE_INDIRECT_ACTION_SPEC , +QUEUE_INDIRECT_ACTION_LIST ,/* Queue indirect action update arguments */ QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE,
@@ -242,6 +244,7 @@ enum index {/* Indirect action arguments */ INDIRECT_ACTION_CREATE , +INDIRECT_ACTION_LIST_CREATE ,INDIRECT_ACTION_UPDATE ,INDIRECT_ACTION_DESTROY , INDIRECT_ACTION_QUERY,
@@ -253,6 +256,7 @@ enum index {INDIRECT_ACTION_EGRESS ,INDIRECT_ACTION_TRANSFER ,INDIRECT_ACTION_SPEC , +INDIRECT_ACTION_LIST ,/* Indirect action destroy arguments */ INDIRECT_ACTION_DESTROY_ID,
@@ -626,6 +630,7 @@ enum index {ACTION_SAMPLE_INDEX ,ACTION_SAMPLE_INDEX_VALUE ,ACTION_INDIRECT , +ACTION_INDIRECT_LIST ,ACTION_SHARED_INDIRECT ,INDIRECT_ACTION_PORT , INDIRECT_ACTION_ID2PTR,
@@ -1266,6 +1271,7 @@ static const enum index next_qia_create_attr[] = {QUEUE_INDIRECT_ACTION_TRANSFER ,QUEUE_INDIRECT_ACTION_CREATE_POSTPONE ,QUEUE_INDIRECT_ACTION_SPEC , +QUEUE_INDIRECT_ACTION_LIST , ZERO, };
@@ -1294,6 +1300,7 @@ static const enum index next_ia_create_attr[] = {INDIRECT_ACTION_EGRESS ,INDIRECT_ACTION_TRANSFER ,INDIRECT_ACTION_SPEC , +INDIRECT_ACTION_LIST , ZERO, };
@@ -2013,6 +2020,7 @@ static const enum index next_action[] = {ACTION_AGE_UPDATE ,ACTION_SAMPLE ,ACTION_INDIRECT , +ACTION_INDIRECT_LIST ,ACTION_SHARED_INDIRECT ,ACTION_MODIFY_FIELD , ACTION_CONNTRACK,
@@ -2289,6 +2297,7 @@ static const enum index next_action_sample[] = {ACTION_RAW_ENCAP ,ACTION_VXLAN_ENCAP ,ACTION_NVGRE_ENCAP , +ACTION_REPRESENTED_PORT ,ACTION_NEXT , ZERO, };
@@ -3426,6 +3435,12 @@ static const struct token token_list[] = { .help = "specify action to create indirect handle", .next = NEXT(next_action), }, + [QUEUE_INDIRECT_ACTION_LIST] = { + .name = "list", + .help = "specify actions for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_qia, + },/* Top-level command. */ [PUSH] = { .name = "push",
@@ -6775,6 +6790,14 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), .call = parse_vc, }, + [ACTION_INDIRECT_LIST] = { + .name = "indirect_list", + .help = "apply indirect list action by id", + .priv = PRIV_ACTION(INDIRECT_LIST, 0), + .next = NEXT(next_ia), + .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), + .call = parse_vc, + }, [ACTION_SHARED_INDIRECT] = { .name = "shared_indirect", .help = "apply indirect action by id and port",
@@ -6823,6 +6846,12 @@ static const struct token token_list[] = { .help = "specify action to create indirect handle", .next = NEXT(next_action), }, + [INDIRECT_ACTION_LIST] = { + .name = "list", + .help = "specify actions for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_ia, + }, [ACTION_POL_G] = { .name = "g_actions", .help = "submit a list of associated actions for green",
@@ -7181,6 +7210,9 @@ parse_ia(struct context *ctx, const struct token *token,return len;case INDIRECT_ACTION_QU_MODE :return len; +case INDIRECT_ACTION_LIST : + out->command =INDIRECT_ACTION_LIST_CREATE ; +return len;default :return -1 ; }
@@ -7278,6 +7310,9 @@ parse_qia(struct context *ctx, const struct token *token,return len;case QUEUE_INDIRECT_ACTION_QU_MODE :return len; +case QUEUE_INDIRECT_ACTION_LIST : + out->command =QUEUE_INDIRECT_ACTION_LIST_CREATE ; +return len;default :return -1 ; }
@@ -7454,10 +7489,12 @@ parse_vc(struct context *ctx, const struct token *token,return -1 ;break ;case ACTIONS : - out->args.vc.actions = + out->args.vc.actions = out->args.vc.pattern ? (void *)RTE_ALIGN_CEIL ((uintptr_t ) (out->args.vc.pattern + out->args.vc.pattern_n), +sizeof (double )) : + (void *)RTE_ALIGN_CEIL ((uintptr_t )(out +1 ),sizeof (double )); ctx->object = out->args.vc.actions; ctx->objmask =NULL ;
@@ -11532,6 +11569,7 @@ cmd_flow_parsed(const struct buffer *in) in->args.aged.destroy);break ;case QUEUE_INDIRECT_ACTION_CREATE : +case QUEUE_INDIRECT_ACTION_LIST_CREATE : port_queue_action_handle_create( in->port, in->queue, in->postpone, in->args.vc.attr.group,
@@ -11567,6 +11605,7 @@ cmd_flow_parsed(const struct buffer *in) in->args.vc.actions);break ;case INDIRECT_ACTION_CREATE : +case INDIRECT_ACTION_LIST_CREATE : port_action_handle_create( in->port, in->args.vc.attr.group, &((const struct rte_flow_indir_action_conf) {
app/test-pmd/config.c +124 -38
228 lines not on this page · raw message
app/test-pmd/testpmd.h +6 -1
@@ -228,7 +228,12 @@ struct port_indirect_action {struct port_indirect_action *next;/**< Next flow in list. */ uint32_t id;/**< Indirect action ID. */ enum rte_flow_action_type type;/**< Action type. */ -struct rte_flow_action_handle *handle;/**< Indirect action handle. */ +union { +struct rte_flow_action_handle *handle; +/**< Indirect action handle. */ +struct rte_flow_action_list_handle *list_handle; +/**< Indirect action list handle*/ + };enum age_action_context_type age_type;/**< Age action context type. */ };
doc/guides/nics/features/default.ini +1 -0
@@ -158,6 +158,7 @@ drop = flag = inc_tcp_ack = inc_tcp_seq = +indirect_list = jump = mac_swap = mark =
doc/guides/prog_guide/rte_flow.rst +6 -0
@@ -3300,6 +3300,12 @@ The ``quota`` value is reduced according to ``mode`` setting. | ``RTE_FLOW_QUOTA_MODE_L3`` | Count packet bytes starting from L3 | +------------------+----------------------------------------------------+ +Action: ``INDIRECT_LIST`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The new ``INDIRECT_LIST`` flow action references one or many flow actions. +Extends the ``INDIRECT`` flow action. + Negative types ~~~~~~~~~~~~~~
doc/guides/rel_notes/release_23_07.rst +4 -0
@@ -55,6 +55,10 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= + * **Added indirect list flow action.** + + * ``RTE_FLOW_ACTION_TYPE_INDIRECT_LIST`` + Removed Items -------------
lib/ethdev/rte_flow.c +92 -0
101 lines not on this page · raw message
lib/ethdev/rte_flow.h +149 -0
161 lines not on this page · raw message
lib/ethdev/rte_flow_driver.h +26 -1
@@ -121,6 +121,17 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_create() */ +struct rte_flow_action_list_handle *(*action_list_handle_create) + (struct rte_eth_dev *dev, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action actions[], +struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_destroy() */ +int (*action_list_handle_destroy) + (struct rte_eth_dev *dev, +struct rte_flow_action_list_handle *handle, +struct rte_flow_error *error);/** See rte_flow_tunnel_decap_set() */ int (*tunnel_decap_set) (struct rte_eth_dev *dev,
@@ -294,7 +305,7 @@ struct rte_flow_ops {void *data, void *user_data, struct rte_flow_error *error); -/** See rte_flow_async_action_handle_query_update */ +/** @see rte_flow_async_action_handle_query_update */ int (*async_action_handle_query_update) (struct rte_eth_dev *dev, uint32_t queue_id, const struct rte_flow_op_attr *op_attr,
@@ -302,6 +313,20 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, void *user_data, struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_create() */ +struct rte_flow_action_list_handle * + (*async_action_list_handle_create) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_destroy() */ +int (*async_action_list_handle_destroy) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *action_handle, +void *user_data,struct rte_flow_error *error); };/**
lib/ethdev/version.map +4 -0
@@ -299,6 +299,10 @@ EXPERIMENTAL { rte_flow_action_handle_query_update; rte_flow_async_action_handle_query_update; rte_flow_async_create_by_index; + rte_flow_action_list_handle_create; + rte_flow_action_list_handle_destroy; + rte_flow_async_action_list_handle_create; + rte_flow_async_action_list_handle_destroy; }; INTERNAL {
Signature · 1 line
2.34.1
RFC PATCH v2 1/1 ethdev: add indirect list flow action
Indirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.
Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.
Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.
There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.
flow 1:
/ indirect handle H conf C1 /
| |
| |
| | flow 2:
| | / indirect handle H conf C2 /
| | | |
| | | |
| | | |
=========================================================
^ | | | |
| | V | V
| ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
| flow mutable flow mutable
| context 1 context 2
| ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
indirect | | |
action | | |
context | V V
| -----------------------------------------------------
| action mutable context
| ----------------------------------------------------- v action immutable context
=========================================================
Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• Indirect METER_MARK policy is immutable action member and profile is action mutable action member.
• Indirect METER_MARK flow action defines init_color as flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.
Indirect action lists action will deprecate and replace existing indirect action after transition period.
Template API:
Action template format:
template .. indirect_list handle Htmpl conf Ctmpl ..
mask .. indirect_list handle Hmask conf Cmask ..
1 If Htmpl was masked (Hmask != 0), PMD compiles base action
configuration during action template, table template and flow rule phases - depending on PMD action implementation. Otherwise, action is compiled from scratch during flow rule processing.
2 If Htmpl and Ctmpl were masked (Hmask !=0 and Cmask != 0), table
template processing overwrites base action configuration with Ctmpl parameters.
Flow rule format:
actions .. indirect_list handle Hflow conf Cflow ..
3 If Htmpl was masked, Hflow can reference a different action of the
same type as Htmpl.
4 If Cflow was specified, it overwrites action configuration.
--- lib/ethdev/rte_flow.h | 266 +++++++++++++++++++++++++++++++++++ lib/ethdev/rte_flow_driver.h | 41 ++++++ 2 files changed, 307 insertions(+)
lib/ethdev/rte_flow.h +266 -0
@@ -2912,6 +2912,13 @@ enum rte_flow_action_type {* applied to the given ethdev Rx queue. */ RTE_FLOW_ACTION_TYPE_SKIP_CMAN , + +/** +* Action handle to reference flow actions list. +* +* @see struct rte_flow_action_indirect_list +*/ + RTE_FLOW_ACTION_TYPE_INDIRECT_LIST, };/**
@@ -6118,6 +6125,265 @@ rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id,void *user_data, struct rte_flow_error *error); +struct rte_flow_action_list_handle ; + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Configure INDIRECT_LIST flow action. +* +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +*/ +struct rte_flow_action_indirect_list { +struct rte_flow_action_list_handle ;/**< Indirect action list handle */ +/** +* Flow mutable configuration array. +* NULL if the handle has no flow mutable configuration update. +* Otherwise, if the handle was created with list A1 / A2 .. An / END +* size of conf is n. +* conf[i] points to flow mutable update of Ai in the handle +* actions list or NULL if Ai has no update. +*/ +const void **conf; +}; + + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Create an indirect flow action object from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action lists. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set +* to one of the error codes defined: +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-EINVAL) if *actions* list invalid. +* - (-ENOTSUP) if *action* list element valid but unsupported. +* - (-E2BIG) to many elements in *actions* +*/ +__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_action_list_handle_create (uint16_t port_id, +const +struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Async function call to create an indirect flow action object +* from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] queue_id +* Flow queue which is used to update the rule. +* @param[in] attr +* Indirect action update operation attributes. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action list. +* @param[in] user_data +* The user data that will be returned on async completion event. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set +* to one of the error codes defined: +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-EINVAL) if *actions* list invalid. +* - (-ENOTSUP) if *action* list element valid but unsupported. +* - (-E2BIG) to many elements in *actions* +*/ +__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_async_action_list_handle_create (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct +rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +void *user_data, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Destroy indirect actions list by handle. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] handle +* Handle for the indirect actions list to be destroyed. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* - (0) if success. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-ENOENT) if actions list pointed by *action* handle was not found. +* - (-EBUSY) if actions list pointed by *action* handle still used +* rte_errno is also set. +*/ +__rte_experimental +int +rte_flow_action_list_handle_destroy (uint16_t port_id, +struct rte_flow_action_list_handle *handle, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue indirect action list destruction operation. +* The destroy queue must be the same +* as the queue on which the action was created. +* +* @param[in] port_id +* Port identifier of Ethernet device. +* @param[in] queue_id +* Flow queue which is used to destroy the rule. +* @param[in] op_attr +* Indirect action destruction operation attributes. +* @param[in] handle +* Handle for the indirect action object to be destroyed. +* @param[in] user_data +* The user data that will be returned on the completion events. +* @param[out] error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_destroy + (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *handle, +void *user_data,struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Query and/or update indirect flow actions list. +* If both query and update not NULL, the function atomically +* queries and updates indirect action. Query and update are carried in order +* specified in the mode parameter. +* If ether query or update is NULL, the function executes +* complementing operation. +* +* @param port_id +* Port identifier of Ethernet device. +* @param handle +* Handle for the indirect actions list object to be updated. +* @param update +* If not NULL, update profile specification used to modify the action +* pointed by handle. +* @see struct rte_flow_action_indirect_list +* @param query +* If not NULL pointer to storage for the associated query data type. +* @see struct rte_flow_action_indirect_list +* @param mode +* Operational mode. +* @param error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOTSUP) if underlying device does not support this functionality. +* - (-EINVAL) if *handle* or *mode* invalid or +* both *query* and *update* are NULL. +*/ +__rte_experimental +int +rte_flow_action_list_handle_query_update (uint16_t port_id, +const struct +rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue async indirect flow actions list query and/or update +* +* @param port_id +* Port identifier of Ethernet device. +* @param queue_id +* Flow queue which is used to update the rule. +* @param attr +* Indirect action update operation attributes. +* @param handle +* Handle for the indirect actions list object to be updated. +* @param update +* If not NULL, update profile specification used to modify the action +* pointed by handle. +* @see struct rte_flow_action_indirect_list +* @param query +* If not NULL, pointer to storage for the associated query data type. +* Query result returned on async completion event. +* @see struct rte_flow_action_indirect_list +* @param mode +* Operational mode. +* @param user_data +* The user data that will be returned on async completion event. +* @param error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOTSUP) if underlying device does not support this functionality. +* - (-EINVAL) if *handle* or *mode* invalid or +* both *update* and *query* are NULL. +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_query_update (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct +rte_flow_action_list_handle *handle, +const void *update,void *query, +enum rte_flow_query_update_mode mode, +void *user_data, +struct rte_flow_error *error); + + #ifdef __cplusplus }#endif
lib/ethdev/rte_flow_driver.h +41 -0
53 lines not on this page · raw message
Signature · 1 line
2.34.1
Hi Gregory,
Overall, the idea of action list indirection sounds good. But why deprecate the existing indirect action API? Are there any strong reasons for that? This action should probably stay. Well, at least, I wouldn't expect this patch to immediately introduce some transition period. Let's cross that bridge
when we get there. What do you think?
Also, what are the target applications/projects to benefit from the new indirect action list API? Could you please provide some examples. Or, alternatively, you could shed light on which "shapes" of flow rules would
be the primary users of the action.
Thank you.
Quoted 448 lines · Gregory Etelson
Indirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.flow 1:
/ indirect handle H conf C1 /| | | | | | flow 2: | | / indirect handle H conf C2 / | | | | | | | | | | | | ========================================================= ^ | | | | | | V | V | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ | flow mutable flow mutable | context 1 context 2 | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ indirect | | | action | | | context | V V | ----------------------------------------------------- | action mutable context | -----------------------------------------------------v action immutable context
=========================================================Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• IndirectMETER_MARKpolicy is immutable action member and profile is action mutable action member.
• IndirectMETER_MARKflow action definesinit_coloras flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.Indirect action lists action will deprecate and replace existing indirect action after transition period.
Template API:
Action template format:
template ..
indirect_listhandle Htmpl conf Ctmpl ..
mask ..indirect_listhandle Hmask conf Cmask ..1 If Htmpl was masked (Hmask != 0), PMD compiles base action
configuration during action template, table template and flow rule phases - depending on PMD action implementation. Otherwise, action is compiled from scratch during flow rule processing.2 If Htmpl and Ctmpl were masked (Hmask !=0 and Cmask != 0), table
template processing overwrites base action configuration with Ctmpl parameters.Flow rule format:
actions ..
indirect_listhandle Hflow conf Cflow ..3 If Htmpl was masked, Hflow can reference a different action of the
same type as Htmpl.4 If Cflow was specified, it overwrites action configuration.
Signed-off-by Gregory Etelson <[email protected]>---
lib/ethdev/rte_flow.h| 266 +++++++++++++++++++++++++++++++++++lib/ethdev/rte_flow_driver.h| 41 ++++++2 files changed, 307 insertions(+)lib/ethdev/rte_flow.h +266
-0@@ -2912,6 +2912,13 @@ enum rte_flow_action_type {* applied to the given ethdev Rx queue. */ RTE_FLOW_ACTION_TYPE_SKIP_CMAN , + +/** +* Action handle to reference flow actions list. +* +* @see struct rte_flow_action_indirect_list +*/ + RTE_FLOW_ACTION_TYPE_INDIRECT_LIST, };/** @@ -6118,6 +6125,265 @@ rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id,void *user_data, struct rte_flow_error *error); +struct rte_flow_action_list_handle ; + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Configure INDIRECT_LIST flow action. +* +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +*/ +struct rte_flow_action_indirect_list { +struct rte_flow_action_list_handle ;/**< Indirect action list handle */ +/** +* Flow mutable configuration array. +* NULL if the handle has no flow mutable configuration update. +* Otherwise, if the handle was created with list A1 / A2 .. An / END +* size of conf is n. +* conf[i] points to flow mutable update of Ai in the handle +* actions list or NULL if Ai has no update. +*/ +const void **conf; +}; + + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Create an indirect flow action object from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action lists. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set +* to one of the error codes defined: +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-EINVAL) if *actions* list invalid. +* - (-ENOTSUP) if *action* list element valid but unsupported. +* - (-E2BIG) to many elements in *actions* +*/ +__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_action_list_handle_create (uint16_t port_id, +const +struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Async function call to create an indirect flow action object +* from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] queue_id +* Flow queue which is used to update the rule. +* @param[in] attr +* Indirect action update operation attributes. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action list. +* @param[in] user_data +* The user data that will be returned on async completion event. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set +* to one of the error codes defined: +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-EINVAL) if *actions* list invalid. +* - (-ENOTSUP) if *action* list element valid but unsupported. +* - (-E2BIG) to many elements in *actions* +*/ +__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_async_action_list_handle_create (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct +rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +void *user_data, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Destroy indirect actions list by handle. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] handle +* Handle for the indirect actions list to be destroyed. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* - (0) if success. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-ENOENT) if actions list pointed by *action* handle was not found. +* - (-EBUSY) if actions list pointed by *action* handle still used +* rte_errno is also set. +*/ +__rte_experimental +int +rte_flow_action_list_handle_destroy (uint16_t port_id, +struct rte_flow_action_list_handle *handle, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue indirect action list destruction operation. +* The destroy queue must be the same +* as the queue on which the action was created. +* +* @param[in] port_id +* Port identifier of Ethernet device. +* @param[in] queue_id +* Flow queue which is used to destroy the rule. +* @param[in] op_attr +* Indirect action destruction operation attributes. +* @param[in] handle +* Handle for the indirect action object to be destroyed. +* @param[in] user_data +* The user data that will be returned on the completion events. +* @param[out] error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_destroy + (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *handle, +void *user_data,struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Query and/or update indirect flow actions list. +* If both query and update not NULL, the function atomically +* queries and updates indirect action. Query and update are carried in order +* specified in the mode parameter. +* If ether query or update is NULL, the function executes +* complementing operation. +* +* @param port_id +* Port identifier of Ethernet device. +* @param handle +* Handle for the indirect actions list object to be updated. +* @param update +* If not NULL, update profile specification used to modify the action +* pointed by handle. +* @see struct rte_flow_action_indirect_list +* @param query +* If not NULL pointer to storage for the associated query data type. +* @see struct rte_flow_action_indirect_list +* @param mode +* Operational mode. +* @param error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOTSUP) if underlying device does not support this functionality. +* - (-EINVAL) if *handle* or *mode* invalid or +* both *query* and *update* are NULL. +*/ +__rte_experimental +int +rte_flow_action_list_handle_query_update (uint16_t port_id, +const struct +rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue async indirect flow actions list query and/or update +* +* @param port_id +* Port identifier of Ethernet device. +* @param queue_id +* Flow queue which is used to update the rule. +* @param attr +* Indirect action update operation attributes. +* @param handle +* Handle for the indirect actions list object to be updated. +* @param update +* If not NULL, update profile specification used to modify the action +* pointed by handle. +* @see struct rte_flow_action_indirect_list +* @param query +* If not NULL, pointer to storage for the associated query data type. +* Query result returned on async completion event. +* @see struct rte_flow_action_indirect_list +* @param mode +* Operational mode. +* @param user_data +* The user data that will be returned on async completion event. +* @param error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOTSUP) if underlying device does not support this functionality. +* - (-EINVAL) if *handle* or *mode* invalid or +* both *update* and *query* are NULL. +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_query_update (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct +rte_flow_action_list_handle *handle, +const void *update,void *query, +enum rte_flow_query_update_mode mode, +void *user_data, +struct rte_flow_error *error); + + #ifdef __cplusplus }#endif lib/ethdev/rte_flow_driver.h +41
-0@@ -121,6 +121,17 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_create() */ +struct rte_flow_action_list_handle *(*action_list_handle_create) + (struct rte_eth_dev *dev, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action actions[], +struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_destroy() */ +int (*action_list_handle_destroy) + (struct rte_eth_dev *dev, +struct rte_flow_action_list_handle *handle, +struct rte_flow_error *error);/** See rte_flow_tunnel_decap_set() */ int (*tunnel_decap_set) (struct rte_eth_dev *dev,@@ -302,6 +313,36 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, void *user_data, struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_create() */ +struct rte_flow_action_list_handle * + (*async_action_list_handle_create) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_destroy() */ +int (*async_action_list_handle_destroy) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *action_handle, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_query_update() */ +int (*action_list_handle_query_update) + (uint16_t port_id, +const struct rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_query_update() */ +int (*async_action_list_handle_query_update) + (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +void *user_data,struct rte_flow_error *error); + };/** Signature · 1 line
2.34.1
Hello Ivan,
Quoted 2 lines
Overall, the idea of action list indirection sounds good. But why deprecate the existing indirect action API?
Deprecation is not necessary.
If the decision is to keep existing indirect action API, it must be updated to differentiate between action mutable and flow mutable update parameters.
Quoted 6 lines
Are there any strong reasons for that? This action should probably stay. Well, at least, I wouldn't expect this patch to immediately introduce some transition period. Let's cross that bridge when we get there. What do you think?
Quoted 7 lines
Also, what are the target applications/projects to benefit from the new indirect action list API? Could you please provide some examples. Or, alternatively, you could shed light on which "shapes" of flow rules would
be the primary users of the action.
We have 2 usages for the new indirect list API
1. Create single HW action from input list of RTE actions.
For example, MLX5 template API will create single mirror HW action from SAMPLE / JUMP list.
2. METER_MARK init_color and CONNTRACK last_direction parameters are flow mutable, by the actions definitions. However, current indirect action cannot update flow parameters.
Regards,
Gregory
RFC PATCH v3 1/1 ethdev: add indirect list flow action
In reply to Gregory EtelsonIndirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.
Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.
Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.
There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.
flow 1:
/ indirect handle H conf C1 /
| |
| |
| | flow 2:
| | / indirect handle H conf C2 /
| | | |
| | | |
| | | |
=========================================================
^ | | | |
| | V | V
| ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
| flow mutable flow mutable
| context 1 context 2
| ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
indirect | | |
action | | |
context | V V
| -----------------------------------------------------
| action mutable context
| ----------------------------------------------------- v action immutable context
=========================================================
Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• Indirect METER_MARK policy is immutable action member and profile is action mutable action member.
• Indirect METER_MARK flow action defines init_color as flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.
Template API:
Action template format:
template .. indirect_list handle Htmpl conf Ctmpl ..
mask .. indirect_list handle Hmask conf Cmask ..
1 If Htmpl was masked (Hmask != 0), PMD compiles base action
configuration during action template, table template and flow rule phases - depending on PMD action implementation. Otherwise, action is compiled from scratch during flow rule processing.
2 If Htmpl and Ctmpl were masked (Hmask !=0 and Cmask != 0), table
template processing overwrites base action configuration with Ctmpl parameters.
Flow rule format:
actions .. indirect_list handle Hflow conf Cflow ..
3 If Htmpl was masked, Hflow can reference a different action of the
same type as Htmpl.
4 If Cflow was specified, it overwrites action configuration.
---
v3: do not deprecate indirect flow action.
--- lib/ethdev/rte_flow.h | 266 +++++++++++++++++++++++++++++++++++ lib/ethdev/rte_flow_driver.h | 41 ++++++ 2 files changed, 307 insertions(+)
lib/ethdev/rte_flow.h +266 -0
@@ -2912,6 +2912,13 @@ enum rte_flow_action_type {* applied to the given ethdev Rx queue. */ RTE_FLOW_ACTION_TYPE_SKIP_CMAN , + +/** +* Action handle to reference flow actions list. +* +* @see struct rte_flow_action_indirect_list +*/ + RTE_FLOW_ACTION_TYPE_INDIRECT_LIST, };/**
@@ -6118,6 +6125,265 @@ rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id,void *user_data, struct rte_flow_error *error); +struct rte_flow_action_list_handle ; + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Configure INDIRECT_LIST flow action. +* +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +*/ +struct rte_flow_action_indirect_list { +struct rte_flow_action_list_handle ;/**< Indirect action list handle */ +/** +* Flow mutable configuration array. +* NULL if the handle has no flow mutable configuration update. +* Otherwise, if the handle was created with list A1 / A2 .. An / END +* size of conf is n. +* conf[i] points to flow mutable update of Ai in the handle +* actions list or NULL if Ai has no update. +*/ +const void **conf; +}; + + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Create an indirect flow action object from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action lists. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set +* to one of the error codes defined: +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-EINVAL) if *actions* list invalid. +* - (-ENOTSUP) if *action* list element valid but unsupported. +* - (-E2BIG) to many elements in *actions* +*/ +__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_action_list_handle_create (uint16_t port_id, +const +struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Async function call to create an indirect flow action object +* from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] queue_id +* Flow queue which is used to update the rule. +* @param[in] attr +* Indirect action update operation attributes. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action list. +* @param[in] user_data +* The user data that will be returned on async completion event. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set +* to one of the error codes defined: +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-EINVAL) if *actions* list invalid. +* - (-ENOTSUP) if *action* list element valid but unsupported. +* - (-E2BIG) to many elements in *actions* +*/ +__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_async_action_list_handle_create (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct +rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +void *user_data, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Destroy indirect actions list by handle. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] handle +* Handle for the indirect actions list to be destroyed. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* - (0) if success. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-ENOENT) if actions list pointed by *action* handle was not found. +* - (-EBUSY) if actions list pointed by *action* handle still used +* rte_errno is also set. +*/ +__rte_experimental +int +rte_flow_action_list_handle_destroy (uint16_t port_id, +struct rte_flow_action_list_handle *handle, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue indirect action list destruction operation. +* The destroy queue must be the same +* as the queue on which the action was created. +* +* @param[in] port_id +* Port identifier of Ethernet device. +* @param[in] queue_id +* Flow queue which is used to destroy the rule. +* @param[in] op_attr +* Indirect action destruction operation attributes. +* @param[in] handle +* Handle for the indirect action object to be destroyed. +* @param[in] user_data +* The user data that will be returned on the completion events. +* @param[out] error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_destroy + (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *handle, +void *user_data,struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Query and/or update indirect flow actions list. +* If both query and update not NULL, the function atomically +* queries and updates indirect action. Query and update are carried in order +* specified in the mode parameter. +* If ether query or update is NULL, the function executes +* complementing operation. +* +* @param port_id +* Port identifier of Ethernet device. +* @param handle +* Handle for the indirect actions list object to be updated. +* @param update +* If not NULL, update profile specification used to modify the action +* pointed by handle. +* @see struct rte_flow_action_indirect_list +* @param query +* If not NULL pointer to storage for the associated query data type. +* @see struct rte_flow_action_indirect_list +* @param mode +* Operational mode. +* @param error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOTSUP) if underlying device does not support this functionality. +* - (-EINVAL) if *handle* or *mode* invalid or +* both *query* and *update* are NULL. +*/ +__rte_experimental +int +rte_flow_action_list_handle_query_update (uint16_t port_id, +const struct +rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue async indirect flow actions list query and/or update +* +* @param port_id +* Port identifier of Ethernet device. +* @param queue_id +* Flow queue which is used to update the rule. +* @param attr +* Indirect action update operation attributes. +* @param handle +* Handle for the indirect actions list object to be updated. +* @param update +* If not NULL, update profile specification used to modify the action +* pointed by handle. +* @see struct rte_flow_action_indirect_list +* @param query +* If not NULL, pointer to storage for the associated query data type. +* Query result returned on async completion event. +* @see struct rte_flow_action_indirect_list +* @param mode +* Operational mode. +* @param user_data +* The user data that will be returned on async completion event. +* @param error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOTSUP) if underlying device does not support this functionality. +* - (-EINVAL) if *handle* or *mode* invalid or +* both *update* and *query* are NULL. +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_query_update (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct +rte_flow_action_list_handle *handle, +const void *update,void *query, +enum rte_flow_query_update_mode mode, +void *user_data, +struct rte_flow_error *error); + + #ifdef __cplusplus }#endif
lib/ethdev/rte_flow_driver.h +41 -0
53 lines not on this page · raw message
Signature · 1 line
2.34.1
Hi Gregory
First I'm assuming this is just RFC, since there is no code implementation.
Quoted 74 lines
-----Original Message-----
From: Gregory Etelson <[email protected]>
Sent: Sunday, May 7, 2023 12:51 PMIndirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.flow 1:
/ indirect handle H conf C1 /| | | | | | flow 2: | | / indirect handle H conf C2 / | | | | | | | | | | | | ========================================================= ^ | | | | | | V | V | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ | flow mutable flow mutable | context 1 context 2 | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ indirect | | | action | | | context | V V | ----------------------------------------------------- | action mutable context | -----------------------------------------------------v action immutable context
=========================================================Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• IndirectMETER_MARKpolicy is immutable action member and profile is action mutable action member.
• IndirectMETER_MARKflow action definesinit_coloras flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.Template API:
Action template format:
Quoted 9 lines
template ..
indirect_listhandle Htmpl conf Ctmpl ..
mask ..indirect_listhandle Hmask conf Cmask ..1 If Htmpl was masked (Hmask != 0), PMD compiles base action
configuration during action template, table template and flow rule phases - depending on PMD action implementation. Otherwise, action is compiled from scratch during flow rule processing.
Why not just say if Hmask != NULL this action is fixed for this template, else action will be set per each flow?
Also since this is a list of action it is possible that one action will have null while other will have a fixed value.
This means that the Ctmpl should also be checked per each entery:
Conf[0] != null, conf[1] != null.
This will also mean that if application wants to use fixed confs he also must supply a valid example action_list, (can be different action_list object per flow but must be composed of the same actions.)
Quoted 4 lines
2 If Htmpl and Ctmpl were masked (Hmask !=0 and Cmask != 0), table
template processing overwrites base action configuration with Ctmpl parameters.
What do you mean based action?
If the Htmpl and Cmask is non zero it means that the configuration and action are based on the one set in the template create and not per flow.
Quoted 43 lines
Flow rule format:
actions ..
indirect_listhandle Hflow conf Cflow ..3 If Htmpl was masked, Hflow can reference a different action of the
same type as Htmpl.4 If Cflow was specified, it overwrites action configuration.
Signed-off-by Gregory Etelson <[email protected]>---
v3: do not deprecate indirect flow action.--- lib/ethdev/rte_flow.h | 266 +++++++++++++++++++++++++++++++++++ lib/ethdev/rte_flow_driver.h | 41 ++++++ 2 files changed, 307 insertions(+)lib/ethdev/rte_flow.h +7
-0@@ -2912,6 +2912,13 @@ enum rte_flow_action_type {* applied to the given ethdev Rx queue. */ RTE_FLOW_ACTION_TYPE_SKIP_CMAN , + +/** +* Action handle to reference flow actions list. +* +* @see struct rte_flow_action_indirect_list +*/ + RTE_FLOW_ACTION_TYPE_INDIRECT_LIST, };/** @@ -6118,6 +6125,265 @@rte_flow_async_action_handle_query_update(uint16_t
port_id,uint32_tqueue_id,lib/ethdev/rte_flow.h +2
-0void *user_data, struct rte_flow_error *error); +struct rte_flow_action_list_handle ; +
lib/ethdev/rte_flow.h rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id, · line 6139
Quoted 10 lines
lib/ethdev/rte_flow.h +10
-0+/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Configure INDIRECT_LIST flow action. +* +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +*/ +struct rte_flow_action_indirect_list { +struct rte_flow_action_list_handle ;/**< Indirect action list handle */
Since the comments above the member the comment should start with /** only
Quoted 29 lines
lib/ethdev/rte_flow.h +29
-0+/** +* Flow mutable configuration array. +* NULL if the handle has no flow mutable configuration update. +* Otherwise, if the handle was created with list A1 / A2 .. An / END +* size of conf is n. +* conf[i] points to flow mutable update of Ai in the handle +* actions list or NULL if Ai has no update. +*/ +const void **conf; +}; + + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Create an indirect flow action object from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action lists. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this
lib/ethdev/rte_flow.h rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id, · line 6178
Quoted 10 lines
lib/ethdev/rte_flow.h +10
-0+* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set +* to one of the error codes defined: +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-EINVAL) if *actions* list invalid. +* - (-ENOTSUP) if *action* list element valid but unsupported. +* - (-E2BIG) to many elements in *actions*
How can you get this error?
Quoted 33 lines
+ */
lib/ethdev/rte_flow.h +32
-0+__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_action_list_handle_create (uint16_t port_id, +const +struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Async function call to create an indirect flow action object +* from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] queue_id +* Flow queue which is used to update the rule. +* @param[in] attr +* Indirect action update operation attributes. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action list. +* @param[in] user_data +* The user data that will be returned on async completion event. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this
lib/ethdev/rte_flow.h rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id, · line 6221
Quoted 10 lines
lib/ethdev/rte_flow.h +10
-0+* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set +* to one of the error codes defined: +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-EINVAL) if *actions* list invalid. +* - (-ENOTSUP) if *action* list element valid but unsupported. +* - (-E2BIG) to many elements in *actions*
Same as above question
Quoted 24 lines
+ */
lib/ethdev/rte_flow.h +3
-0+__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_async_action_list_handle_create(uint16_t port_id, uint32_t
queue_id,lib/ethdev/rte_flow.h +4
-0+const struct rte_flow_op_attr *attr, + const struct + rte_flow_indir_action_conf *conf, + const struct rte_flow_action*actions,
lib/ethdev/rte_flow.h +14
-0+void *user_data, + struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Destroy indirect actions list by handle. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] handle +* Handle for the indirect actions list to be destroyed. +* @param[out] error
lib/ethdev/rte_flow.h rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id, · line 6253
Quoted 10 lines
lib/ethdev/rte_flow.h +10
-0+* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* - (0) if success. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-ENOENT) if actions list pointed by *action* handle was not found. +* - (-EBUSY) if actions list pointed by *action* handle still used +* rte_errno is also set.
Why not keep the same return description as above?
Quoted 22 lines
+ */
lib/ethdev/rte_flow.h +4
-0+__rte_experimental +int +rte_flow_action_list_handle_destroy (uint16_t port_id, + struct rte_flow_action_list_handle*handle,
lib/ethdev/rte_flow.h +16
-0+ struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue indirect action list destruction operation. +* The destroy queue must be the same +* as the queue on which the action was created. +* +* @param[in] port_id +* Port identifier of Ethernet device. +* @param[in] queue_id +* Flow queue which is used to destroy the rule. +* @param[in] op_attr +* Indirect action destruction operation attributes.
lib/ethdev/rte_flow.h rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id, · line 6284
Quoted 10 lines
lib/ethdev/rte_flow.h +10
-0+* @param[in] handle +* Handle for the indirect action object to be destroyed. +* @param[in] user_data +* The user data that will be returned on the completion events. +* @param[out] error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set.
Same errors as above?
Quoted 26 lines
+ */
lib/ethdev/rte_flow.h +15
-0+__rte_experimental +int +rte_flow_async_action_list_handle_destroy + (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *handle, +void *user_data,struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Query and/or update indirect flow actions list. +* If both query and update not NULL, the function atomically +* queries and updates indirect action. Query and update are carried in order
+ * specified in the mode parameter.
+ * If ether query or update is NULL, the function executes
+ * complementing operation.
+ *
+ * @paramport_id
+ * Port identifier of Ethernet device.
+ * @param handle
+ * Handle for the indirect actions list object to be updated.
+ * @param update
Quoted 3 lines
+ * If not NULL, update profile specification used to modify the action + * pointed by handle. + * @see struct rte_flow_action_indirect_list
It should be clear that the update/query is in the order the action was created and if the action i doesn't have configuration it should be s set to NULL. And goes without saying that the list size must be equal to the number of actions, that this list is build from.
Quoted 141 lines
+ * @param query
+ * If not NULL pointer to storage for the associated query data type.
+ * @see structrte_flow_action_indirect_list
+ * @param mode
+ * Operational mode.
+ * @param error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise andrte_errnois set.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-ENOTSUP) if underlying device does not support this functionality.
+ * - (-EINVAL) if *handle* or *mode* invalid or
+ * both *query* and *update* are NULL.
+ */lib/ethdev/rte_flow.h +7
-0+__rte_experimental +int +rte_flow_action_list_handle_query_update (uint16_t port_id, +const struct +rte_flow_action_list_handle *handle, +const void **update,void **query, + enum rte_flow_query_update_modemode,
lib/ethdev/rte_flow.h +42
-0+ struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue async indirect flow actions list query and/or update +* +* @param port_id +* Port identifier of Ethernet device. +* @param queue_id +* Flow queue which is used to update the rule. +* @param attr +* Indirect action update operation attributes. +* @param handle +* Handle for the indirect actions list object to be updated. +* @param update +* If not NULL, update profile specification used to modify the action +* pointed by handle. +* @see struct rte_flow_action_indirect_list +* @param query +* If not NULL, pointer to storage for the associated query data type. +* Query result returned on async completion event. +* @see struct rte_flow_action_indirect_list +* @param mode +* Operational mode. +* @param user_data +* The user data that will be returned on async completion event. +* @param error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOTSUP) if underlying device does not support this functionality. +* - (-EINVAL) if *handle* or *mode* invalid or +* both *update* and *query* are NULL. +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_query_update(uint16_t port_id,
uint32_tqueue_id,lib/ethdev/rte_flow.h +3
-0+const struct rte_flow_op_attr *attr, + const struct + rte_flow_action_list_handle*handle,
lib/ethdev/rte_flow.h +2
-0+ const void *update, void *query, + enum
rte_flow_query_update_modemode,lib/ethdev/rte_flow.h +4
-0+void *user_data, + struct rte_flow_error *error); + + #ifdef __cplusplus }#endif lib/ethdev/rte_flow_driver.h +41
-1@@ -121,6 +121,17 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_create() */ +struct rte_flow_action_list_handle *(*action_list_handle_create) + (struct rte_eth_dev *dev, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action actions[], +struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_destroy() */ +int (*action_list_handle_destroy) + (struct rte_eth_dev *dev, +struct rte_flow_action_list_handle *handle, +struct rte_flow_error *error);/** See rte_flow_tunnel_decap_set() */ int (*tunnel_decap_set) (struct rte_eth_dev *dev,@@ -302,6 +313,36 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, void *user_data, struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_create() */ +struct rte_flow_action_list_handle * + (*async_action_list_handle_create) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_destroy() */ +int (*async_action_list_handle_destroy) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *action_handle, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_query_update() */ +int (*action_list_handle_query_update) + (uint16_t port_id, +const struct rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_query_update() */ +int (*async_action_list_handle_query_update) + (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +void *user_data,struct rte_flow_error *error); + };/** --
Quoted 1 line
2.34.1
Best,
Ori
Hello Ori,
Quoted 2 lines
First I'm assuming this is just RFC, since there is no code implementation.
I'll add code implementation in v4.
Quoted 86 lines
Quoted 74 lines
-----Original Message-----
From: Gregory Etelson <[email protected]>
Sent: Sunday, May 7, 2023 12:51 PMIndirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.flow 1:
/ indirect handle H conf C1 /| | | | | | flow 2: | | / indirect handle H conf C2 / | | | | | | | | | | | | ========================================================= ^ | | | | | | V | V | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ | flow mutable flow mutable | context 1 context 2 | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ indirect | | | action | | | context | V V | ----------------------------------------------------- | action mutable context | -----------------------------------------------------v action immutable context
=========================================================Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• IndirectMETER_MARKpolicy is immutable action member and profile is action mutable action member.
• IndirectMETER_MARKflow action definesinit_coloras flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.Template API:
Action template format:
Quoted 9 lines
template ..
indirect_listhandle Htmpl conf Ctmpl ..
mask ..indirect_listhandle Hmask conf Cmask ..1 If Htmpl was masked (Hmask != 0), PMD compiles base action
configuration during action template, table template and flow rule phases - depending on PMD action implementation. Otherwise, action is compiled from scratch during flow rule processing.Why not just say if Hmask != NULL this action is fixed for this template, else action will be set per each flow?
Quoted 8 lines
Also since this is a list of action it is possible that one action will have null while other will have a fixed value.
This means that the Ctmpl should also be checked per each entery:
Conf[0] != null, conf[1] != null.
This will also mean that if application wants to use fixed confs he also must supply a valid exampleaction_list, (can be differentaction_listobject per flow but must be composed of the same actions.)
Will update indirect_list action template description in v4
Quoted 49 lines
Quoted 4 lines
2 If Htmpl and Ctmpl were masked (Hmask !=0 and Cmask != 0), table
template processing overwrites base action configuration with Ctmpl parameters.What do you mean based action?
If the Htmpl and Cmask is non zero it means that the configuration and action are based on the one set in the template create and not per flow.Quoted 41 lines
Flow rule format:
actions ..
indirect_listhandle Hflow conf Cflow ..3 If Htmpl was masked, Hflow can reference a different action of the
same type as Htmpl.4 If Cflow was specified, it overwrites action configuration.
Signed-off-by Gregory Etelson <[email protected]>---
v3: do not deprecate indirect flow action.--- lib/ethdev/rte_flow.h | 266 +++++++++++++++++++++++++++++++++++ lib/ethdev/rte_flow_driver.h | 41 ++++++ 2 files changed, 307 insertions(+)lib/ethdev/rte_flow.h +7
-0@@ -2912,6 +2912,13 @@ enum rte_flow_action_type {* applied to the given ethdev Rx queue. */ RTE_FLOW_ACTION_TYPE_SKIP_CMAN , + +/** +* Action handle to reference flow actions list. +* +* @see struct rte_flow_action_indirect_list +*/ + RTE_FLOW_ACTION_TYPE_INDIRECT_LIST, };/** @@ -6118,6 +6125,265 @@rte_flow_async_action_handle_query_update(uint16_t
port_id,uint32_tqueue_id,lib/ethdev/rte_flow.h +0
-0void *user_data, struct rte_flow_error *error);
Quoted 14 lines
lib/ethdev/rte_flow.h rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id, · line 6139
Quoted 12 lines
lib/ethdev/rte_flow.h +12
-0+struct rte_flow_action_list_handle ; + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Configure INDIRECT_LIST flow action. +* +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +*/ +struct rte_flow_action_indirect_list { +struct rte_flow_action_list_handle ;/**< Indirect action list handle */ Since the comments above the member the comment should start with /** only
Will update the comment in v4.
Quoted 32 lines
Quoted 32 lines
lib/ethdev/rte_flow.h +32
-0+/** +* Flow mutable configuration array. +* NULL if the handle has no flow mutable configuration update. +* Otherwise, if the handle was created with list A1 / A2 .. An / END +* size of conf is n. +* conf[i] points to flow mutable update of Ai in the handle +* actions list or NULL if Ai has no update. +*/ +const void **conf; +}; + + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Create an indirect flow action object from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action lists. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set
Quoted 9 lines
Quoted 7 lines
+ * to one of the error codes defined: + * - (-ENODEV) if *port_id* invalid. + * - (-ENOSYS) if underlying device does not support this functionality. + * - (-EIO) if underlying device is removed. + * - (-EINVAL) if *actions* list invalid. + * - (-ENOTSUP) if *action* list element valid but unsupported. + * - (-E2BIG) to many elements in *actions*How can you get this error?
Will remove E2BIG in v4.
Quoted 36 lines
Quoted 36 lines
+ */
lib/ethdev/rte_flow.h +35
-0+__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_action_list_handle_create (uint16_t port_id, +const +struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Async function call to create an indirect flow action object +* from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] queue_id +* Flow queue which is used to update the rule. +* @param[in] attr +* Indirect action update operation attributes. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action list. +* @param[in] user_data +* The user data that will be returned on async completion event. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set
Quoted 9 lines
Quoted 7 lines
+ * to one of the error codes defined: + * - (-ENODEV) if *port_id* invalid. + * - (-ENOSYS) if underlying device does not support this functionality. + * - (-EIO) if underlying device is removed. + * - (-EINVAL) if *actions* list invalid. + * - (-ENOTSUP) if *action* list element valid but unsupported. + * - (-E2BIG) to many elements in *actions*Same as above question
Will remove E2BIG in v4.
Quoted 27 lines
Quoted 27 lines
+ */
lib/ethdev/rte_flow.h +3
-0+__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_async_action_list_handle_create(uint16_t port_id, uint32_t
queue_id,lib/ethdev/rte_flow.h +4
-0+const struct rte_flow_op_attr *attr, + const struct + rte_flow_indir_action_conf *conf, + const struct rte_flow_action*actions,
lib/ethdev/rte_flow.h +17
-0+void *user_data, + struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Destroy indirect actions list by handle. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] handle +* Handle for the indirect actions list to be destroyed. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return
Quoted 9 lines
Quoted 7 lines
+ * - (0) if success. + * - (-ENODEV) if *port_id* invalid. + * - (-ENOSYS) if underlying device does not support this functionality. + * - (-EIO) if underlying device is removed. + * - (-ENOENT) if actions list pointed by *action* handle was not found. + * - (-EBUSY) if actions list pointed by *action* handle still used + * rte_errno is also set.Why not keep the same return description as above?
Will update the format in v4.
Quoted 25 lines
Quoted 25 lines
+ */
lib/ethdev/rte_flow.h +4
-0+__rte_experimental +int +rte_flow_action_list_handle_destroy (uint16_t port_id, + struct rte_flow_action_list_handle*handle,
lib/ethdev/rte_flow.h +19
-0+ struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue indirect action list destruction operation. +* The destroy queue must be the same +* as the queue on which the action was created. +* +* @param[in] port_id +* Port identifier of Ethernet device. +* @param[in] queue_id +* Flow queue which is used to destroy the rule. +* @param[in] op_attr +* Indirect action destruction operation attributes. +* @param[in] handle +* Handle for the indirect action object to be destroyed. +* @param[in] user_data
Quoted 9 lines
Quoted 7 lines
+ * The user data that will be returned on the completion events.
+ * @param[out] error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise andrte_errnois set.Same errors as above?
Will update the format in v4.
Quoted 25 lines
Quoted 25 lines
+ */
lib/ethdev/rte_flow.h +15
-0+__rte_experimental +int +rte_flow_async_action_list_handle_destroy + (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *handle, +void *user_data,struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Query and/or update indirect flow actions list. +* If both query and update not NULL, the function atomically +* queries and updates indirect action. Query and update are carried in order
+ * specified in the mode parameter.
+ * If ether query or update is NULL, the function executes
+ * complementing operation.
+ *
+ * @paramport_id
+ * Port identifier of Ethernet device.
+ * @param handle
+ * Handle for the indirect actions list object to be updated.
Quoted 9 lines
Quoted 4 lines
+ * @param update
+ * If not NULL, update profile specification used to modify the action + * pointed by handle. + * @see struct rte_flow_action_indirect_listIt should be clear that the update/query is in the order the action was created and if the action i doesn't have configuration it should be s set to NULL. And goes without saying that the list size must be equal to the number of actions, that this list is build from.
Will update in v4.
Quoted 145 lines
Quoted 141 lines
+ * @param query
+ * If not NULL pointer to storage for the associated query data type.
+ * @see structrte_flow_action_indirect_list
+ * @param mode
+ * Operational mode.
+ * @param error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise andrte_errnois set.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-ENOTSUP) if underlying device does not support this functionality.
+ * - (-EINVAL) if *handle* or *mode* invalid or
+ * both *query* and *update* are NULL.
+ */lib/ethdev/rte_flow.h +7
-0+__rte_experimental +int +rte_flow_action_list_handle_query_update (uint16_t port_id, +const struct +rte_flow_action_list_handle *handle, +const void **update,void **query, + enum rte_flow_query_update_modemode,
lib/ethdev/rte_flow.h +42
-0+ struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue async indirect flow actions list query and/or update +* +* @param port_id +* Port identifier of Ethernet device. +* @param queue_id +* Flow queue which is used to update the rule. +* @param attr +* Indirect action update operation attributes. +* @param handle +* Handle for the indirect actions list object to be updated. +* @param update +* If not NULL, update profile specification used to modify the action +* pointed by handle. +* @see struct rte_flow_action_indirect_list +* @param query +* If not NULL, pointer to storage for the associated query data type. +* Query result returned on async completion event. +* @see struct rte_flow_action_indirect_list +* @param mode +* Operational mode. +* @param user_data +* The user data that will be returned on async completion event. +* @param error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* 0 on success, a negative errno value otherwise and rte_errno is set. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOTSUP) if underlying device does not support this functionality. +* - (-EINVAL) if *handle* or *mode* invalid or +* both *update* and *query* are NULL. +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_query_update(uint16_t port_id,
uint32_tqueue_id,lib/ethdev/rte_flow.h +3
-0+const struct rte_flow_op_attr *attr, + const struct + rte_flow_action_list_handle*handle,
lib/ethdev/rte_flow.h +2
-0+ const void *update, void *query, + enum
rte_flow_query_update_modemode,lib/ethdev/rte_flow.h +4
-0+void *user_data, + struct rte_flow_error *error); + + #ifdef __cplusplus }#endif lib/ethdev/rte_flow_driver.h +41
-1@@ -121,6 +121,17 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_create() */ +struct rte_flow_action_list_handle *(*action_list_handle_create) + (struct rte_eth_dev *dev, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action actions[], +struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_destroy() */ +int (*action_list_handle_destroy) + (struct rte_eth_dev *dev, +struct rte_flow_action_list_handle *handle, +struct rte_flow_error *error);/** See rte_flow_tunnel_decap_set() */ int (*tunnel_decap_set) (struct rte_eth_dev *dev,@@ -302,6 +313,36 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, void *user_data, struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_create() */ +struct rte_flow_action_list_handle * + (*async_action_list_handle_create) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_destroy() */ +int (*async_action_list_handle_destroy) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *action_handle, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_query_update() */ +int (*action_list_handle_query_update) + (uint16_t port_id, +const struct rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_query_update() */ +int (*async_action_list_handle_query_update) + (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +void *user_data,struct rte_flow_error *error); + };/** -- Quoted 1 line
2.34.1
Best,
Ori
PATCH v4 1/1 ethdev: add indirect list flow action
In reply to Gregory EtelsonIndirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.
Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.
Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.
There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.
flow 1:
/ indirect handle H conf C1 /
| |
| |
| | flow 2:
| | / indirect handle H conf C2 /
| | | |
| | | |
| | | |
=========================================================
^ | | | |
| | V | V
| ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
| flow mutable flow mutable
| context 1 context 2
| ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
indirect | | |
action | | |
context | V V
| -----------------------------------------------------
| action mutable context
| ----------------------------------------------------- v action immutable context
=========================================================
Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• Indirect METER_MARK policy is immutable action member and profile is action mutable action member.
• Indirect METER_MARK flow action defines init_color as flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.
If indirect list handle was created from a list of actions A1 / A2 ... An / END
indirect list flow action can update Ai flow mutable context in the action configuration parameter.
Indirect list action configuration is and array [C1, C2, .., Cn] where Ci corresponds to Ai in the action handle source. Ci configuration element points Ai flow mutable update, or it's NULL if Ai has no flow mutable update.
Indirect list action configuration can be NULL if the action has no flow mutable updates.
Template API:
Action template format:
template .. indirect_list handle Htmpl conf Ctmpl ..
mask .. indirect_list handle Hmask conf Cmask ..
1 If Htmpl was masked (Hmask != 0), it will be fixed in that template.
Otherwise, indirect action value is set in a flow rule.
2 If Htmpl and Ctmpl[i] were masked (Hmask !=0 and Cmask[i] != 0),
Htmpl's Ai action flow mutable context fill be updated to Ctmpl[i] values and will be fixed in that template.
Flow rule format:
actions .. indirect_list handle Hflow conf Cflow ..
3 If Htmpl was not masked in actions template, Hflow references an
action of the same type as Htmpl.
4 Cflow[i] updates handle's Ai flow mutable configuration if
the Ci was not masked in action template.
--- app/test-pmd/cmdline_flow.c | 207 ++++++++++++++++++- app/test-pmd/config.c | 163 +++++++++++---- app/test-pmd/testpmd.h | 9 +- doc/guides/nics/features/default.ini | 1 + doc/guides/prog_guide/rte_flow.rst | 119 +++++++++++ doc/guides/rel_notes/release_23_07.rst | 2 + lib/ethdev/ethdev_trace.h | 88 ++++++++ lib/ethdev/ethdev_trace_points.c | 18 ++ lib/ethdev/rte_flow.c | 171 ++++++++++++++++ lib/ethdev/rte_flow.h | 269 +++++++++++++++++++++++++ lib/ethdev/rte_flow_driver.h | 41 ++++ lib/ethdev/version.map | 8 + 12 files changed, 1054 insertions(+), 42 deletions(-)
app/test-pmd/cmdline_flow.c +206 -1
@@ -145,6 +145,7 @@ enum index {/* Queue indirect action arguments */ QUEUE_INDIRECT_ACTION_CREATE , +QUEUE_INDIRECT_ACTION_LIST_CREATE ,QUEUE_INDIRECT_ACTION_UPDATE ,QUEUE_INDIRECT_ACTION_DESTROY , QUEUE_INDIRECT_ACTION_QUERY,
@@ -157,6 +158,7 @@ enum index {QUEUE_INDIRECT_ACTION_TRANSFER ,QUEUE_INDIRECT_ACTION_CREATE_POSTPONE ,QUEUE_INDIRECT_ACTION_SPEC , +QUEUE_INDIRECT_ACTION_LIST ,/* Queue indirect action update arguments */ QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE,
@@ -242,6 +244,8 @@ enum index {/* Indirect action arguments */ INDIRECT_ACTION_CREATE , +INDIRECT_ACTION_LIST_CREATE , +INDIRECT_ACTION_FLOW_CONF_CREATE ,INDIRECT_ACTION_UPDATE ,INDIRECT_ACTION_DESTROY , INDIRECT_ACTION_QUERY,
@@ -253,6 +257,8 @@ enum index {INDIRECT_ACTION_EGRESS ,INDIRECT_ACTION_TRANSFER ,INDIRECT_ACTION_SPEC , +INDIRECT_ACTION_LIST , +INDIRECT_ACTION_FLOW_CONF ,/* Indirect action destroy arguments */ INDIRECT_ACTION_DESTROY_ID,
@@ -626,6 +632,11 @@ enum index {ACTION_SAMPLE_INDEX ,ACTION_SAMPLE_INDEX_VALUE ,ACTION_INDIRECT , +ACTION_INDIRECT_LIST , +ACTION_INDIRECT_LIST_HANDLE , +ACTION_INDIRECT_LIST_CONF , +INDIRECT_LIST_ACTION_ID2PTR_HANDLE , +INDIRECT_LIST_ACTION_ID2PTR_CONF ,ACTION_SHARED_INDIRECT ,INDIRECT_ACTION_PORT , INDIRECT_ACTION_ID2PTR,
@@ -1266,6 +1277,7 @@ static const enum index next_qia_create_attr[] = {QUEUE_INDIRECT_ACTION_TRANSFER ,QUEUE_INDIRECT_ACTION_CREATE_POSTPONE ,QUEUE_INDIRECT_ACTION_SPEC , +QUEUE_INDIRECT_ACTION_LIST , ZERO, };
@@ -1294,6 +1306,8 @@ static const enum index next_ia_create_attr[] = {INDIRECT_ACTION_EGRESS ,INDIRECT_ACTION_TRANSFER ,INDIRECT_ACTION_SPEC , +INDIRECT_ACTION_LIST , +INDIRECT_ACTION_FLOW_CONF , ZERO, };
@@ -1303,6 +1317,13 @@ static const enum index next_ia[] = {ZERO }; +static const enum index next_ial[] = { +ACTION_INDIRECT_LIST_HANDLE , +ACTION_INDIRECT_LIST_CONF , +ACTION_NEXT , +ZERO +}; +static const enum index next_qia_qu_attr[] = {QUEUE_INDIRECT_ACTION_QU_MODE ,QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE ,
@@ -2013,6 +2034,7 @@ static const enum index next_action[] = {ACTION_AGE_UPDATE ,ACTION_SAMPLE ,ACTION_INDIRECT , +ACTION_INDIRECT_LIST ,ACTION_SHARED_INDIRECT ,ACTION_MODIFY_FIELD , ACTION_CONNTRACK,
@@ -2289,6 +2311,7 @@ static const enum index next_action_sample[] = {ACTION_RAW_ENCAP ,ACTION_VXLAN_ENCAP ,ACTION_NVGRE_ENCAP , +ACTION_REPRESENTED_PORT ,ACTION_NEXT , ZERO, };
@@ -2539,6 +2562,10 @@ static int parse_ia_destroy(struct context *ctx, const struct token *token,static int parse_ia_id2ptr (struct context *ctx,const struct token *token,const char *str,unsigned int len,void *buf,unsigned int size); + +static int parse_indlst_id2ptr (struct context *ctx,const struct token *token, +const char *str,unsigned int len,void *buf, +unsigned int size);static int parse_ia_port (struct context *ctx,const struct token *token,const char *str,unsigned int len,void *buf,unsigned int size);
@@ -2627,6 +2654,16 @@ static int comp_qu_mode_name(struct context *ctx, const struct token *token, unsigned int ent, char *buf, unsigned int size); +struct indlst_conf { +uint32_t id; +uint32_t conf_num; +struct rte_flow_action *actions; +const void **conf; +SLIST_ENTRY (indlst_conf) next; +}; + +static const struct indlst_conf *indirect_action_list_conf_get (uint32_t conf_id); +/** Token definitions. */ static const struct token token_list[] = {/* Special tokens. */
@@ -3426,6 +3463,12 @@ static const struct token token_list[] = { .help = "specify action to create indirect handle", .next = NEXT(next_action), }, + [QUEUE_INDIRECT_ACTION_LIST] = { + .name = "list", + .help = "specify actions for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_qia, + },/* Top-level command. */ [PUSH] = { .name = "push",
@@ -6775,6 +6818,37 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), .call = parse_vc, }, + [ACTION_INDIRECT_LIST] = { + .name = "indirect_list", + .help = "apply indirect list action by id", + .priv =PRIV_ACTION (INDIRECT_LIST , +sizeof (struct + rte_flow_action_indirect_list)), + .next = NEXT(next_ial), + .call = parse_vc, + }, + [ACTION_INDIRECT_LIST_HANDLE] = { + .name = "handle", + .help = "indirect list handle", + .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), + .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uintptr_t))), + }, + [ACTION_INDIRECT_LIST_CONF] = { + .name = "conf", + .help = "indirect list configuration", + .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), + .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uintptr_t))), + }, + [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { + .type = "UNSIGNED", + .help = "unsigned integer value", + .call = parse_indlst_id2ptr, + }, + [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { + .type = "UNSIGNED", + .help = "unsigned integer value", + .call = parse_indlst_id2ptr, + }, [ACTION_SHARED_INDIRECT] = { .name = "shared_indirect", .help = "apply indirect action by id and port",
@@ -6823,6 +6897,18 @@ static const struct token token_list[] = { .help = "specify action to create indirect handle", .next = NEXT(next_action), }, + [INDIRECT_ACTION_LIST] = { + .name = "list", + .help = "specify actions for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_ia, + }, + [INDIRECT_ACTION_FLOW_CONF] = { + .name = "flow_conf", + .help = "specify actions configuration for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_ia, + }, [ACTION_POL_G] = { .name = "g_actions", .help = "submit a list of associated actions for green",
@@ -7181,6 +7267,12 @@ parse_ia(struct context *ctx, const struct token *token,return len;case INDIRECT_ACTION_QU_MODE :return len; +case INDIRECT_ACTION_LIST : + out->command =INDIRECT_ACTION_LIST_CREATE ; +return len; +case INDIRECT_ACTION_FLOW_CONF : + out->command =INDIRECT_ACTION_FLOW_CONF_CREATE ; +return len;default :return -1 ; }
@@ -7278,6 +7370,9 @@ parse_qia(struct context *ctx, const struct token *token,return len;case QUEUE_INDIRECT_ACTION_QU_MODE :return len; +case QUEUE_INDIRECT_ACTION_LIST : + out->command =QUEUE_INDIRECT_ACTION_LIST_CREATE ; +return len;default :return -1 ; }
@@ -7454,10 +7549,12 @@ parse_vc(struct context *ctx, const struct token *token,return -1 ;break ;case ACTIONS : - out->args.vc.actions = + out->args.vc.actions = out->args.vc.pattern ? (void *)RTE_ALIGN_CEIL ((uintptr_t ) (out->args.vc.pattern + out->args.vc.pattern_n), +sizeof (double )) : + (void *)RTE_ALIGN_CEIL ((uintptr_t )(out +1 ),sizeof (double )); ctx->object = out->args.vc.actions; ctx->objmask =NULL ;
@@ -10412,6 +10509,49 @@ parse_ia_id2ptr(struct context *ctx, const struct token *token,return ret; } +static int +parse_indlst_id2ptr (struct context *ctx,const struct token *token, +const char *str,unsigned int len, + void __rte_unused *buf, unsigned int __rte_unused size) +{ +struct rte_flow_action *action = ctx->object; +struct rte_flow_action_indirect_list *action_conf; +const struct indlst_conf *indlst_conf; +uint32_t id; +int ret; + +if (!action) +return -1 ; + ctx->objdata =0 ; + ctx->object = &id; + ctx->objmask =NULL ; + ret =parse_int (ctx, token, str, len, ctx->object,sizeof (id)); +if (ret != (int )len) +return ret; + ctx->object = action; + action_conf = (void *)(uintptr_t )action->conf; + action_conf->conf =NULL ; +switch (ctx->curr) { +case INDIRECT_LIST_ACTION_ID2PTR_HANDLE : + action_conf->handle = (typeof(action_conf->handle)) +port_action_handle_get_by_id (ctx->port, id); +if (!action_conf->handle) { +printf ("no indirect list handle for id %u\n" , id); +return -1 ; + } +break ; +case INDIRECT_LIST_ACTION_ID2PTR_CONF : + indlst_conf =indirect_action_list_conf_get (id); +if (!indlst_conf) +return -1 ; + action_conf->conf = (const void **)indlst_conf->conf; +break ; +default : +break ; + } +return ret; +} + static int parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, const char *str, unsigned int len,
@@ -11453,6 +11593,64 @@ cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, *hdr = &cmd_flow_token_hdr; } +static SLIST_HEAD(, indlst_conf) indlst_conf_head = +SLIST_HEAD_INITIALIZER (); + +static void +indirect_action_flow_conf_create (const struct buffer *in) +{ +int len, ret; +uint32_t i; +struct indlst_conf *indlst_conf =NULL ; +size_t base =RTE_ALIGN (sizeof (*indlst_conf),8 ); +struct rte_flow_action *src = in->args.vc.actions; + +if (!in->args.vc.actions_n) + goto end; + len =rte_flow_conv (RTE_FLOW_CONV_OP_ACTIONS ,NULL ,0 , src,NULL ); +if (len <=0 ) + goto end; + len =RTE_ALIGN (len,16 ); + + indlst_conf =calloc (1 , base + len + + in->args.vc.actions_n *sizeof (uintptr_t )); +if (!indlst_conf) + goto end; + indlst_conf->id = in->args.vc.attr.group; + indlst_conf->conf_num = in->args.vc.actions_n -1 ; + indlst_conf->actions =RTE_PTR_ADD (indlst_conf, base); + ret =rte_flow_conv (RTE_FLOW_CONV_OP_ACTIONS , indlst_conf->actions, + len, src,NULL ); +if (ret <=0 ) { +free (indlst_conf); + indlst_conf =NULL ; + goto end; + } + indlst_conf->conf =RTE_PTR_ADD (indlst_conf, base + len); +for (i =0 ; i < indlst_conf->conf_num; i++) + indlst_conf->conf[i] = indlst_conf->actions[i].conf; +SLIST_INSERT_HEAD (&indlst_conf_head, indlst_conf, next); +end: +if (indlst_conf) +printf ("created indirect action list configuration %u\n" , + in->args.vc.attr.group); +else +printf ("cannot create indirect action list configuration %u\n" , + in->args.vc.attr.group); +} + +static const struct indlst_conf * +indirect_action_list_conf_get (uint32_t conf_id) +{ +const struct indlst_conf *conf; + + SLIST_FOREACH(conf, &indlst_conf_head, next) { +if (conf->id == conf_id) +return conf; + } +return NULL ; +} +/** Dispatch parsed buffer to function calls. */ static void cmd_flow_parsed (const struct buffer *in)
@@ -11532,6 +11730,7 @@ cmd_flow_parsed(const struct buffer *in) in->args.aged.destroy);break ;case QUEUE_INDIRECT_ACTION_CREATE : +case QUEUE_INDIRECT_ACTION_LIST_CREATE : port_queue_action_handle_create( in->port, in->queue, in->postpone, in->args.vc.attr.group,
@@ -11567,8 +11766,10 @@ cmd_flow_parsed(const struct buffer *in) in->args.vc.actions);break ;case INDIRECT_ACTION_CREATE : +case INDIRECT_ACTION_LIST_CREATE : port_action_handle_create( in->port, in->args.vc.attr.group, + in->command == INDIRECT_ACTION_LIST_CREATE, &((const struct rte_flow_indir_action_conf) { .ingress = in->args.vc.attr.ingress, .egress = in->args.vc.attr.egress,
@@ -11576,6 +11777,9 @@ cmd_flow_parsed(const struct buffer *in) }), in->args.vc.actions);break ; +case INDIRECT_ACTION_FLOW_CONF_CREATE : +indirect_action_flow_conf_create (in); +break ;case INDIRECT_ACTION_DESTROY : port_action_handle_destroy(in->port, in->args.ia_destroy.action_id_n,
@@ -11653,6 +11857,7 @@ cmd_flow_parsed(const struct buffer *in)default :break ; } +fflush (stdout); }/** Token generator and output processing callback (cmdline API). */
app/test-pmd/config.c +124 -39
229 lines not on this page · raw message
app/test-pmd/testpmd.h +7 -2
@@ -228,7 +228,12 @@ struct port_indirect_action {struct port_indirect_action *next;/**< Next flow in list. */ uint32_t id;/**< Indirect action ID. */ enum rte_flow_action_type type;/**< Action type. */ -struct rte_flow_action_handle *handle;/**< Indirect action handle. */ +union { +struct rte_flow_action_handle *handle; +/**< Indirect action handle. */ +struct rte_flow_action_list_handle *list_handle; +/**< Indirect action list handle*/ + };enum age_action_context_type age_type;/**< Age action context type. */ };
@@ -921,7 +926,7 @@ void update_fwd_ports(portid_t new_pid);void set_fwd_eth_peer (portid_t port_id,char *peer_addr);void port_mtu_set (portid_t port_id,uint16_t mtu); -int port_action_handle_create (portid_t port_id,uint32_t id, +int port_action_handle_create (portid_t port_id,uint32_t id,bool indirect_list,const struct rte_flow_indir_action_conf *conf,const struct rte_flow_action *action); int port_action_handle_destroy(portid_t port_id,
doc/guides/nics/features/default.ini +1 -0
@@ -158,6 +158,7 @@ drop = flag = inc_tcp_ack = inc_tcp_seq = +indirect_list = jump = mac_swap = mark =
doc/guides/prog_guide/rte_flow.rst +119 -0
125 lines not on this page · raw message
doc/guides/rel_notes/release_23_07.rst +2 -0
@@ -55,6 +55,8 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= + * **Added INDIRECT_LIST flow action.** + Removed Items -------------
lib/ethdev/ethdev_trace.h +88 -0
94 lines not on this page · raw message
lib/ethdev/ethdev_trace_points.c +18 -0
@@ -750,3 +750,21 @@ RTE_TRACE_POINT_REGISTER(rte_tm_trace_wred_profile_add,RTE_TRACE_POINT_REGISTER (rte_tm_trace_wred_profile_delete, lib.ethdev.tm.wred_profile_delete) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_action_list_handle_create, + lib.ethdev.flow.action_list_handle_create) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_action_list_handle_destroy, + lib.ethdev.flow.action_list_handle_destroy) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_action_list_handle_query_update, + lib.ethdev.flow.action_list_handle_query_update) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_async_action_list_handle_create, + lib.ethdev.flow.async_action_list_handle_create) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_async_action_list_handle_destroy, + lib.ethdev.flow.async_action_list_handle_destroy) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_async_action_list_handle_query_update, + lib.ethdev.flow.async_action_list_handle_query_update)
lib/ethdev/rte_flow.c +171 -0
180 lines not on this page · raw message
lib/ethdev/rte_flow.h +269 -0
281 lines not on this page · raw message
lib/ethdev/rte_flow_driver.h +41 -0
53 lines not on this page · raw message
lib/ethdev/version.map +8 -0
@@ -299,6 +299,14 @@ EXPERIMENTAL { rte_flow_action_handle_query_update; rte_flow_async_action_handle_query_update; rte_flow_async_create_by_index; + + # added in 23.07 + rte_flow_action_list_handle_create; + rte_flow_action_list_handle_destroy; + rte_flow_action_list_handle_query_update; + rte_flow_async_action_list_handle_create; + rte_flow_async_action_list_handle_destroy; + rte_flow_async_action_list_handle_query_update; }; INTERNAL {
Signature · 1 line
2.34.1
Hi Gregory
Quoted 107 lines
-----Original Message-----
From: Gregory Etelson <[email protected]>
Sent: Friday, May 19, 2023 3:00 PMIndirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.flow 1:
/ indirect handle H conf C1 /| | | | | | flow 2: | | / indirect handle H conf C2 / | | | | | | | | | | | | ========================================================= ^ | | | | | | V | V | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ | flow mutable flow mutable | context 1 context 2 | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ indirect | | | action | | | context | V V | ----------------------------------------------------- | action mutable context | -----------------------------------------------------v action immutable context
=========================================================Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• IndirectMETER_MARKpolicy is immutable action member and profile is action mutable action member.
• IndirectMETER_MARKflow action definesinit_coloras flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.If indirect list handle was created from a list of actions A1 / A2 ... An / END
indirect list flow action can update Ai flow mutable context in the action configuration parameter.
Indirect list action configuration is and array [C1, C2, .., Cn] where Ci corresponds to Ai in the action handle source. Ci configuration element points Ai flow mutable update, or it's NULL if Ai has no flow mutable update.
Indirect list action configuration can be NULL if the action has no flow mutable updates.Template API:
Action template format:
template ..
indirect_listhandle Htmpl conf Ctmpl ..
mask ..indirect_listhandle Hmask conf Cmask ..1 If Htmpl was masked (Hmask != 0), it will be fixed in that template.
Otherwise, indirect action value is set in a flow rule.2 If Htmpl and Ctmpl[i] were masked (Hmask !=0 and Cmask[i] != 0),
Htmpl's Ai action flow mutable context fill be updated to Ctmpl[i] values and will be fixed in that template.Flow rule format:
actions ..
indirect_listhandle Hflow conf Cflow ..3 If Htmpl was not masked in actions template, Hflow references an
action of the same type as Htmpl.4 Cflow[i] updates handle's Ai flow mutable configuration if
the Ci was not masked in action template.Signed-off-by Gregory Etelson <[email protected]>---
[Snip]
Quoted 206 lines
lib/ethdev/rte_flow.h +7
-0@@ -2912,6 +2912,13 @@ enum rte_flow_action_type {* applied to the given ethdev Rx queue. */ RTE_FLOW_ACTION_TYPE_SKIP_CMAN , + +/** +* Action handle to reference flow actions list. +* +* @see struct rte_flow_action_indirect_list +*/ + RTE_FLOW_ACTION_TYPE_INDIRECT_LIST, };/** @@ -6118,6 +6125,268 @@rte_flow_async_action_handle_query_update(uint16_t
port_id,uint32_tqueue_id,lib/ethdev/rte_flow.h +97
-0void *user_data, struct rte_flow_error *error); +struct rte_flow_action_list_handle ; + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Configure INDIRECT_LIST flow action. +* +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +*/ +struct rte_flow_action_indirect_list { +/** Indirect action list handle */ +struct rte_flow_action_list_handle *handle; +/** +* Flow mutable configuration array. +* NULL if the handle has no flow mutable configuration update. +* Otherwise, if the handle was created with list A1 / A2 .. An / END +* size of conf is n. +* conf[i] points to flow mutable update of Ai in the handle +* actions list or NULL if Ai has no update. +*/ +const void **conf; +}; + + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Create an indirect flow action object from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action lists. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set +* to one of the error codes defined: +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-EINVAL) if *actions* list invalid. +* - (-ENOTSUP) if *action* list element valid but unsupported. +*/ +__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_action_list_handle_create (uint16_t port_id, +const +struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Async function call to create an indirect flow action object +* from flow actions list. +* The object is identified by a unique handle. +* The handle has single state and configuration +* across all the flow rules using it. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] queue_id +* Flow queue which is used to update the rule. +* @param[in] attr +* Indirect action update operation attributes. +* @param[in] conf +* Action configuration for the indirect action list creation. +* @param[in] actions +* Specific configuration of the indirect action list. +* @param[in] user_data +* The user data that will be returned on async completion event. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* A valid handle in case of success, NULL otherwise and rte_errno is set +* to one of the error codes defined: +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-EINVAL) if *actions* list invalid. +* - (-ENOTSUP) if *action* list element valid but unsupported. +*/ +__rte_experimental +struct rte_flow_action_list_handle * +rte_flow_async_action_list_handle_create(uint16_t port_id, uint32_t
queue_id,lib/ethdev/rte_flow.h +4
-0+const struct rte_flow_op_attr *attr, + const struct + rte_flow_indir_action_conf *conf, + const struct rte_flow_action*actions,
lib/ethdev/rte_flow.h +28
-0+void *user_data, + struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Destroy indirect actions list by handle. +* +* @param[in] port_id +* The port identifier of the Ethernet device. +* @param[in] handle +* Handle for the indirect actions list to be destroyed. +* @param[out] error +* Perform verbose error reporting if not NULL. PMDs initialize this +* structure in case of error only. +* @return +* - (0) if success. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-ENOENT) if actions list pointed by *action* handle was not found. +* - (-EBUSY) if actions list pointed by *action* handle still used +*/ +__rte_experimental +int +rte_flow_action_list_handle_destroy (uint16_t port_id, + struct rte_flow_action_list_handle*handle,
lib/ethdev/rte_flow.h +47
-0+ struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue indirect action list destruction operation. +* The destroy queue must be the same +* as the queue on which the action was created. +* +* @param[in] port_id +* Port identifier of Ethernet device. +* @param[in] queue_id +* Flow queue which is used to destroy the rule. +* @param[in] op_attr +* Indirect action destruction operation attributes. +* @param[in] handle +* Handle for the indirect action object to be destroyed. +* @param[in] user_data +* The user data that will be returned on the completion events. +* @param[out] error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* - (0) if success. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOSYS) if underlying device does not support this functionality. +* - (-EIO) if underlying device is removed. +* - (-ENOENT) if actions list pointed by *action* handle was not found. +* - (-EBUSY) if actions list pointed by *action* handle still used +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_destroy + (uint16_t port_id,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *handle, +void *user_data,struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Query and/or update indirect flow actions list. +* If both query and update not NULL, the function atomically +* queries and updates indirect action. Query and update are carried in order
+ * specified in the mode parameter.
+ * If ether query or update is NULL, the function executes
Quoted 8 lines
+ * complementing operation.
+ *
+ * @paramport_id
+ * Port identifier of Ethernet device.
+ * @param handle
+ * Handle for the indirect actions list object to be updated.
+ * @param update
+ * If not NULL, update profile specification used to modify the action
It should be explained that the upate/query points always to array with the size of number of actions, the the query/update query/upate all the actions at the same time
This comment is for all such parameters in async and synced functions.
Quoted 164 lines
+ * pointed by handle.
+ * @see structrte_flow_action_indirect_list
+ * @param query
+ * If not NULL pointer to storage for the associated query data type.
+ * @see structrte_flow_action_indirect_list
+ * @param mode
+ * Operational mode.
+ * @param error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * - (0) if success.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-ENOTSUP) if underlying device does not support this functionality.
+ * - (-EINVAL) if *handle* or *mode* invalid or
+ * both *query* and *update* are NULL.
+ */lib/ethdev/rte_flow.h +5
-0+__rte_experimental +int +rte_flow_action_list_handle_query_update (uint16_t port_id, +const struct + rte_flow_action_list_handle*handle,
lib/ethdev/rte_flow.h +2
-0+ const void **update, void **query, + enum
rte_flow_query_update_modemode,lib/ethdev/rte_flow.h +42
-0+ struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue async indirect flow actions list query and/or update +* +* @param port_id +* Port identifier of Ethernet device. +* @param queue_id +* Flow queue which is used to update the rule. +* @param attr +* Indirect action update operation attributes. +* @param handle +* Handle for the indirect actions list object to be updated. +* @param update +* If not NULL, update profile specification used to modify the action +* pointed by handle. +* @see struct rte_flow_action_indirect_list +* @param query +* If not NULL, pointer to storage for the associated query data type. +* Query result returned on async completion event. +* @see struct rte_flow_action_indirect_list +* @param mode +* Operational mode. +* @param user_data +* The user data that will be returned on async completion event. +* @param error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* - (0) if success. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOTSUP) if underlying device does not support this functionality. +* - (-EINVAL) if *handle* or *mode* invalid or +* both *update* and *query* are NULL. +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_query_update(uint16_t port_id,
uint32_tqueue_id,lib/ethdev/rte_flow.h +3
-0+const struct rte_flow_op_attr *attr, + const struct + rte_flow_action_list_handle*handle,
lib/ethdev/rte_flow.h +2
-0+ const void **update, void **query, + enum
rte_flow_query_update_modemode,lib/ethdev/rte_flow.h +4
-0+void *user_data, + struct rte_flow_error *error); + + #ifdef __cplusplus }#endif lib/ethdev/rte_flow_driver.h +41
-0@@ -121,6 +121,17 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_create() */ +struct rte_flow_action_list_handle *(*action_list_handle_create) + (struct rte_eth_dev *dev, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action actions[], +struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_destroy() */ +int (*action_list_handle_destroy) + (struct rte_eth_dev *dev, +struct rte_flow_action_list_handle *handle, +struct rte_flow_error *error);/** See rte_flow_tunnel_decap_set() */ int (*tunnel_decap_set) (struct rte_eth_dev *dev,@@ -302,6 +313,36 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, void *user_data, struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_create() */ +struct rte_flow_action_list_handle * + (*async_action_list_handle_create) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_destroy() */ +int (*async_action_list_handle_destroy) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *action_handle, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_query_update() */ +int (*action_list_handle_query_update) + (struct rte_eth_dev *dev, +const struct rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_query_update() */ +int (*async_action_list_handle_query_update) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +void *user_data,struct rte_flow_error *error); + };/** lib/ethdev/version.map +8
-1@@ -299,6 +299,14 @@ EXPERIMENTAL { rte_flow_action_handle_query_update; rte_flow_async_action_handle_query_update; rte_flow_async_create_by_index; + + # added in 23.07 + rte_flow_action_list_handle_create; + rte_flow_action_list_handle_destroy; + rte_flow_action_list_handle_query_update; + rte_flow_async_action_list_handle_create; + rte_flow_async_action_list_handle_destroy; + rte_flow_async_action_list_handle_query_update; }; INTERNAL { --2.34.1
Hello Ori,
[snip]
Quoted 19 lines
Quoted 10 lines
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Query and/or update indirect flow actions list.
+ * If both query and update not NULL, the function atomically
+ * queries and updates indirect action. Query and update are carried in order
+ * specified in the mode parameter.
+ * If ether query or update is NULL, the function executesQuoted 8 lines
+ * complementing operation.
+ *
+ * @paramport_id
+ * Port identifier of Ethernet device.
+ * @param handle
+ * Handle for the indirect actions list object to be updated.
+ * @param update
+ * If not NULL, update profile specification used to modify the action
Quoted 4 lines
It should be explained that the upate/query points always to array with the size of number of actions, the the query/update query/upate all the actions at the same time
I added update and query parameters description in v5
Quoted 166 lines
This comment is for all such parameters in async and synced functions.
Quoted 164 lines
+ * pointed by handle.
+ * @see structrte_flow_action_indirect_list
+ * @param query
+ * If not NULL pointer to storage for the associated query data type.
+ * @see structrte_flow_action_indirect_list
+ * @param mode
+ * Operational mode.
+ * @param error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * - (0) if success.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-ENOTSUP) if underlying device does not support this functionality.
+ * - (-EINVAL) if *handle* or *mode* invalid or
+ * both *query* and *update* are NULL.
+ */lib/ethdev/rte_flow.h +5
-0+__rte_experimental +int +rte_flow_action_list_handle_query_update (uint16_t port_id, +const struct + rte_flow_action_list_handle*handle,
(quoted diff) +2
-0+ const void **update, void **query, + enum
rte_flow_query_update_modemode,lib/ethdev/rte_flow.h +42
-0+ struct rte_flow_error *error); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice. +* +* Enqueue async indirect flow actions list query and/or update +* +* @param port_id +* Port identifier of Ethernet device. +* @param queue_id +* Flow queue which is used to update the rule. +* @param attr +* Indirect action update operation attributes. +* @param handle +* Handle for the indirect actions list object to be updated. +* @param update +* If not NULL, update profile specification used to modify the action +* pointed by handle. +* @see struct rte_flow_action_indirect_list +* @param query +* If not NULL, pointer to storage for the associated query data type. +* Query result returned on async completion event. +* @see struct rte_flow_action_indirect_list +* @param mode +* Operational mode. +* @param user_data +* The user data that will be returned on async completion event. +* @param error +* Perform verbose error reporting if not NULL. +* PMDs initialize this structure in case of error only. +* +* @return +* - (0) if success. +* - (-ENODEV) if *port_id* invalid. +* - (-ENOTSUP) if underlying device does not support this functionality. +* - (-EINVAL) if *handle* or *mode* invalid or +* both *update* and *query* are NULL. +*/ +__rte_experimental +int +rte_flow_async_action_list_handle_query_update(uint16_t port_id,
uint32_tqueue_id,lib/ethdev/rte_flow.c +3
-0+const struct rte_flow_op_attr *attr, + const struct + rte_flow_action_list_handle*handle,
(quoted diff) +2
-0+ const void **update, void **query, + enum
rte_flow_query_update_modemode,lib/ethdev/rte_flow.h +4
-0+void *user_data, + struct rte_flow_error *error); + + #ifdef __cplusplus }#endif lib/ethdev/rte_flow_driver.h +41
-0@@ -121,6 +121,17 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_create() */ +struct rte_flow_action_list_handle *(*action_list_handle_create) + (struct rte_eth_dev *dev, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action actions[], +struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_destroy() */ +int (*action_list_handle_destroy) + (struct rte_eth_dev *dev, +struct rte_flow_action_list_handle *handle, +struct rte_flow_error *error);/** See rte_flow_tunnel_decap_set() */ int (*tunnel_decap_set) (struct rte_eth_dev *dev,@@ -302,6 +313,36 @@ struct rte_flow_ops { const void *update, void *query, enum rte_flow_query_update_mode qu_mode, void *user_data, struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_create() */ +struct rte_flow_action_list_handle * + (*async_action_list_handle_create) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_indir_action_conf *conf, +const struct rte_flow_action *actions, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_destroy() */ +int (*async_action_list_handle_destroy) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *op_attr, +struct rte_flow_action_list_handle *action_handle, +void *user_data,struct rte_flow_error *error); +/** @see rte_flow_action_list_handle_query_update() */ +int (*action_list_handle_query_update) + (struct rte_eth_dev *dev, +const struct rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +struct rte_flow_error *error); +/** @see rte_flow_async_action_list_handle_query_update() */ +int (*async_action_list_handle_query_update) + (struct rte_eth_dev *dev,uint32_t queue_id, +const struct rte_flow_op_attr *attr, +const struct rte_flow_action_list_handle *handle, +const void **update,void **query, +enum rte_flow_query_update_mode mode, +void *user_data,struct rte_flow_error *error); + };/** lib/ethdev/version.map +8
-1@@ -299,6 +299,14 @@ EXPERIMENTAL { rte_flow_action_handle_query_update; rte_flow_async_action_handle_query_update; rte_flow_async_create_by_index; + + # added in 23.07 + rte_flow_action_list_handle_create; + rte_flow_action_list_handle_destroy; + rte_flow_action_list_handle_query_update; + rte_flow_async_action_list_handle_create; + rte_flow_async_action_list_handle_destroy; + rte_flow_async_action_list_handle_query_update; }; INTERNAL { --2.34.1
PATCH v5 1/2 ethdev: add indirect list flow action
In reply to Gregory EtelsonIndirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.
Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.
Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.
There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.
flow 1:
/ indirect handle H conf C1 /
| |
| |
| | flow 2:
| | / indirect handle H conf C2 /
| | | |
| | | |
| | | |
=========================================================
^ | | | |
| | V | V
| ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
| flow mutable flow mutable
| context 1 context 2
| ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
indirect | | |
action | | |
context | V V
| -----------------------------------------------------
| action mutable context
| ----------------------------------------------------- v action immutable context
=========================================================
Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• Indirect METER_MARK policy is immutable action member and profile is action mutable action member.
• Indirect METER_MARK flow action defines init_color as flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.
If indirect list handle was created from a list of actions A1 / A2 ... An / END
indirect list flow action can update Ai flow mutable context in the action configuration parameter.
Indirect list action configuration is and array [C1, C2, .., Cn] where Ci corresponds to Ai in the action handle source. Ci configuration element points Ai flow mutable update, or it's NULL if Ai has no flow mutable update.
Indirect list action configuration can be NULL if the action has no flow mutable updates.
Template API:
Action template format:
template .. indirect_list handle Htmpl conf Ctmpl ..
mask .. indirect_list handle Hmask conf Cmask ..
1 If Htmpl was masked (Hmask != 0), it will be fixed in that template.
Otherwise, indirect action value is set in a flow rule.
2 If Htmpl and Ctmpl[i] were masked (Hmask !=0 and Cmask[i] != 0),
Htmpl's Ai action flow mutable context fill be updated to Ctmpl[i] values and will be fixed in that template.
Flow rule format:
actions .. indirect_list handle Hflow conf Cflow ..
3 If Htmpl was not masked in actions template, Hflow references an
action of the same type as Htmpl.
4 Cflow[i] updates handle's Ai flow mutable configuration if
the Ci was not masked in action template.
--- app/test-pmd/cmdline_flow.c | 207 ++++++++++++++++++- app/test-pmd/config.c | 163 +++++++++++---- app/test-pmd/testpmd.h | 9 +- doc/guides/nics/features/default.ini | 1 + doc/guides/prog_guide/rte_flow.rst | 119 +++++++++++ doc/guides/rel_notes/release_23_07.rst | 2 + lib/ethdev/ethdev_trace.h | 88 ++++++++ lib/ethdev/ethdev_trace_points.c | 18 ++ lib/ethdev/rte_flow.c | 171 ++++++++++++++++ lib/ethdev/rte_flow.h | 270 +++++++++++++++++++++++++ lib/ethdev/rte_flow_driver.h | 41 ++++ lib/ethdev/version.map | 8 + 12 files changed, 1055 insertions(+), 42 deletions(-)
app/test-pmd/cmdline_flow.c +206 -1
@@ -145,6 +145,7 @@ enum index {/* Queue indirect action arguments */ QUEUE_INDIRECT_ACTION_CREATE , +QUEUE_INDIRECT_ACTION_LIST_CREATE ,QUEUE_INDIRECT_ACTION_UPDATE ,QUEUE_INDIRECT_ACTION_DESTROY , QUEUE_INDIRECT_ACTION_QUERY,
@@ -157,6 +158,7 @@ enum index {QUEUE_INDIRECT_ACTION_TRANSFER ,QUEUE_INDIRECT_ACTION_CREATE_POSTPONE ,QUEUE_INDIRECT_ACTION_SPEC , +QUEUE_INDIRECT_ACTION_LIST ,/* Queue indirect action update arguments */ QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE,
@@ -242,6 +244,8 @@ enum index {/* Indirect action arguments */ INDIRECT_ACTION_CREATE , +INDIRECT_ACTION_LIST_CREATE , +INDIRECT_ACTION_FLOW_CONF_CREATE ,INDIRECT_ACTION_UPDATE ,INDIRECT_ACTION_DESTROY , INDIRECT_ACTION_QUERY,
@@ -253,6 +257,8 @@ enum index {INDIRECT_ACTION_EGRESS ,INDIRECT_ACTION_TRANSFER ,INDIRECT_ACTION_SPEC , +INDIRECT_ACTION_LIST , +INDIRECT_ACTION_FLOW_CONF ,/* Indirect action destroy arguments */ INDIRECT_ACTION_DESTROY_ID,
@@ -626,6 +632,11 @@ enum index {ACTION_SAMPLE_INDEX ,ACTION_SAMPLE_INDEX_VALUE ,ACTION_INDIRECT , +ACTION_INDIRECT_LIST , +ACTION_INDIRECT_LIST_HANDLE , +ACTION_INDIRECT_LIST_CONF , +INDIRECT_LIST_ACTION_ID2PTR_HANDLE , +INDIRECT_LIST_ACTION_ID2PTR_CONF ,ACTION_SHARED_INDIRECT ,INDIRECT_ACTION_PORT , INDIRECT_ACTION_ID2PTR,
@@ -1266,6 +1277,7 @@ static const enum index next_qia_create_attr[] = {QUEUE_INDIRECT_ACTION_TRANSFER ,QUEUE_INDIRECT_ACTION_CREATE_POSTPONE ,QUEUE_INDIRECT_ACTION_SPEC , +QUEUE_INDIRECT_ACTION_LIST , ZERO, };
@@ -1294,6 +1306,8 @@ static const enum index next_ia_create_attr[] = {INDIRECT_ACTION_EGRESS ,INDIRECT_ACTION_TRANSFER ,INDIRECT_ACTION_SPEC , +INDIRECT_ACTION_LIST , +INDIRECT_ACTION_FLOW_CONF , ZERO, };
@@ -1303,6 +1317,13 @@ static const enum index next_ia[] = {ZERO }; +static const enum index next_ial[] = { +ACTION_INDIRECT_LIST_HANDLE , +ACTION_INDIRECT_LIST_CONF , +ACTION_NEXT , +ZERO +}; +static const enum index next_qia_qu_attr[] = {QUEUE_INDIRECT_ACTION_QU_MODE ,QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE ,
@@ -2013,6 +2034,7 @@ static const enum index next_action[] = {ACTION_AGE_UPDATE ,ACTION_SAMPLE ,ACTION_INDIRECT , +ACTION_INDIRECT_LIST ,ACTION_SHARED_INDIRECT ,ACTION_MODIFY_FIELD , ACTION_CONNTRACK,
@@ -2289,6 +2311,7 @@ static const enum index next_action_sample[] = {ACTION_RAW_ENCAP ,ACTION_VXLAN_ENCAP ,ACTION_NVGRE_ENCAP , +ACTION_REPRESENTED_PORT ,ACTION_NEXT , ZERO, };
@@ -2539,6 +2562,10 @@ static int parse_ia_destroy(struct context *ctx, const struct token *token,static int parse_ia_id2ptr (struct context *ctx,const struct token *token,const char *str,unsigned int len,void *buf,unsigned int size); + +static int parse_indlst_id2ptr (struct context *ctx,const struct token *token, +const char *str,unsigned int len,void *buf, +unsigned int size);static int parse_ia_port (struct context *ctx,const struct token *token,const char *str,unsigned int len,void *buf,unsigned int size);
@@ -2627,6 +2654,16 @@ static int comp_qu_mode_name(struct context *ctx, const struct token *token, unsigned int ent, char *buf, unsigned int size); +struct indlst_conf { +uint32_t id; +uint32_t conf_num; +struct rte_flow_action *actions; +const void **conf; +SLIST_ENTRY (indlst_conf) next; +}; + +static const struct indlst_conf *indirect_action_list_conf_get (uint32_t conf_id); +/** Token definitions. */ static const struct token token_list[] = {/* Special tokens. */
@@ -3426,6 +3463,12 @@ static const struct token token_list[] = { .help = "specify action to create indirect handle", .next = NEXT(next_action), }, + [QUEUE_INDIRECT_ACTION_LIST] = { + .name = "list", + .help = "specify actions for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_qia, + },/* Top-level command. */ [PUSH] = { .name = "push",
@@ -6775,6 +6818,37 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), .call = parse_vc, }, + [ACTION_INDIRECT_LIST] = { + .name = "indirect_list", + .help = "apply indirect list action by id", + .priv =PRIV_ACTION (INDIRECT_LIST , +sizeof (struct + rte_flow_action_indirect_list)), + .next = NEXT(next_ial), + .call = parse_vc, + }, + [ACTION_INDIRECT_LIST_HANDLE] = { + .name = "handle", + .help = "indirect list handle", + .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), + .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uintptr_t))), + }, + [ACTION_INDIRECT_LIST_CONF] = { + .name = "conf", + .help = "indirect list configuration", + .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), + .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uintptr_t))), + }, + [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { + .type = "UNSIGNED", + .help = "unsigned integer value", + .call = parse_indlst_id2ptr, + }, + [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { + .type = "UNSIGNED", + .help = "unsigned integer value", + .call = parse_indlst_id2ptr, + }, [ACTION_SHARED_INDIRECT] = { .name = "shared_indirect", .help = "apply indirect action by id and port",
@@ -6823,6 +6897,18 @@ static const struct token token_list[] = { .help = "specify action to create indirect handle", .next = NEXT(next_action), }, + [INDIRECT_ACTION_LIST] = { + .name = "list", + .help = "specify actions for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_ia, + }, + [INDIRECT_ACTION_FLOW_CONF] = { + .name = "flow_conf", + .help = "specify actions configuration for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_ia, + }, [ACTION_POL_G] = { .name = "g_actions", .help = "submit a list of associated actions for green",
@@ -7181,6 +7267,12 @@ parse_ia(struct context *ctx, const struct token *token,return len;case INDIRECT_ACTION_QU_MODE :return len; +case INDIRECT_ACTION_LIST : + out->command =INDIRECT_ACTION_LIST_CREATE ; +return len; +case INDIRECT_ACTION_FLOW_CONF : + out->command =INDIRECT_ACTION_FLOW_CONF_CREATE ; +return len;default :return -1 ; }
@@ -7278,6 +7370,9 @@ parse_qia(struct context *ctx, const struct token *token,return len;case QUEUE_INDIRECT_ACTION_QU_MODE :return len; +case QUEUE_INDIRECT_ACTION_LIST : + out->command =QUEUE_INDIRECT_ACTION_LIST_CREATE ; +return len;default :return -1 ; }
@@ -7454,10 +7549,12 @@ parse_vc(struct context *ctx, const struct token *token,return -1 ;break ;case ACTIONS : - out->args.vc.actions = + out->args.vc.actions = out->args.vc.pattern ? (void *)RTE_ALIGN_CEIL ((uintptr_t ) (out->args.vc.pattern + out->args.vc.pattern_n), +sizeof (double )) : + (void *)RTE_ALIGN_CEIL ((uintptr_t )(out +1 ),sizeof (double )); ctx->object = out->args.vc.actions; ctx->objmask =NULL ;
@@ -10412,6 +10509,49 @@ parse_ia_id2ptr(struct context *ctx, const struct token *token,return ret; } +static int +parse_indlst_id2ptr (struct context *ctx,const struct token *token, +const char *str,unsigned int len, + void __rte_unused *buf, unsigned int __rte_unused size) +{ +struct rte_flow_action *action = ctx->object; +struct rte_flow_action_indirect_list *action_conf; +const struct indlst_conf *indlst_conf; +uint32_t id; +int ret; + +if (!action) +return -1 ; + ctx->objdata =0 ; + ctx->object = &id; + ctx->objmask =NULL ; + ret =parse_int (ctx, token, str, len, ctx->object,sizeof (id)); +if (ret != (int )len) +return ret; + ctx->object = action; + action_conf = (void *)(uintptr_t )action->conf; + action_conf->conf =NULL ; +switch (ctx->curr) { +case INDIRECT_LIST_ACTION_ID2PTR_HANDLE : + action_conf->handle = (typeof(action_conf->handle)) +port_action_handle_get_by_id (ctx->port, id); +if (!action_conf->handle) { +printf ("no indirect list handle for id %u\n" , id); +return -1 ; + } +break ; +case INDIRECT_LIST_ACTION_ID2PTR_CONF : + indlst_conf =indirect_action_list_conf_get (id); +if (!indlst_conf) +return -1 ; + action_conf->conf = (const void **)indlst_conf->conf; +break ; +default : +break ; + } +return ret; +} + static int parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, const char *str, unsigned int len,
@@ -11453,6 +11593,64 @@ cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, *hdr = &cmd_flow_token_hdr; } +static SLIST_HEAD(, indlst_conf) indlst_conf_head = +SLIST_HEAD_INITIALIZER (); + +static void +indirect_action_flow_conf_create (const struct buffer *in) +{ +int len, ret; +uint32_t i; +struct indlst_conf *indlst_conf =NULL ; +size_t base =RTE_ALIGN (sizeof (*indlst_conf),8 ); +struct rte_flow_action *src = in->args.vc.actions; + +if (!in->args.vc.actions_n) + goto end; + len =rte_flow_conv (RTE_FLOW_CONV_OP_ACTIONS ,NULL ,0 , src,NULL ); +if (len <=0 ) + goto end; + len =RTE_ALIGN (len,16 ); + + indlst_conf =calloc (1 , base + len + + in->args.vc.actions_n *sizeof (uintptr_t )); +if (!indlst_conf) + goto end; + indlst_conf->id = in->args.vc.attr.group; + indlst_conf->conf_num = in->args.vc.actions_n -1 ; + indlst_conf->actions =RTE_PTR_ADD (indlst_conf, base); + ret =rte_flow_conv (RTE_FLOW_CONV_OP_ACTIONS , indlst_conf->actions, + len, src,NULL ); +if (ret <=0 ) { +free (indlst_conf); + indlst_conf =NULL ; + goto end; + } + indlst_conf->conf =RTE_PTR_ADD (indlst_conf, base + len); +for (i =0 ; i < indlst_conf->conf_num; i++) + indlst_conf->conf[i] = indlst_conf->actions[i].conf; +SLIST_INSERT_HEAD (&indlst_conf_head, indlst_conf, next); +end: +if (indlst_conf) +printf ("created indirect action list configuration %u\n" , + in->args.vc.attr.group); +else +printf ("cannot create indirect action list configuration %u\n" , + in->args.vc.attr.group); +} + +static const struct indlst_conf * +indirect_action_list_conf_get (uint32_t conf_id) +{ +const struct indlst_conf *conf; + + SLIST_FOREACH(conf, &indlst_conf_head, next) { +if (conf->id == conf_id) +return conf; + } +return NULL ; +} +/** Dispatch parsed buffer to function calls. */ static void cmd_flow_parsed (const struct buffer *in)
@@ -11532,6 +11730,7 @@ cmd_flow_parsed(const struct buffer *in) in->args.aged.destroy);break ;case QUEUE_INDIRECT_ACTION_CREATE : +case QUEUE_INDIRECT_ACTION_LIST_CREATE : port_queue_action_handle_create( in->port, in->queue, in->postpone, in->args.vc.attr.group,
@@ -11567,8 +11766,10 @@ cmd_flow_parsed(const struct buffer *in) in->args.vc.actions);break ;case INDIRECT_ACTION_CREATE : +case INDIRECT_ACTION_LIST_CREATE : port_action_handle_create( in->port, in->args.vc.attr.group, + in->command == INDIRECT_ACTION_LIST_CREATE, &((const struct rte_flow_indir_action_conf) { .ingress = in->args.vc.attr.ingress, .egress = in->args.vc.attr.egress,
@@ -11576,6 +11777,9 @@ cmd_flow_parsed(const struct buffer *in) }), in->args.vc.actions);break ; +case INDIRECT_ACTION_FLOW_CONF_CREATE : +indirect_action_flow_conf_create (in); +break ;case INDIRECT_ACTION_DESTROY : port_action_handle_destroy(in->port, in->args.ia_destroy.action_id_n,
@@ -11653,6 +11857,7 @@ cmd_flow_parsed(const struct buffer *in)default :break ; } +fflush (stdout); }/** Token generator and output processing callback (cmdline API). */
app/test-pmd/config.c +124 -39
229 lines not on this page · raw message
app/test-pmd/testpmd.h +7 -2
@@ -228,7 +228,12 @@ struct port_indirect_action {struct port_indirect_action *next;/**< Next flow in list. */ uint32_t id;/**< Indirect action ID. */ enum rte_flow_action_type type;/**< Action type. */ -struct rte_flow_action_handle *handle;/**< Indirect action handle. */ +union { +struct rte_flow_action_handle *handle; +/**< Indirect action handle. */ +struct rte_flow_action_list_handle *list_handle; +/**< Indirect action list handle*/ + };enum age_action_context_type age_type;/**< Age action context type. */ };
@@ -921,7 +926,7 @@ void update_fwd_ports(portid_t new_pid);void set_fwd_eth_peer (portid_t port_id,char *peer_addr);void port_mtu_set (portid_t port_id,uint16_t mtu); -int port_action_handle_create (portid_t port_id,uint32_t id, +int port_action_handle_create (portid_t port_id,uint32_t id,bool indirect_list,const struct rte_flow_indir_action_conf *conf,const struct rte_flow_action *action); int port_action_handle_destroy(portid_t port_id,
doc/guides/nics/features/default.ini +1 -0
@@ -158,6 +158,7 @@ drop = flag = inc_tcp_ack = inc_tcp_seq = +indirect_list = jump = mac_swap = mark =
doc/guides/prog_guide/rte_flow.rst +119 -0
125 lines not on this page · raw message
doc/guides/rel_notes/release_23_07.rst +2 -0
@@ -55,6 +55,8 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= + * **Added INDIRECT_LIST flow action.** + Removed Items -------------
lib/ethdev/ethdev_trace.h +88 -0
94 lines not on this page · raw message
lib/ethdev/ethdev_trace_points.c +18 -0
@@ -750,3 +750,21 @@ RTE_TRACE_POINT_REGISTER(rte_tm_trace_wred_profile_add,RTE_TRACE_POINT_REGISTER (rte_tm_trace_wred_profile_delete, lib.ethdev.tm.wred_profile_delete) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_action_list_handle_create, + lib.ethdev.flow.action_list_handle_create) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_action_list_handle_destroy, + lib.ethdev.flow.action_list_handle_destroy) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_action_list_handle_query_update, + lib.ethdev.flow.action_list_handle_query_update) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_async_action_list_handle_create, + lib.ethdev.flow.async_action_list_handle_create) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_async_action_list_handle_destroy, + lib.ethdev.flow.async_action_list_handle_destroy) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_async_action_list_handle_query_update, + lib.ethdev.flow.async_action_list_handle_query_update)
lib/ethdev/rte_flow.c +171 -0
180 lines not on this page · raw message
lib/ethdev/rte_flow.h +270 -0
282 lines not on this page · raw message
lib/ethdev/rte_flow_driver.h +41 -0
53 lines not on this page · raw message
lib/ethdev/version.map +8 -0
@@ -299,6 +299,14 @@ EXPERIMENTAL { rte_flow_action_handle_query_update; rte_flow_async_action_handle_query_update; rte_flow_async_create_by_index; + + # added in 23.07 + rte_flow_action_list_handle_create; + rte_flow_action_list_handle_destroy; + rte_flow_action_list_handle_query_update; + rte_flow_async_action_list_handle_create; + rte_flow_async_action_list_handle_destroy; + rte_flow_async_action_list_handle_query_update; }; INTERNAL {
Signature · 1 line
2.34.1
PATCH v5 2/2 ethdev: add indirect list METER_MARK update structures
In the indirect list API, update action and update flow contexts are mutually exclusive.
The patch splits legacy METER_MASK update structure to support indirect list API:
struct rte_flow_indirect_update_action_meter_mark defines METER_MARK action context that is shared between all flows that reference a given indirect list handle.
struct rte_flow_indirect_update_flow_meter_mark defines METER_MARK context private to specific flow.
--- lib/ethdev/rte_flow.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
lib/ethdev/rte_flow.h +32 -0
@@ -3891,6 +3891,38 @@ struct rte_flow_update_meter_mark { uint32_t reserved:27; }; +/** +* @see RTE_FLOW_ACTION_TYPE_METER_MARK +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +* +* Update action mutable context. +*/ +struct rte_flow_indirect_update_action_meter_mark { +/** New meter_mark parameters to be updated. */ +struct rte_flow_action_meter_mark meter_mark; +/** The profile will be updated. */ +uint32_t profile_valid:1 ; +/** The policy will be updated. */ +uint32_t policy_valid:1 ; +/** The color mode will be updated. */ +uint32_t color_mode_valid:1 ; +/** The meter state will be updated. */ +uint32_t state_valid:1 ; +/** Reserved bits for the future usage. */ +uint32_t reserved:28 ; +}; + +/** +* @see RTE_FLOW_ACTION_TYPE_METER_MARK +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +* +* Update flow mutable context. +*/ +struct rte_flow_indirect_update_flow_meter_mark { +/** Updated init color applied to packet */ +enum rte_color init_color; +}; +/* Mbuf dynamic field offset for metadata. */ extern int32_t rte_flow_dynf_metadata_offs;
Signature · 1 line
2.34.1
RE: [PATCH v5 2/2] ethdev: add indirect list METER_MARK update structures
Hi Gregory,
Quoted 41 lines
-----Original Message-----
From: Gregory Etelson <[email protected]>
Sent: Thursday, May 25, 2023 11:12 AMIn the indirect list API, update action and update flow contexts are mutually exclusive.
The patch splits legacyMETER_MASKupdate structure to support indirect list API:
struct rte_flow_indirect_update_action_meter_markdefinesMETER_MARK
action context that is shared between all flows that reference a given indirect list handle.
struct rte_flow_indirect_update_flow_meter_markdefinesMETER_MARKcontext private to specific flow.Signed-off-by Gregory Etelson <[email protected]>--- lib/ethdev/rte_flow.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)lib/ethdev/rte_flow.h +11
-0@@ -3891,6 +3891,38 @@ struct rte_flow_update_meter_mark { uint32_t reserved:27; }; +/** +* @see RTE_FLOW_ACTION_TYPE_METER_MARK +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +* +* Update action mutable context. +*/ +struct rte_flow_indirect_update_action_meter_mark { +/** New meter_mark parameters to be updated. */ +struct rte_flow_action_meter_mark meter_mark; +/** The profile will be updated. */ +uint32_t profile_valid:1 ;
lib/ethdev/rte_flow.h struct rte_flow_update_meter_mark { · line 3914
Quoted 10 lines
lib/ethdev/rte_flow.h +10
-0+/** The policy will be updated. */ + uint32_t policy_valid:1; +/** The color mode will be updated. */ + uint32_t color_mode_valid:1; +/** The meter state will be updated. */ + uint32_t state_valid:1; +/** Reserved bits for the future usage. */ + uint32_t reserved:28; +}; +
Why did you create new meter_mark structure?
Quoted 15 lines
lib/ethdev/rte_flow.h +11
-1+/** +* @see RTE_FLOW_ACTION_TYPE_METER_MARK +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +* +* Update flow mutable context. +*/ +struct rte_flow_indirect_update_flow_meter_mark { +/** Updated init color applied to packet */ +enum rte_color init_color; +}; +/* Mbuf dynamic field offset for metadata. */ extern int32_t rte_flow_dynf_metadata_offs; --
Quoted 1 line
2.34.1
Best,
Ori
RE: [PATCH v5 2/2] ethdev: add indirect list METER_MARK update structures
Hello Ori,
[snip]
Quoted 15 lines
Quoted 15 lines
lib/ethdev/rte_flow.h +15
-0+/** +* @see RTE_FLOW_ACTION_TYPE_METER_MARK +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +* +* Update action mutable context. +*/ +struct rte_flow_indirect_update_action_meter_mark { +/** New meter_mark parameters to be updated. */ +struct rte_flow_action_meter_mark meter_mark; +/** The profile will be updated. */ +uint32_t profile_valid:1 ; +/** The policy will be updated. */ +uint32_t policy_valid:1 ; +/** The color mode will be updated. */ +uint32_t color_mode_valid:1 ;
Quoted 9 lines
lib/ethdev/rte_flow.h struct rte_flow_update_meter_mark { · line 3914
Quoted 6 lines
lib/ethdev/rte_flow.h +6
-0+/** The meter state will be updated. */ + uint32_t state_valid:1; +/** Reserved bits for the future usage. */ + uint32_t reserved:28; +}; +Why did you create new
meter_markstructure?
Fixed.
Quoted 19 lines
Quoted 15 lines
lib/ethdev/rte_flow.h +11
-1+/** +* @see RTE_FLOW_ACTION_TYPE_METER_MARK +* @see RTE_FLOW_ACTION_TYPE_INDIRECT_LIST +* +* Update flow mutable context. +*/ +struct rte_flow_indirect_update_flow_meter_mark { +/** Updated init color applied to packet */ +enum rte_color init_color; +}; +/* Mbuf dynamic field offset for metadata. */ extern int32_t rte_flow_dynf_metadata_offs; --Quoted 1 line
2.34.1
Best,
Ori
PATCH v6 1/1 ethdev: add indirect list flow action
In reply to Gregory EtelsonIndirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.
Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.
Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.
There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.
flow 1:
/ indirect handle H conf C1 /
| |
| |
| | flow 2:
| | / indirect handle H conf C2 /
| | | |
| | | |
| | | |
=========================================================
^ | | | |
| | V | V
| ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
| flow mutable flow mutable
| context 1 context 2
| ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
indirect | | |
action | | |
context | V V
| -----------------------------------------------------
| action mutable context
| ----------------------------------------------------- v action immutable context
=========================================================
Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• Indirect METER_MARK policy is immutable action member and profile is action mutable action member.
• Indirect METER_MARK flow action defines init_color as flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.
If indirect list handle was created from a list of actions A1 / A2 ... An / END
indirect list flow action can update Ai flow mutable context in the action configuration parameter.
Indirect list action configuration is and array [C1, C2, .., Cn] where Ci corresponds to Ai in the action handle source. Ci configuration element points Ai flow mutable update, or it's NULL if Ai has no flow mutable update.
Indirect list action configuration can be NULL if the action has no flow mutable updates.
Template API:
Action template format:
template .. indirect_list handle Htmpl conf Ctmpl ..
mask .. indirect_list handle Hmask conf Cmask ..
1 If Htmpl was masked (Hmask != 0), it will be fixed in that template.
Otherwise, indirect action value is set in a flow rule.
2 If Htmpl and Ctmpl[i] were masked (Hmask !=0 and Cmask[i] != 0),
Htmpl's Ai action flow mutable context fill be updated to Ctmpl[i] values and will be fixed in that template.
Flow rule format:
actions .. indirect_list handle Hflow conf Cflow ..
3 If Htmpl was not masked in actions template, Hflow references an
action of the same type as Htmpl.
4 Cflow[i] updates handle's Ai flow mutable configuration if
the Ci was not masked in action template.
--- app/test-pmd/cmdline_flow.c | 207 ++++++++++++++++++- app/test-pmd/config.c | 163 +++++++++++---- app/test-pmd/testpmd.h | 9 +- doc/guides/nics/features/default.ini | 1 + doc/guides/prog_guide/rte_flow.rst | 119 +++++++++++ doc/guides/rel_notes/release_23_07.rst | 2 + lib/ethdev/ethdev_trace.h | 88 ++++++++ lib/ethdev/ethdev_trace_points.c | 18 ++ lib/ethdev/rte_flow.c | 171 +++++++++++++++ lib/ethdev/rte_flow.h | 276 +++++++++++++++++++++++++ lib/ethdev/rte_flow_driver.h | 41 ++++ lib/ethdev/version.map | 8 + 12 files changed, 1061 insertions(+), 42 deletions(-)
app/test-pmd/cmdline_flow.c +206 -1
@@ -145,6 +145,7 @@ enum index {/* Queue indirect action arguments */ QUEUE_INDIRECT_ACTION_CREATE , +QUEUE_INDIRECT_ACTION_LIST_CREATE ,QUEUE_INDIRECT_ACTION_UPDATE ,QUEUE_INDIRECT_ACTION_DESTROY , QUEUE_INDIRECT_ACTION_QUERY,
@@ -157,6 +158,7 @@ enum index {QUEUE_INDIRECT_ACTION_TRANSFER ,QUEUE_INDIRECT_ACTION_CREATE_POSTPONE ,QUEUE_INDIRECT_ACTION_SPEC , +QUEUE_INDIRECT_ACTION_LIST ,/* Queue indirect action update arguments */ QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE,
@@ -242,6 +244,8 @@ enum index {/* Indirect action arguments */ INDIRECT_ACTION_CREATE , +INDIRECT_ACTION_LIST_CREATE , +INDIRECT_ACTION_FLOW_CONF_CREATE ,INDIRECT_ACTION_UPDATE ,INDIRECT_ACTION_DESTROY , INDIRECT_ACTION_QUERY,
@@ -253,6 +257,8 @@ enum index {INDIRECT_ACTION_EGRESS ,INDIRECT_ACTION_TRANSFER ,INDIRECT_ACTION_SPEC , +INDIRECT_ACTION_LIST , +INDIRECT_ACTION_FLOW_CONF ,/* Indirect action destroy arguments */ INDIRECT_ACTION_DESTROY_ID,
@@ -626,6 +632,11 @@ enum index {ACTION_SAMPLE_INDEX ,ACTION_SAMPLE_INDEX_VALUE ,ACTION_INDIRECT , +ACTION_INDIRECT_LIST , +ACTION_INDIRECT_LIST_HANDLE , +ACTION_INDIRECT_LIST_CONF , +INDIRECT_LIST_ACTION_ID2PTR_HANDLE , +INDIRECT_LIST_ACTION_ID2PTR_CONF ,ACTION_SHARED_INDIRECT ,INDIRECT_ACTION_PORT , INDIRECT_ACTION_ID2PTR,
@@ -1266,6 +1277,7 @@ static const enum index next_qia_create_attr[] = {QUEUE_INDIRECT_ACTION_TRANSFER ,QUEUE_INDIRECT_ACTION_CREATE_POSTPONE ,QUEUE_INDIRECT_ACTION_SPEC , +QUEUE_INDIRECT_ACTION_LIST , ZERO, };
@@ -1294,6 +1306,8 @@ static const enum index next_ia_create_attr[] = {INDIRECT_ACTION_EGRESS ,INDIRECT_ACTION_TRANSFER ,INDIRECT_ACTION_SPEC , +INDIRECT_ACTION_LIST , +INDIRECT_ACTION_FLOW_CONF , ZERO, };
@@ -1303,6 +1317,13 @@ static const enum index next_ia[] = {ZERO }; +static const enum index next_ial[] = { +ACTION_INDIRECT_LIST_HANDLE , +ACTION_INDIRECT_LIST_CONF , +ACTION_NEXT , +ZERO +}; +static const enum index next_qia_qu_attr[] = {QUEUE_INDIRECT_ACTION_QU_MODE ,QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE ,
@@ -2013,6 +2034,7 @@ static const enum index next_action[] = {ACTION_AGE_UPDATE ,ACTION_SAMPLE ,ACTION_INDIRECT , +ACTION_INDIRECT_LIST ,ACTION_SHARED_INDIRECT ,ACTION_MODIFY_FIELD , ACTION_CONNTRACK,
@@ -2289,6 +2311,7 @@ static const enum index next_action_sample[] = {ACTION_RAW_ENCAP ,ACTION_VXLAN_ENCAP ,ACTION_NVGRE_ENCAP , +ACTION_REPRESENTED_PORT ,ACTION_NEXT , ZERO, };
@@ -2539,6 +2562,10 @@ static int parse_ia_destroy(struct context *ctx, const struct token *token,static int parse_ia_id2ptr (struct context *ctx,const struct token *token,const char *str,unsigned int len,void *buf,unsigned int size); + +static int parse_indlst_id2ptr (struct context *ctx,const struct token *token, +const char *str,unsigned int len,void *buf, +unsigned int size);static int parse_ia_port (struct context *ctx,const struct token *token,const char *str,unsigned int len,void *buf,unsigned int size);
@@ -2627,6 +2654,16 @@ static int comp_qu_mode_name(struct context *ctx, const struct token *token, unsigned int ent, char *buf, unsigned int size); +struct indlst_conf { +uint32_t id; +uint32_t conf_num; +struct rte_flow_action *actions; +const void **conf; +SLIST_ENTRY (indlst_conf) next; +}; + +static const struct indlst_conf *indirect_action_list_conf_get (uint32_t conf_id); +/** Token definitions. */ static const struct token token_list[] = {/* Special tokens. */
@@ -3426,6 +3463,12 @@ static const struct token token_list[] = { .help = "specify action to create indirect handle", .next = NEXT(next_action), }, + [QUEUE_INDIRECT_ACTION_LIST] = { + .name = "list", + .help = "specify actions for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_qia, + },/* Top-level command. */ [PUSH] = { .name = "push",
@@ -6775,6 +6818,37 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), .call = parse_vc, }, + [ACTION_INDIRECT_LIST] = { + .name = "indirect_list", + .help = "apply indirect list action by id", + .priv =PRIV_ACTION (INDIRECT_LIST , +sizeof (struct + rte_flow_action_indirect_list)), + .next = NEXT(next_ial), + .call = parse_vc, + }, + [ACTION_INDIRECT_LIST_HANDLE] = { + .name = "handle", + .help = "indirect list handle", + .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), + .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uintptr_t))), + }, + [ACTION_INDIRECT_LIST_CONF] = { + .name = "conf", + .help = "indirect list configuration", + .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), + .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uintptr_t))), + }, + [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { + .type = "UNSIGNED", + .help = "unsigned integer value", + .call = parse_indlst_id2ptr, + }, + [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { + .type = "UNSIGNED", + .help = "unsigned integer value", + .call = parse_indlst_id2ptr, + }, [ACTION_SHARED_INDIRECT] = { .name = "shared_indirect", .help = "apply indirect action by id and port",
@@ -6823,6 +6897,18 @@ static const struct token token_list[] = { .help = "specify action to create indirect handle", .next = NEXT(next_action), }, + [INDIRECT_ACTION_LIST] = { + .name = "list", + .help = "specify actions for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_ia, + }, + [INDIRECT_ACTION_FLOW_CONF] = { + .name = "flow_conf", + .help = "specify actions configuration for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_ia, + }, [ACTION_POL_G] = { .name = "g_actions", .help = "submit a list of associated actions for green",
@@ -7181,6 +7267,12 @@ parse_ia(struct context *ctx, const struct token *token,return len;case INDIRECT_ACTION_QU_MODE :return len; +case INDIRECT_ACTION_LIST : + out->command =INDIRECT_ACTION_LIST_CREATE ; +return len; +case INDIRECT_ACTION_FLOW_CONF : + out->command =INDIRECT_ACTION_FLOW_CONF_CREATE ; +return len;default :return -1 ; }
@@ -7278,6 +7370,9 @@ parse_qia(struct context *ctx, const struct token *token,return len;case QUEUE_INDIRECT_ACTION_QU_MODE :return len; +case QUEUE_INDIRECT_ACTION_LIST : + out->command =QUEUE_INDIRECT_ACTION_LIST_CREATE ; +return len;default :return -1 ; }
@@ -7454,10 +7549,12 @@ parse_vc(struct context *ctx, const struct token *token,return -1 ;break ;case ACTIONS : - out->args.vc.actions = + out->args.vc.actions = out->args.vc.pattern ? (void *)RTE_ALIGN_CEIL ((uintptr_t ) (out->args.vc.pattern + out->args.vc.pattern_n), +sizeof (double )) : + (void *)RTE_ALIGN_CEIL ((uintptr_t )(out +1 ),sizeof (double )); ctx->object = out->args.vc.actions; ctx->objmask =NULL ;
@@ -10412,6 +10509,49 @@ parse_ia_id2ptr(struct context *ctx, const struct token *token,return ret; } +static int +parse_indlst_id2ptr (struct context *ctx,const struct token *token, +const char *str,unsigned int len, + void __rte_unused *buf, unsigned int __rte_unused size) +{ +struct rte_flow_action *action = ctx->object; +struct rte_flow_action_indirect_list *action_conf; +const struct indlst_conf *indlst_conf; +uint32_t id; +int ret; + +if (!action) +return -1 ; + ctx->objdata =0 ; + ctx->object = &id; + ctx->objmask =NULL ; + ret =parse_int (ctx, token, str, len, ctx->object,sizeof (id)); +if (ret != (int )len) +return ret; + ctx->object = action; + action_conf = (void *)(uintptr_t )action->conf; + action_conf->conf =NULL ; +switch (ctx->curr) { +case INDIRECT_LIST_ACTION_ID2PTR_HANDLE : + action_conf->handle = (typeof(action_conf->handle)) +port_action_handle_get_by_id (ctx->port, id); +if (!action_conf->handle) { +printf ("no indirect list handle for id %u\n" , id); +return -1 ; + } +break ; +case INDIRECT_LIST_ACTION_ID2PTR_CONF : + indlst_conf =indirect_action_list_conf_get (id); +if (!indlst_conf) +return -1 ; + action_conf->conf = (const void **)indlst_conf->conf; +break ; +default : +break ; + } +return ret; +} + static int parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, const char *str, unsigned int len,
@@ -11453,6 +11593,64 @@ cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, *hdr = &cmd_flow_token_hdr; } +static SLIST_HEAD(, indlst_conf) indlst_conf_head = +SLIST_HEAD_INITIALIZER (); + +static void +indirect_action_flow_conf_create (const struct buffer *in) +{ +int len, ret; +uint32_t i; +struct indlst_conf *indlst_conf =NULL ; +size_t base =RTE_ALIGN (sizeof (*indlst_conf),8 ); +struct rte_flow_action *src = in->args.vc.actions; + +if (!in->args.vc.actions_n) + goto end; + len =rte_flow_conv (RTE_FLOW_CONV_OP_ACTIONS ,NULL ,0 , src,NULL ); +if (len <=0 ) + goto end; + len =RTE_ALIGN (len,16 ); + + indlst_conf =calloc (1 , base + len + + in->args.vc.actions_n *sizeof (uintptr_t )); +if (!indlst_conf) + goto end; + indlst_conf->id = in->args.vc.attr.group; + indlst_conf->conf_num = in->args.vc.actions_n -1 ; + indlst_conf->actions =RTE_PTR_ADD (indlst_conf, base); + ret =rte_flow_conv (RTE_FLOW_CONV_OP_ACTIONS , indlst_conf->actions, + len, src,NULL ); +if (ret <=0 ) { +free (indlst_conf); + indlst_conf =NULL ; + goto end; + } + indlst_conf->conf =RTE_PTR_ADD (indlst_conf, base + len); +for (i =0 ; i < indlst_conf->conf_num; i++) + indlst_conf->conf[i] = indlst_conf->actions[i].conf; +SLIST_INSERT_HEAD (&indlst_conf_head, indlst_conf, next); +end: +if (indlst_conf) +printf ("created indirect action list configuration %u\n" , + in->args.vc.attr.group); +else +printf ("cannot create indirect action list configuration %u\n" , + in->args.vc.attr.group); +} + +static const struct indlst_conf * +indirect_action_list_conf_get (uint32_t conf_id) +{ +const struct indlst_conf *conf; + + SLIST_FOREACH(conf, &indlst_conf_head, next) { +if (conf->id == conf_id) +return conf; + } +return NULL ; +} +/** Dispatch parsed buffer to function calls. */ static void cmd_flow_parsed (const struct buffer *in)
@@ -11532,6 +11730,7 @@ cmd_flow_parsed(const struct buffer *in) in->args.aged.destroy);break ;case QUEUE_INDIRECT_ACTION_CREATE : +case QUEUE_INDIRECT_ACTION_LIST_CREATE : port_queue_action_handle_create( in->port, in->queue, in->postpone, in->args.vc.attr.group,
@@ -11567,8 +11766,10 @@ cmd_flow_parsed(const struct buffer *in) in->args.vc.actions);break ;case INDIRECT_ACTION_CREATE : +case INDIRECT_ACTION_LIST_CREATE : port_action_handle_create( in->port, in->args.vc.attr.group, + in->command == INDIRECT_ACTION_LIST_CREATE, &((const struct rte_flow_indir_action_conf) { .ingress = in->args.vc.attr.ingress, .egress = in->args.vc.attr.egress,
@@ -11576,6 +11777,9 @@ cmd_flow_parsed(const struct buffer *in) }), in->args.vc.actions);break ; +case INDIRECT_ACTION_FLOW_CONF_CREATE : +indirect_action_flow_conf_create (in); +break ;case INDIRECT_ACTION_DESTROY : port_action_handle_destroy(in->port, in->args.ia_destroy.action_id_n,
@@ -11653,6 +11857,7 @@ cmd_flow_parsed(const struct buffer *in)default :break ; } +fflush (stdout); }/** Token generator and output processing callback (cmdline API). */
app/test-pmd/config.c +124 -39
229 lines not on this page · raw message
app/test-pmd/testpmd.h +7 -2
@@ -228,7 +228,12 @@ struct port_indirect_action {struct port_indirect_action *next;/**< Next flow in list. */ uint32_t id;/**< Indirect action ID. */ enum rte_flow_action_type type;/**< Action type. */ -struct rte_flow_action_handle *handle;/**< Indirect action handle. */ +union { +struct rte_flow_action_handle *handle; +/**< Indirect action handle. */ +struct rte_flow_action_list_handle *list_handle; +/**< Indirect action list handle*/ + };enum age_action_context_type age_type;/**< Age action context type. */ };
@@ -921,7 +926,7 @@ void update_fwd_ports(portid_t new_pid);void set_fwd_eth_peer (portid_t port_id,char *peer_addr);void port_mtu_set (portid_t port_id,uint16_t mtu); -int port_action_handle_create (portid_t port_id,uint32_t id, +int port_action_handle_create (portid_t port_id,uint32_t id,bool indirect_list,const struct rte_flow_indir_action_conf *conf,const struct rte_flow_action *action); int port_action_handle_destroy(portid_t port_id,
doc/guides/nics/features/default.ini +1 -0
@@ -158,6 +158,7 @@ drop = flag = inc_tcp_ack = inc_tcp_seq = +indirect_list = jump = mac_swap = mark =
doc/guides/prog_guide/rte_flow.rst +119 -0
125 lines not on this page · raw message
doc/guides/rel_notes/release_23_07.rst +2 -0
@@ -55,6 +55,8 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= + * **Added INDIRECT_LIST flow action.** + Removed Items -------------
lib/ethdev/ethdev_trace.h +88 -0
94 lines not on this page · raw message
lib/ethdev/ethdev_trace_points.c +18 -0
@@ -750,3 +750,21 @@ RTE_TRACE_POINT_REGISTER(rte_tm_trace_wred_profile_add,RTE_TRACE_POINT_REGISTER (rte_tm_trace_wred_profile_delete, lib.ethdev.tm.wred_profile_delete) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_action_list_handle_create, + lib.ethdev.flow.action_list_handle_create) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_action_list_handle_destroy, + lib.ethdev.flow.action_list_handle_destroy) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_action_list_handle_query_update, + lib.ethdev.flow.action_list_handle_query_update) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_async_action_list_handle_create, + lib.ethdev.flow.async_action_list_handle_create) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_async_action_list_handle_destroy, + lib.ethdev.flow.async_action_list_handle_destroy) + +RTE_TRACE_POINT_REGISTER (rte_flow_trace_async_action_list_handle_query_update, + lib.ethdev.flow.async_action_list_handle_query_update)
lib/ethdev/rte_flow.c +171 -0
180 lines not on this page · raw message
lib/ethdev/rte_flow.h +276 -0
288 lines not on this page · raw message
lib/ethdev/rte_flow_driver.h +41 -0
53 lines not on this page · raw message
lib/ethdev/version.map +8 -0
@@ -299,6 +299,14 @@ EXPERIMENTAL { rte_flow_action_handle_query_update; rte_flow_async_action_handle_query_update; rte_flow_async_create_by_index; + + # added in 23.07 + rte_flow_action_list_handle_create; + rte_flow_action_list_handle_destroy; + rte_flow_action_list_handle_query_update; + rte_flow_async_action_list_handle_create; + rte_flow_async_action_list_handle_destroy; + rte_flow_async_action_list_handle_query_update; }; INTERNAL {
Signature · 1 line
2.34.1
Hi gregory,
Quoted 99 lines
-----Original Message-----
From: Gregory Etelson <[email protected]>
Sent: Sunday, May 28, 2023 6:44 PMIndirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.flow 1:
/ indirect handle H conf C1 /| | | | | | flow 2: | | / indirect handle H conf C2 / | | | | | | | | | | | | ========================================================= ^ | | | | | | V | V | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ | flow mutable flow mutable | context 1 context 2 | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ indirect | | | action | | | context | V V | ----------------------------------------------------- | action mutable context | -----------------------------------------------------v action immutable context
=========================================================Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• IndirectMETER_MARKpolicy is immutable action member and profile is action mutable action member.
• IndirectMETER_MARKflow action definesinit_coloras flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.If indirect list handle was created from a list of actions A1 / A2 ... An / END
indirect list flow action can update Ai flow mutable context in the action configuration parameter.
Indirect list action configuration is and array [C1, C2, .., Cn] where Ci corresponds to Ai in the action handle source. Ci configuration element points Ai flow mutable update, or it's NULL if Ai has no flow mutable update.
Indirect list action configuration can be NULL if the action has no flow mutable updates.Template API:
Action template format:
template ..
indirect_listhandle Htmpl conf Ctmpl ..
mask ..indirect_listhandle Hmask conf Cmask ..1 If Htmpl was masked (Hmask != 0), it will be fixed in that template.
Otherwise, indirect action value is set in a flow rule.2 If Htmpl and Ctmpl[i] were masked (Hmask !=0 and Cmask[i] != 0),
Htmpl's Ai action flow mutable context fill be updated to Ctmpl[i] values and will be fixed in that template.Flow rule format:
actions ..
indirect_listhandle Hflow conf Cflow ..
Quoted 8 lines
3 If Htmpl was not masked in actions template, Hflow references an
action of the same type as Htmpl.4 Cflow[i] updates handle's Ai flow mutable configuration if
the Ci was not masked in action template.Signed-off-by Gregory Etelson <[email protected]>---
Best,
Ori
Ferruh Yigit
AppliedQuoted 104 lines · Ori Kam
Hi gregory,
Quoted 102 lines
-----Original Message-----
From: Gregory Etelson <[email protected]>
Sent: Sunday, May 28, 2023 6:44 PMIndirect API creates a shared flow action with unique action handle. Flow rules can access the shared flow action and resources related to that action through the indirect action handle.
In addition, the API allows to update existing shared flow action configuration. After the update completes, new action configuration is available to all flows that reference that shared action.Indirect actions list expands the indirect action API:
• Indirect action list creates a handle for one or several flow actions, while legacy indirect action handle references single action only.
Input flow actions arranged in END terminated list.
• Flow rule can provide rule specific configuration parameters to existing shared handle.
Updates of flow rule specific configuration will not change the base action configuration.
Base action configuration was set during the action creation.Indirect action list handle defines 2 types of resources:
• Mutable handle resource can be changed during handle lifespan.
• Immutable handle resource value is set during handle creation and cannot be changed.There are 2 types of mutable indirect handle contexts:
• Action mutable context is always shared between all flows that referenced indirect actions list handle. Action mutable context can be changed by explicit invocation of indirect handle update function.
• Flow mutable context is private to a flow.
Flow mutable context can be updated by indirect list handle flow rule configuration.flow 1:
/ indirect handle H conf C1 /| | | | | | flow 2: | | / indirect handle H conf C2 / | | | | | | | | | | | | ========================================================= ^ | | | | | | V | V | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ | flow mutable flow mutable | context 1 context 2 | ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ indirect | | | action | | | context | V V | ----------------------------------------------------- | action mutable context | -----------------------------------------------------v action immutable context
=========================================================Indirect action types - immutable, action / flow mutable, are mutually exclusive and depend on the action definition.
For example:
• IndirectMETER_MARKpolicy is immutable action member and profile is action mutable action member.
• IndirectMETER_MARKflow action definesinit_coloras flow mutable member.
• Indirect QUOTA flow action does not define flow mutable members.If indirect list handle was created from a list of actions A1 / A2 ... An / END
indirect list flow action can update Ai flow mutable context in the action configuration parameter.
Indirect list action configuration is and array [C1, C2, .., Cn] where Ci corresponds to Ai in the action handle source. Ci configuration element points Ai flow mutable update, or it's NULL if Ai has no flow mutable update.
Indirect list action configuration can be NULL if the action has no flow mutable updates.Template API:
Action template format:
template ..
indirect_listhandle Htmpl conf Ctmpl ..
mask ..indirect_listhandle Hmask conf Cmask ..1 If Htmpl was masked (Hmask != 0), it will be fixed in that template.
Otherwise, indirect action value is set in a flow rule.2 If Htmpl and Ctmpl[i] were masked (Hmask !=0 and Cmask[i] != 0),
Htmpl's Ai action flow mutable context fill be updated to Ctmpl[i] values and will be fixed in that template.Flow rule format:
actions ..
indirect_listhandle Hflow conf Cflow ..3 If Htmpl was not masked in actions template, Hflow references an
action of the same type as Htmpl.
Quoted 8 lines
Quoted 5 lines
4 Cflow[i] updates handle's Ai flow mutable configuration if
the Ci was not masked in action template.Signed-off-by Gregory Etelson <[email protected]>---
Acked-by Ori Kam <[email protected]>
Applied to dpdk-next-net/main, thanks.
(checkpatch warnings fixed while merging.)