X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fcmdline_flow.c;h=6263d307edb346a83b00e627ca3ed5c7fcb346c1;hb=fae4b8c47c25286e5d87cde55ff16d1bed298e15;hp=33ba1d7bb075bed32671a2f868584e539774f375;hpb=65388f4c4cda8ec26a0e04371f51b4b81ffaf4d9;p=dpdk.git diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 33ba1d7bb0..6263d307ed 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -41,6 +41,7 @@ enum index { BOOLEAN, STRING, HEX, + FILE_PATH, MAC_ADDR, IPV4_ADDR, IPV6_ADDR, @@ -63,8 +64,10 @@ enum index { CREATE, DESTROY, FLUSH, + DUMP, QUERY, LIST, + AGED, ISOLATE, /* Destroy arguments. */ @@ -76,6 +79,9 @@ enum index { /* List arguments. */ LIST_GROUP, + /* Destroy aged flow arguments. */ + AGED_DESTROY, + /* Validate/create arguments. */ GROUP, PRIORITY, @@ -168,6 +174,8 @@ enum index { ITEM_FUZZY, ITEM_FUZZY_THRESH, ITEM_GTP, + ITEM_GTP_FLAGS, + ITEM_GTP_MSG_TYPE, ITEM_GTP_TEID, ITEM_GTPC, ITEM_GTPU, @@ -215,6 +223,22 @@ enum index { ITEM_TAG_INDEX, ITEM_L2TPV3OIP, ITEM_L2TPV3OIP_SESSION_ID, + ITEM_ESP, + ITEM_ESP_SPI, + ITEM_AH, + ITEM_AH_SPI, + ITEM_PFCP, + ITEM_PFCP_S_FIELD, + ITEM_PFCP_SEID, + ITEM_ECPRI, + ITEM_ECPRI_COMMON, + ITEM_ECPRI_COMMON_TYPE, + ITEM_ECPRI_COMMON_TYPE_IQ_DATA, + ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, + ITEM_ECPRI_COMMON_TYPE_DLY_MSR, + ITEM_ECPRI_MSG_IQ_DATA_PCID, + ITEM_ECPRI_MSG_RTC_CTRL_RTCID, + ITEM_ECPRI_MSG_DLY_MSR_MSRID, /* Validate/create actions. */ ACTIONS, @@ -332,6 +356,8 @@ enum index { ACTION_SET_IPV4_DSCP_VALUE, ACTION_SET_IPV6_DSCP, ACTION_SET_IPV6_DSCP_VALUE, + ACTION_AGE, + ACTION_AGE_TIMEOUT, }; /** Maximum size for pattern in struct rte_flow_item_raw. */ @@ -637,6 +663,9 @@ struct buffer { uint32_t *rule; uint32_t rule_n; } destroy; /**< Destroy arguments. */ + struct { + char file[128]; + } dump; /**< Dump arguments. */ struct { uint32_t rule; struct rte_flow_action action; @@ -648,6 +677,9 @@ struct buffer { struct { int set; } isolate; /**< Isolated mode arguments. */ + struct { + int destroy; + } aged; /**< Aged arguments. */ } args; /**< Command arguments. */ }; @@ -691,12 +723,24 @@ static const enum index next_destroy_attr[] = { ZERO, }; +static const enum index next_dump_attr[] = { + FILE_PATH, + END, + ZERO, +}; + static const enum index next_list_attr[] = { LIST_GROUP, END, ZERO, }; +static const enum index next_aged_attr[] = { + AGED_DESTROY, + END, + ZERO, +}; + static const enum index item_param[] = { ITEM_PARAM_IS, ITEM_PARAM_SPEC, @@ -753,6 +797,10 @@ static const enum index next_item[] = { ITEM_HIGIG2, ITEM_TAG, ITEM_L2TPV3OIP, + ITEM_ESP, + ITEM_AH, + ITEM_PFCP, + ITEM_ECPRI, END_SET, ZERO, }; @@ -916,6 +964,8 @@ static const enum index item_gre_key[] = { }; static const enum index item_gtp[] = { + ITEM_GTP_FLAGS, + ITEM_GTP_MSG_TYPE, ITEM_GTP_TEID, ITEM_NEXT, ZERO, @@ -1012,7 +1062,6 @@ static const enum index item_pppoes[] = { }; static const enum index item_pppoe_proto_id[] = { - ITEM_PPPOE_PROTO_ID, ITEM_NEXT, ZERO, }; @@ -1024,6 +1073,25 @@ static const enum index item_higig2[] = { ZERO, }; +static const enum index item_esp[] = { + ITEM_ESP_SPI, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_ah[] = { + ITEM_AH_SPI, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_pfcp[] = { + ITEM_PFCP_S_FIELD, + ITEM_PFCP_SEID, + ITEM_NEXT, + ZERO, +}; + static const enum index next_set_raw[] = { SET_RAW_INDEX, ITEM_ETH, @@ -1043,6 +1111,24 @@ static const enum index item_l2tpv3oip[] = { ZERO, }; +static const enum index item_ecpri[] = { + ITEM_ECPRI_COMMON, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_ecpri_common[] = { + ITEM_ECPRI_COMMON_TYPE, + ZERO, +}; + +static const enum index item_ecpri_common_type[] = { + ITEM_ECPRI_COMMON_TYPE_IQ_DATA, + ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, + ITEM_ECPRI_COMMON_TYPE_DLY_MSR, + ZERO, +}; + static const enum index next_action[] = { ACTION_END, ACTION_VOID, @@ -1102,6 +1188,7 @@ static const enum index next_action[] = { ACTION_SET_META, ACTION_SET_IPV4_DSCP, ACTION_SET_IPV6_DSCP, + ACTION_AGE, ZERO, }; @@ -1327,6 +1414,13 @@ static const enum index action_set_ipv6_dscp[] = { ZERO, }; +static const enum index action_age[] = { + ACTION_AGE, + ACTION_AGE_TIMEOUT, + ACTION_NEXT, + ZERO, +}; + static int parse_set_raw_encap_decap(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1343,6 +1437,9 @@ static int parse_vc_spec(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); static int parse_vc_conf(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_vc_item_ecpri_type(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_vc_action_rss(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1401,6 +1498,9 @@ static int parse_destroy(struct context *, const struct token *, static int parse_flush(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_dump(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_query(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1410,6 +1510,9 @@ static int parse_action(struct context *, const struct token *, static int parse_list(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_aged(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_isolate(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1428,6 +1531,9 @@ static int parse_string(struct context *, const struct token *, static int parse_hex(struct context *ctx, const struct token *token, const char *str, unsigned int len, void *buf, unsigned int size); +static int parse_string0(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_mac_addr(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1521,6 +1627,12 @@ static const struct token token_list[] = { .type = "HEX", .help = "fixed string", .call = parse_hex, + }, + [FILE_PATH] = { + .name = "{file path}", + .type = "STRING", + .help = "file path", + .call = parse_string0, .comp = comp_none, }, [MAC_ADDR] = { @@ -1582,7 +1694,9 @@ static const struct token token_list[] = { CREATE, DESTROY, FLUSH, + DUMP, LIST, + AGED, QUERY, ISOLATE)), .call = parse_init, @@ -1616,6 +1730,14 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY(struct buffer, port)), .call = parse_flush, }, + [DUMP] = { + .name = "dump", + .help = "dump all flow rules to file", + .next = NEXT(next_dump_attr, NEXT_ENTRY(PORT_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), + ARGS_ENTRY(struct buffer, port)), + .call = parse_dump, + }, [QUERY] = { .name = "query", .help = "query an existing flow rule", @@ -1634,6 +1756,13 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY(struct buffer, port)), .call = parse_list, }, + [AGED] = { + .name = "aged", + .help = "list and destroy aged flows", + .next = NEXT(next_aged_attr, NEXT_ENTRY(PORT_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, port)), + .call = parse_aged, + }, [ISOLATE] = { .name = "isolate", .help = "restrict ingress traffic to the defined flow rules", @@ -1667,6 +1796,12 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), .call = parse_list, }, + [AGED_DESTROY] = { + .name = "destroy", + .help = "specify aged flows need be destroyed", + .call = parse_aged, + .comp = comp_none, + }, /* Validate/create attributes. */ [GROUP] = { .name = "group", @@ -2284,6 +2419,19 @@ static const struct token token_list[] = { .next = NEXT(item_gtp), .call = parse_vc, }, + [ITEM_GTP_FLAGS] = { + .name = "v_pt_rsv_flags", + .help = "GTP flags", + .next = NEXT(item_gtp, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, + v_pt_rsv_flags)), + }, + [ITEM_GTP_MSG_TYPE] = { + .name = "msg_type", + .help = "GTP message type", + .next = NEXT(item_gtp, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, msg_type)), + }, [ITEM_GTP_TEID] = { .name = "teid", .help = "tunnel endpoint identifier", @@ -2571,11 +2719,14 @@ static const struct token token_list[] = { session_id)), }, [ITEM_PPPOE_PROTO_ID] = { - .name = "proto_id", + .name = "pppoe_proto_id", .help = "match PPPoE session protocol identifier", .priv = PRIV_ITEM(PPPOE_PROTO_ID, sizeof(struct rte_flow_item_pppoe_proto_id)), - .next = NEXT(item_pppoe_proto_id), + .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON + (struct rte_flow_item_pppoe_proto_id, proto_id)), .call = parse_vc, }, [ITEM_HIGIG2] = { @@ -2635,7 +2786,113 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, session_id)), }, - + [ITEM_ESP] = { + .name = "esp", + .help = "match ESP header", + .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), + .next = NEXT(item_esp), + .call = parse_vc, + }, + [ITEM_ESP_SPI] = { + .name = "spi", + .help = "security policy index", + .next = NEXT(item_esp, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, + hdr.spi)), + }, + [ITEM_AH] = { + .name = "ah", + .help = "match AH header", + .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), + .next = NEXT(item_ah), + .call = parse_vc, + }, + [ITEM_AH_SPI] = { + .name = "spi", + .help = "security parameters index", + .next = NEXT(item_ah, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), + }, + [ITEM_PFCP] = { + .name = "pfcp", + .help = "match pfcp header", + .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), + .next = NEXT(item_pfcp), + .call = parse_vc, + }, + [ITEM_PFCP_S_FIELD] = { + .name = "s_field", + .help = "S field", + .next = NEXT(item_pfcp, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, + s_field)), + }, + [ITEM_PFCP_SEID] = { + .name = "seid", + .help = "session endpoint identifier", + .next = NEXT(item_pfcp, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), + }, + [ITEM_ECPRI] = { + .name = "ecpri", + .help = "match eCPRI header", + .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), + .next = NEXT(item_ecpri), + .call = parse_vc, + }, + [ITEM_ECPRI_COMMON] = { + .name = "common", + .help = "eCPRI common header", + .next = NEXT(item_ecpri_common), + }, + [ITEM_ECPRI_COMMON_TYPE] = { + .name = "type", + .help = "type of common header", + .next = NEXT(item_ecpri_common_type), + .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), + }, + [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { + .name = "iq_data", + .help = "Type #0: IQ Data", + .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, + ITEM_NEXT)), + .call = parse_vc_item_ecpri_type, + }, + [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { + .name = "pc_id", + .help = "Physical Channel ID", + .next = NEXT(item_ecpri, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, + hdr.type0.pc_id)), + }, + [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { + .name = "rtc_ctrl", + .help = "Type #2: Real-Time Control Data", + .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, + ITEM_NEXT)), + .call = parse_vc_item_ecpri_type, + }, + [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { + .name = "rtc_id", + .help = "Real-Time Control Data ID", + .next = NEXT(item_ecpri, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, + hdr.type2.rtc_id)), + }, + [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { + .name = "delay_measure", + .help = "Type #5: One-Way Delay Measurement", + .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, + ITEM_NEXT)), + .call = parse_vc_item_ecpri_type, + }, + [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { + .name = "msr_id", + .help = "Measurement ID", + .next = NEXT(item_ecpri, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, + hdr.type5.msr_id)), + }, /* Validate/create actions. */ [ACTIONS] = { .name = "actions", @@ -3568,6 +3825,22 @@ static const struct token token_list[] = { (struct rte_flow_action_set_dscp, dscp)), .call = parse_vc_conf, }, + [ACTION_AGE] = { + .name = "age", + .help = "set a specific metadata header", + .next = NEXT(action_age), + .priv = PRIV_ACTION(AGE, + sizeof(struct rte_flow_action_age)), + .call = parse_vc, + }, + [ACTION_AGE_TIMEOUT] = { + .name = "timeout", + .help = "flow age timeout value", + .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, + timeout, 24)), + .next = NEXT(action_age, NEXT_ENTRY(UNSIGNED)), + .call = parse_vc_conf, + }, }; /** Remove and return last entry from argument stack. */ @@ -3942,6 +4215,59 @@ parse_vc_conf(struct context *ctx, const struct token *token, return len; } +/** Parse eCPRI common header type field. */ +static int +parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct rte_flow_item_ecpri *ecpri; + struct rte_flow_item_ecpri *ecpri_mask; + struct rte_flow_item *item; + uint32_t data_size; + uint8_t msg_type; + struct buffer *out = buf; + const struct arg *arg; + + (void)size; + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + switch (ctx->curr) { + case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: + msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; + break; + case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: + msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; + break; + case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: + msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; + break; + default: + return -1; + } + if (!ctx->object) + return len; + arg = pop_args(ctx); + if (!arg) + return -1; + ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; + ecpri->hdr.common.type = msg_type; + data_size = ctx->objdata / 3; /* spec, last, mask */ + ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + + (data_size * 2)); + ecpri_mask->hdr.common.type = 0xFF; + if (arg->hton) { + ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); + ecpri_mask->hdr.common.u32 = + rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); + } + item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; + item->spec = ecpri; + item->mask = ecpri_mask; + return len; +} + /** Parse RSS action. */ static int parse_vc_action_rss(struct context *ctx, const struct token *token, @@ -4513,7 +4839,9 @@ parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, struct rte_flow_item_gre gre = { .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), }; - struct rte_flow_item_mpls mpls; + struct rte_flow_item_mpls mpls = { + .ttl = 0, + }; uint8_t *header; int ret; @@ -5087,6 +5415,33 @@ parse_flush(struct context *ctx, const struct token *token, return len; } +/** Parse tokens for dump command. */ +static int +parse_dump(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + /* Nothing else to do if there is no buffer. */ + if (!out) + return len; + if (!out->command) { + if (ctx->curr != DUMP) + return -1; + if (sizeof(*out) > size) + return -1; + out->command = ctx->curr; + ctx->objdata = 0; + ctx->object = out; + ctx->objmask = NULL; + } + return len; +} + /** Parse tokens for query command. */ static int parse_query(struct context *ctx, const struct token *token, @@ -5186,6 +5541,35 @@ parse_list(struct context *ctx, const struct token *token, return len; } +/** Parse tokens for list all aged flows command. */ +static int +parse_aged(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + /* Nothing else to do if there is no buffer. */ + if (!out) + return len; + if (!out->command) { + if (ctx->curr != AGED) + return -1; + if (sizeof(*out) > size) + return -1; + out->command = ctx->curr; + ctx->objdata = 0; + ctx->object = out; + ctx->objmask = NULL; + } + if (ctx->curr == AGED_DESTROY) + out->args.aged.destroy = 1; + return len; +} + /** Parse tokens for isolate command. */ static int parse_isolate(struct context *ctx, const struct token *token, @@ -5484,6 +5868,35 @@ error: } +/** + * Parse a zero-ended string. + */ +static int +parse_string0(struct context *ctx, const struct token *token __rte_unused, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + const struct arg *arg_data = pop_args(ctx); + + /* Arguments are expected. */ + if (!arg_data) + return -1; + size = arg_data->size; + /* Bit-mask fill is not supported. */ + if (arg_data->mask || size < len + 1) + goto error; + if (!ctx->object) + return len; + buf = (uint8_t *)ctx->object + arg_data->offset; + strncpy(buf, str, len); + if (ctx->objmask) + memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); + return len; +error: + push_args(ctx, arg_data); + return -1; +} + /** * Parse a MAC address. * @@ -6143,6 +6556,9 @@ cmd_flow_parsed(const struct buffer *in) case FLUSH: port_flow_flush(in->port); break; + case DUMP: + port_flow_dump(in->port, in->args.dump.file); + break; case QUERY: port_flow_query(in->port, in->args.query.rule, &in->args.query.action); @@ -6154,6 +6570,9 @@ cmd_flow_parsed(const struct buffer *in) case ISOLATE: port_flow_isolate(in->port, in->args.isolate.set); break; + case AGED: + port_flow_aged(in->port, in->args.aged.destroy); + break; default: break; } @@ -6305,9 +6724,6 @@ flow_item_default_mask(const struct rte_flow_item *item) case RTE_FLOW_ITEM_TYPE_GTP: mask = &rte_flow_item_gtp_mask; break; - case RTE_FLOW_ITEM_TYPE_ESP: - mask = &rte_flow_item_esp_mask; - break; case RTE_FLOW_ITEM_TYPE_GTP_PSC: mask = &rte_flow_item_gtp_psc_mask; break; @@ -6320,6 +6736,15 @@ flow_item_default_mask(const struct rte_flow_item *item) case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: mask = &rte_flow_item_l2tpv3oip_mask; break; + case RTE_FLOW_ITEM_TYPE_ESP: + mask = &rte_flow_item_esp_mask; + break; + case RTE_FLOW_ITEM_TYPE_AH: + mask = &rte_flow_item_ah_mask; + break; + case RTE_FLOW_ITEM_TYPE_PFCP: + mask = &rte_flow_item_pfcp_mask; + break; default: break; } @@ -6413,6 +6838,20 @@ cmd_set_raw_parsed(const struct buffer *in) size = sizeof(struct rte_flow_item_l2tpv3oip); proto = 0x73; break; + case RTE_FLOW_ITEM_TYPE_ESP: + size = sizeof(struct rte_flow_item_esp); + proto = 0x32; + break; + case RTE_FLOW_ITEM_TYPE_AH: + size = sizeof(struct rte_flow_item_ah); + proto = 0x33; + break; + case RTE_FLOW_ITEM_TYPE_GTP: + size = sizeof(struct rte_flow_item_gtp); + break; + case RTE_FLOW_ITEM_TYPE_PFCP: + size = sizeof(struct rte_flow_item_pfcp); + break; default: printf("Error - Not supported item\n"); *total_size = 0;