From 06822012c0f425bb977a87e1302e3700a34ad49f Mon Sep 17 00:00:00 2001 From: Viacheslav Ovsiienko Date: Wed, 13 Oct 2021 21:45:14 +0300 Subject: [PATCH] app/testpmd: update modify field flow action support The testpmd flow create command updates provided: - modify field action supports the updated actions - pointer type added for action source field - pointer and value source field takes hex string instead of unsigned int in host endianness There are some examples of flow with update modified field action: 1. IPv6 destination address bytes 4-7 assignment: 0000::1111 - > 0000:xxxx:4455:6677::1111 flow create 0 egress group 1 pattern eth / ipv6 dst is 0000::1111 / udp / end actions modify_field op set dst_type ipv6_dst dst_offset 32 src_type value src_value 0011223344556677 width 32 / end 2. Copy second byte of IPv4 destination address to the third byte of source address: 10.0.118.4 -> 192.168.100.1 10.0.168.4 -> 192.168.100.1 flow create 0 egress group 1 pattern eth / ipv4 / udp / end actions modify_field op set dst_type ipv4_src dst_offset 16 src_type ipv4_dst src_offset 8 width 8 / end 3. Assign METADATA value with 11223344 value from the hex string in the linear buffer. Please note, the value definition should follow host-endian, example is given for x86 (little-endian): flow create 0 egress group 1 pattern eth / ipv4 / end actions modify_field op set dst_type meta src_type pointer src_ptr 44332211 width 32 / end 4. Assign destination MAC with EA:11:0B:AD:0B:ED value: flow create 0 egress group 1 pattern eth / end actions modify_field op set dst_type mac_dst src_type value src_value EA110BAD0BED width 48 / end Signed-off-by: Viacheslav Ovsiienko Acked-by: Ori Kam --- app/test-pmd/cmdline_flow.c | 55 +++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index d897d0d1d4..6d9e3d5c42 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -451,6 +451,7 @@ enum index { ACTION_MODIFY_FIELD_SRC_LEVEL, ACTION_MODIFY_FIELD_SRC_OFFSET, ACTION_MODIFY_FIELD_SRC_VALUE, + ACTION_MODIFY_FIELD_SRC_POINTER, ACTION_MODIFY_FIELD_WIDTH, ACTION_CONNTRACK, ACTION_CONNTRACK_UPDATE, @@ -475,6 +476,14 @@ enum index { #define ITEM_RAW_SIZE \ (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) +/** Maximum size for external pattern in struct rte_flow_action_modify_data. */ +#define ACTION_MODIFY_PATTERN_SIZE 32 + +/** Storage size for struct rte_flow_action_modify_field including pattern. */ +#define ACTION_MODIFY_SIZE \ + (sizeof(struct rte_flow_action_modify_field) + \ + ACTION_MODIFY_PATTERN_SIZE) + /** Maximum number of queue indices in struct rte_flow_action_rss. */ #define ACTION_RSS_QUEUE_NUM 128 @@ -1726,6 +1735,7 @@ static const enum index action_modify_field_src[] = { ACTION_MODIFY_FIELD_SRC_LEVEL, ACTION_MODIFY_FIELD_SRC_OFFSET, ACTION_MODIFY_FIELD_SRC_VALUE, + ACTION_MODIFY_FIELD_SRC_POINTER, ACTION_MODIFY_FIELD_WIDTH, ZERO, }; @@ -4511,8 +4521,7 @@ static const struct token token_list[] = { [ACTION_MODIFY_FIELD] = { .name = "modify_field", .help = "modify destination field with data from source field", - .priv = PRIV_ACTION(MODIFY_FIELD, - sizeof(struct rte_flow_action_modify_field)), + .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), .call = parse_vc, }, @@ -4595,11 +4604,26 @@ static const struct token token_list[] = { .name = "src_value", .help = "source immediate value", .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, + NEXT_ENTRY(COMMON_HEX)), + .args = ARGS(ARGS_ENTRY_ARB(0, 0), + ARGS_ENTRY_ARB(0, 0), + ARGS_ENTRY(struct rte_flow_action_modify_field, src.value)), .call = parse_vc_conf, }, + [ACTION_MODIFY_FIELD_SRC_POINTER] = { + .name = "src_ptr", + .help = "pointer to source immediate value", + .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), + NEXT_ENTRY(COMMON_HEX)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, + src.pvalue), + ARGS_ENTRY_ARB(0, 0), + ARGS_ENTRY_ARB + (sizeof(struct rte_flow_action_modify_field), + ACTION_MODIFY_PATTERN_SIZE)), + .call = parse_vc_conf, + }, [ACTION_MODIFY_FIELD_WIDTH] = { .name = "width", .help = "number of bits to copy", @@ -7920,15 +7944,11 @@ static int comp_set_modify_field_op(struct context *ctx, const struct token *token, unsigned int ent, char *buf, unsigned int size) { - uint16_t idx = 0; - RTE_SET_USED(ctx); RTE_SET_USED(token); - for (idx = 0; modify_field_ops[idx]; ++idx) - ; if (!buf) - return idx + 1; - if (ent < idx) + return RTE_DIM(modify_field_ops); + if (ent < RTE_DIM(modify_field_ops) - 1) return strlcpy(buf, modify_field_ops[ent], size); return -1; } @@ -7938,16 +7958,17 @@ static int comp_set_modify_field_id(struct context *ctx, const struct token *token, unsigned int ent, char *buf, unsigned int size) { - uint16_t idx = 0; + const char *name; - RTE_SET_USED(ctx); RTE_SET_USED(token); - for (idx = 0; modify_field_ids[idx]; ++idx) - ; if (!buf) - return idx + 1; - if (ent < idx) - return strlcpy(buf, modify_field_ids[ent], size); + return RTE_DIM(modify_field_ids); + if (ent >= RTE_DIM(modify_field_ids) - 1) + return -1; + name = modify_field_ids[ent]; + if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || + (strcmp(name, "pointer") && strcmp(name, "value"))) + return strlcpy(buf, name, size); return -1; } -- 2.20.1