ethdev: add GTP extension header to flow API
[dpdk.git] / app / test-pmd / cmdline_flow.c
index a15a756..cdaabcc 100644 (file)
@@ -18,6 +18,7 @@
 #include <rte_ethdev.h>
 #include <rte_byteorder.h>
 #include <cmdline_parse.h>
+#include <cmdline_parse_etheraddr.h>
 #include <rte_flow.h>
 
 #include "testpmd.h"
@@ -152,6 +153,8 @@ enum index {
        ITEM_NVGRE_TNI,
        ITEM_MPLS,
        ITEM_MPLS_LABEL,
+       ITEM_MPLS_TC,
+       ITEM_MPLS_S,
        ITEM_GRE,
        ITEM_GRE_PROTO,
        ITEM_GRE_C_RSVD0_VER,
@@ -193,6 +196,9 @@ enum index {
        ITEM_META_DATA,
        ITEM_GRE_KEY,
        ITEM_GRE_KEY_VALUE,
+       ITEM_GTP_PSC,
+       ITEM_GTP_PSC_QFI,
+       ITEM_GTP_PSC_PDU_T,
 
        /* Validate/create actions. */
        ACTIONS,
@@ -660,6 +666,7 @@ static const enum index next_item[] = {
        ITEM_ICMP6_ND_OPT_TLA_ETH,
        ITEM_META,
        ITEM_GRE_KEY,
+       ITEM_GTP_PSC,
        END_SET,
        ZERO,
 };
@@ -800,6 +807,8 @@ static const enum index item_nvgre[] = {
 
 static const enum index item_mpls[] = {
        ITEM_MPLS_LABEL,
+       ITEM_MPLS_TC,
+       ITEM_MPLS_S,
        ITEM_NEXT,
        ZERO,
 };
@@ -897,6 +906,13 @@ static const enum index item_meta[] = {
        ZERO,
 };
 
+static const enum index item_gtp_psc[] = {
+       ITEM_GTP_PSC_QFI,
+       ITEM_GTP_PSC_PDU_T,
+       ITEM_NEXT,
+       ZERO,
+};
+
 static const enum index next_action[] = {
        ACTION_END,
        ACTION_VOID,
@@ -1997,6 +2013,22 @@ static const struct token token_list[] = {
                                                  label_tc_s,
                                                  "\xff\xff\xf0")),
        },
+       [ITEM_MPLS_TC] = {
+               .name = "tc",
+               .help = "MPLS Traffic Class",
+               .next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
+               .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
+                                                 label_tc_s,
+                                                 "\x00\x00\x0e")),
+       },
+       [ITEM_MPLS_S] = {
+               .name = "s",
+               .help = "MPLS Bottom-of-Stack",
+               .next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
+               .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
+                                                 label_tc_s,
+                                                 "\x00\x00\x01")),
+       },
        [ITEM_GRE] = {
                .name = "gre",
                .help = "match GRE header",
@@ -2310,6 +2342,28 @@ static const struct token token_list[] = {
                .next = NEXT(item_gre_key, NEXT_ENTRY(UNSIGNED), item_param),
                .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
        },
+       [ITEM_GTP_PSC] = {
+               .name = "gtp_psc",
+               .help = "match GTP extension header with type 0x85",
+               .priv = PRIV_ITEM(GTP_PSC,
+                               sizeof(struct rte_flow_item_gtp_psc)),
+               .next = NEXT(item_gtp_psc),
+               .call = parse_vc,
+       },
+       [ITEM_GTP_PSC_QFI] = {
+               .name = "qfi",
+               .help = "QoS flow identifier",
+               .next = NEXT(item_gtp_psc, NEXT_ENTRY(UNSIGNED), item_param),
+               .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp_psc,
+                                       qfi)),
+       },
+       [ITEM_GTP_PSC_PDU_T] = {
+               .name = "pdu_t",
+               .help = "PDU type",
+               .next = NEXT(item_gtp_psc, NEXT_ENTRY(UNSIGNED), item_param),
+               .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp_psc,
+                                       pdu_type)),
+       },
 
        /* Validate/create actions. */
        [ACTIONS] = {
@@ -3528,8 +3582,12 @@ parse_vc_action_rss(struct context *ctx, const struct token *token,
        if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
            ctx->port != (portid_t)RTE_PORT_ALL) {
                struct rte_eth_dev_info info;
+               int ret2;
+
+               ret2 = rte_eth_dev_info_get(ctx->port, &info);
+               if (ret2 != 0)
+                       return ret2;
 
-               rte_eth_dev_info_get(ctx->port, &info);
                action_rss_data->conf.key_len =
                        RTE_MIN(sizeof(action_rss_data->key),
                                info.hash_key_size);
@@ -4958,8 +5016,8 @@ parse_mac_addr(struct context *ctx, const struct token *token,
        /* Only network endian is supported. */
        if (!arg->hton)
                goto error;
-       ret = rte_ether_unformat_addr(str, &tmp);
-       if (ret < 0)
+       ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
+       if (ret < 0 || (unsigned int)ret != len)
                goto error;
        if (!ctx->object)
                return len;
@@ -5663,6 +5721,7 @@ static const void *
 flow_item_default_mask(const struct rte_flow_item *item)
 {
        const void *mask = NULL;
+       static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
 
        switch (item->type) {
        case RTE_FLOW_ITEM_TYPE_ANY:
@@ -5719,6 +5778,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
        case RTE_FLOW_ITEM_TYPE_GRE:
                mask = &rte_flow_item_gre_mask;
                break;
+       case RTE_FLOW_ITEM_TYPE_GRE_KEY:
+               mask = &gre_key_default_mask;
+               break;
        case RTE_FLOW_ITEM_TYPE_META:
                mask = &rte_flow_item_meta_mask;
                break;
@@ -5731,6 +5793,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
        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;
        default:
                break;
        }
@@ -5804,6 +5869,9 @@ cmd_set_raw_parsed(const struct buffer *in)
                        size = sizeof(struct rte_flow_item_gre);
                        proto = 0x2F;
                        break;
+               case RTE_FLOW_ITEM_TYPE_GRE_KEY:
+                       size = sizeof(rte_be32_t);
+                       break;
                case RTE_FLOW_ITEM_TYPE_MPLS:
                        size = sizeof(struct rte_flow_item_mpls);
                        break;