Show a patch.

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

{
    "id": 73505,
    "url": "https://patches.dpdk.org/api/patches/73505/",
    "web_url": "https://patches.dpdk.org/patch/73505/",
    "project": {
        "id": 1,
        "url": "https://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": "<20200708062720.8363-1-guinanx.sun@intel.com>",
    "date": "2020-07-08T06:27:20",
    "name": "[v5] net/i40e: support cloud filter with L4 port",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "fe13df6fa3c0866c85bbdf4a103a5ae3ffa82514",
    "submitter": {
        "id": 1476,
        "url": "https://patches.dpdk.org/api/people/1476/",
        "name": "Guinan Sun",
        "email": "guinanx.sun@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "https://patches.dpdk.org/api/users/1540/",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "https://patches.dpdk.org/patch/73505/mbox/",
    "series": [
        {
            "id": 10877,
            "url": "https://patches.dpdk.org/api/series/10877/",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=10877",
            "date": "2020-07-08T06:27:20",
            "name": "[v5] net/i40e: support cloud filter with L4 port",
            "version": 5,
            "mbox": "https://patches.dpdk.org/series/10877/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/73505/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/73505/checks/",
    "tags": {},
    "headers": {
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "Return-Path": "<dev-bounces@dpdk.org>",
        "IronPort-SDR": [
            "\n DvFtyzRopubBze4wryC2e4P9qMSTKJaG6x99nKFNr3TA0PDN5BMfCRok+K8jfiEMLUwSxtGqTB\n mRyD7+9VXuRQ==",
            "\n 7vE9qtuTNN0B/yl7RhxnXxFww7M+NVY3JrL0aH1ufe0JpOVvvZpjVxehLYpNa4YsZifCuA6CZH\n wNbr3Hj+6Drg=="
        ],
        "X-Mailer": "git-send-email 2.17.1",
        "To": "dev@dpdk.org",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 94DE0A00BE;\n\tWed,  8 Jul 2020 08:38:18 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 9A0041DD01;\n\tWed,  8 Jul 2020 08:38:17 +0200 (CEST)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n by dpdk.org (Postfix) with ESMTP id 9C1551DAE4\n for <dev@dpdk.org>; Wed,  8 Jul 2020 08:38:15 +0200 (CEST)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 07 Jul 2020 23:38:14 -0700",
            "from intel.sh.intel.com ([10.239.255.18])\n by orsmga002.jf.intel.com with ESMTP; 07 Jul 2020 23:38:11 -0700"
        ],
        "X-BeenThere": "dev@dpdk.org",
        "X-Amp-File-Uploaded": "False",
        "Subject": "[dpdk-dev] [PATCH v5] net/i40e: support cloud filter with L4 port",
        "Cc": "Beilei Xing <beilei.xing@intel.com>, Jeff Guo <jia.guo@intel.com>,\n Guinan Sun <guinanx.sun@intel.com>",
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "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-Post": "<mailto:dev@dpdk.org>",
        "In-Reply-To": "<20200611052416.14592-1-guinanx.sun@intel.com>",
        "X-ExtLoop1": "1",
        "Precedence": "list",
        "From": "Guinan Sun <guinanx.sun@intel.com>",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9675\"; a=\"146817692\"",
            "E=Sophos;i=\"5.75,326,1589266800\"; d=\"scan'208\";a=\"146817692\"",
            "E=Sophos;i=\"5.75,326,1589266800\"; d=\"scan'208\";a=\"297628701\""
        ],
        "References": "<20200611052416.14592-1-guinanx.sun@intel.com>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "Errors-To": "dev-bounces@dpdk.org",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "Message-Id": "<20200708062720.8363-1-guinanx.sun@intel.com>",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Date": "Wed,  8 Jul 2020 06:27:20 +0000",
        "X-Mailman-Version": "2.1.15"
    },
    "content": "This patch enables cloud filter for IPv4_UDP/IPv4_TCP/IPv4_SCTP\nand IPv6_UDP/IPv6_TCP/IPv6_SCTP with SRC port only or DST port only.\nThis supports different filter types for the same packet type.\nE.g. one IPv4_UDP rules with SRC port only and another IPv4_UDP rule\nwith DST port only.\n\nSigned-off-by: Guinan Sun <guinanx.sun@intel.com>\n---\nv5:\n* Add IPv6 to release_20_08.rst and i40e.rst.\n* Fixed the variable assignment.\nv4:\n* Modify release_20_08.rst and i40e.rst.\n* Rename L4 port filter.\n* Modify commit log.\n* Fixed the variable assignment.\nv3:\n* Add limitation to i40e.rst.\n* Rename variables.\n* Fixed the variable assignment.\nv2:\n* Fixed code style and variable naming.\n---\n doc/guides/nics/i40e.rst               |   7 +\n doc/guides/rel_notes/release_20_08.rst |  11 ++\n drivers/net/i40e/i40e_ethdev.c         | 200 ++++++++++++++++++++-\n drivers/net/i40e/i40e_ethdev.h         |  18 ++\n drivers/net/i40e/i40e_flow.c           | 230 +++++++++++++++++++++++++\n 5 files changed, 465 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst\nindex 00c3042d5..c0b45c637 100644\n--- a/doc/guides/nics/i40e.rst\n+++ b/doc/guides/nics/i40e.rst\n@@ -736,6 +736,13 @@ with DPDK, then the configuration will also impact port B in the NIC with\n kernel driver, which don't want to use the TPID.\n So PMD reports warning to clarify what is changed by writing global register.\n \n+Cloud Filter\n+~~~~~~~~~~~~\n+\n+When programming cloud filters for IPv4_UDP/IPv4_TCP/IPv4_SCTP and IPv6_UDP/IPv6_TCP/IPv6_SCTP\n+with SRC port only or DST port only, it will make any cloud filter using inner_vlan or tunnel key\n+invalid. Default configuration will be recovered only by NIC core reset.\n+\n High Performance of Small Packets on 40GbE NIC\n ----------------------------------------------\n \ndiff --git a/doc/guides/rel_notes/release_20_08.rst b/doc/guides/rel_notes/release_20_08.rst\nindex eaa9d13b5..3458bec02 100644\n--- a/doc/guides/rel_notes/release_20_08.rst\n+++ b/doc/guides/rel_notes/release_20_08.rst\n@@ -137,6 +137,17 @@ New Features\n   See the :doc:`../sample_app_ug/l2_forward_real_virtual` for more\n   details of this parameter usage.\n \n+* **Updated Intel i40e driver.**\n+\n+  Updated i40e PMD with new features and improvements, including:\n+\n+  * Improved cloud filter.\n+    This new feature enables cloud filter for IPv4_UDP/IPv4_TCP/IPv4_SCTP\n+    and IPv6_UDP/IPv6_TCP/IPv6_SCTP with SRC port only or DST port only.\n+    This supports different filter types for the same packet type.\n+    E.g. one IPv4_UDP rules with SRC port only and another IPv4_UDP rule\n+    with DST port only.\n+\n \n Removed Items\n -------------\ndiff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c\nindex 777e14926..503097cb5 100644\n--- a/drivers/net/i40e/i40e_ethdev.c\n+++ b/drivers/net/i40e/i40e_ethdev.c\n@@ -7944,6 +7944,13 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,\n #define I40E_TR_GRE_KEY_MASK\t\t\t0x400\n #define I40E_TR_GRE_KEY_WITH_XSUM_MASK\t\t0x800\n #define I40E_TR_GRE_NO_KEY_MASK\t\t\t0x8000\n+#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_PORT_TR_WORD0 0x49\n+#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_DIRECTION_WORD0 0x41\n+#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_INGRESS_WORD0 0x80\n+#define I40E_DIRECTION_INGRESS_KEY\t\t0x8000\n+#define I40E_TR_L4_TYPE_TCP\t\t\t0x2\n+#define I40E_TR_L4_TYPE_UDP\t\t\t0x4\n+#define I40E_TR_L4_TYPE_SCTP\t\t\t0x8\n \n static enum\n i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf)\n@@ -8242,6 +8249,132 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)\n \treturn status;\n }\n \n+static enum i40e_status_code\n+i40e_replace_port_l1_filter(struct i40e_pf *pf,\n+\t\t\t    enum i40e_l4_port_type l4_port_type)\n+{\n+\tstruct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;\n+\tstruct i40e_aqc_replace_cloud_filters_cmd  filter_replace;\n+\tenum i40e_status_code status = I40E_SUCCESS;\n+\tstruct i40e_hw *hw = I40E_PF_TO_HW(pf);\n+\tstruct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;\n+\n+\tif (pf->support_multi_driver) {\n+\t\tPMD_DRV_LOG(ERR, \"Replace l1 filter is not supported.\");\n+\t\treturn I40E_NOT_SUPPORTED;\n+\t}\n+\n+\tmemset(&filter_replace, 0,\n+\t       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));\n+\tmemset(&filter_replace_buf, 0,\n+\t       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));\n+\n+\t/* create L1 filter */\n+\tif (l4_port_type == I40E_L4_PORT_TYPE_SRC) {\n+\t\tfilter_replace.old_filter_type =\n+\t\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TUNNLE_KEY;\n+\t\tfilter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X11;\n+\t\tfilter_replace_buf.data[8] =\n+\t\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_SRC_PORT;\n+\t} else {\n+\t\tfilter_replace.old_filter_type =\n+\t\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_IVLAN;\n+\t\tfilter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X10;\n+\t\tfilter_replace_buf.data[8] =\n+\t\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_DST_PORT;\n+\t}\n+\n+\tfilter_replace.tr_bit = 0;\n+\t/* Prepare the buffer, 3 entries */\n+\tfilter_replace_buf.data[0] =\n+\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_DIRECTION_WORD0;\n+\tfilter_replace_buf.data[0] |=\n+\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;\n+\tfilter_replace_buf.data[2] = 0x00;\n+\tfilter_replace_buf.data[3] =\n+\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_INGRESS_WORD0;\n+\tfilter_replace_buf.data[4] =\n+\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_PORT_TR_WORD0;\n+\tfilter_replace_buf.data[4] |=\n+\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;\n+\tfilter_replace_buf.data[5] = 0x00;\n+\tfilter_replace_buf.data[6] = I40E_TR_L4_TYPE_UDP |\n+\t\tI40E_TR_L4_TYPE_TCP |\n+\t\tI40E_TR_L4_TYPE_SCTP;\n+\tfilter_replace_buf.data[7] = 0x00;\n+\tfilter_replace_buf.data[8] |=\n+\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;\n+\tfilter_replace_buf.data[9] = 0x00;\n+\tfilter_replace_buf.data[10] = 0xFF;\n+\tfilter_replace_buf.data[11] = 0xFF;\n+\n+\tstatus = i40e_aq_replace_cloud_filters(hw, &filter_replace,\n+\t\t\t\t\t       &filter_replace_buf);\n+\tif (!status && filter_replace.old_filter_type !=\n+\t    filter_replace.new_filter_type)\n+\t\tPMD_DRV_LOG(WARNING, \"i40e device %s changed cloud l1 type.\"\n+\t\t\t    \" original: 0x%x, new: 0x%x\",\n+\t\t\t    dev->device->name,\n+\t\t\t    filter_replace.old_filter_type,\n+\t\t\t    filter_replace.new_filter_type);\n+\n+\treturn status;\n+}\n+\n+static enum i40e_status_code\n+i40e_replace_port_cloud_filter(struct i40e_pf *pf,\n+\t\t\t       enum i40e_l4_port_type l4_port_type)\n+{\n+\tstruct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;\n+\tstruct i40e_aqc_replace_cloud_filters_cmd  filter_replace;\n+\tenum i40e_status_code status = I40E_SUCCESS;\n+\tstruct i40e_hw *hw = I40E_PF_TO_HW(pf);\n+\tstruct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;\n+\n+\tif (pf->support_multi_driver) {\n+\t\tPMD_DRV_LOG(ERR, \"Replace cloud filter is not supported.\");\n+\t\treturn I40E_NOT_SUPPORTED;\n+\t}\n+\n+\tmemset(&filter_replace, 0,\n+\t       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));\n+\tmemset(&filter_replace_buf, 0,\n+\t       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));\n+\n+\tif (l4_port_type == I40E_L4_PORT_TYPE_SRC) {\n+\t\tfilter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IIP;\n+\t\tfilter_replace.new_filter_type =\n+\t\t\tI40E_AQC_ADD_CLOUD_FILTER_0X11;\n+\t\tfilter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_0X11;\n+\t} else {\n+\t\tfilter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_OIP;\n+\t\tfilter_replace.new_filter_type =\n+\t\t\tI40E_AQC_ADD_CLOUD_FILTER_0X10;\n+\t\tfilter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_0X10;\n+\t}\n+\n+\tfilter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER;\n+\tfilter_replace.tr_bit = 0;\n+\t/* Prepare the buffer, 2 entries */\n+\tfilter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;\n+\tfilter_replace_buf.data[0] |=\n+\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;\n+\tfilter_replace_buf.data[4] |=\n+\t\tI40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;\n+\tstatus = i40e_aq_replace_cloud_filters(hw, &filter_replace,\n+\t\t\t\t\t       &filter_replace_buf);\n+\n+\tif (!status && filter_replace.old_filter_type !=\n+\t    filter_replace.new_filter_type)\n+\t\tPMD_DRV_LOG(WARNING, \"i40e device %s changed cloud filter type.\"\n+\t\t\t    \" original: 0x%x, new: 0x%x\",\n+\t\t\t    dev->device->name,\n+\t\t\t    filter_replace.old_filter_type,\n+\t\t\t    filter_replace.new_filter_type);\n+\n+\treturn status;\n+}\n+\n int\n i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,\n \t\t      struct i40e_tunnel_filter_conf *tunnel_filter,\n@@ -8389,6 +8522,62 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,\n \t\tpfilter->general_fields[0] = tunnel_filter->inner_vlan;\n \t\tpfilter->general_fields[1] = tunnel_filter->outer_vlan;\n \t\tbig_buffer = 1;\n+\t\tbreak;\n+\tcase I40E_CLOUD_TYPE_UDP:\n+\tcase I40E_CLOUD_TYPE_TCP:\n+\tcase I40E_CLOUD_TYPE_SCTP:\n+\t\tif (tunnel_filter->l4_port_type == I40E_L4_PORT_TYPE_SRC) {\n+\t\t\tif (!pf->sport_replace_flag) {\n+\t\t\t\ti40e_replace_port_l1_filter(pf,\n+\t\t\t\t\t\ttunnel_filter->l4_port_type);\n+\t\t\t\ti40e_replace_port_cloud_filter(pf,\n+\t\t\t\t\t\ttunnel_filter->l4_port_type);\n+\t\t\t\tpf->sport_replace_flag = 1;\n+\t\t\t}\n+\t\t\tteid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);\n+\t\t\tpfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0] =\n+\t\t\t\tI40E_DIRECTION_INGRESS_KEY;\n+\n+\t\t\tif (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_UDP)\n+\t\t\t\tpfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] =\n+\t\t\t\t\tI40E_TR_L4_TYPE_UDP;\n+\t\t\telse if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_TCP)\n+\t\t\t\tpfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] =\n+\t\t\t\t\tI40E_TR_L4_TYPE_TCP;\n+\t\t\telse\n+\t\t\t\tpfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] =\n+\t\t\t\t\tI40E_TR_L4_TYPE_SCTP;\n+\n+\t\t\tpfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] =\n+\t\t\t\t(teid_le >> 16) & 0xFFFF;\n+\t\t\tbig_buffer = 1;\n+\t\t} else {\n+\t\t\tif (!pf->dport_replace_flag) {\n+\t\t\t\ti40e_replace_port_l1_filter(pf,\n+\t\t\t\t\t\ttunnel_filter->l4_port_type);\n+\t\t\t\ti40e_replace_port_cloud_filter(pf,\n+\t\t\t\t\t\ttunnel_filter->l4_port_type);\n+\t\t\t\tpf->dport_replace_flag = 1;\n+\t\t\t}\n+\t\t\tteid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);\n+\t\t\tpfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD0] =\n+\t\t\t\tI40E_DIRECTION_INGRESS_KEY;\n+\n+\t\t\tif (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_UDP)\n+\t\t\t\tpfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1] =\n+\t\t\t\t\tI40E_TR_L4_TYPE_UDP;\n+\t\t\telse if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_TCP)\n+\t\t\t\tpfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1] =\n+\t\t\t\t\tI40E_TR_L4_TYPE_TCP;\n+\t\t\telse\n+\t\t\t\tpfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1] =\n+\t\t\t\t\tI40E_TR_L4_TYPE_SCTP;\n+\n+\t\t\tpfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD2] =\n+\t\t\t\t(teid_le >> 16) & 0xFFFF;\n+\t\t\tbig_buffer = 1;\n+\t\t}\n+\n \t\tbreak;\n \tdefault:\n \t\t/* Other tunnel types is not supported. */\n@@ -8412,7 +8601,16 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,\n \telse if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_QINQ)\n \t\tpfilter->element.flags |=\n \t\t\tI40E_AQC_ADD_CLOUD_FILTER_0X10;\n-\telse {\n+\telse if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_UDP ||\n+\t\t tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_TCP ||\n+\t\t tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_SCTP) {\n+\t\tif (tunnel_filter->l4_port_type == I40E_L4_PORT_TYPE_SRC)\n+\t\t\tpfilter->element.flags |=\n+\t\t\t\tI40E_AQC_ADD_CLOUD_FILTER_0X11;\n+\t\telse\n+\t\t\tpfilter->element.flags |=\n+\t\t\t\tI40E_AQC_ADD_CLOUD_FILTER_0X10;\n+\t} else {\n \t\tval = i40e_dev_get_filter_type(tunnel_filter->filter_type,\n \t\t\t\t\t\t&pfilter->element.flags);\n \t\tif (val < 0) {\ndiff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h\nindex e5d0ce53f..8442eb256 100644\n--- a/drivers/net/i40e/i40e_ethdev.h\n+++ b/drivers/net/i40e/i40e_ethdev.h\n@@ -767,11 +767,14 @@ struct i40e_rss_pattern_info {\n \n #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0 44\n #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1 45\n+#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_SRC_PORT 29\n+#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_DST_PORT 30\n #define I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSOUDP\t8\n #define I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSOGRE\t9\n #define I40E_AQC_ADD_CLOUD_FILTER_0X10\t\t0x10\n #define I40E_AQC_ADD_CLOUD_FILTER_0X11\t\t0x11\n #define I40E_AQC_ADD_CLOUD_FILTER_0X12\t\t0x12\n+#define I40E_AQC_ADD_L1_FILTER_0X10\t\t0x10\n #define I40E_AQC_ADD_L1_FILTER_0X11\t\t0x11\n #define I40E_AQC_ADD_L1_FILTER_0X12\t\t0x12\n #define I40E_AQC_ADD_L1_FILTER_0X13\t\t0x13\n@@ -828,9 +831,20 @@ enum i40e_tunnel_type {\n \tI40E_TUNNEL_TYPE_GTPU,\n \tI40E_TUNNEL_TYPE_ESPoUDP,\n \tI40E_TUNNEL_TYPE_ESPoIP,\n+\tI40E_CLOUD_TYPE_UDP,\n+\tI40E_CLOUD_TYPE_TCP,\n+\tI40E_CLOUD_TYPE_SCTP,\n \tI40E_TUNNEL_TYPE_MAX,\n };\n \n+/**\n+ * L4 port type.\n+ */\n+enum i40e_l4_port_type {\n+\tI40E_L4_PORT_TYPE_SRC = 0,\n+\tI40E_L4_PORT_TYPE_DST,\n+};\n+\n /**\n  * Tunneling Packet filter configuration.\n  */\n@@ -852,6 +866,7 @@ struct i40e_tunnel_filter_conf {\n \t/** Flags from ETH_TUNNEL_FILTER_XX - see above. */\n \tuint16_t filter_type;\n \tenum i40e_tunnel_type tunnel_type; /**< Tunnel Type. */\n+\tenum i40e_l4_port_type l4_port_type; /**< L4 Port Type. */\n \tuint32_t tenant_id;     /**< Tenant ID to match. VNI, GRE key... */\n \tuint16_t queue_id;      /**< Queue assigned to if match. */\n \tuint8_t is_to_vf;       /**< 0 - to PF, 1 - to VF */\n@@ -1073,6 +1088,9 @@ struct i40e_pf {\n \tbool mpls_replace_flag;  /* 1 - MPLS filter replace is done */\n \tbool gtp_replace_flag;   /* 1 - GTP-C/U filter replace is done */\n \tbool qinq_replace_flag;  /* QINQ filter replace is done */\n+\t/* l4 port flag */\n+\tbool sport_replace_flag;   /* Source port replace is done */\n+\tbool dport_replace_flag;   /* Destination port replace is done */\n \tstruct i40e_tm_conf tm_conf;\n \tbool support_multi_driver; /* 1 - support multiple driver */\n \ndiff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c\nindex 8f8df6fae..955aead58 100644\n--- a/drivers/net/i40e/i40e_flow.c\n+++ b/drivers/net/i40e/i40e_flow.c\n@@ -124,6 +124,12 @@ i40e_flow_parse_qinq_pattern(struct rte_eth_dev *dev,\n \t\t\t      struct rte_flow_error *error,\n \t\t\t      struct i40e_tunnel_filter_conf *filter);\n \n+static int i40e_flow_parse_l4_cloud_filter(struct rte_eth_dev *dev,\n+\t\t\t\t\t   const struct rte_flow_attr *attr,\n+\t\t\t\t\t   const struct rte_flow_item pattern[],\n+\t\t\t\t\t   const struct rte_flow_action actions[],\n+\t\t\t\t\t   struct rte_flow_error *error,\n+\t\t\t\t\t   union i40e_filter_t *filter);\n const struct rte_flow_ops i40e_flow_ops = {\n \t.validate = i40e_flow_validate,\n \t.create = i40e_flow_create,\n@@ -1845,6 +1851,13 @@ static struct i40e_valid_pattern i40e_supported_patterns[] = {\n \t/* L2TPv3 over IP */\n \t{ pattern_fdir_ipv4_l2tpv3oip, i40e_flow_parse_fdir_filter },\n \t{ pattern_fdir_ipv6_l2tpv3oip, i40e_flow_parse_fdir_filter },\n+\t/* L4 over port */\n+\t{ pattern_fdir_ipv4_udp, i40e_flow_parse_l4_cloud_filter },\n+\t{ pattern_fdir_ipv4_tcp, i40e_flow_parse_l4_cloud_filter },\n+\t{ pattern_fdir_ipv4_sctp, i40e_flow_parse_l4_cloud_filter },\n+\t{ pattern_fdir_ipv6_udp, i40e_flow_parse_l4_cloud_filter },\n+\t{ pattern_fdir_ipv6_tcp, i40e_flow_parse_l4_cloud_filter },\n+\t{ pattern_fdir_ipv6_sctp, i40e_flow_parse_l4_cloud_filter },\n };\n \n #define NEXT_ITEM_OF_ACTION(act, actions, index)                        \\\n@@ -3541,6 +3554,223 @@ i40e_flow_parse_tunnel_action(struct rte_eth_dev *dev,\n \treturn 0;\n }\n \n+/* 1. Last in item should be NULL as range is not supported.\n+ * 2. Supported filter types: Source port only and Destination port only.\n+ * 3. Mask of fields which need to be matched should be\n+ *    filled with 1.\n+ * 4. Mask of fields which needn't to be matched should be\n+ *    filled with 0.\n+ */\n+static int\n+i40e_flow_parse_l4_pattern(const struct rte_flow_item *pattern,\n+\t\t\t   struct rte_flow_error *error,\n+\t\t\t   struct i40e_tunnel_filter_conf *filter)\n+{\n+\tconst struct rte_flow_item_sctp *sctp_spec, *sctp_mask;\n+\tconst struct rte_flow_item_tcp *tcp_spec, *tcp_mask;\n+\tconst struct rte_flow_item_udp *udp_spec, *udp_mask;\n+\tconst struct rte_flow_item *item = pattern;\n+\tenum rte_flow_item_type item_type;\n+\n+\tfor (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {\n+\t\tif (item->last) {\n+\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t   item,\n+\t\t\t\t\t   \"Not support range\");\n+\t\t\treturn -rte_errno;\n+\t\t}\n+\t\titem_type = item->type;\n+\t\tswitch (item_type) {\n+\t\tcase RTE_FLOW_ITEM_TYPE_ETH:\n+\t\t\tif (item->spec || item->mask) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t\t   item,\n+\t\t\t\t\t\t   \"Invalid ETH item\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_IPV4:\n+\t\t\tfilter->ip_type = I40E_TUNNEL_IPTYPE_IPV4;\n+\t\t\t/* IPv4 is used to describe protocol,\n+\t\t\t * spec and mask should be NULL.\n+\t\t\t */\n+\t\t\tif (item->spec || item->mask) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t\t   item,\n+\t\t\t\t\t\t   \"Invalid IPv4 item\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_IPV6:\n+\t\t\tfilter->ip_type = I40E_TUNNEL_IPTYPE_IPV6;\n+\t\t\t/* IPv6 is used to describe protocol,\n+\t\t\t * spec and mask should be NULL.\n+\t\t\t */\n+\t\t\tif (item->spec || item->mask) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t\t   item,\n+\t\t\t\t\t\t   \"Invalid IPv6 item\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_UDP:\n+\t\t\tudp_spec = item->spec;\n+\t\t\tudp_mask = item->mask;\n+\n+\t\t\tif (!udp_spec || !udp_mask) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t\t   item,\n+\t\t\t\t\t\t   \"Invalid udp item\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\n+\t\t\tif (udp_spec->hdr.src_port != 0 &&\n+\t\t\t    udp_spec->hdr.dst_port != 0) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t\t   item,\n+\t\t\t\t\t\t   \"Invalid udp spec\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\n+\t\t\tif (udp_spec->hdr.src_port != 0) {\n+\t\t\t\tfilter->l4_port_type =\n+\t\t\t\t\tI40E_L4_PORT_TYPE_SRC;\n+\t\t\t\tfilter->tenant_id =\n+\t\t\t\trte_be_to_cpu_32(udp_spec->hdr.src_port);\n+\t\t\t}\n+\n+\t\t\tif (udp_spec->hdr.dst_port != 0) {\n+\t\t\t\tfilter->l4_port_type =\n+\t\t\t\t\tI40E_L4_PORT_TYPE_DST;\n+\t\t\t\tfilter->tenant_id =\n+\t\t\t\trte_be_to_cpu_32(udp_spec->hdr.dst_port);\n+\t\t\t}\n+\n+\t\t\tfilter->tunnel_type = I40E_CLOUD_TYPE_UDP;\n+\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_TCP:\n+\t\t\ttcp_spec = item->spec;\n+\t\t\ttcp_mask = item->mask;\n+\n+\t\t\tif (!tcp_spec || !tcp_mask) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t\t   item,\n+\t\t\t\t\t\t   \"Invalid tcp item\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\n+\t\t\tif (tcp_spec->hdr.src_port != 0 &&\n+\t\t\t    tcp_spec->hdr.dst_port != 0) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t\t   item,\n+\t\t\t\t\t\t   \"Invalid tcp spec\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\n+\t\t\tif (tcp_spec->hdr.src_port != 0) {\n+\t\t\t\tfilter->l4_port_type =\n+\t\t\t\t\tI40E_L4_PORT_TYPE_SRC;\n+\t\t\t\tfilter->tenant_id =\n+\t\t\t\trte_be_to_cpu_32(tcp_spec->hdr.src_port);\n+\t\t\t}\n+\n+\t\t\tif (tcp_spec->hdr.dst_port != 0) {\n+\t\t\t\tfilter->l4_port_type =\n+\t\t\t\t\tI40E_L4_PORT_TYPE_DST;\n+\t\t\t\tfilter->tenant_id =\n+\t\t\t\trte_be_to_cpu_32(tcp_spec->hdr.dst_port);\n+\t\t\t}\n+\n+\t\t\tfilter->tunnel_type = I40E_CLOUD_TYPE_TCP;\n+\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_SCTP:\n+\t\t\tsctp_spec = item->spec;\n+\t\t\tsctp_mask = item->mask;\n+\n+\t\t\tif (!sctp_spec || !sctp_mask) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t\t   item,\n+\t\t\t\t\t\t   \"Invalid sctp item\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\n+\t\t\tif (sctp_spec->hdr.src_port != 0 &&\n+\t\t\t    sctp_spec->hdr.dst_port != 0) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t\t   item,\n+\t\t\t\t\t\t   \"Invalid sctp spec\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\n+\t\t\tif (sctp_spec->hdr.src_port != 0) {\n+\t\t\t\tfilter->l4_port_type =\n+\t\t\t\t\tI40E_L4_PORT_TYPE_SRC;\n+\t\t\t\tfilter->tenant_id =\n+\t\t\t\t\trte_be_to_cpu_32(sctp_spec->hdr.src_port);\n+\t\t\t}\n+\n+\t\t\tif (sctp_spec->hdr.dst_port != 0) {\n+\t\t\t\tfilter->l4_port_type =\n+\t\t\t\t\tI40E_L4_PORT_TYPE_DST;\n+\t\t\t\tfilter->tenant_id =\n+\t\t\t\t\trte_be_to_cpu_32(sctp_spec->hdr.dst_port);\n+\t\t\t}\n+\n+\t\t\tfilter->tunnel_type = I40E_CLOUD_TYPE_SCTP;\n+\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+i40e_flow_parse_l4_cloud_filter(struct rte_eth_dev *dev,\n+\t\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\t\tconst struct rte_flow_item pattern[],\n+\t\t\t\tconst struct rte_flow_action actions[],\n+\t\t\t\tstruct rte_flow_error *error,\n+\t\t\t\tunion i40e_filter_t *filter)\n+{\n+\tstruct i40e_tunnel_filter_conf *tunnel_filter =\n+\t\t&filter->consistent_tunnel_filter;\n+\tint ret;\n+\n+\tret = i40e_flow_parse_l4_pattern(pattern, error, tunnel_filter);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = i40e_flow_parse_attr(attr, error);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tcons_filter_type = RTE_ETH_FILTER_TUNNEL;\n+\n+\treturn ret;\n+}\n+\n static uint16_t i40e_supported_tunnel_filter_types[] = {\n \tETH_TUNNEL_FILTER_IMAC | ETH_TUNNEL_FILTER_TENID |\n \tETH_TUNNEL_FILTER_IVLAN,\n",
    "prefixes": [
        "v5"
    ]
}