get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 119063,
    "url": "http://patches.dpdk.org/api/patches/119063/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20221025075918.7778-9-chaoyong.he@corigine.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<20221025075918.7778-9-chaoyong.he@corigine.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20221025075918.7778-9-chaoyong.he@corigine.com",
    "date": "2022-10-25T07:59:00",
    "name": "[v3,08/26] net/nfp: prepare for IPv4 UDP tunnel decap flow action",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "91ae4b96e2dbc35552827b69faa5e5c1c39dd198",
    "submitter": {
        "id": 2554,
        "url": "http://patches.dpdk.org/api/people/2554/?format=api",
        "name": "Chaoyong He",
        "email": "chaoyong.he@corigine.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20221025075918.7778-9-chaoyong.he@corigine.com/mbox/",
    "series": [
        {
            "id": 25411,
            "url": "http://patches.dpdk.org/api/series/25411/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=25411",
            "date": "2022-10-25T07:58:52",
            "name": "add the extend rte_flow offload support of nfp PMD",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/25411/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/119063/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/119063/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 9F922A0543;\n\tTue, 25 Oct 2022 10:01:05 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id BB4FB42BF9;\n\tTue, 25 Oct 2022 10:00:12 +0200 (CEST)",
            "from NAM11-DM6-obe.outbound.protection.outlook.com\n (mail-dm6nam11on2134.outbound.protection.outlook.com [40.107.223.134])\n by mails.dpdk.org (Postfix) with ESMTP id 097BE42B95\n for <dev@dpdk.org>; Tue, 25 Oct 2022 10:00:10 +0200 (CEST)",
            "from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5)\n by BY5PR13MB4405.namprd13.prod.outlook.com (2603:10b6:a03:1d4::9)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5746.28; Tue, 25 Oct\n 2022 08:00:08 +0000",
            "from SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::7c26:1a0b:2825:6f4b]) by SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::7c26:1a0b:2825:6f4b%4]) with mapi id 15.20.5723.014; Tue, 25 Oct 2022\n 08:00:08 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=jRqh+1UmvUE8xmXQU4mkn8mw+bcqyKklC2mNI9l0TTlLiJLZOp7Ek5/Nmxj2gU9JHW/voNEnc4PhHi+wQ4rXK1XCU/jAd0Ov7MnTTPvePGUIvViRDq4vc8pdHhrjcw7PF5F3JvQD8Ybu0k7C0MBZa/NWhQStfh/NG1xlsTcq2BaNn4gyn45x3wpLh6VApXIjv6yb2kY/E/8bnRFEcYizYy3BWmS13lQcvueTGyEQk5T14az9kRSNYoXNAbn9PncLqOi6nV3IujCBv+Ng5vp7i4qfIGS4ZRPmOy1snPsUcftijAuomeJyvKkqaFauoJgUsBUyt9TIvR0kZ7sL48jvAw==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=puotpMiM7pCnDtHyDCMlyhT/P4hwQb830if8nzxODvk=;\n b=DAQ7vtSCyJYLJskVkwtbe/NN1XZcohnchdD2tP8/oWhM1S4wxvxF1cfRb8/W64hz+g1xV/oWD+8ZY1RHlO/cM2zrrqwCJSkC5YCsRzB1MmytgyjP8hz93qwtd3wj2zJ2gnLhCqbw8iLbbcTb9pDzjxLwHSLvcjqoLT47arZvidrN3XLb2rdj3Q5/IJWEne3SpnRNiMnw/YxXNYqFnD+kRF9X35iPKhq6dcTBVVTtI+mM7ioVGSQTtVaUST/HJFY/shjKfFa1cb7FDCRaTBR5EHJsJZsgjTzwsdB10VR48WK+imjV+rKw8ezm0oMWEcrPmsWkBCLJAfnM/QSGkfbaDA==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com;\n dkim=pass header.d=corigine.com; arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=puotpMiM7pCnDtHyDCMlyhT/P4hwQb830if8nzxODvk=;\n b=q91o0QqfXsGz/LaAYb5aYMwREnGEsRu/h4w8xPYj9AqH3qJwICQ4thrXtcz5BTBh7Kd4gZwtPVisKoJ1ig4kln7GjuspsRFaSCdqtXrEhQmpRZEvtWs63nVO/HwwbSoZD0H3lPnSVzqgfYtR71Z46wvhxsh63/GWjyHUzqMAcQ8=",
        "Authentication-Results": "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=corigine.com;",
        "From": "Chaoyong He <chaoyong.he@corigine.com>",
        "To": "dev@dpdk.org",
        "Cc": "oss-drivers@corigine.com, niklas.soderlund@corigine.com,\n Chaoyong He <chaoyong.he@corigine.com>",
        "Subject": "[PATCH v3 08/26] net/nfp: prepare for IPv4 UDP tunnel decap flow\n action",
        "Date": "Tue, 25 Oct 2022 15:59:00 +0800",
        "Message-Id": "<20221025075918.7778-9-chaoyong.he@corigine.com>",
        "X-Mailer": "git-send-email 2.29.3",
        "In-Reply-To": "<20221025075918.7778-1-chaoyong.he@corigine.com>",
        "References": "<1666427069-10553-1-git-send-email-chaoyong.he@corigine.com>\n <20221025075918.7778-1-chaoyong.he@corigine.com>",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "X-ClientProxiedBy": "SG2PR01CA0142.apcprd01.prod.exchangelabs.com\n (2603:1096:4:8f::22) To SJ0PR13MB5545.namprd13.prod.outlook.com\n (2603:10b6:a03:424::5)",
        "MIME-Version": "1.0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "SJ0PR13MB5545:EE_|BY5PR13MB4405:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "784c54d2-c419-45ed-1f1e-08dab65eeed4",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n 5svVzXuTq0tpfSh16+0N3DIvFL5XuNIgEWO6MJtXDXDLDFdxDQdXziHZqBGn6V/Y/C369KpBfJns74WryEb7wpAjTA3PyjpgYzrxbfCJagkwsEl99rX6G+mJcYj/kmM6ULy4W0hbnsarUAeVo/5waeFUgc59rGkOtHQbjxWKs5PteYbjqjf4kesoh2hjj7+541zOuOZT2xDKzJ/xAL+I/D8j0l/i2pFtJqLb4lAiFe0wrtnmE1SmAd4hKTcHiu68iR/necOE7bNZyR33lDECIv7Rv4D2y5h3W2z1tP5zCjvwrRpBWNEDm8rnRVlubZCPADcvWZthI8f3KyonagC+Kydn8arYtFZ2NKSzoAscPR3T5NhskoTsYlIf4RCwLHgXAfaJ25fN5l3V92JM2B+6QBTo0fA4HIVVDd4g0OUH55VgqWZ6cZmRWRpXIhF+Dsv/ZQVsHgprmux2ufPUebYj8nPADy05i9XTgxFWFObtVSvAt1ns+2IpfdlVohcHdbxT/+MxX7WEOhMaiEJ8v384HiwUR1RLTw6YSOjJP3ja3/4llHn2g9e/u07L4hdwE0mElmFgniwK/9t2mgmuCbYedi4Zdj1tD0/GjFFkYZvz025/U4NPCvrmC/NhN2gHf1Ac20aJ0Njf8o4OUDnPkNNb38Q5kUISrxYGgEJRawFw8UkYXigaBk4jqzST+jXTCkdGsIIfCs/GdaNU0AlQD9fFPP4eJqXYqtXr17K4s0gE+T+OwiB/CHgnR8W60rvjHtGW59YLZ0SlUbiWCREilH1/7w==",
        "X-Forefront-Antispam-Report": "CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:SJ0PR13MB5545.namprd13.prod.outlook.com; PTR:; CAT:NONE;\n SFS:(13230022)(4636009)(39830400003)(346002)(136003)(376002)(366004)(396003)(451199015)(36756003)(6486002)(5660300002)(30864003)(66946007)(66476007)(8936002)(38350700002)(38100700002)(66556008)(83380400001)(66574015)(86362001)(44832011)(6916009)(2616005)(26005)(107886003)(186003)(6512007)(1076003)(316002)(478600001)(52116002)(8676002)(41300700001)(4326008)(2906002)(6506007)(6666004);\n DIR:OUT; SFP:1102;",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-MessageData-0": "=?utf-8?q?PQ4G0SeMTdIb5FeGqURPBo43GJGt?=\n\t=?utf-8?q?RABsKuO5PHXGZSEMC4uTa9FczHvD/6kReFAnLjFZs757rUpvkr9bvywdYNwt/1o5i?=\n\t=?utf-8?q?ewHmj0MApZc6LRdmNESv/Ej6wOxYtSvfptcD440kuRMe2rLWESXXIKA5ADpjJbnyP?=\n\t=?utf-8?q?Pivnhjv7jlOR6HN8Wr4V9T0zdx0gC7NbaTeBCaP5C/5nhau/98yS/I5EjFIeEQOVt?=\n\t=?utf-8?q?FdXMCJ/T6Rk8mdClxWZJPwf8x6Kt4Ex0RUYB3e25WW4azo6i8hmWgXv7Se9eDHMiQ?=\n\t=?utf-8?q?+g5AGiPwhUux9vZymYrXswr1SJjp1a3wPzLH4awC5/nao9uXQ8ps0MWpr4RTYZZ+u?=\n\t=?utf-8?q?K7RDVkklJYnL4ecqU4m0+6PgKGNWBMH42P8sYr1+9/sJys5IS6zv4I/IsyEcwU8n8?=\n\t=?utf-8?q?R3N+g8fH8oWOLSVjX1eShCHQnvrmwZElhBx+lK+XXHH3eT5R6RR0eahVwxwcMbAhq?=\n\t=?utf-8?q?q9ENAuUJCy38c0QqXWa36C3kVbu7ePqXSR8id2x0GbpsmbR0pJLQ6bZzLFABrRteC?=\n\t=?utf-8?q?EvY0CwutE7Y9ZjhQdY1GO76n/RTrbXPP/FcWcwOK5g602lI7HnJuwHhOgxEX4aHO7?=\n\t=?utf-8?q?l/VsfdgW86RY6KqFmAivjCPypywl/x36Dw4ATb/UmvBX9MxSOhVySHJ7oo1ymmdb+?=\n\t=?utf-8?q?zqAgCbCA86a2+59Shyd5RcT/zU0DFUx9kkkWGQ0g+jYKt8xxDyVslffbl6aWR8AxA?=\n\t=?utf-8?q?asjP7I8JHm0gOFNalKkICz2B0XqyLBYNmveDT3tbtSXnJ8qOuP5iPj1LNOA6aeWRF?=\n\t=?utf-8?q?vrVI0Db5s+TU1tDrkSwSesBbS3wpAzFMQ/EBL5Ns/y1mkujHscFKJaISMzRHssj7u?=\n\t=?utf-8?q?n98tnX0omBu+CpXdesa32EcsRo/liHQxorXjnBpwUUxJOFV5TsOGc9jOArkAUpBNF?=\n\t=?utf-8?q?TWq2DH51cTQDNf8joKWEY523CKeLHI+8jVNbaOGvQXJemFCovpcuDuTDYRjykiXOH?=\n\t=?utf-8?q?9jl4l5DeB1y5wB9SvT0EUoVgTB8vhahJTWG2QzSw5lEXYbzgR68F3S3F1rAJCccfs?=\n\t=?utf-8?q?PPqk8dhZYRovxZmZ1FTNER+2E9EW+1sXR3tSThXwvOFr7zJMtn/tVIyTnv9LaiVs2?=\n\t=?utf-8?q?0atq3AfZQnN7Zbuhsf+44uhSauLpI3binr/6ucnDGWjdGdYFHGsP+5GWnN3rmlfZX?=\n\t=?utf-8?q?y7WDpjY+XsMdHCFOoFse++l+gPXUeHlNI9xBY/0ahhM+YBIITzx9cwgHAcp+eXCNT?=\n\t=?utf-8?q?EXXgcL6fYceZ+3Ym/CMbI736aPOKXeXsiDPk2V/yo2co2izdlbF4oiEiWn/KtcKQq?=\n\t=?utf-8?q?kLWSuw4OVZR9Jeh/WhEec971nz+BCk8zs//CcmqYXH5QhsCGGZq6dF2gMUv2VkFgv?=\n\t=?utf-8?q?ByxhsPIbSKj/Uw7TpyQwd84Tq2Xs6qvJR5IzOrFLBWl19khtOdmoaOTDAk/qnDHX+?=\n\t=?utf-8?q?UA6o8OVv+KPo73GwlHIRSJbKUe6P1xdoSEdQeJJps6GeU9hpR+5v968+Z19YxjT+y?=\n\t=?utf-8?q?gaG7bPDuzMiaEB0EXxNqy/GnRc+bqwQ/StmkfRj3o6nGiRlOSERYYjBFMAFhx7e83?=\n\t=?utf-8?q?eaoVaCk7mLCa/On3IWNtyxnHvPdEuMkxNQ=3D=3D?=",
        "X-OriginatorOrg": "corigine.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 784c54d2-c419-45ed-1f1e-08dab65eeed4",
        "X-MS-Exchange-CrossTenant-AuthSource": "SJ0PR13MB5545.namprd13.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "25 Oct 2022 08:00:08.0172 (UTC)",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "fe128f2c-073b-4c20-818e-7246a585940c",
        "X-MS-Exchange-CrossTenant-MailboxType": "HOSTED",
        "X-MS-Exchange-CrossTenant-UserPrincipalName": "\n t5VtinIwaj9aFFdlfFU+Aq9FaVLV9y3vKC0QX6PoaxqxPp7gu5dsGGsafRc1aeCT1e5XKYggSvT49PHPv4FRIhiQ/QLPXhsb52ml6nH3DcI=",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "BY5PR13MB4405",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "Add the related data structure and functions, prepare for\nthe decap action of IPv4 UDP tunnel.\n\nSigned-off-by: Chaoyong He <chaoyong.he@corigine.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>\n---\n doc/guides/nics/features/nfp.ini         |   1 +\n drivers/net/nfp/flower/nfp_flower_cmsg.c | 118 ++++++\n drivers/net/nfp/flower/nfp_flower_cmsg.h |  94 +++++\n drivers/net/nfp/nfp_flow.c               | 461 ++++++++++++++++++++++-\n drivers/net/nfp/nfp_flow.h               |  17 +\n 5 files changed, 676 insertions(+), 15 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini\nindex ff97787bd9..5ccfd61336 100644\n--- a/doc/guides/nics/features/nfp.ini\n+++ b/doc/guides/nics/features/nfp.ini\n@@ -40,6 +40,7 @@ vxlan                = Y\n [rte_flow actions]\n count                = Y\n drop                 = Y\n+jump                 = Y\n of_pop_vlan          = Y\n of_push_vlan         = Y\n of_set_vlan_pcp      = Y\ndiff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.c b/drivers/net/nfp/flower/nfp_flower_cmsg.c\nindex 8983178378..f18f3de042 100644\n--- a/drivers/net/nfp/flower/nfp_flower_cmsg.c\n+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.c\n@@ -304,3 +304,121 @@ nfp_flower_cmsg_tun_neigh_v6_rule(struct nfp_app_fw_flower *app_fw_flower,\n \n \treturn 0;\n }\n+\n+int\n+nfp_flower_cmsg_tun_off_v4(struct nfp_app_fw_flower *app_fw_flower)\n+{\n+\tuint16_t cnt;\n+\tuint32_t count = 0;\n+\tstruct rte_mbuf *mbuf;\n+\tstruct nfp_flow_priv *priv;\n+\tstruct nfp_ipv4_addr_entry *entry;\n+\tstruct nfp_flower_cmsg_tun_ipv4_addr *msg;\n+\n+\tmbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);\n+\tif (mbuf == NULL) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Failed to alloc mbuf for v4 tun addr\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tmsg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_TUN_IPS, sizeof(*msg));\n+\n+\tpriv = app_fw_flower->flow_priv;\n+\trte_spinlock_lock(&priv->ipv4_off_lock);\n+\tLIST_FOREACH(entry, &priv->ipv4_off_list, next) {\n+\t\tif (count >= NFP_FL_IPV4_ADDRS_MAX) {\n+\t\t\trte_spinlock_unlock(&priv->ipv4_off_lock);\n+\t\t\tPMD_DRV_LOG(ERR, \"IPv4 offload exceeds limit.\");\n+\t\t\treturn -ERANGE;\n+\t\t}\n+\t\tmsg->ipv4_addr[count] = entry->ipv4_addr;\n+\t\tcount++;\n+\t}\n+\tmsg->count = rte_cpu_to_be_32(count);\n+\trte_spinlock_unlock(&priv->ipv4_off_lock);\n+\n+\tcnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);\n+\tif (cnt == 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Send cmsg through ctrl vnic failed.\");\n+\t\trte_pktmbuf_free(mbuf);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+nfp_flower_cmsg_pre_tunnel_rule(struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct nfp_fl_rule_metadata *nfp_flow_meta,\n+\t\tuint16_t mac_idx,\n+\t\tbool is_del)\n+{\n+\tuint16_t cnt;\n+\tstruct rte_mbuf *mbuf;\n+\tstruct nfp_flower_meta_tci *meta_tci;\n+\tstruct nfp_flower_cmsg_pre_tun_rule *msg;\n+\n+\tmbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);\n+\tif (mbuf == NULL) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Failed to alloc mbuf for pre tunnel rule\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tmsg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE, sizeof(*msg));\n+\n+\tmeta_tci = (struct nfp_flower_meta_tci *)((char *)nfp_flow_meta +\n+\t\t\tsizeof(struct nfp_fl_rule_metadata));\n+\tif (meta_tci->tci)\n+\t\tmsg->vlan_tci = meta_tci->tci;\n+\telse\n+\t\tmsg->vlan_tci = 0xffff;\n+\n+\tif (is_del)\n+\t\tmsg->flags = rte_cpu_to_be_32(NFP_TUN_PRE_TUN_RULE_DEL);\n+\n+\tmsg->port_idx = rte_cpu_to_be_16(mac_idx);\n+\tmsg->host_ctx_id = nfp_flow_meta->host_ctx_id;\n+\n+\tcnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);\n+\tif (cnt == 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Send cmsg through ctrl vnic failed.\");\n+\t\trte_pktmbuf_free(mbuf);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+nfp_flower_cmsg_tun_mac_rule(struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct rte_ether_addr *mac,\n+\t\tuint16_t mac_idx,\n+\t\tbool is_del)\n+{\n+\tuint16_t cnt;\n+\tstruct rte_mbuf *mbuf;\n+\tstruct nfp_flower_cmsg_tun_mac *msg;\n+\n+\tmbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);\n+\tif (mbuf == NULL) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Failed to alloc mbuf for tunnel mac\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tmsg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_TUN_MAC, sizeof(*msg));\n+\n+\tmsg->count = rte_cpu_to_be_16(1);\n+\tmsg->index = rte_cpu_to_be_16(mac_idx);\n+\trte_ether_addr_copy(mac, &msg->addr);\n+\tif (is_del)\n+\t\tmsg->flags = rte_cpu_to_be_16(NFP_TUN_MAC_OFFLOAD_DEL_FLAG);\n+\n+\tcnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);\n+\tif (cnt == 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Send cmsg through ctrl vnic failed.\");\n+\t\trte_pktmbuf_free(mbuf);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h\nindex d1e0562cf9..0933dacfb1 100644\n--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h\n+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h\n@@ -195,6 +195,91 @@ struct nfp_flower_cmsg_tun_neigh_v6 {\n \tstruct nfp_flower_tun_neigh common;\n };\n \n+#define NFP_TUN_PRE_TUN_RULE_DEL    (1 << 0)\n+#define NFP_TUN_PRE_TUN_IDX_BIT     (1 << 3)\n+#define NFP_TUN_PRE_TUN_IPV6_BIT    (1 << 7)\n+\n+/*\n+ * NFP_FLOWER_CMSG_TYPE_PRE_TUN_RULE\n+ * Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0\n+ * -----\\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ *       +---------------------------------------------------------------+\n+ *     0 |                             FLAGS                             |\n+ *       +---------------------------------------------------------------+\n+ *     1 |         MAC_IDX               |            VLAN_ID            |\n+ *       +---------------------------------------------------------------+\n+ *     2 |                           HOST_CTX                            |\n+ *       +---------------------------------------------------------------+\n+ */\n+struct nfp_flower_cmsg_pre_tun_rule {\n+\trte_be32_t flags;\n+\trte_be16_t port_idx;\n+\trte_be16_t vlan_tci;\n+\trte_be32_t host_ctx_id;\n+};\n+\n+#define NFP_TUN_MAC_OFFLOAD_DEL_FLAG  0x2\n+\n+/*\n+ * NFP_FLOWER_CMSG_TYPE_TUN_MAC\n+ *     Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0\n+ *    -----\\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ *    Word  +-----------------------+---+-+-+---------------+---------------+\n+ *       0  |              spare    |NBI|D|F| Amount of MAC’s in this msg   |\n+ *          +---------------+-------+---+-+-+---------------+---------------+\n+ *       1  |            Index 0            |     MAC[0]    |     MAC[1]    |\n+ *          +---------------+---------------+---------------+---------------+\n+ *       2  |     MAC[2]    |     MAC[3]    |     MAC[4]    |     MAC[5]    |\n+ *          +---------------+---------------+---------------+---------------+\n+ *       3  |            Index 1            |     MAC[0]    |     MAC[1]    |\n+ *          +---------------+---------------+---------------+---------------+\n+ *       4  |     MAC[2]    |     MAC[3]    |     MAC[4]    |     MAC[5]    |\n+ *          +---------------+---------------+---------------+---------------+\n+ *                                        ...\n+ *          +---------------+---------------+---------------+---------------+\n+ *     2N-1 |            Index N            |     MAC[0]    |     MAC[1]    |\n+ *          +---------------+---------------+---------------+---------------+\n+ *     2N   |     MAC[2]    |     MAC[3]    |     MAC[4]    |     MAC[5]    |\n+ *          +---------------+---------------+---------------+---------------+\n+ *\n+ *    F:   Flush bit. Set if entire table must be flushed. Rest of info in cmsg\n+ *        will be ignored. Not implemented.\n+ *    D:   Delete bit. Set if entry must be deleted instead of added\n+ *    NBI: Network Block Interface. Set to 0\n+ *    The amount of MAC’s per control message is limited only by the packet\n+ *    buffer size. A 2048B buffer can fit 253 MAC address and a 10240B buffer\n+ *    1277 MAC addresses.\n+ */\n+struct nfp_flower_cmsg_tun_mac {\n+\trte_be16_t flags;\n+\trte_be16_t count;           /**< Should always be 1 */\n+\trte_be16_t index;\n+\tstruct rte_ether_addr addr;\n+};\n+\n+#define NFP_FL_IPV4_ADDRS_MAX        32\n+\n+/*\n+ * NFP_FLOWER_CMSG_TYPE_TUN_IPS\n+ *    Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0\n+ *    -----\\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ *          +---------------------------------------------------------------+\n+ *        0 |                    Number of IP Addresses                     |\n+ *          +---------------------------------------------------------------+\n+ *        1 |                        IP Address #1                          |\n+ *          +---------------------------------------------------------------+\n+ *        2 |                        IP Address #2                          |\n+ *          +---------------------------------------------------------------+\n+ *          |                             ...                               |\n+ *          +---------------------------------------------------------------+\n+ *       32 |                        IP Address #32                         |\n+ *          +---------------------------------------------------------------+\n+ */\n+struct nfp_flower_cmsg_tun_ipv4_addr {\n+\trte_be32_t count;\n+\trte_be32_t ipv4_addr[NFP_FL_IPV4_ADDRS_MAX];\n+};\n+\n /*\n  * NFP_FLOWER_CMSG_TYPE_FLOW_STATS\n  *    Bit    3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0\n@@ -716,5 +801,14 @@ int nfp_flower_cmsg_tun_neigh_v4_rule(struct nfp_app_fw_flower *app_fw_flower,\n \t\tstruct nfp_flower_cmsg_tun_neigh_v4 *payload);\n int nfp_flower_cmsg_tun_neigh_v6_rule(struct nfp_app_fw_flower *app_fw_flower,\n \t\tstruct nfp_flower_cmsg_tun_neigh_v6 *payload);\n+int nfp_flower_cmsg_tun_off_v4(struct nfp_app_fw_flower *app_fw_flower);\n+int nfp_flower_cmsg_pre_tunnel_rule(struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct nfp_fl_rule_metadata *nfp_flow_meta,\n+\t\tuint16_t mac_idx,\n+\t\tbool is_del);\n+int nfp_flower_cmsg_tun_mac_rule(struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct rte_ether_addr *mac,\n+\t\tuint16_t mac_idx,\n+\t\tbool is_del);\n \n #endif /* _NFP_CMSG_H_ */\ndiff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c\nindex 9ee02b0fb9..c088d24413 100644\n--- a/drivers/net/nfp/nfp_flow.c\n+++ b/drivers/net/nfp/nfp_flow.c\n@@ -47,7 +47,8 @@ struct nfp_flow_item_proc {\n \t/* Size in bytes for @p mask_support and @p mask_default. */\n \tconst unsigned int mask_sz;\n \t/* Merge a pattern item into a flow rule handle. */\n-\tint (*merge)(struct rte_flow *nfp_flow,\n+\tint (*merge)(struct nfp_app_fw_flower *app_fw_flower,\n+\t\t\tstruct rte_flow *nfp_flow,\n \t\t\tchar **mbuf_off,\n \t\t\tconst struct rte_flow_item *item,\n \t\t\tconst struct nfp_flow_item_proc *proc,\n@@ -63,6 +64,12 @@ struct nfp_mask_id_entry {\n \tuint8_t mask_id;\n };\n \n+struct nfp_pre_tun_entry {\n+\tuint16_t mac_index;\n+\tuint16_t ref_cnt;\n+\tuint8_t mac_addr[RTE_ETHER_ADDR_LEN];\n+} __rte_aligned(32);\n+\n static inline struct nfp_flow_priv *\n nfp_flow_dev_to_priv(struct rte_eth_dev *dev)\n {\n@@ -406,6 +413,83 @@ nfp_stats_id_free(struct nfp_flow_priv *priv, uint32_t ctx)\n \treturn 0;\n }\n \n+__rte_unused static int\n+nfp_tun_add_ipv4_off(struct nfp_app_fw_flower *app_fw_flower,\n+\t\trte_be32_t ipv4)\n+{\n+\tstruct nfp_flow_priv *priv;\n+\tstruct nfp_ipv4_addr_entry *entry;\n+\tstruct nfp_ipv4_addr_entry *tmp_entry;\n+\n+\tpriv = app_fw_flower->flow_priv;\n+\n+\trte_spinlock_lock(&priv->ipv4_off_lock);\n+\tLIST_FOREACH(entry, &priv->ipv4_off_list, next) {\n+\t\tif (entry->ipv4_addr == ipv4) {\n+\t\t\tentry->ref_count++;\n+\t\t\trte_spinlock_unlock(&priv->ipv4_off_lock);\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\trte_spinlock_unlock(&priv->ipv4_off_lock);\n+\n+\ttmp_entry = rte_zmalloc(\"nfp_ipv4_off\", sizeof(struct nfp_ipv4_addr_entry), 0);\n+\tif (tmp_entry == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Mem error when offloading IP address.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\ttmp_entry->ipv4_addr = ipv4;\n+\ttmp_entry->ref_count = 1;\n+\n+\trte_spinlock_lock(&priv->ipv4_off_lock);\n+\tLIST_INSERT_HEAD(&priv->ipv4_off_list, tmp_entry, next);\n+\trte_spinlock_unlock(&priv->ipv4_off_lock);\n+\n+\treturn nfp_flower_cmsg_tun_off_v4(app_fw_flower);\n+}\n+\n+static int\n+nfp_tun_del_ipv4_off(struct nfp_app_fw_flower *app_fw_flower,\n+\t\trte_be32_t ipv4)\n+{\n+\tstruct nfp_flow_priv *priv;\n+\tstruct nfp_ipv4_addr_entry *entry;\n+\n+\tpriv = app_fw_flower->flow_priv;\n+\n+\trte_spinlock_lock(&priv->ipv4_off_lock);\n+\tLIST_FOREACH(entry, &priv->ipv4_off_list, next) {\n+\t\tif (entry->ipv4_addr == ipv4) {\n+\t\t\tentry->ref_count--;\n+\t\t\tif (entry->ref_count == 0) {\n+\t\t\t\tLIST_REMOVE(entry, next);\n+\t\t\t\trte_free(entry);\n+\t\t\t\trte_spinlock_unlock(&priv->ipv4_off_lock);\n+\t\t\t\treturn nfp_flower_cmsg_tun_off_v4(app_fw_flower);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\trte_spinlock_unlock(&priv->ipv4_off_lock);\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_tun_check_ip_off_del(struct nfp_flower_representor *repr,\n+\t\tstruct rte_flow *nfp_flow)\n+{\n+\tint ret;\n+\tstruct nfp_flower_ipv4_udp_tun *udp4;\n+\n+\tudp4 = (struct nfp_flower_ipv4_udp_tun *)(nfp_flow->payload.mask_data -\n+\t\t\tsizeof(struct nfp_flower_ipv4_udp_tun));\n+\tret = nfp_tun_del_ipv4_off(repr->app_fw_flower, udp4->ipv4.dst);\n+\n+\treturn ret;\n+}\n+\n static void\n nfp_flower_compile_meta_tci(char *mbuf_off, struct nfp_fl_key_ls *key_layer)\n {\n@@ -635,6 +719,9 @@ nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[],\n \t\tcase RTE_FLOW_ACTION_TYPE_COUNT:\n \t\t\tPMD_DRV_LOG(DEBUG, \"RTE_FLOW_ACTION_TYPE_COUNT detected\");\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_JUMP:\n+\t\t\tPMD_DRV_LOG(DEBUG, \"RTE_FLOW_ACTION_TYPE_JUMP detected\");\n+\t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_PORT_ID:\n \t\t\tPMD_DRV_LOG(DEBUG, \"RTE_FLOW_ACTION_TYPE_PORT_ID detected\");\n \t\t\tkey_ls->act_size += sizeof(struct nfp_fl_act_output);\n@@ -786,7 +873,8 @@ nfp_flow_is_tunnel(struct rte_flow *nfp_flow)\n }\n \n static int\n-nfp_flow_merge_eth(__rte_unused struct rte_flow *nfp_flow,\n+nfp_flow_merge_eth(__rte_unused struct nfp_app_fw_flower *app_fw_flower,\n+\t\t__rte_unused struct rte_flow *nfp_flow,\n \t\tchar **mbuf_off,\n \t\tconst struct rte_flow_item *item,\n \t\tconst struct nfp_flow_item_proc *proc,\n@@ -823,7 +911,8 @@ nfp_flow_merge_eth(__rte_unused struct rte_flow *nfp_flow,\n }\n \n static int\n-nfp_flow_merge_vlan(struct rte_flow *nfp_flow,\n+nfp_flow_merge_vlan(__rte_unused struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct rte_flow *nfp_flow,\n \t\t__rte_unused char **mbuf_off,\n \t\tconst struct rte_flow_item *item,\n \t\tconst struct nfp_flow_item_proc *proc,\n@@ -853,7 +942,8 @@ nfp_flow_merge_vlan(struct rte_flow *nfp_flow,\n }\n \n static int\n-nfp_flow_merge_ipv4(struct rte_flow *nfp_flow,\n+nfp_flow_merge_ipv4(__rte_unused struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct rte_flow *nfp_flow,\n \t\tchar **mbuf_off,\n \t\tconst struct rte_flow_item *item,\n \t\tconst struct nfp_flow_item_proc *proc,\n@@ -914,7 +1004,8 @@ nfp_flow_merge_ipv4(struct rte_flow *nfp_flow,\n }\n \n static int\n-nfp_flow_merge_ipv6(struct rte_flow *nfp_flow,\n+nfp_flow_merge_ipv6(__rte_unused struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct rte_flow *nfp_flow,\n \t\tchar **mbuf_off,\n \t\tconst struct rte_flow_item *item,\n \t\tconst struct nfp_flow_item_proc *proc,\n@@ -979,7 +1070,8 @@ nfp_flow_merge_ipv6(struct rte_flow *nfp_flow,\n }\n \n static int\n-nfp_flow_merge_tcp(struct rte_flow *nfp_flow,\n+nfp_flow_merge_tcp(__rte_unused struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct rte_flow *nfp_flow,\n \t\tchar **mbuf_off,\n \t\tconst struct rte_flow_item *item,\n \t\tconst struct nfp_flow_item_proc *proc,\n@@ -1052,7 +1144,8 @@ nfp_flow_merge_tcp(struct rte_flow *nfp_flow,\n }\n \n static int\n-nfp_flow_merge_udp(struct rte_flow *nfp_flow,\n+nfp_flow_merge_udp(__rte_unused struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct rte_flow *nfp_flow,\n \t\tchar **mbuf_off,\n \t\tconst struct rte_flow_item *item,\n \t\tconst struct nfp_flow_item_proc *proc,\n@@ -1100,7 +1193,8 @@ nfp_flow_merge_udp(struct rte_flow *nfp_flow,\n }\n \n static int\n-nfp_flow_merge_sctp(struct rte_flow *nfp_flow,\n+nfp_flow_merge_sctp(__rte_unused struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct rte_flow *nfp_flow,\n \t\tchar **mbuf_off,\n \t\tconst struct rte_flow_item *item,\n \t\tconst struct nfp_flow_item_proc *proc,\n@@ -1142,7 +1236,8 @@ nfp_flow_merge_sctp(struct rte_flow *nfp_flow,\n }\n \n static int\n-nfp_flow_merge_vxlan(struct rte_flow *nfp_flow,\n+nfp_flow_merge_vxlan(__rte_unused struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct rte_flow *nfp_flow,\n \t\tchar **mbuf_off,\n \t\tconst struct rte_flow_item *item,\n \t\tconst struct nfp_flow_item_proc *proc,\n@@ -1391,7 +1486,8 @@ nfp_flow_inner_item_get(const struct rte_flow_item items[],\n }\n \n static int\n-nfp_flow_compile_item_proc(const struct rte_flow_item items[],\n+nfp_flow_compile_item_proc(struct nfp_flower_representor *repr,\n+\t\tconst struct rte_flow_item items[],\n \t\tstruct rte_flow *nfp_flow,\n \t\tchar **mbuf_off_exact,\n \t\tchar **mbuf_off_mask,\n@@ -1402,6 +1498,7 @@ nfp_flow_compile_item_proc(const struct rte_flow_item items[],\n \tbool continue_flag = true;\n \tconst struct rte_flow_item *item;\n \tconst struct nfp_flow_item_proc *proc_list;\n+\tstruct nfp_app_fw_flower *app_fw_flower = repr->app_fw_flower;\n \n \tproc_list = nfp_flow_item_proc_list;\n \tfor (item = items; item->type != RTE_FLOW_ITEM_TYPE_END && continue_flag; ++item) {\n@@ -1437,14 +1534,14 @@ nfp_flow_compile_item_proc(const struct rte_flow_item items[],\n \t\t\tbreak;\n \t\t}\n \n-\t\tret = proc->merge(nfp_flow, mbuf_off_exact, item,\n+\t\tret = proc->merge(app_fw_flower, nfp_flow, mbuf_off_exact, item,\n \t\t\t\tproc, false, is_outer_layer);\n \t\tif (ret != 0) {\n \t\t\tPMD_DRV_LOG(ERR, \"nfp flow item %d exact merge failed\", item->type);\n \t\t\tbreak;\n \t\t}\n \n-\t\tret = proc->merge(nfp_flow, mbuf_off_mask, item,\n+\t\tret = proc->merge(app_fw_flower, nfp_flow, mbuf_off_mask, item,\n \t\t\t\tproc, true, is_outer_layer);\n \t\tif (ret != 0) {\n \t\t\tPMD_DRV_LOG(ERR, \"nfp flow item %d mask merge failed\", item->type);\n@@ -1458,7 +1555,7 @@ nfp_flow_compile_item_proc(const struct rte_flow_item items[],\n }\n \n static int\n-nfp_flow_compile_items(__rte_unused struct nfp_flower_representor *representor,\n+nfp_flow_compile_items(struct nfp_flower_representor *representor,\n \t\tconst struct rte_flow_item items[],\n \t\tstruct rte_flow *nfp_flow)\n {\n@@ -1489,7 +1586,7 @@ nfp_flow_compile_items(__rte_unused struct nfp_flower_representor *representor,\n \t\tis_outer_layer = false;\n \n \t/* Go over items */\n-\tret = nfp_flow_compile_item_proc(loop_item, nfp_flow,\n+\tret = nfp_flow_compile_item_proc(representor, loop_item, nfp_flow,\n \t\t\t&mbuf_off_exact, &mbuf_off_mask, is_outer_layer);\n \tif (ret != 0) {\n \t\tPMD_DRV_LOG(ERR, \"nfp flow item compile failed.\");\n@@ -1498,7 +1595,7 @@ nfp_flow_compile_items(__rte_unused struct nfp_flower_representor *representor,\n \n \t/* Go over inner items */\n \tif (is_tun_flow) {\n-\t\tret = nfp_flow_compile_item_proc(items, nfp_flow,\n+\t\tret = nfp_flow_compile_item_proc(representor, items, nfp_flow,\n \t\t\t\t&mbuf_off_exact, &mbuf_off_mask, true);\n \t\tif (ret != 0) {\n \t\t\tPMD_DRV_LOG(ERR, \"nfp flow outer item compile failed.\");\n@@ -1873,6 +1970,59 @@ nfp_flower_add_tun_neigh_v4_encap(struct nfp_app_fw_flower *app_fw_flower,\n \treturn nfp_flower_cmsg_tun_neigh_v4_rule(app_fw_flower, &payload);\n }\n \n+__rte_unused static int\n+nfp_flower_add_tun_neigh_v4_decap(struct nfp_app_fw_flower *app_fw_flower,\n+\t\tstruct rte_flow *nfp_flow)\n+{\n+\tstruct nfp_fl_tun *tmp;\n+\tstruct nfp_fl_tun *tun;\n+\tstruct nfp_flow_priv *priv;\n+\tstruct nfp_flower_ipv4 *ipv4;\n+\tstruct nfp_flower_mac_mpls *eth;\n+\tstruct nfp_flower_in_port *port;\n+\tstruct nfp_flower_meta_tci *meta_tci;\n+\tstruct nfp_flower_cmsg_tun_neigh_v4 payload;\n+\n+\tmeta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data;\n+\tport = (struct nfp_flower_in_port *)(meta_tci + 1);\n+\teth = (struct nfp_flower_mac_mpls *)(port + 1);\n+\n+\tif (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_TP)\n+\t\tipv4 = (struct nfp_flower_ipv4 *)((char *)eth +\n+\t\t\t\tsizeof(struct nfp_flower_mac_mpls) +\n+\t\t\t\tsizeof(struct nfp_flower_tp_ports));\n+\telse\n+\t\tipv4 = (struct nfp_flower_ipv4 *)((char *)eth +\n+\t\t\t\tsizeof(struct nfp_flower_mac_mpls));\n+\n+\ttun = &nfp_flow->tun;\n+\ttun->payload.v6_flag = 0;\n+\ttun->payload.dst.dst_ipv4 = ipv4->ipv4_src;\n+\ttun->payload.src.src_ipv4 = ipv4->ipv4_dst;\n+\tmemcpy(tun->payload.dst_addr, eth->mac_src, RTE_ETHER_ADDR_LEN);\n+\tmemcpy(tun->payload.src_addr, eth->mac_dst, RTE_ETHER_ADDR_LEN);\n+\n+\ttun->ref_cnt = 1;\n+\tpriv = app_fw_flower->flow_priv;\n+\tLIST_FOREACH(tmp, &priv->nn_list, next) {\n+\t\tif (memcmp(&tmp->payload, &tun->payload, sizeof(struct nfp_fl_tun_entry)) == 0) {\n+\t\t\ttmp->ref_cnt++;\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\n+\tLIST_INSERT_HEAD(&priv->nn_list, tun, next);\n+\n+\tmemset(&payload, 0, sizeof(struct nfp_flower_cmsg_tun_neigh_v4));\n+\tpayload.dst_ipv4 = ipv4->ipv4_src;\n+\tpayload.src_ipv4 = ipv4->ipv4_dst;\n+\tmemcpy(payload.common.dst_mac, eth->mac_src, RTE_ETHER_ADDR_LEN);\n+\tmemcpy(payload.common.src_mac, eth->mac_dst, RTE_ETHER_ADDR_LEN);\n+\tpayload.common.port_id = port->in_port;\n+\n+\treturn nfp_flower_cmsg_tun_neigh_v4_rule(app_fw_flower, &payload);\n+}\n+\n static int\n nfp_flower_del_tun_neigh_v4(struct nfp_app_fw_flower *app_fw_flower,\n \t\trte_be32_t ipv4)\n@@ -2090,6 +2240,200 @@ nfp_flow_action_vxlan_encap(struct nfp_app_fw_flower *app_fw_flower,\n \t\t\t\tactions, vxlan_data, nfp_flow_meta, tun);\n }\n \n+static struct nfp_pre_tun_entry *\n+nfp_pre_tun_table_search(struct nfp_flow_priv *priv,\n+\t\tchar *hash_data,\n+\t\tuint32_t hash_len)\n+{\n+\tint index;\n+\tuint32_t hash_key;\n+\tstruct nfp_pre_tun_entry *mac_index;\n+\n+\thash_key = rte_jhash(hash_data, hash_len, priv->hash_seed);\n+\tindex = rte_hash_lookup_data(priv->pre_tun_table, &hash_key, (void **)&mac_index);\n+\tif (index < 0) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Data NOT found in the hash table\");\n+\t\treturn NULL;\n+\t}\n+\n+\treturn mac_index;\n+}\n+\n+static bool\n+nfp_pre_tun_table_add(struct nfp_flow_priv *priv,\n+\t\tchar *hash_data,\n+\t\tuint32_t hash_len)\n+{\n+\tint ret;\n+\tuint32_t hash_key;\n+\n+\thash_key = rte_jhash(hash_data, hash_len, priv->hash_seed);\n+\tret = rte_hash_add_key_data(priv->pre_tun_table, &hash_key, hash_data);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Add to pre tunnel table failed\");\n+\t\treturn false;\n+\t}\n+\n+\treturn true;\n+}\n+\n+static bool\n+nfp_pre_tun_table_delete(struct nfp_flow_priv *priv,\n+\t\tchar *hash_data,\n+\t\tuint32_t hash_len)\n+{\n+\tint ret;\n+\tuint32_t hash_key;\n+\n+\thash_key = rte_jhash(hash_data, hash_len, priv->hash_seed);\n+\tret = rte_hash_del_key(priv->pre_tun_table, &hash_key);\n+\tif (ret < 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Delete from pre tunnel table failed\");\n+\t\treturn false;\n+\t}\n+\n+\treturn true;\n+}\n+\n+__rte_unused static int\n+nfp_pre_tun_table_check_add(struct nfp_flower_representor *repr,\n+\t\tuint16_t *index)\n+{\n+\tuint16_t i;\n+\tuint32_t entry_size;\n+\tuint16_t mac_index = 1;\n+\tstruct nfp_flow_priv *priv;\n+\tstruct nfp_pre_tun_entry *entry;\n+\tstruct nfp_pre_tun_entry *find_entry;\n+\n+\tpriv = repr->app_fw_flower->flow_priv;\n+\tif (priv->pre_tun_cnt >= NFP_TUN_PRE_TUN_RULE_LIMIT) {\n+\t\tPMD_DRV_LOG(ERR, \"Pre tunnel table has full\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tentry_size = sizeof(struct nfp_pre_tun_entry);\n+\tentry = rte_zmalloc(\"nfp_pre_tun\", entry_size, 0);\n+\tif (entry == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Memory alloc failed for pre tunnel table\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tentry->ref_cnt = 1U;\n+\tmemcpy(entry->mac_addr, repr->mac_addr.addr_bytes, RTE_ETHER_ADDR_LEN);\n+\n+\t/* 0 is considered a failed match */\n+\tfor (i = 1; i < NFP_TUN_PRE_TUN_RULE_LIMIT; i++) {\n+\t\tif (priv->pre_tun_bitmap[i] == 0)\n+\t\t\tcontinue;\n+\t\tentry->mac_index = i;\n+\t\tfind_entry = nfp_pre_tun_table_search(priv, (char *)entry, entry_size);\n+\t\tif (find_entry != NULL) {\n+\t\t\tfind_entry->ref_cnt++;\n+\t\t\t*index = find_entry->mac_index;\n+\t\t\trte_free(entry);\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\n+\tfor (i = 1; i < NFP_TUN_PRE_TUN_RULE_LIMIT; i++) {\n+\t\tif (priv->pre_tun_bitmap[i] == 0) {\n+\t\t\tpriv->pre_tun_bitmap[i] = 1U;\n+\t\t\tmac_index = i;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tentry->mac_index = mac_index;\n+\tif (!nfp_pre_tun_table_add(priv, (char *)entry, entry_size)) {\n+\t\trte_free(entry);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t*index = entry->mac_index;\n+\tpriv->pre_tun_cnt++;\n+\treturn 0;\n+}\n+\n+static int\n+nfp_pre_tun_table_check_del(struct nfp_flower_representor *repr,\n+\t\tstruct rte_flow *nfp_flow)\n+{\n+\tuint16_t i;\n+\tint ret = 0;\n+\tuint32_t entry_size;\n+\tuint16_t nfp_mac_idx;\n+\tstruct nfp_flow_priv *priv;\n+\tstruct nfp_pre_tun_entry *entry;\n+\tstruct nfp_pre_tun_entry *find_entry;\n+\tstruct nfp_fl_rule_metadata *nfp_flow_meta;\n+\n+\tpriv = repr->app_fw_flower->flow_priv;\n+\tif (priv->pre_tun_cnt == 1)\n+\t\treturn 0;\n+\n+\tentry_size = sizeof(struct nfp_pre_tun_entry);\n+\tentry = rte_zmalloc(\"nfp_pre_tun\", entry_size, 0);\n+\tif (entry == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Memory alloc failed for pre tunnel table\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tentry->ref_cnt = 1U;\n+\tmemcpy(entry->mac_addr, repr->mac_addr.addr_bytes, RTE_ETHER_ADDR_LEN);\n+\n+\t/* 0 is considered a failed match */\n+\tfor (i = 1; i < NFP_TUN_PRE_TUN_RULE_LIMIT; i++) {\n+\t\tif (priv->pre_tun_bitmap[i] == 0)\n+\t\t\tcontinue;\n+\t\tentry->mac_index = i;\n+\t\tfind_entry = nfp_pre_tun_table_search(priv, (char *)entry, entry_size);\n+\t\tif (find_entry != NULL) {\n+\t\t\tfind_entry->ref_cnt--;\n+\t\t\tif (find_entry->ref_cnt != 0)\n+\t\t\t\tgoto free_entry;\n+\t\t\tpriv->pre_tun_bitmap[i] = 0;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tnfp_flow_meta = nfp_flow->payload.meta;\n+\tnfp_mac_idx = (find_entry->mac_index << 8) |\n+\t\t\tNFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT |\n+\t\t\tNFP_TUN_PRE_TUN_IDX_BIT;\n+\tret = nfp_flower_cmsg_tun_mac_rule(repr->app_fw_flower, &repr->mac_addr,\n+\t\t\tnfp_mac_idx, true);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Send tunnel mac rule failed\");\n+\t\tret = -EINVAL;\n+\t\tgoto free_entry;\n+\t}\n+\n+\tret = nfp_flower_cmsg_pre_tunnel_rule(repr->app_fw_flower, nfp_flow_meta,\n+\t\t\tnfp_mac_idx, true);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Send pre tunnel rule failed\");\n+\t\tret = -EINVAL;\n+\t\tgoto free_entry;\n+\t}\n+\n+\tfind_entry->ref_cnt = 1U;\n+\tif (!nfp_pre_tun_table_delete(priv, (char *)find_entry, entry_size)) {\n+\t\tPMD_DRV_LOG(ERR, \"Delete entry from pre tunnel table failed\");\n+\t\tret = -EINVAL;\n+\t\tgoto free_entry;\n+\t}\n+\n+\trte_free(entry);\n+\trte_free(find_entry);\n+\tpriv->pre_tun_cnt--;\n+\n+free_entry:\n+\trte_free(entry);\n+\n+\treturn ret;\n+}\n+\n static int\n nfp_flow_compile_action(struct nfp_flower_representor *representor,\n \t\tconst struct rte_flow_action actions[],\n@@ -2125,6 +2469,9 @@ nfp_flow_compile_action(struct nfp_flower_representor *representor,\n \t\tcase RTE_FLOW_ACTION_TYPE_COUNT:\n \t\t\tPMD_DRV_LOG(DEBUG, \"Process RTE_FLOW_ACTION_TYPE_COUNT\");\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_JUMP:\n+\t\t\tPMD_DRV_LOG(DEBUG, \"Process RTE_FLOW_ACTION_TYPE_JUMP\");\n+\t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_PORT_ID:\n \t\t\tPMD_DRV_LOG(DEBUG, \"Process RTE_FLOW_ACTION_TYPE_PORT_ID\");\n \t\t\tret = nfp_flow_action_output(position, action, nfp_flow_meta);\n@@ -2561,6 +2908,15 @@ nfp_flow_destroy(struct rte_eth_dev *dev,\n \t\t/* Delete the entry from nn table */\n \t\tret = nfp_flower_del_tun_neigh(app_fw_flower, nfp_flow);\n \t\tbreak;\n+\tcase NFP_FLOW_DECAP:\n+\t\t/* Delete the entry from nn table */\n+\t\tret = nfp_flower_del_tun_neigh(app_fw_flower, nfp_flow);\n+\t\tif (ret != 0)\n+\t\t\tgoto exit;\n+\n+\t\t/* Delete the entry in pre tunnel table */\n+\t\tret = nfp_pre_tun_table_check_del(representor, nfp_flow);\n+\t\tbreak;\n \tdefault:\n \t\tPMD_DRV_LOG(ERR, \"Invalid nfp flow type %d.\", nfp_flow->type);\n \t\tret = -EINVAL;\n@@ -2570,6 +2926,10 @@ nfp_flow_destroy(struct rte_eth_dev *dev,\n \tif (ret != 0)\n \t\tgoto exit;\n \n+\t/* Delete the ip off */\n+\tif (nfp_flow_is_tunnel(nfp_flow))\n+\t\tnfp_tun_check_ip_off_del(representor, nfp_flow);\n+\n \t/* Delete the flow from hardware */\n \tif (nfp_flow->install_flag) {\n \t\tret = nfp_flower_cmsg_flow_delete(app_fw_flower, nfp_flow);\n@@ -2703,6 +3063,49 @@ nfp_flow_tunnel_item_release(__rte_unused struct rte_eth_dev *dev,\n \treturn 0;\n }\n \n+static int\n+nfp_flow_tunnel_decap_set(__rte_unused struct rte_eth_dev *dev,\n+\t\tstruct rte_flow_tunnel *tunnel,\n+\t\tstruct rte_flow_action **pmd_actions,\n+\t\tuint32_t *num_of_actions,\n+\t\t__rte_unused struct rte_flow_error *err)\n+{\n+\tstruct rte_flow_action *nfp_action;\n+\n+\tnfp_action = rte_zmalloc(\"nfp_tun_action\", sizeof(struct rte_flow_action), 0);\n+\tif (nfp_action == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Alloc memory for nfp tunnel action failed.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tswitch (tunnel->type) {\n+\tdefault:\n+\t\t*pmd_actions = NULL;\n+\t\t*num_of_actions = 0;\n+\t\trte_free(nfp_action);\n+\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_flow_tunnel_action_decap_release(__rte_unused struct rte_eth_dev *dev,\n+\t\tstruct rte_flow_action *pmd_actions,\n+\t\tuint32_t num_of_actions,\n+\t\t__rte_unused struct rte_flow_error *err)\n+{\n+\tuint32_t i;\n+\tstruct rte_flow_action *nfp_action;\n+\n+\tfor (i = 0; i < num_of_actions; i++) {\n+\t\tnfp_action = &pmd_actions[i];\n+\t\trte_free(nfp_action);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static const struct rte_flow_ops nfp_flow_ops = {\n \t.validate                    = nfp_flow_validate,\n \t.create                      = nfp_flow_create,\n@@ -2711,6 +3114,8 @@ static const struct rte_flow_ops nfp_flow_ops = {\n \t.query                       = nfp_flow_query,\n \t.tunnel_match                = nfp_flow_tunnel_match,\n \t.tunnel_item_release         = nfp_flow_tunnel_item_release,\n+\t.tunnel_decap_set            = nfp_flow_tunnel_decap_set,\n+\t.tunnel_action_decap_release = nfp_flow_tunnel_action_decap_release,\n };\n \n int\n@@ -2755,6 +3160,15 @@ nfp_flow_priv_init(struct nfp_pf_dev *pf_dev)\n \t\t.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,\n \t};\n \n+\tstruct rte_hash_parameters pre_tun_hash_params = {\n+\t\t.name       = \"pre_tunnel_table\",\n+\t\t.entries    = 32,\n+\t\t.hash_func  = rte_jhash,\n+\t\t.socket_id  = rte_socket_id(),\n+\t\t.key_len    = sizeof(uint32_t),\n+\t\t.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY,\n+\t};\n+\n \tctx_count = nfp_rtsym_read_le(pf_dev->sym_tbl,\n \t\t\t\"CONFIG_FC_HOST_CTX_COUNT\", &ret);\n \tif (ret < 0) {\n@@ -2835,11 +3249,27 @@ nfp_flow_priv_init(struct nfp_pf_dev *pf_dev)\n \t\tgoto free_mask_table;\n \t}\n \n+\t/* pre tunnel table */\n+\tpriv->pre_tun_cnt = 1;\n+\tpre_tun_hash_params.hash_func_init_val = priv->hash_seed;\n+\tpriv->pre_tun_table = rte_hash_create(&pre_tun_hash_params);\n+\tif (priv->pre_tun_table == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Pre tunnel table creation failed\");\n+\t\tret = -ENOMEM;\n+\t\tgoto free_flow_table;\n+\t}\n+\n+\t/* ipv4 off list */\n+\trte_spinlock_init(&priv->ipv4_off_lock);\n+\tLIST_INIT(&priv->ipv4_off_list);\n+\n \t/* neighbor next list */\n \tLIST_INIT(&priv->nn_list);\n \n \treturn 0;\n \n+free_flow_table:\n+\trte_hash_free(priv->flow_table);\n free_mask_table:\n \trte_free(priv->mask_table);\n free_stats:\n@@ -2863,6 +3293,7 @@ nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev)\n \tapp_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);\n \tpriv = app_fw_flower->flow_priv;\n \n+\trte_hash_free(priv->pre_tun_table);\n \trte_hash_free(priv->flow_table);\n \trte_hash_free(priv->mask_table);\n \trte_free(priv->stats);\ndiff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h\nindex 892dbc08f1..f536da2650 100644\n--- a/drivers/net/nfp/nfp_flow.h\n+++ b/drivers/net/nfp/nfp_flow.h\n@@ -6,6 +6,7 @@\n #ifndef _NFP_FLOW_H_\n #define _NFP_FLOW_H_\n \n+#include <sys/queue.h>\n #include <rte_bitops.h>\n #include <ethdev_driver.h>\n \n@@ -93,6 +94,7 @@ enum nfp_flower_tun_type {\n enum nfp_flow_type {\n \tNFP_FLOW_COMMON,\n \tNFP_FLOW_ENCAP,\n+\tNFP_FLOW_DECAP,\n };\n \n struct nfp_fl_key_ls {\n@@ -169,6 +171,14 @@ struct nfp_fl_stats {\n \tuint64_t bytes;\n };\n \n+struct nfp_ipv4_addr_entry {\n+\tLIST_ENTRY(nfp_ipv4_addr_entry) next;\n+\trte_be32_t ipv4_addr;\n+\tint ref_count;\n+};\n+\n+#define NFP_TUN_PRE_TUN_RULE_LIMIT  32\n+\n struct nfp_flow_priv {\n \tuint32_t hash_seed; /**< Hash seed for hash tables in this structure. */\n \tuint64_t flower_version; /**< Flow version, always increase. */\n@@ -184,6 +194,13 @@ struct nfp_flow_priv {\n \tstruct nfp_fl_stats_id stats_ids; /**< The stats id ring. */\n \tstruct nfp_fl_stats *stats; /**< Store stats of flow. */\n \trte_spinlock_t stats_lock; /** < Lock the update of 'stats' field. */\n+\t/* pre tunnel rule */\n+\tuint16_t pre_tun_cnt; /**< The size of pre tunnel rule */\n+\tuint8_t pre_tun_bitmap[NFP_TUN_PRE_TUN_RULE_LIMIT]; /**< Bitmap of pre tunnel rule */\n+\tstruct rte_hash *pre_tun_table; /**< Hash table to store pre tunnel rule */\n+\t/* IPv4 off */\n+\tLIST_HEAD(, nfp_ipv4_addr_entry) ipv4_off_list; /**< Store ipv4 off */\n+\trte_spinlock_t ipv4_off_lock; /**< Lock the ipv4 off list */\n \t/* neighbor next */\n \tLIST_HEAD(, nfp_fl_tun)nn_list; /**< Store nn entry */\n };\n",
    "prefixes": [
        "v3",
        "08/26"
    ]
}