Show a patch.

GET /api/patches/41643/
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 41643,
    "url": "http://patches.dpdk.org/api/patches/41643/",
    "web_url": "http://patches.dpdk.org/patch/41643/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk"
    },
    "msgid": "<68db0702177fe7298675ca0ba8848f1fae531a94.1530089445.git.nelio.laranjeiro@6wind.com>",
    "date": "2018-06-27T08:53:43",
    "name": "[v5,1/2] app/testpmd: add VXLAN encap/decap support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "c928e2162aa5b217d9a31f47f9dd20251c2e9d1a",
    "submitter": {
        "id": 243,
        "url": "http://patches.dpdk.org/api/people/243/",
        "name": "Nélio Laranjeiro",
        "email": "nelio.laranjeiro@6wind.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@intel.com"
    },
    "mbox": "http://patches.dpdk.org/patch/41643/mbox/",
    "series": [
        {
            "id": 255,
            "url": "http://patches.dpdk.org/api/series/255/",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=255",
            "date": "2018-06-27T08:53:42",
            "name": "app/testpmd implement VXLAN/NVGRE Encap/Decap",
            "version": 5,
            "mbox": "http://patches.dpdk.org/series/255/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/41643/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/41643/checks/",
    "tags": {},
    "headers": {
        "X-Mailman-Version": "2.1.15",
        "In-Reply-To": "<cover.1530089445.git.nelio.laranjeiro@6wind.com>",
        "Errors-To": "dev-bounces@dpdk.org",
        "X-Mailer": "git-send-email 2.18.0",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 58FAD1BECF;\n\tWed, 27 Jun 2018 10:53:32 +0200 (CEST)",
            "from mail-wm0-f66.google.com (mail-wm0-f66.google.com\n\t[74.125.82.66]) by dpdk.org (Postfix) with ESMTP id CE0131BEC9\n\tfor <dev@dpdk.org>; Wed, 27 Jun 2018 10:53:28 +0200 (CEST)",
            "by mail-wm0-f66.google.com with SMTP id x6-v6so4809356wmc.3\n\tfor <dev@dpdk.org>; Wed, 27 Jun 2018 01:53:28 -0700 (PDT)",
            "from laranjeiro-vm.dev.6wind.com\n\t(host.78.145.23.62.rev.coltfrance.com. [62.23.145.78])\n\tby smtp.gmail.com with ESMTPSA id\n\ta203-v6sm4738860wme.46.2018.06.27.01.53.27\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tWed, 27 Jun 2018 01:53:27 -0700 (PDT)"
        ],
        "References": "<cover.1529420040.git.nelio.laranjeiro@6wind.com>\n\t<cover.1530089445.git.nelio.laranjeiro@6wind.com>",
        "X-Google-Smtp-Source": "AAOMgpeMXvKaE9Tz1PKiqi9bqBsjZJzjjzfUuQLJftyyfwBd3NVQ8Mk/jJBUWoFLKVYg22loA2KEJQ==",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=6wind-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=h27CPK7+zeQE4vj7YI6aHuQlhFKE3u/2/tccqXrioOo=;\n\tb=jQ2Trfn16yuE1vhjjdiddT2wtiWKWv922xT5xbWZYCV1Rmm0/vVYY2FxXXhS59Fq/O\n\tqTKacQR3SZq2UXSpmkO2MoKQD2Nljch1bfLBmpOIPwc5ah0tUfh6o7jhZSO5WrAXH+SX\n\tKDNQOZhTw7l/5qkxSa479Djb6Ac+mMJOctZIh+lZ+oGsfm0PQol9W5wlH3fv0BcVRXHL\n\txttp/9E3gKcZv4GkdC039bBOEYZ9FRM2EGeQjg3b+gMuYZSjSi8dGl2/zbZzIahtnnlq\n\t3qFwtO4DCB4bHaUnV+4kCxg5SjwHNFAFNa9aAuJhyWDj+96W7+AOsbs05QgQWs17Wv7i\n\t1Z2A==",
        "X-BeenThere": "dev@dpdk.org",
        "X-Received": "by 2002:a1c:5c82:: with SMTP id\n\tq124-v6mr4464801wmb.24.1530089607867; \n\tWed, 27 Jun 2018 01:53:27 -0700 (PDT)",
        "Message-Id": "<68db0702177fe7298675ca0ba8848f1fae531a94.1530089445.git.nelio.laranjeiro@6wind.com>",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=h27CPK7+zeQE4vj7YI6aHuQlhFKE3u/2/tccqXrioOo=;\n\tb=c4B3iM33Ia5s33CixJMueGhbtYkureyer467oh0qoLViyPWZYK122yja7x8nPw8kpJ\n\tESBni6qIaT3J8Qqd3StK9FbxPZ+vEPf8VvsQcacHPhaWT4lEaD6Bg9c/agC/H2CGayNl\n\tPtnvKZKixF2GAEmkV+KBKixBUU2C4paqqKDdoOv/zVj46N32GMM3l47E0DOzuz+glkXV\n\tFW5cY2SY+dRi+WVodmh1EwrAZ/XThtrv0bCp21fAwXqlU0rCrYYSgOiomJTgW9jBf5l+\n\tsHWS9Izj6J0WtBi6Tla8teifInQBCFUQIyI6OtK0DmymzNMEX95OAauHmNQOOdgmoNRP\n\tSc1Q==",
        "Delivered-To": "patchwork@dpdk.org",
        "Precedence": "list",
        "From": "Nelio Laranjeiro <nelio.laranjeiro@6wind.com>",
        "X-Original-To": "patchwork@dpdk.org",
        "List-Post": "<mailto:dev@dpdk.org>",
        "Return-Path": "<dev-bounces@dpdk.org>",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "To": "dev@dpdk.org, Adrien Mazarguil <adrien.mazarguil@6wind.com>,\n\tWenzhuo Lu <wenzhuo.lu@intel.com>, Jingjing Wu <jingjing.wu@intel.com>,\n\tBernard Iremonger <bernard.iremonger@intel.com>,\n\tMohammad Abdul Awal <mohammad.abdul.awal@intel.com>,\n\tStephen Hemminger <stephen@networkplumber.org>",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "Date": "Wed, 27 Jun 2018 10:53:43 +0200",
        "X-Gm-Message-State": "APt69E3B7pdLtGeJ86PGKGOmguVXQeJOgj+PQpLKlyp1/KELFAKS6hP6\n\tJPq8bh6ro110HCRRN8oNCRR9iV78kw==",
        "Cc": "Ori Kam <orika@mellanox.com>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "Subject": "[dpdk-dev] [PATCH v5 1/2] app/testpmd: add VXLAN encap/decap support"
    },
    "content": "Due to the complex VXLAN_ENCAP flow action and based on the fact testpmd\ndoes not allocate memory, this patch adds a new command in testpmd to\ninitialise a global structure containing the necessary information to\nmake the outer layer of the packet.  This same global structure will\nthen be used by the flow command line in testpmd when the action\nvxlan_encap will be parsed, at this point, the conversion into such\naction becomes trivial.\n\nThis global structure is only used for the encap action.\n\nSigned-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>\nAcked-by: Ori Kam <orika@mellanox.com>\n---\n app/test-pmd/cmdline.c                      | 134 +++++++++++++++++++\n app/test-pmd/cmdline_flow.c                 | 139 ++++++++++++++++++++\n app/test-pmd/testpmd.c                      |  17 +++\n app/test-pmd/testpmd.h                      |  17 +++\n doc/guides/testpmd_app_ug/testpmd_funcs.rst |  40 ++++++\n 5 files changed, 347 insertions(+)",
    "diff": "diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c\nindex 27e2aa8c8..048fff2bd 100644\n--- a/app/test-pmd/cmdline.c\n+++ b/app/test-pmd/cmdline.c\n@@ -781,6 +781,14 @@ static void cmd_help_long_parsed(void *parsed_result,\n \t\t\t\"port tm hierarchy commit (port_id) (clean_on_fail)\\n\"\n \t\t\t\"\tCommit tm hierarchy.\\n\\n\"\n \n+\t\t\t\"vxlan ipv4|ipv6 vni udp-src udp-dst ip-src ip-dst\"\n+\t\t\t\" eth-src eth-dst\\n\"\n+\t\t\t\"       Configure the VXLAN encapsulation for flows.\\n\\n\"\n+\n+\t\t\t\"vxlan-with-vlan ipv4|ipv6 vni udp-src udp-dst ip-src ip-dst\"\n+\t\t\t\" vlan-tci eth-src eth-dst\\n\"\n+\t\t\t\"       Configure the VXLAN encapsulation for flows.\\n\\n\"\n+\n \t\t\t, list_pkt_forwarding_modes()\n \t\t);\n \t}\n@@ -14838,6 +14846,130 @@ cmdline_parse_inst_t cmd_set_port_tm_hierarchy_default = {\n };\n #endif\n \n+/** Set VXLAN encapsulation details */\n+struct cmd_set_vxlan_result {\n+\tcmdline_fixed_string_t set;\n+\tcmdline_fixed_string_t vxlan;\n+\tcmdline_fixed_string_t ip_version;\n+\tuint32_t vlan_present:1;\n+\tuint32_t vni;\n+\tuint16_t udp_src;\n+\tuint16_t udp_dst;\n+\tcmdline_ipaddr_t ip_src;\n+\tcmdline_ipaddr_t ip_dst;\n+\tuint16_t tci;\n+\tstruct ether_addr eth_src;\n+\tstruct ether_addr eth_dst;\n+};\n+\n+cmdline_parse_token_string_t cmd_set_vxlan_set =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, set, \"set\");\n+cmdline_parse_token_string_t cmd_set_vxlan_vxlan =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, vxlan, \"vxlan\");\n+cmdline_parse_token_string_t cmd_set_vxlan_vxlan_with_vlan =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, vxlan,\n+\t\t\t\t \"vxlan-with-vlan\");\n+cmdline_parse_token_string_t cmd_set_vxlan_ip_version =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, ip_version,\n+\t\t\t\t \"ipv4#ipv6\");\n+cmdline_parse_token_num_t cmd_set_vxlan_vni =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, vni, UINT32);\n+cmdline_parse_token_num_t cmd_set_vxlan_udp_src =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, udp_src, UINT16);\n+cmdline_parse_token_num_t cmd_set_vxlan_udp_dst =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, udp_dst, UINT16);\n+cmdline_parse_token_ipaddr_t cmd_set_vxlan_ip_src =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_set_vxlan_result, ip_src);\n+cmdline_parse_token_ipaddr_t cmd_set_vxlan_ip_dst =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_set_vxlan_result, ip_dst);\n+cmdline_parse_token_num_t cmd_set_vxlan_vlan =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, tci, UINT16);\n+cmdline_parse_token_etheraddr_t cmd_set_vxlan_eth_src =\n+\tTOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vxlan_result, eth_src);\n+cmdline_parse_token_etheraddr_t cmd_set_vxlan_eth_dst =\n+\tTOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vxlan_result, eth_dst);\n+\n+static void cmd_set_vxlan_parsed(void *parsed_result,\n+\t__attribute__((unused)) struct cmdline *cl,\n+\t__attribute__((unused)) void *data)\n+{\n+\tstruct cmd_set_vxlan_result *res = parsed_result;\n+\tunion {\n+\t\tuint32_t vxlan_id;\n+\t\tuint8_t vni[4];\n+\t} id = {\n+\t\t.vxlan_id = rte_cpu_to_be_32(res->vni) & RTE_BE32(0x00ffffff),\n+\t};\n+\n+\tif (strcmp(res->vxlan, \"vxlan\") == 0)\n+\t\tvxlan_encap_conf.select_vlan = 0;\n+\telse if (strcmp(res->vxlan, \"vxlan-with-vlan\") == 0)\n+\t\tvxlan_encap_conf.select_vlan = 1;\n+\tif (strcmp(res->ip_version, \"ipv4\") == 0)\n+\t\tvxlan_encap_conf.select_ipv4 = 1;\n+\telse if (strcmp(res->ip_version, \"ipv6\") == 0)\n+\t\tvxlan_encap_conf.select_ipv4 = 0;\n+\telse\n+\t\treturn;\n+\trte_memcpy(vxlan_encap_conf.vni, &id.vni[1], 3);\n+\tvxlan_encap_conf.udp_src = rte_cpu_to_be_16(res->udp_src);\n+\tvxlan_encap_conf.udp_dst = rte_cpu_to_be_16(res->udp_dst);\n+\tif (vxlan_encap_conf.select_ipv4) {\n+\t\tIPV4_ADDR_TO_UINT(res->ip_src, vxlan_encap_conf.ipv4_src);\n+\t\tIPV4_ADDR_TO_UINT(res->ip_dst, vxlan_encap_conf.ipv4_dst);\n+\t} else {\n+\t\tIPV6_ADDR_TO_ARRAY(res->ip_src, vxlan_encap_conf.ipv6_src);\n+\t\tIPV6_ADDR_TO_ARRAY(res->ip_dst, vxlan_encap_conf.ipv6_dst);\n+\t}\n+\tif (vxlan_encap_conf.select_vlan)\n+\t\tvxlan_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci);\n+\trte_memcpy(vxlan_encap_conf.eth_src, res->eth_src.addr_bytes,\n+\t\t   ETHER_ADDR_LEN);\n+\trte_memcpy(vxlan_encap_conf.eth_dst, res->eth_dst.addr_bytes,\n+\t\t   ETHER_ADDR_LEN);\n+}\n+\n+cmdline_parse_inst_t cmd_set_vxlan = {\n+\t.f = cmd_set_vxlan_parsed,\n+\t.data = NULL,\n+\t.help_str = \"set vxlan ipv4|ipv6 <vni> <udp-src> <udp-dst> <ip-src>\"\n+\t\t\" <ip-dst> <eth-src> <eth-dst>\",\n+\t.tokens = {\n+\t\t(void *)&cmd_set_vxlan_set,\n+\t\t(void *)&cmd_set_vxlan_vxlan,\n+\t\t(void *)&cmd_set_vxlan_ip_version,\n+\t\t(void *)&cmd_set_vxlan_vni,\n+\t\t(void *)&cmd_set_vxlan_udp_src,\n+\t\t(void *)&cmd_set_vxlan_udp_dst,\n+\t\t(void *)&cmd_set_vxlan_ip_src,\n+\t\t(void *)&cmd_set_vxlan_ip_dst,\n+\t\t(void *)&cmd_set_vxlan_eth_src,\n+\t\t(void *)&cmd_set_vxlan_eth_dst,\n+\t\tNULL,\n+\t},\n+};\n+\n+cmdline_parse_inst_t cmd_set_vxlan_with_vlan = {\n+\t.f = cmd_set_vxlan_parsed,\n+\t.data = NULL,\n+\t.help_str = \"set vxlan-with-vlan ipv4|ipv6 <vni> <udp-src> <udp-dst>\"\n+\t\t\" <ip-src> <ip-dst> <vlan-tci> <eth-src> <eth-dst>\",\n+\t.tokens = {\n+\t\t(void *)&cmd_set_vxlan_set,\n+\t\t(void *)&cmd_set_vxlan_vxlan_with_vlan,\n+\t\t(void *)&cmd_set_vxlan_ip_version,\n+\t\t(void *)&cmd_set_vxlan_vni,\n+\t\t(void *)&cmd_set_vxlan_udp_src,\n+\t\t(void *)&cmd_set_vxlan_udp_dst,\n+\t\t(void *)&cmd_set_vxlan_ip_src,\n+\t\t(void *)&cmd_set_vxlan_ip_dst,\n+\t\t(void *)&cmd_set_vxlan_vlan,\n+\t\t(void *)&cmd_set_vxlan_eth_src,\n+\t\t(void *)&cmd_set_vxlan_eth_dst,\n+\t\tNULL,\n+\t},\n+};\n+\n /* Strict link priority scheduling mode setting */\n static void\n cmd_strict_link_prio_parsed(\n@@ -17462,6 +17594,8 @@ cmdline_parse_ctx_t main_ctx[] = {\n #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED\n \t(cmdline_parse_inst_t *)&cmd_set_port_tm_hierarchy_default,\n #endif\n+\t(cmdline_parse_inst_t *)&cmd_set_vxlan,\n+\t(cmdline_parse_inst_t *)&cmd_set_vxlan_with_vlan,\n \t(cmdline_parse_inst_t *)&cmd_ddp_add,\n \t(cmdline_parse_inst_t *)&cmd_ddp_del,\n \t(cmdline_parse_inst_t *)&cmd_ddp_get_list,\ndiff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c\nindex 934cf7e90..7823addb7 100644\n--- a/app/test-pmd/cmdline_flow.c\n+++ b/app/test-pmd/cmdline_flow.c\n@@ -239,6 +239,8 @@ enum index {\n \tACTION_OF_POP_MPLS_ETHERTYPE,\n \tACTION_OF_PUSH_MPLS,\n \tACTION_OF_PUSH_MPLS_ETHERTYPE,\n+\tACTION_VXLAN_ENCAP,\n+\tACTION_VXLAN_DECAP,\n };\n \n /** Maximum size for pattern in struct rte_flow_item_raw. */\n@@ -258,6 +260,23 @@ struct action_rss_data {\n \tuint16_t queue[ACTION_RSS_QUEUE_NUM];\n };\n \n+/** Maximum number of items in struct rte_flow_action_vxlan_encap. */\n+#define ACTION_VXLAN_ENCAP_ITEMS_NUM 6\n+\n+/** Storage for struct rte_flow_action_vxlan_encap including external data. */\n+struct action_vxlan_encap_data {\n+\tstruct rte_flow_action_vxlan_encap conf;\n+\tstruct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM];\n+\tstruct rte_flow_item_eth item_eth;\n+\tstruct rte_flow_item_vlan item_vlan;\n+\tunion {\n+\t\tstruct rte_flow_item_ipv4 item_ipv4;\n+\t\tstruct rte_flow_item_ipv6 item_ipv6;\n+\t};\n+\tstruct rte_flow_item_udp item_udp;\n+\tstruct rte_flow_item_vxlan item_vxlan;\n+};\n+\n /** Maximum number of subsequent tokens and arguments on the stack. */\n #define CTX_STACK_SIZE 16\n \n@@ -775,6 +794,8 @@ static const enum index next_action[] = {\n \tACTION_OF_SET_VLAN_PCP,\n \tACTION_OF_POP_MPLS,\n \tACTION_OF_PUSH_MPLS,\n+\tACTION_VXLAN_ENCAP,\n+\tACTION_VXLAN_DECAP,\n \tZERO,\n };\n \n@@ -905,6 +926,9 @@ static int parse_vc_action_rss_type(struct context *, const struct token *,\n static int parse_vc_action_rss_queue(struct context *, const struct token *,\n \t\t\t\t     const char *, unsigned int, void *,\n \t\t\t\t     unsigned int);\n+static int parse_vc_action_vxlan_encap(struct context *, const struct token *,\n+\t\t\t\t       const char *, unsigned int, void *,\n+\t\t\t\t       unsigned int);\n static int parse_destroy(struct context *, const struct token *,\n \t\t\t const char *, unsigned int,\n \t\t\t void *, unsigned int);\n@@ -2387,6 +2411,24 @@ static const struct token token_list[] = {\n \t\t\t      ethertype)),\n \t\t.call = parse_vc_conf,\n \t},\n+\t[ACTION_VXLAN_ENCAP] = {\n+\t\t.name = \"vxlan_encap\",\n+\t\t.help = \"VXLAN encapsulation, uses configuration set by \\\"set\"\n+\t\t\t\" vxlan\\\"\",\n+\t\t.priv = PRIV_ACTION(VXLAN_ENCAP,\n+\t\t\t\t    sizeof(struct action_vxlan_encap_data)),\n+\t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),\n+\t\t.call = parse_vc_action_vxlan_encap,\n+\t},\n+\t[ACTION_VXLAN_DECAP] = {\n+\t\t.name = \"vxlan_decap\",\n+\t\t.help = \"Performs a decapsulation action by stripping all\"\n+\t\t\t\" headers of the VXLAN tunnel network overlay from the\"\n+\t\t\t\" matched flow.\",\n+\t\t.priv = PRIV_ACTION(VXLAN_DECAP, 0),\n+\t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),\n+\t\t.call = parse_vc,\n+\t},\n };\n \n /** Remove and return last entry from argument stack. */\n@@ -2951,6 +2993,103 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token,\n \treturn len;\n }\n \n+/** Parse VXLAN encap action. */\n+static int\n+parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token,\n+\t\t\t    const char *str, unsigned int len,\n+\t\t\t    void *buf, unsigned int size)\n+{\n+\tstruct buffer *out = buf;\n+\tstruct rte_flow_action *action;\n+\tstruct action_vxlan_encap_data *action_vxlan_encap_data;\n+\tint ret;\n+\n+\tret = parse_vc(ctx, token, str, len, buf, size);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\t/* Nothing else to do if there is no buffer. */\n+\tif (!out)\n+\t\treturn ret;\n+\tif (!out->args.vc.actions_n)\n+\t\treturn -1;\n+\taction = &out->args.vc.actions[out->args.vc.actions_n - 1];\n+\t/* Point to selected object. */\n+\tctx->object = out->args.vc.data;\n+\tctx->objmask = NULL;\n+\t/* Set up default configuration. */\n+\taction_vxlan_encap_data = ctx->object;\n+\t*action_vxlan_encap_data = (struct action_vxlan_encap_data){\n+\t\t.conf = (struct rte_flow_action_vxlan_encap){\n+\t\t\t.definition = action_vxlan_encap_data->items,\n+\t\t},\n+\t\t.items = {\n+\t\t\t{\n+\t\t\t\t.type = RTE_FLOW_ITEM_TYPE_ETH,\n+\t\t\t\t.spec = &action_vxlan_encap_data->item_eth,\n+\t\t\t\t.mask = &rte_flow_item_eth_mask,\n+\t\t\t},\n+\t\t\t{\n+\t\t\t\t.type = RTE_FLOW_ITEM_TYPE_VLAN,\n+\t\t\t\t.spec = &action_vxlan_encap_data->item_vlan,\n+\t\t\t\t.mask = &rte_flow_item_vlan_mask,\n+\t\t\t},\n+\t\t\t{\n+\t\t\t\t.type = RTE_FLOW_ITEM_TYPE_IPV4,\n+\t\t\t\t.spec = &action_vxlan_encap_data->item_ipv4,\n+\t\t\t\t.mask = &rte_flow_item_ipv4_mask,\n+\t\t\t},\n+\t\t\t{\n+\t\t\t\t.type = RTE_FLOW_ITEM_TYPE_UDP,\n+\t\t\t\t.spec = &action_vxlan_encap_data->item_udp,\n+\t\t\t\t.mask = &rte_flow_item_udp_mask,\n+\t\t\t},\n+\t\t\t{\n+\t\t\t\t.type = RTE_FLOW_ITEM_TYPE_VXLAN,\n+\t\t\t\t.spec = &action_vxlan_encap_data->item_vxlan,\n+\t\t\t\t.mask = &rte_flow_item_vxlan_mask,\n+\t\t\t},\n+\t\t\t{\n+\t\t\t\t.type = RTE_FLOW_ITEM_TYPE_END,\n+\t\t\t},\n+\t\t},\n+\t\t.item_eth.type = 0,\n+\t\t.item_vlan.tci = vxlan_encap_conf.vlan_tci,\n+\t\t.item_ipv4.hdr = {\n+\t\t\t.src_addr = vxlan_encap_conf.ipv4_src,\n+\t\t\t.dst_addr = vxlan_encap_conf.ipv4_dst,\n+\t\t},\n+\t\t.item_udp.hdr = {\n+\t\t\t.src_port = vxlan_encap_conf.udp_src,\n+\t\t\t.dst_port = vxlan_encap_conf.udp_dst,\n+\t\t},\n+\t\t.item_vxlan.flags = 0,\n+\t};\n+\tmemcpy(action_vxlan_encap_data->item_eth.dst.addr_bytes,\n+\t       vxlan_encap_conf.eth_dst, ETHER_ADDR_LEN);\n+\tmemcpy(action_vxlan_encap_data->item_eth.src.addr_bytes,\n+\t       vxlan_encap_conf.eth_src, ETHER_ADDR_LEN);\n+\tif (!vxlan_encap_conf.select_ipv4) {\n+\t\tmemcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr,\n+\t\t       &vxlan_encap_conf.ipv6_src,\n+\t\t       sizeof(vxlan_encap_conf.ipv6_src));\n+\t\tmemcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr,\n+\t\t       &vxlan_encap_conf.ipv6_dst,\n+\t\t       sizeof(vxlan_encap_conf.ipv6_dst));\n+\t\taction_vxlan_encap_data->items[2] = (struct rte_flow_item){\n+\t\t\t.type = RTE_FLOW_ITEM_TYPE_IPV6,\n+\t\t\t.spec = &action_vxlan_encap_data->item_ipv6,\n+\t\t\t.mask = &rte_flow_item_ipv6_mask,\n+\t\t};\n+\t}\n+\tif (!vxlan_encap_conf.select_vlan)\n+\t\taction_vxlan_encap_data->items[1].type =\n+\t\t\tRTE_FLOW_ITEM_TYPE_VOID;\n+\tmemcpy(action_vxlan_encap_data->item_vxlan.vni, vxlan_encap_conf.vni,\n+\t       RTE_DIM(vxlan_encap_conf.vni));\n+\taction->conf = &action_vxlan_encap_data->conf;\n+\treturn ret;\n+}\n+\n /** Parse tokens for destroy command. */\n static int\n parse_destroy(struct context *ctx, const struct token *token,\ndiff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c\nindex 63c2a5aca..4a18d043c 100644\n--- a/app/test-pmd/testpmd.c\n+++ b/app/test-pmd/testpmd.c\n@@ -393,6 +393,23 @@ uint8_t bitrate_enabled;\n struct gro_status gro_ports[RTE_MAX_ETHPORTS];\n uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES;\n \n+struct vxlan_encap_conf vxlan_encap_conf = {\n+\t.select_ipv4 = 1,\n+\t.select_vlan = 0,\n+\t.vni = \"\\x00\\x00\\x00\",\n+\t.udp_src = 0,\n+\t.udp_dst = RTE_BE16(4789),\n+\t.ipv4_src = IPv4(127, 0, 0, 1),\n+\t.ipv4_dst = IPv4(255, 255, 255, 255),\n+\t.ipv6_src = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n+\t\t\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\",\n+\t.ipv6_dst = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\n+\t\t\"\\x00\\x00\\x00\\x00\\x00\\x00\\x11\\x11\",\n+\t.vlan_tci = 0,\n+\t.eth_src = \"\\x00\\x00\\x00\\x00\\x00\\x00\",\n+\t.eth_dst = \"\\xff\\xff\\xff\\xff\\xff\\xff\",\n+};\n+\n /* Forward function declarations */\n static void map_port_queue_stats_mapping_registers(portid_t pi,\n \t\t\t\t\t\t   struct rte_port *port);\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex f51cd9dd9..0d6618788 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -479,6 +479,23 @@ struct gso_status {\n extern struct gso_status gso_ports[RTE_MAX_ETHPORTS];\n extern uint16_t gso_max_segment_size;\n \n+/* VXLAN encap/decap parameters. */\n+struct vxlan_encap_conf {\n+\tuint32_t select_ipv4:1;\n+\tuint32_t select_vlan:1;\n+\tuint8_t vni[3];\n+\trte_be16_t udp_src;\n+\trte_be16_t udp_dst;\n+\trte_be32_t ipv4_src;\n+\trte_be32_t ipv4_dst;\n+\tuint8_t ipv6_src[16];\n+\tuint8_t ipv6_dst[16];\n+\trte_be16_t vlan_tci;\n+\tuint8_t eth_src[ETHER_ADDR_LEN];\n+\tuint8_t eth_dst[ETHER_ADDR_LEN];\n+};\n+struct vxlan_encap_conf vxlan_encap_conf;\n+\n static inline unsigned int\n lcore_num(void)\n {\ndiff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst\nindex 0d6fd50ca..698b83268 100644\n--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst\n+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst\n@@ -1534,6 +1534,18 @@ Enable or disable a per queue Tx offloading only on a specific Tx queue::\n \n This command should be run when the port is stopped, or else it will fail.\n \n+Config VXLAN Encap outer layers\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+Configure the outer layer to encapsulate a packet inside a VXLAN tunnel::\n+\n+ testpmd> set vxlan ipv4|ipv6 (vni) (udp-src) (udp-dst) (ip-src) (ip-dst) (mac-src) (mac-dst)\n+ testpmd> set vxlan-with-vlan ipv4|ipv6 (vni) (udp-src) (udp-dst) (ip-src) (ip-dst) (vlan-tci) (mac-src) (mac-dst)\n+\n+Those command will set an internal configuration inside testpmd, any following\n+flow rule using the action vxlan_encap will use the last configuration set.\n+To have a different encapsulation header, one of those commands must be called\n+before the flow rule creation.\n \n Port Functions\n --------------\n@@ -3650,6 +3662,12 @@ This section lists supported actions and their attributes, if any.\n \n   - ``ethertype``: Ethertype.\n \n+- ``vxlan_encap``: Performs a VXLAN encapsulation, outer layer configuration\n+  is done through `Config VXLAN Encap outer layers`_.\n+\n+- ``vxlan_decap``: Performs a decapsulation action by stripping all headers of\n+  the VXLAN tunnel network overlay from the matched flow.\n+\n Destroying flow rules\n ~~~~~~~~~~~~~~~~~~~~~\n \n@@ -3915,6 +3933,28 @@ Validate and create a QinQ rule on port 0 to steer traffic to a queue on the hos\n    0       0       0       i-      ETH VLAN VLAN=>VF QUEUE\n    1       0       0       i-      ETH VLAN VLAN=>PF QUEUE\n \n+Sample VXLAN encapsulation rule\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+VXLAN encapsulation outer layer has default value pre-configured in testpmd\n+source code, those can be changed by using the following commands\n+\n+IPv4 VXLAN outer header::\n+\n+ testpmd> set vxlan ipv4 4 4 4 127.0.0.1 128.0.0.1 11:11:11:11:11:11 22:22:22:22:22:22\n+ testpmd> flow create 0 ingress pattern end actions vxlan_encap / queue index 0 / end\n+\n+ testpmd> set vxlan-with-vlan ipv4 4 4 4 127.0.0.1 128.0.0.1 34 11:11:11:11:11:11 22:22:22:22:22:22\n+ testpmd> flow create 0 ingress pattern end actions vxlan_encap / queue index 0 / end\n+\n+IPv6 VXLAN outer header::\n+\n+ testpmd> set vxlan ipv6 4 4 4 ::1 ::2222 11:11:11:11:11:11 22:22:22:22:22:22\n+ testpmd> flow create 0 ingress pattern end actions vxlan_encap / queue index 0 / end\n+\n+ testpmd> set vxlan-with-vlan ipv6 4 4 4 ::1 ::2222 34 11:11:11:11:11:11 22:22:22:22:22:22\n+ testpmd> flow create 0 ingress pattern end actions vxlan_encap / queue index 0 / end\n+\n BPF Functions\n --------------\n \n",
    "prefixes": [
        "v5",
        "1/2"
    ]
}