From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7B8EB4719D; Tue, 6 Jan 2026 16:39:29 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5AF4340B8D; Tue, 6 Jan 2026 16:39:02 +0100 (CET) Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) by mails.dpdk.org (Postfix) with ESMTP id EB97040A79 for ; Tue, 6 Jan 2026 16:38:59 +0100 (CET) Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-4779a4fc95aso14077705e9.1 for ; Tue, 06 Jan 2026 07:38:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dyna-nic.com; s=google; t=1767713939; x=1768318739; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SqT/UezN7Wsm0+OdSYWHq0LrFuCMGDGqfRc2RnkfPCs=; b=Cbzj1mlnQYVKPZCQmLgPXpAXQu1lhnFIAotb2AiJnzB5J8k5KIKAxc5fK726w7WlBe rZbC/UVS0oMr5MKmK2cp0HQ/p4RjwJp9LHKK0ljBRWN+AyUEVCr2o0CuNkin9Fj7WdXW EqNGeHK+N9Q6/7Mn9gf1r8MD0YjwFrK7cqlwIef+9FR90BO6sJxAuZqhffN1V/a5y4Qv hyWsJP5fWF2Gp7enmK3naLvlf+6/hSFVphZpTInNzDgIJP8AG36D5lXOuHB4A8j6ViuM oyQFG5/V6osLiBp264J3By8fjUCKedG3ptHzDGj891gldR4gk1DZuU1zW2s/TVF7LfpZ Jz3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767713939; x=1768318739; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=SqT/UezN7Wsm0+OdSYWHq0LrFuCMGDGqfRc2RnkfPCs=; b=ixtDaehMtV1wVaRvGzxeWkb65nrtug6/FycHRvQNq3US4ekHzYiFoAWzlTTEOjis6r xP4ImogM1/dufNYH0LqvzsOPIWJZKIC59vZRI7EpVo3WBY2lNeN81WE0TeumDHPsTVOH c1TUYWAfJkgxU5Efji+gw1UjPjaLn/Eb8qqfxK/pVbUS/+E2Wvkpi+D4SMs5yudY2j0x Qok/+zMU4q6j28U/VonTUhHwLunAc/jJv9EDXaUd2GG5hygqK3AsX6Ct/fTKA9rIz5wv RmBPcGGvRQ3zGgUhH5/msFm2LgI9FRTmLC66gN9dRH88+ckGu51TlAn3/qkdQiQEaN96 xw0A== X-Gm-Message-State: AOJu0YxhLZTTzBXwYGZdSt+PL08Jtl8ZPRAoG9NaCJ4x568mr3cogmYn F0ab9OmJjfp4q+4+szV2/9muq4aIfy9qLnJptv1aScKO02m1hX6GXvKlhnNAGKaTAFuQfKGufJ+ WuKFQ X-Gm-Gg: AY/fxX4kpu5zXCsIXSIxc2mltaHOjMpV5eyX+CjlOWyfmQJC/p1ydxHSYTIVBhhL8qZ gKU9alYDwg7wrlDT8Q46gpHnBwlSQcGXlZ7A6mVYHQvtyuRLd2fZqvNQkVrntO5UIpkWgN0sIS6 nCujKRTONFOf9KK2ndZTXc5yiW5gR4m5kNkPbVJN2d/yXjxchliOWMDA6Qg2eftMJxe+jv6s1wO eK3PgECN44MPR8Qf6FaluyO50xrdYg+b/vAOyfHbdI9rMOC7NOXfcJTroQ2gTYaimLsq6TG4i4v 8Gh4Qo++OdkdrS07zKnU65+/zjDElqFElndpuAlNhWNQJCRsmfq8y6xZfCuEqvecepWUAab+f/W lQp26LpVstjdsFFO/SIE2oQ+BgaVoPn7S1u7qvpxN0hD5cX4ZSVfmjllgeQJN0Y5ciTRoUUS9un JCbZ4CnZu77Mdq7+FdgwnTOdsirye1kdwqLu2b2vKk+7xOtg== X-Google-Smtp-Source: AGHT+IHvppbPk4xtoYKCwOhYNxc6FkRLaUakRaU8KIeAcM08KHBbmvp9nP8Iv3f2Za6JWiHvsdO0EQ== X-Received: by 2002:a05:600c:1c1a:b0:45d:5c71:769d with SMTP id 5b1f17b1804b1-47d7f417295mr39443425e9.8.1767713937704; Tue, 06 Jan 2026 07:38:57 -0800 (PST) Received: from claret.liberouter.org (rt-tmc-kou.liberouter.org. [195.113.172.126]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47d7fad882asm20975265e9.1.2026.01.06.07.38.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jan 2026 07:38:56 -0800 (PST) From: Lukas Sismis To: dev@dpdk.org Cc: Lukas Sismis Subject: [PATCH v2 2/7] app/testpmd: integrate shared flow parser library Date: Tue, 6 Jan 2026 16:38:32 +0100 Message-ID: <20260106153838.398033-3-sismis@dyna-nic.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260106153838.398033-1-sismis@dyna-nic.com> References: <20260106153838.398033-1-sismis@dyna-nic.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Switch testpmd to use the shared librte_flow_parser library instead of the embedded cmdline_flow.c implementation. Changes: - Remove app/test-pmd/cmdline_flow.c (moved to library) - Add flow_parser.c: Implements flow operation callbacks that bridge the parser library to testpmd's port/flow management functions - Add flow_parser_cli.c: Hosts cmdline integration for 'flow' and 'set raw_encap/decap' commands - Update cmdline.c to register flow commands with the parser - Update meson.build to link against flow_parser library The testpmd flow command syntax remains unchanged. All existing flow commands continue to work identically. Signed-off-by: Lukas Sismis --- app/test-pmd/cmd_flex_item.c | 41 +- app/test-pmd/cmdline.c | 254 +- app/test-pmd/cmdline_flow.c | 14434 ---------------------------- app/test-pmd/config.c | 112 +- app/test-pmd/flow_parser.c | 406 + app/test-pmd/flow_parser.h | 8 + app/test-pmd/flow_parser_cli.c | 149 + app/test-pmd/meson.build | 5 +- app/test-pmd/testpmd.c | 4 + app/test-pmd/testpmd.h | 126 +- lib/flow_parser/rte_flow_parser.c | 328 +- lib/flow_parser/rte_flow_parser.h | 126 +- 12 files changed, 1012 insertions(+), 14981 deletions(-) delete mode 100644 app/test-pmd/cmdline_flow.c create mode 100644 app/test-pmd/flow_parser.c create mode 100644 app/test-pmd/flow_parser.h create mode 100644 app/test-pmd/flow_parser_cli.c diff --git a/app/test-pmd/cmd_flex_item.c b/app/test-pmd/cmd_flex_item.c index af6c087feb..c076ffb05b 100644 --- a/app/test-pmd/cmd_flex_item.c +++ b/app/test-pmd/cmd_flex_item.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "testpmd.h" @@ -126,39 +127,43 @@ enum flex_link_type { static int flex_link_item_parse(const char *src, struct rte_flow_item *item) { -#define FLEX_PARSE_DATA_SIZE 1024 - - int ret; - uint8_t *ptr, data[FLEX_PARSE_DATA_SIZE] = {0,}; + uint8_t *ptr; char flow_rule[256]; - struct rte_flow_attr *attr; - struct rte_flow_item *pattern; - struct rte_flow_action *actions; + uint8_t outbuf[4096]; + struct rte_flow_parser_output *out = (void *)outbuf; + int ret; sprintf(flow_rule, "flow create 0 pattern %s / end actions drop / end", src); - src = flow_rule; - ret = flow_parse(src, (void *)data, sizeof(data), - &attr, &pattern, &actions); + memset(outbuf, 0, sizeof(outbuf)); + ret = rte_flow_parser_parse(flow_rule, out, sizeof(outbuf)); if (ret) return ret; - item->type = pattern->type; - ret = rte_flow_conv(RTE_FLOW_CONV_OP_ITEM_MASK, NULL, 0, item, NULL); - if ((ret > 0) && pattern->spec) { + if (out->command != RTE_FLOW_PARSER_CMD_CREATE) + return -EINVAL; + + if (!out->args.vc.pattern || out->args.vc.pattern_n == 0) + return -EINVAL; + + item->type = out->args.vc.pattern[0].type; + if (out->args.vc.pattern[0].spec) { ptr = (void *)(uintptr_t)item->spec; - memcpy(ptr, pattern->spec, ret); + memcpy(ptr, out->args.vc.pattern[0].spec, + FLEX_MAX_FLOW_PATTERN_LENGTH); } else { item->spec = NULL; } - if ((ret > 0) && pattern->mask) { + if (out->args.vc.pattern[0].mask) { ptr = (void *)(uintptr_t)item->mask; - memcpy(ptr, pattern->mask, ret); + memcpy(ptr, out->args.vc.pattern[0].mask, + FLEX_MAX_FLOW_PATTERN_LENGTH); } else { item->mask = NULL; } - if ((ret > 0) && pattern->last) { + if (out->args.vc.pattern[0].last) { ptr = (void *)(uintptr_t)item->last; - memcpy(ptr, pattern->last, ret); + memcpy(ptr, out->args.vc.pattern[0].last, + FLEX_MAX_FLOW_PATTERN_LENGTH); } else { item->last = NULL; } diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index c33c66f327..c9b3d08456 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef RTE_LIB_GRO #include #endif @@ -65,6 +66,7 @@ #include #endif #include "testpmd.h" +#include "flow_parser.h" #include "cmdline_cman.h" #include "cmdline_mtr.h" #include "cmdline_tm.h" @@ -2357,7 +2359,7 @@ cmd_config_rss_parsed(void *parsed_result, } else if (!strcmp(res->value, "none")) { rss_conf.rss_hf = 0; } else { - rss_conf.rss_hf = str_to_rsstypes(res->value); + rss_conf.rss_hf = rte_eth_rss_type_from_str(res->value); if (rss_conf.rss_hf == 0) { fprintf(stderr, "Unknown parameter\n"); return; @@ -9453,6 +9455,9 @@ do { \ /* Generic flow interface command. */ extern cmdline_parse_inst_t cmd_flow; +extern cmdline_parse_inst_t cmd_set_raw; +extern cmdline_parse_inst_t cmd_show_set_raw; +extern cmdline_parse_inst_t cmd_show_set_raw_all; /* *** ADD/REMOVE A MULTICAST MAC ADDRESS TO/FROM A PORT *** */ struct cmd_mcast_addr_result { @@ -10351,6 +10356,8 @@ static void cmd_set_vxlan_parsed(void *parsed_result, __rte_unused void *data) { struct cmd_set_vxlan_result *res = parsed_result; + struct rte_flow_parser_vxlan_encap_conf *vxlan_conf = + rte_flow_parser_vxlan_encap_conf(); union { uint32_t vxlan_id; uint8_t vni[4]; @@ -10358,38 +10365,41 @@ static void cmd_set_vxlan_parsed(void *parsed_result, .vxlan_id = rte_cpu_to_be_32(res->vni) & RTE_BE32(0x00ffffff), }; - vxlan_encap_conf.select_tos_ttl = 0; + if (vxlan_conf == NULL) + return; + + vxlan_conf->select_tos_ttl = 0; if (strcmp(res->vxlan, "vxlan") == 0) - vxlan_encap_conf.select_vlan = 0; + vxlan_conf->select_vlan = 0; else if (strcmp(res->vxlan, "vxlan-with-vlan") == 0) - vxlan_encap_conf.select_vlan = 1; + vxlan_conf->select_vlan = 1; else if (strcmp(res->vxlan, "vxlan-tos-ttl") == 0) { - vxlan_encap_conf.select_vlan = 0; - vxlan_encap_conf.select_tos_ttl = 1; + vxlan_conf->select_vlan = 0; + vxlan_conf->select_tos_ttl = 1; } if (strcmp(res->ip_version, "ipv4") == 0) - vxlan_encap_conf.select_ipv4 = 1; + vxlan_conf->select_ipv4 = 1; else if (strcmp(res->ip_version, "ipv6") == 0) - vxlan_encap_conf.select_ipv4 = 0; + vxlan_conf->select_ipv4 = 0; else return; - rte_memcpy(vxlan_encap_conf.vni, &id.vni[1], 3); - vxlan_encap_conf.udp_src = rte_cpu_to_be_16(res->udp_src); - vxlan_encap_conf.udp_dst = rte_cpu_to_be_16(res->udp_dst); - vxlan_encap_conf.ip_tos = res->tos; - vxlan_encap_conf.ip_ttl = res->ttl; - if (vxlan_encap_conf.select_ipv4) { - IPV4_ADDR_TO_UINT(res->ip_src, vxlan_encap_conf.ipv4_src); - IPV4_ADDR_TO_UINT(res->ip_dst, vxlan_encap_conf.ipv4_dst); + rte_memcpy(vxlan_conf->vni, &id.vni[1], 3); + vxlan_conf->udp_src = rte_cpu_to_be_16(res->udp_src); + vxlan_conf->udp_dst = rte_cpu_to_be_16(res->udp_dst); + vxlan_conf->ip_tos = res->tos; + vxlan_conf->ip_ttl = res->ttl; + if (vxlan_conf->select_ipv4) { + IPV4_ADDR_TO_UINT(res->ip_src, vxlan_conf->ipv4_src); + IPV4_ADDR_TO_UINT(res->ip_dst, vxlan_conf->ipv4_dst); } else { - IPV6_ADDR_TO_ARRAY(res->ip_src, vxlan_encap_conf.ipv6_src); - IPV6_ADDR_TO_ARRAY(res->ip_dst, vxlan_encap_conf.ipv6_dst); + IPV6_ADDR_TO_ARRAY(res->ip_src, vxlan_conf->ipv6_src); + IPV6_ADDR_TO_ARRAY(res->ip_dst, vxlan_conf->ipv6_dst); } - if (vxlan_encap_conf.select_vlan) - vxlan_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci); - rte_memcpy(vxlan_encap_conf.eth_src, res->eth_src.addr_bytes, + if (vxlan_conf->select_vlan) + vxlan_conf->vlan_tci = rte_cpu_to_be_16(res->tci); + rte_memcpy(vxlan_conf->eth_src, res->eth_src.addr_bytes, RTE_ETHER_ADDR_LEN); - rte_memcpy(vxlan_encap_conf.eth_dst, res->eth_dst.addr_bytes, + rte_memcpy(vxlan_conf->eth_dst, res->eth_dst.addr_bytes, RTE_ETHER_ADDR_LEN); } @@ -10551,6 +10561,8 @@ static void cmd_set_nvgre_parsed(void *parsed_result, __rte_unused void *data) { struct cmd_set_nvgre_result *res = parsed_result; + struct rte_flow_parser_nvgre_encap_conf *nvgre_conf = + rte_flow_parser_nvgre_encap_conf(); union { uint32_t nvgre_tni; uint8_t tni[4]; @@ -10558,29 +10570,32 @@ static void cmd_set_nvgre_parsed(void *parsed_result, .nvgre_tni = rte_cpu_to_be_32(res->tni) & RTE_BE32(0x00ffffff), }; + if (nvgre_conf == NULL) + return; + if (strcmp(res->nvgre, "nvgre") == 0) - nvgre_encap_conf.select_vlan = 0; + nvgre_conf->select_vlan = 0; else if (strcmp(res->nvgre, "nvgre-with-vlan") == 0) - nvgre_encap_conf.select_vlan = 1; + nvgre_conf->select_vlan = 1; if (strcmp(res->ip_version, "ipv4") == 0) - nvgre_encap_conf.select_ipv4 = 1; + nvgre_conf->select_ipv4 = 1; else if (strcmp(res->ip_version, "ipv6") == 0) - nvgre_encap_conf.select_ipv4 = 0; + nvgre_conf->select_ipv4 = 0; else return; - rte_memcpy(nvgre_encap_conf.tni, &id.tni[1], 3); - if (nvgre_encap_conf.select_ipv4) { - IPV4_ADDR_TO_UINT(res->ip_src, nvgre_encap_conf.ipv4_src); - IPV4_ADDR_TO_UINT(res->ip_dst, nvgre_encap_conf.ipv4_dst); + rte_memcpy(nvgre_conf->tni, &id.tni[1], 3); + if (nvgre_conf->select_ipv4) { + IPV4_ADDR_TO_UINT(res->ip_src, nvgre_conf->ipv4_src); + IPV4_ADDR_TO_UINT(res->ip_dst, nvgre_conf->ipv4_dst); } else { - IPV6_ADDR_TO_ARRAY(res->ip_src, nvgre_encap_conf.ipv6_src); - IPV6_ADDR_TO_ARRAY(res->ip_dst, nvgre_encap_conf.ipv6_dst); + IPV6_ADDR_TO_ARRAY(res->ip_src, nvgre_conf->ipv6_src); + IPV6_ADDR_TO_ARRAY(res->ip_dst, nvgre_conf->ipv6_dst); } - if (nvgre_encap_conf.select_vlan) - nvgre_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci); - rte_memcpy(nvgre_encap_conf.eth_src, res->eth_src.addr_bytes, + if (nvgre_conf->select_vlan) + nvgre_conf->vlan_tci = rte_cpu_to_be_16(res->tci); + rte_memcpy(nvgre_conf->eth_src, res->eth_src.addr_bytes, RTE_ETHER_ADDR_LEN); - rte_memcpy(nvgre_encap_conf.eth_dst, res->eth_dst.addr_bytes, + rte_memcpy(nvgre_conf->eth_dst, res->eth_dst.addr_bytes, RTE_ETHER_ADDR_LEN); } @@ -10682,22 +10697,27 @@ static void cmd_set_l2_encap_parsed(void *parsed_result, __rte_unused void *data) { struct cmd_set_l2_encap_result *res = parsed_result; + struct rte_flow_parser_l2_encap_conf *l2_conf = + rte_flow_parser_l2_encap_conf(); + + if (l2_conf == NULL) + return; if (strcmp(res->l2_encap, "l2_encap") == 0) - l2_encap_conf.select_vlan = 0; + l2_conf->select_vlan = 0; else if (strcmp(res->l2_encap, "l2_encap-with-vlan") == 0) - l2_encap_conf.select_vlan = 1; + l2_conf->select_vlan = 1; if (strcmp(res->ip_version, "ipv4") == 0) - l2_encap_conf.select_ipv4 = 1; + l2_conf->select_ipv4 = 1; else if (strcmp(res->ip_version, "ipv6") == 0) - l2_encap_conf.select_ipv4 = 0; + l2_conf->select_ipv4 = 0; else return; - if (l2_encap_conf.select_vlan) - l2_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci); - rte_memcpy(l2_encap_conf.eth_src, res->eth_src.addr_bytes, + if (l2_conf->select_vlan) + l2_conf->vlan_tci = rte_cpu_to_be_16(res->tci); + rte_memcpy(l2_conf->eth_src, res->eth_src.addr_bytes, RTE_ETHER_ADDR_LEN); - rte_memcpy(l2_encap_conf.eth_dst, res->eth_dst.addr_bytes, + rte_memcpy(l2_conf->eth_dst, res->eth_dst.addr_bytes, RTE_ETHER_ADDR_LEN); } @@ -10761,11 +10781,16 @@ static void cmd_set_l2_decap_parsed(void *parsed_result, __rte_unused void *data) { struct cmd_set_l2_decap_result *res = parsed_result; + struct rte_flow_parser_l2_decap_conf *l2_conf = + rte_flow_parser_l2_decap_conf(); + + if (l2_conf == NULL) + return; if (strcmp(res->l2_decap, "l2_decap") == 0) - l2_decap_conf.select_vlan = 0; + l2_conf->select_vlan = 0; else if (strcmp(res->l2_decap, "l2_decap-with-vlan") == 0) - l2_decap_conf.select_vlan = 1; + l2_conf->select_vlan = 1; } static cmdline_parse_inst_t cmd_set_l2_decap = { @@ -10860,6 +10885,8 @@ static void cmd_set_mplsogre_encap_parsed(void *parsed_result, __rte_unused void *data) { struct cmd_set_mplsogre_encap_result *res = parsed_result; + struct rte_flow_parser_mplsogre_encap_conf *mplsogre_conf = + rte_flow_parser_mplsogre_encap_conf(); union { uint32_t mplsogre_label; uint8_t label[4]; @@ -10867,29 +10894,32 @@ static void cmd_set_mplsogre_encap_parsed(void *parsed_result, .mplsogre_label = rte_cpu_to_be_32(res->label<<12), }; + if (mplsogre_conf == NULL) + return; + if (strcmp(res->mplsogre, "mplsogre_encap") == 0) - mplsogre_encap_conf.select_vlan = 0; + mplsogre_conf->select_vlan = 0; else if (strcmp(res->mplsogre, "mplsogre_encap-with-vlan") == 0) - mplsogre_encap_conf.select_vlan = 1; + mplsogre_conf->select_vlan = 1; if (strcmp(res->ip_version, "ipv4") == 0) - mplsogre_encap_conf.select_ipv4 = 1; + mplsogre_conf->select_ipv4 = 1; else if (strcmp(res->ip_version, "ipv6") == 0) - mplsogre_encap_conf.select_ipv4 = 0; + mplsogre_conf->select_ipv4 = 0; else return; - rte_memcpy(mplsogre_encap_conf.label, &id.label, 3); - if (mplsogre_encap_conf.select_ipv4) { - IPV4_ADDR_TO_UINT(res->ip_src, mplsogre_encap_conf.ipv4_src); - IPV4_ADDR_TO_UINT(res->ip_dst, mplsogre_encap_conf.ipv4_dst); + rte_memcpy(mplsogre_conf->label, &id.label, 3); + if (mplsogre_conf->select_ipv4) { + IPV4_ADDR_TO_UINT(res->ip_src, mplsogre_conf->ipv4_src); + IPV4_ADDR_TO_UINT(res->ip_dst, mplsogre_conf->ipv4_dst); } else { - IPV6_ADDR_TO_ARRAY(res->ip_src, mplsogre_encap_conf.ipv6_src); - IPV6_ADDR_TO_ARRAY(res->ip_dst, mplsogre_encap_conf.ipv6_dst); + IPV6_ADDR_TO_ARRAY(res->ip_src, mplsogre_conf->ipv6_src); + IPV6_ADDR_TO_ARRAY(res->ip_dst, mplsogre_conf->ipv6_dst); } - if (mplsogre_encap_conf.select_vlan) - mplsogre_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci); - rte_memcpy(mplsogre_encap_conf.eth_src, res->eth_src.addr_bytes, + if (mplsogre_conf->select_vlan) + mplsogre_conf->vlan_tci = rte_cpu_to_be_16(res->tci); + rte_memcpy(mplsogre_conf->eth_src, res->eth_src.addr_bytes, RTE_ETHER_ADDR_LEN); - rte_memcpy(mplsogre_encap_conf.eth_dst, res->eth_dst.addr_bytes, + rte_memcpy(mplsogre_conf->eth_dst, res->eth_dst.addr_bytes, RTE_ETHER_ADDR_LEN); } @@ -10975,15 +11005,20 @@ static void cmd_set_mplsogre_decap_parsed(void *parsed_result, __rte_unused void *data) { struct cmd_set_mplsogre_decap_result *res = parsed_result; + struct rte_flow_parser_mplsogre_decap_conf *mplsogre_conf = + rte_flow_parser_mplsogre_decap_conf(); + + if (mplsogre_conf == NULL) + return; if (strcmp(res->mplsogre, "mplsogre_decap") == 0) - mplsogre_decap_conf.select_vlan = 0; + mplsogre_conf->select_vlan = 0; else if (strcmp(res->mplsogre, "mplsogre_decap-with-vlan") == 0) - mplsogre_decap_conf.select_vlan = 1; + mplsogre_conf->select_vlan = 1; if (strcmp(res->ip_version, "ipv4") == 0) - mplsogre_decap_conf.select_ipv4 = 1; + mplsogre_conf->select_ipv4 = 1; else if (strcmp(res->ip_version, "ipv6") == 0) - mplsogre_decap_conf.select_ipv4 = 0; + mplsogre_conf->select_ipv4 = 0; } static cmdline_parse_inst_t cmd_set_mplsogre_decap = { @@ -11096,6 +11131,8 @@ static void cmd_set_mplsoudp_encap_parsed(void *parsed_result, __rte_unused void *data) { struct cmd_set_mplsoudp_encap_result *res = parsed_result; + struct rte_flow_parser_mplsoudp_encap_conf *mplsoudp_conf = + rte_flow_parser_mplsoudp_encap_conf(); union { uint32_t mplsoudp_label; uint8_t label[4]; @@ -11103,31 +11140,34 @@ static void cmd_set_mplsoudp_encap_parsed(void *parsed_result, .mplsoudp_label = rte_cpu_to_be_32(res->label<<12), }; + if (mplsoudp_conf == NULL) + return; + if (strcmp(res->mplsoudp, "mplsoudp_encap") == 0) - mplsoudp_encap_conf.select_vlan = 0; + mplsoudp_conf->select_vlan = 0; else if (strcmp(res->mplsoudp, "mplsoudp_encap-with-vlan") == 0) - mplsoudp_encap_conf.select_vlan = 1; + mplsoudp_conf->select_vlan = 1; if (strcmp(res->ip_version, "ipv4") == 0) - mplsoudp_encap_conf.select_ipv4 = 1; + mplsoudp_conf->select_ipv4 = 1; else if (strcmp(res->ip_version, "ipv6") == 0) - mplsoudp_encap_conf.select_ipv4 = 0; + mplsoudp_conf->select_ipv4 = 0; else return; - rte_memcpy(mplsoudp_encap_conf.label, &id.label, 3); - mplsoudp_encap_conf.udp_src = rte_cpu_to_be_16(res->udp_src); - mplsoudp_encap_conf.udp_dst = rte_cpu_to_be_16(res->udp_dst); - if (mplsoudp_encap_conf.select_ipv4) { - IPV4_ADDR_TO_UINT(res->ip_src, mplsoudp_encap_conf.ipv4_src); - IPV4_ADDR_TO_UINT(res->ip_dst, mplsoudp_encap_conf.ipv4_dst); + rte_memcpy(mplsoudp_conf->label, &id.label, 3); + mplsoudp_conf->udp_src = rte_cpu_to_be_16(res->udp_src); + mplsoudp_conf->udp_dst = rte_cpu_to_be_16(res->udp_dst); + if (mplsoudp_conf->select_ipv4) { + IPV4_ADDR_TO_UINT(res->ip_src, mplsoudp_conf->ipv4_src); + IPV4_ADDR_TO_UINT(res->ip_dst, mplsoudp_conf->ipv4_dst); } else { - IPV6_ADDR_TO_ARRAY(res->ip_src, mplsoudp_encap_conf.ipv6_src); - IPV6_ADDR_TO_ARRAY(res->ip_dst, mplsoudp_encap_conf.ipv6_dst); + IPV6_ADDR_TO_ARRAY(res->ip_src, mplsoudp_conf->ipv6_src); + IPV6_ADDR_TO_ARRAY(res->ip_dst, mplsoudp_conf->ipv6_dst); } - if (mplsoudp_encap_conf.select_vlan) - mplsoudp_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci); - rte_memcpy(mplsoudp_encap_conf.eth_src, res->eth_src.addr_bytes, + if (mplsoudp_conf->select_vlan) + mplsoudp_conf->vlan_tci = rte_cpu_to_be_16(res->tci); + rte_memcpy(mplsoudp_conf->eth_src, res->eth_src.addr_bytes, RTE_ETHER_ADDR_LEN); - rte_memcpy(mplsoudp_encap_conf.eth_dst, res->eth_dst.addr_bytes, + rte_memcpy(mplsoudp_conf->eth_dst, res->eth_dst.addr_bytes, RTE_ETHER_ADDR_LEN); } @@ -11222,15 +11262,20 @@ static void cmd_set_mplsoudp_decap_parsed(void *parsed_result, __rte_unused void *data) { struct cmd_set_mplsoudp_decap_result *res = parsed_result; + struct rte_flow_parser_mplsoudp_decap_conf *mplsoudp_conf = + rte_flow_parser_mplsoudp_decap_conf(); + + if (mplsoudp_conf == NULL) + return; if (strcmp(res->mplsoudp, "mplsoudp_decap") == 0) - mplsoudp_decap_conf.select_vlan = 0; + mplsoudp_conf->select_vlan = 0; else if (strcmp(res->mplsoudp, "mplsoudp_decap-with-vlan") == 0) - mplsoudp_decap_conf.select_vlan = 1; + mplsoudp_conf->select_vlan = 1; if (strcmp(res->ip_version, "ipv4") == 0) - mplsoudp_decap_conf.select_ipv4 = 1; + mplsoudp_conf->select_ipv4 = 1; else if (strcmp(res->ip_version, "ipv6") == 0) - mplsoudp_decap_conf.select_ipv4 = 0; + mplsoudp_conf->select_ipv4 = 0; } static cmdline_parse_inst_t cmd_set_mplsoudp_decap = { @@ -11409,25 +11454,26 @@ static void cmd_set_conntrack_common_parsed(void *parsed_result, __rte_unused void *data) { struct cmd_set_conntrack_common_result *res = parsed_result; + struct rte_flow_action_conntrack *ct = rte_flow_parser_conntrack_context(); /* No need to swap to big endian. */ - conntrack_context.peer_port = res->peer_port; - conntrack_context.is_original_dir = res->is_original; - conntrack_context.enable = res->en; - conntrack_context.live_connection = res->is_live; - conntrack_context.selective_ack = res->s_ack; - conntrack_context.challenge_ack_passed = res->c_ack; - conntrack_context.last_direction = res->ld; - conntrack_context.liberal_mode = res->lb; - conntrack_context.state = (enum rte_flow_conntrack_state)res->stat; - conntrack_context.max_ack_window = res->factor; - conntrack_context.retransmission_limit = res->re_num; - conntrack_context.last_window = res->lw; - conntrack_context.last_index = + ct->peer_port = res->peer_port; + ct->is_original_dir = res->is_original; + ct->enable = res->en; + ct->live_connection = res->is_live; + ct->selective_ack = res->s_ack; + ct->challenge_ack_passed = res->c_ack; + ct->last_direction = res->ld; + ct->liberal_mode = res->lb; + ct->state = (enum rte_flow_conntrack_state)res->stat; + ct->max_ack_window = res->factor; + ct->retransmission_limit = res->re_num; + ct->last_window = res->lw; + ct->last_index = (enum rte_flow_conntrack_tcp_last_index)res->li; - conntrack_context.last_seq = res->ls; - conntrack_context.last_ack = res->la; - conntrack_context.last_end = res->le; + ct->last_seq = res->ls; + ct->last_ack = res->la; + ct->last_end = res->le; } static cmdline_parse_inst_t cmd_set_conntrack_common = { @@ -11558,12 +11604,13 @@ static void cmd_set_conntrack_dir_parsed(void *parsed_result, __rte_unused void *data) { struct cmd_set_conntrack_dir_result *res = parsed_result; + struct rte_flow_action_conntrack *ct = rte_flow_parser_conntrack_context(); struct rte_flow_tcp_dir_param *dir = NULL; if (strcmp(res->dir, "orig") == 0) - dir = &conntrack_context.original_dir; + dir = &ct->original_dir; else if (strcmp(res->dir, "rply") == 0) - dir = &conntrack_context.reply_dir; + dir = &ct->reply_dir; else return; dir->scale = res->factor; @@ -14340,6 +14387,9 @@ init_cmdline(void) unsigned int count; unsigned int i; + /* dynamic flow/set tokens managed by librte_flow_parser. */ + rte_flow_parser_cmdline_register(&cmd_flow, &cmd_set_raw); + /* initialize non-constant commands */ cmd_set_fwd_mode_init(); cmd_set_fwd_retry_mode_init(); diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c deleted file mode 100644 index 54b247899d..0000000000 --- a/app/test-pmd/cmdline_flow.c +++ /dev/null @@ -1,14434 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2016 6WIND S.A. - * Copyright 2016 Mellanox Technologies, Ltd - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "testpmd.h" - -/** Parser token indices. */ -enum index { - /* Special tokens. */ - ZERO = 0, - END, - START_SET, - END_SET, - - /* Common tokens. */ - COMMON_INTEGER, - COMMON_UNSIGNED, - COMMON_PREFIX, - COMMON_BOOLEAN, - COMMON_STRING, - COMMON_HEX, - COMMON_FILE_PATH, - COMMON_MAC_ADDR, - COMMON_IPV4_ADDR, - COMMON_IPV6_ADDR, - COMMON_RULE_ID, - COMMON_PORT_ID, - COMMON_GROUP_ID, - COMMON_PRIORITY_LEVEL, - COMMON_INDIRECT_ACTION_ID, - COMMON_PROFILE_ID, - COMMON_POLICY_ID, - COMMON_FLEX_HANDLE, - COMMON_FLEX_TOKEN, - COMMON_PATTERN_TEMPLATE_ID, - COMMON_ACTIONS_TEMPLATE_ID, - COMMON_TABLE_ID, - COMMON_QUEUE_ID, - COMMON_METER_COLOR_NAME, - - /* TOP-level command. */ - ADD, - - /* Top-level command. */ - SET, - /* Sub-leve commands. */ - SET_RAW_ENCAP, - SET_RAW_DECAP, - SET_RAW_INDEX, - SET_SAMPLE_ACTIONS, - SET_SAMPLE_INDEX, - SET_IPV6_EXT_REMOVE, - SET_IPV6_EXT_PUSH, - SET_IPV6_EXT_INDEX, - - /* Top-level command. */ - FLOW, - /* Sub-level commands. */ - INFO, - CONFIGURE, - PATTERN_TEMPLATE, - ACTIONS_TEMPLATE, - TABLE, - FLOW_GROUP, - INDIRECT_ACTION, - VALIDATE, - CREATE, - DESTROY, - UPDATE, - FLUSH, - DUMP, - QUERY, - LIST, - AGED, - ISOLATE, - TUNNEL, - FLEX, - QUEUE, - PUSH, - PULL, - HASH, - - /* Flex arguments */ - FLEX_ITEM_CREATE, - FLEX_ITEM_DESTROY, - - /* Pattern template arguments. */ - PATTERN_TEMPLATE_CREATE, - PATTERN_TEMPLATE_DESTROY, - PATTERN_TEMPLATE_CREATE_ID, - PATTERN_TEMPLATE_DESTROY_ID, - PATTERN_TEMPLATE_RELAXED_MATCHING, - PATTERN_TEMPLATE_INGRESS, - PATTERN_TEMPLATE_EGRESS, - PATTERN_TEMPLATE_TRANSFER, - PATTERN_TEMPLATE_SPEC, - - /* Actions template arguments. */ - ACTIONS_TEMPLATE_CREATE, - ACTIONS_TEMPLATE_DESTROY, - ACTIONS_TEMPLATE_CREATE_ID, - ACTIONS_TEMPLATE_DESTROY_ID, - ACTIONS_TEMPLATE_INGRESS, - ACTIONS_TEMPLATE_EGRESS, - ACTIONS_TEMPLATE_TRANSFER, - ACTIONS_TEMPLATE_SPEC, - ACTIONS_TEMPLATE_MASK, - - /* Queue arguments. */ - QUEUE_CREATE, - QUEUE_DESTROY, - QUEUE_FLOW_UPDATE_RESIZED, - QUEUE_UPDATE, - QUEUE_AGED, - QUEUE_INDIRECT_ACTION, - - /* Queue create arguments. */ - QUEUE_CREATE_POSTPONE, - QUEUE_TEMPLATE_TABLE, - QUEUE_PATTERN_TEMPLATE, - QUEUE_ACTIONS_TEMPLATE, - QUEUE_RULE_ID, - - /* Queue destroy arguments. */ - QUEUE_DESTROY_ID, - QUEUE_DESTROY_POSTPONE, - - /* Queue update arguments. */ - QUEUE_UPDATE_ID, - - /* 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, - QUEUE_INDIRECT_ACTION_QUERY_UPDATE, - - /* Queue indirect action create arguments */ - QUEUE_INDIRECT_ACTION_CREATE_ID, - QUEUE_INDIRECT_ACTION_INGRESS, - QUEUE_INDIRECT_ACTION_EGRESS, - 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, - - /* Queue indirect action destroy arguments */ - QUEUE_INDIRECT_ACTION_DESTROY_ID, - QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, - - /* Queue indirect action query arguments */ - QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, - - /* Queue indirect action query_update arguments */ - QUEUE_INDIRECT_ACTION_QU_MODE, - - /* Push arguments. */ - PUSH_QUEUE, - - /* Pull arguments. */ - PULL_QUEUE, - - /* Table arguments. */ - TABLE_CREATE, - TABLE_DESTROY, - TABLE_RESIZE, - TABLE_RESIZE_COMPLETE, - TABLE_CREATE_ID, - TABLE_DESTROY_ID, - TABLE_RESIZE_ID, - TABLE_RESIZE_RULES_NUMBER, - TABLE_INSERTION_TYPE, - TABLE_INSERTION_TYPE_NAME, - TABLE_HASH_FUNC, - TABLE_HASH_FUNC_NAME, - TABLE_GROUP, - TABLE_PRIORITY, - TABLE_INGRESS, - TABLE_EGRESS, - TABLE_TRANSFER, - TABLE_TRANSFER_WIRE_ORIG, - TABLE_TRANSFER_VPORT_ORIG, - TABLE_RESIZABLE, - TABLE_RULES_NUMBER, - TABLE_PATTERN_TEMPLATE, - TABLE_ACTIONS_TEMPLATE, - - /* Group arguments */ - GROUP_ID, - GROUP_INGRESS, - GROUP_EGRESS, - GROUP_TRANSFER, - GROUP_SET_MISS_ACTIONS, - - /* Hash calculation arguments. */ - HASH_CALC_TABLE, - HASH_CALC_PATTERN_INDEX, - HASH_CALC_PATTERN, - HASH_CALC_ENCAP, - HASH_CALC_DEST, - ENCAP_HASH_FIELD_SRC_PORT, - ENCAP_HASH_FIELD_GRE_FLOW_ID, - - /* Tunnel arguments. */ - TUNNEL_CREATE, - TUNNEL_CREATE_TYPE, - TUNNEL_LIST, - TUNNEL_DESTROY, - TUNNEL_DESTROY_ID, - - /* Destroy arguments. */ - DESTROY_RULE, - DESTROY_IS_USER_ID, - - /* Query arguments. */ - QUERY_ACTION, - QUERY_IS_USER_ID, - - /* List arguments. */ - LIST_GROUP, - - /* Destroy aged flow arguments. */ - AGED_DESTROY, - - /* Validate/create arguments. */ - VC_GROUP, - VC_PRIORITY, - VC_INGRESS, - VC_EGRESS, - VC_TRANSFER, - VC_TUNNEL_SET, - VC_TUNNEL_MATCH, - VC_USER_ID, - VC_IS_USER_ID, - - /* Dump arguments */ - DUMP_ALL, - DUMP_ONE, - DUMP_IS_USER_ID, - - /* Configure arguments */ - CONFIG_QUEUES_NUMBER, - CONFIG_QUEUES_SIZE, - CONFIG_COUNTERS_NUMBER, - CONFIG_AGING_OBJECTS_NUMBER, - CONFIG_METERS_NUMBER, - CONFIG_CONN_TRACK_NUMBER, - CONFIG_QUOTAS_NUMBER, - CONFIG_FLAGS, - CONFIG_HOST_PORT, - - /* Indirect action arguments */ - INDIRECT_ACTION_CREATE, - INDIRECT_ACTION_LIST_CREATE, - INDIRECT_ACTION_FLOW_CONF_CREATE, - INDIRECT_ACTION_UPDATE, - INDIRECT_ACTION_DESTROY, - INDIRECT_ACTION_QUERY, - INDIRECT_ACTION_QUERY_UPDATE, - - /* Indirect action create arguments */ - INDIRECT_ACTION_CREATE_ID, - INDIRECT_ACTION_INGRESS, - INDIRECT_ACTION_EGRESS, - INDIRECT_ACTION_TRANSFER, - INDIRECT_ACTION_SPEC, - INDIRECT_ACTION_LIST, - INDIRECT_ACTION_FLOW_CONF, - - /* Indirect action destroy arguments */ - INDIRECT_ACTION_DESTROY_ID, - - /* Indirect action query-and-update arguments */ - INDIRECT_ACTION_QU_MODE, - INDIRECT_ACTION_QU_MODE_NAME, - - /* Validate/create pattern. */ - ITEM_PATTERN, - ITEM_PARAM_IS, - ITEM_PARAM_SPEC, - ITEM_PARAM_LAST, - ITEM_PARAM_MASK, - ITEM_PARAM_PREFIX, - ITEM_NEXT, - ITEM_END, - ITEM_VOID, - ITEM_INVERT, - ITEM_ANY, - ITEM_ANY_NUM, - ITEM_PORT_ID, - ITEM_PORT_ID_ID, - ITEM_MARK, - ITEM_MARK_ID, - ITEM_RAW, - ITEM_RAW_RELATIVE, - ITEM_RAW_SEARCH, - ITEM_RAW_OFFSET, - ITEM_RAW_LIMIT, - ITEM_RAW_PATTERN, - ITEM_RAW_PATTERN_HEX, - ITEM_ETH, - ITEM_ETH_DST, - ITEM_ETH_SRC, - ITEM_ETH_TYPE, - ITEM_ETH_HAS_VLAN, - ITEM_VLAN, - ITEM_VLAN_TCI, - ITEM_VLAN_PCP, - ITEM_VLAN_DEI, - ITEM_VLAN_VID, - ITEM_VLAN_INNER_TYPE, - ITEM_VLAN_HAS_MORE_VLAN, - ITEM_IPV4, - ITEM_IPV4_VER_IHL, - ITEM_IPV4_TOS, - ITEM_IPV4_LENGTH, - ITEM_IPV4_ID, - ITEM_IPV4_FRAGMENT_OFFSET, - ITEM_IPV4_TTL, - ITEM_IPV4_PROTO, - ITEM_IPV4_SRC, - ITEM_IPV4_DST, - ITEM_IPV6, - ITEM_IPV6_TC, - ITEM_IPV6_FLOW, - ITEM_IPV6_LEN, - ITEM_IPV6_PROTO, - ITEM_IPV6_HOP, - ITEM_IPV6_SRC, - ITEM_IPV6_DST, - ITEM_IPV6_HAS_FRAG_EXT, - ITEM_IPV6_ROUTING_EXT, - ITEM_IPV6_ROUTING_EXT_TYPE, - ITEM_IPV6_ROUTING_EXT_NEXT_HDR, - ITEM_IPV6_ROUTING_EXT_SEG_LEFT, - ITEM_ICMP, - ITEM_ICMP_TYPE, - ITEM_ICMP_CODE, - ITEM_ICMP_IDENT, - ITEM_ICMP_SEQ, - ITEM_UDP, - ITEM_UDP_SRC, - ITEM_UDP_DST, - ITEM_TCP, - ITEM_TCP_SRC, - ITEM_TCP_DST, - ITEM_TCP_FLAGS, - ITEM_SCTP, - ITEM_SCTP_SRC, - ITEM_SCTP_DST, - ITEM_SCTP_TAG, - ITEM_SCTP_CKSUM, - ITEM_VXLAN, - ITEM_VXLAN_VNI, - ITEM_VXLAN_FLAG_G, - ITEM_VXLAN_FLAG_VER, - ITEM_VXLAN_FLAG_I, - ITEM_VXLAN_FLAG_P, - ITEM_VXLAN_FLAG_B, - ITEM_VXLAN_FLAG_O, - ITEM_VXLAN_FLAG_D, - ITEM_VXLAN_FLAG_A, - ITEM_VXLAN_GBP_ID, - /* Used for "struct rte_vxlan_hdr", GPE Next protocol */ - ITEM_VXLAN_GPE_PROTO, - ITEM_VXLAN_FIRST_RSVD, - ITEM_VXLAN_SECND_RSVD, - ITEM_VXLAN_THIRD_RSVD, - ITEM_VXLAN_LAST_RSVD, - ITEM_E_TAG, - ITEM_E_TAG_GRP_ECID_B, - ITEM_NVGRE, - ITEM_NVGRE_TNI, - ITEM_MPLS, - ITEM_MPLS_LABEL, - ITEM_MPLS_TC, - ITEM_MPLS_S, - ITEM_MPLS_TTL, - ITEM_GRE, - ITEM_GRE_PROTO, - ITEM_GRE_C_RSVD0_VER, - ITEM_GRE_C_BIT, - ITEM_GRE_K_BIT, - ITEM_GRE_S_BIT, - ITEM_FUZZY, - ITEM_FUZZY_THRESH, - ITEM_GTP, - ITEM_GTP_FLAGS, - ITEM_GTP_MSG_TYPE, - ITEM_GTP_TEID, - ITEM_GTPC, - ITEM_GTPU, - ITEM_GENEVE, - ITEM_GENEVE_VNI, - ITEM_GENEVE_PROTO, - ITEM_GENEVE_OPTLEN, - ITEM_VXLAN_GPE, - ITEM_VXLAN_GPE_VNI, - /* Used for "struct rte_vxlan_gpe_hdr", deprecated, prefer ITEM_VXLAN_GPE_PROTO */ - ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR, - ITEM_VXLAN_GPE_FLAGS, - ITEM_VXLAN_GPE_RSVD0, - ITEM_VXLAN_GPE_RSVD1, - ITEM_ARP_ETH_IPV4, - ITEM_ARP_ETH_IPV4_SHA, - ITEM_ARP_ETH_IPV4_SPA, - ITEM_ARP_ETH_IPV4_THA, - ITEM_ARP_ETH_IPV4_TPA, - ITEM_IPV6_EXT, - ITEM_IPV6_EXT_NEXT_HDR, - ITEM_IPV6_FRAG_EXT, - ITEM_IPV6_FRAG_EXT_NEXT_HDR, - ITEM_IPV6_FRAG_EXT_FRAG_DATA, - ITEM_IPV6_FRAG_EXT_ID, - ITEM_ICMP6, - ITEM_ICMP6_TYPE, - ITEM_ICMP6_CODE, - ITEM_ICMP6_ECHO_REQUEST, - ITEM_ICMP6_ECHO_REQUEST_ID, - ITEM_ICMP6_ECHO_REQUEST_SEQ, - ITEM_ICMP6_ECHO_REPLY, - ITEM_ICMP6_ECHO_REPLY_ID, - ITEM_ICMP6_ECHO_REPLY_SEQ, - ITEM_ICMP6_ND_NS, - ITEM_ICMP6_ND_NS_TARGET_ADDR, - ITEM_ICMP6_ND_NA, - ITEM_ICMP6_ND_NA_TARGET_ADDR, - ITEM_ICMP6_ND_OPT, - ITEM_ICMP6_ND_OPT_TYPE, - ITEM_ICMP6_ND_OPT_SLA_ETH, - ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, - ITEM_ICMP6_ND_OPT_TLA_ETH, - ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, - ITEM_META, - ITEM_META_DATA, - ITEM_RANDOM, - ITEM_RANDOM_VALUE, - ITEM_GRE_KEY, - ITEM_GRE_KEY_VALUE, - ITEM_GRE_OPTION, - ITEM_GRE_OPTION_CHECKSUM, - ITEM_GRE_OPTION_KEY, - ITEM_GRE_OPTION_SEQUENCE, - ITEM_GTP_PSC, - ITEM_GTP_PSC_QFI, - ITEM_GTP_PSC_PDU_T, - ITEM_PPPOES, - ITEM_PPPOED, - ITEM_PPPOE_SEID, - ITEM_PPPOE_PROTO_ID, - ITEM_HIGIG2, - ITEM_HIGIG2_CLASSIFICATION, - ITEM_HIGIG2_VID, - ITEM_TAG, - ITEM_TAG_DATA, - 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, - ITEM_GENEVE_OPT, - ITEM_GENEVE_OPT_CLASS, - ITEM_GENEVE_OPT_TYPE, - ITEM_GENEVE_OPT_LENGTH, - ITEM_GENEVE_OPT_DATA, - ITEM_INTEGRITY, - ITEM_INTEGRITY_LEVEL, - ITEM_INTEGRITY_VALUE, - ITEM_CONNTRACK, - ITEM_POL_PORT, - ITEM_POL_METER, - ITEM_POL_POLICY, - ITEM_PORT_REPRESENTOR, - ITEM_PORT_REPRESENTOR_PORT_ID, - ITEM_REPRESENTED_PORT, - ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, - ITEM_FLEX, - ITEM_FLEX_ITEM_HANDLE, - ITEM_FLEX_PATTERN_HANDLE, - ITEM_L2TPV2, - ITEM_L2TPV2_TYPE, - ITEM_L2TPV2_TYPE_DATA, - ITEM_L2TPV2_TYPE_DATA_L, - ITEM_L2TPV2_TYPE_DATA_S, - ITEM_L2TPV2_TYPE_DATA_O, - ITEM_L2TPV2_TYPE_DATA_L_S, - ITEM_L2TPV2_TYPE_CTRL, - ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, - ITEM_L2TPV2_MSG_DATA_SESSION_ID, - ITEM_L2TPV2_MSG_DATA_L_LENGTH, - ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, - ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, - ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, - ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, - ITEM_L2TPV2_MSG_DATA_S_NS, - ITEM_L2TPV2_MSG_DATA_S_NR, - ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, - ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, - ITEM_L2TPV2_MSG_DATA_O_OFFSET, - ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, - ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, - ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, - ITEM_L2TPV2_MSG_DATA_L_S_NS, - ITEM_L2TPV2_MSG_DATA_L_S_NR, - ITEM_L2TPV2_MSG_CTRL_LENGTH, - ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, - ITEM_L2TPV2_MSG_CTRL_SESSION_ID, - ITEM_L2TPV2_MSG_CTRL_NS, - ITEM_L2TPV2_MSG_CTRL_NR, - ITEM_PPP, - ITEM_PPP_ADDR, - ITEM_PPP_CTRL, - ITEM_PPP_PROTO_ID, - ITEM_METER, - ITEM_METER_COLOR, - ITEM_QUOTA, - ITEM_QUOTA_STATE, - ITEM_QUOTA_STATE_NAME, - ITEM_AGGR_AFFINITY, - ITEM_AGGR_AFFINITY_VALUE, - ITEM_TX_QUEUE, - ITEM_TX_QUEUE_VALUE, - ITEM_IB_BTH, - ITEM_IB_BTH_OPCODE, - ITEM_IB_BTH_PKEY, - ITEM_IB_BTH_DST_QPN, - ITEM_IB_BTH_PSN, - ITEM_IPV6_PUSH_REMOVE_EXT, - ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, - ITEM_PTYPE, - ITEM_PTYPE_VALUE, - ITEM_NSH, - ITEM_COMPARE, - ITEM_COMPARE_OP, - ITEM_COMPARE_OP_VALUE, - ITEM_COMPARE_FIELD_A_TYPE, - ITEM_COMPARE_FIELD_A_TYPE_VALUE, - ITEM_COMPARE_FIELD_A_LEVEL, - ITEM_COMPARE_FIELD_A_LEVEL_VALUE, - ITEM_COMPARE_FIELD_A_TAG_INDEX, - ITEM_COMPARE_FIELD_A_TYPE_ID, - ITEM_COMPARE_FIELD_A_CLASS_ID, - ITEM_COMPARE_FIELD_A_OFFSET, - ITEM_COMPARE_FIELD_B_TYPE, - ITEM_COMPARE_FIELD_B_TYPE_VALUE, - ITEM_COMPARE_FIELD_B_LEVEL, - ITEM_COMPARE_FIELD_B_LEVEL_VALUE, - ITEM_COMPARE_FIELD_B_TAG_INDEX, - ITEM_COMPARE_FIELD_B_TYPE_ID, - ITEM_COMPARE_FIELD_B_CLASS_ID, - ITEM_COMPARE_FIELD_B_OFFSET, - ITEM_COMPARE_FIELD_B_VALUE, - ITEM_COMPARE_FIELD_B_POINTER, - ITEM_COMPARE_FIELD_WIDTH, - - /* Validate/create actions. */ - ACTIONS, - ACTION_NEXT, - ACTION_END, - ACTION_VOID, - ACTION_PASSTHRU, - ACTION_SKIP_CMAN, - ACTION_JUMP, - ACTION_JUMP_GROUP, - ACTION_MARK, - ACTION_MARK_ID, - ACTION_FLAG, - ACTION_QUEUE, - ACTION_QUEUE_INDEX, - ACTION_DROP, - ACTION_COUNT, - ACTION_COUNT_ID, - ACTION_RSS, - ACTION_RSS_FUNC, - ACTION_RSS_LEVEL, - ACTION_RSS_FUNC_DEFAULT, - ACTION_RSS_FUNC_TOEPLITZ, - ACTION_RSS_FUNC_SIMPLE_XOR, - ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, - ACTION_RSS_TYPES, - ACTION_RSS_TYPE, - ACTION_RSS_KEY, - ACTION_RSS_KEY_LEN, - ACTION_RSS_QUEUES, - ACTION_RSS_QUEUE, - ACTION_PF, - ACTION_VF, - ACTION_VF_ORIGINAL, - ACTION_VF_ID, - ACTION_PORT_ID, - ACTION_PORT_ID_ORIGINAL, - ACTION_PORT_ID_ID, - ACTION_METER, - ACTION_METER_COLOR, - ACTION_METER_COLOR_TYPE, - ACTION_METER_COLOR_GREEN, - ACTION_METER_COLOR_YELLOW, - ACTION_METER_COLOR_RED, - ACTION_METER_ID, - ACTION_METER_MARK, - ACTION_METER_MARK_CONF, - ACTION_METER_MARK_CONF_COLOR, - ACTION_METER_PROFILE, - ACTION_METER_PROFILE_ID2PTR, - ACTION_METER_POLICY, - ACTION_METER_POLICY_ID2PTR, - ACTION_METER_COLOR_MODE, - ACTION_METER_STATE, - ACTION_OF_DEC_NW_TTL, - ACTION_OF_POP_VLAN, - ACTION_OF_PUSH_VLAN, - ACTION_OF_PUSH_VLAN_ETHERTYPE, - ACTION_OF_SET_VLAN_VID, - ACTION_OF_SET_VLAN_VID_VLAN_VID, - ACTION_OF_SET_VLAN_PCP, - ACTION_OF_SET_VLAN_PCP_VLAN_PCP, - ACTION_OF_POP_MPLS, - ACTION_OF_POP_MPLS_ETHERTYPE, - ACTION_OF_PUSH_MPLS, - ACTION_OF_PUSH_MPLS_ETHERTYPE, - ACTION_VXLAN_ENCAP, - ACTION_VXLAN_DECAP, - ACTION_NVGRE_ENCAP, - ACTION_NVGRE_DECAP, - ACTION_L2_ENCAP, - ACTION_L2_DECAP, - ACTION_MPLSOGRE_ENCAP, - ACTION_MPLSOGRE_DECAP, - ACTION_MPLSOUDP_ENCAP, - ACTION_MPLSOUDP_DECAP, - ACTION_SET_IPV4_SRC, - ACTION_SET_IPV4_SRC_IPV4_SRC, - ACTION_SET_IPV4_DST, - ACTION_SET_IPV4_DST_IPV4_DST, - ACTION_SET_IPV6_SRC, - ACTION_SET_IPV6_SRC_IPV6_SRC, - ACTION_SET_IPV6_DST, - ACTION_SET_IPV6_DST_IPV6_DST, - ACTION_SET_TP_SRC, - ACTION_SET_TP_SRC_TP_SRC, - ACTION_SET_TP_DST, - ACTION_SET_TP_DST_TP_DST, - ACTION_MAC_SWAP, - ACTION_DEC_TTL, - ACTION_SET_TTL, - ACTION_SET_TTL_TTL, - ACTION_SET_MAC_SRC, - ACTION_SET_MAC_SRC_MAC_SRC, - ACTION_SET_MAC_DST, - ACTION_SET_MAC_DST_MAC_DST, - ACTION_INC_TCP_SEQ, - ACTION_INC_TCP_SEQ_VALUE, - ACTION_DEC_TCP_SEQ, - ACTION_DEC_TCP_SEQ_VALUE, - ACTION_INC_TCP_ACK, - ACTION_INC_TCP_ACK_VALUE, - ACTION_DEC_TCP_ACK, - ACTION_DEC_TCP_ACK_VALUE, - ACTION_RAW_ENCAP, - ACTION_RAW_DECAP, - ACTION_RAW_ENCAP_SIZE, - ACTION_RAW_ENCAP_INDEX, - ACTION_RAW_ENCAP_INDEX_VALUE, - ACTION_RAW_DECAP_INDEX, - ACTION_RAW_DECAP_INDEX_VALUE, - ACTION_SET_TAG, - ACTION_SET_TAG_DATA, - ACTION_SET_TAG_INDEX, - ACTION_SET_TAG_MASK, - ACTION_SET_META, - ACTION_SET_META_DATA, - ACTION_SET_META_MASK, - ACTION_SET_IPV4_DSCP, - ACTION_SET_IPV4_DSCP_VALUE, - ACTION_SET_IPV6_DSCP, - ACTION_SET_IPV6_DSCP_VALUE, - ACTION_AGE, - ACTION_AGE_TIMEOUT, - ACTION_AGE_UPDATE, - ACTION_AGE_UPDATE_TIMEOUT, - ACTION_AGE_UPDATE_TOUCH, - ACTION_SAMPLE, - ACTION_SAMPLE_RATIO, - 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, - ACTION_MODIFY_FIELD, - ACTION_MODIFY_FIELD_OP, - ACTION_MODIFY_FIELD_OP_VALUE, - ACTION_MODIFY_FIELD_DST_TYPE, - ACTION_MODIFY_FIELD_DST_TYPE_VALUE, - ACTION_MODIFY_FIELD_DST_LEVEL, - ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, - ACTION_MODIFY_FIELD_DST_TAG_INDEX, - ACTION_MODIFY_FIELD_DST_TYPE_ID, - ACTION_MODIFY_FIELD_DST_CLASS_ID, - ACTION_MODIFY_FIELD_DST_OFFSET, - ACTION_MODIFY_FIELD_SRC_TYPE, - ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, - ACTION_MODIFY_FIELD_SRC_LEVEL, - ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, - ACTION_MODIFY_FIELD_SRC_TAG_INDEX, - ACTION_MODIFY_FIELD_SRC_TYPE_ID, - ACTION_MODIFY_FIELD_SRC_CLASS_ID, - ACTION_MODIFY_FIELD_SRC_OFFSET, - ACTION_MODIFY_FIELD_SRC_VALUE, - ACTION_MODIFY_FIELD_SRC_POINTER, - ACTION_MODIFY_FIELD_WIDTH, - ACTION_CONNTRACK, - ACTION_CONNTRACK_UPDATE, - ACTION_CONNTRACK_UPDATE_DIR, - ACTION_CONNTRACK_UPDATE_CTX, - ACTION_POL_G, - ACTION_POL_Y, - ACTION_POL_R, - ACTION_PORT_REPRESENTOR, - ACTION_PORT_REPRESENTOR_PORT_ID, - ACTION_REPRESENTED_PORT, - ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, - ACTION_SEND_TO_KERNEL, - ACTION_QUOTA_CREATE, - ACTION_QUOTA_CREATE_LIMIT, - ACTION_QUOTA_CREATE_MODE, - ACTION_QUOTA_CREATE_MODE_NAME, - ACTION_QUOTA_QU, - ACTION_QUOTA_QU_LIMIT, - ACTION_QUOTA_QU_UPDATE_OP, - ACTION_QUOTA_QU_UPDATE_OP_NAME, - ACTION_IPV6_EXT_REMOVE, - ACTION_IPV6_EXT_REMOVE_INDEX, - ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, - ACTION_IPV6_EXT_PUSH, - ACTION_IPV6_EXT_PUSH_INDEX, - ACTION_IPV6_EXT_PUSH_INDEX_VALUE, - ACTION_NAT64, - ACTION_NAT64_MODE, - ACTION_JUMP_TO_TABLE_INDEX, - ACTION_JUMP_TO_TABLE_INDEX_TABLE, - ACTION_JUMP_TO_TABLE_INDEX_TABLE_VALUE, - ACTION_JUMP_TO_TABLE_INDEX_INDEX, -}; - -/** Maximum size for pattern in struct rte_flow_item_raw. */ -#define ITEM_RAW_PATTERN_SIZE 512 - -/** Maximum size for GENEVE option data pattern in bytes. */ -#define ITEM_GENEVE_OPT_DATA_SIZE 124 - -/** Storage size for struct rte_flow_item_raw including pattern. */ -#define ITEM_RAW_SIZE \ - (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) - -static const char *const compare_ops[] = { - "eq", "ne", "lt", "le", "gt", "ge", NULL -}; - -/** Maximum size for external pattern in struct rte_flow_field_data. */ -#define FLOW_FIELD_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) + \ - FLOW_FIELD_PATTERN_SIZE) - -/** Maximum number of queue indices in struct rte_flow_action_rss. */ -#define ACTION_RSS_QUEUE_NUM 128 - -/** Storage for struct rte_flow_action_rss including external data. */ -struct action_rss_data { - struct rte_flow_action_rss conf; - uint8_t key[RSS_HASH_KEY_LENGTH]; - uint16_t queue[ACTION_RSS_QUEUE_NUM]; -}; - -/** Maximum data size in struct rte_flow_action_raw_encap. */ -#define ACTION_RAW_ENCAP_MAX_DATA 512 -#define RAW_ENCAP_CONFS_MAX_NUM 8 - -/** Storage for struct rte_flow_action_raw_encap. */ -struct raw_encap_conf { - uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; - uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; - size_t size; -}; - -struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; - -/** Storage for struct rte_flow_action_raw_encap including external data. */ -struct action_raw_encap_data { - struct rte_flow_action_raw_encap conf; - uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; - uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; - uint16_t idx; -}; - -/** Storage for struct rte_flow_action_raw_decap. */ -struct raw_decap_conf { - uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; - size_t size; -}; - -struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; - -/** Storage for struct rte_flow_action_raw_decap including external data. */ -struct action_raw_decap_data { - struct rte_flow_action_raw_decap conf; - uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; - uint16_t idx; -}; - -/** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ -#define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 -#define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 - -/** Storage for struct rte_flow_action_ipv6_ext_push. */ -struct ipv6_ext_push_conf { - uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; - size_t size; - uint8_t type; -}; - -struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; - -/** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ -struct action_ipv6_ext_push_data { - struct rte_flow_action_ipv6_ext_push conf; - uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; - uint8_t type; - uint16_t idx; -}; - -/** Storage for struct rte_flow_action_ipv6_ext_remove. */ -struct ipv6_ext_remove_conf { - struct rte_flow_action_ipv6_ext_remove conf; - uint8_t type; -}; - -struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; - -/** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ -struct action_ipv6_ext_remove_data { - struct rte_flow_action_ipv6_ext_remove conf; - uint8_t type; - uint16_t idx; -}; - -struct vxlan_encap_conf vxlan_encap_conf = { - .select_ipv4 = 1, - .select_vlan = 0, - .select_tos_ttl = 0, - .vni = { 0x00, 0x00, 0x00 }, - .udp_src = 0, - .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), - .ipv4_src = RTE_IPV4(127, 0, 0, 1), - .ipv4_dst = RTE_IPV4(255, 255, 255, 255), - .ipv6_src = RTE_IPV6_ADDR_LOOPBACK, - .ipv6_dst = RTE_IPV6(0, 0, 0, 0, 0, 0, 0, 0x1111), - .vlan_tci = 0, - .ip_tos = 0, - .ip_ttl = 255, - .eth_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .eth_dst = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, -}; - -/** Maximum number of items in struct rte_flow_action_vxlan_encap. */ -#define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 - -/** Storage for struct rte_flow_action_vxlan_encap including external data. */ -struct action_vxlan_encap_data { - struct rte_flow_action_vxlan_encap conf; - struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; - struct rte_flow_item_eth item_eth; - struct rte_flow_item_vlan item_vlan; - union { - struct rte_flow_item_ipv4 item_ipv4; - struct rte_flow_item_ipv6 item_ipv6; - }; - struct rte_flow_item_udp item_udp; - struct rte_flow_item_vxlan item_vxlan; -}; - -struct nvgre_encap_conf nvgre_encap_conf = { - .select_ipv4 = 1, - .select_vlan = 0, - .tni = { 0x00, 0x00, 0x00 }, - .ipv4_src = RTE_IPV4(127, 0, 0, 1), - .ipv4_dst = RTE_IPV4(255, 255, 255, 255), - .ipv6_src = RTE_IPV6_ADDR_LOOPBACK, - .ipv6_dst = RTE_IPV6(0, 0, 0, 0, 0, 0, 0, 0x1111), - .vlan_tci = 0, - .eth_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .eth_dst = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, -}; - -/** Maximum number of items in struct rte_flow_action_nvgre_encap. */ -#define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 - -/** Storage for struct rte_flow_action_nvgre_encap including external data. */ -struct action_nvgre_encap_data { - struct rte_flow_action_nvgre_encap conf; - struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; - struct rte_flow_item_eth item_eth; - struct rte_flow_item_vlan item_vlan; - union { - struct rte_flow_item_ipv4 item_ipv4; - struct rte_flow_item_ipv6 item_ipv6; - }; - struct rte_flow_item_nvgre item_nvgre; -}; - -struct l2_encap_conf l2_encap_conf; - -struct l2_decap_conf l2_decap_conf; - -struct mplsogre_encap_conf mplsogre_encap_conf; - -struct mplsogre_decap_conf mplsogre_decap_conf; - -struct mplsoudp_encap_conf mplsoudp_encap_conf; - -struct mplsoudp_decap_conf mplsoudp_decap_conf; - -struct rte_flow_action_conntrack conntrack_context; - -#define ACTION_SAMPLE_ACTIONS_NUM 10 -#define RAW_SAMPLE_CONFS_MAX_NUM 8 -/** Storage for struct rte_flow_action_sample including external data. */ -struct action_sample_data { - struct rte_flow_action_sample conf; - uint32_t idx; -}; -/** Storage for struct rte_flow_action_sample. */ -struct raw_sample_conf { - struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; -}; -struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; -struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; -struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; -struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; -struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; -struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; -struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; -struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; -struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; -struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; -struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; -struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; - -static const char *const modify_field_ops[] = { - "set", "add", "sub", NULL -}; - -static const char *const flow_field_ids[] = { - "start", "mac_dst", "mac_src", - "vlan_type", "vlan_id", "mac_type", - "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", - "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", - "tcp_port_src", "tcp_port_dst", - "tcp_seq_num", "tcp_ack_num", "tcp_flags", - "udp_port_src", "udp_port_dst", - "vxlan_vni", "geneve_vni", "gtp_teid", - "tag", "mark", "meta", "pointer", "value", - "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", - "ipv6_proto", - "flex_item", - "hash_result", - "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", - "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", - "ipv4_proto", - "ipv6_flow_label", "ipv6_traffic_class", - "esp_spi", "esp_seq_num", "esp_proto", - "random", - "vxlan_last_rsvd", - NULL -}; - -static const char *const meter_colors[] = { - "green", "yellow", "red", "all", NULL -}; - -static const char *const table_insertion_types[] = { - "pattern", "index", "index_with_pattern", NULL -}; - -static const char *const table_hash_funcs[] = { - "default", "linear", "crc32", "crc16", NULL -}; - -#define RAW_IPSEC_CONFS_MAX_NUM 8 - -/** Maximum number of subsequent tokens and arguments on the stack. */ -#define CTX_STACK_SIZE 16 - -/** Parser context. */ -struct context { - /** Stack of subsequent token lists to process. */ - const enum index *next[CTX_STACK_SIZE]; - /** Arguments for stacked tokens. */ - const void *args[CTX_STACK_SIZE]; - enum index curr; /**< Current token index. */ - enum index prev; /**< Index of the last token seen. */ - int next_num; /**< Number of entries in next[]. */ - int args_num; /**< Number of entries in args[]. */ - uint32_t eol:1; /**< EOL has been detected. */ - uint32_t last:1; /**< No more arguments. */ - portid_t port; /**< Current port ID (for completions). */ - uint32_t objdata; /**< Object-specific data. */ - void *object; /**< Address of current object for relative offsets. */ - void *objmask; /**< Object a full mask must be written to. */ -}; - -/** Token argument. */ -struct arg { - uint32_t hton:1; /**< Use network byte ordering. */ - uint32_t sign:1; /**< Value is signed. */ - uint32_t bounded:1; /**< Value is bounded. */ - uintmax_t min; /**< Minimum value if bounded. */ - uintmax_t max; /**< Maximum value if bounded. */ - uint32_t offset; /**< Relative offset from ctx->object. */ - uint32_t size; /**< Field size. */ - const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ -}; - -/** Parser token definition. */ -struct token { - /** Type displayed during completion (defaults to "TOKEN"). */ - const char *type; - /** Help displayed during completion (defaults to token name). */ - const char *help; - /** Private data used by parser functions. */ - const void *priv; - /** - * Lists of subsequent tokens to push on the stack. Each call to the - * parser consumes the last entry of that stack. - */ - const enum index *const *next; - /** Arguments stack for subsequent tokens that need them. */ - const struct arg *const *args; - /** - * Token-processing callback, returns -1 in case of error, the - * length of the matched string otherwise. If NULL, attempts to - * match the token name. - * - * If buf is not NULL, the result should be stored in it according - * to context. An error is returned if not large enough. - */ - int (*call)(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size); - /** - * Callback that provides possible values for this token, used for - * completion. Returns -1 in case of error, the number of possible - * values otherwise. If NULL, the token name is used. - * - * If buf is not NULL, entry index ent is written to buf and the - * full length of the entry is returned (same behavior as - * snprintf()). - */ - int (*comp)(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size); - /** Mandatory token name, no default value. */ - const char *name; -}; - -/** Static initializer for the next field. */ -#define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } - -/** Static initializer for a NEXT() entry. */ -#define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } - -/** Static initializer for the args field. */ -#define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } - -/** Static initializer for ARGS() to target a field. */ -#define ARGS_ENTRY(s, f) \ - (&(const struct arg){ \ - .offset = offsetof(s, f), \ - .size = sizeof(((s *)0)->f), \ - }) - -/** Static initializer for ARGS() to target a bit-field. */ -#define ARGS_ENTRY_BF(s, f, b) \ - (&(const struct arg){ \ - .size = sizeof(s), \ - .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ - }) - -/** Static initializer for ARGS() to target a field with limits. */ -#define ARGS_ENTRY_BOUNDED(s, f, i, a) \ - (&(const struct arg){ \ - .bounded = 1, \ - .min = (i), \ - .max = (a), \ - .offset = offsetof(s, f), \ - .size = sizeof(((s *)0)->f), \ - }) - -/** Static initializer for ARGS() to target an arbitrary bit-mask. */ -#define ARGS_ENTRY_MASK(s, f, m) \ - (&(const struct arg){ \ - .offset = offsetof(s, f), \ - .size = sizeof(((s *)0)->f), \ - .mask = (const void *)(m), \ - }) - -/** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ -#define ARGS_ENTRY_MASK_HTON(s, f, m) \ - (&(const struct arg){ \ - .hton = 1, \ - .offset = offsetof(s, f), \ - .size = sizeof(((s *)0)->f), \ - .mask = (const void *)(m), \ - }) - -/** Static initializer for ARGS() to target a pointer. */ -#define ARGS_ENTRY_PTR(s, f) \ - (&(const struct arg){ \ - .size = sizeof(*((s *)0)->f), \ - }) - -/** Static initializer for ARGS() with arbitrary offset and size. */ -#define ARGS_ENTRY_ARB(o, s) \ - (&(const struct arg){ \ - .offset = (o), \ - .size = (s), \ - }) - -/** Same as ARGS_ENTRY_ARB() with bounded values. */ -#define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ - (&(const struct arg){ \ - .bounded = 1, \ - .min = (i), \ - .max = (a), \ - .offset = (o), \ - .size = (s), \ - }) - -/** Same as ARGS_ENTRY() using network byte ordering. */ -#define ARGS_ENTRY_HTON(s, f) \ - (&(const struct arg){ \ - .hton = 1, \ - .offset = offsetof(s, f), \ - .size = sizeof(((s *)0)->f), \ - }) - -/** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ -#define ARG_ENTRY_HTON(s) \ - (&(const struct arg){ \ - .hton = 1, \ - .offset = 0, \ - .size = sizeof(s), \ - }) - -/** Parser output buffer layout expected by cmd_flow_parsed(). */ -struct buffer { - enum index command; /**< Flow command. */ - portid_t port; /**< Affected port ID. */ - queueid_t queue; /** Async queue ID. */ - bool postpone; /** Postpone async operation */ - union { - struct { - struct rte_flow_port_attr port_attr; - uint32_t nb_queue; - struct rte_flow_queue_attr queue_attr; - } configure; /**< Configuration arguments. */ - struct { - uint32_t *template_id; - uint32_t template_id_n; - } templ_destroy; /**< Template destroy arguments. */ - struct { - uint32_t id; - struct rte_flow_template_table_attr attr; - uint32_t *pat_templ_id; - uint32_t pat_templ_id_n; - uint32_t *act_templ_id; - uint32_t act_templ_id_n; - } table; /**< Table arguments. */ - struct { - uint32_t *table_id; - uint32_t table_id_n; - } table_destroy; /**< Template destroy arguments. */ - struct { - uint32_t *action_id; - uint32_t action_id_n; - } ia_destroy; /**< Indirect action destroy arguments. */ - struct { - uint32_t action_id; - enum rte_flow_query_update_mode qu_mode; - } ia; /* Indirect action query arguments */ - struct { - uint32_t table_id; - uint32_t pat_templ_id; - uint32_t rule_id; - uint32_t act_templ_id; - struct rte_flow_attr attr; - struct tunnel_ops tunnel_ops; - uintptr_t user_id; - struct rte_flow_item *pattern; - struct rte_flow_action *actions; - struct rte_flow_action *masks; - uint32_t pattern_n; - uint32_t actions_n; - uint8_t *data; - enum rte_flow_encap_hash_field field; - uint8_t encap_hash; - } vc; /**< Validate/create arguments. */ - struct { - uint64_t *rule; - uint64_t rule_n; - bool is_user_id; - } destroy; /**< Destroy arguments. */ - struct { - char file[128]; - bool mode; - uint64_t rule; - bool is_user_id; - } dump; /**< Dump arguments. */ - struct { - uint64_t rule; - struct rte_flow_action action; - bool is_user_id; - } query; /**< Query arguments. */ - struct { - uint32_t *group; - uint32_t group_n; - } list; /**< List arguments. */ - struct { - int set; - } isolate; /**< Isolated mode arguments. */ - struct { - int destroy; - } aged; /**< Aged arguments. */ - struct { - uint32_t policy_id; - } policy;/**< Policy arguments. */ - struct { - uint16_t token; - uintptr_t uintptr; - char filename[128]; - } flex; /**< Flex arguments*/ - } args; /**< Command arguments. */ -}; - -/** Private data for pattern items. */ -struct parse_item_priv { - enum rte_flow_item_type type; /**< Item type. */ - uint32_t size; /**< Size of item specification structure. */ -}; - -#define PRIV_ITEM(t, s) \ - (&(const struct parse_item_priv){ \ - .type = RTE_FLOW_ITEM_TYPE_ ## t, \ - .size = s, \ - }) - -/** Private data for actions. */ -struct parse_action_priv { - enum rte_flow_action_type type; /**< Action type. */ - uint32_t size; /**< Size of action configuration structure. */ -}; - -#define PRIV_ACTION(t, s) \ - (&(const struct parse_action_priv){ \ - .type = RTE_FLOW_ACTION_TYPE_ ## t, \ - .size = s, \ - }) - -static const enum index next_flex_item[] = { - FLEX_ITEM_CREATE, - FLEX_ITEM_DESTROY, - ZERO, -}; - -static const enum index next_config_attr[] = { - CONFIG_QUEUES_NUMBER, - CONFIG_QUEUES_SIZE, - CONFIG_COUNTERS_NUMBER, - CONFIG_AGING_OBJECTS_NUMBER, - CONFIG_METERS_NUMBER, - CONFIG_CONN_TRACK_NUMBER, - CONFIG_QUOTAS_NUMBER, - CONFIG_FLAGS, - CONFIG_HOST_PORT, - END, - ZERO, -}; - -static const enum index next_pt_subcmd[] = { - PATTERN_TEMPLATE_CREATE, - PATTERN_TEMPLATE_DESTROY, - ZERO, -}; - -static const enum index next_pt_attr[] = { - PATTERN_TEMPLATE_CREATE_ID, - PATTERN_TEMPLATE_RELAXED_MATCHING, - PATTERN_TEMPLATE_INGRESS, - PATTERN_TEMPLATE_EGRESS, - PATTERN_TEMPLATE_TRANSFER, - PATTERN_TEMPLATE_SPEC, - ZERO, -}; - -static const enum index next_pt_destroy_attr[] = { - PATTERN_TEMPLATE_DESTROY_ID, - END, - ZERO, -}; - -static const enum index next_at_subcmd[] = { - ACTIONS_TEMPLATE_CREATE, - ACTIONS_TEMPLATE_DESTROY, - ZERO, -}; - -static const enum index next_at_attr[] = { - ACTIONS_TEMPLATE_CREATE_ID, - ACTIONS_TEMPLATE_INGRESS, - ACTIONS_TEMPLATE_EGRESS, - ACTIONS_TEMPLATE_TRANSFER, - ACTIONS_TEMPLATE_SPEC, - ZERO, -}; - -static const enum index next_at_destroy_attr[] = { - ACTIONS_TEMPLATE_DESTROY_ID, - END, - ZERO, -}; - -static const enum index next_group_attr[] = { - GROUP_INGRESS, - GROUP_EGRESS, - GROUP_TRANSFER, - GROUP_SET_MISS_ACTIONS, - ZERO, -}; - -static const enum index next_table_subcmd[] = { - TABLE_CREATE, - TABLE_DESTROY, - TABLE_RESIZE, - TABLE_RESIZE_COMPLETE, - ZERO, -}; - -static const enum index next_table_attr[] = { - TABLE_CREATE_ID, - TABLE_GROUP, - TABLE_INSERTION_TYPE, - TABLE_HASH_FUNC, - TABLE_PRIORITY, - TABLE_INGRESS, - TABLE_EGRESS, - TABLE_TRANSFER, - TABLE_TRANSFER_WIRE_ORIG, - TABLE_TRANSFER_VPORT_ORIG, - TABLE_RESIZABLE, - TABLE_RULES_NUMBER, - TABLE_PATTERN_TEMPLATE, - TABLE_ACTIONS_TEMPLATE, - END, - ZERO, -}; - -static const enum index next_table_destroy_attr[] = { - TABLE_DESTROY_ID, - END, - ZERO, -}; - -static const enum index next_queue_subcmd[] = { - QUEUE_CREATE, - QUEUE_DESTROY, - QUEUE_FLOW_UPDATE_RESIZED, - QUEUE_UPDATE, - QUEUE_AGED, - QUEUE_INDIRECT_ACTION, - ZERO, -}; - -static const enum index next_queue_destroy_attr[] = { - QUEUE_DESTROY_ID, - END, - ZERO, -}; - -static const enum index next_qia_subcmd[] = { - QUEUE_INDIRECT_ACTION_CREATE, - QUEUE_INDIRECT_ACTION_UPDATE, - QUEUE_INDIRECT_ACTION_DESTROY, - QUEUE_INDIRECT_ACTION_QUERY, - QUEUE_INDIRECT_ACTION_QUERY_UPDATE, - ZERO, -}; - -static const enum index next_qia_create_attr[] = { - QUEUE_INDIRECT_ACTION_CREATE_ID, - QUEUE_INDIRECT_ACTION_INGRESS, - QUEUE_INDIRECT_ACTION_EGRESS, - QUEUE_INDIRECT_ACTION_TRANSFER, - QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, - QUEUE_INDIRECT_ACTION_SPEC, - QUEUE_INDIRECT_ACTION_LIST, - ZERO, -}; - -static const enum index next_qia_update_attr[] = { - QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, - QUEUE_INDIRECT_ACTION_SPEC, - ZERO, -}; - -static const enum index next_qia_destroy_attr[] = { - QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, - QUEUE_INDIRECT_ACTION_DESTROY_ID, - END, - ZERO, -}; - -static const enum index next_qia_query_attr[] = { - QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, - END, - ZERO, -}; - -static const enum index next_ia_create_attr[] = { - INDIRECT_ACTION_CREATE_ID, - INDIRECT_ACTION_INGRESS, - INDIRECT_ACTION_EGRESS, - INDIRECT_ACTION_TRANSFER, - INDIRECT_ACTION_SPEC, - INDIRECT_ACTION_LIST, - INDIRECT_ACTION_FLOW_CONF, - ZERO, -}; - -static const enum index next_ia[] = { - INDIRECT_ACTION_ID2PTR, - ACTION_NEXT, - 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, - INDIRECT_ACTION_SPEC, - ZERO -}; - -static const enum index next_ia_qu_attr[] = { - INDIRECT_ACTION_QU_MODE, - INDIRECT_ACTION_SPEC, - ZERO -}; - -static const enum index next_dump_subcmd[] = { - DUMP_ALL, - DUMP_ONE, - DUMP_IS_USER_ID, - ZERO, -}; - -static const enum index next_ia_subcmd[] = { - INDIRECT_ACTION_CREATE, - INDIRECT_ACTION_UPDATE, - INDIRECT_ACTION_DESTROY, - INDIRECT_ACTION_QUERY, - INDIRECT_ACTION_QUERY_UPDATE, - ZERO, -}; - -static const enum index next_vc_attr[] = { - VC_GROUP, - VC_PRIORITY, - VC_INGRESS, - VC_EGRESS, - VC_TRANSFER, - VC_TUNNEL_SET, - VC_TUNNEL_MATCH, - VC_USER_ID, - ITEM_PATTERN, - ZERO, -}; - -static const enum index next_destroy_attr[] = { - DESTROY_RULE, - DESTROY_IS_USER_ID, - END, - ZERO, -}; - -static const enum index next_dump_attr[] = { - COMMON_FILE_PATH, - END, - ZERO, -}; - -static const enum index next_query_attr[] = { - QUERY_IS_USER_ID, - 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 next_ia_destroy_attr[] = { - INDIRECT_ACTION_DESTROY_ID, - END, - ZERO, -}; - -static const enum index next_async_insert_subcmd[] = { - QUEUE_PATTERN_TEMPLATE, - QUEUE_RULE_ID, - ZERO, -}; - -static const enum index next_async_pattern_subcmd[] = { - QUEUE_PATTERN_TEMPLATE, - QUEUE_ACTIONS_TEMPLATE, - ZERO, -}; - -static const enum index item_param[] = { - ITEM_PARAM_IS, - ITEM_PARAM_SPEC, - ITEM_PARAM_LAST, - ITEM_PARAM_MASK, - ITEM_PARAM_PREFIX, - ZERO, -}; - -static const enum index next_item[] = { - ITEM_END, - ITEM_VOID, - ITEM_INVERT, - ITEM_ANY, - ITEM_PORT_ID, - ITEM_MARK, - ITEM_RAW, - ITEM_ETH, - ITEM_VLAN, - ITEM_IPV4, - ITEM_IPV6, - ITEM_ICMP, - ITEM_UDP, - ITEM_TCP, - ITEM_SCTP, - ITEM_VXLAN, - ITEM_E_TAG, - ITEM_NVGRE, - ITEM_MPLS, - ITEM_GRE, - ITEM_FUZZY, - ITEM_GTP, - ITEM_GTPC, - ITEM_GTPU, - ITEM_GENEVE, - ITEM_VXLAN_GPE, - ITEM_ARP_ETH_IPV4, - ITEM_IPV6_EXT, - ITEM_IPV6_FRAG_EXT, - ITEM_IPV6_ROUTING_EXT, - ITEM_ICMP6, - ITEM_ICMP6_ECHO_REQUEST, - ITEM_ICMP6_ECHO_REPLY, - ITEM_ICMP6_ND_NS, - ITEM_ICMP6_ND_NA, - ITEM_ICMP6_ND_OPT, - ITEM_ICMP6_ND_OPT_SLA_ETH, - ITEM_ICMP6_ND_OPT_TLA_ETH, - ITEM_META, - ITEM_RANDOM, - ITEM_GRE_KEY, - ITEM_GRE_OPTION, - ITEM_GTP_PSC, - ITEM_PPPOES, - ITEM_PPPOED, - ITEM_PPPOE_PROTO_ID, - ITEM_HIGIG2, - ITEM_TAG, - ITEM_L2TPV3OIP, - ITEM_ESP, - ITEM_AH, - ITEM_PFCP, - ITEM_ECPRI, - ITEM_GENEVE_OPT, - ITEM_INTEGRITY, - ITEM_CONNTRACK, - ITEM_PORT_REPRESENTOR, - ITEM_REPRESENTED_PORT, - ITEM_FLEX, - ITEM_L2TPV2, - ITEM_PPP, - ITEM_METER, - ITEM_QUOTA, - ITEM_AGGR_AFFINITY, - ITEM_TX_QUEUE, - ITEM_IB_BTH, - ITEM_PTYPE, - ITEM_NSH, - ITEM_COMPARE, - END_SET, - ZERO, -}; - -static const enum index item_fuzzy[] = { - ITEM_FUZZY_THRESH, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_any[] = { - ITEM_ANY_NUM, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_port_id[] = { - ITEM_PORT_ID_ID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_mark[] = { - ITEM_MARK_ID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_raw[] = { - ITEM_RAW_RELATIVE, - ITEM_RAW_SEARCH, - ITEM_RAW_OFFSET, - ITEM_RAW_LIMIT, - ITEM_RAW_PATTERN, - ITEM_RAW_PATTERN_HEX, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_eth[] = { - ITEM_ETH_DST, - ITEM_ETH_SRC, - ITEM_ETH_TYPE, - ITEM_ETH_HAS_VLAN, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_vlan[] = { - ITEM_VLAN_TCI, - ITEM_VLAN_PCP, - ITEM_VLAN_DEI, - ITEM_VLAN_VID, - ITEM_VLAN_INNER_TYPE, - ITEM_VLAN_HAS_MORE_VLAN, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_ipv4[] = { - ITEM_IPV4_VER_IHL, - ITEM_IPV4_TOS, - ITEM_IPV4_LENGTH, - ITEM_IPV4_ID, - ITEM_IPV4_FRAGMENT_OFFSET, - ITEM_IPV4_TTL, - ITEM_IPV4_PROTO, - ITEM_IPV4_SRC, - ITEM_IPV4_DST, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_ipv6[] = { - ITEM_IPV6_TC, - ITEM_IPV6_FLOW, - ITEM_IPV6_LEN, - ITEM_IPV6_PROTO, - ITEM_IPV6_HOP, - ITEM_IPV6_SRC, - ITEM_IPV6_DST, - ITEM_IPV6_HAS_FRAG_EXT, - ITEM_IPV6_ROUTING_EXT, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_ipv6_routing_ext[] = { - ITEM_IPV6_ROUTING_EXT_TYPE, - ITEM_IPV6_ROUTING_EXT_NEXT_HDR, - ITEM_IPV6_ROUTING_EXT_SEG_LEFT, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_icmp[] = { - ITEM_ICMP_TYPE, - ITEM_ICMP_CODE, - ITEM_ICMP_IDENT, - ITEM_ICMP_SEQ, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_udp[] = { - ITEM_UDP_SRC, - ITEM_UDP_DST, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_tcp[] = { - ITEM_TCP_SRC, - ITEM_TCP_DST, - ITEM_TCP_FLAGS, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_sctp[] = { - ITEM_SCTP_SRC, - ITEM_SCTP_DST, - ITEM_SCTP_TAG, - ITEM_SCTP_CKSUM, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_vxlan[] = { - ITEM_VXLAN_VNI, - ITEM_VXLAN_FLAG_G, - ITEM_VXLAN_FLAG_VER, - ITEM_VXLAN_FLAG_I, - ITEM_VXLAN_FLAG_P, - ITEM_VXLAN_FLAG_B, - ITEM_VXLAN_FLAG_O, - ITEM_VXLAN_FLAG_D, - ITEM_VXLAN_FLAG_A, - ITEM_VXLAN_GBP_ID, - ITEM_VXLAN_GPE_PROTO, - ITEM_VXLAN_FIRST_RSVD, - ITEM_VXLAN_SECND_RSVD, - ITEM_VXLAN_THIRD_RSVD, - ITEM_VXLAN_LAST_RSVD, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_e_tag[] = { - ITEM_E_TAG_GRP_ECID_B, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_nvgre[] = { - ITEM_NVGRE_TNI, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_mpls[] = { - ITEM_MPLS_LABEL, - ITEM_MPLS_TC, - ITEM_MPLS_S, - ITEM_MPLS_TTL, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_gre[] = { - ITEM_GRE_PROTO, - ITEM_GRE_C_RSVD0_VER, - ITEM_GRE_C_BIT, - ITEM_GRE_K_BIT, - ITEM_GRE_S_BIT, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_gre_key[] = { - ITEM_GRE_KEY_VALUE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_gre_option[] = { - ITEM_GRE_OPTION_CHECKSUM, - ITEM_GRE_OPTION_KEY, - ITEM_GRE_OPTION_SEQUENCE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_gtp[] = { - ITEM_GTP_FLAGS, - ITEM_GTP_MSG_TYPE, - ITEM_GTP_TEID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_geneve[] = { - ITEM_GENEVE_VNI, - ITEM_GENEVE_PROTO, - ITEM_GENEVE_OPTLEN, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_vxlan_gpe[] = { - ITEM_VXLAN_GPE_VNI, - ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR, - ITEM_VXLAN_GPE_FLAGS, - ITEM_VXLAN_GPE_RSVD0, - ITEM_VXLAN_GPE_RSVD1, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_arp_eth_ipv4[] = { - ITEM_ARP_ETH_IPV4_SHA, - ITEM_ARP_ETH_IPV4_SPA, - ITEM_ARP_ETH_IPV4_THA, - ITEM_ARP_ETH_IPV4_TPA, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_ipv6_ext[] = { - ITEM_IPV6_EXT_NEXT_HDR, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_ipv6_frag_ext[] = { - ITEM_IPV6_FRAG_EXT_NEXT_HDR, - ITEM_IPV6_FRAG_EXT_FRAG_DATA, - ITEM_IPV6_FRAG_EXT_ID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_icmp6[] = { - ITEM_ICMP6_TYPE, - ITEM_ICMP6_CODE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_icmp6_echo_request[] = { - ITEM_ICMP6_ECHO_REQUEST_ID, - ITEM_ICMP6_ECHO_REQUEST_SEQ, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_icmp6_echo_reply[] = { - ITEM_ICMP6_ECHO_REPLY_ID, - ITEM_ICMP6_ECHO_REPLY_SEQ, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_icmp6_nd_ns[] = { - ITEM_ICMP6_ND_NS_TARGET_ADDR, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_icmp6_nd_na[] = { - ITEM_ICMP6_ND_NA_TARGET_ADDR, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_icmp6_nd_opt[] = { - ITEM_ICMP6_ND_OPT_TYPE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_icmp6_nd_opt_sla_eth[] = { - ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_icmp6_nd_opt_tla_eth[] = { - ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_meta[] = { - ITEM_META_DATA, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_random[] = { - ITEM_RANDOM_VALUE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_gtp_psc[] = { - ITEM_GTP_PSC_QFI, - ITEM_GTP_PSC_PDU_T, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_pppoed[] = { - ITEM_PPPOE_SEID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_pppoes[] = { - ITEM_PPPOE_SEID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_pppoe_proto_id[] = { - ITEM_NEXT, - ZERO, -}; - -static const enum index item_higig2[] = { - ITEM_HIGIG2_CLASSIFICATION, - ITEM_HIGIG2_VID, - ITEM_NEXT, - 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, - ZERO, -}; - -static const enum index item_tag[] = { - ITEM_TAG_DATA, - ITEM_TAG_INDEX, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_l2tpv3oip[] = { - ITEM_L2TPV3OIP_SESSION_ID, - ITEM_NEXT, - 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 item_geneve_opt[] = { - ITEM_GENEVE_OPT_CLASS, - ITEM_GENEVE_OPT_TYPE, - ITEM_GENEVE_OPT_LENGTH, - ITEM_GENEVE_OPT_DATA, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_integrity[] = { - ITEM_INTEGRITY_LEVEL, - ITEM_INTEGRITY_VALUE, - ZERO, -}; - -static const enum index item_integrity_lv[] = { - ITEM_INTEGRITY_LEVEL, - ITEM_INTEGRITY_VALUE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_port_representor[] = { - ITEM_PORT_REPRESENTOR_PORT_ID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_represented_port[] = { - ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_flex[] = { - ITEM_FLEX_PATTERN_HANDLE, - ITEM_FLEX_ITEM_HANDLE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_l2tpv2[] = { - ITEM_L2TPV2_TYPE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_l2tpv2_type[] = { - ITEM_L2TPV2_TYPE_DATA, - ITEM_L2TPV2_TYPE_DATA_L, - ITEM_L2TPV2_TYPE_DATA_S, - ITEM_L2TPV2_TYPE_DATA_O, - ITEM_L2TPV2_TYPE_DATA_L_S, - ITEM_L2TPV2_TYPE_CTRL, - ZERO, -}; - -static const enum index item_l2tpv2_type_data[] = { - ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, - ITEM_L2TPV2_MSG_DATA_SESSION_ID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_l2tpv2_type_data_l[] = { - ITEM_L2TPV2_MSG_DATA_L_LENGTH, - ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, - ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_l2tpv2_type_data_s[] = { - ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, - ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, - ITEM_L2TPV2_MSG_DATA_S_NS, - ITEM_L2TPV2_MSG_DATA_S_NR, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_l2tpv2_type_data_o[] = { - ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, - ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, - ITEM_L2TPV2_MSG_DATA_O_OFFSET, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_l2tpv2_type_data_l_s[] = { - ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, - ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, - ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, - ITEM_L2TPV2_MSG_DATA_L_S_NS, - ITEM_L2TPV2_MSG_DATA_L_S_NR, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_l2tpv2_type_ctrl[] = { - ITEM_L2TPV2_MSG_CTRL_LENGTH, - ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, - ITEM_L2TPV2_MSG_CTRL_SESSION_ID, - ITEM_L2TPV2_MSG_CTRL_NS, - ITEM_L2TPV2_MSG_CTRL_NR, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_ppp[] = { - ITEM_PPP_ADDR, - ITEM_PPP_CTRL, - ITEM_PPP_PROTO_ID, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_meter[] = { - ITEM_METER_COLOR, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_quota[] = { - ITEM_QUOTA_STATE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_aggr_affinity[] = { - ITEM_AGGR_AFFINITY_VALUE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_tx_queue[] = { - ITEM_TX_QUEUE_VALUE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_ib_bth[] = { - ITEM_IB_BTH_OPCODE, - ITEM_IB_BTH_PKEY, - ITEM_IB_BTH_DST_QPN, - ITEM_IB_BTH_PSN, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_ptype[] = { - ITEM_PTYPE_VALUE, - ITEM_NEXT, - ZERO, -}; - -static const enum index item_nsh[] = { - ITEM_NEXT, - ZERO, -}; - -static const enum index item_compare_field[] = { - ITEM_COMPARE_OP, - ITEM_COMPARE_FIELD_A_TYPE, - ITEM_COMPARE_FIELD_B_TYPE, - ITEM_NEXT, - ZERO, -}; - -static const enum index compare_field_a[] = { - ITEM_COMPARE_FIELD_A_TYPE, - ITEM_COMPARE_FIELD_A_LEVEL, - ITEM_COMPARE_FIELD_A_TAG_INDEX, - ITEM_COMPARE_FIELD_A_TYPE_ID, - ITEM_COMPARE_FIELD_A_CLASS_ID, - ITEM_COMPARE_FIELD_A_OFFSET, - ITEM_COMPARE_FIELD_B_TYPE, - ZERO, -}; - -static const enum index compare_field_b[] = { - ITEM_COMPARE_FIELD_B_TYPE, - ITEM_COMPARE_FIELD_B_LEVEL, - ITEM_COMPARE_FIELD_B_TAG_INDEX, - ITEM_COMPARE_FIELD_B_TYPE_ID, - ITEM_COMPARE_FIELD_B_CLASS_ID, - ITEM_COMPARE_FIELD_B_OFFSET, - ITEM_COMPARE_FIELD_B_VALUE, - ITEM_COMPARE_FIELD_B_POINTER, - ITEM_COMPARE_FIELD_WIDTH, - ZERO, -}; - -static const enum index next_action[] = { - ACTION_END, - ACTION_VOID, - ACTION_PASSTHRU, - ACTION_SKIP_CMAN, - ACTION_JUMP, - ACTION_MARK, - ACTION_FLAG, - ACTION_QUEUE, - ACTION_DROP, - ACTION_COUNT, - ACTION_RSS, - ACTION_PF, - ACTION_VF, - ACTION_PORT_ID, - ACTION_METER, - ACTION_METER_COLOR, - ACTION_METER_MARK, - ACTION_METER_MARK_CONF, - ACTION_OF_DEC_NW_TTL, - ACTION_OF_POP_VLAN, - ACTION_OF_PUSH_VLAN, - ACTION_OF_SET_VLAN_VID, - ACTION_OF_SET_VLAN_PCP, - ACTION_OF_POP_MPLS, - ACTION_OF_PUSH_MPLS, - ACTION_VXLAN_ENCAP, - ACTION_VXLAN_DECAP, - ACTION_NVGRE_ENCAP, - ACTION_NVGRE_DECAP, - ACTION_L2_ENCAP, - ACTION_L2_DECAP, - ACTION_MPLSOGRE_ENCAP, - ACTION_MPLSOGRE_DECAP, - ACTION_MPLSOUDP_ENCAP, - ACTION_MPLSOUDP_DECAP, - ACTION_SET_IPV4_SRC, - ACTION_SET_IPV4_DST, - ACTION_SET_IPV6_SRC, - ACTION_SET_IPV6_DST, - ACTION_SET_TP_SRC, - ACTION_SET_TP_DST, - ACTION_MAC_SWAP, - ACTION_DEC_TTL, - ACTION_SET_TTL, - ACTION_SET_MAC_SRC, - ACTION_SET_MAC_DST, - ACTION_INC_TCP_SEQ, - ACTION_DEC_TCP_SEQ, - ACTION_INC_TCP_ACK, - ACTION_DEC_TCP_ACK, - ACTION_RAW_ENCAP, - ACTION_RAW_DECAP, - ACTION_SET_TAG, - ACTION_SET_META, - ACTION_SET_IPV4_DSCP, - ACTION_SET_IPV6_DSCP, - ACTION_AGE, - ACTION_AGE_UPDATE, - ACTION_SAMPLE, - ACTION_INDIRECT, - ACTION_INDIRECT_LIST, - ACTION_SHARED_INDIRECT, - ACTION_MODIFY_FIELD, - ACTION_CONNTRACK, - ACTION_CONNTRACK_UPDATE, - ACTION_PORT_REPRESENTOR, - ACTION_REPRESENTED_PORT, - ACTION_SEND_TO_KERNEL, - ACTION_QUOTA_CREATE, - ACTION_QUOTA_QU, - ACTION_IPV6_EXT_REMOVE, - ACTION_IPV6_EXT_PUSH, - ACTION_NAT64, - ACTION_JUMP_TO_TABLE_INDEX, - ZERO, -}; - -static const enum index action_quota_create[] = { - ACTION_QUOTA_CREATE_LIMIT, - ACTION_QUOTA_CREATE_MODE, - ACTION_NEXT, - ZERO -}; - -static const enum index action_quota_update[] = { - ACTION_QUOTA_QU_LIMIT, - ACTION_QUOTA_QU_UPDATE_OP, - ACTION_NEXT, - ZERO -}; - -static const enum index action_mark[] = { - ACTION_MARK_ID, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_queue[] = { - ACTION_QUEUE_INDEX, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_count[] = { - ACTION_COUNT_ID, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_rss[] = { - ACTION_RSS_FUNC, - ACTION_RSS_LEVEL, - ACTION_RSS_TYPES, - ACTION_RSS_KEY, - ACTION_RSS_KEY_LEN, - ACTION_RSS_QUEUES, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_vf[] = { - ACTION_VF_ORIGINAL, - ACTION_VF_ID, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_port_id[] = { - ACTION_PORT_ID_ORIGINAL, - ACTION_PORT_ID_ID, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_meter[] = { - ACTION_METER_ID, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_meter_color[] = { - ACTION_METER_COLOR_TYPE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_meter_mark[] = { - ACTION_METER_PROFILE, - ACTION_METER_POLICY, - ACTION_METER_COLOR_MODE, - ACTION_METER_STATE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_of_push_vlan[] = { - ACTION_OF_PUSH_VLAN_ETHERTYPE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_of_set_vlan_vid[] = { - ACTION_OF_SET_VLAN_VID_VLAN_VID, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_of_set_vlan_pcp[] = { - ACTION_OF_SET_VLAN_PCP_VLAN_PCP, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_of_pop_mpls[] = { - ACTION_OF_POP_MPLS_ETHERTYPE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_of_push_mpls[] = { - ACTION_OF_PUSH_MPLS_ETHERTYPE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_ipv4_src[] = { - ACTION_SET_IPV4_SRC_IPV4_SRC, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_mac_src[] = { - ACTION_SET_MAC_SRC_MAC_SRC, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_ipv4_dst[] = { - ACTION_SET_IPV4_DST_IPV4_DST, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_ipv6_src[] = { - ACTION_SET_IPV6_SRC_IPV6_SRC, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_ipv6_dst[] = { - ACTION_SET_IPV6_DST_IPV6_DST, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_tp_src[] = { - ACTION_SET_TP_SRC_TP_SRC, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_tp_dst[] = { - ACTION_SET_TP_DST_TP_DST, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_ttl[] = { - ACTION_SET_TTL_TTL, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_jump[] = { - ACTION_JUMP_GROUP, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_mac_dst[] = { - ACTION_SET_MAC_DST_MAC_DST, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_inc_tcp_seq[] = { - ACTION_INC_TCP_SEQ_VALUE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_dec_tcp_seq[] = { - ACTION_DEC_TCP_SEQ_VALUE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_inc_tcp_ack[] = { - ACTION_INC_TCP_ACK_VALUE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_dec_tcp_ack[] = { - ACTION_DEC_TCP_ACK_VALUE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_raw_encap[] = { - ACTION_RAW_ENCAP_SIZE, - ACTION_RAW_ENCAP_INDEX, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_raw_decap[] = { - ACTION_RAW_DECAP_INDEX, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_ipv6_ext_remove[] = { - ACTION_IPV6_EXT_REMOVE_INDEX, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_ipv6_ext_push[] = { - ACTION_IPV6_EXT_PUSH_INDEX, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_tag[] = { - ACTION_SET_TAG_DATA, - ACTION_SET_TAG_INDEX, - ACTION_SET_TAG_MASK, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_meta[] = { - ACTION_SET_META_DATA, - ACTION_SET_META_MASK, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_ipv4_dscp[] = { - ACTION_SET_IPV4_DSCP_VALUE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_set_ipv6_dscp[] = { - ACTION_SET_IPV6_DSCP_VALUE, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_age[] = { - ACTION_AGE, - ACTION_AGE_TIMEOUT, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_age_update[] = { - ACTION_AGE_UPDATE, - ACTION_AGE_UPDATE_TIMEOUT, - ACTION_AGE_UPDATE_TOUCH, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_sample[] = { - ACTION_SAMPLE, - ACTION_SAMPLE_RATIO, - ACTION_SAMPLE_INDEX, - ACTION_NEXT, - ZERO, -}; - -static const enum index next_action_sample[] = { - ACTION_QUEUE, - ACTION_RSS, - ACTION_MARK, - ACTION_COUNT, - ACTION_PORT_ID, - ACTION_RAW_ENCAP, - ACTION_VXLAN_ENCAP, - ACTION_NVGRE_ENCAP, - ACTION_REPRESENTED_PORT, - ACTION_PORT_REPRESENTOR, - ACTION_NEXT, - ZERO, -}; - -static const enum index item_ipv6_push_ext[] = { - ITEM_IPV6_PUSH_REMOVE_EXT, - ZERO, -}; - -static const enum index item_ipv6_push_ext_type[] = { - ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, - ZERO, -}; - -static const enum index item_ipv6_push_ext_header[] = { - ITEM_IPV6_ROUTING_EXT, - ITEM_NEXT, - ZERO, -}; - -static const enum index action_modify_field_dst[] = { - ACTION_MODIFY_FIELD_DST_LEVEL, - ACTION_MODIFY_FIELD_DST_TAG_INDEX, - ACTION_MODIFY_FIELD_DST_TYPE_ID, - ACTION_MODIFY_FIELD_DST_CLASS_ID, - ACTION_MODIFY_FIELD_DST_OFFSET, - ACTION_MODIFY_FIELD_SRC_TYPE, - ZERO, -}; - -static const enum index action_modify_field_src[] = { - ACTION_MODIFY_FIELD_SRC_LEVEL, - ACTION_MODIFY_FIELD_SRC_TAG_INDEX, - ACTION_MODIFY_FIELD_SRC_TYPE_ID, - ACTION_MODIFY_FIELD_SRC_CLASS_ID, - ACTION_MODIFY_FIELD_SRC_OFFSET, - ACTION_MODIFY_FIELD_SRC_VALUE, - ACTION_MODIFY_FIELD_SRC_POINTER, - ACTION_MODIFY_FIELD_WIDTH, - ZERO, -}; - -static const enum index action_update_conntrack[] = { - ACTION_CONNTRACK_UPDATE_DIR, - ACTION_CONNTRACK_UPDATE_CTX, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_port_representor[] = { - ACTION_PORT_REPRESENTOR_PORT_ID, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_represented_port[] = { - ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, - ACTION_NEXT, - ZERO, -}; - -static const enum index action_nat64[] = { - ACTION_NAT64_MODE, - ACTION_NEXT, - ZERO, -}; - -static const enum index next_hash_subcmd[] = { - HASH_CALC_TABLE, - HASH_CALC_ENCAP, - ZERO, -}; - -static const enum index next_hash_encap_dest_subcmd[] = { - ENCAP_HASH_FIELD_SRC_PORT, - ENCAP_HASH_FIELD_GRE_FLOW_ID, - ZERO, -}; - -static const enum index action_jump_to_table_index[] = { - ACTION_JUMP_TO_TABLE_INDEX_TABLE, - ACTION_JUMP_TO_TABLE_INDEX_INDEX, - ACTION_NEXT, - ZERO, -}; - -static int parse_set_raw_encap_decap(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_set_sample_action(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_set_ipv6_ext_action(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_set_init(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int -parse_flex_handle(struct context *, const struct token *, - const char *, unsigned int, void *, unsigned int); -static int parse_init(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_vc(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -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_conf_timeout(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_item_l2tpv2_type(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_vc_action_meter_color_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); -static int parse_vc_action_rss_func(struct context *, const struct token *, - const char *, unsigned int, void *, - unsigned int); -static int parse_vc_action_rss_type(struct context *, const struct token *, - const char *, unsigned int, void *, - unsigned int); -static int parse_vc_action_rss_queue(struct context *, const struct token *, - const char *, unsigned int, void *, - unsigned int); -static int parse_vc_action_vxlan_encap(struct context *, const struct token *, - const char *, unsigned int, void *, - unsigned int); -static int parse_vc_action_nvgre_encap(struct context *, const struct token *, - const char *, unsigned int, void *, - unsigned int); -static int parse_vc_action_l2_encap(struct context *, const struct token *, - const char *, unsigned int, void *, - unsigned int); -static int parse_vc_action_l2_decap(struct context *, const struct token *, - const char *, unsigned int, void *, - unsigned int); -static int parse_vc_action_mplsogre_encap(struct context *, - const struct token *, const char *, - unsigned int, void *, unsigned int); -static int parse_vc_action_mplsogre_decap(struct context *, - const struct token *, const char *, - unsigned int, void *, unsigned int); -static int parse_vc_action_mplsoudp_encap(struct context *, - const struct token *, const char *, - unsigned int, void *, unsigned int); -static int parse_vc_action_mplsoudp_decap(struct context *, - const struct token *, const char *, - unsigned int, void *, unsigned int); -static int parse_vc_action_raw_encap(struct context *, - const struct token *, const char *, - unsigned int, void *, unsigned int); -static int parse_vc_action_raw_decap(struct context *, - const struct token *, const char *, - unsigned int, void *, unsigned int); -static int parse_vc_action_raw_encap_index(struct context *, - const struct token *, const char *, - unsigned int, void *, unsigned int); -static int parse_vc_action_raw_decap_index(struct context *, - const struct token *, const char *, - unsigned int, void *, unsigned int); -static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, - const struct token *token, - const char *str, unsigned int len, - void *buf, - unsigned int size); -static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, - const struct token *token, - const char *str, unsigned int len, - void *buf, - unsigned int size); -static int parse_vc_action_set_meta(struct context *ctx, - const struct token *token, const char *str, - unsigned int len, void *buf, - unsigned int size); -static int parse_vc_action_sample(struct context *ctx, - const struct token *token, const char *str, - unsigned int len, void *buf, - unsigned int size); -static int -parse_vc_action_sample_index(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int -parse_vc_modify_field_op(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int -parse_vc_modify_field_id(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int -parse_vc_modify_field_level(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int -parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int parse_destroy(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -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); -static int parse_action(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -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); -static int parse_configure(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_template(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_template_destroy(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_table(struct context *, const struct token *, - const char *, unsigned int, void *, unsigned int); -static int parse_table_destroy(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_jump_table_id(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_qo(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_qo_destroy(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_qia(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_qia_destroy(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_push(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_pull(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_group(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_hash(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_tunnel(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_flex(struct context *, const struct token *, - const char *, unsigned int, void *, unsigned int); -static int parse_int(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_prefix(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_boolean(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_string(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -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); -static int parse_ipv4_addr(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_ipv6_addr(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_port(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_ia(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_ia_destroy(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size); -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); -static int parse_mp(struct context *, const struct token *, - const char *, unsigned int, - void *, unsigned int); -static int parse_meter_profile_id2ptr(struct context *ctx, - const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size); -static int parse_meter_policy_id2ptr(struct context *ctx, - const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size); -static int parse_meter_color(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int parse_insertion_table_type(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int parse_hash_table_type(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int -parse_quota_state_name(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int -parse_quota_mode_name(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int -parse_quota_update_name(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int -parse_qu_mode_name(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int comp_none(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_boolean(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_action(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_port(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_rule_id(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_vc_action_rss_type(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_vc_action_rss_queue(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_set_raw_index(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_set_sample_index(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size); -static int comp_set_modify_field_op(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_set_modify_field_id(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_pattern_template_id(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_actions_template_id(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_table_id(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_queue_id(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_meter_color(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_insertion_table_type(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int comp_hash_table_type(struct context *, const struct token *, - unsigned int, char *, unsigned int); -static int -comp_quota_state_name(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size); -static int -comp_quota_mode_name(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size); -static int -comp_quota_update_name(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size); -static int -comp_qu_mode_name(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size); -static int -comp_set_compare_field_id(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size); -static int -comp_set_compare_op(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size); -static int -parse_vc_compare_op(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int -parse_vc_compare_field_id(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size); -static int -parse_vc_compare_field_level(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *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. */ - [ZERO] = { - .name = "ZERO", - .help = "null entry, abused as the entry point", - .next = NEXT(NEXT_ENTRY(FLOW, ADD)), - }, - [END] = { - .name = "", - .type = "RETURN", - .help = "command may end here", - }, - [START_SET] = { - .name = "START_SET", - .help = "null entry, abused as the entry point for set", - .next = NEXT(NEXT_ENTRY(SET)), - }, - [END_SET] = { - .name = "end_set", - .type = "RETURN", - .help = "set command may end here", - }, - /* Common tokens. */ - [COMMON_INTEGER] = { - .name = "{int}", - .type = "INTEGER", - .help = "integer value", - .call = parse_int, - .comp = comp_none, - }, - [COMMON_UNSIGNED] = { - .name = "{unsigned}", - .type = "UNSIGNED", - .help = "unsigned integer value", - .call = parse_int, - .comp = comp_none, - }, - [COMMON_PREFIX] = { - .name = "{prefix}", - .type = "PREFIX", - .help = "prefix length for bit-mask", - .call = parse_prefix, - .comp = comp_none, - }, - [COMMON_BOOLEAN] = { - .name = "{boolean}", - .type = "BOOLEAN", - .help = "any boolean value", - .call = parse_boolean, - .comp = comp_boolean, - }, - [COMMON_STRING] = { - .name = "{string}", - .type = "STRING", - .help = "fixed string", - .call = parse_string, - .comp = comp_none, - }, - [COMMON_HEX] = { - .name = "{hex}", - .type = "HEX", - .help = "fixed string", - .call = parse_hex, - }, - [COMMON_FILE_PATH] = { - .name = "{file path}", - .type = "STRING", - .help = "file path", - .call = parse_string0, - .comp = comp_none, - }, - [COMMON_MAC_ADDR] = { - .name = "{MAC address}", - .type = "MAC-48", - .help = "standard MAC address notation", - .call = parse_mac_addr, - .comp = comp_none, - }, - [COMMON_IPV4_ADDR] = { - .name = "{IPv4 address}", - .type = "IPV4 ADDRESS", - .help = "standard IPv4 address notation", - .call = parse_ipv4_addr, - .comp = comp_none, - }, - [COMMON_IPV6_ADDR] = { - .name = "{IPv6 address}", - .type = "IPV6 ADDRESS", - .help = "standard IPv6 address notation", - .call = parse_ipv6_addr, - .comp = comp_none, - }, - [COMMON_RULE_ID] = { - .name = "{rule id}", - .type = "RULE ID", - .help = "rule identifier", - .call = parse_int, - .comp = comp_rule_id, - }, - [COMMON_PORT_ID] = { - .name = "{port_id}", - .type = "PORT ID", - .help = "port identifier", - .call = parse_port, - .comp = comp_port, - }, - [COMMON_GROUP_ID] = { - .name = "{group_id}", - .type = "GROUP ID", - .help = "group identifier", - .call = parse_int, - .comp = comp_none, - }, - [COMMON_PRIORITY_LEVEL] = { - .name = "{level}", - .type = "PRIORITY", - .help = "priority level", - .call = parse_int, - .comp = comp_none, - }, - [COMMON_INDIRECT_ACTION_ID] = { - .name = "{indirect_action_id}", - .type = "INDIRECT_ACTION_ID", - .help = "indirect action id", - .call = parse_int, - .comp = comp_none, - }, - [COMMON_PROFILE_ID] = { - .name = "{profile_id}", - .type = "PROFILE_ID", - .help = "profile id", - .call = parse_int, - .comp = comp_none, - }, - [COMMON_POLICY_ID] = { - .name = "{policy_id}", - .type = "POLICY_ID", - .help = "policy id", - .call = parse_int, - .comp = comp_none, - }, - [COMMON_FLEX_TOKEN] = { - .name = "{flex token}", - .type = "flex token", - .help = "flex token", - .call = parse_int, - .comp = comp_none, - }, - [COMMON_FLEX_HANDLE] = { - .name = "{flex handle}", - .type = "FLEX HANDLE", - .help = "fill flex item data", - .call = parse_flex_handle, - .comp = comp_none, - }, - [COMMON_PATTERN_TEMPLATE_ID] = { - .name = "{pattern_template_id}", - .type = "PATTERN_TEMPLATE_ID", - .help = "pattern template id", - .call = parse_int, - .comp = comp_pattern_template_id, - }, - [COMMON_ACTIONS_TEMPLATE_ID] = { - .name = "{actions_template_id}", - .type = "ACTIONS_TEMPLATE_ID", - .help = "actions template id", - .call = parse_int, - .comp = comp_actions_template_id, - }, - [COMMON_TABLE_ID] = { - .name = "{table_id}", - .type = "TABLE_ID", - .help = "table id", - .call = parse_int, - .comp = comp_table_id, - }, - [COMMON_QUEUE_ID] = { - .name = "{queue_id}", - .type = "QUEUE_ID", - .help = "queue id", - .call = parse_int, - .comp = comp_queue_id, - }, - [COMMON_METER_COLOR_NAME] = { - .name = "color_name", - .help = "meter color name", - .call = parse_meter_color, - .comp = comp_meter_color, - }, - /* Top-level command. */ - [FLOW] = { - .name = "flow", - .type = "{command} {port_id} [{arg} [...]]", - .help = "manage ingress/egress flow rules", - .next = NEXT(NEXT_ENTRY - (INFO, - CONFIGURE, - PATTERN_TEMPLATE, - ACTIONS_TEMPLATE, - TABLE, - FLOW_GROUP, - INDIRECT_ACTION, - VALIDATE, - CREATE, - DESTROY, - UPDATE, - FLUSH, - DUMP, - LIST, - AGED, - QUERY, - ISOLATE, - TUNNEL, - FLEX, - QUEUE, - PUSH, - PULL, - HASH)), - .call = parse_init, - }, - /* Top-level command. */ - [INFO] = { - .name = "info", - .help = "get information about flow engine", - .next = NEXT(NEXT_ENTRY(END), - NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_configure, - }, - /* Top-level command. */ - [CONFIGURE] = { - .name = "configure", - .help = "configure flow engine", - .next = NEXT(next_config_attr, - NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_configure, - }, - /* Configure arguments. */ - [CONFIG_QUEUES_NUMBER] = { - .name = "queues_number", - .help = "number of queues", - .next = NEXT(next_config_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.configure.nb_queue)), - }, - [CONFIG_QUEUES_SIZE] = { - .name = "queues_size", - .help = "number of elements in queues", - .next = NEXT(next_config_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.configure.queue_attr.size)), - }, - [CONFIG_COUNTERS_NUMBER] = { - .name = "counters_number", - .help = "number of counters", - .next = NEXT(next_config_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.configure.port_attr.nb_counters)), - }, - [CONFIG_AGING_OBJECTS_NUMBER] = { - .name = "aging_counters_number", - .help = "number of aging objects", - .next = NEXT(next_config_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.configure.port_attr.nb_aging_objects)), - }, - [CONFIG_QUOTAS_NUMBER] = { - .name = "quotas_number", - .help = "number of quotas", - .next = NEXT(next_config_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.configure.port_attr.nb_quotas)), - }, - [CONFIG_METERS_NUMBER] = { - .name = "meters_number", - .help = "number of meters", - .next = NEXT(next_config_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.configure.port_attr.nb_meters)), - }, - [CONFIG_CONN_TRACK_NUMBER] = { - .name = "conn_tracks_number", - .help = "number of connection trackings", - .next = NEXT(next_config_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.configure.port_attr.nb_conn_tracks)), - }, - [CONFIG_FLAGS] = { - .name = "flags", - .help = "configuration flags", - .next = NEXT(next_config_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.configure.port_attr.flags)), - }, - [CONFIG_HOST_PORT] = { - .name = "host_port", - .help = "host port for shared objects", - .next = NEXT(next_config_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.configure.port_attr.host_port_id)), - }, - /* Top-level command. */ - [PATTERN_TEMPLATE] = { - .name = "pattern_template", - .type = "{command} {port_id} [{arg} [...]]", - .help = "manage pattern templates", - .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_template, - }, - /* Sub-level commands. */ - [PATTERN_TEMPLATE_CREATE] = { - .name = "create", - .help = "create pattern template", - .next = NEXT(next_pt_attr), - .call = parse_template, - }, - [PATTERN_TEMPLATE_DESTROY] = { - .name = "destroy", - .help = "destroy pattern template", - .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_template_destroy, - }, - /* Pattern template arguments. */ - [PATTERN_TEMPLATE_CREATE_ID] = { - .name = "pattern_template_id", - .help = "specify a pattern template id to create", - .next = NEXT(next_pt_attr, - NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), - }, - [PATTERN_TEMPLATE_DESTROY_ID] = { - .name = "pattern_template", - .help = "specify a pattern template id to destroy", - .next = NEXT(next_pt_destroy_attr, - NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), - .args = ARGS(ARGS_ENTRY_PTR(struct buffer, - args.templ_destroy.template_id)), - .call = parse_template_destroy, - }, - [PATTERN_TEMPLATE_RELAXED_MATCHING] = { - .name = "relaxed", - .help = "is matching relaxed", - .next = NEXT(next_pt_attr, - NEXT_ENTRY(COMMON_BOOLEAN)), - .args = ARGS(ARGS_ENTRY_BF(struct buffer, - args.vc.attr.reserved, 1)), - }, - [PATTERN_TEMPLATE_INGRESS] = { - .name = "ingress", - .help = "attribute pattern to ingress", - .next = NEXT(next_pt_attr), - .call = parse_template, - }, - [PATTERN_TEMPLATE_EGRESS] = { - .name = "egress", - .help = "attribute pattern to egress", - .next = NEXT(next_pt_attr), - .call = parse_template, - }, - [PATTERN_TEMPLATE_TRANSFER] = { - .name = "transfer", - .help = "attribute pattern to transfer", - .next = NEXT(next_pt_attr), - .call = parse_template, - }, - [PATTERN_TEMPLATE_SPEC] = { - .name = "template", - .help = "specify item to create pattern template", - .next = NEXT(next_item), - }, - /* Top-level command. */ - [ACTIONS_TEMPLATE] = { - .name = "actions_template", - .type = "{command} {port_id} [{arg} [...]]", - .help = "manage actions templates", - .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_template, - }, - /* Sub-level commands. */ - [ACTIONS_TEMPLATE_CREATE] = { - .name = "create", - .help = "create actions template", - .next = NEXT(next_at_attr), - .call = parse_template, - }, - [ACTIONS_TEMPLATE_DESTROY] = { - .name = "destroy", - .help = "destroy actions template", - .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_template_destroy, - }, - /* Actions template arguments. */ - [ACTIONS_TEMPLATE_CREATE_ID] = { - .name = "actions_template_id", - .help = "specify an actions template id to create", - .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), - NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), - NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), - }, - [ACTIONS_TEMPLATE_DESTROY_ID] = { - .name = "actions_template", - .help = "specify an actions template id to destroy", - .next = NEXT(next_at_destroy_attr, - NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), - .args = ARGS(ARGS_ENTRY_PTR(struct buffer, - args.templ_destroy.template_id)), - .call = parse_template_destroy, - }, - [ACTIONS_TEMPLATE_INGRESS] = { - .name = "ingress", - .help = "attribute actions to ingress", - .next = NEXT(next_at_attr), - .call = parse_template, - }, - [ACTIONS_TEMPLATE_EGRESS] = { - .name = "egress", - .help = "attribute actions to egress", - .next = NEXT(next_at_attr), - .call = parse_template, - }, - [ACTIONS_TEMPLATE_TRANSFER] = { - .name = "transfer", - .help = "attribute actions to transfer", - .next = NEXT(next_at_attr), - .call = parse_template, - }, - [ACTIONS_TEMPLATE_SPEC] = { - .name = "template", - .help = "specify action to create actions template", - .next = NEXT(next_action), - .call = parse_template, - }, - [ACTIONS_TEMPLATE_MASK] = { - .name = "mask", - .help = "specify action mask to create actions template", - .next = NEXT(next_action), - .call = parse_template, - }, - /* Top-level command. */ - [TABLE] = { - .name = "template_table", - .type = "{command} {port_id} [{arg} [...]]", - .help = "manage template tables", - .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_table, - }, - /* Sub-level commands. */ - [TABLE_CREATE] = { - .name = "create", - .help = "create template table", - .next = NEXT(next_table_attr), - .call = parse_table, - }, - [TABLE_DESTROY] = { - .name = "destroy", - .help = "destroy template table", - .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_table_destroy, - }, - [TABLE_RESIZE] = { - .name = "resize", - .help = "resize template table", - .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), - .call = parse_table - }, - [TABLE_RESIZE_COMPLETE] = { - .name = "resize_complete", - .help = "complete table resize", - .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_table_destroy, - }, - /* Table arguments. */ - [TABLE_CREATE_ID] = { - .name = "table_id", - .help = "specify table id to create", - .next = NEXT(next_table_attr, - NEXT_ENTRY(COMMON_TABLE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), - }, - [TABLE_DESTROY_ID] = { - .name = "table", - .help = "table id", - .next = NEXT(next_table_destroy_attr, - NEXT_ENTRY(COMMON_TABLE_ID)), - .args = ARGS(ARGS_ENTRY_PTR(struct buffer, - args.table_destroy.table_id)), - .call = parse_table_destroy, - }, - [TABLE_RESIZE_ID] = { - .name = "table_resize_id", - .help = "table resize id", - .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), - NEXT_ENTRY(COMMON_TABLE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), - .call = parse_table - }, - [TABLE_RESIZE_RULES_NUMBER] = { - .name = "table_resize_rules_num", - .help = "table resize rules number", - .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.table.attr.nb_flows)), - .call = parse_table - }, - [TABLE_INSERTION_TYPE] = { - .name = "insertion_type", - .help = "specify insertion type", - .next = NEXT(next_table_attr, - NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.table.attr.insertion_type)), - }, - [TABLE_INSERTION_TYPE_NAME] = { - .name = "insertion_type_name", - .help = "insertion type name", - .call = parse_insertion_table_type, - .comp = comp_insertion_table_type, - }, - [TABLE_HASH_FUNC] = { - .name = "hash_func", - .help = "specify hash calculation function", - .next = NEXT(next_table_attr, - NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.table.attr.hash_func)), - }, - [TABLE_HASH_FUNC_NAME] = { - .name = "hash_func_name", - .help = "hash calculation function name", - .call = parse_hash_table_type, - .comp = comp_hash_table_type, - }, - [TABLE_GROUP] = { - .name = "group", - .help = "specify a group", - .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.table.attr.flow_attr.group)), - }, - [TABLE_PRIORITY] = { - .name = "priority", - .help = "specify a priority level", - .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.table.attr.flow_attr.priority)), - }, - [TABLE_EGRESS] = { - .name = "egress", - .help = "affect rule to egress", - .next = NEXT(next_table_attr), - .call = parse_table, - }, - [TABLE_INGRESS] = { - .name = "ingress", - .help = "affect rule to ingress", - .next = NEXT(next_table_attr), - .call = parse_table, - }, - [TABLE_TRANSFER] = { - .name = "transfer", - .help = "affect rule to transfer", - .next = NEXT(next_table_attr), - .call = parse_table, - }, - [TABLE_TRANSFER_WIRE_ORIG] = { - .name = "wire_orig", - .help = "affect rule direction to transfer", - .next = NEXT(next_table_attr), - .call = parse_table, - }, - [TABLE_TRANSFER_VPORT_ORIG] = { - .name = "vport_orig", - .help = "affect rule direction to transfer", - .next = NEXT(next_table_attr), - .call = parse_table, - }, - [TABLE_RESIZABLE] = { - .name = "resizable", - .help = "set resizable attribute", - .next = NEXT(next_table_attr), - .call = parse_table, - }, - [TABLE_RULES_NUMBER] = { - .name = "rules_number", - .help = "number of rules in table", - .next = NEXT(next_table_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.table.attr.nb_flows)), - .call = parse_table, - }, - [TABLE_PATTERN_TEMPLATE] = { - .name = "pattern_template", - .help = "specify pattern template id", - .next = NEXT(next_table_attr, - NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), - .args = ARGS(ARGS_ENTRY_PTR(struct buffer, - args.table.pat_templ_id)), - .call = parse_table, - }, - [TABLE_ACTIONS_TEMPLATE] = { - .name = "actions_template", - .help = "specify actions template id", - .next = NEXT(next_table_attr, - NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), - .args = ARGS(ARGS_ENTRY_PTR(struct buffer, - args.table.act_templ_id)), - .call = parse_table, - }, - /* Top-level command. */ - [FLOW_GROUP] = { - .name = "group", - .help = "manage flow groups", - .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_group, - }, - /* Sub-level commands. */ - [GROUP_SET_MISS_ACTIONS] = { - .name = "set_miss_actions", - .help = "set group miss actions", - .next = NEXT(next_action), - .call = parse_group, - }, - /* Group arguments */ - [GROUP_ID] = { - .name = "group_id", - .help = "group id", - .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), - }, - [GROUP_INGRESS] = { - .name = "ingress", - .help = "group ingress attr", - .next = NEXT(next_group_attr), - .call = parse_group, - }, - [GROUP_EGRESS] = { - .name = "egress", - .help = "group egress attr", - .next = NEXT(next_group_attr), - .call = parse_group, - }, - [GROUP_TRANSFER] = { - .name = "transfer", - .help = "group transfer attr", - .next = NEXT(next_group_attr), - .call = parse_group, - }, - /* Top-level command. */ - [QUEUE] = { - .name = "queue", - .help = "queue a flow rule operation", - .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_qo, - }, - /* Sub-level commands. */ - [QUEUE_CREATE] = { - .name = "create", - .help = "create a flow rule", - .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), - NEXT_ENTRY(COMMON_QUEUE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, queue)), - .call = parse_qo, - }, - [QUEUE_DESTROY] = { - .name = "destroy", - .help = "destroy a flow rule", - .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_POSTPONE), - NEXT_ENTRY(COMMON_QUEUE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, queue)), - .call = parse_qo_destroy, - }, - [QUEUE_FLOW_UPDATE_RESIZED] = { - .name = "update_resized", - .help = "update a flow after table resize", - .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), - NEXT_ENTRY(COMMON_QUEUE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, queue)), - .call = parse_qo_destroy, - }, - [QUEUE_UPDATE] = { - .name = "update", - .help = "update a flow rule", - .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), - NEXT_ENTRY(COMMON_QUEUE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, queue)), - .call = parse_qo, - }, - [QUEUE_AGED] = { - .name = "aged", - .help = "list and destroy aged flows", - .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, queue)), - .call = parse_aged, - }, - [QUEUE_INDIRECT_ACTION] = { - .name = "indirect_action", - .help = "queue indirect actions", - .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, queue)), - .call = parse_qia, - }, - /* Queue arguments. */ - [QUEUE_TEMPLATE_TABLE] = { - .name = "template_table", - .help = "specify table id", - .next = NEXT(next_async_insert_subcmd, - NEXT_ENTRY(COMMON_TABLE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.vc.table_id)), - .call = parse_qo, - }, - [QUEUE_PATTERN_TEMPLATE] = { - .name = "pattern_template", - .help = "specify pattern template index", - .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.vc.pat_templ_id)), - .call = parse_qo, - }, - [QUEUE_ACTIONS_TEMPLATE] = { - .name = "actions_template", - .help = "specify actions template index", - .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.vc.act_templ_id)), - .call = parse_qo, - }, - [QUEUE_RULE_ID] = { - .name = "rule_index", - .help = "specify flow rule index", - .next = NEXT(next_async_pattern_subcmd, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.vc.rule_id)), - .call = parse_qo, - }, - [QUEUE_CREATE_POSTPONE] = { - .name = "postpone", - .help = "postpone create operation", - .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), - NEXT_ENTRY(COMMON_BOOLEAN)), - .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), - .call = parse_qo, - }, - [QUEUE_DESTROY_POSTPONE] = { - .name = "postpone", - .help = "postpone destroy operation", - .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), - NEXT_ENTRY(COMMON_BOOLEAN)), - .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), - .call = parse_qo_destroy, - }, - [QUEUE_DESTROY_ID] = { - .name = "rule", - .help = "specify rule id to destroy", - .next = NEXT(next_queue_destroy_attr, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_PTR(struct buffer, - args.destroy.rule)), - .call = parse_qo_destroy, - }, - [QUEUE_UPDATE_ID] = { - .name = "rule", - .help = "specify rule id to update", - .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.vc.rule_id)), - .call = parse_qo, - }, - /* Queue indirect action arguments */ - [QUEUE_INDIRECT_ACTION_CREATE] = { - .name = "create", - .help = "create indirect action", - .next = NEXT(next_qia_create_attr), - .call = parse_qia, - }, - [QUEUE_INDIRECT_ACTION_UPDATE] = { - .name = "update", - .help = "update indirect action", - .next = NEXT(next_qia_update_attr, - NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), - .call = parse_qia, - }, - [QUEUE_INDIRECT_ACTION_DESTROY] = { - .name = "destroy", - .help = "destroy indirect action", - .next = NEXT(next_qia_destroy_attr), - .call = parse_qia_destroy, - }, - [QUEUE_INDIRECT_ACTION_QUERY] = { - .name = "query", - .help = "query indirect action", - .next = NEXT(next_qia_query_attr, - NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), - .call = parse_qia, - }, - /* Indirect action destroy arguments. */ - [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { - .name = "postpone", - .help = "postpone destroy operation", - .next = NEXT(next_qia_destroy_attr, - NEXT_ENTRY(COMMON_BOOLEAN)), - .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), - }, - [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { - .name = "action_id", - .help = "specify a indirect action id to destroy", - .next = NEXT(next_qia_destroy_attr, - NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), - .args = ARGS(ARGS_ENTRY_PTR(struct buffer, - args.ia_destroy.action_id)), - .call = parse_qia_destroy, - }, - [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { - .name = "query_update", - .help = "indirect query [and|or] update action", - .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), - .call = parse_qia - }, - [QUEUE_INDIRECT_ACTION_QU_MODE] = { - .name = "mode", - .help = "indirect query [and|or] update action", - .next = NEXT(next_qia_qu_attr, - NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), - .call = parse_qia - }, - /* Indirect action update arguments. */ - [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { - .name = "postpone", - .help = "postpone update operation", - .next = NEXT(next_qia_update_attr, - NEXT_ENTRY(COMMON_BOOLEAN)), - .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), - }, - /* Indirect action update arguments. */ - [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { - .name = "postpone", - .help = "postpone query operation", - .next = NEXT(next_qia_query_attr, - NEXT_ENTRY(COMMON_BOOLEAN)), - .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), - }, - /* Indirect action create arguments. */ - [QUEUE_INDIRECT_ACTION_CREATE_ID] = { - .name = "action_id", - .help = "specify a indirect action id to create", - .next = NEXT(next_qia_create_attr, - NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), - }, - [QUEUE_INDIRECT_ACTION_INGRESS] = { - .name = "ingress", - .help = "affect rule to ingress", - .next = NEXT(next_qia_create_attr), - .call = parse_qia, - }, - [QUEUE_INDIRECT_ACTION_EGRESS] = { - .name = "egress", - .help = "affect rule to egress", - .next = NEXT(next_qia_create_attr), - .call = parse_qia, - }, - [QUEUE_INDIRECT_ACTION_TRANSFER] = { - .name = "transfer", - .help = "affect rule to transfer", - .next = NEXT(next_qia_create_attr), - .call = parse_qia, - }, - [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { - .name = "postpone", - .help = "postpone create operation", - .next = NEXT(next_qia_create_attr, - NEXT_ENTRY(COMMON_BOOLEAN)), - .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), - }, - [QUEUE_INDIRECT_ACTION_SPEC] = { - .name = "action", - .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", - .help = "push enqueued operations", - .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_push, - }, - /* Sub-level commands. */ - [PUSH_QUEUE] = { - .name = "queue", - .help = "specify queue id", - .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, queue)), - }, - /* Top-level command. */ - [PULL] = { - .name = "pull", - .help = "pull flow operations results", - .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_pull, - }, - /* Sub-level commands. */ - [PULL_QUEUE] = { - .name = "queue", - .help = "specify queue id", - .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, queue)), - }, - /* Top-level command. */ - [HASH] = { - .name = "hash", - .help = "calculate hash for a given pattern in a given template table", - .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_hash, - }, - /* Sub-level commands. */ - [HASH_CALC_TABLE] = { - .name = "template_table", - .help = "specify table id", - .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), - NEXT_ENTRY(COMMON_TABLE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.vc.table_id)), - .call = parse_hash, - }, - [HASH_CALC_ENCAP] = { - .name = "encap", - .help = "calculates encap hash", - .next = NEXT(next_hash_encap_dest_subcmd), - .call = parse_hash, - }, - [HASH_CALC_PATTERN_INDEX] = { - .name = "pattern_template", - .help = "specify pattern template id", - .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, - args.vc.pat_templ_id)), - .call = parse_hash, - }, - [ENCAP_HASH_FIELD_SRC_PORT] = { - .name = "hash_field_sport", - .help = "the encap hash field is src port", - .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), - .call = parse_hash, - }, - [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { - .name = "hash_field_flow_id", - .help = "the encap hash field is NVGRE flow id", - .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), - .call = parse_hash, - }, - /* Top-level command. */ - [INDIRECT_ACTION] = { - .name = "indirect_action", - .type = "{command} {port_id} [{arg} [...]]", - .help = "manage indirect actions", - .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_ia, - }, - /* Sub-level commands. */ - [INDIRECT_ACTION_CREATE] = { - .name = "create", - .help = "create indirect action", - .next = NEXT(next_ia_create_attr), - .call = parse_ia, - }, - [INDIRECT_ACTION_UPDATE] = { - .name = "update", - .help = "update indirect action", - .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), - NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), - .call = parse_ia, - }, - [INDIRECT_ACTION_DESTROY] = { - .name = "destroy", - .help = "destroy indirect action", - .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_ia_destroy, - }, - [INDIRECT_ACTION_QUERY] = { - .name = "query", - .help = "query indirect action", - .next = NEXT(NEXT_ENTRY(END), - NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), - .call = parse_ia, - }, - [INDIRECT_ACTION_QUERY_UPDATE] = { - .name = "query_update", - .help = "query [and|or] update", - .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), - .call = parse_ia - }, - [INDIRECT_ACTION_QU_MODE] = { - .name = "mode", - .help = "query_update mode", - .next = NEXT(next_ia_qu_attr, - NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), - .call = parse_ia, - }, - [INDIRECT_ACTION_QU_MODE_NAME] = { - .name = "mode_name", - .help = "query-update mode name", - .call = parse_qu_mode_name, - .comp = comp_qu_mode_name, - }, - [VALIDATE] = { - .name = "validate", - .help = "check whether a flow rule can be created", - .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_vc, - }, - [CREATE] = { - .name = "create", - .help = "create a flow rule", - .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_vc, - }, - [DESTROY] = { - .name = "destroy", - .help = "destroy specific flow rules", - .next = NEXT(next_destroy_attr, - NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_destroy, - }, - [UPDATE] = { - .name = "update", - .help = "update a flow rule with new actions", - .next = NEXT(NEXT_ENTRY(VC_IS_USER_ID, END), - NEXT_ENTRY(ACTIONS), - NEXT_ENTRY(COMMON_RULE_ID), - NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.rule_id), - ARGS_ENTRY(struct buffer, port)), - .call = parse_vc, - }, - [FLUSH] = { - .name = "flush", - .help = "destroy all flow rules", - .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_flush, - }, - [DUMP] = { - .name = "dump", - .help = "dump single/all flow rules to file", - .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_dump, - }, - [QUERY] = { - .name = "query", - .help = "query an existing flow rule", - .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), - NEXT_ENTRY(COMMON_RULE_ID), - NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), - ARGS_ENTRY(struct buffer, args.query.rule), - ARGS_ENTRY(struct buffer, port)), - .call = parse_query, - }, - [LIST] = { - .name = "list", - .help = "list existing flow rules", - .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), - .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(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_aged, - }, - [ISOLATE] = { - .name = "isolate", - .help = "restrict ingress traffic to the defined flow rules", - .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), - NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), - ARGS_ENTRY(struct buffer, port)), - .call = parse_isolate, - }, - [FLEX] = { - .name = "flex_item", - .help = "flex item API", - .next = NEXT(next_flex_item), - .call = parse_flex, - }, - [FLEX_ITEM_CREATE] = { - .name = "create", - .help = "flex item create", - .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), - ARGS_ENTRY(struct buffer, args.flex.token), - ARGS_ENTRY(struct buffer, port)), - .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), - NEXT_ENTRY(COMMON_FLEX_TOKEN), - NEXT_ENTRY(COMMON_PORT_ID)), - .call = parse_flex - }, - [FLEX_ITEM_DESTROY] = { - .name = "destroy", - .help = "flex item destroy", - .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), - ARGS_ENTRY(struct buffer, port)), - .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), - NEXT_ENTRY(COMMON_PORT_ID)), - .call = parse_flex - }, - [TUNNEL] = { - .name = "tunnel", - .help = "new tunnel API", - .next = NEXT(NEXT_ENTRY - (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), - .call = parse_tunnel, - }, - /* Tunnel arguments. */ - [TUNNEL_CREATE] = { - .name = "create", - .help = "create new tunnel object", - .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), - NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_tunnel, - }, - [TUNNEL_CREATE_TYPE] = { - .name = "type", - .help = "create new tunnel", - .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), - .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), - .call = parse_tunnel, - }, - [TUNNEL_DESTROY] = { - .name = "destroy", - .help = "destroy tunnel", - .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), - NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_tunnel, - }, - [TUNNEL_DESTROY_ID] = { - .name = "id", - .help = "tunnel identifier to destroy", - .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), - .call = parse_tunnel, - }, - [TUNNEL_LIST] = { - .name = "list", - .help = "list existing tunnels", - .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, port)), - .call = parse_tunnel, - }, - /* Destroy arguments. */ - [DESTROY_RULE] = { - .name = "rule", - .help = "specify a rule identifier", - .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), - .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), - .call = parse_destroy, - }, - [DESTROY_IS_USER_ID] = { - .name = "user_id", - .help = "rule identifier is user-id", - .next = NEXT(next_destroy_attr), - .call = parse_destroy, - }, - /* Dump arguments. */ - [DUMP_ALL] = { - .name = "all", - .help = "dump all", - .next = NEXT(next_dump_attr), - .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), - .call = parse_dump, - }, - [DUMP_ONE] = { - .name = "rule", - .help = "dump one rule", - .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), - ARGS_ENTRY(struct buffer, args.dump.rule)), - .call = parse_dump, - }, - [DUMP_IS_USER_ID] = { - .name = "user_id", - .help = "rule identifier is user-id", - .next = NEXT(next_dump_subcmd), - .call = parse_dump, - }, - /* Query arguments. */ - [QUERY_ACTION] = { - .name = "{action}", - .type = "ACTION", - .help = "action to query, must be part of the rule", - .call = parse_action, - .comp = comp_action, - }, - [QUERY_IS_USER_ID] = { - .name = "user_id", - .help = "rule identifier is user-id", - .next = NEXT(next_query_attr), - .call = parse_query, - }, - /* List arguments. */ - [LIST_GROUP] = { - .name = "group", - .help = "specify a group", - .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), - .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. */ - [VC_GROUP] = { - .name = "group", - .help = "specify a group", - .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), - .call = parse_vc, - }, - [VC_PRIORITY] = { - .name = "priority", - .help = "specify a priority level", - .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), - .call = parse_vc, - }, - [VC_INGRESS] = { - .name = "ingress", - .help = "affect rule to ingress", - .next = NEXT(next_vc_attr), - .call = parse_vc, - }, - [VC_EGRESS] = { - .name = "egress", - .help = "affect rule to egress", - .next = NEXT(next_vc_attr), - .call = parse_vc, - }, - [VC_TRANSFER] = { - .name = "transfer", - .help = "apply rule directly to endpoints found in pattern", - .next = NEXT(next_vc_attr), - .call = parse_vc, - }, - [VC_TUNNEL_SET] = { - .name = "tunnel_set", - .help = "tunnel steer rule", - .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), - .call = parse_vc, - }, - [VC_TUNNEL_MATCH] = { - .name = "tunnel_match", - .help = "tunnel match rule", - .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), - .call = parse_vc, - }, - [VC_USER_ID] = { - .name = "user_id", - .help = "specify a user id to create", - .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), - .call = parse_vc, - }, - [VC_IS_USER_ID] = { - .name = "user_id", - .help = "rule identifier is user-id", - .call = parse_vc, - }, - /* Validate/create pattern. */ - [ITEM_PATTERN] = { - .name = "pattern", - .help = "submit a list of pattern items", - .next = NEXT(next_item), - .call = parse_vc, - }, - [ITEM_PARAM_IS] = { - .name = "is", - .help = "match value perfectly (with full bit-mask)", - .call = parse_vc_spec, - }, - [ITEM_PARAM_SPEC] = { - .name = "spec", - .help = "match value according to configured bit-mask", - .call = parse_vc_spec, - }, - [ITEM_PARAM_LAST] = { - .name = "last", - .help = "specify upper bound to establish a range", - .call = parse_vc_spec, - }, - [ITEM_PARAM_MASK] = { - .name = "mask", - .help = "specify bit-mask with relevant bits set to one", - .call = parse_vc_spec, - }, - [ITEM_PARAM_PREFIX] = { - .name = "prefix", - .help = "generate bit-mask from a prefix length", - .call = parse_vc_spec, - }, - [ITEM_NEXT] = { - .name = "/", - .help = "specify next pattern item", - .next = NEXT(next_item), - }, - [ITEM_END] = { - .name = "end", - .help = "end list of pattern items", - .priv = PRIV_ITEM(END, 0), - .next = NEXT(NEXT_ENTRY(ACTIONS, END)), - .call = parse_vc, - }, - [ITEM_VOID] = { - .name = "void", - .help = "no-op pattern item", - .priv = PRIV_ITEM(VOID, 0), - .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), - .call = parse_vc, - }, - [ITEM_INVERT] = { - .name = "invert", - .help = "perform actions when pattern does not match", - .priv = PRIV_ITEM(INVERT, 0), - .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), - .call = parse_vc, - }, - [ITEM_ANY] = { - .name = "any", - .help = "match any protocol for the current layer", - .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), - .next = NEXT(item_any), - .call = parse_vc, - }, - [ITEM_ANY_NUM] = { - .name = "num", - .help = "number of layers covered", - .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), - }, - [ITEM_PORT_ID] = { - .name = "port_id", - .help = "match traffic from/to a given DPDK port ID", - .priv = PRIV_ITEM(PORT_ID, - sizeof(struct rte_flow_item_port_id)), - .next = NEXT(item_port_id), - .call = parse_vc, - }, - [ITEM_PORT_ID_ID] = { - .name = "id", - .help = "DPDK port ID", - .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), - }, - [ITEM_MARK] = { - .name = "mark", - .help = "match traffic against value set in previously matched rule", - .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), - .next = NEXT(item_mark), - .call = parse_vc, - }, - [ITEM_MARK_ID] = { - .name = "id", - .help = "Integer value to match against", - .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), - }, - [ITEM_RAW] = { - .name = "raw", - .help = "match an arbitrary byte string", - .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), - .next = NEXT(item_raw), - .call = parse_vc, - }, - [ITEM_RAW_RELATIVE] = { - .name = "relative", - .help = "look for pattern after the previous item", - .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, - relative, 1)), - }, - [ITEM_RAW_SEARCH] = { - .name = "search", - .help = "search pattern from offset (see also limit)", - .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, - search, 1)), - }, - [ITEM_RAW_OFFSET] = { - .name = "offset", - .help = "absolute or relative offset for pattern", - .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), - }, - [ITEM_RAW_LIMIT] = { - .name = "limit", - .help = "search area limit for start of pattern", - .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), - }, - [ITEM_RAW_PATTERN] = { - .name = "pattern", - .help = "byte string to look for", - .next = NEXT(item_raw, - NEXT_ENTRY(COMMON_STRING), - NEXT_ENTRY(ITEM_PARAM_IS, - ITEM_PARAM_SPEC, - ITEM_PARAM_MASK)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), - ARGS_ENTRY(struct rte_flow_item_raw, length), - ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), - ITEM_RAW_PATTERN_SIZE)), - }, - [ITEM_RAW_PATTERN_HEX] = { - .name = "pattern_hex", - .help = "hex string to look for", - .next = NEXT(item_raw, - NEXT_ENTRY(COMMON_HEX), - NEXT_ENTRY(ITEM_PARAM_IS, - ITEM_PARAM_SPEC, - ITEM_PARAM_MASK)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), - ARGS_ENTRY(struct rte_flow_item_raw, length), - ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), - ITEM_RAW_PATTERN_SIZE)), - }, - [ITEM_ETH] = { - .name = "eth", - .help = "match Ethernet header", - .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), - .next = NEXT(item_eth), - .call = parse_vc, - }, - [ITEM_ETH_DST] = { - .name = "dst", - .help = "destination MAC", - .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), - }, - [ITEM_ETH_SRC] = { - .name = "src", - .help = "source MAC", - .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), - }, - [ITEM_ETH_TYPE] = { - .name = "type", - .help = "EtherType", - .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), - }, - [ITEM_ETH_HAS_VLAN] = { - .name = "has_vlan", - .help = "packet header contains VLAN", - .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, - has_vlan, 1)), - }, - [ITEM_VLAN] = { - .name = "vlan", - .help = "match 802.1Q/ad VLAN tag", - .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), - .next = NEXT(item_vlan), - .call = parse_vc, - }, - [ITEM_VLAN_TCI] = { - .name = "tci", - .help = "tag control information", - .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), - }, - [ITEM_VLAN_PCP] = { - .name = "pcp", - .help = "priority code point", - .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, - hdr.vlan_tci, "\xe0\x00")), - }, - [ITEM_VLAN_DEI] = { - .name = "dei", - .help = "drop eligible indicator", - .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, - hdr.vlan_tci, "\x10\x00")), - }, - [ITEM_VLAN_VID] = { - .name = "vid", - .help = "VLAN identifier", - .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, - hdr.vlan_tci, "\x0f\xff")), - }, - [ITEM_VLAN_INNER_TYPE] = { - .name = "inner_type", - .help = "inner EtherType", - .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, - hdr.eth_proto)), - }, - [ITEM_VLAN_HAS_MORE_VLAN] = { - .name = "has_more_vlan", - .help = "packet header contains another VLAN", - .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, - has_more_vlan, 1)), - }, - [ITEM_IPV4] = { - .name = "ipv4", - .help = "match IPv4 header", - .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), - .next = NEXT(item_ipv4), - .call = parse_vc, - }, - [ITEM_IPV4_VER_IHL] = { - .name = "version_ihl", - .help = "match header length", - .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, - hdr.version_ihl)), - }, - [ITEM_IPV4_TOS] = { - .name = "tos", - .help = "type of service", - .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, - hdr.type_of_service)), - }, - [ITEM_IPV4_LENGTH] = { - .name = "length", - .help = "total length", - .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, - hdr.total_length)), - }, - [ITEM_IPV4_ID] = { - .name = "packet_id", - .help = "fragment packet id", - .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, - hdr.packet_id)), - }, - [ITEM_IPV4_FRAGMENT_OFFSET] = { - .name = "fragment_offset", - .help = "fragmentation flags and fragment offset", - .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, - hdr.fragment_offset)), - }, - [ITEM_IPV4_TTL] = { - .name = "ttl", - .help = "time to live", - .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, - hdr.time_to_live)), - }, - [ITEM_IPV4_PROTO] = { - .name = "proto", - .help = "next protocol ID", - .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, - hdr.next_proto_id)), - }, - [ITEM_IPV4_SRC] = { - .name = "src", - .help = "source address", - .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, - hdr.src_addr)), - }, - [ITEM_IPV4_DST] = { - .name = "dst", - .help = "destination address", - .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, - hdr.dst_addr)), - }, - [ITEM_IPV6] = { - .name = "ipv6", - .help = "match IPv6 header", - .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), - .next = NEXT(item_ipv6), - .call = parse_vc, - }, - [ITEM_IPV6_TC] = { - .name = "tc", - .help = "traffic class", - .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, - hdr.vtc_flow, - "\x0f\xf0\x00\x00")), - }, - [ITEM_IPV6_FLOW] = { - .name = "flow", - .help = "flow label", - .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, - hdr.vtc_flow, - "\x00\x0f\xff\xff")), - }, - [ITEM_IPV6_LEN] = { - .name = "length", - .help = "payload length", - .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, - hdr.payload_len)), - }, - [ITEM_IPV6_PROTO] = { - .name = "proto", - .help = "protocol (next header)", - .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, - hdr.proto)), - }, - [ITEM_IPV6_HOP] = { - .name = "hop", - .help = "hop limit", - .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, - hdr.hop_limits)), - }, - [ITEM_IPV6_SRC] = { - .name = "src", - .help = "source address", - .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, - hdr.src_addr)), - }, - [ITEM_IPV6_DST] = { - .name = "dst", - .help = "destination address", - .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, - hdr.dst_addr)), - }, - [ITEM_IPV6_HAS_FRAG_EXT] = { - .name = "has_frag_ext", - .help = "fragment packet attribute", - .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, - has_frag_ext, 1)), - }, - [ITEM_IPV6_ROUTING_EXT] = { - .name = "ipv6_routing_ext", - .help = "match IPv6 routing extension header", - .priv = PRIV_ITEM(IPV6_ROUTING_EXT, - sizeof(struct rte_flow_item_ipv6_routing_ext)), - .next = NEXT(item_ipv6_routing_ext), - .call = parse_vc, - }, - [ITEM_IPV6_ROUTING_EXT_TYPE] = { - .name = "ext_type", - .help = "match IPv6 routing extension header type", - .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, - hdr.type)), - }, - [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { - .name = "ext_next_hdr", - .help = "match IPv6 routing extension header next header type", - .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, - hdr.next_hdr)), - }, - [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { - .name = "ext_seg_left", - .help = "match IPv6 routing extension header segment left", - .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, - hdr.segments_left)), - }, - [ITEM_ICMP] = { - .name = "icmp", - .help = "match ICMP header", - .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), - .next = NEXT(item_icmp), - .call = parse_vc, - }, - [ITEM_ICMP_TYPE] = { - .name = "type", - .help = "ICMP packet type", - .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, - hdr.icmp_type)), - }, - [ITEM_ICMP_CODE] = { - .name = "code", - .help = "ICMP packet code", - .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, - hdr.icmp_code)), - }, - [ITEM_ICMP_IDENT] = { - .name = "ident", - .help = "ICMP packet identifier", - .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, - hdr.icmp_ident)), - }, - [ITEM_ICMP_SEQ] = { - .name = "seq", - .help = "ICMP packet sequence number", - .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, - hdr.icmp_seq_nb)), - }, - [ITEM_UDP] = { - .name = "udp", - .help = "match UDP header", - .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), - .next = NEXT(item_udp), - .call = parse_vc, - }, - [ITEM_UDP_SRC] = { - .name = "src", - .help = "UDP source port", - .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, - hdr.src_port)), - }, - [ITEM_UDP_DST] = { - .name = "dst", - .help = "UDP destination port", - .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, - hdr.dst_port)), - }, - [ITEM_TCP] = { - .name = "tcp", - .help = "match TCP header", - .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), - .next = NEXT(item_tcp), - .call = parse_vc, - }, - [ITEM_TCP_SRC] = { - .name = "src", - .help = "TCP source port", - .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, - hdr.src_port)), - }, - [ITEM_TCP_DST] = { - .name = "dst", - .help = "TCP destination port", - .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, - hdr.dst_port)), - }, - [ITEM_TCP_FLAGS] = { - .name = "flags", - .help = "TCP flags", - .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, - hdr.tcp_flags)), - }, - [ITEM_SCTP] = { - .name = "sctp", - .help = "match SCTP header", - .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), - .next = NEXT(item_sctp), - .call = parse_vc, - }, - [ITEM_SCTP_SRC] = { - .name = "src", - .help = "SCTP source port", - .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, - hdr.src_port)), - }, - [ITEM_SCTP_DST] = { - .name = "dst", - .help = "SCTP destination port", - .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, - hdr.dst_port)), - }, - [ITEM_SCTP_TAG] = { - .name = "tag", - .help = "validation tag", - .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, - hdr.tag)), - }, - [ITEM_SCTP_CKSUM] = { - .name = "cksum", - .help = "checksum", - .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, - hdr.cksum)), - }, - [ITEM_VXLAN] = { - .name = "vxlan", - .help = "match VXLAN header", - .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), - .next = NEXT(item_vxlan), - .call = parse_vc, - }, - [ITEM_VXLAN_VNI] = { - .name = "vni", - .help = "VXLAN identifier", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), - }, - [ITEM_VXLAN_FLAG_G] = { - .name = "flag_g", - .help = "VXLAN GBP bit", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, - hdr.flag_g, 1)), - }, - [ITEM_VXLAN_FLAG_VER] = { - .name = "flag_ver", - .help = "VXLAN GPE version", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, - hdr.flag_ver, 2)), - }, - [ITEM_VXLAN_FLAG_I] = { - .name = "flag_i", - .help = "VXLAN Instance bit", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, - hdr.flag_i, 1)), - }, - [ITEM_VXLAN_FLAG_P] = { - .name = "flag_p", - .help = "VXLAN GPE Next Protocol bit", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, - hdr.flag_p, 1)), - }, - [ITEM_VXLAN_FLAG_B] = { - .name = "flag_b", - .help = "VXLAN GPE Ingress-Replicated BUM", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, - hdr.flag_b, 1)), - }, - [ITEM_VXLAN_FLAG_O] = { - .name = "flag_o", - .help = "VXLAN GPE OAM Packet bit", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, - hdr.flag_o, 1)), - }, - [ITEM_VXLAN_FLAG_D] = { - .name = "flag_d", - .help = "VXLAN GBP Don't Learn bit", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, - hdr.flag_d, 1)), - }, - [ITEM_VXLAN_FLAG_A] = { - .name = "flag_a", - .help = "VXLAN GBP Applied bit", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, - hdr.flag_a, 1)), - }, - [ITEM_VXLAN_GBP_ID] = { - .name = "group_policy_id", - .help = "VXLAN GBP ID", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, - hdr.policy_id)), - }, - [ITEM_VXLAN_GPE_PROTO] = { - .name = "protocol", - .help = "VXLAN GPE next protocol", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, - hdr.proto)), - }, - [ITEM_VXLAN_FIRST_RSVD] = { - .name = "first_rsvd", - .help = "VXLAN rsvd0 first byte", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, - hdr.rsvd0[0])), - }, - [ITEM_VXLAN_SECND_RSVD] = { - .name = "second_rsvd", - .help = "VXLAN rsvd0 second byte", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, - hdr.rsvd0[1])), - }, - [ITEM_VXLAN_THIRD_RSVD] = { - .name = "third_rsvd", - .help = "VXLAN rsvd0 third byte", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, - hdr.rsvd0[2])), - }, - [ITEM_VXLAN_LAST_RSVD] = { - .name = "last_rsvd", - .help = "VXLAN last reserved byte", - .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, - hdr.last_rsvd)), - }, - [ITEM_E_TAG] = { - .name = "e_tag", - .help = "match E-Tag header", - .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), - .next = NEXT(item_e_tag), - .call = parse_vc, - }, - [ITEM_E_TAG_GRP_ECID_B] = { - .name = "grp_ecid_b", - .help = "GRP and E-CID base", - .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, - rsvd_grp_ecid_b, - "\x3f\xff")), - }, - [ITEM_NVGRE] = { - .name = "nvgre", - .help = "match NVGRE header", - .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), - .next = NEXT(item_nvgre), - .call = parse_vc, - }, - [ITEM_NVGRE_TNI] = { - .name = "tni", - .help = "virtual subnet ID", - .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), - }, - [ITEM_MPLS] = { - .name = "mpls", - .help = "match MPLS header", - .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), - .next = NEXT(item_mpls), - .call = parse_vc, - }, - [ITEM_MPLS_LABEL] = { - .name = "label", - .help = "MPLS label", - .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, - label_tc_s, - "\xff\xff\xf0")), - }, - [ITEM_MPLS_TC] = { - .name = "tc", - .help = "MPLS Traffic Class", - .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_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(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, - label_tc_s, - "\x00\x00\x01")), - }, - [ITEM_MPLS_TTL] = { - .name = "ttl", - .help = "MPLS Time-to-Live", - .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), - }, - [ITEM_GRE] = { - .name = "gre", - .help = "match GRE header", - .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), - .next = NEXT(item_gre), - .call = parse_vc, - }, - [ITEM_GRE_PROTO] = { - .name = "protocol", - .help = "GRE protocol type", - .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, - protocol)), - }, - [ITEM_GRE_C_RSVD0_VER] = { - .name = "c_rsvd0_ver", - .help = - "checksum (1b), undefined (1b), key bit (1b)," - " sequence number (1b), reserved 0 (9b)," - " version (3b)", - .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, - c_rsvd0_ver)), - }, - [ITEM_GRE_C_BIT] = { - .name = "c_bit", - .help = "checksum bit (C)", - .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), - item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, - c_rsvd0_ver, - "\x80\x00\x00\x00")), - }, - [ITEM_GRE_S_BIT] = { - .name = "s_bit", - .help = "sequence number bit (S)", - .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, - c_rsvd0_ver, - "\x10\x00\x00\x00")), - }, - [ITEM_GRE_K_BIT] = { - .name = "k_bit", - .help = "key bit (K)", - .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, - c_rsvd0_ver, - "\x20\x00\x00\x00")), - }, - [ITEM_FUZZY] = { - .name = "fuzzy", - .help = "fuzzy pattern match, expect faster than default", - .priv = PRIV_ITEM(FUZZY, - sizeof(struct rte_flow_item_fuzzy)), - .next = NEXT(item_fuzzy), - .call = parse_vc, - }, - [ITEM_FUZZY_THRESH] = { - .name = "thresh", - .help = "match accuracy threshold", - .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, - thresh)), - }, - [ITEM_GTP] = { - .name = "gtp", - .help = "match GTP header", - .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), - .next = NEXT(item_gtp), - .call = parse_vc, - }, - [ITEM_GTP_FLAGS] = { - .name = "v_pt_rsv_flags", - .help = "GTP flags", - .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, - hdr.gtp_hdr_info)), - }, - [ITEM_GTP_MSG_TYPE] = { - .name = "msg_type", - .help = "GTP message type", - .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), - }, - [ITEM_GTP_TEID] = { - .name = "teid", - .help = "tunnel endpoint identifier", - .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), - }, - [ITEM_GTPC] = { - .name = "gtpc", - .help = "match GTP header", - .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), - .next = NEXT(item_gtp), - .call = parse_vc, - }, - [ITEM_GTPU] = { - .name = "gtpu", - .help = "match GTP header", - .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), - .next = NEXT(item_gtp), - .call = parse_vc, - }, - [ITEM_GENEVE] = { - .name = "geneve", - .help = "match GENEVE header", - .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), - .next = NEXT(item_geneve), - .call = parse_vc, - }, - [ITEM_GENEVE_VNI] = { - .name = "vni", - .help = "virtual network identifier", - .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), - }, - [ITEM_GENEVE_PROTO] = { - .name = "protocol", - .help = "GENEVE protocol type", - .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, - protocol)), - }, - [ITEM_GENEVE_OPTLEN] = { - .name = "optlen", - .help = "GENEVE options length in dwords", - .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, - ver_opt_len_o_c_rsvd0, - "\x3f\x00")), - }, - [ITEM_VXLAN_GPE] = { - .name = "vxlan-gpe", - .help = "match VXLAN-GPE header", - .priv = PRIV_ITEM(VXLAN_GPE, - sizeof(struct rte_flow_item_vxlan_gpe)), - .next = NEXT(item_vxlan_gpe), - .call = parse_vc, - }, - [ITEM_VXLAN_GPE_VNI] = { - .name = "vni", - .help = "VXLAN-GPE identifier", - .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, - hdr.vni)), - }, - [ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR] = { - .name = "protocol", - .help = "VXLAN-GPE next protocol", - .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, - protocol)), - }, - [ITEM_VXLAN_GPE_FLAGS] = { - .name = "flags", - .help = "VXLAN-GPE flags", - .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, - flags)), - }, - [ITEM_VXLAN_GPE_RSVD0] = { - .name = "rsvd0", - .help = "VXLAN-GPE rsvd0", - .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, - rsvd0)), - }, - [ITEM_VXLAN_GPE_RSVD1] = { - .name = "rsvd1", - .help = "VXLAN-GPE rsvd1", - .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, - rsvd1)), - }, - [ITEM_ARP_ETH_IPV4] = { - .name = "arp_eth_ipv4", - .help = "match ARP header for Ethernet/IPv4", - .priv = PRIV_ITEM(ARP_ETH_IPV4, - sizeof(struct rte_flow_item_arp_eth_ipv4)), - .next = NEXT(item_arp_eth_ipv4), - .call = parse_vc, - }, - [ITEM_ARP_ETH_IPV4_SHA] = { - .name = "sha", - .help = "sender hardware address", - .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, - hdr.arp_data.arp_sha)), - }, - [ITEM_ARP_ETH_IPV4_SPA] = { - .name = "spa", - .help = "sender IPv4 address", - .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, - hdr.arp_data.arp_sip)), - }, - [ITEM_ARP_ETH_IPV4_THA] = { - .name = "tha", - .help = "target hardware address", - .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, - hdr.arp_data.arp_tha)), - }, - [ITEM_ARP_ETH_IPV4_TPA] = { - .name = "tpa", - .help = "target IPv4 address", - .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, - hdr.arp_data.arp_tip)), - }, - [ITEM_IPV6_EXT] = { - .name = "ipv6_ext", - .help = "match presence of any IPv6 extension header", - .priv = PRIV_ITEM(IPV6_EXT, - sizeof(struct rte_flow_item_ipv6_ext)), - .next = NEXT(item_ipv6_ext), - .call = parse_vc, - }, - [ITEM_IPV6_EXT_NEXT_HDR] = { - .name = "next_hdr", - .help = "next header", - .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, - next_hdr)), - }, - [ITEM_IPV6_FRAG_EXT] = { - .name = "ipv6_frag_ext", - .help = "match presence of IPv6 fragment extension header", - .priv = PRIV_ITEM(IPV6_FRAG_EXT, - sizeof(struct rte_flow_item_ipv6_frag_ext)), - .next = NEXT(item_ipv6_frag_ext), - .call = parse_vc, - }, - [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { - .name = "next_hdr", - .help = "next header", - .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, - hdr.next_header)), - }, - [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { - .name = "frag_data", - .help = "fragment flags and offset", - .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, - hdr.frag_data)), - }, - [ITEM_IPV6_FRAG_EXT_ID] = { - .name = "packet_id", - .help = "fragment packet id", - .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, - hdr.id)), - }, - [ITEM_ICMP6] = { - .name = "icmp6", - .help = "match any ICMPv6 header", - .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), - .next = NEXT(item_icmp6), - .call = parse_vc, - }, - [ITEM_ICMP6_TYPE] = { - .name = "type", - .help = "ICMPv6 type", - .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, - type)), - }, - [ITEM_ICMP6_CODE] = { - .name = "code", - .help = "ICMPv6 code", - .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, - code)), - }, - [ITEM_ICMP6_ECHO_REQUEST] = { - .name = "icmp6_echo_request", - .help = "match ICMPv6 echo request", - .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, - sizeof(struct rte_flow_item_icmp6_echo)), - .next = NEXT(item_icmp6_echo_request), - .call = parse_vc, - }, - [ITEM_ICMP6_ECHO_REQUEST_ID] = { - .name = "ident", - .help = "ICMPv6 echo request identifier", - .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, - hdr.identifier)), - }, - [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { - .name = "seq", - .help = "ICMPv6 echo request sequence", - .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, - hdr.sequence)), - }, - [ITEM_ICMP6_ECHO_REPLY] = { - .name = "icmp6_echo_reply", - .help = "match ICMPv6 echo reply", - .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, - sizeof(struct rte_flow_item_icmp6_echo)), - .next = NEXT(item_icmp6_echo_reply), - .call = parse_vc, - }, - [ITEM_ICMP6_ECHO_REPLY_ID] = { - .name = "ident", - .help = "ICMPv6 echo reply identifier", - .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, - hdr.identifier)), - }, - [ITEM_ICMP6_ECHO_REPLY_SEQ] = { - .name = "seq", - .help = "ICMPv6 echo reply sequence", - .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, - hdr.sequence)), - }, - [ITEM_ICMP6_ND_NS] = { - .name = "icmp6_nd_ns", - .help = "match ICMPv6 neighbor discovery solicitation", - .priv = PRIV_ITEM(ICMP6_ND_NS, - sizeof(struct rte_flow_item_icmp6_nd_ns)), - .next = NEXT(item_icmp6_nd_ns), - .call = parse_vc, - }, - [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { - .name = "target_addr", - .help = "target address", - .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, - target_addr)), - }, - [ITEM_ICMP6_ND_NA] = { - .name = "icmp6_nd_na", - .help = "match ICMPv6 neighbor discovery advertisement", - .priv = PRIV_ITEM(ICMP6_ND_NA, - sizeof(struct rte_flow_item_icmp6_nd_na)), - .next = NEXT(item_icmp6_nd_na), - .call = parse_vc, - }, - [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { - .name = "target_addr", - .help = "target address", - .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, - target_addr)), - }, - [ITEM_ICMP6_ND_OPT] = { - .name = "icmp6_nd_opt", - .help = "match presence of any ICMPv6 neighbor discovery" - " option", - .priv = PRIV_ITEM(ICMP6_ND_OPT, - sizeof(struct rte_flow_item_icmp6_nd_opt)), - .next = NEXT(item_icmp6_nd_opt), - .call = parse_vc, - }, - [ITEM_ICMP6_ND_OPT_TYPE] = { - .name = "type", - .help = "ND option type", - .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, - type)), - }, - [ITEM_ICMP6_ND_OPT_SLA_ETH] = { - .name = "icmp6_nd_opt_sla_eth", - .help = "match ICMPv6 neighbor discovery source Ethernet" - " link-layer address option", - .priv = PRIV_ITEM - (ICMP6_ND_OPT_SLA_ETH, - sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), - .next = NEXT(item_icmp6_nd_opt_sla_eth), - .call = parse_vc, - }, - [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { - .name = "sla", - .help = "source Ethernet LLA", - .next = NEXT(item_icmp6_nd_opt_sla_eth, - NEXT_ENTRY(COMMON_MAC_ADDR), item_param), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), - }, - [ITEM_ICMP6_ND_OPT_TLA_ETH] = { - .name = "icmp6_nd_opt_tla_eth", - .help = "match ICMPv6 neighbor discovery target Ethernet" - " link-layer address option", - .priv = PRIV_ITEM - (ICMP6_ND_OPT_TLA_ETH, - sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), - .next = NEXT(item_icmp6_nd_opt_tla_eth), - .call = parse_vc, - }, - [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { - .name = "tla", - .help = "target Ethernet LLA", - .next = NEXT(item_icmp6_nd_opt_tla_eth, - NEXT_ENTRY(COMMON_MAC_ADDR), item_param), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), - }, - [ITEM_META] = { - .name = "meta", - .help = "match metadata header", - .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), - .next = NEXT(item_meta), - .call = parse_vc, - }, - [ITEM_META_DATA] = { - .name = "data", - .help = "metadata value", - .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, - data, "\xff\xff\xff\xff")), - }, - [ITEM_RANDOM] = { - .name = "random", - .help = "match random value", - .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), - .next = NEXT(item_random), - .call = parse_vc, - }, - [ITEM_RANDOM_VALUE] = { - .name = "value", - .help = "random value", - .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, - value, "\xff\xff\xff\xff")), - }, - [ITEM_GRE_KEY] = { - .name = "gre_key", - .help = "match GRE key", - .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), - .next = NEXT(item_gre_key), - .call = parse_vc, - }, - [ITEM_GRE_KEY_VALUE] = { - .name = "value", - .help = "key value", - .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), - }, - [ITEM_GRE_OPTION] = { - .name = "gre_option", - .help = "match GRE optional fields", - .priv = PRIV_ITEM(GRE_OPTION, - sizeof(struct rte_flow_item_gre_opt)), - .next = NEXT(item_gre_option), - .call = parse_vc, - }, - [ITEM_GRE_OPTION_CHECKSUM] = { - .name = "checksum", - .help = "match GRE checksum", - .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, - checksum_rsvd.checksum)), - }, - [ITEM_GRE_OPTION_KEY] = { - .name = "key", - .help = "match GRE key", - .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, - key.key)), - }, - [ITEM_GRE_OPTION_SEQUENCE] = { - .name = "sequence", - .help = "match GRE sequence", - .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, - sequence.sequence)), - }, - [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(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, - hdr.qfi, 6)), - }, - [ITEM_GTP_PSC_PDU_T] = { - .name = "pdu_t", - .help = "PDU type", - .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, - hdr.type, 4)), - }, - [ITEM_PPPOES] = { - .name = "pppoes", - .help = "match PPPoE session header", - .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), - .next = NEXT(item_pppoes), - .call = parse_vc, - }, - [ITEM_PPPOED] = { - .name = "pppoed", - .help = "match PPPoE discovery header", - .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), - .next = NEXT(item_pppoed), - .call = parse_vc, - }, - [ITEM_PPPOE_SEID] = { - .name = "seid", - .help = "session identifier", - .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, - session_id)), - }, - [ITEM_PPPOE_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_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_item_pppoe_proto_id, proto_id)), - .call = parse_vc, - }, - [ITEM_HIGIG2] = { - .name = "higig2", - .help = "matches higig2 header", - .priv = PRIV_ITEM(HIGIG2, - sizeof(struct rte_flow_item_higig2_hdr)), - .next = NEXT(item_higig2), - .call = parse_vc, - }, - [ITEM_HIGIG2_CLASSIFICATION] = { - .name = "classification", - .help = "matches classification of higig2 header", - .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, - hdr.ppt1.classification)), - }, - [ITEM_HIGIG2_VID] = { - .name = "vid", - .help = "matches vid of higig2 header", - .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, - hdr.ppt1.vid)), - }, - [ITEM_TAG] = { - .name = "tag", - .help = "match tag value", - .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), - .next = NEXT(item_tag), - .call = parse_vc, - }, - [ITEM_TAG_DATA] = { - .name = "data", - .help = "tag value to match", - .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), - }, - [ITEM_TAG_INDEX] = { - .name = "index", - .help = "index of tag array to match", - .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), - NEXT_ENTRY(ITEM_PARAM_IS)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), - }, - [ITEM_L2TPV3OIP] = { - .name = "l2tpv3oip", - .help = "match L2TPv3 over IP header", - .priv = PRIV_ITEM(L2TPV3OIP, - sizeof(struct rte_flow_item_l2tpv3oip)), - .next = NEXT(item_l2tpv3oip), - .call = parse_vc, - }, - [ITEM_L2TPV3OIP_SESSION_ID] = { - .name = "session_id", - .help = "session identifier", - .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .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(COMMON_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(COMMON_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(COMMON_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(COMMON_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(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, - ITEM_ECPRI_COMMON, ITEM_NEXT), - NEXT_ENTRY(COMMON_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(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, - ITEM_ECPRI_COMMON, ITEM_NEXT), - NEXT_ENTRY(COMMON_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(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, - ITEM_ECPRI_COMMON, ITEM_NEXT), - NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, - hdr.type5.msr_id)), - }, - [ITEM_GENEVE_OPT] = { - .name = "geneve-opt", - .help = "GENEVE header option", - .priv = PRIV_ITEM(GENEVE_OPT, - sizeof(struct rte_flow_item_geneve_opt) + - ITEM_GENEVE_OPT_DATA_SIZE), - .next = NEXT(item_geneve_opt), - .call = parse_vc, - }, - [ITEM_GENEVE_OPT_CLASS] = { - .name = "class", - .help = "GENEVE option class", - .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, - option_class)), - }, - [ITEM_GENEVE_OPT_TYPE] = { - .name = "type", - .help = "GENEVE option type", - .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, - option_type)), - }, - [ITEM_GENEVE_OPT_LENGTH] = { - .name = "length", - .help = "GENEVE option data length (in 32b words)", - .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_BOUNDED( - struct rte_flow_item_geneve_opt, option_len, - 0, 31)), - }, - [ITEM_GENEVE_OPT_DATA] = { - .name = "data", - .help = "GENEVE option data pattern", - .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), - ARGS_ENTRY_ARB(0, 0), - ARGS_ENTRY_ARB - (sizeof(struct rte_flow_item_geneve_opt), - ITEM_GENEVE_OPT_DATA_SIZE)), - }, - [ITEM_INTEGRITY] = { - .name = "integrity", - .help = "match packet integrity", - .priv = PRIV_ITEM(INTEGRITY, - sizeof(struct rte_flow_item_integrity)), - .next = NEXT(item_integrity), - .call = parse_vc, - }, - [ITEM_INTEGRITY_LEVEL] = { - .name = "level", - .help = "integrity level", - .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), - }, - [ITEM_INTEGRITY_VALUE] = { - .name = "value", - .help = "integrity value", - .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), - }, - [ITEM_CONNTRACK] = { - .name = "conntrack", - .help = "conntrack state", - .priv = PRIV_ITEM(CONNTRACK, - sizeof(struct rte_flow_item_conntrack)), - .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), - .call = parse_vc, - }, - [ITEM_PORT_REPRESENTOR] = { - .name = "port_representor", - .help = "match traffic entering the embedded switch from the given ethdev", - .priv = PRIV_ITEM(PORT_REPRESENTOR, - sizeof(struct rte_flow_item_ethdev)), - .next = NEXT(item_port_representor), - .call = parse_vc, - }, - [ITEM_PORT_REPRESENTOR_PORT_ID] = { - .name = "port_id", - .help = "ethdev port ID", - .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), - }, - [ITEM_REPRESENTED_PORT] = { - .name = "represented_port", - .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", - .priv = PRIV_ITEM(REPRESENTED_PORT, - sizeof(struct rte_flow_item_ethdev)), - .next = NEXT(item_represented_port), - .call = parse_vc, - }, - [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { - .name = "ethdev_port_id", - .help = "ethdev port ID", - .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), - }, - [ITEM_FLEX] = { - .name = "flex", - .help = "match flex header", - .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), - .next = NEXT(item_flex), - .call = parse_vc, - }, - [ITEM_FLEX_ITEM_HANDLE] = { - .name = "item", - .help = "flex item handle", - .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), - NEXT_ENTRY(ITEM_PARAM_IS)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), - }, - [ITEM_FLEX_PATTERN_HANDLE] = { - .name = "pattern", - .help = "flex pattern handle", - .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), - NEXT_ENTRY(ITEM_PARAM_IS)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), - }, - [ITEM_L2TPV2] = { - .name = "l2tpv2", - .help = "match L2TPv2 header", - .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), - .next = NEXT(item_l2tpv2), - .call = parse_vc, - }, - [ITEM_L2TPV2_TYPE] = { - .name = "type", - .help = "type of l2tpv2", - .next = NEXT(item_l2tpv2_type), - .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), - }, - [ITEM_L2TPV2_TYPE_DATA] = { - .name = "data", - .help = "Type #7: data message without any options", - .next = NEXT(item_l2tpv2_type_data), - .call = parse_vc_item_l2tpv2_type, - }, - [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { - .name = "tunnel_id", - .help = "tunnel identifier", - .next = NEXT(item_l2tpv2_type_data, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type7.tunnel_id)), - }, - [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { - .name = "session_id", - .help = "session identifier", - .next = NEXT(item_l2tpv2_type_data, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type7.session_id)), - }, - [ITEM_L2TPV2_TYPE_DATA_L] = { - .name = "data_l", - .help = "Type #6: data message with length option", - .next = NEXT(item_l2tpv2_type_data_l), - .call = parse_vc_item_l2tpv2_type, - }, - [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { - .name = "length", - .help = "message length", - .next = NEXT(item_l2tpv2_type_data_l, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type6.length)), - }, - [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { - .name = "tunnel_id", - .help = "tunnel identifier", - .next = NEXT(item_l2tpv2_type_data_l, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type6.tunnel_id)), - }, - [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { - .name = "session_id", - .help = "session identifier", - .next = NEXT(item_l2tpv2_type_data_l, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type6.session_id)), - }, - [ITEM_L2TPV2_TYPE_DATA_S] = { - .name = "data_s", - .help = "Type #5: data message with ns, nr option", - .next = NEXT(item_l2tpv2_type_data_s), - .call = parse_vc_item_l2tpv2_type, - }, - [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { - .name = "tunnel_id", - .help = "tunnel identifier", - .next = NEXT(item_l2tpv2_type_data_s, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type5.tunnel_id)), - }, - [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { - .name = "session_id", - .help = "session identifier", - .next = NEXT(item_l2tpv2_type_data_s, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type5.session_id)), - }, - [ITEM_L2TPV2_MSG_DATA_S_NS] = { - .name = "ns", - .help = "sequence number for message", - .next = NEXT(item_l2tpv2_type_data_s, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type5.ns)), - }, - [ITEM_L2TPV2_MSG_DATA_S_NR] = { - .name = "nr", - .help = "sequence number for next receive message", - .next = NEXT(item_l2tpv2_type_data_s, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type5.nr)), - }, - [ITEM_L2TPV2_TYPE_DATA_O] = { - .name = "data_o", - .help = "Type #4: data message with offset option", - .next = NEXT(item_l2tpv2_type_data_o), - .call = parse_vc_item_l2tpv2_type, - }, - [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { - .name = "tunnel_id", - .help = "tunnel identifier", - .next = NEXT(item_l2tpv2_type_data_o, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type4.tunnel_id)), - }, - [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { - .name = "session_id", - .help = "session identifier", - .next = NEXT(item_l2tpv2_type_data_o, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type5.session_id)), - }, - [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { - .name = "offset_size", - .help = "the size of offset padding", - .next = NEXT(item_l2tpv2_type_data_o, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type4.offset_size)), - }, - [ITEM_L2TPV2_TYPE_DATA_L_S] = { - .name = "data_l_s", - .help = "Type #3: data message contains length, ns, nr " - "options", - .next = NEXT(item_l2tpv2_type_data_l_s), - .call = parse_vc_item_l2tpv2_type, - }, - [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { - .name = "length", - .help = "message length", - .next = NEXT(item_l2tpv2_type_data_l_s, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type3.length)), - }, - [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { - .name = "tunnel_id", - .help = "tunnel identifier", - .next = NEXT(item_l2tpv2_type_data_l_s, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type3.tunnel_id)), - }, - [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { - .name = "session_id", - .help = "session identifier", - .next = NEXT(item_l2tpv2_type_data_l_s, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type3.session_id)), - }, - [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { - .name = "ns", - .help = "sequence number for message", - .next = NEXT(item_l2tpv2_type_data_l_s, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type3.ns)), - }, - [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { - .name = "nr", - .help = "sequence number for next receive message", - .next = NEXT(item_l2tpv2_type_data_l_s, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type3.nr)), - }, - [ITEM_L2TPV2_TYPE_CTRL] = { - .name = "control", - .help = "Type #3: conrtol message contains length, ns, nr " - "options", - .next = NEXT(item_l2tpv2_type_ctrl), - .call = parse_vc_item_l2tpv2_type, - }, - [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { - .name = "length", - .help = "message length", - .next = NEXT(item_l2tpv2_type_ctrl, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type3.length)), - }, - [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { - .name = "tunnel_id", - .help = "tunnel identifier", - .next = NEXT(item_l2tpv2_type_ctrl, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type3.tunnel_id)), - }, - [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { - .name = "session_id", - .help = "session identifier", - .next = NEXT(item_l2tpv2_type_ctrl, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type3.session_id)), - }, - [ITEM_L2TPV2_MSG_CTRL_NS] = { - .name = "ns", - .help = "sequence number for message", - .next = NEXT(item_l2tpv2_type_ctrl, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type3.ns)), - }, - [ITEM_L2TPV2_MSG_CTRL_NR] = { - .name = "nr", - .help = "sequence number for next receive message", - .next = NEXT(item_l2tpv2_type_ctrl, - NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, - hdr.type3.nr)), - }, - [ITEM_PPP] = { - .name = "ppp", - .help = "match PPP header", - .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), - .next = NEXT(item_ppp), - .call = parse_vc, - }, - [ITEM_PPP_ADDR] = { - .name = "addr", - .help = "PPP address", - .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), - }, - [ITEM_PPP_CTRL] = { - .name = "ctrl", - .help = "PPP control", - .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), - }, - [ITEM_PPP_PROTO_ID] = { - .name = "proto_id", - .help = "PPP protocol identifier", - .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, - hdr.proto_id)), - }, - [ITEM_METER] = { - .name = "meter", - .help = "match meter color", - .priv = PRIV_ITEM(METER_COLOR, - sizeof(struct rte_flow_item_meter_color)), - .next = NEXT(item_meter), - .call = parse_vc, - }, - [ITEM_METER_COLOR] = { - .name = "color", - .help = "meter color", - .next = NEXT(item_meter, - NEXT_ENTRY(COMMON_METER_COLOR_NAME), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, - color)), - }, - [ITEM_QUOTA] = { - .name = "quota", - .help = "match quota", - .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), - .next = NEXT(item_quota), - .call = parse_vc - }, - [ITEM_QUOTA_STATE] = { - .name = "quota_state", - .help = "quota state", - .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), - NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) - }, - [ITEM_QUOTA_STATE_NAME] = { - .name = "state_name", - .help = "quota state name", - .call = parse_quota_state_name, - .comp = comp_quota_state_name - }, - [ITEM_IB_BTH] = { - .name = "ib_bth", - .help = "match ib bth fields", - .priv = PRIV_ITEM(IB_BTH, - sizeof(struct rte_flow_item_ib_bth)), - .next = NEXT(item_ib_bth), - .call = parse_vc, - }, - [ITEM_IB_BTH_OPCODE] = { - .name = "opcode", - .help = "match ib bth opcode", - .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, - hdr.opcode)), - }, - [ITEM_IB_BTH_PKEY] = { - .name = "pkey", - .help = "partition key", - .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, - hdr.pkey)), - }, - [ITEM_IB_BTH_DST_QPN] = { - .name = "dst_qp", - .help = "destination qp", - .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, - hdr.dst_qp)), - }, - [ITEM_IB_BTH_PSN] = { - .name = "psn", - .help = "packet sequence number", - .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, - hdr.psn)), - }, - [ITEM_PTYPE] = { - .name = "ptype", - .help = "match L2/L3/L4 and tunnel information", - .priv = PRIV_ITEM(PTYPE, - sizeof(struct rte_flow_item_ptype)), - .next = NEXT(item_ptype), - .call = parse_vc, - }, - [ITEM_PTYPE_VALUE] = { - .name = "packet_type", - .help = "packet type as defined in rte_mbuf_ptype", - .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), - }, - [ITEM_NSH] = { - .name = "nsh", - .help = "match NSH header", - .priv = PRIV_ITEM(NSH, - sizeof(struct rte_flow_item_nsh)), - .next = NEXT(item_nsh), - .call = parse_vc, - }, - [ITEM_COMPARE] = { - .name = "compare", - .help = "match with the comparison result", - .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), - .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), - .call = parse_vc, - }, - [ITEM_COMPARE_OP] = { - .name = "op", - .help = "operation type", - .next = NEXT(item_compare_field, - NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), - }, - [ITEM_COMPARE_OP_VALUE] = { - .name = "{operation}", - .help = "operation type value", - .call = parse_vc_compare_op, - .comp = comp_set_compare_op, - }, - [ITEM_COMPARE_FIELD_A_TYPE] = { - .name = "a_type", - .help = "compared field type", - .next = NEXT(compare_field_a, - NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), - }, - [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { - .name = "{a_type}", - .help = "compared field type value", - .call = parse_vc_compare_field_id, - .comp = comp_set_compare_field_id, - }, - [ITEM_COMPARE_FIELD_A_LEVEL] = { - .name = "a_level", - .help = "compared field level", - .next = NEXT(compare_field_a, - NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), - }, - [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { - .name = "{a_level}", - .help = "compared field level value", - .call = parse_vc_compare_field_level, - .comp = comp_none, - }, - [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { - .name = "a_tag_index", - .help = "compared field tag array", - .next = NEXT(compare_field_a, - NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, - a.tag_index)), - }, - [ITEM_COMPARE_FIELD_A_TYPE_ID] = { - .name = "a_type_id", - .help = "compared field type ID", - .next = NEXT(compare_field_a, - NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, - a.type)), - }, - [ITEM_COMPARE_FIELD_A_CLASS_ID] = { - .name = "a_class", - .help = "compared field class ID", - .next = NEXT(compare_field_a, - NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, - a.class_id)), - }, - [ITEM_COMPARE_FIELD_A_OFFSET] = { - .name = "a_offset", - .help = "compared field bit offset", - .next = NEXT(compare_field_a, - NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, - a.offset)), - }, - [ITEM_COMPARE_FIELD_B_TYPE] = { - .name = "b_type", - .help = "comparator field type", - .next = NEXT(compare_field_b, - NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, - b.field)), - }, - [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { - .name = "{b_type}", - .help = "comparator field type value", - .call = parse_vc_compare_field_id, - .comp = comp_set_compare_field_id, - }, - [ITEM_COMPARE_FIELD_B_LEVEL] = { - .name = "b_level", - .help = "comparator field level", - .next = NEXT(compare_field_b, - NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, - b.level)), - }, - [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { - .name = "{b_level}", - .help = "comparator field level value", - .call = parse_vc_compare_field_level, - .comp = comp_none, - }, - [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { - .name = "b_tag_index", - .help = "comparator field tag array", - .next = NEXT(compare_field_b, - NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, - b.tag_index)), - }, - [ITEM_COMPARE_FIELD_B_TYPE_ID] = { - .name = "b_type_id", - .help = "comparator field type ID", - .next = NEXT(compare_field_b, - NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, - b.type)), - }, - [ITEM_COMPARE_FIELD_B_CLASS_ID] = { - .name = "b_class", - .help = "comparator field class ID", - .next = NEXT(compare_field_b, - NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, - b.class_id)), - }, - [ITEM_COMPARE_FIELD_B_OFFSET] = { - .name = "b_offset", - .help = "comparator field bit offset", - .next = NEXT(compare_field_b, - NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, - b.offset)), - }, - [ITEM_COMPARE_FIELD_B_VALUE] = { - .name = "b_value", - .help = "comparator immediate value", - .next = NEXT(compare_field_b, - NEXT_ENTRY(COMMON_HEX), item_param), - .args = ARGS(ARGS_ENTRY_ARB(0, 0), - ARGS_ENTRY_ARB(0, 0), - ARGS_ENTRY(struct rte_flow_item_compare, - b.value)), - }, - [ITEM_COMPARE_FIELD_B_POINTER] = { - .name = "b_ptr", - .help = "pointer to comparator immediate value", - .next = NEXT(compare_field_b, - NEXT_ENTRY(COMMON_HEX), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, - b.pvalue), - ARGS_ENTRY_ARB(0, 0), - ARGS_ENTRY_ARB - (sizeof(struct rte_flow_item_compare), - FLOW_FIELD_PATTERN_SIZE)), - }, - [ITEM_COMPARE_FIELD_WIDTH] = { - .name = "width", - .help = "number of bits to compare", - .next = NEXT(item_compare_field, - NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, - width)), - }, - - /* Validate/create actions. */ - [ACTIONS] = { - .name = "actions", - .help = "submit a list of associated actions", - .next = NEXT(next_action), - .call = parse_vc, - }, - [ACTION_NEXT] = { - .name = "/", - .help = "specify next action", - .next = NEXT(next_action), - }, - [ACTION_END] = { - .name = "end", - .help = "end list of actions", - .priv = PRIV_ACTION(END, 0), - .call = parse_vc, - }, - [ACTION_VOID] = { - .name = "void", - .help = "no-op action", - .priv = PRIV_ACTION(VOID, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_PASSTHRU] = { - .name = "passthru", - .help = "let subsequent rule process matched packets", - .priv = PRIV_ACTION(PASSTHRU, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_SKIP_CMAN] = { - .name = "skip_cman", - .help = "bypass cman on received packets", - .priv = PRIV_ACTION(SKIP_CMAN, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_JUMP] = { - .name = "jump", - .help = "redirect traffic to a given group", - .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), - .next = NEXT(action_jump), - .call = parse_vc, - }, - [ACTION_JUMP_GROUP] = { - .name = "group", - .help = "group to redirect traffic to", - .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), - .call = parse_vc_conf, - }, - [ACTION_MARK] = { - .name = "mark", - .help = "attach 32 bit value to packets", - .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), - .next = NEXT(action_mark), - .call = parse_vc, - }, - [ACTION_MARK_ID] = { - .name = "id", - .help = "32 bit value to return with packets", - .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), - .call = parse_vc_conf, - }, - [ACTION_FLAG] = { - .name = "flag", - .help = "flag packets", - .priv = PRIV_ACTION(FLAG, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_QUEUE] = { - .name = "queue", - .help = "assign packets to a given queue index", - .priv = PRIV_ACTION(QUEUE, - sizeof(struct rte_flow_action_queue)), - .next = NEXT(action_queue), - .call = parse_vc, - }, - [ACTION_QUEUE_INDEX] = { - .name = "index", - .help = "queue index to use", - .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), - .call = parse_vc_conf, - }, - [ACTION_DROP] = { - .name = "drop", - .help = "drop packets (note: passthru has priority)", - .priv = PRIV_ACTION(DROP, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_COUNT] = { - .name = "count", - .help = "enable counters for this rule", - .priv = PRIV_ACTION(COUNT, - sizeof(struct rte_flow_action_count)), - .next = NEXT(action_count), - .call = parse_vc, - }, - [ACTION_COUNT_ID] = { - .name = "identifier", - .help = "counter identifier to use", - .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), - .call = parse_vc_conf, - }, - [ACTION_RSS] = { - .name = "rss", - .help = "spread packets among several queues", - .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), - .next = NEXT(action_rss), - .call = parse_vc_action_rss, - }, - [ACTION_RSS_FUNC] = { - .name = "func", - .help = "RSS hash function to apply", - .next = NEXT(action_rss, - NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, - ACTION_RSS_FUNC_TOEPLITZ, - ACTION_RSS_FUNC_SIMPLE_XOR, - ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), - }, - [ACTION_RSS_FUNC_DEFAULT] = { - .name = "default", - .help = "default hash function", - .call = parse_vc_action_rss_func, - }, - [ACTION_RSS_FUNC_TOEPLITZ] = { - .name = "toeplitz", - .help = "Toeplitz hash function", - .call = parse_vc_action_rss_func, - }, - [ACTION_RSS_FUNC_SIMPLE_XOR] = { - .name = "simple_xor", - .help = "simple XOR hash function", - .call = parse_vc_action_rss_func, - }, - [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { - .name = "symmetric_toeplitz", - .help = "Symmetric Toeplitz hash function", - .call = parse_vc_action_rss_func, - }, - [ACTION_RSS_LEVEL] = { - .name = "level", - .help = "encapsulation level for \"types\"", - .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_ARB - (offsetof(struct action_rss_data, conf) + - offsetof(struct rte_flow_action_rss, level), - sizeof(((struct rte_flow_action_rss *)0)-> - level))), - }, - [ACTION_RSS_TYPES] = { - .name = "types", - .help = "specific RSS hash types", - .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), - }, - [ACTION_RSS_TYPE] = { - .name = "{type}", - .help = "RSS hash type", - .call = parse_vc_action_rss_type, - .comp = comp_vc_action_rss_type, - }, - [ACTION_RSS_KEY] = { - .name = "key", - .help = "RSS hash key", - .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), - .args = ARGS(ARGS_ENTRY_ARB - (offsetof(struct action_rss_data, conf) + - offsetof(struct rte_flow_action_rss, key), - sizeof(((struct rte_flow_action_rss *)0)->key)), - ARGS_ENTRY_ARB - (offsetof(struct action_rss_data, conf) + - offsetof(struct rte_flow_action_rss, key_len), - sizeof(((struct rte_flow_action_rss *)0)-> - key_len)), - ARGS_ENTRY(struct action_rss_data, key)), - }, - [ACTION_RSS_KEY_LEN] = { - .name = "key_len", - .help = "RSS hash key length in bytes", - .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct action_rss_data, conf) + - offsetof(struct rte_flow_action_rss, key_len), - sizeof(((struct rte_flow_action_rss *)0)-> - key_len), - 0, - RSS_HASH_KEY_LENGTH)), - }, - [ACTION_RSS_QUEUES] = { - .name = "queues", - .help = "queue indices to use", - .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), - .call = parse_vc_conf, - }, - [ACTION_RSS_QUEUE] = { - .name = "{queue}", - .help = "queue index", - .call = parse_vc_action_rss_queue, - .comp = comp_vc_action_rss_queue, - }, - [ACTION_PF] = { - .name = "pf", - .help = "direct traffic to physical function", - .priv = PRIV_ACTION(PF, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_VF] = { - .name = "vf", - .help = "direct traffic to a virtual function ID", - .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), - .next = NEXT(action_vf), - .call = parse_vc, - }, - [ACTION_VF_ORIGINAL] = { - .name = "original", - .help = "use original VF ID if possible", - .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, - original, 1)), - .call = parse_vc_conf, - }, - [ACTION_VF_ID] = { - .name = "id", - .help = "VF ID", - .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), - .call = parse_vc_conf, - }, - [ACTION_PORT_ID] = { - .name = "port_id", - .help = "direct matching traffic to a given DPDK port ID", - .priv = PRIV_ACTION(PORT_ID, - sizeof(struct rte_flow_action_port_id)), - .next = NEXT(action_port_id), - .call = parse_vc, - }, - [ACTION_PORT_ID_ORIGINAL] = { - .name = "original", - .help = "use original DPDK port ID if possible", - .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, - original, 1)), - .call = parse_vc_conf, - }, - [ACTION_PORT_ID_ID] = { - .name = "id", - .help = "DPDK port ID", - .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), - .call = parse_vc_conf, - }, - [ACTION_METER] = { - .name = "meter", - .help = "meter the directed packets at given id", - .priv = PRIV_ACTION(METER, - sizeof(struct rte_flow_action_meter)), - .next = NEXT(action_meter), - .call = parse_vc, - }, - [ACTION_METER_COLOR] = { - .name = "color", - .help = "meter color for the packets", - .priv = PRIV_ACTION(METER_COLOR, - sizeof(struct rte_flow_action_meter_color)), - .next = NEXT(action_meter_color), - .call = parse_vc, - }, - [ACTION_METER_COLOR_TYPE] = { - .name = "type", - .help = "specific meter color", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT), - NEXT_ENTRY(ACTION_METER_COLOR_GREEN, - ACTION_METER_COLOR_YELLOW, - ACTION_METER_COLOR_RED)), - }, - [ACTION_METER_COLOR_GREEN] = { - .name = "green", - .help = "meter color green", - .call = parse_vc_action_meter_color_type, - }, - [ACTION_METER_COLOR_YELLOW] = { - .name = "yellow", - .help = "meter color yellow", - .call = parse_vc_action_meter_color_type, - }, - [ACTION_METER_COLOR_RED] = { - .name = "red", - .help = "meter color red", - .call = parse_vc_action_meter_color_type, - }, - [ACTION_METER_ID] = { - .name = "mtr_id", - .help = "meter id to use", - .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), - .call = parse_vc_conf, - }, - [ACTION_METER_MARK] = { - .name = "meter_mark", - .help = "meter the directed packets using profile and policy", - .priv = PRIV_ACTION(METER_MARK, - sizeof(struct rte_flow_action_meter_mark)), - .next = NEXT(action_meter_mark), - .call = parse_vc, - }, - [ACTION_METER_MARK_CONF] = { - .name = "meter_mark_conf", - .help = "meter mark configuration", - .priv = PRIV_ACTION(METER_MARK, - sizeof(struct rte_flow_action_meter_mark)), - .next = NEXT(NEXT_ENTRY(ACTION_METER_MARK_CONF_COLOR)), - .call = parse_vc, - }, - [ACTION_METER_MARK_CONF_COLOR] = { - .name = "mtr_update_init_color", - .help = "meter update init color", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT), - NEXT_ENTRY(COMMON_METER_COLOR_NAME)), - .args = ARGS(ARGS_ENTRY - (struct rte_flow_indirect_update_flow_meter_mark, - init_color)), - }, - [ACTION_METER_PROFILE] = { - .name = "mtr_profile", - .help = "meter profile id to use", - .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), - .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), - }, - [ACTION_METER_PROFILE_ID2PTR] = { - .name = "{mtr_profile_id}", - .type = "PROFILE_ID", - .help = "meter profile id", - .next = NEXT(action_meter_mark), - .call = parse_meter_profile_id2ptr, - .comp = comp_none, - }, - [ACTION_METER_POLICY] = { - .name = "mtr_policy", - .help = "meter policy id to use", - .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), - ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), - }, - [ACTION_METER_POLICY_ID2PTR] = { - .name = "{mtr_policy_id}", - .type = "POLICY_ID", - .help = "meter policy id", - .next = NEXT(action_meter_mark), - .call = parse_meter_policy_id2ptr, - .comp = comp_none, - }, - [ACTION_METER_COLOR_MODE] = { - .name = "mtr_color_mode", - .help = "meter color awareness mode", - .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), - .call = parse_vc_conf, - }, - [ACTION_METER_STATE] = { - .name = "mtr_state", - .help = "meter state", - .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), - .call = parse_vc_conf, - }, - [ACTION_OF_DEC_NW_TTL] = { - .name = "of_dec_nw_ttl", - .help = "OpenFlow's OFPAT_DEC_NW_TTL", - .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_OF_POP_VLAN] = { - .name = "of_pop_vlan", - .help = "OpenFlow's OFPAT_POP_VLAN", - .priv = PRIV_ACTION(OF_POP_VLAN, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_OF_PUSH_VLAN] = { - .name = "of_push_vlan", - .help = "OpenFlow's OFPAT_PUSH_VLAN", - .priv = PRIV_ACTION - (OF_PUSH_VLAN, - sizeof(struct rte_flow_action_of_push_vlan)), - .next = NEXT(action_of_push_vlan), - .call = parse_vc, - }, - [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { - .name = "ethertype", - .help = "EtherType", - .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_of_push_vlan, - ethertype)), - .call = parse_vc_conf, - }, - [ACTION_OF_SET_VLAN_VID] = { - .name = "of_set_vlan_vid", - .help = "OpenFlow's OFPAT_SET_VLAN_VID", - .priv = PRIV_ACTION - (OF_SET_VLAN_VID, - sizeof(struct rte_flow_action_of_set_vlan_vid)), - .next = NEXT(action_of_set_vlan_vid), - .call = parse_vc, - }, - [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { - .name = "vlan_vid", - .help = "VLAN id", - .next = NEXT(action_of_set_vlan_vid, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_of_set_vlan_vid, - vlan_vid)), - .call = parse_vc_conf, - }, - [ACTION_OF_SET_VLAN_PCP] = { - .name = "of_set_vlan_pcp", - .help = "OpenFlow's OFPAT_SET_VLAN_PCP", - .priv = PRIV_ACTION - (OF_SET_VLAN_PCP, - sizeof(struct rte_flow_action_of_set_vlan_pcp)), - .next = NEXT(action_of_set_vlan_pcp), - .call = parse_vc, - }, - [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { - .name = "vlan_pcp", - .help = "VLAN priority", - .next = NEXT(action_of_set_vlan_pcp, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_of_set_vlan_pcp, - vlan_pcp)), - .call = parse_vc_conf, - }, - [ACTION_OF_POP_MPLS] = { - .name = "of_pop_mpls", - .help = "OpenFlow's OFPAT_POP_MPLS", - .priv = PRIV_ACTION(OF_POP_MPLS, - sizeof(struct rte_flow_action_of_pop_mpls)), - .next = NEXT(action_of_pop_mpls), - .call = parse_vc, - }, - [ACTION_OF_POP_MPLS_ETHERTYPE] = { - .name = "ethertype", - .help = "EtherType", - .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_of_pop_mpls, - ethertype)), - .call = parse_vc_conf, - }, - [ACTION_OF_PUSH_MPLS] = { - .name = "of_push_mpls", - .help = "OpenFlow's OFPAT_PUSH_MPLS", - .priv = PRIV_ACTION - (OF_PUSH_MPLS, - sizeof(struct rte_flow_action_of_push_mpls)), - .next = NEXT(action_of_push_mpls), - .call = parse_vc, - }, - [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { - .name = "ethertype", - .help = "EtherType", - .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_of_push_mpls, - ethertype)), - .call = parse_vc_conf, - }, - [ACTION_VXLAN_ENCAP] = { - .name = "vxlan_encap", - .help = "VXLAN encapsulation, uses configuration set by \"set" - " vxlan\"", - .priv = PRIV_ACTION(VXLAN_ENCAP, - sizeof(struct action_vxlan_encap_data)), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_vxlan_encap, - }, - [ACTION_VXLAN_DECAP] = { - .name = "vxlan_decap", - .help = "Performs a decapsulation action by stripping all" - " headers of the VXLAN tunnel network overlay from the" - " matched flow.", - .priv = PRIV_ACTION(VXLAN_DECAP, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_NVGRE_ENCAP] = { - .name = "nvgre_encap", - .help = "NVGRE encapsulation, uses configuration set by \"set" - " nvgre\"", - .priv = PRIV_ACTION(NVGRE_ENCAP, - sizeof(struct action_nvgre_encap_data)), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_nvgre_encap, - }, - [ACTION_NVGRE_DECAP] = { - .name = "nvgre_decap", - .help = "Performs a decapsulation action by stripping all" - " headers of the NVGRE tunnel network overlay from the" - " matched flow.", - .priv = PRIV_ACTION(NVGRE_DECAP, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_L2_ENCAP] = { - .name = "l2_encap", - .help = "l2 encap, uses configuration set by" - " \"set l2_encap\"", - .priv = PRIV_ACTION(RAW_ENCAP, - sizeof(struct action_raw_encap_data)), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_l2_encap, - }, - [ACTION_L2_DECAP] = { - .name = "l2_decap", - .help = "l2 decap, uses configuration set by" - " \"set l2_decap\"", - .priv = PRIV_ACTION(RAW_DECAP, - sizeof(struct action_raw_decap_data)), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_l2_decap, - }, - [ACTION_MPLSOGRE_ENCAP] = { - .name = "mplsogre_encap", - .help = "mplsogre encapsulation, uses configuration set by" - " \"set mplsogre_encap\"", - .priv = PRIV_ACTION(RAW_ENCAP, - sizeof(struct action_raw_encap_data)), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_mplsogre_encap, - }, - [ACTION_MPLSOGRE_DECAP] = { - .name = "mplsogre_decap", - .help = "mplsogre decapsulation, uses configuration set by" - " \"set mplsogre_decap\"", - .priv = PRIV_ACTION(RAW_DECAP, - sizeof(struct action_raw_decap_data)), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_mplsogre_decap, - }, - [ACTION_MPLSOUDP_ENCAP] = { - .name = "mplsoudp_encap", - .help = "mplsoudp encapsulation, uses configuration set by" - " \"set mplsoudp_encap\"", - .priv = PRIV_ACTION(RAW_ENCAP, - sizeof(struct action_raw_encap_data)), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_mplsoudp_encap, - }, - [ACTION_MPLSOUDP_DECAP] = { - .name = "mplsoudp_decap", - .help = "mplsoudp decapsulation, uses configuration set by" - " \"set mplsoudp_decap\"", - .priv = PRIV_ACTION(RAW_DECAP, - sizeof(struct action_raw_decap_data)), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_mplsoudp_decap, - }, - [ACTION_SET_IPV4_SRC] = { - .name = "set_ipv4_src", - .help = "Set a new IPv4 source address in the outermost" - " IPv4 header", - .priv = PRIV_ACTION(SET_IPV4_SRC, - sizeof(struct rte_flow_action_set_ipv4)), - .next = NEXT(action_set_ipv4_src), - .call = parse_vc, - }, - [ACTION_SET_IPV4_SRC_IPV4_SRC] = { - .name = "ipv4_addr", - .help = "new IPv4 source address to set", - .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_set_ipv4, ipv4_addr)), - .call = parse_vc_conf, - }, - [ACTION_SET_IPV4_DST] = { - .name = "set_ipv4_dst", - .help = "Set a new IPv4 destination address in the outermost" - " IPv4 header", - .priv = PRIV_ACTION(SET_IPV4_DST, - sizeof(struct rte_flow_action_set_ipv4)), - .next = NEXT(action_set_ipv4_dst), - .call = parse_vc, - }, - [ACTION_SET_IPV4_DST_IPV4_DST] = { - .name = "ipv4_addr", - .help = "new IPv4 destination address to set", - .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_set_ipv4, ipv4_addr)), - .call = parse_vc_conf, - }, - [ACTION_SET_IPV6_SRC] = { - .name = "set_ipv6_src", - .help = "Set a new IPv6 source address in the outermost" - " IPv6 header", - .priv = PRIV_ACTION(SET_IPV6_SRC, - sizeof(struct rte_flow_action_set_ipv6)), - .next = NEXT(action_set_ipv6_src), - .call = parse_vc, - }, - [ACTION_SET_IPV6_SRC_IPV6_SRC] = { - .name = "ipv6_addr", - .help = "new IPv6 source address to set", - .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_set_ipv6, ipv6_addr)), - .call = parse_vc_conf, - }, - [ACTION_SET_IPV6_DST] = { - .name = "set_ipv6_dst", - .help = "Set a new IPv6 destination address in the outermost" - " IPv6 header", - .priv = PRIV_ACTION(SET_IPV6_DST, - sizeof(struct rte_flow_action_set_ipv6)), - .next = NEXT(action_set_ipv6_dst), - .call = parse_vc, - }, - [ACTION_SET_IPV6_DST_IPV6_DST] = { - .name = "ipv6_addr", - .help = "new IPv6 destination address to set", - .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_set_ipv6, ipv6_addr)), - .call = parse_vc_conf, - }, - [ACTION_SET_TP_SRC] = { - .name = "set_tp_src", - .help = "set a new source port number in the outermost" - " TCP/UDP header", - .priv = PRIV_ACTION(SET_TP_SRC, - sizeof(struct rte_flow_action_set_tp)), - .next = NEXT(action_set_tp_src), - .call = parse_vc, - }, - [ACTION_SET_TP_SRC_TP_SRC] = { - .name = "port", - .help = "new source port number to set", - .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_set_tp, port)), - .call = parse_vc_conf, - }, - [ACTION_SET_TP_DST] = { - .name = "set_tp_dst", - .help = "set a new destination port number in the outermost" - " TCP/UDP header", - .priv = PRIV_ACTION(SET_TP_DST, - sizeof(struct rte_flow_action_set_tp)), - .next = NEXT(action_set_tp_dst), - .call = parse_vc, - }, - [ACTION_SET_TP_DST_TP_DST] = { - .name = "port", - .help = "new destination port number to set", - .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_set_tp, port)), - .call = parse_vc_conf, - }, - [ACTION_MAC_SWAP] = { - .name = "mac_swap", - .help = "Swap the source and destination MAC addresses" - " in the outermost Ethernet header", - .priv = PRIV_ACTION(MAC_SWAP, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_DEC_TTL] = { - .name = "dec_ttl", - .help = "decrease network TTL if available", - .priv = PRIV_ACTION(DEC_TTL, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_SET_TTL] = { - .name = "set_ttl", - .help = "set ttl value", - .priv = PRIV_ACTION(SET_TTL, - sizeof(struct rte_flow_action_set_ttl)), - .next = NEXT(action_set_ttl), - .call = parse_vc, - }, - [ACTION_SET_TTL_TTL] = { - .name = "ttl_value", - .help = "new ttl value to set", - .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_set_ttl, ttl_value)), - .call = parse_vc_conf, - }, - [ACTION_SET_MAC_SRC] = { - .name = "set_mac_src", - .help = "set source mac address", - .priv = PRIV_ACTION(SET_MAC_SRC, - sizeof(struct rte_flow_action_set_mac)), - .next = NEXT(action_set_mac_src), - .call = parse_vc, - }, - [ACTION_SET_MAC_SRC_MAC_SRC] = { - .name = "mac_addr", - .help = "new source mac address", - .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_set_mac, mac_addr)), - .call = parse_vc_conf, - }, - [ACTION_SET_MAC_DST] = { - .name = "set_mac_dst", - .help = "set destination mac address", - .priv = PRIV_ACTION(SET_MAC_DST, - sizeof(struct rte_flow_action_set_mac)), - .next = NEXT(action_set_mac_dst), - .call = parse_vc, - }, - [ACTION_SET_MAC_DST_MAC_DST] = { - .name = "mac_addr", - .help = "new destination mac address to set", - .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), - .args = ARGS(ARGS_ENTRY_HTON - (struct rte_flow_action_set_mac, mac_addr)), - .call = parse_vc_conf, - }, - [ACTION_INC_TCP_SEQ] = { - .name = "inc_tcp_seq", - .help = "increase TCP sequence number", - .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), - .next = NEXT(action_inc_tcp_seq), - .call = parse_vc, - }, - [ACTION_INC_TCP_SEQ_VALUE] = { - .name = "value", - .help = "the value to increase TCP sequence number by", - .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), - .call = parse_vc_conf, - }, - [ACTION_DEC_TCP_SEQ] = { - .name = "dec_tcp_seq", - .help = "decrease TCP sequence number", - .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), - .next = NEXT(action_dec_tcp_seq), - .call = parse_vc, - }, - [ACTION_DEC_TCP_SEQ_VALUE] = { - .name = "value", - .help = "the value to decrease TCP sequence number by", - .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), - .call = parse_vc_conf, - }, - [ACTION_INC_TCP_ACK] = { - .name = "inc_tcp_ack", - .help = "increase TCP acknowledgment number", - .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), - .next = NEXT(action_inc_tcp_ack), - .call = parse_vc, - }, - [ACTION_INC_TCP_ACK_VALUE] = { - .name = "value", - .help = "the value to increase TCP acknowledgment number by", - .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), - .call = parse_vc_conf, - }, - [ACTION_DEC_TCP_ACK] = { - .name = "dec_tcp_ack", - .help = "decrease TCP acknowledgment number", - .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), - .next = NEXT(action_dec_tcp_ack), - .call = parse_vc, - }, - [ACTION_DEC_TCP_ACK_VALUE] = { - .name = "value", - .help = "the value to decrease TCP acknowledgment number by", - .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), - .call = parse_vc_conf, - }, - [ACTION_RAW_ENCAP] = { - .name = "raw_encap", - .help = "encapsulation data, defined by set raw_encap", - .priv = PRIV_ACTION(RAW_ENCAP, - sizeof(struct action_raw_encap_data)), - .next = NEXT(action_raw_encap), - .call = parse_vc_action_raw_encap, - }, - [ACTION_RAW_ENCAP_SIZE] = { - .name = "size", - .help = "raw encap size", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT), - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), - .call = parse_vc_conf, - }, - [ACTION_RAW_ENCAP_INDEX] = { - .name = "index", - .help = "the index of raw_encap_confs", - .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), - }, - [ACTION_RAW_ENCAP_INDEX_VALUE] = { - .name = "{index}", - .type = "UNSIGNED", - .help = "unsigned integer value", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_raw_encap_index, - .comp = comp_set_raw_index, - }, - [ACTION_RAW_DECAP] = { - .name = "raw_decap", - .help = "decapsulation data, defined by set raw_encap", - .priv = PRIV_ACTION(RAW_DECAP, - sizeof(struct action_raw_decap_data)), - .next = NEXT(action_raw_decap), - .call = parse_vc_action_raw_decap, - }, - [ACTION_RAW_DECAP_INDEX] = { - .name = "index", - .help = "the index of raw_encap_confs", - .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), - }, - [ACTION_RAW_DECAP_INDEX_VALUE] = { - .name = "{index}", - .type = "UNSIGNED", - .help = "unsigned integer value", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_raw_decap_index, - .comp = comp_set_raw_index, - }, - [ACTION_MODIFY_FIELD] = { - .name = "modify_field", - .help = "modify destination field with data from source field", - .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), - .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), - .call = parse_vc, - }, - [ACTION_MODIFY_FIELD_OP] = { - .name = "op", - .help = "operation type", - .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), - NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_OP_VALUE] = { - .name = "{operation}", - .help = "operation type value", - .call = parse_vc_modify_field_op, - .comp = comp_set_modify_field_op, - }, - [ACTION_MODIFY_FIELD_DST_TYPE] = { - .name = "dst_type", - .help = "destination field type", - .next = NEXT(action_modify_field_dst, - NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { - .name = "{dst_type}", - .help = "destination field type value", - .call = parse_vc_modify_field_id, - .comp = comp_set_modify_field_id, - }, - [ACTION_MODIFY_FIELD_DST_LEVEL] = { - .name = "dst_level", - .help = "destination field level", - .next = NEXT(action_modify_field_dst, - NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { - .name = "{dst_level}", - .help = "destination field level value", - .call = parse_vc_modify_field_level, - .comp = comp_none, - }, - [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { - .name = "dst_tag_index", - .help = "destination field tag array", - .next = NEXT(action_modify_field_dst, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, - dst.tag_index)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { - .name = "dst_type_id", - .help = "destination field type ID", - .next = NEXT(action_modify_field_dst, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, - dst.type)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { - .name = "dst_class", - .help = "destination field class ID", - .next = NEXT(action_modify_field_dst, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, - dst.class_id)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_DST_OFFSET] = { - .name = "dst_offset", - .help = "destination field bit offset", - .next = NEXT(action_modify_field_dst, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, - dst.offset)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_SRC_TYPE] = { - .name = "src_type", - .help = "source field type", - .next = NEXT(action_modify_field_src, - NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { - .name = "{src_type}", - .help = "source field type value", - .call = parse_vc_modify_field_id, - .comp = comp_set_modify_field_id, - }, - [ACTION_MODIFY_FIELD_SRC_LEVEL] = { - .name = "src_level", - .help = "source field level", - .next = NEXT(action_modify_field_src, - NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { - .name = "{src_level}", - .help = "source field level value", - .call = parse_vc_modify_field_level, - .comp = comp_none, - }, - [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { - .name = "src_tag_index", - .help = "source field tag array", - .next = NEXT(action_modify_field_src, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, - src.tag_index)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { - .name = "src_type_id", - .help = "source field type ID", - .next = NEXT(action_modify_field_src, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, - src.type)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { - .name = "src_class", - .help = "source field class ID", - .next = NEXT(action_modify_field_src, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, - src.class_id)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_SRC_OFFSET] = { - .name = "src_offset", - .help = "source field bit offset", - .next = NEXT(action_modify_field_src, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, - src.offset)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_SRC_VALUE] = { - .name = "src_value", - .help = "source immediate value", - .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), - 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), - FLOW_FIELD_PATTERN_SIZE)), - .call = parse_vc_conf, - }, - [ACTION_MODIFY_FIELD_WIDTH] = { - .name = "width", - .help = "number of bits to copy", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT), - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, - width)), - .call = parse_vc_conf, - }, - [ACTION_SEND_TO_KERNEL] = { - .name = "send_to_kernel", - .help = "send packets to kernel", - .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc, - }, - [ACTION_IPV6_EXT_REMOVE] = { - .name = "ipv6_ext_remove", - .help = "IPv6 extension type, defined by set ipv6_ext_remove", - .priv = PRIV_ACTION(IPV6_EXT_REMOVE, - sizeof(struct action_ipv6_ext_remove_data)), - .next = NEXT(action_ipv6_ext_remove), - .call = parse_vc_action_ipv6_ext_remove, - }, - [ACTION_IPV6_EXT_REMOVE_INDEX] = { - .name = "index", - .help = "the index of ipv6_ext_remove", - .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), - }, - [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { - .name = "{index}", - .type = "UNSIGNED", - .help = "unsigned integer value", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_ipv6_ext_remove_index, - .comp = comp_set_ipv6_ext_index, - }, - [ACTION_IPV6_EXT_PUSH] = { - .name = "ipv6_ext_push", - .help = "IPv6 extension data, defined by set ipv6_ext_push", - .priv = PRIV_ACTION(IPV6_EXT_PUSH, - sizeof(struct action_ipv6_ext_push_data)), - .next = NEXT(action_ipv6_ext_push), - .call = parse_vc_action_ipv6_ext_push, - }, - [ACTION_IPV6_EXT_PUSH_INDEX] = { - .name = "index", - .help = "the index of ipv6_ext_push", - .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), - }, - [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { - .name = "{index}", - .type = "UNSIGNED", - .help = "unsigned integer value", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_ipv6_ext_push_index, - .comp = comp_set_ipv6_ext_index, - }, - [ACTION_NAT64] = { - .name = "nat64", - .help = "NAT64 IP headers translation", - .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), - .next = NEXT(action_nat64), - .call = parse_vc, - }, - [ACTION_NAT64_MODE] = { - .name = "type", - .help = "NAT64 translation type", - .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), - .call = parse_vc_conf, - }, - [ACTION_JUMP_TO_TABLE_INDEX] = { - .name = "jump_to_table_index", - .help = "Jump to table index", - .priv = PRIV_ACTION(JUMP_TO_TABLE_INDEX, - sizeof(struct rte_flow_action_jump_to_table_index)), - .next = NEXT(action_jump_to_table_index), - .call = parse_vc, - }, - [ACTION_JUMP_TO_TABLE_INDEX_TABLE] = { - .name = "table", - .help = "table id to redirect traffic to", - .next = NEXT(action_jump_to_table_index, - NEXT_ENTRY(ACTION_JUMP_TO_TABLE_INDEX_TABLE_VALUE)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump_to_table_index, table)), - .call = parse_vc_conf, - }, - [ACTION_JUMP_TO_TABLE_INDEX_TABLE_VALUE] = { - .name = "{table_id}", - .type = "TABLE_ID", - .help = "table id for jump action", - .call = parse_jump_table_id, - .comp = comp_table_id, - }, - [ACTION_JUMP_TO_TABLE_INDEX_INDEX] = { - .name = "index", - .help = "rule index to redirect traffic to", - .next = NEXT(action_jump_to_table_index, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump_to_table_index, index)), - .call = parse_vc_conf, - }, - - /* Top level command. */ - [SET] = { - .name = "set", - .help = "set raw encap/decap/sample data", - .type = "set raw_encap|raw_decap " - " or set sample_actions ", - .next = NEXT(NEXT_ENTRY - (SET_RAW_ENCAP, - SET_RAW_DECAP, - SET_SAMPLE_ACTIONS, - SET_IPV6_EXT_REMOVE, - SET_IPV6_EXT_PUSH)), - .call = parse_set_init, - }, - /* Sub-level commands. */ - [SET_RAW_ENCAP] = { - .name = "raw_encap", - .help = "set raw encap data", - .next = NEXT(next_set_raw), - .args = ARGS(ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct buffer, port), - sizeof(((struct buffer *)0)->port), - 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), - .call = parse_set_raw_encap_decap, - }, - [SET_RAW_DECAP] = { - .name = "raw_decap", - .help = "set raw decap data", - .next = NEXT(next_set_raw), - .args = ARGS(ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct buffer, port), - sizeof(((struct buffer *)0)->port), - 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), - .call = parse_set_raw_encap_decap, - }, - [SET_RAW_INDEX] = { - .name = "{index}", - .type = "COMMON_UNSIGNED", - .help = "index of raw_encap/raw_decap data", - .next = NEXT(next_item), - .call = parse_port, - }, - [SET_SAMPLE_INDEX] = { - .name = "{index}", - .type = "UNSIGNED", - .help = "index of sample actions", - .next = NEXT(next_action_sample), - .call = parse_port, - }, - [SET_SAMPLE_ACTIONS] = { - .name = "sample_actions", - .help = "set sample actions list", - .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), - .args = ARGS(ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct buffer, port), - sizeof(((struct buffer *)0)->port), - 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), - .call = parse_set_sample_action, - }, - [SET_IPV6_EXT_PUSH] = { - .name = "ipv6_ext_push", - .help = "set IPv6 extension header", - .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), - .args = ARGS(ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct buffer, port), - sizeof(((struct buffer *)0)->port), - 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), - .call = parse_set_ipv6_ext_action, - }, - [SET_IPV6_EXT_REMOVE] = { - .name = "ipv6_ext_remove", - .help = "set IPv6 extension header", - .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), - .args = ARGS(ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct buffer, port), - sizeof(((struct buffer *)0)->port), - 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), - .call = parse_set_ipv6_ext_action, - }, - [SET_IPV6_EXT_INDEX] = { - .name = "{index}", - .type = "UNSIGNED", - .help = "index of ipv6 extension push/remove actions", - .next = NEXT(item_ipv6_push_ext), - .call = parse_port, - }, - [ITEM_IPV6_PUSH_REMOVE_EXT] = { - .name = "ipv6_ext", - .help = "set IPv6 extension header", - .priv = PRIV_ITEM(IPV6_EXT, - sizeof(struct rte_flow_item_ipv6_ext)), - .next = NEXT(item_ipv6_push_ext_type), - .call = parse_vc, - }, - [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { - .name = "type", - .help = "set IPv6 extension type", - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, - next_hdr)), - .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - }, - [ACTION_SET_TAG] = { - .name = "set_tag", - .help = "set tag", - .priv = PRIV_ACTION(SET_TAG, - sizeof(struct rte_flow_action_set_tag)), - .next = NEXT(action_set_tag), - .call = parse_vc, - }, - [ACTION_SET_TAG_INDEX] = { - .name = "index", - .help = "index of tag array", - .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), - .call = parse_vc_conf, - }, - [ACTION_SET_TAG_DATA] = { - .name = "data", - .help = "tag value", - .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY - (struct rte_flow_action_set_tag, data)), - .call = parse_vc_conf, - }, - [ACTION_SET_TAG_MASK] = { - .name = "mask", - .help = "mask for tag value", - .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY - (struct rte_flow_action_set_tag, mask)), - .call = parse_vc_conf, - }, - [ACTION_SET_META] = { - .name = "set_meta", - .help = "set metadata", - .priv = PRIV_ACTION(SET_META, - sizeof(struct rte_flow_action_set_meta)), - .next = NEXT(action_set_meta), - .call = parse_vc_action_set_meta, - }, - [ACTION_SET_META_DATA] = { - .name = "data", - .help = "metadata value", - .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY - (struct rte_flow_action_set_meta, data)), - .call = parse_vc_conf, - }, - [ACTION_SET_META_MASK] = { - .name = "mask", - .help = "mask for metadata value", - .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY - (struct rte_flow_action_set_meta, mask)), - .call = parse_vc_conf, - }, - [ACTION_SET_IPV4_DSCP] = { - .name = "set_ipv4_dscp", - .help = "set DSCP value", - .priv = PRIV_ACTION(SET_IPV4_DSCP, - sizeof(struct rte_flow_action_set_dscp)), - .next = NEXT(action_set_ipv4_dscp), - .call = parse_vc, - }, - [ACTION_SET_IPV4_DSCP_VALUE] = { - .name = "dscp_value", - .help = "new IPv4 DSCP value to set", - .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY - (struct rte_flow_action_set_dscp, dscp)), - .call = parse_vc_conf, - }, - [ACTION_SET_IPV6_DSCP] = { - .name = "set_ipv6_dscp", - .help = "set DSCP value", - .priv = PRIV_ACTION(SET_IPV6_DSCP, - sizeof(struct rte_flow_action_set_dscp)), - .next = NEXT(action_set_ipv6_dscp), - .call = parse_vc, - }, - [ACTION_SET_IPV6_DSCP_VALUE] = { - .name = "dscp_value", - .help = "new IPv6 DSCP value to set", - .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY - (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(COMMON_UNSIGNED)), - .call = parse_vc_conf, - }, - [ACTION_AGE_UPDATE] = { - .name = "age_update", - .help = "update aging parameter", - .next = NEXT(action_age_update), - .priv = PRIV_ACTION(AGE, - sizeof(struct rte_flow_update_age)), - .call = parse_vc, - }, - [ACTION_AGE_UPDATE_TIMEOUT] = { - .name = "timeout", - .help = "age timeout update value", - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, - timeout, 24)), - .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), - .call = parse_vc_conf_timeout, - }, - [ACTION_AGE_UPDATE_TOUCH] = { - .name = "touch", - .help = "this flow is touched", - .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), - .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, - touch, 1)), - .call = parse_vc_conf, - }, - [ACTION_SAMPLE] = { - .name = "sample", - .help = "set a sample action", - .next = NEXT(action_sample), - .priv = PRIV_ACTION(SAMPLE, - sizeof(struct action_sample_data)), - .call = parse_vc_action_sample, - }, - [ACTION_SAMPLE_RATIO] = { - .name = "ratio", - .help = "flow sample ratio value", - .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY_ARB - (offsetof(struct action_sample_data, conf) + - offsetof(struct rte_flow_action_sample, ratio), - sizeof(((struct rte_flow_action_sample *)0)-> - ratio))), - }, - [ACTION_SAMPLE_INDEX] = { - .name = "index", - .help = "the index of sample actions list", - .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), - }, - [ACTION_SAMPLE_INDEX_VALUE] = { - .name = "{index}", - .type = "COMMON_UNSIGNED", - .help = "unsigned integer value", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_vc_action_sample_index, - .comp = comp_set_sample_index, - }, - [ACTION_CONNTRACK] = { - .name = "conntrack", - .help = "create a conntrack object", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .priv = PRIV_ACTION(CONNTRACK, - sizeof(struct rte_flow_action_conntrack)), - .call = parse_vc, - }, - [ACTION_CONNTRACK_UPDATE] = { - .name = "conntrack_update", - .help = "update a conntrack object", - .next = NEXT(action_update_conntrack), - .priv = PRIV_ACTION(CONNTRACK, - sizeof(struct rte_flow_modify_conntrack)), - .call = parse_vc, - }, - [ACTION_CONNTRACK_UPDATE_DIR] = { - .name = "dir", - .help = "update a conntrack object direction", - .next = NEXT(action_update_conntrack), - .call = parse_vc_action_conntrack_update, - }, - [ACTION_CONNTRACK_UPDATE_CTX] = { - .name = "ctx", - .help = "update a conntrack object context", - .next = NEXT(action_update_conntrack), - .call = parse_vc_action_conntrack_update, - }, - [ACTION_PORT_REPRESENTOR] = { - .name = "port_representor", - .help = "at embedded switch level, send matching traffic to the given ethdev", - .priv = PRIV_ACTION(PORT_REPRESENTOR, - sizeof(struct rte_flow_action_ethdev)), - .next = NEXT(action_port_representor), - .call = parse_vc, - }, - [ACTION_PORT_REPRESENTOR_PORT_ID] = { - .name = "port_id", - .help = "ethdev port ID", - .next = NEXT(action_port_representor, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, - port_id)), - .call = parse_vc_conf, - }, - [ACTION_REPRESENTED_PORT] = { - .name = "represented_port", - .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", - .priv = PRIV_ACTION(REPRESENTED_PORT, - sizeof(struct rte_flow_action_ethdev)), - .next = NEXT(action_represented_port), - .call = parse_vc, - }, - [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { - .name = "ethdev_port_id", - .help = "ethdev port ID", - .next = NEXT(action_represented_port, - NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, - port_id)), - .call = parse_vc_conf, - }, - /* Indirect action destroy arguments. */ - [INDIRECT_ACTION_DESTROY_ID] = { - .name = "action_id", - .help = "specify a indirect action id to destroy", - .next = NEXT(next_ia_destroy_attr, - NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), - .args = ARGS(ARGS_ENTRY_PTR(struct buffer, - args.ia_destroy.action_id)), - .call = parse_ia_destroy, - }, - /* Indirect action create arguments. */ - [INDIRECT_ACTION_CREATE_ID] = { - .name = "action_id", - .help = "specify a indirect action id to create", - .next = NEXT(next_ia_create_attr, - NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), - }, - [ACTION_INDIRECT] = { - .name = "indirect", - .help = "apply indirect action by id", - .priv = PRIV_ACTION(INDIRECT, 0), - .next = NEXT(next_ia), - .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(uint32_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(uint32_t))), - }, - [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { - .type = "UNSIGNED", - .help = "unsigned integer value", - .call = parse_indlst_id2ptr, - .comp = comp_none, - }, - [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { - .type = "UNSIGNED", - .help = "unsigned integer value", - .call = parse_indlst_id2ptr, - .comp = comp_none, - }, - [ACTION_SHARED_INDIRECT] = { - .name = "shared_indirect", - .help = "apply indirect action by id and port", - .priv = PRIV_ACTION(INDIRECT, 0), - .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), - .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), - ARGS_ENTRY_ARB(0, sizeof(uint32_t))), - .call = parse_vc, - }, - [INDIRECT_ACTION_PORT] = { - .name = "{indirect_action_port}", - .type = "INDIRECT_ACTION_PORT", - .help = "indirect action port", - .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), - .call = parse_ia_port, - .comp = comp_none, - }, - [INDIRECT_ACTION_ID2PTR] = { - .name = "{action_id}", - .type = "INDIRECT_ACTION_ID", - .help = "indirect action id", - .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), - .call = parse_ia_id2ptr, - .comp = comp_none, - }, - [INDIRECT_ACTION_INGRESS] = { - .name = "ingress", - .help = "affect rule to ingress", - .next = NEXT(next_ia_create_attr), - .call = parse_ia, - }, - [INDIRECT_ACTION_EGRESS] = { - .name = "egress", - .help = "affect rule to egress", - .next = NEXT(next_ia_create_attr), - .call = parse_ia, - }, - [INDIRECT_ACTION_TRANSFER] = { - .name = "transfer", - .help = "affect rule to transfer", - .next = NEXT(next_ia_create_attr), - .call = parse_ia, - }, - [INDIRECT_ACTION_SPEC] = { - .name = "action", - .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", - .next = NEXT(next_action), - .call = parse_mp, - }, - [ACTION_POL_Y] = { - .name = "y_actions", - .help = "submit a list of associated actions for yellow", - .next = NEXT(next_action), - }, - [ACTION_POL_R] = { - .name = "r_actions", - .help = "submit a list of associated actions for red", - .next = NEXT(next_action), - }, - [ACTION_QUOTA_CREATE] = { - .name = "quota_create", - .help = "create quota action", - .priv = PRIV_ACTION(QUOTA, - sizeof(struct rte_flow_action_quota)), - .next = NEXT(action_quota_create), - .call = parse_vc - }, - [ACTION_QUOTA_CREATE_LIMIT] = { - .name = "limit", - .help = "quota limit", - .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), - .call = parse_vc_conf - }, - [ACTION_QUOTA_CREATE_MODE] = { - .name = "mode", - .help = "quota mode", - .next = NEXT(action_quota_create, - NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), - .call = parse_vc_conf - }, - [ACTION_QUOTA_CREATE_MODE_NAME] = { - .name = "mode_name", - .help = "quota mode name", - .call = parse_quota_mode_name, - .comp = comp_quota_mode_name - }, - [ACTION_QUOTA_QU] = { - .name = "quota_update", - .help = "update quota action", - .priv = PRIV_ACTION(QUOTA, - sizeof(struct rte_flow_update_quota)), - .next = NEXT(action_quota_update), - .call = parse_vc - }, - [ACTION_QUOTA_QU_LIMIT] = { - .name = "limit", - .help = "quota limit", - .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), - .call = parse_vc_conf - }, - [ACTION_QUOTA_QU_UPDATE_OP] = { - .name = "update_op", - .help = "query update op SET|ADD", - .next = NEXT(action_quota_update, - NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), - .call = parse_vc_conf - }, - [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { - .name = "update_op_name", - .help = "quota update op name", - .call = parse_quota_update_name, - .comp = comp_quota_update_name - }, - - /* Top-level command. */ - [ADD] = { - .name = "add", - .type = "port meter policy {port_id} {arg}", - .help = "add port meter policy", - .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), - .call = parse_init, - }, - /* Sub-level commands. */ - [ITEM_POL_PORT] = { - .name = "port", - .help = "add port meter policy", - .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), - }, - [ITEM_POL_METER] = { - .name = "meter", - .help = "add port meter policy", - .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), - }, - [ITEM_POL_POLICY] = { - .name = "policy", - .help = "add port meter policy", - .next = NEXT(NEXT_ENTRY(ACTION_POL_R), - NEXT_ENTRY(ACTION_POL_Y), - NEXT_ENTRY(ACTION_POL_G), - NEXT_ENTRY(COMMON_POLICY_ID), - NEXT_ENTRY(COMMON_PORT_ID)), - .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), - ARGS_ENTRY(struct buffer, port)), - .call = parse_mp, - }, - [ITEM_AGGR_AFFINITY] = { - .name = "aggr_affinity", - .help = "match on the aggregated port receiving the packets", - .priv = PRIV_ITEM(AGGR_AFFINITY, - sizeof(struct rte_flow_item_aggr_affinity)), - .next = NEXT(item_aggr_affinity), - .call = parse_vc, - }, - [ITEM_AGGR_AFFINITY_VALUE] = { - .name = "affinity", - .help = "aggregated affinity value", - .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, - affinity)), - }, - [ITEM_TX_QUEUE] = { - .name = "tx_queue", - .help = "match on the tx queue of send packet", - .priv = PRIV_ITEM(TX_QUEUE, - sizeof(struct rte_flow_item_tx_queue)), - .next = NEXT(item_tx_queue), - .call = parse_vc, - }, - [ITEM_TX_QUEUE_VALUE] = { - .name = "tx_queue_value", - .help = "tx queue value", - .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), - item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, - tx_queue)), - }, -}; - -/** Remove and return last entry from argument stack. */ -static const struct arg * -pop_args(struct context *ctx) -{ - return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; -} - -/** Add entry on top of the argument stack. */ -static int -push_args(struct context *ctx, const struct arg *arg) -{ - if (ctx->args_num == CTX_STACK_SIZE) - return -1; - ctx->args[ctx->args_num++] = arg; - return 0; -} - -/** Spread value into buffer according to bit-mask. */ -static size_t -arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) -{ - uint32_t i = arg->size; - uint32_t end = 0; - int sub = 1; - int add = 0; - size_t len = 0; - - if (!arg->mask) - return 0; -#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN - if (!arg->hton) { - i = 0; - end = arg->size; - sub = 0; - add = 1; - } -#endif - while (i != end) { - unsigned int shift = 0; - uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); - - for (shift = 0; arg->mask[i] >> shift; ++shift) { - if (!(arg->mask[i] & (1 << shift))) - continue; - ++len; - if (!dst) - continue; - *buf &= ~(1 << shift); - *buf |= (val & 1) << shift; - val >>= 1; - } - i += add; - } - return len; -} - -/** Compare a string with a partial one of a given length. */ -static int -strcmp_partial(const char *full, const char *partial, size_t partial_len) -{ - int r = strncmp(full, partial, partial_len); - - if (r) - return r; - if (strlen(full) <= partial_len) - return 0; - return full[partial_len]; -} - -/** - * Parse a prefix length and generate a bit-mask. - * - * Last argument (ctx->args) is retrieved to determine mask size, storage - * location and whether the result must use network byte ordering. - */ -static int -parse_prefix(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - const struct arg *arg = pop_args(ctx); - static const uint8_t conv[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, - 0xf8, 0xfc, 0xfe, 0xff }; - char *end; - uintmax_t u; - unsigned int bytes; - unsigned int extra; - - (void)token; - /* Argument is expected. */ - if (!arg) - return -1; - errno = 0; - u = strtoumax(str, &end, 0); - if (errno || (size_t)(end - str) != len) - goto error; - if (arg->mask) { - uintmax_t v = 0; - - extra = arg_entry_bf_fill(NULL, 0, arg); - if (u > extra) - goto error; - if (!ctx->object) - return len; - extra -= u; - while (u--) { - v <<= 1; - v |= 1; - } - v <<= extra; - if (!arg_entry_bf_fill(ctx->object, v, arg) || - !arg_entry_bf_fill(ctx->objmask, -1, arg)) - goto error; - return len; - } - bytes = u / 8; - extra = u % 8; - size = arg->size; - if (bytes > size || bytes + !!extra > size) - goto error; - if (!ctx->object) - return len; - buf = (uint8_t *)ctx->object + arg->offset; -#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN - if (!arg->hton) { - memset((uint8_t *)buf + size - bytes, 0xff, bytes); - memset(buf, 0x00, size - bytes); - if (extra) - ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; - } else -#endif - { - memset(buf, 0xff, bytes); - memset((uint8_t *)buf + bytes, 0x00, size - bytes); - if (extra) - ((uint8_t *)buf)[bytes] = conv[extra]; - } - if (ctx->objmask) - memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); - return len; -error: - push_args(ctx, arg); - return -1; -} - -/** Default parsing function for token name matching. */ -static int -parse_default(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - (void)ctx; - (void)buf; - (void)size; - if (strcmp_partial(token->name, str, len)) - return -1; - return len; -} - -/** Parse flow command, initialize output buffer for subsequent tokens. */ -static int -parse_init(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; - /* Make sure buffer is large enough. */ - if (size < sizeof(*out)) - return -1; - /* Initialize buffer. */ - memset(out, 0x00, sizeof(*out)); - memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - return len; -} - -/** Parse tokens for indirect action commands. */ -static int -parse_ia(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 != INDIRECT_ACTION) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.data = (uint8_t *)out + size; - return len; - } - switch (ctx->curr) { - case INDIRECT_ACTION_CREATE: - case INDIRECT_ACTION_UPDATE: - case INDIRECT_ACTION_QUERY_UPDATE: - out->args.vc.actions = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - out->args.vc.attr.group = UINT32_MAX; - /* fallthrough */ - case INDIRECT_ACTION_QUERY: - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - return len; - case INDIRECT_ACTION_EGRESS: - out->args.vc.attr.egress = 1; - return len; - case INDIRECT_ACTION_INGRESS: - out->args.vc.attr.ingress = 1; - return len; - case INDIRECT_ACTION_TRANSFER: - out->args.vc.attr.transfer = 1; - 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; - } -} - - -/** Parse tokens for indirect action destroy command. */ -static int -parse_ia_destroy(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - uint32_t *action_id; - - /* 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 || out->command == INDIRECT_ACTION) { - if (ctx->curr != INDIRECT_ACTION_DESTROY) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.ia_destroy.action_id = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; - } - action_id = out->args.ia_destroy.action_id - + out->args.ia_destroy.action_id_n++; - if ((uint8_t *)action_id > (uint8_t *)out + size) - return -1; - ctx->objdata = 0; - ctx->object = action_id; - ctx->objmask = NULL; - return len; -} - -/** Parse tokens for indirect action commands. */ -static int -parse_qia(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 != QUEUE) - return -1; - if (sizeof(*out) > size) - return -1; - out->args.vc.data = (uint8_t *)out + size; - return len; - } - switch (ctx->curr) { - case QUEUE_INDIRECT_ACTION: - return len; - case QUEUE_INDIRECT_ACTION_CREATE: - case QUEUE_INDIRECT_ACTION_UPDATE: - case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: - out->args.vc.actions = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - out->args.vc.attr.group = UINT32_MAX; - /* fallthrough */ - case QUEUE_INDIRECT_ACTION_QUERY: - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - return len; - case QUEUE_INDIRECT_ACTION_EGRESS: - out->args.vc.attr.egress = 1; - return len; - case QUEUE_INDIRECT_ACTION_INGRESS: - out->args.vc.attr.ingress = 1; - return len; - case QUEUE_INDIRECT_ACTION_TRANSFER: - out->args.vc.attr.transfer = 1; - return len; - case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: - 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; - } -} - -/** Parse tokens for indirect action destroy command. */ -static int -parse_qia_destroy(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - uint32_t *action_id; - - /* 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 || out->command == QUEUE) { - if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.ia_destroy.action_id = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; - } - switch (ctx->curr) { - case QUEUE_INDIRECT_ACTION: - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - return len; - case QUEUE_INDIRECT_ACTION_DESTROY_ID: - action_id = out->args.ia_destroy.action_id - + out->args.ia_destroy.action_id_n++; - if ((uint8_t *)action_id > (uint8_t *)out + size) - return -1; - ctx->objdata = 0; - ctx->object = action_id; - ctx->objmask = NULL; - return len; - case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: - return len; - default: - return -1; - } -} - -/** Parse tokens for meter policy action commands. */ -static int -parse_mp(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 != ITEM_POL_POLICY) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.data = (uint8_t *)out + size; - return len; - } - switch (ctx->curr) { - case ACTION_POL_G: - out->args.vc.actions = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - return len; - default: - return -1; - } -} - -/** Parse tokens for validate/create commands. */ -static int -parse_vc(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - uint8_t *data; - uint32_t data_size; - - /* 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 != VALIDATE && ctx->curr != CREATE && - ctx->curr != PATTERN_TEMPLATE_CREATE && - ctx->curr != ACTIONS_TEMPLATE_CREATE && - ctx->curr != UPDATE) - return -1; - if (ctx->curr == UPDATE) - out->args.vc.pattern = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.data = (uint8_t *)out + size; - return len; - } - ctx->objdata = 0; - switch (ctx->curr) { - default: - ctx->object = &out->args.vc.attr; - break; - case VC_TUNNEL_SET: - case VC_TUNNEL_MATCH: - ctx->object = &out->args.vc.tunnel_ops; - break; - case VC_USER_ID: - ctx->object = out; - break; - } - ctx->objmask = NULL; - switch (ctx->curr) { - case VC_GROUP: - case VC_PRIORITY: - case VC_USER_ID: - return len; - case VC_TUNNEL_SET: - out->args.vc.tunnel_ops.enabled = 1; - out->args.vc.tunnel_ops.actions = 1; - return len; - case VC_TUNNEL_MATCH: - out->args.vc.tunnel_ops.enabled = 1; - out->args.vc.tunnel_ops.items = 1; - return len; - case VC_INGRESS: - out->args.vc.attr.ingress = 1; - return len; - case VC_EGRESS: - out->args.vc.attr.egress = 1; - return len; - case VC_TRANSFER: - out->args.vc.attr.transfer = 1; - return len; - case ITEM_PATTERN: - out->args.vc.pattern = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - ctx->object = out->args.vc.pattern; - ctx->objmask = NULL; - return len; - case ITEM_END: - if ((out->command == VALIDATE || out->command == CREATE) && - ctx->last) - return -1; - if (out->command == PATTERN_TEMPLATE_CREATE && - !ctx->last) - return -1; - break; - case 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; - return len; - case VC_IS_USER_ID: - out->args.vc.user_id = true; - return len; - default: - if (!token->priv) - return -1; - break; - } - if (!out->args.vc.actions) { - const struct parse_item_priv *priv = token->priv; - struct rte_flow_item *item = - out->args.vc.pattern + out->args.vc.pattern_n; - - data_size = priv->size * 3; /* spec, last, mask */ - data = (void *)RTE_ALIGN_FLOOR((uintptr_t) - (out->args.vc.data - data_size), - sizeof(double)); - if ((uint8_t *)item + sizeof(*item) > data) - return -1; - *item = (struct rte_flow_item){ - .type = priv->type, - }; - ++out->args.vc.pattern_n; - ctx->object = item; - ctx->objmask = NULL; - } else { - const struct parse_action_priv *priv = token->priv; - struct rte_flow_action *action = - out->args.vc.actions + out->args.vc.actions_n; - - data_size = priv->size; /* configuration */ - data = (void *)RTE_ALIGN_FLOOR((uintptr_t) - (out->args.vc.data - data_size), - sizeof(double)); - if ((uint8_t *)action + sizeof(*action) > data) - return -1; - *action = (struct rte_flow_action){ - .type = priv->type, - .conf = data_size ? data : NULL, - }; - ++out->args.vc.actions_n; - ctx->object = action; - ctx->objmask = NULL; - } - memset(data, 0, data_size); - out->args.vc.data = data; - ctx->objdata = data_size; - return len; -} - -/** Parse pattern item parameter type. */ -static int -parse_vc_spec(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_item *item; - uint32_t data_size; - int index; - int objmask = 0; - - (void)size; - /* Token name must match. */ - if (parse_default(ctx, token, str, len, NULL, 0) < 0) - return -1; - /* Parse parameter types. */ - switch (ctx->curr) { - case ITEM_PARAM_IS: - index = 0; - objmask = 1; - break; - case ITEM_PARAM_SPEC: - index = 0; - break; - case ITEM_PARAM_LAST: - index = 1; - break; - case ITEM_PARAM_PREFIX: - /* Modify next token to expect a prefix. */ - if (ctx->next_num < 2) - return -1; - ctx->next[ctx->next_num - 2] = NEXT_ENTRY(COMMON_PREFIX); - /* Fall through. */ - case ITEM_PARAM_MASK: - index = 2; - break; - default: - return -1; - } - /* Nothing else to do if there is no buffer. */ - if (!out) - return len; - if (!out->args.vc.pattern_n) - return -1; - item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; - data_size = ctx->objdata / 3; /* spec, last, mask */ - /* Point to selected object. */ - ctx->object = out->args.vc.data + (data_size * index); - if (objmask) { - ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ - item->mask = ctx->objmask; - } else - ctx->objmask = NULL; - /* Update relevant item pointer. */ - *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = - ctx->object; - return len; -} - -/** Parse action configuration field. */ -static int -parse_vc_conf(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - - (void)size; - /* 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; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - return len; -} - -/** Parse action configuration field. */ -static int -parse_vc_conf_timeout(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_update_age *update; - - (void)size; - if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) - return -1; - /* 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; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Update the timeout is valid. */ - update = (struct rte_flow_update_age *)out->args.vc.data; - update->timeout_valid = 1; - 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 L2TPv2 common header type field. */ -static int -parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct rte_flow_item_l2tpv2 *l2tpv2; - struct rte_flow_item_l2tpv2 *l2tpv2_mask; - struct rte_flow_item *item; - uint32_t data_size; - uint16_t msg_type = 0; - 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_L2TPV2_TYPE_DATA: - msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; - break; - case ITEM_L2TPV2_TYPE_DATA_L: - msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; - break; - case ITEM_L2TPV2_TYPE_DATA_S: - msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; - break; - case ITEM_L2TPV2_TYPE_DATA_O: - msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; - break; - case ITEM_L2TPV2_TYPE_DATA_L_S: - msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; - break; - case ITEM_L2TPV2_TYPE_CTRL: - msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; - break; - default: - return -1; - } - if (!ctx->object) - return len; - arg = pop_args(ctx); - if (!arg) - return -1; - l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; - l2tpv2->hdr.common.flags_version |= msg_type; - data_size = ctx->objdata / 3; /* spec, last, mask */ - l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + - (data_size * 2)); - l2tpv2_mask->hdr.common.flags_version = 0xFFFF; - if (arg->hton) { - l2tpv2->hdr.common.flags_version = - rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); - l2tpv2_mask->hdr.common.flags_version = - rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); - } - item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; - item->spec = l2tpv2; - item->mask = l2tpv2_mask; - return len; -} - -/** Parse operation for compare match item. */ -static int -parse_vc_compare_op(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct rte_flow_item_compare *compare_item; - unsigned int i; - - (void)token; - (void)buf; - (void)size; - if (ctx->curr != ITEM_COMPARE_OP_VALUE) - return -1; - for (i = 0; compare_ops[i]; ++i) - if (!strcmp_partial(compare_ops[i], str, len)) - break; - if (!compare_ops[i]) - return -1; - if (!ctx->object) - return len; - compare_item = ctx->object; - compare_item->operation = (enum rte_flow_item_compare_op)i; - return len; -} - -/** Parse id for compare match item. */ -static int -parse_vc_compare_field_id(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct rte_flow_item_compare *compare_item; - unsigned int i; - - (void)token; - (void)buf; - (void)size; - if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && - ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) - return -1; - for (i = 0; flow_field_ids[i]; ++i) - if (!strcmp_partial(flow_field_ids[i], str, len)) - break; - if (!flow_field_ids[i]) - return -1; - if (!ctx->object) - return len; - compare_item = ctx->object; - if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) - compare_item->a.field = (enum rte_flow_field_id)i; - else - compare_item->b.field = (enum rte_flow_field_id)i; - return len; -} - -/** Parse level for compare match item. */ -static int -parse_vc_compare_field_level(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct rte_flow_item_compare *compare_item; - struct flex_item *fp = NULL; - uint32_t val; - struct buffer *out = buf; - char *end; - - (void)token; - (void)size; - if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && - ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) - return -1; - if (!ctx->object) - return len; - compare_item = ctx->object; - errno = 0; - val = strtoumax(str, &end, 0); - if (errno || (size_t)(end - str) != len) - return -1; - /* No need to validate action template mask value */ - if (out->args.vc.masks) { - if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) - compare_item->a.level = val; - else - compare_item->b.level = val; - return len; - } - if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && - compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || - (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && - compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { - if (val >= FLEX_MAX_PARSERS_NUM) { - printf("Bad flex item handle\n"); - return -1; - } - fp = flex_items[ctx->port][val]; - if (!fp) { - printf("Bad flex item handle\n"); - return -1; - } - } - if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { - if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) - compare_item->a.level = val; - else - compare_item->a.flex_handle = fp->flex_handle; - } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { - if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) - compare_item->b.level = val; - else - compare_item->b.flex_handle = fp->flex_handle; - } - return len; -} - -/** Parse meter color action type. */ -static int -parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct rte_flow_action *action_data; - struct rte_flow_action_meter_color *conf; - enum rte_color color; - - (void)buf; - (void)size; - /* Token name must match. */ - if (parse_default(ctx, token, str, len, NULL, 0) < 0) - return -1; - switch (ctx->curr) { - case ACTION_METER_COLOR_GREEN: - color = RTE_COLOR_GREEN; - break; - case ACTION_METER_COLOR_YELLOW: - color = RTE_COLOR_YELLOW; - break; - case ACTION_METER_COLOR_RED: - color = RTE_COLOR_RED; - break; - default: - return -1; - } - - if (!ctx->object) - return len; - action_data = ctx->object; - conf = (struct rte_flow_action_meter_color *) - (uintptr_t)(action_data->conf); - conf->color = color; - return len; -} - -/** Parse RSS action. */ -static int -parse_vc_action_rss(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_rss_data *action_rss_data; - unsigned int i; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Set up default configuration. */ - action_rss_data = ctx->object; - *action_rss_data = (struct action_rss_data){ - .conf = (struct rte_flow_action_rss){ - .func = RTE_ETH_HASH_FUNCTION_DEFAULT, - .level = 0, - .types = rss_hf, - .key_len = 0, - .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), - .key = NULL, - .queue = action_rss_data->queue, - }, - .queue = { 0 }, - }; - for (i = 0; i < action_rss_data->conf.queue_num; ++i) - action_rss_data->queue[i] = i; - action->conf = &action_rss_data->conf; - return ret; -} - -/** - * Parse func field for RSS action. - * - * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the - * ACTION_RSS_FUNC_* index that called this function. - */ -static int -parse_vc_action_rss_func(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct action_rss_data *action_rss_data; - enum rte_eth_hash_function func; - - (void)buf; - (void)size; - /* Token name must match. */ - if (parse_default(ctx, token, str, len, NULL, 0) < 0) - return -1; - switch (ctx->curr) { - case ACTION_RSS_FUNC_DEFAULT: - func = RTE_ETH_HASH_FUNCTION_DEFAULT; - break; - case ACTION_RSS_FUNC_TOEPLITZ: - func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; - break; - case ACTION_RSS_FUNC_SIMPLE_XOR: - func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; - break; - case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: - func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; - break; - default: - return -1; - } - if (!ctx->object) - return len; - action_rss_data = ctx->object; - action_rss_data->conf.func = func; - return len; -} - -/** - * Parse type field for RSS action. - * - * Valid tokens are type field names and the "end" token. - */ -static int -parse_vc_action_rss_type(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct action_rss_data *action_rss_data; - unsigned int i; - - (void)token; - (void)buf; - (void)size; - if (ctx->curr != ACTION_RSS_TYPE) - return -1; - if (!(ctx->objdata >> 16) && ctx->object) { - action_rss_data = ctx->object; - action_rss_data->conf.types = 0; - } - if (!strcmp_partial("end", str, len)) { - ctx->objdata &= 0xffff; - return len; - } - for (i = 0; rss_type_table[i].str; ++i) - if (!strcmp_partial(rss_type_table[i].str, str, len)) - break; - if (!rss_type_table[i].str) - return -1; - ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); - /* Repeat token. */ - if (ctx->next_num == RTE_DIM(ctx->next)) - return -1; - ctx->next[ctx->next_num++] = NEXT_ENTRY(ACTION_RSS_TYPE); - if (!ctx->object) - return len; - action_rss_data = ctx->object; - action_rss_data->conf.types |= rss_type_table[i].rss_type; - return len; -} - -/** - * Parse queue field for RSS action. - * - * Valid tokens are queue indices and the "end" token. - */ -static int -parse_vc_action_rss_queue(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct action_rss_data *action_rss_data; - const struct arg *arg; - int ret; - int i; - - (void)token; - (void)buf; - (void)size; - if (ctx->curr != ACTION_RSS_QUEUE) - return -1; - i = ctx->objdata >> 16; - if (!strcmp_partial("end", str, len)) { - ctx->objdata &= 0xffff; - goto end; - } - if (i >= ACTION_RSS_QUEUE_NUM) - return -1; - arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + - i * sizeof(action_rss_data->queue[i]), - sizeof(action_rss_data->queue[i])); - if (push_args(ctx, arg)) - return -1; - ret = parse_int(ctx, token, str, len, NULL, 0); - if (ret < 0) { - pop_args(ctx); - return -1; - } - ++i; - ctx->objdata = i << 16 | (ctx->objdata & 0xffff); - /* Repeat token. */ - if (ctx->next_num == RTE_DIM(ctx->next)) - return -1; - ctx->next[ctx->next_num++] = NEXT_ENTRY(ACTION_RSS_QUEUE); -end: - if (!ctx->object) - return len; - action_rss_data = ctx->object; - action_rss_data->conf.queue_num = i; - action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; - return len; -} - -/** Setup VXLAN encap configuration. */ -static int -parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) -{ - /* Set up default configuration. */ - *action_vxlan_encap_data = (struct action_vxlan_encap_data){ - .conf = (struct rte_flow_action_vxlan_encap){ - .definition = action_vxlan_encap_data->items, - }, - .items = { - { - .type = RTE_FLOW_ITEM_TYPE_ETH, - .spec = &action_vxlan_encap_data->item_eth, - .mask = &rte_flow_item_eth_mask, - }, - { - .type = RTE_FLOW_ITEM_TYPE_VLAN, - .spec = &action_vxlan_encap_data->item_vlan, - .mask = &rte_flow_item_vlan_mask, - }, - { - .type = RTE_FLOW_ITEM_TYPE_IPV4, - .spec = &action_vxlan_encap_data->item_ipv4, - .mask = &rte_flow_item_ipv4_mask, - }, - { - .type = RTE_FLOW_ITEM_TYPE_UDP, - .spec = &action_vxlan_encap_data->item_udp, - .mask = &rte_flow_item_udp_mask, - }, - { - .type = RTE_FLOW_ITEM_TYPE_VXLAN, - .spec = &action_vxlan_encap_data->item_vxlan, - .mask = &rte_flow_item_vxlan_mask, - }, - { - .type = RTE_FLOW_ITEM_TYPE_END, - }, - }, - .item_eth.hdr.ether_type = 0, - .item_vlan = { - .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, - .hdr.eth_proto = 0, - }, - .item_ipv4.hdr = { - .src_addr = vxlan_encap_conf.ipv4_src, - .dst_addr = vxlan_encap_conf.ipv4_dst, - }, - .item_udp.hdr = { - .src_port = vxlan_encap_conf.udp_src, - .dst_port = vxlan_encap_conf.udp_dst, - }, - .item_vxlan.hdr.flags = 0, - }; - memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, - vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); - memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, - vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - if (!vxlan_encap_conf.select_ipv4) { - memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, - &vxlan_encap_conf.ipv6_src, - sizeof(vxlan_encap_conf.ipv6_src)); - memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, - &vxlan_encap_conf.ipv6_dst, - sizeof(vxlan_encap_conf.ipv6_dst)); - action_vxlan_encap_data->items[2] = (struct rte_flow_item){ - .type = RTE_FLOW_ITEM_TYPE_IPV6, - .spec = &action_vxlan_encap_data->item_ipv6, - .mask = &rte_flow_item_ipv6_mask, - }; - } - if (!vxlan_encap_conf.select_vlan) - action_vxlan_encap_data->items[1].type = - RTE_FLOW_ITEM_TYPE_VOID; - if (vxlan_encap_conf.select_tos_ttl) { - if (vxlan_encap_conf.select_ipv4) { - static struct rte_flow_item_ipv4 ipv4_mask_tos; - - memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, - sizeof(ipv4_mask_tos)); - ipv4_mask_tos.hdr.type_of_service = 0xff; - ipv4_mask_tos.hdr.time_to_live = 0xff; - action_vxlan_encap_data->item_ipv4.hdr.type_of_service = - vxlan_encap_conf.ip_tos; - action_vxlan_encap_data->item_ipv4.hdr.time_to_live = - vxlan_encap_conf.ip_ttl; - action_vxlan_encap_data->items[2].mask = - &ipv4_mask_tos; - } else { - static struct rte_flow_item_ipv6 ipv6_mask_tos; - - memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, - sizeof(ipv6_mask_tos)); - ipv6_mask_tos.hdr.vtc_flow |= - RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); - ipv6_mask_tos.hdr.hop_limits = 0xff; - action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= - rte_cpu_to_be_32 - ((uint32_t)vxlan_encap_conf.ip_tos << - RTE_IPV6_HDR_TC_SHIFT); - action_vxlan_encap_data->item_ipv6.hdr.hop_limits = - vxlan_encap_conf.ip_ttl; - action_vxlan_encap_data->items[2].mask = - &ipv6_mask_tos; - } - } - memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, - RTE_DIM(vxlan_encap_conf.vni)); - return 0; -} - -/** Parse VXLAN encap action. */ -static int -parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_vxlan_encap_data *action_vxlan_encap_data; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - action_vxlan_encap_data = ctx->object; - parse_setup_vxlan_encap_data(action_vxlan_encap_data); - action->conf = &action_vxlan_encap_data->conf; - return ret; -} - -/** Setup NVGRE encap configuration. */ -static int -parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) -{ - /* Set up default configuration. */ - *action_nvgre_encap_data = (struct action_nvgre_encap_data){ - .conf = (struct rte_flow_action_nvgre_encap){ - .definition = action_nvgre_encap_data->items, - }, - .items = { - { - .type = RTE_FLOW_ITEM_TYPE_ETH, - .spec = &action_nvgre_encap_data->item_eth, - .mask = &rte_flow_item_eth_mask, - }, - { - .type = RTE_FLOW_ITEM_TYPE_VLAN, - .spec = &action_nvgre_encap_data->item_vlan, - .mask = &rte_flow_item_vlan_mask, - }, - { - .type = RTE_FLOW_ITEM_TYPE_IPV4, - .spec = &action_nvgre_encap_data->item_ipv4, - .mask = &rte_flow_item_ipv4_mask, - }, - { - .type = RTE_FLOW_ITEM_TYPE_NVGRE, - .spec = &action_nvgre_encap_data->item_nvgre, - .mask = &rte_flow_item_nvgre_mask, - }, - { - .type = RTE_FLOW_ITEM_TYPE_END, - }, - }, - .item_eth.hdr.ether_type = 0, - .item_vlan = { - .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, - .hdr.eth_proto = 0, - }, - .item_ipv4.hdr = { - .src_addr = nvgre_encap_conf.ipv4_src, - .dst_addr = nvgre_encap_conf.ipv4_dst, - }, - .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), - .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), - .item_nvgre.flow_id = 0, - }; - memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, - nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); - memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, - nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - if (!nvgre_encap_conf.select_ipv4) { - memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, - &nvgre_encap_conf.ipv6_src, - sizeof(nvgre_encap_conf.ipv6_src)); - memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, - &nvgre_encap_conf.ipv6_dst, - sizeof(nvgre_encap_conf.ipv6_dst)); - action_nvgre_encap_data->items[2] = (struct rte_flow_item){ - .type = RTE_FLOW_ITEM_TYPE_IPV6, - .spec = &action_nvgre_encap_data->item_ipv6, - .mask = &rte_flow_item_ipv6_mask, - }; - } - if (!nvgre_encap_conf.select_vlan) - action_nvgre_encap_data->items[1].type = - RTE_FLOW_ITEM_TYPE_VOID; - memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, - RTE_DIM(nvgre_encap_conf.tni)); - return 0; -} - -/** Parse NVGRE encap action. */ -static int -parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_nvgre_encap_data *action_nvgre_encap_data; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - action_nvgre_encap_data = ctx->object; - parse_setup_nvgre_encap_data(action_nvgre_encap_data); - action->conf = &action_nvgre_encap_data->conf; - return ret; -} - -/** Parse l2 encap action. */ -static int -parse_vc_action_l2_encap(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_raw_encap_data *action_encap_data; - struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; - struct rte_flow_item_vlan vlan = { - .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, - .hdr.eth_proto = 0, - }; - uint8_t *header; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Copy the headers to the buffer. */ - action_encap_data = ctx->object; - *action_encap_data = (struct action_raw_encap_data) { - .conf = (struct rte_flow_action_raw_encap){ - .data = action_encap_data->data, - }, - .data = {}, - }; - header = action_encap_data->data; - if (l2_encap_conf.select_vlan) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); - else if (l2_encap_conf.select_ipv4) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - else - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(eth.hdr.dst_addr.addr_bytes, - l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); - memcpy(eth.hdr.src_addr.addr_bytes, - l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); - header += sizeof(struct rte_ether_hdr); - if (l2_encap_conf.select_vlan) { - if (l2_encap_conf.select_ipv4) - vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - else - vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); - header += sizeof(struct rte_vlan_hdr); - } - action_encap_data->conf.size = header - - action_encap_data->data; - action->conf = &action_encap_data->conf; - return ret; -} - -/** Parse l2 decap action. */ -static int -parse_vc_action_l2_decap(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_raw_decap_data *action_decap_data; - struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; - struct rte_flow_item_vlan vlan = { - .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, - .hdr.eth_proto = 0, - }; - uint8_t *header; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Copy the headers to the buffer. */ - action_decap_data = ctx->object; - *action_decap_data = (struct action_raw_decap_data) { - .conf = (struct rte_flow_action_raw_decap){ - .data = action_decap_data->data, - }, - .data = {}, - }; - header = action_decap_data->data; - if (l2_decap_conf.select_vlan) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); - memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); - header += sizeof(struct rte_ether_hdr); - if (l2_decap_conf.select_vlan) { - memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); - header += sizeof(struct rte_vlan_hdr); - } - action_decap_data->conf.size = header - - action_decap_data->data; - action->conf = &action_decap_data->conf; - return ret; -} - -#define ETHER_TYPE_MPLS_UNICAST 0x8847 - -/** Parse MPLSOGRE encap action. */ -static int -parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_raw_encap_data *action_encap_data; - struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; - struct rte_flow_item_vlan vlan = { - .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, - .hdr.eth_proto = 0, - }; - struct rte_flow_item_ipv4 ipv4 = { - .hdr = { - .src_addr = mplsogre_encap_conf.ipv4_src, - .dst_addr = mplsogre_encap_conf.ipv4_dst, - .next_proto_id = IPPROTO_GRE, - .version_ihl = RTE_IPV4_VHL_DEF, - .time_to_live = IPDEFTTL, - }, - }; - struct rte_flow_item_ipv6 ipv6 = { - .hdr = { - .proto = IPPROTO_GRE, - .hop_limits = IPDEFTTL, - }, - }; - struct rte_flow_item_gre gre = { - .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), - }; - struct rte_flow_item_mpls mpls = { - .ttl = 0, - }; - uint8_t *header; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Copy the headers to the buffer. */ - action_encap_data = ctx->object; - *action_encap_data = (struct action_raw_encap_data) { - .conf = (struct rte_flow_action_raw_encap){ - .data = action_encap_data->data, - }, - .data = {}, - .preserve = {}, - }; - header = action_encap_data->data; - if (mplsogre_encap_conf.select_vlan) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); - else if (mplsogre_encap_conf.select_ipv4) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - else - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(eth.hdr.dst_addr.addr_bytes, - mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); - memcpy(eth.hdr.src_addr.addr_bytes, - mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); - header += sizeof(struct rte_ether_hdr); - if (mplsogre_encap_conf.select_vlan) { - if (mplsogre_encap_conf.select_ipv4) - vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - else - vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); - header += sizeof(struct rte_vlan_hdr); - } - if (mplsogre_encap_conf.select_ipv4) { - memcpy(header, &ipv4, sizeof(ipv4)); - header += sizeof(ipv4); - } else { - memcpy(&ipv6.hdr.src_addr, - &mplsogre_encap_conf.ipv6_src, - sizeof(mplsogre_encap_conf.ipv6_src)); - memcpy(&ipv6.hdr.dst_addr, - &mplsogre_encap_conf.ipv6_dst, - sizeof(mplsogre_encap_conf.ipv6_dst)); - memcpy(header, &ipv6, sizeof(ipv6)); - header += sizeof(ipv6); - } - memcpy(header, &gre, sizeof(gre)); - header += sizeof(gre); - memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, - RTE_DIM(mplsogre_encap_conf.label)); - mpls.label_tc_s[2] |= 0x1; - memcpy(header, &mpls, sizeof(mpls)); - header += sizeof(mpls); - action_encap_data->conf.size = header - - action_encap_data->data; - action->conf = &action_encap_data->conf; - return ret; -} - -/** Parse MPLSOGRE decap action. */ -static int -parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_raw_decap_data *action_decap_data; - struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; - struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; - struct rte_flow_item_ipv4 ipv4 = { - .hdr = { - .next_proto_id = IPPROTO_GRE, - }, - }; - struct rte_flow_item_ipv6 ipv6 = { - .hdr = { - .proto = IPPROTO_GRE, - }, - }; - struct rte_flow_item_gre gre = { - .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), - }; - struct rte_flow_item_mpls mpls; - uint8_t *header; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Copy the headers to the buffer. */ - action_decap_data = ctx->object; - *action_decap_data = (struct action_raw_decap_data) { - .conf = (struct rte_flow_action_raw_decap){ - .data = action_decap_data->data, - }, - .data = {}, - }; - header = action_decap_data->data; - if (mplsogre_decap_conf.select_vlan) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); - else if (mplsogre_encap_conf.select_ipv4) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - else - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(eth.hdr.dst_addr.addr_bytes, - mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); - memcpy(eth.hdr.src_addr.addr_bytes, - mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); - header += sizeof(struct rte_ether_hdr); - if (mplsogre_encap_conf.select_vlan) { - if (mplsogre_encap_conf.select_ipv4) - vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - else - vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); - header += sizeof(struct rte_vlan_hdr); - } - if (mplsogre_encap_conf.select_ipv4) { - memcpy(header, &ipv4, sizeof(ipv4)); - header += sizeof(ipv4); - } else { - memcpy(header, &ipv6, sizeof(ipv6)); - header += sizeof(ipv6); - } - memcpy(header, &gre, sizeof(gre)); - header += sizeof(gre); - memset(&mpls, 0, sizeof(mpls)); - memcpy(header, &mpls, sizeof(mpls)); - header += sizeof(mpls); - action_decap_data->conf.size = header - - action_decap_data->data; - action->conf = &action_decap_data->conf; - return ret; -} - -/** Parse MPLSOUDP encap action. */ -static int -parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_raw_encap_data *action_encap_data; - struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; - struct rte_flow_item_vlan vlan = { - .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, - .hdr.eth_proto = 0, - }; - struct rte_flow_item_ipv4 ipv4 = { - .hdr = { - .src_addr = mplsoudp_encap_conf.ipv4_src, - .dst_addr = mplsoudp_encap_conf.ipv4_dst, - .next_proto_id = IPPROTO_UDP, - .version_ihl = RTE_IPV4_VHL_DEF, - .time_to_live = IPDEFTTL, - }, - }; - struct rte_flow_item_ipv6 ipv6 = { - .hdr = { - .proto = IPPROTO_UDP, - .hop_limits = IPDEFTTL, - }, - }; - struct rte_flow_item_udp udp = { - .hdr = { - .src_port = mplsoudp_encap_conf.udp_src, - .dst_port = mplsoudp_encap_conf.udp_dst, - }, - }; - struct rte_flow_item_mpls mpls; - uint8_t *header; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Copy the headers to the buffer. */ - action_encap_data = ctx->object; - *action_encap_data = (struct action_raw_encap_data) { - .conf = (struct rte_flow_action_raw_encap){ - .data = action_encap_data->data, - }, - .data = {}, - .preserve = {}, - }; - header = action_encap_data->data; - if (mplsoudp_encap_conf.select_vlan) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); - else if (mplsoudp_encap_conf.select_ipv4) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - else - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(eth.hdr.dst_addr.addr_bytes, - mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); - memcpy(eth.hdr.src_addr.addr_bytes, - mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); - header += sizeof(struct rte_ether_hdr); - if (mplsoudp_encap_conf.select_vlan) { - if (mplsoudp_encap_conf.select_ipv4) - vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - else - vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); - header += sizeof(struct rte_vlan_hdr); - } - if (mplsoudp_encap_conf.select_ipv4) { - memcpy(header, &ipv4, sizeof(ipv4)); - header += sizeof(ipv4); - } else { - memcpy(&ipv6.hdr.src_addr, - &mplsoudp_encap_conf.ipv6_src, - sizeof(mplsoudp_encap_conf.ipv6_src)); - memcpy(&ipv6.hdr.dst_addr, - &mplsoudp_encap_conf.ipv6_dst, - sizeof(mplsoudp_encap_conf.ipv6_dst)); - memcpy(header, &ipv6, sizeof(ipv6)); - header += sizeof(ipv6); - } - memcpy(header, &udp, sizeof(udp)); - header += sizeof(udp); - memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, - RTE_DIM(mplsoudp_encap_conf.label)); - mpls.label_tc_s[2] |= 0x1; - memcpy(header, &mpls, sizeof(mpls)); - header += sizeof(mpls); - action_encap_data->conf.size = header - - action_encap_data->data; - action->conf = &action_encap_data->conf; - return ret; -} - -/** Parse MPLSOUDP decap action. */ -static int -parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_raw_decap_data *action_decap_data; - struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; - struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; - struct rte_flow_item_ipv4 ipv4 = { - .hdr = { - .next_proto_id = IPPROTO_UDP, - }, - }; - struct rte_flow_item_ipv6 ipv6 = { - .hdr = { - .proto = IPPROTO_UDP, - }, - }; - struct rte_flow_item_udp udp = { - .hdr = { - .dst_port = rte_cpu_to_be_16(6635), - }, - }; - struct rte_flow_item_mpls mpls; - uint8_t *header; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Copy the headers to the buffer. */ - action_decap_data = ctx->object; - *action_decap_data = (struct action_raw_decap_data) { - .conf = (struct rte_flow_action_raw_decap){ - .data = action_decap_data->data, - }, - .data = {}, - }; - header = action_decap_data->data; - if (mplsoudp_decap_conf.select_vlan) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); - else if (mplsoudp_encap_conf.select_ipv4) - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - else - eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(eth.hdr.dst_addr.addr_bytes, - mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); - memcpy(eth.hdr.src_addr.addr_bytes, - mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); - header += sizeof(struct rte_ether_hdr); - if (mplsoudp_encap_conf.select_vlan) { - if (mplsoudp_encap_conf.select_ipv4) - vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); - else - vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); - header += sizeof(struct rte_vlan_hdr); - } - if (mplsoudp_encap_conf.select_ipv4) { - memcpy(header, &ipv4, sizeof(ipv4)); - header += sizeof(ipv4); - } else { - memcpy(header, &ipv6, sizeof(ipv6)); - header += sizeof(ipv6); - } - memcpy(header, &udp, sizeof(udp)); - header += sizeof(udp); - memset(&mpls, 0, sizeof(mpls)); - memcpy(header, &mpls, sizeof(mpls)); - header += sizeof(mpls); - action_decap_data->conf.size = header - - action_decap_data->data; - action->conf = &action_decap_data->conf; - return ret; -} - -static int -parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct action_raw_decap_data *action_raw_decap_data; - struct rte_flow_action *action; - const struct arg *arg; - struct buffer *out = buf; - int ret; - uint16_t idx; - - RTE_SET_USED(token); - RTE_SET_USED(buf); - RTE_SET_USED(size); - arg = ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct action_raw_decap_data, idx), - sizeof(((struct action_raw_decap_data *)0)->idx), - 0, RAW_ENCAP_CONFS_MAX_NUM - 1); - if (push_args(ctx, arg)) - return -1; - ret = parse_int(ctx, token, str, len, NULL, 0); - if (ret < 0) { - pop_args(ctx); - return -1; - } - if (!ctx->object) - return len; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - action_raw_decap_data = ctx->object; - idx = action_raw_decap_data->idx; - action_raw_decap_data->conf.data = raw_decap_confs[idx].data; - action_raw_decap_data->conf.size = raw_decap_confs[idx].size; - action->conf = &action_raw_decap_data->conf; - return len; -} - - -static int -parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct action_raw_encap_data *action_raw_encap_data; - struct rte_flow_action *action; - const struct arg *arg; - struct buffer *out = buf; - int ret; - uint16_t idx; - - RTE_SET_USED(token); - RTE_SET_USED(buf); - RTE_SET_USED(size); - if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) - return -1; - arg = ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct action_raw_encap_data, idx), - sizeof(((struct action_raw_encap_data *)0)->idx), - 0, RAW_ENCAP_CONFS_MAX_NUM - 1); - if (push_args(ctx, arg)) - return -1; - ret = parse_int(ctx, token, str, len, NULL, 0); - if (ret < 0) { - pop_args(ctx); - return -1; - } - if (!ctx->object) - return len; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - action_raw_encap_data = ctx->object; - idx = action_raw_encap_data->idx; - action_raw_encap_data->conf.data = raw_encap_confs[idx].data; - action_raw_encap_data->conf.size = raw_encap_confs[idx].size; - action_raw_encap_data->conf.preserve = NULL; - action->conf = &action_raw_encap_data->conf; - return len; -} - -static int -parse_vc_action_raw_encap(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct buffer *out = buf; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - return ret; -} - -static int -parse_vc_action_raw_decap(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_raw_decap_data *action_raw_decap_data = NULL; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Copy the headers to the buffer. */ - action_raw_decap_data = ctx->object; - action_raw_decap_data->conf.data = raw_decap_confs[0].data; - action_raw_decap_data->conf.size = raw_decap_confs[0].size; - action->conf = &action_raw_decap_data->conf; - return ret; -} - -static int -parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Copy the headers to the buffer. */ - ipv6_ext_remove_data = ctx->object; - ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; - action->conf = &ipv6_ext_remove_data->conf; - return ret; -} - -static int -parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; - struct rte_flow_action *action; - const struct arg *arg; - struct buffer *out = buf; - int ret; - uint16_t idx; - - RTE_SET_USED(token); - RTE_SET_USED(buf); - RTE_SET_USED(size); - arg = ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct action_ipv6_ext_remove_data, idx), - sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), - 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); - if (push_args(ctx, arg)) - return -1; - ret = parse_int(ctx, token, str, len, NULL, 0); - if (ret < 0) { - pop_args(ctx); - return -1; - } - if (!ctx->object) - return len; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - action_ipv6_ext_remove_data = ctx->object; - idx = action_ipv6_ext_remove_data->idx; - action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; - action->conf = &action_ipv6_ext_remove_data->conf; - return len; -} - -static int -parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Copy the headers to the buffer. */ - ipv6_ext_push_data = ctx->object; - ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; - ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; - ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; - action->conf = &ipv6_ext_push_data->conf; - return ret; -} - -static int -parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; - struct rte_flow_action *action; - const struct arg *arg; - struct buffer *out = buf; - int ret; - uint16_t idx; - - RTE_SET_USED(token); - RTE_SET_USED(buf); - RTE_SET_USED(size); - arg = ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct action_ipv6_ext_push_data, idx), - sizeof(((struct action_ipv6_ext_push_data *)0)->idx), - 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); - if (push_args(ctx, arg)) - return -1; - ret = parse_int(ctx, token, str, len, NULL, 0); - if (ret < 0) { - pop_args(ctx); - return -1; - } - if (!ctx->object) - return len; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - action_ipv6_ext_push_data = ctx->object; - idx = action_ipv6_ext_push_data->idx; - action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; - action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; - action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; - action->conf = &action_ipv6_ext_push_data->conf; - return len; -} - -static int -parse_vc_action_set_meta(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - ret = rte_flow_dynf_metadata_register(); - if (ret < 0) - return -1; - return len; -} - -static int -parse_vc_action_sample(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_action *action; - struct action_sample_data *action_sample_data = NULL; - static struct rte_flow_action end_action = { - RTE_FLOW_ACTION_TYPE_END, 0 - }; - int ret; - - ret = parse_vc(ctx, token, str, len, buf, size); - if (ret < 0) - return ret; - /* Nothing else to do if there is no buffer. */ - if (!out) - return ret; - if (!out->args.vc.actions_n) - return -1; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - /* Point to selected object. */ - ctx->object = out->args.vc.data; - ctx->objmask = NULL; - /* Copy the headers to the buffer. */ - action_sample_data = ctx->object; - action_sample_data->conf.actions = &end_action; - action->conf = &action_sample_data->conf; - return ret; -} - -static int -parse_vc_action_sample_index(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct action_sample_data *action_sample_data; - struct rte_flow_action *action; - const struct arg *arg; - struct buffer *out = buf; - int ret; - uint16_t idx; - - RTE_SET_USED(token); - RTE_SET_USED(buf); - RTE_SET_USED(size); - if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) - return -1; - arg = ARGS_ENTRY_ARB_BOUNDED - (offsetof(struct action_sample_data, idx), - sizeof(((struct action_sample_data *)0)->idx), - 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); - if (push_args(ctx, arg)) - return -1; - ret = parse_int(ctx, token, str, len, NULL, 0); - if (ret < 0) { - pop_args(ctx); - return -1; - } - if (!ctx->object) - return len; - action = &out->args.vc.actions[out->args.vc.actions_n - 1]; - action_sample_data = ctx->object; - idx = action_sample_data->idx; - action_sample_data->conf.actions = raw_sample_confs[idx].data; - action->conf = &action_sample_data->conf; - return len; -} - -/** Parse operation for modify_field command. */ -static int -parse_vc_modify_field_op(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct rte_flow_action_modify_field *action_modify_field; - unsigned int i; - - (void)token; - (void)buf; - (void)size; - if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) - return -1; - for (i = 0; modify_field_ops[i]; ++i) - if (!strcmp_partial(modify_field_ops[i], str, len)) - break; - if (!modify_field_ops[i]) - return -1; - if (!ctx->object) - return len; - action_modify_field = ctx->object; - action_modify_field->operation = (enum rte_flow_modify_op)i; - return len; -} - -/** Parse id for modify_field command. */ -static int -parse_vc_modify_field_id(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct rte_flow_action_modify_field *action_modify_field; - unsigned int i; - - (void)token; - (void)buf; - (void)size; - if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && - ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) - return -1; - for (i = 0; flow_field_ids[i]; ++i) - if (!strcmp_partial(flow_field_ids[i], str, len)) - break; - if (!flow_field_ids[i]) - return -1; - if (!ctx->object) - return len; - action_modify_field = ctx->object; - if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) - action_modify_field->dst.field = (enum rte_flow_field_id)i; - else - action_modify_field->src.field = (enum rte_flow_field_id)i; - return len; -} - -/** Parse level for modify_field command. */ -static int -parse_vc_modify_field_level(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct rte_flow_action_modify_field *action; - struct flex_item *fp = NULL; - uint32_t val; - struct buffer *out = buf; - char *end; - - (void)token; - (void)size; - if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && - ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) - return -1; - if (!ctx->object) - return len; - action = ctx->object; - errno = 0; - val = strtoumax(str, &end, 0); - if (errno || (size_t)(end - str) != len) - return -1; - /* No need to validate action template mask value */ - if (out->args.vc.masks) { - if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) - action->dst.level = val; - else - action->src.level = val; - return len; - } - if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && - action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || - (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && - action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { - if (val >= FLEX_MAX_PARSERS_NUM) { - printf("Bad flex item handle\n"); - return -1; - } - fp = flex_items[ctx->port][val]; - if (!fp) { - printf("Bad flex item handle\n"); - return -1; - } - } - if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { - if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) - action->dst.level = val; - else - action->dst.flex_handle = fp->flex_handle; - } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { - if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) - action->src.level = val; - else - action->src.flex_handle = fp->flex_handle; - } - return len; -} - -/** Parse the conntrack update, not a rte_flow_action. */ -static int -parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct buffer *out = buf; - struct rte_flow_modify_conntrack *ct_modify = NULL; - - (void)size; - if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && - ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) - return -1; - /* 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; - ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; - if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { - ct_modify->new_ct.is_original_dir = - conntrack_context.is_original_dir; - ct_modify->direction = 1; - } else { - uint32_t old_dir; - - old_dir = ct_modify->new_ct.is_original_dir; - memcpy(&ct_modify->new_ct, &conntrack_context, - sizeof(conntrack_context)); - ct_modify->new_ct.is_original_dir = old_dir; - ct_modify->state = 1; - } - return len; -} - -/** Parse tokens for destroy command. */ -static int -parse_destroy(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 != DESTROY) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.destroy.rule = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; - } - if (ctx->curr == DESTROY_IS_USER_ID) { - out->args.destroy.is_user_id = true; - return len; - } - if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + - sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) - return -1; - ctx->objdata = 0; - ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; - ctx->objmask = NULL; - return len; -} - -/** Parse tokens for flush command. */ -static int -parse_flush(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 != FLUSH) - 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 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; - } - switch (ctx->curr) { - case DUMP_ALL: - case DUMP_ONE: - out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - return len; - case DUMP_IS_USER_ID: - out->args.dump.is_user_id = true; - return len; - default: - return -1; - } -} - -/** Parse tokens for query command. */ -static int -parse_query(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 != QUERY) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - } - if (ctx->curr == QUERY_IS_USER_ID) { - out->args.query.is_user_id = true; - return len; - } - return len; -} - -/** Parse action names. */ -static int -parse_action(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - const struct arg *arg = pop_args(ctx); - unsigned int i; - - (void)size; - /* Argument is expected. */ - if (!arg) - return -1; - /* Parse action name. */ - for (i = 0; next_action[i]; ++i) { - const struct parse_action_priv *priv; - - token = &token_list[next_action[i]]; - if (strcmp_partial(token->name, str, len)) - continue; - priv = token->priv; - if (!priv) - goto error; - if (out) - memcpy((uint8_t *)ctx->object + arg->offset, - &priv->type, - arg->size); - return len; - } -error: - push_args(ctx, arg); - return -1; -} - -/** Parse tokens for list command. */ -static int -parse_list(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 != LIST) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.list.group = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; - } - if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + - sizeof(*out->args.list.group)) > (uint8_t *)out + size) - return -1; - ctx->objdata = 0; - ctx->object = out->args.list.group + out->args.list.group_n++; - ctx->objmask = NULL; - 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 || out->command == QUEUE) { - if (ctx->curr != AGED && ctx->curr != QUEUE_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, - 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 != ISOLATE) - 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 info/configure command. */ -static int -parse_configure(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 != INFO && ctx->curr != CONFIGURE) - 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 template create command. */ -static int -parse_template(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 != PATTERN_TEMPLATE && - ctx->curr != ACTIONS_TEMPLATE) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.data = (uint8_t *)out + size; - return len; - } - switch (ctx->curr) { - case PATTERN_TEMPLATE_CREATE: - out->args.vc.pattern = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - out->args.vc.pat_templ_id = UINT32_MAX; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - return len; - case PATTERN_TEMPLATE_EGRESS: - out->args.vc.attr.egress = 1; - return len; - case PATTERN_TEMPLATE_INGRESS: - out->args.vc.attr.ingress = 1; - return len; - case PATTERN_TEMPLATE_TRANSFER: - out->args.vc.attr.transfer = 1; - return len; - case ACTIONS_TEMPLATE_CREATE: - out->args.vc.act_templ_id = UINT32_MAX; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - return len; - case ACTIONS_TEMPLATE_SPEC: - out->args.vc.actions = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - ctx->object = out->args.vc.actions; - ctx->objmask = NULL; - return len; - case ACTIONS_TEMPLATE_MASK: - out->args.vc.masks = - (void *)RTE_ALIGN_CEIL((uintptr_t) - (out->args.vc.actions + - out->args.vc.actions_n), - sizeof(double)); - ctx->object = out->args.vc.masks; - ctx->objmask = NULL; - return len; - case ACTIONS_TEMPLATE_EGRESS: - out->args.vc.attr.egress = 1; - return len; - case ACTIONS_TEMPLATE_INGRESS: - out->args.vc.attr.ingress = 1; - return len; - case ACTIONS_TEMPLATE_TRANSFER: - out->args.vc.attr.transfer = 1; - return len; - default: - return -1; - } -} - -/** Parse tokens for template destroy command. */ -static int -parse_template_destroy(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - uint32_t *template_id; - - /* 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 || - out->command == PATTERN_TEMPLATE || - out->command == ACTIONS_TEMPLATE) { - if (ctx->curr != PATTERN_TEMPLATE_DESTROY && - ctx->curr != ACTIONS_TEMPLATE_DESTROY) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.templ_destroy.template_id = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; - } - template_id = out->args.templ_destroy.template_id - + out->args.templ_destroy.template_id_n++; - if ((uint8_t *)template_id > (uint8_t *)out + size) - return -1; - ctx->objdata = 0; - ctx->object = template_id; - ctx->objmask = NULL; - return len; -} - -/** Parse tokens for table create command. */ -static int -parse_table(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - uint32_t *template_id; - - /* 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 != TABLE) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - return len; - } - switch (ctx->curr) { - case TABLE_CREATE: - case TABLE_RESIZE: - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.table.id = UINT32_MAX; - return len; - case TABLE_PATTERN_TEMPLATE: - out->args.table.pat_templ_id = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - template_id = out->args.table.pat_templ_id - + out->args.table.pat_templ_id_n++; - if ((uint8_t *)template_id > (uint8_t *)out + size) - return -1; - ctx->objdata = 0; - ctx->object = template_id; - ctx->objmask = NULL; - return len; - case TABLE_ACTIONS_TEMPLATE: - out->args.table.act_templ_id = - (void *)RTE_ALIGN_CEIL((uintptr_t) - (out->args.table.pat_templ_id + - out->args.table.pat_templ_id_n), - sizeof(double)); - template_id = out->args.table.act_templ_id - + out->args.table.act_templ_id_n++; - if ((uint8_t *)template_id > (uint8_t *)out + size) - return -1; - ctx->objdata = 0; - ctx->object = template_id; - ctx->objmask = NULL; - return len; - case TABLE_INGRESS: - out->args.table.attr.flow_attr.ingress = 1; - return len; - case TABLE_EGRESS: - out->args.table.attr.flow_attr.egress = 1; - return len; - case TABLE_TRANSFER: - out->args.table.attr.flow_attr.transfer = 1; - return len; - case TABLE_TRANSFER_WIRE_ORIG: - if (!out->args.table.attr.flow_attr.transfer) - return -1; - out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; - return len; - case TABLE_TRANSFER_VPORT_ORIG: - if (!out->args.table.attr.flow_attr.transfer) - return -1; - out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; - return len; - case TABLE_RESIZABLE: - out->args.table.attr.specialize |= - RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; - return len; - case TABLE_RULES_NUMBER: - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - return len; - case TABLE_RESIZE_ID: - case TABLE_RESIZE_RULES_NUMBER: - return len; - default: - return -1; - } -} - -/** Parse tokens for table destroy command. */ -static int -parse_table_destroy(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - uint32_t *table_id; - - /* 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 || out->command == TABLE) { - if (ctx->curr != TABLE_DESTROY && - ctx->curr != TABLE_RESIZE_COMPLETE) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.table_destroy.table_id = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; - } - table_id = out->args.table_destroy.table_id - + out->args.table_destroy.table_id_n++; - if ((uint8_t *)table_id > (uint8_t *)out + size) - return -1; - ctx->objdata = 0; - ctx->object = table_id; - ctx->objmask = NULL; - return len; -} - -/** Parse table id and convert to table pointer for jump_to_table_index action. */ -static int -parse_jump_table_id(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - struct rte_port *port; - struct port_table *pt; - uint32_t table_id; - const struct arg *arg; - void *entry_ptr; - - /* Get the arg before parse_int consumes it */ - arg = pop_args(ctx); - if (!arg) - return -1; - /* Push it back and do the standard integer parsing */ - if (push_args(ctx, arg) < 0) - return -1; - if (parse_int(ctx, token, str, len, buf, size) < 0) - return -1; - /* Nothing else to do if there is no buffer */ - if (!out || !ctx->object) - return len; - /* Get the parsed table ID from where parse_int stored it */ - entry_ptr = (uint8_t *)ctx->object + arg->offset; - memcpy(&table_id, entry_ptr, sizeof(uint32_t)); - /* Look up the table using table ID */ - port = &ports[ctx->port]; - for (pt = port->table_list; pt != NULL; pt = pt->next) { - if (pt->id == table_id) - break; - } - if (!pt || !pt->table) { - printf("Table #%u not found on port %u\n", table_id, ctx->port); - return -1; - } - /* Replace the table ID with the table pointer */ - memcpy(entry_ptr, &pt->table, sizeof(struct rte_flow_template_table *)); - return len; -} - -/** Parse tokens for queue create commands. */ -static int -parse_qo(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 != QUEUE) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.data = (uint8_t *)out + size; - return len; - } - switch (ctx->curr) { - case QUEUE_CREATE: - case QUEUE_UPDATE: - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.rule_id = UINT32_MAX; - return len; - case QUEUE_TEMPLATE_TABLE: - case QUEUE_PATTERN_TEMPLATE: - case QUEUE_ACTIONS_TEMPLATE: - case QUEUE_CREATE_POSTPONE: - case QUEUE_RULE_ID: - case QUEUE_UPDATE_ID: - return len; - case ITEM_PATTERN: - out->args.vc.pattern = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - ctx->object = out->args.vc.pattern; - ctx->objmask = NULL; - return len; - case ACTIONS: - out->args.vc.actions = - (void *)RTE_ALIGN_CEIL((uintptr_t) - (out->args.vc.pattern + - out->args.vc.pattern_n), - sizeof(double)); - ctx->object = out->args.vc.actions; - ctx->objmask = NULL; - return len; - default: - return -1; - } -} - -/** Parse tokens for queue destroy command. */ -static int -parse_qo_destroy(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = buf; - uint64_t *flow_id; - - /* 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 || out->command == QUEUE) { - if (ctx->curr != QUEUE_DESTROY && - ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.destroy.rule = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; - } - switch (ctx->curr) { - case QUEUE_DESTROY_ID: - flow_id = out->args.destroy.rule - + out->args.destroy.rule_n++; - if ((uint8_t *)flow_id > (uint8_t *)out + size) - return -1; - ctx->objdata = 0; - ctx->object = flow_id; - ctx->objmask = NULL; - return len; - case QUEUE_DESTROY_POSTPONE: - return len; - default: - return -1; - } -} - -/** Parse tokens for push queue command. */ -static int -parse_push(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 != PUSH) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.data = (uint8_t *)out + size; - } - return len; -} - -/** Parse tokens for pull command. */ -static int -parse_pull(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 != PULL) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.data = (uint8_t *)out + size; - } - return len; -} - -/** Parse tokens for hash calculation commands. */ -static int -parse_hash(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 != HASH) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.data = (uint8_t *)out + size; - return len; - } - switch (ctx->curr) { - case HASH_CALC_TABLE: - case HASH_CALC_PATTERN_INDEX: - return len; - case ITEM_PATTERN: - out->args.vc.pattern = - (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - ctx->object = out->args.vc.pattern; - ctx->objmask = NULL; - return len; - case HASH_CALC_ENCAP: - out->args.vc.encap_hash = 1; - return len; - case ENCAP_HASH_FIELD_SRC_PORT: - out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; - return len; - case ENCAP_HASH_FIELD_GRE_FLOW_ID: - out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; - return len; - default: - return -1; - } -} - -static int -parse_group(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 != FLOW_GROUP) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.data = (uint8_t *)out + size; - return len; - } - switch (ctx->curr) { - case GROUP_INGRESS: - out->args.vc.attr.ingress = 1; - return len; - case GROUP_EGRESS: - out->args.vc.attr.egress = 1; - return len; - case GROUP_TRANSFER: - out->args.vc.attr.transfer = 1; - return len; - case GROUP_SET_MISS_ACTIONS: - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; - default: - return -1; - } -} - -static int -parse_flex(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 == ZERO) { - if (ctx->curr != FLEX) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - } else { - switch (ctx->curr) { - default: - break; - case FLEX_ITEM_CREATE: - case FLEX_ITEM_DESTROY: - out->command = ctx->curr; - break; - } - } - - return len; -} - -static int -parse_tunnel(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 != TUNNEL) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - } else { - switch (ctx->curr) { - default: - break; - case TUNNEL_CREATE: - case TUNNEL_DESTROY: - case TUNNEL_LIST: - out->command = ctx->curr; - break; - case TUNNEL_CREATE_TYPE: - case TUNNEL_DESTROY_ID: - ctx->object = &out->args.vc.tunnel_ops; - break; - } - } - - return len; -} - -/** - * Parse signed/unsigned integers 8 to 64-bit long. - * - * Last argument (ctx->args) is retrieved to determine integer type and - * storage location. - */ -static int -parse_int(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - const struct arg *arg = pop_args(ctx); - uintmax_t u; - char *end; - - (void)token; - /* Argument is expected. */ - if (!arg) - return -1; - errno = 0; - u = arg->sign ? - (uintmax_t)strtoimax(str, &end, 0) : - strtoumax(str, &end, 0); - if (errno || (size_t)(end - str) != len) - goto error; - if (arg->bounded && - ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || - (intmax_t)u > (intmax_t)arg->max)) || - (!arg->sign && (u < arg->min || u > arg->max)))) - goto error; - if (!ctx->object) - return len; - if (arg->mask) { - if (!arg_entry_bf_fill(ctx->object, u, arg) || - !arg_entry_bf_fill(ctx->objmask, -1, arg)) - goto error; - return len; - } - buf = (uint8_t *)ctx->object + arg->offset; - size = arg->size; - if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) - return -1; -objmask: - switch (size) { - case sizeof(uint8_t): - *(uint8_t *)buf = u; - break; - case sizeof(uint16_t): - *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; - break; - case sizeof(uint8_t [3]): -#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN - if (!arg->hton) { - ((uint8_t *)buf)[0] = u; - ((uint8_t *)buf)[1] = u >> 8; - ((uint8_t *)buf)[2] = u >> 16; - break; - } -#endif - ((uint8_t *)buf)[0] = u >> 16; - ((uint8_t *)buf)[1] = u >> 8; - ((uint8_t *)buf)[2] = u; - break; - case sizeof(uint32_t): - *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; - break; - case sizeof(uint64_t): - *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; - break; - default: - goto error; - } - if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { - u = -1; - buf = (uint8_t *)ctx->objmask + arg->offset; - goto objmask; - } - return len; -error: - push_args(ctx, arg); - return -1; -} - -/** - * Parse a string. - * - * Three arguments (ctx->args) are retrieved from the stack to store data, - * its actual length and address (in that order). - */ -static int -parse_string(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - const struct arg *arg_data = pop_args(ctx); - const struct arg *arg_len = pop_args(ctx); - const struct arg *arg_addr = pop_args(ctx); - char tmp[16]; /* Ought to be enough. */ - int ret; - - /* Arguments are expected. */ - if (!arg_data) - return -1; - if (!arg_len) { - push_args(ctx, arg_data); - return -1; - } - if (!arg_addr) { - push_args(ctx, arg_len); - push_args(ctx, arg_data); - return -1; - } - size = arg_data->size; - /* Bit-mask fill is not supported. */ - if (arg_data->mask || size < len) - goto error; - if (!ctx->object) - return len; - /* Let parse_int() fill length information first. */ - ret = snprintf(tmp, sizeof(tmp), "%u", len); - if (ret < 0) - goto error; - push_args(ctx, arg_len); - ret = parse_int(ctx, token, tmp, ret, NULL, 0); - if (ret < 0) { - pop_args(ctx); - goto error; - } - buf = (uint8_t *)ctx->object + arg_data->offset; - /* Output buffer is not necessarily NUL-terminated. */ - memcpy(buf, str, len); - memset((uint8_t *)buf + len, 0x00, size - len); - if (ctx->objmask) - memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); - /* Save address if requested. */ - if (arg_addr->size) { - memcpy((uint8_t *)ctx->object + arg_addr->offset, - (void *[]){ - (uint8_t *)ctx->object + arg_data->offset - }, - arg_addr->size); - if (ctx->objmask) - memcpy((uint8_t *)ctx->objmask + arg_addr->offset, - (void *[]){ - (uint8_t *)ctx->objmask + arg_data->offset - }, - arg_addr->size); - } - return len; -error: - push_args(ctx, arg_addr); - push_args(ctx, arg_len); - push_args(ctx, arg_data); - return -1; -} - -static int -parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) -{ - const uint8_t *head = dst; - uint32_t left; - - if (*size == 0) - return -1; - - left = *size; - - /* Convert chars to bytes */ - while (left) { - char tmp[3], *end = tmp; - uint32_t read_lim = left & 1 ? 1 : 2; - - snprintf(tmp, read_lim + 1, "%s", src); - *dst = strtoul(tmp, &end, 16); - if (*end) { - *dst = 0; - *size = (uint32_t)(dst - head); - return -1; - } - left -= read_lim; - src += read_lim; - dst++; - } - *dst = 0; - *size = (uint32_t)(dst - head); - return 0; -} - -static int -parse_hex(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - const struct arg *arg_data = pop_args(ctx); - const struct arg *arg_len = pop_args(ctx); - const struct arg *arg_addr = pop_args(ctx); - char tmp[16]; /* Ought to be enough. */ - int ret; - unsigned int hexlen = len; - uint8_t hex_tmp[256]; - - /* Arguments are expected. */ - if (!arg_data) - return -1; - if (!arg_len) { - push_args(ctx, arg_data); - return -1; - } - if (!arg_addr) { - push_args(ctx, arg_len); - push_args(ctx, arg_data); - return -1; - } - size = arg_data->size; - /* Bit-mask fill is not supported. */ - if (arg_data->mask) - goto error; - if (!ctx->object) - return len; - - /* translate bytes string to array. */ - if (str[0] == '0' && ((str[1] == 'x') || - (str[1] == 'X'))) { - str += 2; - hexlen -= 2; - } - if (hexlen > RTE_DIM(hex_tmp)) - goto error; - ret = parse_hex_string(str, hex_tmp, &hexlen); - if (ret < 0) - goto error; - /* Check the converted binary fits into data buffer. */ - if (hexlen > size) - goto error; - /* Let parse_int() fill length information first. */ - ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); - if (ret < 0) - goto error; - /* Save length if requested. */ - if (arg_len->size) { - push_args(ctx, arg_len); - ret = parse_int(ctx, token, tmp, ret, NULL, 0); - if (ret < 0) { - pop_args(ctx); - goto error; - } - } - buf = (uint8_t *)ctx->object + arg_data->offset; - /* Output buffer is not necessarily NUL-terminated. */ - memcpy(buf, hex_tmp, hexlen); - memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); - if (ctx->objmask) - memset((uint8_t *)ctx->objmask + arg_data->offset, - 0xff, hexlen); - /* Save address if requested. */ - if (arg_addr->size) { - memcpy((uint8_t *)ctx->object + arg_addr->offset, - (void *[]){ - (uint8_t *)ctx->object + arg_data->offset - }, - arg_addr->size); - if (ctx->objmask) - memcpy((uint8_t *)ctx->objmask + arg_addr->offset, - (void *[]){ - (uint8_t *)ctx->objmask + arg_data->offset - }, - arg_addr->size); - } - return len; -error: - push_args(ctx, arg_addr); - push_args(ctx, arg_len); - push_args(ctx, arg_data); - return -1; - -} - -/** - * 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. - * - * Last argument (ctx->args) is retrieved to determine storage size and - * location. - */ -static int -parse_mac_addr(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - const struct arg *arg = pop_args(ctx); - struct rte_ether_addr tmp; - int ret; - - (void)token; - /* Argument is expected. */ - if (!arg) - return -1; - size = arg->size; - /* Bit-mask fill is not supported. */ - if (arg->mask || size != sizeof(tmp)) - goto error; - /* Only network endian is supported. */ - if (!arg->hton) - goto error; - ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); - if (ret < 0 || (unsigned int)ret != len) - goto error; - if (!ctx->object) - return len; - buf = (uint8_t *)ctx->object + arg->offset; - memcpy(buf, &tmp, size); - if (ctx->objmask) - memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); - return len; -error: - push_args(ctx, arg); - return -1; -} - -/** - * Parse an IPv4 address. - * - * Last argument (ctx->args) is retrieved to determine storage size and - * location. - */ -static int -parse_ipv4_addr(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - const struct arg *arg = pop_args(ctx); - char str2[INET_ADDRSTRLEN]; - struct in_addr tmp; - int ret; - - /* Length is longer than the max length an IPv4 address can have. */ - if (len >= INET_ADDRSTRLEN) - return -1; - /* Argument is expected. */ - if (!arg) - return -1; - size = arg->size; - /* Bit-mask fill is not supported. */ - if (arg->mask || size != sizeof(tmp)) - goto error; - /* Only network endian is supported. */ - if (!arg->hton) - goto error; - memcpy(str2, str, len); - str2[len] = '\0'; - ret = inet_pton(AF_INET, str2, &tmp); - if (ret != 1) { - /* Attempt integer parsing. */ - push_args(ctx, arg); - return parse_int(ctx, token, str, len, buf, size); - } - if (!ctx->object) - return len; - buf = (uint8_t *)ctx->object + arg->offset; - memcpy(buf, &tmp, size); - if (ctx->objmask) - memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); - return len; -error: - push_args(ctx, arg); - return -1; -} - -/** - * Parse an IPv6 address. - * - * Last argument (ctx->args) is retrieved to determine storage size and - * location. - */ -static int -parse_ipv6_addr(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - const struct arg *arg = pop_args(ctx); - char str2[INET6_ADDRSTRLEN]; - struct rte_ipv6_addr tmp; - int ret; - - (void)token; - /* Length is longer than the max length an IPv6 address can have. */ - if (len >= INET6_ADDRSTRLEN) - return -1; - /* Argument is expected. */ - if (!arg) - return -1; - size = arg->size; - /* Bit-mask fill is not supported. */ - if (arg->mask || size != sizeof(tmp)) - goto error; - /* Only network endian is supported. */ - if (!arg->hton) - goto error; - memcpy(str2, str, len); - str2[len] = '\0'; - ret = inet_pton(AF_INET6, str2, &tmp); - if (ret != 1) - goto error; - if (!ctx->object) - return len; - buf = (uint8_t *)ctx->object + arg->offset; - memcpy(buf, &tmp, size); - if (ctx->objmask) - memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); - return len; -error: - push_args(ctx, arg); - return -1; -} - -/** Boolean values (even indices stand for false). */ -static const char *const boolean_name[] = { - "0", "1", - "false", "true", - "no", "yes", - "N", "Y", - "off", "on", - NULL, -}; - -/** - * Parse a boolean value. - * - * Last argument (ctx->args) is retrieved to determine storage size and - * location. - */ -static int -parse_boolean(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - const struct arg *arg = pop_args(ctx); - unsigned int i; - int ret; - - /* Argument is expected. */ - if (!arg) - return -1; - for (i = 0; boolean_name[i]; ++i) - if (!strcmp_partial(boolean_name[i], str, len)) - break; - /* Process token as integer. */ - if (boolean_name[i]) - str = i & 1 ? "1" : "0"; - push_args(ctx, arg); - ret = parse_int(ctx, token, str, strlen(str), buf, size); - return ret > 0 ? (int)len : ret; -} - -/** Parse port and update context. */ -static int -parse_port(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct buffer *out = &(struct buffer){ .port = 0 }; - int ret; - - if (buf) - out = buf; - else { - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - size = sizeof(*out); - } - ret = parse_int(ctx, token, str, len, out, size); - if (ret >= 0) - ctx->port = out->port; - if (!buf) - ctx->object = NULL; - return ret; -} - -/** Parse tokens for shared indirect actions. */ -static int -parse_ia_port(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct rte_flow_action *action = ctx->object; - uint32_t id; - int ret; - - (void)buf; - (void)size; - ctx->objdata = 0; - ctx->object = &id; - ctx->objmask = NULL; - ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); - ctx->object = action; - if (ret != (int)len) - return ret; - /* set indirect action */ - if (action) - action->conf = (void *)(uintptr_t)id; - return ret; -} - -static int -parse_ia_id2ptr(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct rte_flow_action *action = ctx->object; - uint32_t id; - int ret; - - (void)buf; - (void)size; - ctx->objdata = 0; - ctx->object = &id; - ctx->objmask = NULL; - ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); - ctx->object = action; - if (ret != (int)len) - return ret; - /* set indirect action */ - if (action) { - portid_t port_id = ctx->port; - if (ctx->prev == INDIRECT_ACTION_PORT) - port_id = (portid_t)(uintptr_t)action->conf; - action->conf = port_action_handle_get_by_id(port_id, id); - ret = (action->conf) ? ret : -1; - } - return ret; -} - -static int -parse_indlst_id2ptr(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - __rte_unused void *buf, __rte_unused unsigned int 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; - - ctx->objdata = 0; - ctx->object = &id; - ctx->objmask = NULL; - ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); - ctx->object = action; - if (ret != (int)len) - return ret; - - /* set handle and conf */ - if (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, - void *buf, unsigned int size) -{ - struct rte_flow_action *action = ctx->object; - struct rte_flow_action_meter_mark *meter; - struct rte_flow_meter_profile *profile = NULL; - uint32_t id = 0; - int ret; - - (void)buf; - (void)size; - ctx->objdata = 0; - ctx->object = &id; - ctx->objmask = NULL; - ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); - ctx->object = action; - if (ret != (int)len) - return ret; - /* set meter profile */ - if (action) { - meter = (struct rte_flow_action_meter_mark *) - (uintptr_t)(action->conf); - profile = port_meter_profile_get_by_id(ctx->port, id); - meter->profile = profile; - ret = (profile) ? ret : -1; - } - return ret; -} - -static int -parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct rte_flow_action *action = ctx->object; - struct rte_flow_action_meter_mark *meter; - struct rte_flow_meter_policy *policy = NULL; - uint32_t id = 0; - int ret; - - (void)buf; - (void)size; - ctx->objdata = 0; - ctx->object = &id; - ctx->objmask = NULL; - ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); - ctx->object = action; - if (ret != (int)len) - return ret; - /* set meter policy */ - if (action) { - meter = (struct rte_flow_action_meter_mark *) - (uintptr_t)(action->conf); - policy = port_meter_policy_get_by_id(ctx->port, id); - meter->policy = policy; - ret = (policy) ? ret : -1; - } - return ret; -} - -/** Parse set command, initialize output buffer for subsequent tokens. */ -static int -parse_set_raw_encap_decap(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; - /* Make sure buffer is large enough. */ - if (size < sizeof(*out)) - return -1; - ctx->objdata = 0; - ctx->objmask = NULL; - ctx->object = out; - if (!out->command) - return -1; - out->command = ctx->curr; - /* For encap/decap we need is pattern */ - out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; -} - -/** Parse set command, initialize output buffer for subsequent tokens. */ -static int -parse_set_sample_action(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; - /* Make sure buffer is large enough. */ - if (size < sizeof(*out)) - return -1; - ctx->objdata = 0; - ctx->objmask = NULL; - ctx->object = out; - if (!out->command) - return -1; - out->command = ctx->curr; - /* For sampler we need is actions */ - out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; -} - -/** Parse set command, initialize output buffer for subsequent tokens. */ -static int -parse_set_ipv6_ext_action(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; - /* Make sure buffer is large enough. */ - if (size < sizeof(*out)) - return -1; - ctx->objdata = 0; - ctx->objmask = NULL; - ctx->object = out; - if (!out->command) - return -1; - out->command = ctx->curr; - /* For ipv6_ext_push/remove we need is pattern */ - out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - return len; -} - -/** - * Parse set raw_encap/raw_decap command, - * initialize output buffer for subsequent tokens. - */ -static int -parse_set_init(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; - /* Make sure buffer is large enough. */ - if (size < sizeof(*out)) - return -1; - /* Initialize buffer. */ - memset(out, 0x00, sizeof(*out)); - memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); - ctx->objdata = 0; - ctx->object = out; - ctx->objmask = NULL; - if (!out->command) { - if (ctx->curr != SET) - return -1; - if (sizeof(*out) > size) - return -1; - out->command = ctx->curr; - out->args.vc.data = (uint8_t *)out + size; - ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), - sizeof(double)); - } - return len; -} - -/* - * Replace testpmd handles in a flex flow item with real values. - */ -static int -parse_flex_handle(struct context *ctx, const struct token *token, - const char *str, unsigned int len, - void *buf, unsigned int size) -{ - struct rte_flow_item_flex *spec, *mask; - const struct rte_flow_item_flex *src_spec, *src_mask; - const struct arg *arg = pop_args(ctx); - uint32_t offset; - uint16_t handle; - int ret; - - if (!arg) { - printf("Bad environment\n"); - return -1; - } - offset = arg->offset; - push_args(ctx, arg); - ret = parse_int(ctx, token, str, len, buf, size); - if (ret <= 0 || !ctx->object) - return ret; - if (ctx->port >= RTE_MAX_ETHPORTS) { - printf("Bad port\n"); - return -1; - } - if (offset == offsetof(struct rte_flow_item_flex, handle)) { - const struct flex_item *fp; - spec = ctx->object; - handle = (uint16_t)(uintptr_t)spec->handle; - if (handle >= FLEX_MAX_PARSERS_NUM) { - printf("Bad flex item handle\n"); - return -1; - } - fp = flex_items[ctx->port][handle]; - if (!fp) { - printf("Bad flex item handle\n"); - return -1; - } - spec->handle = fp->flex_handle; - mask = spec + 2; /* spec, last, mask */ - mask->handle = fp->flex_handle; - } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { - handle = (uint16_t)(uintptr_t) - ((struct rte_flow_item_flex *)ctx->object)->pattern; - if (handle >= FLEX_MAX_PATTERNS_NUM) { - printf("Bad pattern handle\n"); - return -1; - } - src_spec = &flex_patterns[handle].spec; - src_mask = &flex_patterns[handle].mask; - spec = ctx->object; - mask = spec + 2; /* spec, last, mask */ - /* fill flow rule spec and mask parameters */ - spec->length = src_spec->length; - spec->pattern = src_spec->pattern; - mask->length = src_mask->length; - mask->pattern = src_mask->pattern; - } else { - printf("Bad arguments - unknown flex item offset\n"); - return -1; - } - return ret; -} - -/** Parse Meter color name */ -static int -parse_meter_color(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - unsigned int i; - struct buffer *out = buf; - - (void)token; - (void)buf; - (void)size; - for (i = 0; meter_colors[i]; ++i) - if (!strcmp_partial(meter_colors[i], str, len)) - break; - if (!meter_colors[i]) - return -1; - if (!ctx->object) - return len; - if (ctx->prev == ACTION_METER_MARK_CONF_COLOR) { - struct rte_flow_action *action = - out->args.vc.actions + out->args.vc.actions_n - 1; - const struct arg *arg = pop_args(ctx); - - if (!arg) - return -1; - *(int *)RTE_PTR_ADD(action->conf, arg->offset) = i; - } else { - ((struct rte_flow_item_meter_color *) - ctx->object)->color = (enum rte_color)i; - } - return len; -} - -/** Parse Insertion Table Type name */ -static int -parse_insertion_table_type(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - const struct arg *arg = pop_args(ctx); - unsigned int i; - char tmp[2]; - int ret; - - (void)size; - /* Argument is expected. */ - if (!arg) - return -1; - for (i = 0; table_insertion_types[i]; ++i) - if (!strcmp_partial(table_insertion_types[i], str, len)) - break; - if (!table_insertion_types[i]) - return -1; - push_args(ctx, arg); - snprintf(tmp, sizeof(tmp), "%u", i); - ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); - return ret > 0 ? (int)len : ret; -} - -/** Parse Hash Calculation Table Type name */ -static int -parse_hash_table_type(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - const struct arg *arg = pop_args(ctx); - unsigned int i; - char tmp[2]; - int ret; - - (void)size; - /* Argument is expected. */ - if (!arg) - return -1; - for (i = 0; table_hash_funcs[i]; ++i) - if (!strcmp_partial(table_hash_funcs[i], str, len)) - break; - if (!table_hash_funcs[i]) - return -1; - push_args(ctx, arg); - snprintf(tmp, sizeof(tmp), "%u", i); - ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); - return ret > 0 ? (int)len : ret; -} - -static int -parse_name_to_index(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size, - const char *const names[], size_t names_size, uint32_t *dst) -{ - int ret; - uint32_t i; - - RTE_SET_USED(token); - RTE_SET_USED(buf); - RTE_SET_USED(size); - if (!ctx->object) - return len; - for (i = 0; i < names_size; i++) { - if (!names[i]) - continue; - ret = strcmp_partial(names[i], str, - RTE_MIN(len, strlen(names[i]))); - if (!ret) { - *dst = i; - return len; - } - } - return -1; -} - -static const char *const quota_mode_names[] = { - NULL, - [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", - [RTE_FLOW_QUOTA_MODE_L2] = "l2", - [RTE_FLOW_QUOTA_MODE_L3] = "l3" -}; - -static const char *const quota_state_names[] = { - [RTE_FLOW_QUOTA_STATE_PASS] = "pass", - [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" -}; - -static const char *const quota_update_names[] = { - [RTE_FLOW_UPDATE_QUOTA_SET] = "set", - [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" -}; - -static const char *const query_update_mode_names[] = { - [RTE_FLOW_QU_QUERY_FIRST] = "query_first", - [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" -}; - -static int -parse_quota_state_name(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct rte_flow_item_quota *quota = ctx->object; - - return parse_name_to_index(ctx, token, str, len, buf, size, - quota_state_names, - RTE_DIM(quota_state_names), - (uint32_t *)"a->state); -} - -static int -parse_quota_mode_name(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct rte_flow_action_quota *quota = ctx->object; - - return parse_name_to_index(ctx, token, str, len, buf, size, - quota_mode_names, - RTE_DIM(quota_mode_names), - (uint32_t *)"a->mode); -} - -static int -parse_quota_update_name(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct rte_flow_update_quota *update = ctx->object; - - return parse_name_to_index(ctx, token, str, len, buf, size, - quota_update_names, - RTE_DIM(quota_update_names), - (uint32_t *)&update->op); -} - -static int -parse_qu_mode_name(struct context *ctx, const struct token *token, - const char *str, unsigned int len, void *buf, - unsigned int size) -{ - struct buffer *out = ctx->object; - - return parse_name_to_index(ctx, token, str, len, buf, size, - query_update_mode_names, - RTE_DIM(query_update_mode_names), - (uint32_t *)&out->args.ia.qu_mode); -} - -/** No completion. */ -static int -comp_none(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - (void)ctx; - (void)token; - (void)ent; - (void)buf; - (void)size; - return 0; -} - -/** Complete boolean values. */ -static int -comp_boolean(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - unsigned int i; - - (void)ctx; - (void)token; - for (i = 0; boolean_name[i]; ++i) - if (buf && i == ent) - return strlcpy(buf, boolean_name[i], size); - if (buf) - return -1; - return i; -} - -/** Complete action names. */ -static int -comp_action(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - unsigned int i; - - (void)ctx; - (void)token; - for (i = 0; next_action[i]; ++i) - if (buf && i == ent) - return strlcpy(buf, token_list[next_action[i]].name, - size); - if (buf) - return -1; - return i; -} - -/** Complete available ports. */ -static int -comp_port(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - unsigned int i = 0; - portid_t p; - - (void)ctx; - (void)token; - RTE_ETH_FOREACH_DEV(p) { - if (buf && i == ent) - return snprintf(buf, size, "%u", p); - ++i; - } - if (buf) - return -1; - return i; -} - -/** Complete available rule IDs. */ -static int -comp_rule_id(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - unsigned int i = 0; - struct rte_port *port; - struct port_flow *pf; - - (void)token; - if (port_id_is_invalid(ctx->port, DISABLED_WARN) || - ctx->port == (portid_t)RTE_PORT_ALL) - return -1; - port = &ports[ctx->port]; - for (pf = port->flow_list; pf != NULL; pf = pf->next) { - if (buf && i == ent) - return snprintf(buf, size, "%"PRIu64, pf->id); - ++i; - } - if (buf) - return -1; - return i; -} - -/** Complete operation for compare match item. */ -static int -comp_set_compare_op(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - RTE_SET_USED(ctx); - RTE_SET_USED(token); - if (!buf) - return RTE_DIM(compare_ops); - if (ent < RTE_DIM(compare_ops) - 1) - return strlcpy(buf, compare_ops[ent], size); - return -1; -} - -/** Complete field id for compare match item. */ -static int -comp_set_compare_field_id(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - const char *name; - - RTE_SET_USED(token); - if (!buf) - return RTE_DIM(flow_field_ids); - if (ent >= RTE_DIM(flow_field_ids) - 1) - return -1; - name = flow_field_ids[ent]; - if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || - (strcmp(name, "pointer") && strcmp(name, "value"))) - return strlcpy(buf, name, size); - return -1; -} - -/** Complete type field for RSS action. */ -static int -comp_vc_action_rss_type(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - unsigned int i; - - (void)ctx; - (void)token; - for (i = 0; rss_type_table[i].str; ++i) - ; - if (!buf) - return i + 1; - if (ent < i) - return strlcpy(buf, rss_type_table[ent].str, size); - if (ent == i) - return snprintf(buf, size, "end"); - return -1; -} - -/** Complete queue field for RSS action. */ -static int -comp_vc_action_rss_queue(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - (void)ctx; - (void)token; - if (!buf) - return nb_rxq + 1; - if (ent < nb_rxq) - return snprintf(buf, size, "%u", ent); - if (ent == nb_rxq) - return snprintf(buf, size, "end"); - return -1; -} - -/** Complete index number for set raw_encap/raw_decap commands. */ -static int -comp_set_raw_index(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - uint16_t idx = 0; - uint16_t nb = 0; - - RTE_SET_USED(ctx); - RTE_SET_USED(token); - for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { - if (buf && idx == ent) - return snprintf(buf, size, "%u", idx); - ++nb; - } - return nb; -} - -/** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ -static int -comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - uint16_t idx = 0; - uint16_t nb = 0; - - RTE_SET_USED(ctx); - RTE_SET_USED(token); - for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { - if (buf && idx == ent) - return snprintf(buf, size, "%u", idx); - ++nb; - } - return nb; -} - -/** Complete index number for set raw_encap/raw_decap commands. */ -static int -comp_set_sample_index(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - uint16_t idx = 0; - uint16_t nb = 0; - - RTE_SET_USED(ctx); - RTE_SET_USED(token); - for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { - if (buf && idx == ent) - return snprintf(buf, size, "%u", idx); - ++nb; - } - return nb; -} - -/** Complete operation for modify_field command. */ -static int -comp_set_modify_field_op(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - RTE_SET_USED(ctx); - RTE_SET_USED(token); - if (!buf) - return RTE_DIM(modify_field_ops); - if (ent < RTE_DIM(modify_field_ops) - 1) - return strlcpy(buf, modify_field_ops[ent], size); - return -1; -} - -/** Complete field id for modify_field command. */ -static int -comp_set_modify_field_id(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - const char *name; - - RTE_SET_USED(token); - if (!buf) - return RTE_DIM(flow_field_ids); - if (ent >= RTE_DIM(flow_field_ids) - 1) - return -1; - name = flow_field_ids[ent]; - if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || - (strcmp(name, "pointer") && strcmp(name, "value"))) - return strlcpy(buf, name, size); - return -1; -} - -/** Complete available pattern template IDs. */ -static int -comp_pattern_template_id(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - unsigned int i = 0; - struct rte_port *port; - struct port_template *pt; - - (void)token; - if (port_id_is_invalid(ctx->port, DISABLED_WARN) || - ctx->port == (portid_t)RTE_PORT_ALL) - return -1; - port = &ports[ctx->port]; - for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { - if (buf && i == ent) - return snprintf(buf, size, "%u", pt->id); - ++i; - } - if (buf) - return -1; - return i; -} - -/** Complete available actions template IDs. */ -static int -comp_actions_template_id(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - unsigned int i = 0; - struct rte_port *port; - struct port_template *pt; - - (void)token; - if (port_id_is_invalid(ctx->port, DISABLED_WARN) || - ctx->port == (portid_t)RTE_PORT_ALL) - return -1; - port = &ports[ctx->port]; - for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { - if (buf && i == ent) - return snprintf(buf, size, "%u", pt->id); - ++i; - } - if (buf) - return -1; - return i; -} - -/** Complete available table IDs. */ -static int -comp_table_id(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - unsigned int i = 0; - struct rte_port *port; - struct port_table *pt; - - (void)token; - if (port_id_is_invalid(ctx->port, DISABLED_WARN) || - ctx->port == (portid_t)RTE_PORT_ALL) - return -1; - port = &ports[ctx->port]; - for (pt = port->table_list; pt != NULL; pt = pt->next) { - if (buf && i == ent) - return snprintf(buf, size, "%u", pt->id); - ++i; - } - if (buf) - return -1; - return i; -} - -/** Complete available queue IDs. */ -static int -comp_queue_id(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - unsigned int i = 0; - struct rte_port *port; - - (void)token; - if (port_id_is_invalid(ctx->port, DISABLED_WARN) || - ctx->port == (portid_t)RTE_PORT_ALL) - return -1; - port = &ports[ctx->port]; - for (i = 0; i < port->queue_nb; i++) { - if (buf && i == ent) - return snprintf(buf, size, "%u", i); - } - if (buf) - return -1; - return i; -} - -static int -comp_names_to_index(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size, - const char *const names[], size_t names_size) -{ - RTE_SET_USED(ctx); - RTE_SET_USED(token); - if (!buf) - return names_size; - if (ent < names_size && names[ent] != NULL) - return rte_strscpy(buf, names[ent], size); - return -1; - -} - -/** Complete available Meter colors. */ -static int -comp_meter_color(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - RTE_SET_USED(ctx); - RTE_SET_USED(token); - if (!buf) - return RTE_DIM(meter_colors); - if (ent < RTE_DIM(meter_colors) - 1) - return strlcpy(buf, meter_colors[ent], size); - return -1; -} - -/** Complete available Insertion Table types. */ -static int -comp_insertion_table_type(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - RTE_SET_USED(ctx); - RTE_SET_USED(token); - if (!buf) - return RTE_DIM(table_insertion_types); - if (ent < RTE_DIM(table_insertion_types) - 1) - return rte_strscpy(buf, table_insertion_types[ent], size); - return -1; -} - -/** Complete available Hash Calculation Table types. */ -static int -comp_hash_table_type(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - RTE_SET_USED(ctx); - RTE_SET_USED(token); - if (!buf) - return RTE_DIM(table_hash_funcs); - if (ent < RTE_DIM(table_hash_funcs) - 1) - return rte_strscpy(buf, table_hash_funcs[ent], size); - return -1; -} - -static int -comp_quota_state_name(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - return comp_names_to_index(ctx, token, ent, buf, size, - quota_state_names, - RTE_DIM(quota_state_names)); -} - -static int -comp_quota_mode_name(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - return comp_names_to_index(ctx, token, ent, buf, size, - quota_mode_names, - RTE_DIM(quota_mode_names)); -} - -static int -comp_quota_update_name(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - return comp_names_to_index(ctx, token, ent, buf, size, - quota_update_names, - RTE_DIM(quota_update_names)); -} - -static int -comp_qu_mode_name(struct context *ctx, const struct token *token, - unsigned int ent, char *buf, unsigned int size) -{ - return comp_names_to_index(ctx, token, ent, buf, size, - query_update_mode_names, - RTE_DIM(query_update_mode_names)); -} - -/** Internal context. */ -static struct context cmd_flow_context; - -/** Global parser instance (cmdline API). */ -cmdline_parse_inst_t cmd_flow; -cmdline_parse_inst_t cmd_set_raw; - -/** Initialize context. */ -static void -cmd_flow_context_init(struct context *ctx) -{ - /* A full memset() is not necessary. */ - ctx->curr = ZERO; - ctx->prev = ZERO; - ctx->next_num = 0; - ctx->args_num = 0; - ctx->eol = 0; - ctx->last = 0; - ctx->port = 0; - ctx->objdata = 0; - ctx->object = NULL; - ctx->objmask = NULL; -} - -/** Parse a token (cmdline API). */ -static int -cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, - unsigned int size) -{ - struct context *ctx = &cmd_flow_context; - const struct token *token; - const enum index *list; - int len; - int i; - - (void)hdr; - token = &token_list[ctx->curr]; - /* Check argument length. */ - ctx->eol = 0; - ctx->last = 1; - for (len = 0; src[len]; ++len) - if (src[len] == '#' || isspace(src[len])) - break; - if (!len) - return -1; - /* Last argument and EOL detection. */ - for (i = len; src[i]; ++i) - if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') - break; - else if (!isspace(src[i])) { - ctx->last = 0; - break; - } - for (; src[i]; ++i) - if (src[i] == '\r' || src[i] == '\n') { - ctx->eol = 1; - break; - } - /* Initialize context if necessary. */ - if (!ctx->next_num) { - if (!token->next) - return 0; - ctx->next[ctx->next_num++] = token->next[0]; - } - /* Process argument through candidates. */ - ctx->prev = ctx->curr; - list = ctx->next[ctx->next_num - 1]; - for (i = 0; list[i]; ++i) { - const struct token *next = &token_list[list[i]]; - int tmp; - - ctx->curr = list[i]; - if (next->call) - tmp = next->call(ctx, next, src, len, result, size); - else - tmp = parse_default(ctx, next, src, len, result, size); - if (tmp == -1 || tmp != len) - continue; - token = next; - break; - } - if (!list[i]) - return -1; - --ctx->next_num; - /* Push subsequent tokens if any. */ - if (token->next) - for (i = 0; token->next[i]; ++i) { - if (ctx->next_num == RTE_DIM(ctx->next)) - return -1; - ctx->next[ctx->next_num++] = token->next[i]; - } - /* Push arguments if any. */ - if (token->args) - for (i = 0; token->args[i]; ++i) { - if (ctx->args_num == RTE_DIM(ctx->args)) - return -1; - ctx->args[ctx->args_num++] = token->args[i]; - } - return len; -} - -int -flow_parse(const char *src, void *result, unsigned int size, - struct rte_flow_attr **attr, - struct rte_flow_item **pattern, struct rte_flow_action **actions) -{ - int ret; - struct context saved_flow_ctx = cmd_flow_context; - - cmd_flow_context_init(&cmd_flow_context); - do { - ret = cmd_flow_parse(NULL, src, result, size); - if (ret > 0) { - src += ret; - while (isspace(*src)) - src++; - } - } while (ret > 0 && strlen(src)); - cmd_flow_context = saved_flow_ctx; - *attr = &((struct buffer *)result)->args.vc.attr; - *pattern = ((struct buffer *)result)->args.vc.pattern; - *actions = ((struct buffer *)result)->args.vc.actions; - return (ret >= 0 && !strlen(src)) ? 0 : -1; -} - -/** Return number of completion entries (cmdline API). */ -static int -cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) -{ - struct context *ctx = &cmd_flow_context; - const struct token *token = &token_list[ctx->curr]; - const enum index *list; - int i; - - (void)hdr; - /* Count number of tokens in current list. */ - if (ctx->next_num) - list = ctx->next[ctx->next_num - 1]; - else - list = token->next[0]; - for (i = 0; list[i]; ++i) - ; - if (!i) - return 0; - /* - * If there is a single token, use its completion callback, otherwise - * return the number of entries. - */ - token = &token_list[list[0]]; - if (i == 1 && token->comp) { - /* Save index for cmd_flow_get_help(). */ - ctx->prev = list[0]; - return token->comp(ctx, token, 0, NULL, 0); - } - return i; -} - -/** Return a completion entry (cmdline API). */ -static int -cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, - char *dst, unsigned int size) -{ - struct context *ctx = &cmd_flow_context; - const struct token *token = &token_list[ctx->curr]; - const enum index *list; - int i; - - (void)hdr; - /* Count number of tokens in current list. */ - if (ctx->next_num) - list = ctx->next[ctx->next_num - 1]; - else - list = token->next[0]; - for (i = 0; list[i]; ++i) - ; - if (!i) - return -1; - /* If there is a single token, use its completion callback. */ - token = &token_list[list[0]]; - if (i == 1 && token->comp) { - /* Save index for cmd_flow_get_help(). */ - ctx->prev = list[0]; - return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; - } - /* Otherwise make sure the index is valid and use defaults. */ - if (index >= i) - return -1; - token = &token_list[list[index]]; - strlcpy(dst, token->name, size); - /* Save index for cmd_flow_get_help(). */ - ctx->prev = list[index]; - return 0; -} - -/** Populate help strings for current token (cmdline API). */ -static int -cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) -{ - struct context *ctx = &cmd_flow_context; - const struct token *token = &token_list[ctx->prev]; - - (void)hdr; - if (!size) - return -1; - /* Set token type and update global help with details. */ - strlcpy(dst, (token->type ? token->type : "TOKEN"), size); - if (token->help) - cmd_flow.help_str = token->help; - else - cmd_flow.help_str = token->name; - return 0; -} - -/** Token definition template (cmdline API). */ -static struct cmdline_token_hdr cmd_flow_token_hdr = { - .ops = &(struct cmdline_token_ops){ - .parse = cmd_flow_parse, - .complete_get_nb = cmd_flow_complete_get_nb, - .complete_get_elt = cmd_flow_complete_get_elt, - .get_help = cmd_flow_get_help, - }, - .offset = 0, -}; - -/** Populate the next dynamic token. */ -static void -cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, - cmdline_parse_token_hdr_t **hdr_inst) -{ - struct context *ctx = &cmd_flow_context; - - /* Always reinitialize context before requesting the first token. */ - if (!(hdr_inst - cmd_flow.tokens)) - cmd_flow_context_init(ctx); - /* Return NULL when no more tokens are expected. */ - if (!ctx->next_num && ctx->curr) { - *hdr = NULL; - return; - } - /* Determine if command should end here. */ - if (ctx->eol && ctx->last && ctx->next_num) { - const enum index *list = ctx->next[ctx->next_num - 1]; - int i; - - for (i = 0; list[i]; ++i) { - if (list[i] != END) - continue; - *hdr = NULL; - return; - } - } - *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) -{ - switch (in->command) { - case INFO: - port_flow_get_info(in->port); - break; - case CONFIGURE: - port_flow_configure(in->port, - &in->args.configure.port_attr, - in->args.configure.nb_queue, - &in->args.configure.queue_attr); - break; - case PATTERN_TEMPLATE_CREATE: - port_flow_pattern_template_create(in->port, - in->args.vc.pat_templ_id, - &((const struct rte_flow_pattern_template_attr) { - .relaxed_matching = in->args.vc.attr.reserved, - .ingress = in->args.vc.attr.ingress, - .egress = in->args.vc.attr.egress, - .transfer = in->args.vc.attr.transfer, - }), - in->args.vc.pattern); - break; - case PATTERN_TEMPLATE_DESTROY: - port_flow_pattern_template_destroy(in->port, - in->args.templ_destroy.template_id_n, - in->args.templ_destroy.template_id); - break; - case ACTIONS_TEMPLATE_CREATE: - port_flow_actions_template_create(in->port, - in->args.vc.act_templ_id, - &((const struct rte_flow_actions_template_attr) { - .ingress = in->args.vc.attr.ingress, - .egress = in->args.vc.attr.egress, - .transfer = in->args.vc.attr.transfer, - }), - in->args.vc.actions, - in->args.vc.masks); - break; - case ACTIONS_TEMPLATE_DESTROY: - port_flow_actions_template_destroy(in->port, - in->args.templ_destroy.template_id_n, - in->args.templ_destroy.template_id); - break; - case TABLE_CREATE: - port_flow_template_table_create(in->port, in->args.table.id, - &in->args.table.attr, in->args.table.pat_templ_id_n, - in->args.table.pat_templ_id, in->args.table.act_templ_id_n, - in->args.table.act_templ_id); - break; - case TABLE_DESTROY: - port_flow_template_table_destroy(in->port, - in->args.table_destroy.table_id_n, - in->args.table_destroy.table_id); - break; - case TABLE_RESIZE_COMPLETE: - port_flow_template_table_resize_complete - (in->port, in->args.table_destroy.table_id[0]); - break; - case GROUP_SET_MISS_ACTIONS: - port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, - in->args.vc.actions); - break; - case TABLE_RESIZE: - port_flow_template_table_resize(in->port, in->args.table.id, - in->args.table.attr.nb_flows); - break; - case QUEUE_CREATE: - port_queue_flow_create(in->port, in->queue, in->postpone, - in->args.vc.table_id, in->args.vc.rule_id, - in->args.vc.pat_templ_id, in->args.vc.act_templ_id, - in->args.vc.pattern, in->args.vc.actions); - break; - case QUEUE_DESTROY: - port_queue_flow_destroy(in->port, in->queue, in->postpone, - in->args.destroy.rule_n, - in->args.destroy.rule); - break; - case QUEUE_FLOW_UPDATE_RESIZED: - port_queue_flow_update_resized(in->port, in->queue, - in->postpone, - in->args.destroy.rule[0]); - break; - case QUEUE_UPDATE: - port_queue_flow_update(in->port, in->queue, in->postpone, - in->args.vc.rule_id, in->args.vc.act_templ_id, - in->args.vc.actions); - break; - case PUSH: - port_queue_flow_push(in->port, in->queue); - break; - case PULL: - port_queue_flow_pull(in->port, in->queue); - break; - case HASH: - if (!in->args.vc.encap_hash) - port_flow_hash_calc(in->port, in->args.vc.table_id, - in->args.vc.pat_templ_id, - in->args.vc.pattern); - else - port_flow_hash_calc_encap(in->port, in->args.vc.field, - in->args.vc.pattern); - break; - case QUEUE_AGED: - port_queue_flow_aged(in->port, in->queue, - 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, - in->command == QUEUE_INDIRECT_ACTION_LIST_CREATE, - &((const struct rte_flow_indir_action_conf) { - .ingress = in->args.vc.attr.ingress, - .egress = in->args.vc.attr.egress, - .transfer = in->args.vc.attr.transfer, - }), - in->args.vc.actions); - break; - case QUEUE_INDIRECT_ACTION_DESTROY: - port_queue_action_handle_destroy(in->port, - in->queue, in->postpone, - in->args.ia_destroy.action_id_n, - in->args.ia_destroy.action_id); - break; - case QUEUE_INDIRECT_ACTION_UPDATE: - port_queue_action_handle_update(in->port, - in->queue, in->postpone, - in->args.vc.attr.group, - in->args.vc.actions); - break; - case QUEUE_INDIRECT_ACTION_QUERY: - port_queue_action_handle_query(in->port, - in->queue, in->postpone, - in->args.ia.action_id); - break; - case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: - port_queue_action_handle_query_update(in->port, in->queue, - in->postpone, - in->args.ia.action_id, - in->args.ia.qu_mode, - 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, - .transfer = in->args.vc.attr.transfer, - }), - 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, - in->args.ia_destroy.action_id); - break; - case INDIRECT_ACTION_UPDATE: - port_action_handle_update(in->port, in->args.vc.attr.group, - in->args.vc.actions); - break; - case INDIRECT_ACTION_QUERY: - port_action_handle_query(in->port, in->args.ia.action_id); - break; - case INDIRECT_ACTION_QUERY_UPDATE: - port_action_handle_query_update(in->port, - in->args.ia.action_id, - in->args.ia.qu_mode, - in->args.vc.actions); - break; - case VALIDATE: - port_flow_validate(in->port, &in->args.vc.attr, - in->args.vc.pattern, in->args.vc.actions, - &in->args.vc.tunnel_ops); - break; - case CREATE: - port_flow_create(in->port, &in->args.vc.attr, - in->args.vc.pattern, in->args.vc.actions, - &in->args.vc.tunnel_ops, in->args.vc.user_id); - break; - case DESTROY: - port_flow_destroy(in->port, in->args.destroy.rule_n, - in->args.destroy.rule, - in->args.destroy.is_user_id); - break; - case UPDATE: - port_flow_update(in->port, in->args.vc.rule_id, - in->args.vc.actions, in->args.vc.user_id); - break; - case FLUSH: - port_flow_flush(in->port); - break; - case DUMP_ONE: - case DUMP_ALL: - port_flow_dump(in->port, in->args.dump.mode, - in->args.dump.rule, in->args.dump.file, - in->args.dump.is_user_id); - break; - case QUERY: - port_flow_query(in->port, in->args.query.rule, - &in->args.query.action, - in->args.query.is_user_id); - break; - case LIST: - port_flow_list(in->port, in->args.list.group_n, - in->args.list.group); - break; - case ISOLATE: - port_flow_isolate(in->port, in->args.isolate.set); - break; - case AGED: - port_flow_aged(in->port, in->args.aged.destroy); - break; - case TUNNEL_CREATE: - port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); - break; - case TUNNEL_DESTROY: - port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); - break; - case TUNNEL_LIST: - port_flow_tunnel_list(in->port); - break; - case ACTION_POL_G: - port_meter_policy_add(in->port, in->args.policy.policy_id, - in->args.vc.actions); - break; - case FLEX_ITEM_CREATE: - flex_item_create(in->port, in->args.flex.token, - in->args.flex.filename); - break; - case FLEX_ITEM_DESTROY: - flex_item_destroy(in->port, in->args.flex.token); - break; - default: - break; - } - fflush(stdout); -} - -/** Token generator and output processing callback (cmdline API). */ -static void -cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) -{ - if (cl == NULL) - cmd_flow_tok(arg0, arg2); - else - cmd_flow_parsed(arg0); -} - -/** Global parser instance (cmdline API). */ -cmdline_parse_inst_t cmd_flow = { - .f = cmd_flow_cb, - .data = NULL, /**< Unused. */ - .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ - .tokens = { - NULL, - }, /**< Tokens are returned by cmd_flow_tok(). */ -}; - -/** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ - -static void -update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) -{ - struct rte_ipv4_hdr *ipv4; - struct rte_ether_hdr *eth; - struct rte_ipv6_hdr *ipv6; - struct rte_vxlan_hdr *vxlan; - struct rte_vxlan_gpe_hdr *gpe; - struct rte_flow_item_nvgre *nvgre; - uint32_t ipv6_vtc_flow; - - switch (item->type) { - case RTE_FLOW_ITEM_TYPE_ETH: - eth = (struct rte_ether_hdr *)buf; - if (next_proto) - eth->ether_type = rte_cpu_to_be_16(next_proto); - break; - case RTE_FLOW_ITEM_TYPE_IPV4: - ipv4 = (struct rte_ipv4_hdr *)buf; - if (!ipv4->version_ihl) - ipv4->version_ihl = RTE_IPV4_VHL_DEF; - if (next_proto && ipv4->next_proto_id == 0) - ipv4->next_proto_id = (uint8_t)next_proto; - break; - case RTE_FLOW_ITEM_TYPE_IPV6: - ipv6 = (struct rte_ipv6_hdr *)buf; - if (next_proto && ipv6->proto == 0) - ipv6->proto = (uint8_t)next_proto; - ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); - ipv6_vtc_flow &= 0x0FFFFFFF; /* reset version bits. */ - ipv6_vtc_flow |= 0x60000000; /* set ipv6 version. */ - ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); - break; - case RTE_FLOW_ITEM_TYPE_VXLAN: - vxlan = (struct rte_vxlan_hdr *)buf; - if (!vxlan->flags) - vxlan->flags = 0x08; - break; - case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: - gpe = (struct rte_vxlan_gpe_hdr *)buf; - gpe->vx_flags = 0x0C; - break; - case RTE_FLOW_ITEM_TYPE_NVGRE: - nvgre = (struct rte_flow_item_nvgre *)buf; - nvgre->protocol = rte_cpu_to_be_16(0x6558); - nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); - break; - default: - break; - } -} - -/** Helper of get item's default mask. */ -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); - static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { - .hdr = { - .next_hdr = 0xff, - .type = 0xff, - .segments_left = 0xff, - }, - }; - - switch (item->type) { - case RTE_FLOW_ITEM_TYPE_ANY: - mask = &rte_flow_item_any_mask; - break; - case RTE_FLOW_ITEM_TYPE_PORT_ID: - mask = &rte_flow_item_port_id_mask; - break; - case RTE_FLOW_ITEM_TYPE_RAW: - mask = &rte_flow_item_raw_mask; - break; - case RTE_FLOW_ITEM_TYPE_ETH: - mask = &rte_flow_item_eth_mask; - break; - case RTE_FLOW_ITEM_TYPE_VLAN: - mask = &rte_flow_item_vlan_mask; - break; - case RTE_FLOW_ITEM_TYPE_IPV4: - mask = &rte_flow_item_ipv4_mask; - break; - case RTE_FLOW_ITEM_TYPE_IPV6: - mask = &rte_flow_item_ipv6_mask; - break; - case RTE_FLOW_ITEM_TYPE_ICMP: - mask = &rte_flow_item_icmp_mask; - break; - case RTE_FLOW_ITEM_TYPE_UDP: - mask = &rte_flow_item_udp_mask; - break; - case RTE_FLOW_ITEM_TYPE_TCP: - mask = &rte_flow_item_tcp_mask; - break; - case RTE_FLOW_ITEM_TYPE_SCTP: - mask = &rte_flow_item_sctp_mask; - break; - case RTE_FLOW_ITEM_TYPE_VXLAN: - mask = &rte_flow_item_vxlan_mask; - break; - case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: - mask = &rte_flow_item_vxlan_gpe_mask; - break; - case RTE_FLOW_ITEM_TYPE_E_TAG: - mask = &rte_flow_item_e_tag_mask; - break; - case RTE_FLOW_ITEM_TYPE_NVGRE: - mask = &rte_flow_item_nvgre_mask; - break; - case RTE_FLOW_ITEM_TYPE_MPLS: - mask = &rte_flow_item_mpls_mask; - break; - 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; - case RTE_FLOW_ITEM_TYPE_RANDOM: - mask = &rte_flow_item_random_mask; - break; - case RTE_FLOW_ITEM_TYPE_FUZZY: - mask = &rte_flow_item_fuzzy_mask; - break; - case RTE_FLOW_ITEM_TYPE_GTP: - mask = &rte_flow_item_gtp_mask; - break; - case RTE_FLOW_ITEM_TYPE_GTP_PSC: - mask = &rte_flow_item_gtp_psc_mask; - break; - case RTE_FLOW_ITEM_TYPE_GENEVE: - mask = &rte_flow_item_geneve_mask; - break; - case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: - mask = &rte_flow_item_geneve_opt_mask; - break; - case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: - mask = &rte_flow_item_pppoe_proto_id_mask; - break; - 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; - case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: - case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: - mask = &rte_flow_item_ethdev_mask; - break; - case RTE_FLOW_ITEM_TYPE_L2TPV2: - mask = &rte_flow_item_l2tpv2_mask; - break; - case RTE_FLOW_ITEM_TYPE_PPP: - mask = &rte_flow_item_ppp_mask; - break; - case RTE_FLOW_ITEM_TYPE_METER_COLOR: - mask = &rte_flow_item_meter_color_mask; - break; - case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: - mask = &ipv6_routing_ext_default_mask; - break; - case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: - mask = &rte_flow_item_aggr_affinity_mask; - break; - case RTE_FLOW_ITEM_TYPE_TX_QUEUE: - mask = &rte_flow_item_tx_queue_mask; - break; - case RTE_FLOW_ITEM_TYPE_IB_BTH: - mask = &rte_flow_item_ib_bth_mask; - break; - case RTE_FLOW_ITEM_TYPE_PTYPE: - mask = &rte_flow_item_ptype_mask; - break; - default: - break; - } - return mask; -} - -/** Dispatch parsed buffer to function calls. */ -static void -cmd_set_ipv6_ext_parsed(const struct buffer *in) -{ - uint32_t n = in->args.vc.pattern_n; - int i = 0; - struct rte_flow_item *item = NULL; - size_t size = 0; - uint8_t *data = NULL; - uint8_t *type = NULL; - size_t *total_size = NULL; - uint16_t idx = in->port; /* We borrow port field as index */ - struct rte_flow_item_ipv6_routing_ext *ext; - const struct rte_flow_item_ipv6_ext *ipv6_ext; - - RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || - in->command == SET_IPV6_EXT_REMOVE); - - if (in->command == SET_IPV6_EXT_REMOVE) { - if (n != 1 || in->args.vc.pattern->type != - RTE_FLOW_ITEM_TYPE_IPV6_EXT) { - fprintf(stderr, "Error - Not supported item\n"); - return; - } - type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; - item = in->args.vc.pattern; - ipv6_ext = item->spec; - *type = ipv6_ext->next_hdr; - return; - } - - total_size = &ipv6_ext_push_confs[idx].size; - data = (uint8_t *)&ipv6_ext_push_confs[idx].data; - type = (uint8_t *)&ipv6_ext_push_confs[idx].type; - - *total_size = 0; - memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); - for (i = n - 1 ; i >= 0; --i) { - item = in->args.vc.pattern + i; - switch (item->type) { - case RTE_FLOW_ITEM_TYPE_IPV6_EXT: - ipv6_ext = item->spec; - *type = ipv6_ext->next_hdr; - break; - case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: - ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; - if (!ext->hdr.hdr_len) { - size = sizeof(struct rte_ipv6_routing_ext) + - (ext->hdr.segments_left << 4); - ext->hdr.hdr_len = ext->hdr.segments_left << 1; - /* Indicate no TLV once SRH. */ - if (ext->hdr.type == 4) - ext->hdr.last_entry = ext->hdr.segments_left - 1; - } else { - size = sizeof(struct rte_ipv6_routing_ext) + - (ext->hdr.hdr_len << 3); - } - *total_size += size; - memcpy(data, ext, size); - break; - default: - fprintf(stderr, "Error - Not supported item\n"); - goto error; - } - } - RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); - return; -error: - *total_size = 0; - memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); -} - -/** Dispatch parsed buffer to function calls. */ -static void -cmd_set_raw_parsed_sample(const struct buffer *in) -{ - uint32_t n = in->args.vc.actions_n; - uint32_t i = 0; - struct rte_flow_action *action = NULL; - struct rte_flow_action *data = NULL; - const struct rte_flow_action_rss *rss = NULL; - size_t size = 0; - uint16_t idx = in->port; /* We borrow port field as index */ - uint32_t max_size = sizeof(struct rte_flow_action) * - ACTION_SAMPLE_ACTIONS_NUM; - - RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); - data = (struct rte_flow_action *)&raw_sample_confs[idx].data; - memset(data, 0x00, max_size); - for (; i <= n - 1; i++) { - action = in->args.vc.actions + i; - if (action->type == RTE_FLOW_ACTION_TYPE_END) - break; - switch (action->type) { - case RTE_FLOW_ACTION_TYPE_MARK: - size = sizeof(struct rte_flow_action_mark); - rte_memcpy(&sample_mark[idx], - (const void *)action->conf, size); - action->conf = &sample_mark[idx]; - break; - case RTE_FLOW_ACTION_TYPE_COUNT: - size = sizeof(struct rte_flow_action_count); - rte_memcpy(&sample_count[idx], - (const void *)action->conf, size); - action->conf = &sample_count[idx]; - break; - case RTE_FLOW_ACTION_TYPE_QUEUE: - size = sizeof(struct rte_flow_action_queue); - rte_memcpy(&sample_queue[idx], - (const void *)action->conf, size); - action->conf = &sample_queue[idx]; - break; - case RTE_FLOW_ACTION_TYPE_RSS: - size = sizeof(struct rte_flow_action_rss); - rss = action->conf; - rte_memcpy(&sample_rss_data[idx].conf, - (const void *)rss, size); - if (rss->key_len && rss->key) { - sample_rss_data[idx].conf.key = - sample_rss_data[idx].key; - rte_memcpy((void *)((uintptr_t) - sample_rss_data[idx].conf.key), - (const void *)rss->key, - sizeof(uint8_t) * rss->key_len); - } - if (rss->queue_num && rss->queue) { - sample_rss_data[idx].conf.queue = - sample_rss_data[idx].queue; - rte_memcpy((void *)((uintptr_t) - sample_rss_data[idx].conf.queue), - (const void *)rss->queue, - sizeof(uint16_t) * rss->queue_num); - } - action->conf = &sample_rss_data[idx].conf; - break; - case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: - size = sizeof(struct rte_flow_action_raw_encap); - rte_memcpy(&sample_encap[idx], - (const void *)action->conf, size); - action->conf = &sample_encap[idx]; - break; - case RTE_FLOW_ACTION_TYPE_PORT_ID: - size = sizeof(struct rte_flow_action_port_id); - rte_memcpy(&sample_port_id[idx], - (const void *)action->conf, size); - action->conf = &sample_port_id[idx]; - break; - case RTE_FLOW_ACTION_TYPE_PF: - break; - case RTE_FLOW_ACTION_TYPE_VF: - size = sizeof(struct rte_flow_action_vf); - rte_memcpy(&sample_vf[idx], - (const void *)action->conf, size); - action->conf = &sample_vf[idx]; - break; - case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: - size = sizeof(struct rte_flow_action_vxlan_encap); - parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); - action->conf = &sample_vxlan_encap[idx].conf; - break; - case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: - size = sizeof(struct rte_flow_action_nvgre_encap); - parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); - action->conf = &sample_nvgre_encap[idx]; - break; - case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: - size = sizeof(struct rte_flow_action_ethdev); - rte_memcpy(&sample_port_representor[idx], - (const void *)action->conf, size); - action->conf = &sample_port_representor[idx]; - break; - case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: - size = sizeof(struct rte_flow_action_ethdev); - rte_memcpy(&sample_represented_port[idx], - (const void *)action->conf, size); - action->conf = &sample_represented_port[idx]; - break; - default: - fprintf(stderr, "Error - Not supported action\n"); - return; - } - *data = *action; - data++; - } -} - -/** Dispatch parsed buffer to function calls. */ -static void -cmd_set_raw_parsed(const struct buffer *in) -{ - uint32_t n = in->args.vc.pattern_n; - int i = 0; - struct rte_flow_item *item = NULL; - size_t size = 0; - uint8_t *data = NULL; - uint8_t *data_tail = NULL; - size_t *total_size = NULL; - uint16_t upper_layer = 0; - uint16_t proto = 0; - uint16_t idx = in->port; /* We borrow port field as index */ - int gtp_psc = -1; /* GTP PSC option index. */ - const void *src_spec; - - if (in->command == SET_SAMPLE_ACTIONS) { - cmd_set_raw_parsed_sample(in); - return; - } - else if (in->command == SET_IPV6_EXT_PUSH || - in->command == SET_IPV6_EXT_REMOVE) { - cmd_set_ipv6_ext_parsed(in); - return; - } - RTE_ASSERT(in->command == SET_RAW_ENCAP || - in->command == SET_RAW_DECAP); - if (in->command == SET_RAW_ENCAP) { - total_size = &raw_encap_confs[idx].size; - data = (uint8_t *)&raw_encap_confs[idx].data; - } else { - total_size = &raw_decap_confs[idx].size; - data = (uint8_t *)&raw_decap_confs[idx].data; - } - *total_size = 0; - memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); - /* process hdr from upper layer to low layer (L3/L4 -> L2). */ - data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; - for (i = n - 1 ; i >= 0; --i) { - const struct rte_flow_item_gtp *gtp; - const struct rte_flow_item_geneve_opt *opt; - struct rte_flow_item_ipv6_routing_ext *ext; - - item = in->args.vc.pattern + i; - if (item->spec == NULL) - item->spec = flow_item_default_mask(item); - src_spec = item->spec; - switch (item->type) { - case RTE_FLOW_ITEM_TYPE_ETH: - size = sizeof(struct rte_ether_hdr); - break; - case RTE_FLOW_ITEM_TYPE_VLAN: - size = sizeof(struct rte_vlan_hdr); - proto = RTE_ETHER_TYPE_VLAN; - break; - case RTE_FLOW_ITEM_TYPE_IPV4: - size = sizeof(struct rte_ipv4_hdr); - proto = RTE_ETHER_TYPE_IPV4; - break; - case RTE_FLOW_ITEM_TYPE_IPV6: - size = sizeof(struct rte_ipv6_hdr); - proto = RTE_ETHER_TYPE_IPV6; - break; - case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: - ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; - if (!ext->hdr.hdr_len) { - size = sizeof(struct rte_ipv6_routing_ext) + - (ext->hdr.segments_left << 4); - ext->hdr.hdr_len = ext->hdr.segments_left << 1; - /* SRv6 without TLV. */ - if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) - ext->hdr.last_entry = ext->hdr.segments_left - 1; - } else { - size = sizeof(struct rte_ipv6_routing_ext) + - (ext->hdr.hdr_len << 3); - } - proto = IPPROTO_ROUTING; - break; - case RTE_FLOW_ITEM_TYPE_UDP: - size = sizeof(struct rte_udp_hdr); - proto = 0x11; - break; - case RTE_FLOW_ITEM_TYPE_TCP: - size = sizeof(struct rte_tcp_hdr); - proto = 0x06; - break; - case RTE_FLOW_ITEM_TYPE_VXLAN: - size = sizeof(struct rte_vxlan_hdr); - break; - case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: - size = sizeof(struct rte_vxlan_gpe_hdr); - break; - case RTE_FLOW_ITEM_TYPE_GRE: - size = sizeof(struct rte_gre_hdr); - proto = 0x2F; - break; - case RTE_FLOW_ITEM_TYPE_GRE_KEY: - size = sizeof(rte_be32_t); - proto = 0x0; - break; - case RTE_FLOW_ITEM_TYPE_MPLS: - size = sizeof(struct rte_mpls_hdr); - proto = 0x0; - break; - case RTE_FLOW_ITEM_TYPE_NVGRE: - size = sizeof(struct rte_flow_item_nvgre); - proto = 0x2F; - break; - case RTE_FLOW_ITEM_TYPE_GENEVE: - size = sizeof(struct rte_geneve_hdr); - break; - case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: - opt = (const struct rte_flow_item_geneve_opt *) - item->spec; - size = offsetof(struct rte_flow_item_geneve_opt, - option_len) + sizeof(uint8_t); - if (opt->option_len && opt->data) { - *total_size += opt->option_len * - sizeof(uint32_t); - rte_memcpy(data_tail - (*total_size), - opt->data, - opt->option_len * sizeof(uint32_t)); - } - break; - case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: - size = sizeof(rte_be32_t); - proto = 0x73; - break; - case RTE_FLOW_ITEM_TYPE_ESP: - size = sizeof(struct rte_esp_hdr); - 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: - if (gtp_psc < 0) { - size = sizeof(struct rte_gtp_hdr); - break; - } - if (gtp_psc != i + 1) { - fprintf(stderr, - "Error - GTP PSC does not follow GTP\n"); - goto error; - } - gtp = item->spec; - if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { - /* Only E flag should be set. */ - fprintf(stderr, - "Error - GTP unsupported flags\n"); - goto error; - } else { - struct rte_gtp_hdr_ext_word ext_word = { - .next_ext = 0x85 - }; - - /* We have to add GTP header extra word. */ - *total_size += sizeof(ext_word); - rte_memcpy(data_tail - (*total_size), - &ext_word, sizeof(ext_word)); - } - size = sizeof(struct rte_gtp_hdr); - break; - case RTE_FLOW_ITEM_TYPE_GTP_PSC: - if (gtp_psc >= 0) { - fprintf(stderr, - "Error - Multiple GTP PSC items\n"); - goto error; - } else { - const struct rte_flow_item_gtp_psc - *opt = item->spec; - struct rte_gtp_psc_generic_hdr *hdr; - size_t hdr_size = RTE_ALIGN(sizeof(*hdr), - sizeof(int32_t)); - - *total_size += hdr_size; - hdr = (typeof(hdr))(data_tail - (*total_size)); - memset(hdr, 0, hdr_size); - *hdr = opt->hdr; - hdr->ext_hdr_len = 1; - gtp_psc = i; - size = 0; - } - break; - case RTE_FLOW_ITEM_TYPE_PFCP: - size = sizeof(struct rte_flow_item_pfcp); - break; - case RTE_FLOW_ITEM_TYPE_FLEX: - if (item->spec != NULL) { - size = ((const struct rte_flow_item_flex *)item->spec)->length; - src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; - } else { - size = 0; - src_spec = NULL; - } - break; - case RTE_FLOW_ITEM_TYPE_GRE_OPTION: - size = 0; - if (item->spec) { - const struct rte_flow_item_gre_opt - *opt = item->spec; - if (opt->checksum_rsvd.checksum) { - *total_size += - sizeof(opt->checksum_rsvd); - rte_memcpy(data_tail - (*total_size), - &opt->checksum_rsvd, - sizeof(opt->checksum_rsvd)); - } - if (opt->key.key) { - *total_size += sizeof(opt->key.key); - rte_memcpy(data_tail - (*total_size), - &opt->key.key, - sizeof(opt->key.key)); - } - if (opt->sequence.sequence) { - *total_size += sizeof(opt->sequence.sequence); - rte_memcpy(data_tail - (*total_size), - &opt->sequence.sequence, - sizeof(opt->sequence.sequence)); - } - } - proto = 0x2F; - break; - default: - fprintf(stderr, "Error - Not supported item\n"); - goto error; - } - if (size) { - *total_size += size; - rte_memcpy(data_tail - (*total_size), src_spec, size); - /* update some fields which cannot be set by cmdline */ - update_fields((data_tail - (*total_size)), item, - upper_layer); - upper_layer = proto; - } - } - if (verbose_level & 0x1) - printf("total data size is %zu\n", (*total_size)); - RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); - memmove(data, (data_tail - (*total_size)), *total_size); - return; - -error: - *total_size = 0; - memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); -} - -/** Populate help strings for current token (cmdline API). */ -static int -cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, - unsigned int size) -{ - struct context *ctx = &cmd_flow_context; - const struct token *token = &token_list[ctx->prev]; - - (void)hdr; - if (!size) - return -1; - /* Set token type and update global help with details. */ - snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); - if (token->help) - cmd_set_raw.help_str = token->help; - else - cmd_set_raw.help_str = token->name; - return 0; -} - -/** Token definition template (cmdline API). */ -static struct cmdline_token_hdr cmd_set_raw_token_hdr = { - .ops = &(struct cmdline_token_ops){ - .parse = cmd_flow_parse, - .complete_get_nb = cmd_flow_complete_get_nb, - .complete_get_elt = cmd_flow_complete_get_elt, - .get_help = cmd_set_raw_get_help, - }, - .offset = 0, -}; - -/** Populate the next dynamic token. */ -static void -cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, - cmdline_parse_token_hdr_t **hdr_inst) -{ - struct context *ctx = &cmd_flow_context; - - /* Always reinitialize context before requesting the first token. */ - if (!(hdr_inst - cmd_set_raw.tokens)) { - cmd_flow_context_init(ctx); - ctx->curr = START_SET; - } - /* Return NULL when no more tokens are expected. */ - if (!ctx->next_num && (ctx->curr != START_SET)) { - *hdr = NULL; - return; - } - /* Determine if command should end here. */ - if (ctx->eol && ctx->last && ctx->next_num) { - const enum index *list = ctx->next[ctx->next_num - 1]; - int i; - - for (i = 0; list[i]; ++i) { - if (list[i] != END) - continue; - *hdr = NULL; - return; - } - } - *hdr = &cmd_set_raw_token_hdr; -} - -/** Token generator and output processing callback (cmdline API). */ -static void -cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) -{ - if (cl == NULL) - cmd_set_raw_tok(arg0, arg2); - else - cmd_set_raw_parsed(arg0); -} - -/** Global parser instance (cmdline API). */ -cmdline_parse_inst_t cmd_set_raw = { - .f = cmd_set_raw_cb, - .data = NULL, /**< Unused. */ - .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ - .tokens = { - NULL, - }, /**< Tokens are returned by cmd_flow_tok(). */ -}; - -/* *** display raw_encap/raw_decap buf */ -struct cmd_show_set_raw_result { - cmdline_fixed_string_t cmd_show; - cmdline_fixed_string_t cmd_what; - cmdline_fixed_string_t cmd_all; - uint16_t cmd_index; -}; - -static void -cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) -{ - struct cmd_show_set_raw_result *res = parsed_result; - uint16_t index = res->cmd_index; - uint8_t all = 0; - uint8_t *raw_data = NULL; - size_t raw_size = 0; - char title[16] = {0}; - - RTE_SET_USED(cl); - RTE_SET_USED(data); - if (!strcmp(res->cmd_all, "all")) { - all = 1; - index = 0; - } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { - fprintf(stderr, "index should be 0-%u\n", - RAW_ENCAP_CONFS_MAX_NUM - 1); - return; - } - do { - if (!strcmp(res->cmd_what, "raw_encap")) { - raw_data = (uint8_t *)&raw_encap_confs[index].data; - raw_size = raw_encap_confs[index].size; - snprintf(title, 16, "\nindex: %u", index); - rte_hexdump(stdout, title, raw_data, raw_size); - } else { - raw_data = (uint8_t *)&raw_decap_confs[index].data; - raw_size = raw_decap_confs[index].size; - snprintf(title, 16, "\nindex: %u", index); - rte_hexdump(stdout, title, raw_data, raw_size); - } - } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); -} - -static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = - TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, - cmd_show, "show"); -static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = - TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, - cmd_what, "raw_encap#raw_decap"); -static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = - TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, - cmd_index, RTE_UINT16); -static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = - TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, - cmd_all, "all"); -cmdline_parse_inst_t cmd_show_set_raw = { - .f = cmd_show_set_raw_parsed, - .data = NULL, - .help_str = "show ", - .tokens = { - (void *)&cmd_show_set_raw_cmd_show, - (void *)&cmd_show_set_raw_cmd_what, - (void *)&cmd_show_set_raw_cmd_index, - NULL, - }, -}; -cmdline_parse_inst_t cmd_show_set_raw_all = { - .f = cmd_show_set_raw_parsed, - .data = NULL, - .help_str = "show all", - .tokens = { - (void *)&cmd_show_set_raw_cmd_show, - (void *)&cmd_show_set_raw_cmd_what, - (void *)&cmd_show_set_raw_cmd_all, - NULL, - }, -}; diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 6ea506254b..3934ec6e56 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #ifdef RTE_NET_IXGBE @@ -87,73 +88,6 @@ static const struct { }, }; -const struct rss_type_info rss_type_table[] = { - /* Group types */ - { "all", RTE_ETH_RSS_ETH | RTE_ETH_RSS_VLAN | RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP | - RTE_ETH_RSS_UDP | RTE_ETH_RSS_SCTP | RTE_ETH_RSS_L2_PAYLOAD | - RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_ESP | RTE_ETH_RSS_AH | RTE_ETH_RSS_PFCP | - RTE_ETH_RSS_GTPU | RTE_ETH_RSS_ECPRI | RTE_ETH_RSS_MPLS | RTE_ETH_RSS_L2TPV2 | - RTE_ETH_RSS_IB_BTH }, - { "none", 0 }, - { "ip", RTE_ETH_RSS_IP }, - { "udp", RTE_ETH_RSS_UDP }, - { "tcp", RTE_ETH_RSS_TCP }, - { "sctp", RTE_ETH_RSS_SCTP }, - { "tunnel", RTE_ETH_RSS_TUNNEL }, - { "vlan", RTE_ETH_RSS_VLAN }, - - /* Individual type */ - { "ipv4", RTE_ETH_RSS_IPV4 }, - { "ipv4-frag", RTE_ETH_RSS_FRAG_IPV4 }, - { "ipv4-tcp", RTE_ETH_RSS_NONFRAG_IPV4_TCP }, - { "ipv4-udp", RTE_ETH_RSS_NONFRAG_IPV4_UDP }, - { "ipv4-sctp", RTE_ETH_RSS_NONFRAG_IPV4_SCTP }, - { "ipv4-other", RTE_ETH_RSS_NONFRAG_IPV4_OTHER }, - { "ipv6", RTE_ETH_RSS_IPV6 }, - { "ipv6-frag", RTE_ETH_RSS_FRAG_IPV6 }, - { "ipv6-tcp", RTE_ETH_RSS_NONFRAG_IPV6_TCP }, - { "ipv6-udp", RTE_ETH_RSS_NONFRAG_IPV6_UDP }, - { "ipv6-sctp", RTE_ETH_RSS_NONFRAG_IPV6_SCTP }, - { "ipv6-other", RTE_ETH_RSS_NONFRAG_IPV6_OTHER }, - { "l2-payload", RTE_ETH_RSS_L2_PAYLOAD }, - { "ipv6-ex", RTE_ETH_RSS_IPV6_EX }, - { "ipv6-tcp-ex", RTE_ETH_RSS_IPV6_TCP_EX }, - { "ipv6-udp-ex", RTE_ETH_RSS_IPV6_UDP_EX }, - { "port", RTE_ETH_RSS_PORT }, - { "vxlan", RTE_ETH_RSS_VXLAN }, - { "geneve", RTE_ETH_RSS_GENEVE }, - { "nvgre", RTE_ETH_RSS_NVGRE }, - { "gtpu", RTE_ETH_RSS_GTPU }, - { "eth", RTE_ETH_RSS_ETH }, - { "s-vlan", RTE_ETH_RSS_S_VLAN }, - { "c-vlan", RTE_ETH_RSS_C_VLAN }, - { "esp", RTE_ETH_RSS_ESP }, - { "ah", RTE_ETH_RSS_AH }, - { "l2tpv3", RTE_ETH_RSS_L2TPV3 }, - { "pfcp", RTE_ETH_RSS_PFCP }, - { "pppoe", RTE_ETH_RSS_PPPOE }, - { "ecpri", RTE_ETH_RSS_ECPRI }, - { "mpls", RTE_ETH_RSS_MPLS }, - { "ipv4-chksum", RTE_ETH_RSS_IPV4_CHKSUM }, - { "l4-chksum", RTE_ETH_RSS_L4_CHKSUM }, - { "l2tpv2", RTE_ETH_RSS_L2TPV2 }, - { "l3-pre96", RTE_ETH_RSS_L3_PRE96 }, - { "l3-pre64", RTE_ETH_RSS_L3_PRE64 }, - { "l3-pre56", RTE_ETH_RSS_L3_PRE56 }, - { "l3-pre48", RTE_ETH_RSS_L3_PRE48 }, - { "l3-pre40", RTE_ETH_RSS_L3_PRE40 }, - { "l3-pre32", RTE_ETH_RSS_L3_PRE32 }, - { "l2-dst-only", RTE_ETH_RSS_L2_DST_ONLY }, - { "l2-src-only", RTE_ETH_RSS_L2_SRC_ONLY }, - { "l4-dst-only", RTE_ETH_RSS_L4_DST_ONLY }, - { "l4-src-only", RTE_ETH_RSS_L4_SRC_ONLY }, - { "l3-dst-only", RTE_ETH_RSS_L3_DST_ONLY }, - { "l3-src-only", RTE_ETH_RSS_L3_SRC_ONLY }, - { "ipv6-flow-label", RTE_ETH_RSS_IPV6_FLOW_LABEL }, - { "ib-bth", RTE_ETH_RSS_IB_BTH }, - { NULL, 0}, -}; - static const struct { enum rte_eth_fec_mode mode; const char *name; @@ -729,32 +663,6 @@ print_dev_capabilities(uint64_t capabilities) } } -uint64_t -str_to_rsstypes(const char *str) -{ - uint16_t i; - - for (i = 0; rss_type_table[i].str != NULL; i++) { - if (strcmp(rss_type_table[i].str, str) == 0) - return rss_type_table[i].rss_type; - } - - return 0; -} - -const char * -rsstypes_to_str(uint64_t rss_type) -{ - uint16_t i; - - for (i = 0; rss_type_table[i].str != NULL; i++) { - if (rss_type_table[i].rss_type == rss_type) - return rss_type_table[i].str; - } - - return NULL; -} - static void rss_offload_types_display(uint64_t offload_types, uint16_t char_num_per_line) { @@ -767,7 +675,7 @@ rss_offload_types_display(uint64_t offload_types, uint16_t char_num_per_line) for (i = 0; i < sizeof(offload_types) * CHAR_BIT; i++) { rss_offload = RTE_BIT64(i); if ((offload_types & rss_offload) != 0) { - const char *p = rsstypes_to_str(rss_offload); + const char *p = rte_eth_rss_type_to_str(rss_offload); user_defined_str_len = strlen("user-defined-") + (i / 10 + 1); @@ -1538,6 +1446,7 @@ port_flow_complain(struct rte_flow_error *error) static void rss_types_display(uint64_t rss_types, uint16_t char_num_per_line) { + const struct rte_eth_rss_type_info *tbl = rte_eth_rss_type_info_get(); uint16_t total_len = 0; uint16_t str_len; uint16_t i; @@ -1545,19 +1454,18 @@ rss_types_display(uint64_t rss_types, uint16_t char_num_per_line) if (rss_types == 0) return; - for (i = 0; rss_type_table[i].str; i++) { - if (rss_type_table[i].rss_type == 0) + for (i = 0; tbl[i].str; i++) { + if (tbl[i].rss_type == 0) continue; - if ((rss_types & rss_type_table[i].rss_type) == - rss_type_table[i].rss_type) { + if ((rss_types & tbl[i].rss_type) == tbl[i].rss_type) { /* Contain two spaces */ - str_len = strlen(rss_type_table[i].str) + 2; + str_len = strlen(tbl[i].str) + 2; if (total_len + str_len > char_num_per_line) { printf("\n"); total_len = 0; } - printf(" %s", rss_type_table[i].str); + printf(" %s", tbl[i].str); total_len += str_len; } } @@ -1861,7 +1769,7 @@ action_handle_create(portid_t port_id, struct rte_flow_action_conntrack *ct = (struct rte_flow_action_conntrack *)(uintptr_t)(action->conf); - memcpy(ct, &conntrack_context, sizeof(*ct)); + memcpy(ct, rte_flow_parser_conntrack_context(), sizeof(*ct)); } pia->type = action->type; pia->handle = rte_flow_action_handle_create(port_id, conf, action, @@ -4820,7 +4728,7 @@ port_rss_hash_key_update(portid_t port_id, char rss_type[], uint8_t *hash_key, if (diag == 0) { rss_conf.rss_key = hash_key; rss_conf.rss_key_len = hash_key_len; - rss_conf.rss_hf = str_to_rsstypes(rss_type); + rss_conf.rss_hf = rte_eth_rss_type_from_str(rss_type); diag = rte_eth_dev_rss_hash_update(port_id, &rss_conf); } if (diag == 0) diff --git a/app/test-pmd/flow_parser.c b/app/test-pmd/flow_parser.c new file mode 100644 index 0000000000..29e2ff384f --- /dev/null +++ b/app/test-pmd/flow_parser.c @@ -0,0 +1,406 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "testpmd.h" +#include "flow_parser.h" + +static struct rte_port * +parser_port_get(uint16_t port_id) +{ + if (port_id_is_invalid(port_id, DISABLED_WARN) || + port_id == (portid_t)RTE_PORT_ALL) + return NULL; + return &ports[port_id]; +} + +static struct port_flow * +parser_flow_by_index(struct rte_port *port, unsigned int index) +{ + struct port_flow *pf = port->flow_list; + + while (pf && index--) + pf = pf->next; + return pf; +} + +static struct port_template * +parser_template_by_index(struct port_template *list, unsigned int index) +{ + struct port_template *pt = list; + + while (pt && index--) + pt = pt->next; + return pt; +} + +static struct port_table * +parser_table_by_index(struct port_table *list, unsigned int index) +{ + struct port_table *pt = list; + + while (pt && index--) + pt = pt->next; + return pt; +} + +static const struct tunnel_ops * +parser_tunnel_convert(const struct rte_flow_parser_tunnel_ops *src, + struct tunnel_ops *dst) +{ + if (!src) + return NULL; + memset(dst, 0, sizeof(*dst)); + dst->id = src->id; + strlcpy(dst->type, src->type, sizeof(dst->type)); + dst->enabled = src->enabled; + dst->actions = src->actions; + dst->items = src->items; + return dst; +} + +static int +parser_port_validate(uint16_t port_id) +{ + return port_id_is_invalid(port_id, DISABLED_WARN); +} + +static uint16_t +parser_flow_rule_count(uint16_t port_id) +{ + struct rte_port *port = parser_port_get(port_id); + uint16_t count = 0; + + if (!port) + return 0; + for (struct port_flow *pf = port->flow_list; pf; pf = pf->next) + count++; + return count; +} + +static int +parser_flow_rule_id_get(uint16_t port_id, unsigned int index, + uint64_t *rule_id) +{ + struct rte_port *port = parser_port_get(port_id); + struct port_flow *pf; + + if (!port || !rule_id) + return -ENOENT; + pf = parser_flow_by_index(port, index); + if (!pf) + return -ENOENT; + *rule_id = pf->id; + return 0; +} + +static uint16_t +parser_pattern_template_count(uint16_t port_id) +{ + struct rte_port *port = parser_port_get(port_id); + uint16_t count = 0; + + if (!port) + return 0; + for (struct port_template *pt = port->pattern_templ_list; + pt; + pt = pt->next) + count++; + return count; +} + +static int +parser_pattern_template_id_get(uint16_t port_id, unsigned int index, + uint32_t *template_id) +{ + struct rte_port *port = parser_port_get(port_id); + struct port_template *pt; + + if (!port || !template_id) + return -ENOENT; + pt = parser_template_by_index(port->pattern_templ_list, index); + if (!pt) + return -ENOENT; + *template_id = pt->id; + return 0; +} + +static uint16_t +parser_actions_template_count(uint16_t port_id) +{ + struct rte_port *port = parser_port_get(port_id); + uint16_t count = 0; + + if (!port) + return 0; + for (struct port_template *pt = port->actions_templ_list; + pt; + pt = pt->next) + count++; + return count; +} + +static int +parser_actions_template_id_get(uint16_t port_id, unsigned int index, + uint32_t *template_id) +{ + struct rte_port *port = parser_port_get(port_id); + struct port_template *pt; + + if (!port || !template_id) + return -ENOENT; + pt = parser_template_by_index(port->actions_templ_list, index); + if (!pt) + return -ENOENT; + *template_id = pt->id; + return 0; +} + +static uint16_t +parser_table_count(uint16_t port_id) +{ + struct rte_port *port = parser_port_get(port_id); + uint16_t count = 0; + + if (!port) + return 0; + for (struct port_table *pt = port->table_list; pt; pt = pt->next) + count++; + return count; +} + +static int +parser_table_id_get(uint16_t port_id, unsigned int index, + uint32_t *table_id) +{ + struct rte_port *port = parser_port_get(port_id); + struct port_table *pt; + + if (!port || !table_id) + return -ENOENT; + pt = parser_table_by_index(port->table_list, index); + if (!pt) + return -ENOENT; + *table_id = pt->id; + return 0; +} + +static uint16_t +parser_queue_count(uint16_t port_id) +{ + struct rte_port *port = parser_port_get(port_id); + + if (!port) + return 0; + return port->queue_nb; +} + +static uint16_t +parser_rss_queue_count(uint16_t port_id) +{ + struct rte_port *port = parser_port_get(port_id); + + if (!port) + return 0; + return port->queue_nb ? port->queue_nb : port->dev_info.max_rx_queues; +} + +static struct rte_flow_template_table * +parser_table_get(uint16_t port_id, uint32_t table_id) +{ + struct rte_port *port = parser_port_get(port_id); + struct port_table *pt; + + if (!port) + return NULL; + for (pt = port->table_list; pt; pt = pt->next) + if (pt->id == table_id) + return pt->table; + return NULL; +} + +static struct rte_flow_action_handle * +parser_action_handle_get(uint16_t port_id, uint32_t action_id) +{ + return port_action_handle_get_by_id(port_id, action_id); +} + +static struct rte_flow_meter_profile * +parser_meter_profile_get(uint16_t port_id, uint32_t profile_id) +{ + return port_meter_profile_get_by_id(port_id, profile_id); +} + +static struct rte_flow_meter_policy * +parser_meter_policy_get(uint16_t port_id, uint32_t policy_id) +{ + return port_meter_policy_get_by_id(port_id, policy_id); +} + +static struct rte_flow_item_flex_handle * +parser_flex_handle_get(uint16_t port_id, uint16_t flex_id) +{ + struct flex_item *fp; + + if (port_id >= RTE_MAX_ETHPORTS || flex_id >= FLEX_MAX_PARSERS_NUM) + return NULL; + fp = flex_items[port_id][flex_id]; + return fp ? fp->flex_handle : NULL; +} + +static int +parser_flex_pattern_get(uint16_t pattern_id, + const struct rte_flow_item_flex **spec, + const struct rte_flow_item_flex **mask) +{ + if (pattern_id >= FLEX_MAX_PATTERNS_NUM || !spec || !mask) + return -ENOENT; + *spec = &flex_patterns[pattern_id].spec; + *mask = &flex_patterns[pattern_id].mask; + return 0; +} + +static uint16_t +parser_verbose_level_get(void) +{ + return verbose_level; +} +static int +parser_flow_validate(uint16_t port_id, const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + const struct rte_flow_parser_tunnel_ops *tunnel_ops) +{ + struct tunnel_ops ops; + + return port_flow_validate(port_id, attr, pattern, actions, + tunnel_ops ? parser_tunnel_convert(tunnel_ops, &ops) + : NULL); +} + +static int +parser_flow_create(uint16_t port_id, const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + const struct rte_flow_parser_tunnel_ops *tunnel_ops, + uintptr_t user_id) +{ + struct tunnel_ops ops; + + return port_flow_create(port_id, attr, pattern, actions, + tunnel_ops ? parser_tunnel_convert(tunnel_ops, &ops) + : NULL, + user_id); +} + +static void +parser_flow_aged(uint16_t port_id, int destroy) +{ + port_flow_aged(port_id, (uint8_t)destroy); +} + +static void +parser_flow_tunnel_create(uint16_t port_id, + const struct rte_flow_parser_tunnel_ops *ops_cfg) +{ + struct tunnel_ops ops; + + port_flow_tunnel_create(port_id, + ops_cfg ? parser_tunnel_convert(ops_cfg, &ops) + : NULL); +} + +static const struct rte_flow_parser_ops_query parser_query_ops = { + .port_validate = parser_port_validate, + .flow_rule_count = parser_flow_rule_count, + .flow_rule_id_get = parser_flow_rule_id_get, + .pattern_template_count = parser_pattern_template_count, + .pattern_template_id_get = parser_pattern_template_id_get, + .actions_template_count = parser_actions_template_count, + .actions_template_id_get = parser_actions_template_id_get, + .table_count = parser_table_count, + .table_id_get = parser_table_id_get, + .queue_count = parser_queue_count, + .rss_queue_count = parser_rss_queue_count, + .table_get = parser_table_get, + .action_handle_get = parser_action_handle_get, + .meter_profile_get = parser_meter_profile_get, + .meter_policy_get = parser_meter_policy_get, + .verbose_level_get = parser_verbose_level_get, + .flex_handle_get = parser_flex_handle_get, + .flex_pattern_get = parser_flex_pattern_get, +}; + +static const struct rte_flow_parser_ops_command parser_command_ops = { + .flow_get_info = port_flow_get_info, + .flow_configure = port_flow_configure, + .flow_pattern_template_create = port_flow_pattern_template_create, + .flow_pattern_template_destroy = port_flow_pattern_template_destroy, + .flow_actions_template_create = port_flow_actions_template_create, + .flow_actions_template_destroy = port_flow_actions_template_destroy, + .flow_template_table_create = port_flow_template_table_create, + .flow_template_table_destroy = port_flow_template_table_destroy, + .flow_template_table_resize_complete = + port_flow_template_table_resize_complete, + .queue_group_set_miss_actions = port_queue_group_set_miss_actions, + .flow_template_table_resize = port_flow_template_table_resize, + .queue_flow_create = port_queue_flow_create, + .queue_flow_destroy = port_queue_flow_destroy, + .queue_flow_update_resized = port_queue_flow_update_resized, + .queue_flow_update = port_queue_flow_update, + .queue_flow_push = port_queue_flow_push, + .queue_flow_pull = port_queue_flow_pull, + .flow_hash_calc = port_flow_hash_calc, + .flow_hash_calc_encap = port_flow_hash_calc_encap, + .queue_flow_aged = port_queue_flow_aged, + .queue_action_handle_create = port_queue_action_handle_create, + .queue_action_handle_destroy = port_queue_action_handle_destroy, + .queue_action_handle_update = port_queue_action_handle_update, + .queue_action_handle_query = port_queue_action_handle_query, + .queue_action_handle_query_update = port_queue_action_handle_query_update, + .action_handle_create = port_action_handle_create, + .action_handle_destroy = port_action_handle_destroy, + .action_handle_update = port_action_handle_update, + .action_handle_query = port_action_handle_query, + .action_handle_query_update = port_action_handle_query_update, + .flow_validate = parser_flow_validate, + .flow_create = parser_flow_create, + .flow_destroy = port_flow_destroy, + .flow_update = port_flow_update, + .flow_flush = port_flow_flush, + .flow_dump = port_flow_dump, + .flow_query = port_flow_query, + .flow_list = port_flow_list, + .flow_isolate = port_flow_isolate, + .flow_aged = parser_flow_aged, + .flow_tunnel_create = parser_flow_tunnel_create, + .flow_tunnel_destroy = port_flow_tunnel_destroy, + .flow_tunnel_list = port_flow_tunnel_list, + .meter_policy_add = port_meter_policy_add, + .flex_item_create = flex_item_create, + .flex_item_destroy = flex_item_destroy, +}; + +static const struct rte_flow_parser_ops parser_ops = { + .query = &parser_query_ops, + .command = &parser_command_ops, +}; + +int +testpmd_flow_parser_init(void) +{ + return rte_flow_parser_init(&parser_ops); +} diff --git a/app/test-pmd/flow_parser.h b/app/test-pmd/flow_parser.h new file mode 100644 index 0000000000..8b5c99cd8b --- /dev/null +++ b/app/test-pmd/flow_parser.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef _TESTPMD_FLOW_PARSER_H_ +#define _TESTPMD_FLOW_PARSER_H_ + +#include + +#endif /* _TESTPMD_FLOW_PARSER_H_ */ \ No newline at end of file diff --git a/app/test-pmd/flow_parser_cli.c b/app/test-pmd/flow_parser_cli.c new file mode 100644 index 0000000000..98491089d4 --- /dev/null +++ b/app/test-pmd/flow_parser_cli.c @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include + +#include +#include +#include +#include + +#include + +/* Dynamic token callbacks live in librte_flow_parser, but cmdline instances + * are owned by testpmd. + */ +static void +cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) +{ + if (cl == NULL) + rte_flow_parser_cmd_flow_tok(arg0, arg2); + else + rte_flow_parser_cmd_flow_dispatch(arg0); +} + +static void +cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) +{ + if (cl == NULL) + rte_flow_parser_cmd_set_raw_tok(arg0, arg2); + else + rte_flow_parser_cmd_set_raw_dispatch(arg0); +} + +/* show raw_encap/raw_decap support */ +struct cmd_show_set_raw_result { + cmdline_fixed_string_t cmd_show; + cmdline_fixed_string_t cmd_what; + cmdline_fixed_string_t cmd_all; + uint16_t cmd_index; +}; + +static void +cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) +{ + struct cmd_show_set_raw_result *res = parsed_result; + uint16_t index = res->cmd_index; + const uint8_t *raw_data = NULL; + size_t raw_size = 0; + char title[16] = { 0 }; + int all = 0; + + RTE_SET_USED(cl); + RTE_SET_USED(data); + if (!strcmp(res->cmd_all, "all")) { + all = 1; + index = 0; + } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { + fprintf(stderr, "index should be 0-%u\n", + RAW_ENCAP_CONFS_MAX_NUM - 1); + return; + } + do { + if (!strcmp(res->cmd_what, "raw_encap")) { + const struct rte_flow_action_raw_encap *conf = + rte_flow_parser_raw_encap_conf_get(index); + + if (!conf || !conf->data || !conf->size) { + fprintf(stderr, + "raw_encap %u not configured\n", + index); + goto next; + } + raw_data = conf->data; + raw_size = conf->size; + } else if (!strcmp(res->cmd_what, "raw_decap")) { + const struct rte_flow_action_raw_decap *conf = + rte_flow_parser_raw_decap_conf_get(index); + + if (!conf || !conf->data || !conf->size) { + fprintf(stderr, + "raw_decap %u not configured\n", + index); + goto next; + } + raw_data = conf->data; + raw_size = conf->size; + } + snprintf(title, sizeof(title), "\nindex: %u", index); + rte_hexdump(stdout, title, raw_data, raw_size); +next: + raw_data = NULL; + raw_size = 0; + } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); +} + +static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = + TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, + cmd_show, "show"); +static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = + TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, + cmd_what, "raw_encap#raw_decap"); +static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = + TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, + cmd_index, RTE_UINT16); +static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = + TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, + cmd_all, "all"); + +cmdline_parse_inst_t cmd_flow = { + .f = cmd_flow_cb, + .data = NULL, + .help_str = NULL, + .tokens = { + NULL, + }, +}; + +cmdline_parse_inst_t cmd_set_raw = { + .f = cmd_set_raw_cb, + .data = NULL, + .help_str = NULL, + .tokens = { + NULL, + }, +}; + +cmdline_parse_inst_t cmd_show_set_raw = { + .f = cmd_show_set_raw_parsed, + .data = NULL, + .help_str = "show ", + .tokens = { + (void *)&cmd_show_set_raw_cmd_show, + (void *)&cmd_show_set_raw_cmd_what, + (void *)&cmd_show_set_raw_cmd_index, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_show_set_raw_all = { + .f = cmd_show_set_raw_parsed, + .data = NULL, + .help_str = "show all", + .tokens = { + (void *)&cmd_show_set_raw_cmd_show, + (void *)&cmd_show_set_raw_cmd_what, + (void *)&cmd_show_set_raw_cmd_all, + NULL, + }, +}; diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build index 83163a5406..79eabc2cfd 100644 --- a/app/test-pmd/meson.build +++ b/app/test-pmd/meson.build @@ -7,13 +7,14 @@ sources = files( '5tswap.c', 'cmdline.c', 'cmdline_cman.c', - 'cmdline_flow.c', 'cmdline_mtr.c', 'cmdline_tm.c', 'cmd_flex_item.c', 'config.c', 'csumonly.c', 'flowgen.c', + 'flow_parser.c', + 'flow_parser_cli.c', 'hairpin.c', 'icmpecho.c', 'ieee1588fwd.c', @@ -34,7 +35,7 @@ if dpdk_conf.has('RTE_HAS_JANSSON') ext_deps += jansson_dep endif -deps += ['ethdev', 'cmdline', 'pci'] +deps += ['ethdev', 'cmdline', 'pci', 'flow_parser'] if dpdk_conf.has('RTE_CRYPTO_SCHEDULER') deps += 'crypto_scheduler' endif diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 1fe41d852a..ab9c76a5c2 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -4616,6 +4616,10 @@ main(int argc, char** argv) init_config(); + if (testpmd_flow_parser_init() != 0) + rte_exit(EXIT_FAILURE, + "Could not initialize flow parser hooks.\n"); + if (hot_plug) { ret = rte_dev_hotplug_handle_enable(); if (ret) { diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 492b5757f1..c1c12d09fe 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -94,8 +95,8 @@ struct cmdline_file_info { #define MAX_MEMPOOL 8 typedef uint32_t lcoreid_t; -typedef uint16_t portid_t; -typedef uint16_t queueid_t; +typedef rte_port_id_t portid_t; +typedef rte_queue_id_t queueid_t; typedef uint16_t streamid_t; enum { @@ -155,18 +156,6 @@ struct pkt_burst_stats { #define TESTPMD_RSS_TYPES_CHAR_NUM_PER_LINE 64 -/** Information for a given RSS type. */ -struct rss_type_info { - const char *str; /**< Type name. */ - uint64_t rss_type; /**< Type value. */ -}; - -/** - * RSS type information table. - * - * An entry with a NULL type name terminates the list. - */ -extern const struct rss_type_info rss_type_table[]; /** * Dynf name array. @@ -729,109 +718,8 @@ extern struct gso_status gso_ports[RTE_MAX_ETHPORTS]; extern uint16_t gso_max_segment_size; #endif /* RTE_LIB_GSO */ -/* VXLAN encap/decap parameters. */ -struct vxlan_encap_conf { - uint32_t select_ipv4:1; - uint32_t select_vlan:1; - uint32_t select_tos_ttl:1; - uint8_t vni[3]; - rte_be16_t udp_src; - rte_be16_t udp_dst; - rte_be32_t ipv4_src; - rte_be32_t ipv4_dst; - struct rte_ipv6_addr ipv6_src; - struct rte_ipv6_addr ipv6_dst; - rte_be16_t vlan_tci; - uint8_t ip_tos; - uint8_t ip_ttl; - uint8_t eth_src[RTE_ETHER_ADDR_LEN]; - uint8_t eth_dst[RTE_ETHER_ADDR_LEN]; -}; - -extern struct vxlan_encap_conf vxlan_encap_conf; - -/* NVGRE encap/decap parameters. */ -struct nvgre_encap_conf { - uint32_t select_ipv4:1; - uint32_t select_vlan:1; - uint8_t tni[3]; - rte_be32_t ipv4_src; - rte_be32_t ipv4_dst; - struct rte_ipv6_addr ipv6_src; - struct rte_ipv6_addr ipv6_dst; - rte_be16_t vlan_tci; - uint8_t eth_src[RTE_ETHER_ADDR_LEN]; - uint8_t eth_dst[RTE_ETHER_ADDR_LEN]; -}; - -extern struct nvgre_encap_conf nvgre_encap_conf; - -/* L2 encap parameters. */ -struct l2_encap_conf { - uint32_t select_ipv4:1; - uint32_t select_vlan:1; - rte_be16_t vlan_tci; - uint8_t eth_src[RTE_ETHER_ADDR_LEN]; - uint8_t eth_dst[RTE_ETHER_ADDR_LEN]; -}; -extern struct l2_encap_conf l2_encap_conf; - -/* L2 decap parameters. */ -struct l2_decap_conf { - uint32_t select_vlan:1; -}; -extern struct l2_decap_conf l2_decap_conf; - -/* MPLSoGRE encap parameters. */ -struct mplsogre_encap_conf { - uint32_t select_ipv4:1; - uint32_t select_vlan:1; - uint8_t label[3]; - rte_be32_t ipv4_src; - rte_be32_t ipv4_dst; - struct rte_ipv6_addr ipv6_src; - struct rte_ipv6_addr ipv6_dst; - rte_be16_t vlan_tci; - uint8_t eth_src[RTE_ETHER_ADDR_LEN]; - uint8_t eth_dst[RTE_ETHER_ADDR_LEN]; -}; -extern struct mplsogre_encap_conf mplsogre_encap_conf; - -/* MPLSoGRE decap parameters. */ -struct mplsogre_decap_conf { - uint32_t select_ipv4:1; - uint32_t select_vlan:1; -}; -extern struct mplsogre_decap_conf mplsogre_decap_conf; - -/* MPLSoUDP encap parameters. */ -struct mplsoudp_encap_conf { - uint32_t select_ipv4:1; - uint32_t select_vlan:1; - uint8_t label[3]; - rte_be16_t udp_src; - rte_be16_t udp_dst; - rte_be32_t ipv4_src; - rte_be32_t ipv4_dst; - struct rte_ipv6_addr ipv6_src; - struct rte_ipv6_addr ipv6_dst; - rte_be16_t vlan_tci; - uint8_t eth_src[RTE_ETHER_ADDR_LEN]; - uint8_t eth_dst[RTE_ETHER_ADDR_LEN]; -}; -extern struct mplsoudp_encap_conf mplsoudp_encap_conf; - -/* MPLSoUDP decap parameters. */ -struct mplsoudp_decap_conf { - uint32_t select_ipv4:1; - uint32_t select_vlan:1; -}; -extern struct mplsoudp_decap_conf mplsoudp_decap_conf; - extern enum rte_eth_rx_mq_mode rx_mq_mode; -extern struct rte_flow_action_conntrack conntrack_context; - extern int proc_id; extern unsigned int num_procs; @@ -946,6 +834,7 @@ int cmdline_read_from_file(const char *filename, bool echo); int init_cmdline(void); void prompt(void); void prompt_exit(void); +int testpmd_flow_parser_init(void); void nic_stats_display(portid_t port_id); void nic_stats_clear(portid_t port_id); void nic_xstats_display(portid_t port_id); @@ -1284,18 +1173,11 @@ void flex_item_create(portid_t port_id, uint16_t flex_id, const char *filename); void flex_item_destroy(portid_t port_id, uint16_t flex_id); void port_flex_item_flush(portid_t port_id); -extern int flow_parse(const char *src, void *result, unsigned int size, - struct rte_flow_attr **attr, - struct rte_flow_item **pattern, - struct rte_flow_action **actions); int setup_hairpin_queues(portid_t pi, portid_t p_pi, uint16_t cnt_pi); int hairpin_bind(uint16_t cfg_pi, portid_t *pl, portid_t *peer_pl); void hairpin_map_usage(void); int parse_hairpin_map(const char *hpmap); -uint64_t str_to_rsstypes(const char *str); -const char *rsstypes_to_str(uint64_t rss_type); - uint16_t str_to_flowtype(const char *string); const char *flowtype_to_str(uint16_t flow_type); diff --git a/lib/flow_parser/rte_flow_parser.c b/lib/flow_parser/rte_flow_parser.c index 070747f508..0b8611af10 100644 --- a/lib/flow_parser/rte_flow_parser.c +++ b/lib/flow_parser/rte_flow_parser.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2026 Dyna-NIC + * Copyright 2016 6WIND S.A. + * Copyright 2016 Mellanox Technologies, Ltd */ #include @@ -199,6 +200,7 @@ struct rte_flow_parser_ctx { struct rte_flow_parser_mplsogre_decap_conf mplsogre_decap_conf; struct rte_flow_parser_mplsoudp_encap_conf mplsoudp_encap_conf; struct rte_flow_parser_mplsoudp_decap_conf mplsoudp_decap_conf; + struct rte_flow_action_conntrack conntrack_context; struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; @@ -1051,9 +1053,6 @@ parser_ctx_set_sample_actions(uint16_t idx, } return 0; } - -struct rte_flow_action_conntrack conntrack_context; - void rte_flow_parser_reset_defaults(void) { @@ -1124,6 +1123,12 @@ rte_flow_parser_mplsoudp_decap_conf(void) return &parser.ctx.mplsoudp_decap_conf; } +struct rte_flow_action_conntrack * +rte_flow_parser_conntrack_context(void) +{ + return &parser.ctx.conntrack_context; +} + static inline const struct rte_flow_parser_ops_query * parser_query_ops(void) { @@ -1310,28 +1315,30 @@ parser_flex_pattern_get(uint16_t pattern_id, return ops->flex_pattern_get(pattern_id, spec, mask); } -static inline void +static inline int parser_command_flow_get_info(rte_port_id_t port_id) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_get_info) - ops->flow_get_info(port_id); + return ops->flow_get_info(port_id); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_configure(rte_port_id_t port_id, const struct rte_flow_port_attr *port_attr, - uint32_t nb_queue, + uint16_t nb_queue, const struct rte_flow_queue_attr *queue_attr) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_configure) - ops->flow_configure(port_id, port_attr, nb_queue, queue_attr); + return ops->flow_configure(port_id, port_attr, nb_queue, queue_attr); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_pattern_template_create(rte_port_id_t port_id, uint32_t id, const struct rte_flow_pattern_template_attr *attr, const struct rte_flow_item pattern[]) @@ -1339,10 +1346,11 @@ parser_command_flow_pattern_template_create(rte_port_id_t port_id, uint32_t id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_pattern_template_create) - ops->flow_pattern_template_create(port_id, id, attr, pattern); + return ops->flow_pattern_template_create(port_id, id, attr, pattern); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_pattern_template_destroy(rte_port_id_t port_id, uint32_t nb_id, const uint32_t id[]) @@ -1350,10 +1358,11 @@ parser_command_flow_pattern_template_destroy(rte_port_id_t port_id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_pattern_template_destroy) - ops->flow_pattern_template_destroy(port_id, nb_id, id); + return ops->flow_pattern_template_destroy(port_id, nb_id, id); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_actions_template_create(rte_port_id_t port_id, uint32_t id, const struct rte_flow_actions_template_attr *attr, const struct rte_flow_action actions[], @@ -1362,11 +1371,12 @@ parser_command_flow_actions_template_create(rte_port_id_t port_id, uint32_t id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_actions_template_create) - ops->flow_actions_template_create(port_id, id, attr, actions, + return ops->flow_actions_template_create(port_id, id, attr, actions, masks); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_actions_template_destroy(rte_port_id_t port_id, uint32_t nb_id, const uint32_t id[]) @@ -1374,10 +1384,11 @@ parser_command_flow_actions_template_destroy(rte_port_id_t port_id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_actions_template_destroy) - ops->flow_actions_template_destroy(port_id, nb_id, id); + return ops->flow_actions_template_destroy(port_id, nb_id, id); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_template_table_create(rte_port_id_t port_id, uint32_t table_id, const struct rte_flow_template_table_attr *attr, uint32_t nb_pattern, @@ -1388,12 +1399,13 @@ parser_command_flow_template_table_create(rte_port_id_t port_id, uint32_t table_ const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_template_table_create) - ops->flow_template_table_create(port_id, table_id, attr, - nb_pattern, pattern_id, - nb_action, action_id); + return ops->flow_template_table_create(port_id, table_id, attr, + nb_pattern, pattern_id, + nb_action, action_id); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_template_table_destroy(rte_port_id_t port_id, uint32_t nb_id, const uint32_t id[]) @@ -1401,20 +1413,22 @@ parser_command_flow_template_table_destroy(rte_port_id_t port_id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_template_table_destroy) - ops->flow_template_table_destroy(port_id, nb_id, id); + return ops->flow_template_table_destroy(port_id, nb_id, id); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_template_table_resize_complete(rte_port_id_t port_id, uint32_t table_id) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_template_table_resize_complete) - ops->flow_template_table_resize_complete(port_id, table_id); + return ops->flow_template_table_resize_complete(port_id, table_id); + return -ENOTSUP; } -static inline void +static inline int parser_command_queue_group_set_miss_actions(rte_port_id_t port_id, const struct rte_flow_attr *attr, const struct rte_flow_action actions[]) @@ -1422,20 +1436,22 @@ parser_command_queue_group_set_miss_actions(rte_port_id_t port_id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_group_set_miss_actions) - ops->queue_group_set_miss_actions(port_id, attr, actions); + return ops->queue_group_set_miss_actions(port_id, attr, actions); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_template_table_resize(rte_port_id_t port_id, uint32_t table_id, uint32_t nb_rules) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_template_table_resize) - ops->flow_template_table_resize(port_id, table_id, nb_rules); + return ops->flow_template_table_resize(port_id, table_id, nb_rules); + return -ENOTSUP; } -static inline void +static inline int parser_command_queue_flow_create(rte_port_id_t port_id, rte_queue_id_t queue, bool postpone, uint32_t table_id, uint32_t rule_id, uint32_t pattern_templ_id, @@ -1446,35 +1462,38 @@ parser_command_queue_flow_create(rte_port_id_t port_id, rte_queue_id_t queue, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_flow_create) - ops->queue_flow_create(port_id, queue, postpone, table_id, + return ops->queue_flow_create(port_id, queue, postpone, table_id, rule_id, pattern_templ_id, actions_templ_id, pattern, actions); + return -ENOTSUP; } -static inline void +static inline int parser_command_queue_flow_destroy(rte_port_id_t port_id, rte_queue_id_t queue, bool postpone, uint32_t rule_n, - const uint64_t rule[], bool is_user_id) + const uint64_t rule[]) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_flow_destroy) - ops->queue_flow_destroy(port_id, queue, postpone, rule_n, - rule, is_user_id); + return ops->queue_flow_destroy(port_id, queue, postpone, rule_n, + rule); + return -ENOTSUP; } -static inline void +static inline int parser_command_queue_flow_update_resized(rte_port_id_t port_id, rte_queue_id_t queue, - bool postpone, uint64_t rule_id) + bool postpone, uint32_t flow_id) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_flow_update_resized) - ops->queue_flow_update_resized(port_id, queue, postpone, - rule_id); + return ops->queue_flow_update_resized(port_id, queue, postpone, + flow_id); + return -ENOTSUP; } -static inline void +static inline int parser_command_queue_flow_update(rte_port_id_t port_id, rte_queue_id_t queue, bool postpone, uint32_t rule_id, uint32_t action_templ_id, @@ -1483,29 +1502,32 @@ parser_command_queue_flow_update(rte_port_id_t port_id, rte_queue_id_t queue, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_flow_update) - ops->queue_flow_update(port_id, queue, postpone, rule_id, + return ops->queue_flow_update(port_id, queue, postpone, rule_id, action_templ_id, actions); + return -ENOTSUP; } -static inline void +static inline int parser_command_queue_flow_push(rte_port_id_t port_id, rte_queue_id_t queue) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_flow_push) - ops->queue_flow_push(port_id, queue); + return ops->queue_flow_push(port_id, queue); + return -ENOTSUP; } -static inline void +static inline int parser_command_queue_flow_pull(rte_port_id_t port_id, rte_queue_id_t queue) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_flow_pull) - ops->queue_flow_pull(port_id, queue); + return ops->queue_flow_pull(port_id, queue); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_hash_calc(rte_port_id_t port_id, uint32_t table_id, uint32_t pattern_templ_id, const struct rte_flow_item pattern[]) @@ -1513,11 +1535,12 @@ parser_command_flow_hash_calc(rte_port_id_t port_id, uint32_t table_id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_hash_calc) - ops->flow_hash_calc(port_id, table_id, pattern_templ_id, - pattern); + return ops->flow_hash_calc(port_id, table_id, + (uint8_t)pattern_templ_id, pattern); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_hash_calc_encap(rte_port_id_t port_id, enum rte_flow_encap_hash_field field, const struct rte_flow_item pattern[]) @@ -1525,7 +1548,8 @@ parser_command_flow_hash_calc_encap(rte_port_id_t port_id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_hash_calc_encap) - ops->flow_hash_calc_encap(port_id, field, pattern); + return ops->flow_hash_calc_encap(port_id, field, pattern); + return -ENOTSUP; } static inline void @@ -1534,10 +1558,10 @@ parser_command_queue_flow_aged(rte_port_id_t port_id, rte_queue_id_t queue, bool const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_flow_aged) - ops->queue_flow_aged(port_id, queue, destroy); + ops->queue_flow_aged(port_id, (uint32_t)queue, destroy ? 1 : 0); } -static inline void +static inline int parser_command_queue_action_handle_create(rte_port_id_t port_id, rte_queue_id_t queue, bool postpone, uint32_t group, bool is_list, @@ -1547,11 +1571,12 @@ parser_command_queue_action_handle_create(rte_port_id_t port_id, rte_queue_id_t const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_action_handle_create) - ops->queue_action_handle_create(port_id, queue, postpone, - group, is_list, conf, actions); + return ops->queue_action_handle_create(port_id, (uint32_t)queue, + postpone, group, is_list, conf, actions); + return -ENOTSUP; } -static inline void +static inline int parser_command_queue_action_handle_destroy(rte_port_id_t port_id, rte_queue_id_t queue, bool postpone, uint32_t nb_id, const uint32_t id[]) @@ -1559,11 +1584,12 @@ parser_command_queue_action_handle_destroy(rte_port_id_t port_id, rte_queue_id_t const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_action_handle_destroy) - ops->queue_action_handle_destroy(port_id, queue, postpone, - nb_id, id); + return ops->queue_action_handle_destroy(port_id, (uint32_t)queue, + postpone, nb_id, id); + return -ENOTSUP; } -static inline void +static inline int parser_command_queue_action_handle_update(rte_port_id_t port_id, rte_queue_id_t queue, bool postpone, uint32_t group, const struct rte_flow_action actions[]) @@ -1571,19 +1597,21 @@ parser_command_queue_action_handle_update(rte_port_id_t port_id, rte_queue_id_t const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_action_handle_update) - ops->queue_action_handle_update(port_id, queue, postpone, - group, actions); + return ops->queue_action_handle_update(port_id, (uint32_t)queue, + postpone, group, actions); + return -ENOTSUP; } -static inline void +static inline int parser_command_queue_action_handle_query(rte_port_id_t port_id, rte_queue_id_t queue, bool postpone, uint32_t action_id) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_action_handle_query) - ops->queue_action_handle_query(port_id, queue, postpone, - action_id); + return ops->queue_action_handle_query(port_id, (uint32_t)queue, + postpone, action_id); + return -ENOTSUP; } static inline void @@ -1596,12 +1624,12 @@ parser_command_queue_action_handle_query_update(rte_port_id_t port_id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->queue_action_handle_query_update) - ops->queue_action_handle_query_update(port_id, queue, postpone, - action_id, qu_mode, + ops->queue_action_handle_query_update(port_id, (uint32_t)queue, + postpone, action_id, qu_mode, actions); } -static inline void +static inline int parser_command_action_handle_create(rte_port_id_t port_id, uint32_t group, bool is_list, const struct rte_flow_indir_action_conf *conf, @@ -1610,37 +1638,41 @@ parser_command_action_handle_create(rte_port_id_t port_id, uint32_t group, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->action_handle_create) - ops->action_handle_create(port_id, group, is_list, conf, + return ops->action_handle_create(port_id, group, is_list, conf, actions); + return -ENOTSUP; } -static inline void +static inline int parser_command_action_handle_destroy(rte_port_id_t port_id, uint32_t nb_id, const uint32_t id[]) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->action_handle_destroy) - ops->action_handle_destroy(port_id, nb_id, id); + return ops->action_handle_destroy(port_id, nb_id, id); + return -ENOTSUP; } -static inline void +static inline int parser_command_action_handle_update(rte_port_id_t port_id, uint32_t group, const struct rte_flow_action actions[]) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->action_handle_update) - ops->action_handle_update(port_id, group, actions); + return ops->action_handle_update(port_id, group, actions); + return -ENOTSUP; } -static inline void +static inline int parser_command_action_handle_query(rte_port_id_t port_id, uint32_t action_id) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->action_handle_query) - ops->action_handle_query(port_id, action_id); + return ops->action_handle_query(port_id, action_id); + return -ENOTSUP; } static inline void @@ -1656,7 +1688,7 @@ parser_command_action_handle_query_update(rte_port_id_t port_id, actions); } -static inline void +static inline int parser_command_flow_validate(rte_port_id_t port_id, const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], @@ -1666,11 +1698,12 @@ parser_command_flow_validate(rte_port_id_t port_id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_validate) - ops->flow_validate(port_id, attr, pattern, actions, - tunnel_ops); + return ops->flow_validate(port_id, attr, pattern, actions, + tunnel_ops); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_create(rte_port_id_t port_id, const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], @@ -1681,58 +1714,64 @@ parser_command_flow_create(rte_port_id_t port_id, const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_create) - ops->flow_create(port_id, attr, pattern, actions, tunnel_ops, - user_id); + return ops->flow_create(port_id, attr, pattern, actions, tunnel_ops, + user_id); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_destroy(rte_port_id_t port_id, uint32_t nb_rule, const uint64_t rule[], bool is_user_id) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_destroy) - ops->flow_destroy(port_id, nb_rule, rule, is_user_id); + return ops->flow_destroy(port_id, nb_rule, rule, is_user_id); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_update(rte_port_id_t port_id, uint32_t rule_id, const struct rte_flow_action actions[], - uintptr_t user_id) + bool is_user_id) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_update) - ops->flow_update(port_id, rule_id, actions, user_id); + return ops->flow_update(port_id, rule_id, actions, is_user_id); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_flush(rte_port_id_t port_id) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_flush) - ops->flow_flush(port_id); + return ops->flow_flush(port_id); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_dump(rte_port_id_t port_id, bool all, uint64_t rule, const char *file, bool is_user_id) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_dump) - ops->flow_dump(port_id, all, rule, file, is_user_id); + return ops->flow_dump(port_id, all, rule, file, is_user_id); + return -ENOTSUP; } -static inline void +static inline int parser_command_flow_query(rte_port_id_t port_id, uint64_t rule, - struct rte_flow_action *action, bool is_user_id) + const struct rte_flow_action *action, bool is_user_id) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_query) - ops->flow_query(port_id, rule, action, is_user_id); + return ops->flow_query(port_id, rule, action, is_user_id); + return -ENOTSUP; } static inline void @@ -1745,13 +1784,14 @@ parser_command_flow_list(rte_port_id_t port_id, uint32_t group_n, ops->flow_list(port_id, group_n, group); } -static inline void +static inline int parser_command_flow_isolate(rte_port_id_t port_id, int set) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->flow_isolate) - ops->flow_isolate(port_id, set); + return ops->flow_isolate(port_id, set); + return -ENOTSUP; } static inline void @@ -1791,14 +1831,15 @@ parser_command_flow_tunnel_list(rte_port_id_t port_id) ops->flow_tunnel_list(port_id); } -static inline void +static inline int parser_command_meter_policy_add(rte_port_id_t port_id, uint32_t policy_id, const struct rte_flow_action actions[]) { const struct rte_flow_parser_ops_command *ops = parser_command_ops(); if (ops && ops->meter_policy_add) - ops->meter_policy_add(port_id, policy_id, actions); + return ops->meter_policy_add(port_id, policy_id, actions); + return -ENOTSUP; } static inline void @@ -9597,7 +9638,7 @@ parse_vc(struct context *ctx, const struct token *token, ctx->objmask = NULL; return len; case RTE_FLOW_PARSER_CMD_VC_IS_USER_ID: - out->args.vc.user_id = true; + out->args.vc.is_user_id = true; return len; default: if (!token->priv) @@ -11514,14 +11555,14 @@ parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; if (ctx->curr == RTE_FLOW_PARSER_CMD_ACTION_CONNTRACK_UPDATE_DIR) { ct_modify->new_ct.is_original_dir = - conntrack_context.is_original_dir; + parser.ctx.conntrack_context.is_original_dir; ct_modify->direction = 1; } else { uint32_t old_dir; old_dir = ct_modify->new_ct.is_original_dir; - memcpy(&ct_modify->new_ct, &conntrack_context, - sizeof(conntrack_context)); + memcpy(&ct_modify->new_ct, &parser.ctx.conntrack_context, + sizeof(parser.ctx.conntrack_context)); ct_modify->new_ct.is_original_dir = old_dir; ct_modify->state = 1; } @@ -14096,21 +14137,23 @@ indirect_action_list_conf_get(uint32_t conf_id) } /** Dispatch parsed buffer to function calls. */ -static void +static int cmd_flow_parsed(struct rte_flow_parser_output *in) { + int ret = 0; + switch (in->command) { case RTE_FLOW_PARSER_CMD_INFO: - parser_command_flow_get_info(in->port); + ret = parser_command_flow_get_info(in->port); break; case RTE_FLOW_PARSER_CMD_CONFIGURE: - parser_command_flow_configure(in->port, + ret = parser_command_flow_configure(in->port, &in->args.configure.port_attr, in->args.configure.nb_queue, &in->args.configure.queue_attr); break; case RTE_FLOW_PARSER_CMD_PATTERN_TEMPLATE_CREATE: - parser_command_flow_pattern_template_create(in->port, + ret = parser_command_flow_pattern_template_create(in->port, in->args.vc.pat_templ_id, &((const struct rte_flow_pattern_template_attr) { .relaxed_matching = in->args.vc.attr.reserved, @@ -14121,12 +14164,12 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) in->args.vc.pattern); break; case RTE_FLOW_PARSER_CMD_PATTERN_TEMPLATE_DESTROY: - parser_command_flow_pattern_template_destroy(in->port, + ret = parser_command_flow_pattern_template_destroy(in->port, in->args.templ_destroy.template_id_n, in->args.templ_destroy.template_id); break; case RTE_FLOW_PARSER_CMD_ACTIONS_TEMPLATE_CREATE: - parser_command_flow_actions_template_create(in->port, + ret = parser_command_flow_actions_template_create(in->port, in->args.vc.act_templ_id, &((const struct rte_flow_actions_template_attr) { .ingress = in->args.vc.attr.ingress, @@ -14137,12 +14180,12 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) in->args.vc.masks); break; case RTE_FLOW_PARSER_CMD_ACTIONS_TEMPLATE_DESTROY: - parser_command_flow_actions_template_destroy(in->port, + ret = parser_command_flow_actions_template_destroy(in->port, in->args.templ_destroy.template_id_n, in->args.templ_destroy.template_id); break; case RTE_FLOW_PARSER_CMD_TABLE_CREATE: - parser_command_flow_template_table_create(in->port, + ret = parser_command_flow_template_table_create(in->port, in->args.table.id, &in->args.table.attr, in->args.table.pat_templ_id_n, in->args.table.pat_templ_id, @@ -14150,60 +14193,59 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) in->args.table.act_templ_id); break; case RTE_FLOW_PARSER_CMD_TABLE_DESTROY: - parser_command_flow_template_table_destroy(in->port, + ret = parser_command_flow_template_table_destroy(in->port, in->args.table_destroy.table_id_n, in->args.table_destroy.table_id); break; case RTE_FLOW_PARSER_CMD_TABLE_RESIZE_COMPLETE: - parser_command_flow_template_table_resize_complete + ret = parser_command_flow_template_table_resize_complete (in->port, in->args.table_destroy.table_id[0]); break; case RTE_FLOW_PARSER_CMD_GROUP_SET_MISS_ACTIONS: - parser_command_queue_group_set_miss_actions(in->port, + ret = parser_command_queue_group_set_miss_actions(in->port, &in->args.vc.attr, in->args.vc.actions); break; case RTE_FLOW_PARSER_CMD_TABLE_RESIZE: - parser_command_flow_template_table_resize(in->port, + ret = parser_command_flow_template_table_resize(in->port, in->args.table.id, in->args.table.attr.nb_flows); break; case RTE_FLOW_PARSER_CMD_QUEUE_CREATE: - parser_command_queue_flow_create(in->port, in->queue, + ret = parser_command_queue_flow_create(in->port, in->queue, in->postpone, in->args.vc.table_id, in->args.vc.rule_id, in->args.vc.pat_templ_id, in->args.vc.act_templ_id, in->args.vc.pattern, in->args.vc.actions); break; case RTE_FLOW_PARSER_CMD_QUEUE_DESTROY: - parser_command_queue_flow_destroy(in->port, in->queue, + ret = parser_command_queue_flow_destroy(in->port, in->queue, in->postpone, in->args.destroy.rule_n, - in->args.destroy.rule, - in->args.destroy.is_user_id); + in->args.destroy.rule); break; case RTE_FLOW_PARSER_CMD_QUEUE_FLOW_UPDATE_RESIZED: - parser_command_queue_flow_update_resized(in->port, in->queue, + ret = parser_command_queue_flow_update_resized(in->port, in->queue, in->postpone, - in->args.destroy.rule[0]); + (uint32_t)in->args.destroy.rule[0]); break; case RTE_FLOW_PARSER_CMD_QUEUE_UPDATE: - parser_command_queue_flow_update(in->port, in->queue, + ret = parser_command_queue_flow_update(in->port, in->queue, in->postpone, in->args.vc.rule_id, in->args.vc.act_templ_id, in->args.vc.actions); break; case RTE_FLOW_PARSER_CMD_PUSH: - parser_command_queue_flow_push(in->port, in->queue); + ret = parser_command_queue_flow_push(in->port, in->queue); break; case RTE_FLOW_PARSER_CMD_PULL: - parser_command_queue_flow_pull(in->port, in->queue); + ret = parser_command_queue_flow_pull(in->port, in->queue); break; case RTE_FLOW_PARSER_CMD_HASH: if (!in->args.vc.encap_hash) - parser_command_flow_hash_calc(in->port, + ret = parser_command_flow_hash_calc(in->port, in->args.vc.table_id, in->args.vc.pat_templ_id, in->args.vc.pattern); else - parser_command_flow_hash_calc_encap(in->port, + ret = parser_command_flow_hash_calc_encap(in->port, in->args.vc.field, in->args.vc.pattern); break; @@ -14213,7 +14255,7 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) break; case RTE_FLOW_PARSER_CMD_QUEUE_INDIRECT_ACTION_CREATE: case RTE_FLOW_PARSER_CMD_QUEUE_INDIRECT_ACTION_LIST_CREATE: - parser_command_queue_action_handle_create( + ret = parser_command_queue_action_handle_create( in->port, in->queue, in->postpone, in->args.vc.attr.group, in->command == RTE_FLOW_PARSER_CMD_QUEUE_INDIRECT_ACTION_LIST_CREATE, @@ -14225,19 +14267,19 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) in->args.vc.actions); break; case RTE_FLOW_PARSER_CMD_QUEUE_INDIRECT_ACTION_DESTROY: - parser_command_queue_action_handle_destroy(in->port, + ret = parser_command_queue_action_handle_destroy(in->port, in->queue, in->postpone, in->args.ia_destroy.action_id_n, in->args.ia_destroy.action_id); break; case RTE_FLOW_PARSER_CMD_QUEUE_INDIRECT_ACTION_UPDATE: - parser_command_queue_action_handle_update(in->port, + ret = parser_command_queue_action_handle_update(in->port, in->queue, in->postpone, in->args.vc.attr.group, in->args.vc.actions); break; case RTE_FLOW_PARSER_CMD_QUEUE_INDIRECT_ACTION_QUERY: - parser_command_queue_action_handle_query(in->port, + ret = parser_command_queue_action_handle_query(in->port, in->queue, in->postpone, in->args.ia.action_id); break; @@ -14250,7 +14292,7 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) break; case RTE_FLOW_PARSER_CMD_INDIRECT_ACTION_CREATE: case RTE_FLOW_PARSER_CMD_INDIRECT_ACTION_LIST_CREATE: - parser_command_action_handle_create( + ret = parser_command_action_handle_create( in->port, in->args.vc.attr.group, in->command == RTE_FLOW_PARSER_CMD_INDIRECT_ACTION_LIST_CREATE, &((const struct rte_flow_indir_action_conf) { @@ -14264,16 +14306,16 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) indirect_action_flow_conf_create(in); break; case RTE_FLOW_PARSER_CMD_INDIRECT_ACTION_DESTROY: - parser_command_action_handle_destroy(in->port, + ret = parser_command_action_handle_destroy(in->port, in->args.ia_destroy.action_id_n, in->args.ia_destroy.action_id); break; case RTE_FLOW_PARSER_CMD_INDIRECT_ACTION_UPDATE: - parser_command_action_handle_update(in->port, + ret = parser_command_action_handle_update(in->port, in->args.vc.attr.group, in->args.vc.actions); break; case RTE_FLOW_PARSER_CMD_INDIRECT_ACTION_QUERY: - parser_command_action_handle_query(in->port, + ret = parser_command_action_handle_query(in->port, in->args.ia.action_id); break; case RTE_FLOW_PARSER_CMD_INDIRECT_ACTION_QUERY_UPDATE: @@ -14282,38 +14324,38 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) in->args.vc.actions); break; case RTE_FLOW_PARSER_CMD_VALIDATE: - parser_command_flow_validate(in->port, &in->args.vc.attr, + ret = parser_command_flow_validate(in->port, &in->args.vc.attr, in->args.vc.pattern, in->args.vc.actions, (const struct rte_flow_parser_tunnel_ops *) &in->args.vc.tunnel_ops); break; case RTE_FLOW_PARSER_CMD_CREATE: - parser_command_flow_create(in->port, &in->args.vc.attr, + ret = parser_command_flow_create(in->port, &in->args.vc.attr, in->args.vc.pattern, in->args.vc.actions, (const struct rte_flow_parser_tunnel_ops *) &in->args.vc.tunnel_ops, in->args.vc.user_id); break; case RTE_FLOW_PARSER_CMD_DESTROY: - parser_command_flow_destroy(in->port, + ret = parser_command_flow_destroy(in->port, in->args.destroy.rule_n, in->args.destroy.rule, in->args.destroy.is_user_id); break; case RTE_FLOW_PARSER_CMD_UPDATE: - parser_command_flow_update(in->port, in->args.vc.rule_id, - in->args.vc.actions, in->args.vc.user_id); + ret = parser_command_flow_update(in->port, in->args.vc.rule_id, + in->args.vc.actions, in->args.vc.is_user_id); break; case RTE_FLOW_PARSER_CMD_FLUSH: - parser_command_flow_flush(in->port); + ret = parser_command_flow_flush(in->port); break; case RTE_FLOW_PARSER_CMD_DUMP_ONE: case RTE_FLOW_PARSER_CMD_DUMP_ALL: - parser_command_flow_dump(in->port, in->args.dump.mode, + ret = parser_command_flow_dump(in->port, in->args.dump.mode, in->args.dump.rule, in->args.dump.file, in->args.dump.is_user_id); break; case RTE_FLOW_PARSER_CMD_QUERY: - parser_command_flow_query(in->port, in->args.query.rule, + ret = parser_command_flow_query(in->port, in->args.query.rule, &in->args.query.action, in->args.query.is_user_id); break; @@ -14322,7 +14364,7 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) in->args.list.group); break; case RTE_FLOW_PARSER_CMD_ISOLATE: - parser_command_flow_isolate(in->port, in->args.isolate.set); + ret = parser_command_flow_isolate(in->port, in->args.isolate.set); break; case RTE_FLOW_PARSER_CMD_AGED: parser_command_flow_aged(in->port, in->args.aged.destroy); @@ -14340,7 +14382,7 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) parser_command_flow_tunnel_list(in->port); break; case RTE_FLOW_PARSER_CMD_ACTION_POL_G: - parser_command_meter_policy_add(in->port, + ret = parser_command_meter_policy_add(in->port, in->args.policy.policy_id, in->args.vc.actions); break; @@ -14356,6 +14398,7 @@ cmd_flow_parsed(struct rte_flow_parser_output *in) break; } fflush(stdout); + return ret; } /** Dispatch parsed buffer to function calls. */ @@ -14633,7 +14676,7 @@ rte_flow_parser_cmd_flow_dispatch(struct rte_flow_parser_output *out) { if (!out) return; - cmd_flow_parsed((struct rte_flow_parser_output *)out); + (void)cmd_flow_parsed((struct rte_flow_parser_output *)out); } void @@ -14695,7 +14738,7 @@ rte_flow_parser_run(const char *src) cmd_set_raw_parsed(out); break; default: - cmd_flow_parsed(out); + return cmd_flow_parsed(out); break; } return 0; @@ -14836,6 +14879,7 @@ RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_parser_mplsogre_encap_conf, 26.0); RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_parser_mplsogre_decap_conf, 26.0); RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_parser_mplsoudp_encap_conf, 26.0); RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_parser_mplsoudp_decap_conf, 26.0); +RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_parser_conntrack_context, 26.0); RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_parser_raw_encap_conf_get, 26.0); RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_parser_raw_decap_conf_get, 26.0); RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_parser_cmdline_register, 26.0); diff --git a/lib/flow_parser/rte_flow_parser.h b/lib/flow_parser/rte_flow_parser.h index 9883dee51d..8e9fc2b1db 100644 --- a/lib/flow_parser/rte_flow_parser.h +++ b/lib/flow_parser/rte_flow_parser.h @@ -139,6 +139,13 @@ __rte_experimental struct rte_flow_parser_mplsoudp_decap_conf * rte_flow_parser_mplsoudp_decap_conf(void); +/** + * Accessor for mutable conntrack context used by conntrack update parsing. + */ +__rte_experimental +struct rte_flow_action_conntrack * +rte_flow_parser_conntrack_context(void); + /* Raw encap/decap configuration accessors. */ __rte_experimental const struct rte_flow_action_raw_encap * @@ -930,7 +937,7 @@ struct rte_flow_parser_output { union { struct { struct rte_flow_port_attr port_attr; - uint32_t nb_queue; + uint16_t nb_queue; struct rte_flow_queue_attr queue_attr; } configure; /**< Configuration arguments. */ struct { @@ -965,6 +972,7 @@ struct rte_flow_parser_output { struct rte_flow_attr attr; struct rte_flow_parser_tunnel_ops tunnel_ops; uintptr_t user_id; + bool is_user_id; struct rte_flow_item *pattern; struct rte_flow_action *actions; struct rte_flow_action *masks; @@ -1052,112 +1060,112 @@ struct rte_flow_parser_ops_query { * should implement the callbacks they need; unused callbacks may be NULL. */ struct rte_flow_parser_ops_command { - void (*flow_get_info)(uint16_t port_id); - void (*flow_configure)(uint16_t port_id, + int (*flow_get_info)(uint16_t port_id); + int (*flow_configure)(uint16_t port_id, const struct rte_flow_port_attr *port_attr, - uint32_t nb_queue, + uint16_t nb_queue, const struct rte_flow_queue_attr *queue_attr); - void (*flow_pattern_template_create)(uint16_t port_id, uint32_t id, - const struct rte_flow_pattern_template_attr *attr, - const struct rte_flow_item pattern[]); - void (*flow_pattern_template_destroy)(uint16_t port_id, - uint32_t nb_id, const uint32_t id[]); - void (*flow_actions_template_create)(uint16_t port_id, uint32_t id, - const struct rte_flow_actions_template_attr *attr, - const struct rte_flow_action actions[], - const struct rte_flow_action masks[]); - void (*flow_actions_template_destroy)(uint16_t port_id, - uint32_t nb_id, const uint32_t id[]); - void (*flow_template_table_create)(uint16_t port_id, uint32_t table_id, + int (*flow_pattern_template_create)(uint16_t port_id, uint32_t id, + const struct rte_flow_pattern_template_attr *attr, + const struct rte_flow_item pattern[]); + int (*flow_pattern_template_destroy)(uint16_t port_id, + uint32_t nb_id, const uint32_t id[]); + int (*flow_actions_template_create)(uint16_t port_id, uint32_t id, + const struct rte_flow_actions_template_attr *attr, + const struct rte_flow_action actions[], + const struct rte_flow_action masks[]); + int (*flow_actions_template_destroy)(uint16_t port_id, + uint32_t nb_id, const uint32_t id[]); + int (*flow_template_table_create)(uint16_t port_id, uint32_t table_id, const struct rte_flow_template_table_attr *attr, - uint32_t nb_pattern, const uint32_t pattern_id[], - uint32_t nb_action, const uint32_t action_id[]); - void (*flow_template_table_destroy)(uint16_t port_id, uint32_t nb_id, + uint32_t nb_pattern, uint32_t pattern_id[], + uint32_t nb_action, uint32_t action_id[]); + int (*flow_template_table_destroy)(uint16_t port_id, uint32_t nb_id, const uint32_t id[]); - void (*flow_template_table_resize_complete)(uint16_t port_id, + int (*flow_template_table_resize_complete)(uint16_t port_id, uint32_t table_id); - void (*queue_group_set_miss_actions)(uint16_t port_id, + int (*queue_group_set_miss_actions)(uint16_t port_id, const struct rte_flow_attr *attr, const struct rte_flow_action actions[]); - void (*flow_template_table_resize)(uint16_t port_id, uint32_t table_id, + int (*flow_template_table_resize)(uint16_t port_id, uint32_t table_id, uint32_t nb_rules); - void (*queue_flow_create)(uint16_t port_id, uint16_t queue, + int (*queue_flow_create)(uint16_t port_id, uint16_t queue, bool postpone, uint32_t table_id, uint32_t rule_id, uint32_t pattern_template_id, uint32_t action_template_id, const struct rte_flow_item pattern[], const struct rte_flow_action actions[]); - void (*queue_flow_destroy)(uint16_t port_id, uint16_t queue, + int (*queue_flow_destroy)(uint16_t port_id, uint16_t queue, bool postpone, uint32_t nb_rule, - const uint64_t rule[], bool is_user_id); - void (*queue_flow_update_resized)(uint16_t port_id, uint16_t queue, - bool postpone, uint64_t rule_id); - void (*queue_flow_update)(uint16_t port_id, uint16_t queue, + const uint64_t rule[]); + int (*queue_flow_update_resized)(uint16_t port_id, uint16_t queue, + bool postpone, uint32_t flow_id); + int (*queue_flow_update)(uint16_t port_id, uint16_t queue, bool postpone, uint32_t rule_id, uint32_t action_template_id, const struct rte_flow_action actions[]); - void (*queue_flow_push)(uint16_t port_id, uint16_t queue); - void (*queue_flow_pull)(uint16_t port_id, uint16_t queue); - void (*flow_hash_calc)(uint16_t port_id, uint32_t table_id, - uint32_t pattern_template_id, + int (*queue_flow_push)(uint16_t port_id, uint16_t queue); + int (*queue_flow_pull)(uint16_t port_id, uint16_t queue); + int (*flow_hash_calc)(uint16_t port_id, uint32_t table_id, + uint8_t pattern_template_index, const struct rte_flow_item pattern[]); - void (*flow_hash_calc_encap)(uint16_t port_id, + int (*flow_hash_calc_encap)(uint16_t port_id, enum rte_flow_encap_hash_field field, const struct rte_flow_item pattern[]); - void (*queue_flow_aged)(uint16_t port_id, uint16_t queue, - bool destroy); - void (*queue_action_handle_create)(uint16_t port_id, uint16_t queue, - bool postpone, uint32_t group, + void (*queue_flow_aged)(uint16_t port_id, uint32_t queue, + uint8_t destroy); + int (*queue_action_handle_create)(uint16_t port_id, uint32_t queue, + bool postpone, uint32_t id, bool is_list, const struct rte_flow_indir_action_conf *conf, const struct rte_flow_action actions[]); - void (*queue_action_handle_destroy)(uint16_t port_id, uint16_t queue, + int (*queue_action_handle_destroy)(uint16_t port_id, uint32_t queue, bool postpone, uint32_t nb_id, const uint32_t id[]); - void (*queue_action_handle_update)(uint16_t port_id, uint16_t queue, - bool postpone, uint32_t group, + int (*queue_action_handle_update)(uint16_t port_id, uint32_t queue, + bool postpone, uint32_t id, const struct rte_flow_action actions[]); - void (*queue_action_handle_query)(uint16_t port_id, uint16_t queue, + int (*queue_action_handle_query)(uint16_t port_id, uint32_t queue, bool postpone, uint32_t action_id); void (*queue_action_handle_query_update)(uint16_t port_id, - uint16_t queue, bool postpone, uint32_t action_id, + uint32_t queue, bool postpone, uint32_t action_id, enum rte_flow_query_update_mode qu_mode, - struct rte_flow_action actions[]); - void (*action_handle_create)(uint16_t port_id, uint32_t group, + const struct rte_flow_action actions[]); + int (*action_handle_create)(uint16_t port_id, uint32_t id, bool is_list, const struct rte_flow_indir_action_conf *conf, const struct rte_flow_action actions[]); - void (*action_handle_destroy)(uint16_t port_id, uint32_t nb_id, + int (*action_handle_destroy)(uint16_t port_id, uint32_t nb_id, const uint32_t id[]); - void (*action_handle_update)(uint16_t port_id, uint32_t group, + int (*action_handle_update)(uint16_t port_id, uint32_t id, const struct rte_flow_action actions[]); - void (*action_handle_query)(uint16_t port_id, uint32_t action_id); + int (*action_handle_query)(uint16_t port_id, uint32_t action_id); void (*action_handle_query_update)(uint16_t port_id, uint32_t action_id, enum rte_flow_query_update_mode qu_mode, - struct rte_flow_action actions[]); - void (*flow_validate)(uint16_t port_id, const struct rte_flow_attr *attr, + const struct rte_flow_action actions[]); + int (*flow_validate)(uint16_t port_id, const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], const struct rte_flow_action actions[], const struct rte_flow_parser_tunnel_ops *ops); - void (*flow_create)(uint16_t port_id, const struct rte_flow_attr *attr, + int (*flow_create)(uint16_t port_id, const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], const struct rte_flow_action actions[], const struct rte_flow_parser_tunnel_ops *ops, uintptr_t user_id); - void (*flow_destroy)(uint16_t port_id, uint32_t nb_rule, + int (*flow_destroy)(uint16_t port_id, uint32_t nb_rule, const uint64_t rule[], bool is_user_id); - void (*flow_update)(uint16_t port_id, uint32_t rule_id, - const struct rte_flow_action actions[], uintptr_t user_id); - void (*flow_flush)(uint16_t port_id); - void (*flow_dump)(uint16_t port_id, bool all, uint64_t rule, + int (*flow_update)(uint16_t port_id, uint32_t rule_id, + const struct rte_flow_action actions[], bool is_user_id); + int (*flow_flush)(uint16_t port_id); + int (*flow_dump)(uint16_t port_id, bool all, uint64_t rule, const char *file, bool is_user_id); - void (*flow_query)(uint16_t port_id, uint64_t rule, - struct rte_flow_action *action, bool is_user_id); + int (*flow_query)(uint16_t port_id, uint64_t rule, + const struct rte_flow_action *action, bool is_user_id); void (*flow_list)(uint16_t port_id, uint32_t group_n, const uint32_t group[]); - void (*flow_isolate)(uint16_t port_id, int set); + int (*flow_isolate)(uint16_t port_id, int set); void (*flow_aged)(uint16_t port_id, int destroy); void (*flow_tunnel_create)(uint16_t port_id, const struct rte_flow_parser_tunnel_ops *ops); void (*flow_tunnel_destroy)(uint16_t port_id, uint32_t id); void (*flow_tunnel_list)(uint16_t port_id); - void (*meter_policy_add)(uint16_t port_id, uint32_t policy_id, + int (*meter_policy_add)(uint16_t port_id, uint32_t policy_id, const struct rte_flow_action actions[]); void (*flex_item_create)(uint16_t port_id, uint16_t flex_id, const char *filename); -- 2.43.7