get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 47192,
    "url": "https://patches.dpdk.org/api/patches/47192/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1540229891-112870-4-git-send-email-orika@mellanox.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "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",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1540229891-112870-4-git-send-email-orika@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1540229891-112870-4-git-send-email-orika@mellanox.com",
    "date": "2018-10-22T17:38:11",
    "name": "[v6,3/3] app/testpmd: add MPLSoGRE encapsulation",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "cbc1ec198b42075d2a31e57bf37e5e49dfe6c6cb",
    "submitter": {
        "id": 795,
        "url": "https://patches.dpdk.org/api/people/795/?format=api",
        "name": "Ori Kam",
        "email": "orika@mellanox.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1540229891-112870-4-git-send-email-orika@mellanox.com/mbox/",
    "series": [
        {
            "id": 2014,
            "url": "https://patches.dpdk.org/api/series/2014/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=2014",
            "date": "2018-10-22T17:38:08",
            "name": "ethdev: add generic raw tunnel encapsulation",
            "version": 6,
            "mbox": "https://patches.dpdk.org/series/2014/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/47192/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/47192/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id BE4041B461;\n\tMon, 22 Oct 2018 19:38:55 +0200 (CEST)",
            "from EUR03-VE1-obe.outbound.protection.outlook.com\n\t(mail-eopbgr50040.outbound.protection.outlook.com [40.107.5.40])\n\tby dpdk.org (Postfix) with ESMTP id 756401B450\n\tfor <dev@dpdk.org>; Mon, 22 Oct 2018 19:38:49 +0200 (CEST)",
            "from mellanox.com (37.142.13.130) by\n\tAM4PR05MB3426.eurprd05.prod.outlook.com (2603:10a6:205:6::15) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1250.30; Mon, 22 Oct 2018 17:38:45 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com;\n\ts=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=y7rkkpvfOZGpFecZOYeeYFDFZzuU2JjBKfBbwhPSiQI=;\n\tb=MFUOBI53gDezhCgxg6Soxk2pP78ZreCphFC0ehZJnN0Zrpc+1ECIbQRo7NybCemGiRlH4imnFYeyPwYBkky/PADeRsktA0CkhHvs1lnr7EpcXPAjLPLlA92KJ8YmrideY3u7y1gtz3PMneVs+Yv86j/j1/zrqIQQG3jY3kACIxc=",
        "From": "Ori Kam <orika@mellanox.com>",
        "To": "wenzhuo.lu@intel.com, jingjing.wu@intel.com, bernard.iremonger@intel.com,\n\tarybchenko@solarflare.com, ferruh.yigit@intel.com,\n\tstephen@networkplumber.org, adrien.mazarguil@6wind.com",
        "Cc": "dev@dpdk.org, dekelp@mellanox.com, thomas@monjalon.net,\n\tnelio.laranjeiro@6wind.com, yskoh@mellanox.com, orika@mellanox.com,\n\tshahafs@mellanox.com",
        "Date": "Mon, 22 Oct 2018 17:38:11 +0000",
        "Message-Id": "<1540229891-112870-4-git-send-email-orika@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1540229891-112870-1-git-send-email-orika@mellanox.com>",
        "References": "<1539796072-111646-1-git-send-email-orika@mellanox.com>\n\t<1540229891-112870-1-git-send-email-orika@mellanox.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[37.142.13.130]",
        "X-ClientProxiedBy": "CWLP265CA0300.GBRP265.PROD.OUTLOOK.COM\n\t(2603:10a6:401:5d::24) To AM4PR05MB3426.eurprd05.prod.outlook.com\n\t(2603:10a6:205:6::15)",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "3d29fa85-a56f-4cad-2569-08d638453891",
        "X-MS-Office365-Filtering-HT": "Tenant",
        "X-Microsoft-Antispam": "BCL:0; PCL:0;\n\tRULEID:(7020095)(4652040)(8989299)(5600074)(711020)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020);\n\tSRVR:AM4PR05MB3426; ",
        "X-Microsoft-Exchange-Diagnostics": [
            "1; AM4PR05MB3426;\n\t3:6TMYURB7g/FYJZjRcAdytzHh8ON04IRycjqfwRgNOFEsVIw0BvNA4QdZ2zjW9AAIJ2Kfjn1gzkvgB9sOKQ/vgFUmXT7hI2vC2cF8Q+EjO7Hr/p0c4qyPQNE4iAp0hlh7bz4zkFgnW8bru1hnV6GxfvJByGfAgNhpN+w9m9AEWqL9x5Q32ba3yWMmt01l80V3Hfa0qQ7x3p+bBlBmzQh2//IOX6o8XDpyQZMm4pPuVOGHNsp8mI1wehNDKuQkqjfL;\n\t25:MXyVt7PNpAa/bm/mkhI/7s+dxPFltdqKeDDoL81QuNEYqg0TEWrFVYXTZmrfjfAL3y3M7wgsMx59tUUwewUVBYiDqoovk+wd+X6B4lpikYDRrjfRxBmoSQyzBhhC/ZE6Y9hXPmhNcna32g92u785r+I+X0pF5UHijR8+oIWsY/Tgo+sHdigf1CbMWfjmOq80P5juY6tkh7b+SHL/iBmd3tn/6vN+tHi802ukUGj//SUnEHazb6qhEw+8FIMR+Ryfc6SOH7j4OHRxuNR46euoCeecjENmLbB0dnFu2RB23RKmKFJXfRc94w1Amdczwfln98M6M4+B2XgkJUx5UUSfCg==;\n\t31:kFhQ2hR1y5vgt0/oOwX2A6YijH2qvBw8vWc7vmCS2/5ZEF5ulkFgTtHsLGreCaitVvLr91AC+2my/3ORBUwZNxsB3KnAOdrQWKMeudaf2EKQYSXwhoG8WxgHsxfDMdrcNvWMXbf/AoAEw7/rjbk19d8Yu/9EefnCqbr58EgS9BTu9KSuVsPsH3uoLRVkmkX/Qz42raJQPvVzJP0S0ev2gOw3z3ztxnw3nfkXHZxV9ic=",
            "1; AM4PR05MB3426;\n\t20:1sKdO8Q6J8givYJGWHJHLmpCOjrkJY4oOfOOT8CfOOL/1h1wm0Jd032tgMwXqbIJ+eR7LxJJTLa956Mg7FpYnZSf54IHQqMzy9wnIiUUhhD3YS6pmsDD8hKHSefV1PGWHRJzyHWHt9Z/Fkc7w7vxOa3u/JuaMqWfwfoFcm8dX7X8xZqFgmsClT6kjU0gqncxq+XHtTnf6THrKXqlVA8Eyi/q/AfT9KCCCatYn3Kn4s7Wvv18K2kG900IOb+4ADILj4FGypxXlHKlQGtcwk6xYU68R7Wm+aYboJTV30NawXEGppmqhdsQgyLFJBKNkR6q7lwKmKE1NITm5ATyX1C6Skoj2Jh7ajEJHnmQVEZyOwX0EYxkmxZAhUyJat4MqtpRev7ua5JZ6kTkf5e+BocQX5q4Kn6tfvgbio/F6JnWU4wxUTs4RnFQgcn8P9ILWqnXK9QdnbORdiTL6R78s2XPRtng0Q1unG91gZAzcExWeKOl7slTmDM+qlqX6W8WP5MI;\n\t4:Zya3KJL2c29Y6SNj65rH5m/9/kIhK92EGg9G08VuV5Rp0W92ha1RWHV9suajXA9s/b1xkXWsb0PB0ZwO8YFNsRHfSh9Hm5NZapj1ZFDL71HZ7EIhSBTWAw2xFAhe/L+iEFRarFcCQQShBRuNVN2i/v2VXVopHYQ3bC6hy/KULET5BwRnGZZ19aAVEk05hqKS4rmjijjChZGwH1pwTgCHzQSpJNwp7APbqKDutyBA6JV7RnU4qdRBQpOucTToVqJ7kDX9zmOXGIbc4o9x4dgzEJPyck51ymetFoB26NxyJ+0mWYfCN70aa71yR153wwe3",
            "=?us-ascii?Q?1; AM4PR05MB3426;\n\t23:WXqSO7qf18w9gnPr3x5tR7bDAZYvyLbpeuk8NGx0e?=\n\tQmdBcXi9HC15kQtDpRa4iTSnZsVLrBLCpzTEVY1ev0qz5t+6nmQ909VdxyQ+IAb+e93eNvtfE8A4miV8atHImwXw53qMt9HVs0/S24wICeCPk6IS02LWUmQdb4OOFLKqaec+iMVTV2klOTkpLXc1v9IjPZOr09FLSXbQhetlEC+jIv+AyE0cq9rI5frtkDiO+LEhawwUjBaHhsq1kEYIpP6D+5Mz83AiGr9zu1jfis/BXYgbAlbe2ZnjrAVEGLYhOJfjm3n2z949m7WRmycVSkkWntahbXBa6P0oyRccuZE0y12vqwufzjz8/kOtU53aQVJyTiyUEYyhNCWE+oP+spatANIlXP8UItc3xVfavG1E8pe+MoAtHgT88U/3MN2c7Tx8TpfkGEp6oz0hC2WrQ16MfzchF7WsIozP18aZ8s6Ro3wOjQJzd7Iasq/6w3H0rK27wzZI+0g2KfuMcbKW2LoP2afqQmcwiG2sVBu5T3GY6bbvz7rfqOvTEy7OdKnrrGW5XsNyDBcz9lt7gX643lZhJuR2BHGszMIV0LdaNeo3LRVAyctH63O9DSuA18dQ+lm7IzXqGMjLVhFIpKchTFcny8R9EH/E9kqF8MtJDdKWsLnD9CjE3ONzRLyW2VvM+3mIR4sNa4IDrvWVlIS0oRFJef8mWLHTvpwy7DjerT7zlppIuoW8PNZv+ZjXFrRIq9moTv2wIvpadc/x6bZ9zweealqX9XppEcs+2ydpflgvSOToKM1ZABfpv5h3/VsBsKmaWbO3BsTprr2zeb41O3bP/wwjDw1M+94mVLV/tb8Rscqw8VqA5CvHsqu1U91UGBDB39KMqwHWMYKX2ssrxN0fMk5yN+TV4IBj/WXRHDwayM4wrvVs3wg4cul6XsYtKoQYaiVTunoWLoLM4+bat0CaFJrNxaa96CTJ7K/+uoUUgJfyuUlQJzRHnZdDhj0u2Gb7Z9VxlqWNnorx/+VkH4FcxhLVe/lw8KPIT62PA6+0sR1NO35f02AOOAxGSFPjE13Rduo87CxqwITWuJJ53cnOwoYkBmKIoGUc/4Tr2rkQsZVfJd9RnbXNpLi+5Usv2eVU6QZ9sygYglh3v9fwSYmSW50Ciwya5BmwligjQkmr+VdCcm3Grb8RlZYDZ/LIUsEdjsi3Aj9TPBJGMsfkFRSL4Pa1l0m65gYcuXGOKRQgxf76IyMpq5DePNgjWmcujmbsZCQTj7obaLaZt4/UyyLGRrSMKjnI0HGWMLtI4jntypxhtat+0z4cvilh1FESB2mTjd9+qvidJ9a6SHNZ/Rq",
            "1; AM4PR05MB3426;\n\t6:IKBrMl4qna4GCuyshG0+s7lXRzwbtSWG4shBr2KhXyWKBDB7c0A8S6hn479bpfqoCzu5GiaI04Ax0gj3eWnYIa5jGIVpYXGr76Fm/C1OGVvz3GtnLzFLjtuUcfF858DW0tb/ih2Y2DXOZAWTJy/+Xey2uQTRKvwmXVDTQ9EeNXfs0wsYroMYJOeHR7lT3ke7FThZRhHsbsspPxJYJnXW3WFDAm/OdEl38CGXMfnNJFNFl6ijuhGNrJXozckICVT78WCNZ3fliSGYucyDqDwZeH8naxvIjWWzPfqhW9xc6A/rl3XQ9eSQ185o/V7oKk+wTnWxyxTOjnF0SOe0Q+QxozTqvHOZwyv9IHikrefmCAH0ZyN2rTDYnM4IpNjJU7H1wBvEs/QomTannPuB0k2o8PudsRauYJY70eashm0c5SoDG7bUFXqUD8+Rxtg/SHv6mp7nJ7FEfjvpRASXK+/0ZA==;\n\t5:MBSHeVEzi8jURBaLHIgBUNSc/mLsataMyh59WnG9MSHyk2+IMJ2PtbiCS87Ne3rs8cn1Lw6oyscHmfaIiVj4HlcnpIROsu7FQoCofTpJb4JXlicmxR2ncho/Bz9u+DR+v83GMMfyC4boE1BbAbflozP4WtLb35EzLtVD7O93+JY=;\n\t7:vbbAGAfEHbP+K5DtPXXcCTWwC7vXxeW76RxCQOIs8kZw2wAbBC67w9bKxTB3AoowvieSPMABtg/Z87WCyYtlZpZNUlGb+3wERGRjrhSFoTzOyPRPwdwQbk7qefgnCwwg4cEok7bi7rDUNtQUAgJTouyoFO/bEArqHbZCtQqKrzjHWVfmT/nnImZ0smIAnilcMqzJL1qcQ8Ca2J4YWxoeKKCi/dnQrRJ+apVCoYScCgMOlj+jhL1ZdxoF9/Cy8iar"
        ],
        "X-MS-TrafficTypeDiagnostic": "AM4PR05MB3426:",
        "X-LD-Processed": "a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr",
        "X-Microsoft-Antispam-PRVS": "<AM4PR05MB3426F9793D0152BC3CBA2D2FDBF40@AM4PR05MB3426.eurprd05.prod.outlook.com>",
        "X-Exchange-Antispam-Report-Test": "UriScan:(17755550239193);",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-Exchange-Antispam-Report-CFA-Test": "BCL:0; PCL:0;\n\tRULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(93006095)(93001095)(10201501046)(3002001)(3231355)(944501410)(52105095)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(201708071742011)(7699051)(76991095);\n\tSRVR:AM4PR05MB3426; BCL:0; PCL:0; RULEID:; SRVR:AM4PR05MB3426; ",
        "X-Forefront-PRVS": "08331F819E",
        "X-Forefront-Antispam-Report": "SFV:NSPM;\n\tSFS:(10009020)(376002)(346002)(136003)(366004)(39860400002)(396003)(189003)(199004)(97736004)(478600001)(186003)(386003)(5660300001)(106356001)(6346003)(4326008)(66066001)(81166006)(81156014)(16586007)(105586002)(7416002)(26005)(53936002)(55016002)(8886007)(48376002)(4720700003)(4744004)(68736007)(33026002)(50466002)(3846002)(7696005)(2906002)(14444005)(51416003)(486006)(107886003)(16526019)(36756003)(50226002)(6666004)(8676002)(316002)(446003)(52116002)(76176011)(8936002)(956004)(21086003)(69596002)(305945005)(7736002)(6116002)(25786009)(476003)(2616005)(47776003)(11346002)(86362001);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB3426; H:mellanox.com; FPR:;\n\tSPF:None; \n\tLANG:en; PTR:InfoNoRecords; MX:1; A:1; ",
        "Received-SPF": "None (protection.outlook.com: mellanox.com does not designate\n\tpermitted sender hosts)",
        "Authentication-Results": "spf=none (sender IP is )\n\tsmtp.mailfrom=orika@mellanox.com; ",
        "X-Microsoft-Antispam-Message-Info": "AbhIs/R11rbK0qL47exHppOBpZoVaRTlJMOMY/YWfmiWgv78zUp4g+rKVUdCmAjp4dtkGj4Cdx2GuJD+7a0whSqgQZQDVDw1EJspllivJI8cqaEab0X7Py1yzpk/93ry+cfxR4eZFPGdZF7wbEsgfimx5Xut8T+vSkmqbcTPE2hT4lg7JYCru5qDRDgWjhR2DoNwipG68GwfqKbgtHrWcJEx1/sOdaj6kLtkOll+BFdxRSs+iEnP/7v7vbPWq+4hUayDSI+YI6MOkLdABQSdJbE1ruT61eO7d+UFOJCCxZqPHgb62vZ9H6o7FK11xFlzj1+4IYuXdunSyVK4ZpjCbhGqlvDR5HhapZJ8PyXoiqg=",
        "SpamDiagnosticOutput": "1:99",
        "SpamDiagnosticMetadata": "NSPM",
        "X-OriginatorOrg": "Mellanox.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "22 Oct 2018 17:38:45.8769\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "3d29fa85-a56f-4cad-2569-08d638453891",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM4PR05MB3426",
        "Subject": "[dpdk-dev] [PATCH v6 3/3] app/testpmd: add MPLSoGRE encapsulation",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "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>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@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>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Example for MPLSoGRE tunnel:\nETH / IPV4 / GRE / MPLS / IP / L4..L7\n\nIn order to encapsulate such a tunnel there is a need to remove L2 of\nthe inner packet and encap the remaining tunnel, this is done by\napplying 2 rte flow commands l2_decap followed by mplsogre_encap.\nBoth commands must appear in the same flow, and from the point of the\npacket it both actions are applyed at the same time. (There is no part\nwhere a packet doesn't have L2 header).\n\nDecapsulating such a tunnel works the other way, first we need to decap\nthe outer tunnel header and then apply the new L2.\nSo the commands will be mplsogre_decap / l2_encap\n\nDue to the complex encapsulation of MPLSoGRE flow action and\nbased on the fact testpmd does not allocate memory, this patch adds a\nnew command in testpmd to initialise a global structure containing the\nnecessary information to make the outer layer of the packet.  This same\nglobal structures will then be used by the flow commands in testpmd when\nthe action mplsogre_encap, mplsogre_decap, will be parsed, at this point,\nthe conversion into such action becomes trivial.\n\nSigned-off-by: Ori Kam <orika@mellanox.com>\n\n---\nv6:\n * fix compilation issue.\n---\n app/test-pmd/cmdline.c                      | 227 ++++++++++++++++++++++++++\n app/test-pmd/cmdline_flow.c                 | 239 ++++++++++++++++++++++++++--\n app/test-pmd/testpmd.h                      |  22 +++\n doc/guides/testpmd_app_ug/testpmd_funcs.rst | 103 ++++++++++++\n 4 files changed, 580 insertions(+), 11 deletions(-)",
    "diff": "diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c\nindex e807dbb..6e14345 100644\n--- a/app/test-pmd/cmdline.c\n+++ b/app/test-pmd/cmdline.c\n@@ -15436,6 +15436,229 @@ static void cmd_set_l2_decap_parsed(void *parsed_result,\n \t},\n };\n \n+/** Set MPLSoGRE encapsulation details */\n+struct cmd_set_mplsogre_encap_result {\n+\tcmdline_fixed_string_t set;\n+\tcmdline_fixed_string_t mplsogre;\n+\tcmdline_fixed_string_t pos_token;\n+\tcmdline_fixed_string_t ip_version;\n+\tuint32_t vlan_present:1;\n+\tuint32_t label;\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_mplsogre_encap_set =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result, set,\n+\t\t\t\t \"set\");\n+cmdline_parse_token_string_t cmd_set_mplsogre_encap_mplsogre_encap =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result, mplsogre,\n+\t\t\t\t \"mplsogre_encap\");\n+cmdline_parse_token_string_t cmd_set_mplsogre_encap_mplsogre_encap_with_vlan =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t mplsogre, \"mplsogre_encap-with-vlan\");\n+cmdline_parse_token_string_t cmd_set_mplsogre_encap_ip_version =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t pos_token, \"ip-version\");\n+cmdline_parse_token_string_t cmd_set_mplsogre_encap_ip_version_value =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t ip_version, \"ipv4#ipv6\");\n+cmdline_parse_token_string_t cmd_set_mplsogre_encap_label =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t pos_token, \"label\");\n+cmdline_parse_token_num_t cmd_set_mplsogre_encap_label_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_mplsogre_encap_result, label,\n+\t\t\t      UINT32);\n+cmdline_parse_token_string_t cmd_set_mplsogre_encap_ip_src =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t pos_token, \"ip-src\");\n+cmdline_parse_token_ipaddr_t cmd_set_mplsogre_encap_ip_src_value =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_set_mplsogre_encap_result, ip_src);\n+cmdline_parse_token_string_t cmd_set_mplsogre_encap_ip_dst =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t pos_token, \"ip-dst\");\n+cmdline_parse_token_ipaddr_t cmd_set_mplsogre_encap_ip_dst_value =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_set_mplsogre_encap_result, ip_dst);\n+cmdline_parse_token_string_t cmd_set_mplsogre_encap_vlan =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t pos_token, \"vlan-tci\");\n+cmdline_parse_token_num_t cmd_set_mplsogre_encap_vlan_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_mplsogre_encap_result, tci,\n+\t\t\t      UINT16);\n+cmdline_parse_token_string_t cmd_set_mplsogre_encap_eth_src =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t pos_token, \"eth-src\");\n+cmdline_parse_token_etheraddr_t cmd_set_mplsogre_encap_eth_src_value =\n+\tTOKEN_ETHERADDR_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t    eth_src);\n+cmdline_parse_token_string_t cmd_set_mplsogre_encap_eth_dst =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t pos_token, \"eth-dst\");\n+cmdline_parse_token_etheraddr_t cmd_set_mplsogre_encap_eth_dst_value =\n+\tTOKEN_ETHERADDR_INITIALIZER(struct cmd_set_mplsogre_encap_result,\n+\t\t\t\t    eth_dst);\n+\n+static void cmd_set_mplsogre_encap_parsed(void *parsed_result,\n+\t__attribute__((unused)) struct cmdline *cl,\n+\t__attribute__((unused)) void *data)\n+{\n+\tstruct cmd_set_mplsogre_encap_result *res = parsed_result;\n+\tunion {\n+\t\tuint32_t mplsogre_label;\n+\t\tuint8_t label[3];\n+\t} id = {\n+\t\t.mplsogre_label =\n+\t\t\trte_cpu_to_be_32(res->label) & RTE_BE32(0x00ffffff),\n+\t};\n+\n+\tif (strcmp(res->mplsogre, \"mplsogre_encap\") == 0)\n+\t\tmplsogre_encap_conf.select_vlan = 0;\n+\telse if (strcmp(res->mplsogre, \"mplsogre_encap-with-vlan\") == 0)\n+\t\tmplsogre_encap_conf.select_vlan = 1;\n+\tif (strcmp(res->ip_version, \"ipv4\") == 0)\n+\t\tmplsogre_encap_conf.select_ipv4 = 1;\n+\telse if (strcmp(res->ip_version, \"ipv6\") == 0)\n+\t\tmplsogre_encap_conf.select_ipv4 = 0;\n+\telse\n+\t\treturn;\n+\trte_memcpy(mplsogre_encap_conf.label, &id.label[1], 3);\n+\tif (mplsogre_encap_conf.select_ipv4) {\n+\t\tIPV4_ADDR_TO_UINT(res->ip_src, mplsogre_encap_conf.ipv4_src);\n+\t\tIPV4_ADDR_TO_UINT(res->ip_dst, mplsogre_encap_conf.ipv4_dst);\n+\t} else {\n+\t\tIPV6_ADDR_TO_ARRAY(res->ip_src, mplsogre_encap_conf.ipv6_src);\n+\t\tIPV6_ADDR_TO_ARRAY(res->ip_dst, mplsogre_encap_conf.ipv6_dst);\n+\t}\n+\tif (mplsogre_encap_conf.select_vlan)\n+\t\tmplsogre_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci);\n+\trte_memcpy(mplsogre_encap_conf.eth_src, res->eth_src.addr_bytes,\n+\t\t   ETHER_ADDR_LEN);\n+\trte_memcpy(mplsogre_encap_conf.eth_dst, res->eth_dst.addr_bytes,\n+\t\t   ETHER_ADDR_LEN);\n+}\n+\n+cmdline_parse_inst_t cmd_set_mplsogre_encap = {\n+\t.f = cmd_set_mplsogre_encap_parsed,\n+\t.data = NULL,\n+\t.help_str = \"set mplsogre_encap ip-version ipv4|ipv6 label <label>\"\n+\t\t\" ip-src <ip-src> ip-dst <ip-dst> eth-src <eth-src>\"\n+\t\t\" eth-dst <eth-dst>\",\n+\t.tokens = {\n+\t\t(void *)&cmd_set_mplsogre_encap_set,\n+\t\t(void *)&cmd_set_mplsogre_encap_mplsogre_encap,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_version,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_version_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_label,\n+\t\t(void *)&cmd_set_mplsogre_encap_label_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_src,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_src_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_dst,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_dst_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_eth_src,\n+\t\t(void *)&cmd_set_mplsogre_encap_eth_src_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_eth_dst,\n+\t\t(void *)&cmd_set_mplsogre_encap_eth_dst_value,\n+\t\tNULL,\n+\t},\n+};\n+\n+cmdline_parse_inst_t cmd_set_mplsogre_encap_with_vlan = {\n+\t.f = cmd_set_mplsogre_encap_parsed,\n+\t.data = NULL,\n+\t.help_str = \"set mplsogre_encap-with-vlan ip-version ipv4|ipv6\"\n+\t\t\" label <label> ip-src <ip-src> ip-dst <ip-dst>\"\n+\t\t\" vlan-tci <vlan-tci> eth-src <eth-src> eth-dst <eth-dst>\",\n+\t.tokens = {\n+\t\t(void *)&cmd_set_mplsogre_encap_set,\n+\t\t(void *)&cmd_set_mplsogre_encap_mplsogre_encap_with_vlan,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_version,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_version_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_label,\n+\t\t(void *)&cmd_set_mplsogre_encap_label_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_src,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_src_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_dst,\n+\t\t(void *)&cmd_set_mplsogre_encap_ip_dst_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_vlan,\n+\t\t(void *)&cmd_set_mplsogre_encap_vlan_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_eth_src,\n+\t\t(void *)&cmd_set_mplsogre_encap_eth_src_value,\n+\t\t(void *)&cmd_set_mplsogre_encap_eth_dst,\n+\t\t(void *)&cmd_set_mplsogre_encap_eth_dst_value,\n+\t\tNULL,\n+\t},\n+};\n+\n+/** Set MPLSoGRE decapsulation details */\n+struct cmd_set_mplsogre_decap_result {\n+\tcmdline_fixed_string_t set;\n+\tcmdline_fixed_string_t mplsogre;\n+\tcmdline_fixed_string_t pos_token;\n+\tcmdline_fixed_string_t ip_version;\n+\tuint32_t vlan_present:1;\n+};\n+\n+cmdline_parse_token_string_t cmd_set_mplsogre_decap_set =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_decap_result, set,\n+\t\t\t\t \"set\");\n+cmdline_parse_token_string_t cmd_set_mplsogre_decap_mplsogre_decap =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_decap_result, mplsogre,\n+\t\t\t\t \"mplsogre_decap\");\n+cmdline_parse_token_string_t cmd_set_mplsogre_decap_mplsogre_decap_with_vlan =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_decap_result,\n+\t\t\t\t mplsogre, \"mplsogre_decap-with-vlan\");\n+cmdline_parse_token_string_t cmd_set_mplsogre_decap_ip_version =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_decap_result,\n+\t\t\t\t pos_token, \"ip-version\");\n+cmdline_parse_token_string_t cmd_set_mplsogre_decap_ip_version_value =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_decap_result,\n+\t\t\t\t ip_version, \"ipv4#ipv6\");\n+\n+static void cmd_set_mplsogre_decap_parsed(void *parsed_result,\n+\t__attribute__((unused)) struct cmdline *cl,\n+\t__attribute__((unused)) void *data)\n+{\n+\tstruct cmd_set_mplsogre_decap_result *res = parsed_result;\n+\n+\tif (strcmp(res->mplsogre, \"mplsogre_decap\") == 0)\n+\t\tmplsogre_decap_conf.select_vlan = 0;\n+\telse if (strcmp(res->mplsogre, \"mplsogre_decap-with-vlan\") == 0)\n+\t\tmplsogre_decap_conf.select_vlan = 1;\n+\tif (strcmp(res->ip_version, \"ipv4\") == 0)\n+\t\tmplsogre_decap_conf.select_ipv4 = 1;\n+\telse if (strcmp(res->ip_version, \"ipv6\") == 0)\n+\t\tmplsogre_decap_conf.select_ipv4 = 0;\n+}\n+\n+cmdline_parse_inst_t cmd_set_mplsogre_decap = {\n+\t.f = cmd_set_mplsogre_decap_parsed,\n+\t.data = NULL,\n+\t.help_str = \"set mplsogre_decap ip-version ipv4|ipv6\",\n+\t.tokens = {\n+\t\t(void *)&cmd_set_mplsogre_decap_set,\n+\t\t(void *)&cmd_set_mplsogre_decap_mplsogre_decap,\n+\t\t(void *)&cmd_set_mplsogre_decap_ip_version,\n+\t\t(void *)&cmd_set_mplsogre_decap_ip_version_value,\n+\t\tNULL,\n+\t},\n+};\n+\n+cmdline_parse_inst_t cmd_set_mplsogre_decap_with_vlan = {\n+\t.f = cmd_set_mplsogre_decap_parsed,\n+\t.data = NULL,\n+\t.help_str = \"set mplsogre_decap-with-vlan ip-version ipv4|ipv6\",\n+\t.tokens = {\n+\t\t(void *)&cmd_set_mplsogre_decap_set,\n+\t\t(void *)&cmd_set_mplsogre_decap_mplsogre_decap_with_vlan,\n+\t\t(void *)&cmd_set_mplsogre_decap_ip_version,\n+\t\t(void *)&cmd_set_mplsogre_decap_ip_version_value,\n+\t\tNULL,\n+\t},\n+};\n+\n /** Set MPLSoUDP encapsulation details */\n struct cmd_set_mplsoudp_encap_result {\n \tcmdline_fixed_string_t set;\n@@ -18317,6 +18540,10 @@ struct cmd_config_per_queue_tx_offload_result {\n \t(cmdline_parse_inst_t *)&cmd_set_l2_encap_with_vlan,\n \t(cmdline_parse_inst_t *)&cmd_set_l2_decap,\n \t(cmdline_parse_inst_t *)&cmd_set_l2_decap_with_vlan,\n+\t(cmdline_parse_inst_t *)&cmd_set_mplsogre_encap,\n+\t(cmdline_parse_inst_t *)&cmd_set_mplsogre_encap_with_vlan,\n+\t(cmdline_parse_inst_t *)&cmd_set_mplsogre_decap,\n+\t(cmdline_parse_inst_t *)&cmd_set_mplsogre_decap_with_vlan,\n \t(cmdline_parse_inst_t *)&cmd_set_mplsoudp_encap,\n \t(cmdline_parse_inst_t *)&cmd_set_mplsoudp_encap_with_vlan,\n \t(cmdline_parse_inst_t *)&cmd_set_mplsoudp_decap,\ndiff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c\nindex b876918..3d7d040 100644\n--- a/app/test-pmd/cmdline_flow.c\n+++ b/app/test-pmd/cmdline_flow.c\n@@ -245,6 +245,8 @@ enum index {\n \tACTION_NVGRE_DECAP,\n \tACTION_L2_ENCAP,\n \tACTION_L2_DECAP,\n+\tACTION_MPLSOGRE_ENCAP,\n+\tACTION_MPLSOGRE_DECAP,\n \tACTION_MPLSOUDP_ENCAP,\n \tACTION_MPLSOUDP_DECAP,\n \tACTION_SET_IPV4_SRC,\n@@ -851,6 +853,8 @@ struct parse_action_priv {\n \tACTION_NVGRE_DECAP,\n \tACTION_L2_ENCAP,\n \tACTION_L2_DECAP,\n+\tACTION_MPLSOGRE_ENCAP,\n+\tACTION_MPLSOGRE_DECAP,\n \tACTION_MPLSOUDP_ENCAP,\n \tACTION_MPLSOUDP_DECAP,\n \tACTION_SET_IPV4_SRC,\n@@ -1038,6 +1042,12 @@ static int parse_vc_action_l2_encap(struct context *, const struct token *,\n static int parse_vc_action_l2_decap(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_mplsogre_encap(struct context *,\n+\t\t\t\t\t  const struct token *, const char *,\n+\t\t\t\t\t  unsigned int, void *, unsigned int);\n+static int parse_vc_action_mplsogre_decap(struct context *,\n+\t\t\t\t\t  const struct token *, const char *,\n+\t\t\t\t\t  unsigned int, void *, unsigned int);\n static int parse_vc_action_mplsoudp_encap(struct context *,\n \t\t\t\t\t  const struct token *, const char *,\n \t\t\t\t\t  unsigned int, void *, unsigned int);\n@@ -2562,19 +2572,10 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,\n \t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),\n \t\t.call = parse_vc,\n \t},\n-\t[ACTION_MPLSOUDP_ENCAP] = {\n-\t\t.name = \"mplsoudp_encap\",\n-\t\t.help = \"mplsoudp encapsulation, uses configuration set by\"\n-\t\t\t\" \\\"set mplsoudp_encap\\\"\",\n-\t\t.priv = PRIV_ACTION(RAW_ENCAP,\n-\t\t\t\t    sizeof(struct action_raw_encap_data)),\n-\t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),\n-\t\t.call = parse_vc_action_mplsoudp_encap,\n-\t},\n \t[ACTION_L2_ENCAP] = {\n \t\t.name = \"l2_encap\",\n-\t\t.help = \"l2 encapsulation, uses configuration set by\"\n-\t\t\t\" \\\"set l2_encp\\\"\",\n+\t\t.help = \"l2 encap, uses configuration set by\"\n+\t\t\t\" \\\"set l2_encap\\\"\",\n \t\t.priv = PRIV_ACTION(RAW_ENCAP,\n \t\t\t\t    sizeof(struct action_raw_encap_data)),\n \t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),\n@@ -2589,6 +2590,33 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,\n \t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),\n \t\t.call = parse_vc_action_l2_decap,\n \t},\n+\t[ACTION_MPLSOGRE_ENCAP] = {\n+\t\t.name = \"mplsogre_encap\",\n+\t\t.help = \"mplsogre encapsulation, uses configuration set by\"\n+\t\t\t\" \\\"set mplsogre_encap\\\"\",\n+\t\t.priv = PRIV_ACTION(RAW_ENCAP,\n+\t\t\t\t    sizeof(struct action_raw_encap_data)),\n+\t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),\n+\t\t.call = parse_vc_action_mplsogre_encap,\n+\t},\n+\t[ACTION_MPLSOGRE_DECAP] = {\n+\t\t.name = \"mplsogre_decap\",\n+\t\t.help = \"mplsogre decapsulation, uses configuration set by\"\n+\t\t\t\" \\\"set mplsogre_decap\\\"\",\n+\t\t.priv = PRIV_ACTION(RAW_DECAP,\n+\t\t\t\t    sizeof(struct action_raw_decap_data)),\n+\t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),\n+\t\t.call = parse_vc_action_mplsogre_decap,\n+\t},\n+\t[ACTION_MPLSOUDP_ENCAP] = {\n+\t\t.name = \"mplsoudp_encap\",\n+\t\t.help = \"mplsoudp encapsulation, uses configuration set by\"\n+\t\t\t\" \\\"set mplsoudp_encap\\\"\",\n+\t\t.priv = PRIV_ACTION(RAW_ENCAP,\n+\t\t\t\t    sizeof(struct action_raw_encap_data)),\n+\t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),\n+\t\t.call = parse_vc_action_mplsoudp_encap,\n+\t},\n \t[ACTION_MPLSOUDP_DECAP] = {\n \t\t.name = \"mplsoudp_decap\",\n \t\t.help = \"mplsoudp decapsulation, uses configuration set by\"\n@@ -3579,6 +3607,195 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *,\n \treturn ret;\n }\n \n+#define ETHER_TYPE_MPLS_UNICAST 0x8847\n+\n+/** Parse MPLSOGRE encap action. */\n+static int\n+parse_vc_action_mplsogre_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_raw_encap_data *action_encap_data;\n+\tstruct rte_flow_item_eth eth = { .type = 0, };\n+\tstruct rte_flow_item_vlan vlan = {\n+\t\t.tci = mplsogre_encap_conf.vlan_tci,\n+\t\t.inner_type = 0,\n+\t};\n+\tstruct rte_flow_item_ipv4 ipv4 = {\n+\t\t.hdr =  {\n+\t\t\t.src_addr = mplsogre_encap_conf.ipv4_src,\n+\t\t\t.dst_addr = mplsogre_encap_conf.ipv4_dst,\n+\t\t\t.next_proto_id = IPPROTO_GRE,\n+\t\t},\n+\t};\n+\tstruct rte_flow_item_ipv6 ipv6 = {\n+\t\t.hdr =  {\n+\t\t\t.proto = IPPROTO_GRE,\n+\t\t},\n+\t};\n+\tstruct rte_flow_item_gre gre = {\n+\t\t.protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST),\n+\t};\n+\tstruct rte_flow_item_mpls mpls;\n+\tuint8_t *header;\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/* Copy the headers to the buffer. */\n+\taction_encap_data = ctx->object;\n+\t*action_encap_data = (struct action_raw_encap_data) {\n+\t\t.conf = (struct rte_flow_action_raw_encap){\n+\t\t\t.data = action_encap_data->data,\n+\t\t},\n+\t\t.data = {},\n+\t\t.preserve = {},\n+\t};\n+\theader = action_encap_data->data;\n+\tif (mplsogre_encap_conf.select_vlan)\n+\t\teth.type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);\n+\telse if (mplsogre_encap_conf.select_ipv4)\n+\t\teth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);\n+\telse\n+\t\teth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);\n+\tmemcpy(eth.dst.addr_bytes,\n+\t       mplsogre_encap_conf.eth_dst, ETHER_ADDR_LEN);\n+\tmemcpy(eth.src.addr_bytes,\n+\t       mplsogre_encap_conf.eth_src, ETHER_ADDR_LEN);\n+\tmemcpy(header, &eth, sizeof(eth));\n+\theader += sizeof(eth);\n+\tif (mplsogre_encap_conf.select_vlan) {\n+\t\tif (mplsogre_encap_conf.select_ipv4)\n+\t\t\tvlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);\n+\t\telse\n+\t\t\tvlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);\n+\t\tmemcpy(header, &vlan, sizeof(vlan));\n+\t\theader += sizeof(vlan);\n+\t}\n+\tif (mplsogre_encap_conf.select_ipv4) {\n+\t\tmemcpy(header, &ipv4, sizeof(ipv4));\n+\t\theader += sizeof(ipv4);\n+\t} else {\n+\t\tmemcpy(&ipv6.hdr.src_addr,\n+\t\t       &mplsogre_encap_conf.ipv6_src,\n+\t\t       sizeof(mplsogre_encap_conf.ipv6_src));\n+\t\tmemcpy(&ipv6.hdr.dst_addr,\n+\t\t       &mplsogre_encap_conf.ipv6_dst,\n+\t\t       sizeof(mplsogre_encap_conf.ipv6_dst));\n+\t\tmemcpy(header, &ipv6, sizeof(ipv6));\n+\t\theader += sizeof(ipv6);\n+\t}\n+\tmemcpy(header, &gre, sizeof(gre));\n+\theader += sizeof(gre);\n+\tmemcpy(mpls.label_tc_s, mplsogre_encap_conf.label,\n+\t       RTE_DIM(mplsogre_encap_conf.label));\n+\tmemcpy(header, &mpls, sizeof(mpls));\n+\theader += sizeof(mpls);\n+\taction_encap_data->conf.size = header -\n+\t\taction_encap_data->data;\n+\taction->conf = &action_encap_data->conf;\n+\treturn ret;\n+}\n+\n+/** Parse MPLSOGRE decap action. */\n+static int\n+parse_vc_action_mplsogre_decap(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_raw_decap_data *action_decap_data;\n+\tstruct rte_flow_item_eth eth = { .type = 0, };\n+\tstruct rte_flow_item_vlan vlan = {.tci = 0};\n+\tstruct rte_flow_item_ipv4 ipv4 = {\n+\t\t.hdr =  {\n+\t\t\t.next_proto_id = IPPROTO_GRE,\n+\t\t},\n+\t};\n+\tstruct rte_flow_item_ipv6 ipv6 = {\n+\t\t.hdr =  {\n+\t\t\t.proto = IPPROTO_GRE,\n+\t\t},\n+\t};\n+\tstruct rte_flow_item_gre gre = {\n+\t\t.protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST),\n+\t};\n+\tstruct rte_flow_item_mpls mpls;\n+\tuint8_t *header;\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/* Copy the headers to the buffer. */\n+\taction_decap_data = ctx->object;\n+\t*action_decap_data = (struct action_raw_decap_data) {\n+\t\t.conf = (struct rte_flow_action_raw_decap){\n+\t\t\t.data = action_decap_data->data,\n+\t\t},\n+\t\t.data = {},\n+\t};\n+\theader = action_decap_data->data;\n+\tif (mplsogre_decap_conf.select_vlan)\n+\t\teth.type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);\n+\telse if (mplsogre_encap_conf.select_ipv4)\n+\t\teth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);\n+\telse\n+\t\teth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);\n+\tmemcpy(eth.dst.addr_bytes,\n+\t       mplsogre_encap_conf.eth_dst, ETHER_ADDR_LEN);\n+\tmemcpy(eth.src.addr_bytes,\n+\t       mplsogre_encap_conf.eth_src, ETHER_ADDR_LEN);\n+\tmemcpy(header, &eth, sizeof(eth));\n+\theader += sizeof(eth);\n+\tif (mplsogre_encap_conf.select_vlan) {\n+\t\tif (mplsogre_encap_conf.select_ipv4)\n+\t\t\tvlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);\n+\t\telse\n+\t\t\tvlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);\n+\t\tmemcpy(header, &vlan, sizeof(vlan));\n+\t\theader += sizeof(vlan);\n+\t}\n+\tif (mplsogre_encap_conf.select_ipv4) {\n+\t\tmemcpy(header, &ipv4, sizeof(ipv4));\n+\t\theader += sizeof(ipv4);\n+\t} else {\n+\t\tmemcpy(header, &ipv6, sizeof(ipv6));\n+\t\theader += sizeof(ipv6);\n+\t}\n+\tmemcpy(header, &gre, sizeof(gre));\n+\theader += sizeof(gre);\n+\tmemset(&mpls, 0, sizeof(mpls));\n+\tmemcpy(header, &mpls, sizeof(mpls));\n+\theader += sizeof(mpls);\n+\taction_decap_data->conf.size = header -\n+\t\taction_decap_data->data;\n+\taction->conf = &action_decap_data->conf;\n+\treturn ret;\n+}\n+\n /** Parse MPLSOUDP encap action. */\n static int\n parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token,\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex 12daee5..0738105 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -523,6 +523,28 @@ struct l2_decap_conf {\n };\n struct l2_decap_conf l2_decap_conf;\n \n+/* MPLSoGRE encap parameters. */\n+struct mplsogre_encap_conf {\n+\tuint32_t select_ipv4:1;\n+\tuint32_t select_vlan:1;\n+\tuint8_t label[3];\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 mplsogre_encap_conf mplsogre_encap_conf;\n+\n+/* MPLSoGRE decap parameters. */\n+struct mplsogre_decap_conf {\n+\tuint32_t select_ipv4:1;\n+\tuint32_t select_vlan:1;\n+};\n+struct mplsogre_decap_conf mplsogre_decap_conf;\n+\n /* MPLSoUDP encap parameters. */\n struct mplsoudp_encap_conf {\n \tuint32_t select_ipv4:1;\ndiff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst\nindex fb26315..8d60bf0 100644\n--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst\n+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst\n@@ -1607,6 +1607,35 @@ flow rule using the action l2_decap 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+Config MPLSoGRE Encap outer layers\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+Configure the outer layer to encapsulate a packet inside a MPLSoGRE tunnel::\n+\n+ set mplsogre_encap ip-version (ipv4|ipv6) label (label) \\\n+        ip-src (ip-src) ip-dst (ip-dst) eth-src (eth-src) eth-dst (eth-dst)\n+ set mplsogre_encap-with-vlan ip-version (ipv4|ipv6) label (label) \\\n+        ip-src (ip-src) ip-dst (ip-dst) vlan-tci (vlan-tci) \\\n+        eth-src (eth-src) eth-dst (eth-dst)\n+\n+Those command will set an internal configuration inside testpmd, any following\n+flow rule using the action mplsogre_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+Config MPLSoGRE Decap outer layers\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+Configure the outer layer to decapsulate MPLSoGRE packet::\n+\n+ set mplsogre_decap ip-version (ipv4|ipv6)\n+ set mplsogre_decap-with-vlan ip-version (ipv4|ipv6)\n+\n+Those command will set an internal configuration inside testpmd, any following\n+flow rule using the action mplsogre_decap will use the last configuration set.\n+To have a different decapsulation header, one of those commands must be called\n+before the flow rule creation.\n+\n Config MPLSoUDP Encap outer layers\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n \n@@ -3834,6 +3863,12 @@ This section lists supported actions and their attributes, if any.\n - ``l2_decap``: Performs a L2 decapsulation, L2 configuration\n   is done through `Config L2 Decap`_.\n \n+- ``mplsogre_encap``: Performs a MPLSoGRE encapsulation, outer layer\n+  configuration is done through `Config MPLSoGRE Encap outer layers`_.\n+\n+- ``mplsogre_decap``: Performs a MPLSoGRE decapsulation, outer layer\n+  configuration is done through `Config MPLSoGRE Decap outer layers`_.\n+\n - ``mplsoudp_encap``: Performs a MPLSoUDP encapsulation, outer layer\n   configuration is done through `Config MPLSoUDP Encap outer layers`_.\n \n@@ -4237,6 +4272,74 @@ L2 with VXLAN header::\n  testpmd> flow create 0 egress pattern eth / end actions l2_encap / mplsoudp_encap /\n          queue index 0 / end\n \n+Sample MPLSoGRE encapsulation rule\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+MPLSoGRE 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 MPLSoGRE outer header::\n+\n+ testpmd> set mplsogre_encap ip-version ipv4 label 4\n+        ip-src 127.0.0.1 ip-dst 128.0.0.1 eth-src 11:11:11:11:11:11\n+        eth-dst 22:22:22:22:22:22\n+ testpmd> flow create 0 egress pattern eth / end actions l2_decap /\n+        mplsogre_encap / end\n+\n+IPv4 MPLSoGRE with VLAN outer header::\n+\n+ testpmd> set mplsogre_encap-with-vlan ip-version ipv4 label 4\n+        ip-src 127.0.0.1 ip-dst 128.0.0.1 vlan-tci 34\n+        eth-src 11:11:11:11:11:11 eth-dst 22:22:22:22:22:22\n+ testpmd> flow create 0 egress pattern eth / end actions l2_decap /\n+        mplsogre_encap / end\n+\n+IPv6 MPLSoGRE outer header::\n+\n+ testpmd> set mplsogre_encap ip-version ipv6 mask 4\n+        ip-src ::1 ip-dst ::2222 eth-src 11:11:11:11:11:11\n+        eth-dst 22:22:22:22:22:22\n+ testpmd> flow create 0 egress pattern eth / end actions l2_decap /\n+        mplsogre_encap / end\n+\n+IPv6 MPLSoGRE with VLAN outer header::\n+\n+ testpmd> set mplsogre_encap-with-vlan ip-version ipv6 mask 4\n+        ip-src ::1 ip-dst ::2222 vlan-tci 34\n+        eth-src 11:11:11:11:11:11 eth-dst 22:22:22:22:22:22\n+ testpmd> flow create 0 egress pattern eth / end actions l2_decap /\n+        mplsogre_encap / end\n+\n+Sample MPLSoGRE decapsulation rule\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+MPLSoGRE decapsulation outer layer has default value pre-configured in testpmd\n+source code, those can be changed by using the following commands\n+\n+IPv4 MPLSoGRE outer header::\n+\n+ testpmd> set mplsogre_decap ip-version ipv4\n+ testpmd> flow create 0 ingress pattern eth / ipv4 / gre / mpls / end actions\n+        mplsogre_decap / l2_encap / end\n+\n+IPv4 MPLSoGRE with VLAN outer header::\n+\n+ testpmd> set mplsogre_decap-with-vlan ip-version ipv4\n+ testpmd> flow create 0 ingress pattern eth / vlan / ipv4 / gre / mpls / end\n+        actions mplsogre_decap / l2_encap / end\n+\n+IPv6 MPLSoGRE outer header::\n+\n+ testpmd> set mplsogre_decap ip-version ipv6\n+ testpmd> flow create 0 ingress pattern eth / ipv6 / gre / mpls / end\n+        actions mplsogre_decap / l2_encap / end\n+\n+IPv6 MPLSoGRE with VLAN outer header::\n+\n+ testpmd> set mplsogre_decap-with-vlan ip-version ipv6\n+ testpmd> flow create 0 ingress pattern eth / vlan / ipv6 / gre / mpls / end\n+        actions mplsogre_decap / l2_encap / end\n+\n Sample MPLSoUDP encapsulation rule\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n \n",
    "prefixes": [
        "v6",
        "3/3"
    ]
}