get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 66966,
    "url": "https://patches.dpdk.org/api/patches/66966/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1584672375-376187-12-git-send-email-alvinx.zhang@intel.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": "<1584672375-376187-12-git-send-email-alvinx.zhang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1584672375-376187-12-git-send-email-alvinx.zhang@intel.com",
    "date": "2020-03-20T02:46:12",
    "name": "[v2,11/14] net/igc: implement 2-tuple filter",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "2f0af20f016b41822e1896bc82b103d45fe79671",
    "submitter": {
        "id": 1398,
        "url": "https://patches.dpdk.org/api/people/1398/?format=api",
        "name": "Alvin Zhang",
        "email": "alvinx.zhang@intel.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/1584672375-376187-12-git-send-email-alvinx.zhang@intel.com/mbox/",
    "series": [
        {
            "id": 8992,
            "url": "https://patches.dpdk.org/api/series/8992/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=8992",
            "date": "2020-03-20T02:46:01",
            "name": "igc PMD",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/8992/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/66966/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/66966/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id D4BE9A0583;\n\tFri, 20 Mar 2020 03:52:41 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 44E5C1C07D;\n\tFri, 20 Mar 2020 03:51:26 +0100 (CET)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n by dpdk.org (Postfix) with ESMTP id D1D491C0AE\n for <dev@dpdk.org>; Fri, 20 Mar 2020 03:51:14 +0100 (CET)",
            "from fmsmga002.fm.intel.com ([10.253.24.26])\n by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 19 Mar 2020 19:51:14 -0700",
            "from unknown (HELO dpdk-zhangalvin-dev.sh.intel.com)\n ([10.240.183.54])\n by fmsmga002.fm.intel.com with ESMTP; 19 Mar 2020 19:51:12 -0700"
        ],
        "IronPort-SDR": [
            "\n xETcUnRF9dfg4hevnqHA1QVQM3ir+nwMPGsriyKg/pv10SOfNZTlCsugnUtOiXy98gUmES9dQe\n J+XCeK/3isuA==",
            "\n SkkSm1NLYKcxkH0diqNkhmm3fcq+V9Xt4xSv7ds++d+sf0VOL3IMkhpiujqTsQFgOC1EI3v3cm\n aP+zEq/2JzFQ=="
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.72,283,1580803200\"; d=\"scan'208\";a=\"280290253\"",
        "From": "alvinx.zhang@intel.com",
        "To": "dev@dpdk.org, xiaolong.ye@intel.com, haiyue.wang@intel.com,\n qi.z.zhang@intel.com, beilei.xing@intel.com",
        "Date": "Fri, 20 Mar 2020 10:46:12 +0800",
        "Message-Id": "<1584672375-376187-12-git-send-email-alvinx.zhang@intel.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1584672375-376187-1-git-send-email-alvinx.zhang@intel.com>",
        "References": "<1583742247-370386-1-git-send-email-alvinx.zhang@intel.com>\n <1584672375-376187-1-git-send-email-alvinx.zhang@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 11/14] net/igc: implement 2-tuple filter",
        "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 <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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Alvin Zhang <alvinx.zhang@intel.com>\n\nAdd L3 protocol type and L4 destination port filter.\n\nSigned-off-by: Alvin Zhang <alvinx.zhang@intel.com>\n---\n drivers/net/igc/igc_ethdev.h |  38 +++++\n drivers/net/igc/igc_filter.c | 341 +++++++++++++++++++++++++++++++++++++++++++\n drivers/net/igc/igc_filter.h |   3 +\n 3 files changed, 382 insertions(+)",
    "diff": "diff --git a/drivers/net/igc/igc_ethdev.h b/drivers/net/igc/igc_ethdev.h\nindex 1fbcc3b..49075c8 100644\n--- a/drivers/net/igc/igc_ethdev.h\n+++ b/drivers/net/igc/igc_ethdev.h\n@@ -98,6 +98,9 @@\n #define IGC_GET_QUEUE_FROM_ETQF(_etqf)\t\\\n \t((uint8_t)(((_etqf) & IGC_ETQF_QUEUE_MASK) >> IGC_ETQF_QUEUE_SHIFT))\n \n+#define IGC_MAX_2TUPLE_FILTERS\t\t8\n+#define IGC_2TUPLE_MAX_PRI\t\t7\n+\n /* structure for interrupt relative data */\n struct igc_interrupt {\n \tuint32_t flags;\n@@ -138,6 +141,40 @@ struct igc_ethertype_filter {\n \tuint32_t etqf;\n };\n \n+/* Structure of 2-tuple filter info. */\n+struct igc_2tuple_info {\n+\tuint16_t dst_port;\n+\tuint8_t proto;           /* l4 protocol. */\n+\n+\t/*\n+\t * the packet matched above 2tuple and contain any set bit will hit\n+\t * this filter.\n+\t */\n+\tuint8_t tcp_flags;\n+\n+\t/*\n+\t * seven levels (001b-111b), 111b is highest, used when more than one\n+\t * filter matches.\n+\t */\n+\tuint8_t priority;\n+\tuint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */\n+\t\tsrc_ip_mask:1,   /* if mask is 1b, do not compare src ip. */\n+\t\tdst_port_mask:1, /* if mask is 1b, do not compare dst port. */\n+\t\tsrc_port_mask:1, /* if mask is 1b, do not compare src port. */\n+\t\tproto_mask:1;    /* if mask is 1b, do not compare protocol. */\n+};\n+\n+/* Structure of 2-tuple filter */\n+struct igc_2tuple_filter {\n+\tRTE_STD_C11\n+\tunion {\n+\t\tuint64_t hash_val;\n+\t\tstruct igc_2tuple_info tuple2_info;\n+\t};\n+\n+\tuint8_t queue;\n+};\n+\n /*\n  * Structure to store private data for each driver instance (for each port).\n  */\n@@ -153,6 +190,7 @@ struct igc_adapter {\n \tbool\t\tstopped;\n \n \tstruct igc_ethertype_filter ethertype_filters[IGC_MAX_ETQF_FILTERS];\n+\tstruct igc_2tuple_filter tuple2_filters[IGC_MAX_2TUPLE_FILTERS];\n };\n \n #define IGC_DEV_PRIVATE(_dev)\t((_dev)->data->dev_private)\ndiff --git a/drivers/net/igc/igc_filter.c b/drivers/net/igc/igc_filter.c\nindex 231fcd4..340dbee 100644\n--- a/drivers/net/igc/igc_filter.c\n+++ b/drivers/net/igc/igc_filter.c\n@@ -210,10 +210,347 @@\n \treturn ret;\n }\n \n+/*\n+ * Translate elements in n-tuple filter to 2-tuple filter\n+ *\n+ * @ntuple, n-tuple filter pointer\n+ * @tuple2, 2-tuple filter pointer\n+ *\n+ * Return 0, or negative for error\n+ */\n+static int\n+filter_ntuple_to_2tuple(const struct rte_eth_ntuple_filter *ntuple,\n+\t\t\tstruct igc_2tuple_filter *tuple2)\n+{\n+\tstruct igc_2tuple_info *info;\n+\n+\t/* check max value */\n+\tif (ntuple->queue >= IGC_QUEUE_PAIRS_NUM ||\n+\t\tntuple->priority > IGC_2TUPLE_MAX_PRI ||\n+\t\tntuple->tcp_flags > RTE_NTUPLE_TCP_FLAGS_MASK) {\n+\t\tPMD_DRV_LOG(ERR, \"out of range, queue %u(max is %u), priority\"\n+\t\t\t\" %u(max is %u) tcp_flags %u(max is %u).\",\n+\t\t\tntuple->queue, IGC_QUEUE_PAIRS_NUM - 1,\n+\t\t\tntuple->priority, IGC_2TUPLE_MAX_PRI,\n+\t\t\tntuple->tcp_flags, RTE_NTUPLE_TCP_FLAGS_MASK);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\ttuple2->queue = ntuple->queue;\n+\tinfo = &tuple2->tuple2_info;\n+\n+\t/* port and it's mask assignment */\n+\tswitch (ntuple->dst_port_mask) {\n+\tcase UINT16_MAX:\n+\t\tinfo->dst_port_mask = 0;\n+\t\tinfo->dst_port = ntuple->dst_port;\n+\t\tbreak;\n+\tcase 0:\n+\t\tinfo->dst_port_mask = 1;\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"invalid dst_port mask.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* protocol and it's mask assignment */\n+\tswitch (ntuple->proto_mask) {\n+\tcase UINT8_MAX:\n+\t\tinfo->proto_mask = 0;\n+\t\tinfo->proto = ntuple->proto;\n+\t\tbreak;\n+\tcase 0:\n+\t\tinfo->proto_mask = 1;\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"invalid protocol mask.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* priority and TCP flags assignment */\n+\tinfo->priority = (uint8_t)ntuple->priority;\n+\tif (ntuple->flags & RTE_NTUPLE_FLAGS_TCP_FLAG)\n+\t\tinfo->tcp_flags = ntuple->tcp_flags;\n+\telse\n+\t\tinfo->tcp_flags = 0;\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * igc_2tuple_filter_lookup - lookup 2-tuple filter\n+ *\n+ * @igc, IGC filter pointer\n+ * @tuple2, 2-tuple pointer\n+ * @empty, a place to store the index of empty entry if the item not found\n+ *  it's not smaller than 0 if valid, otherwise -1 for no empty entry.\n+ *  empty parameter is only valid if the return value of the function is -1\n+ *\n+ * Return value\n+ * >= 0, item index of the filter\n+ * -1, the item not been found\n+ */\n+static int\n+igc_2tuple_filter_lookup(const struct igc_adapter *igc,\n+\t\t\tconst struct igc_2tuple_filter *tuple2,\n+\t\t\tint *empty)\n+{\n+\tint i = 0;\n+\n+\tif (empty) {\n+\t\t/* set to invalid valid */\n+\t\t*empty = -1;\n+\n+\t\t/* search the filters array */\n+\t\tfor (; i < IGC_MAX_2TUPLE_FILTERS; i++) {\n+\t\t\tif (igc->tuple2_filters[i].hash_val) {\n+\t\t\t\t/* compare the hase value */\n+\t\t\t\tif (tuple2->hash_val ==\n+\t\t\t\t\tigc->tuple2_filters[i].hash_val)\n+\t\t\t\t\t/* filter be found, return index */\n+\t\t\t\t\treturn i;\n+\t\t\t} else {\n+\t\t\t\t/* get the empty entry */\n+\t\t\t\t*empty = i;\n+\t\t\t\ti++;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t/* search the rest of filters */\n+\tfor (; i < IGC_MAX_2TUPLE_FILTERS; i++) {\n+\t\tif (tuple2->hash_val == igc->tuple2_filters[i].hash_val)\n+\t\t\t/* filter be found, return index */\n+\t\t\treturn i;\n+\t}\n+\n+\treturn -1;\n+}\n+\n+static int\n+igc_get_ntuple_filter(struct rte_eth_dev *dev,\n+\t\tstruct rte_eth_ntuple_filter *ntuple)\n+{\n+\tstruct igc_adapter *igc = IGC_DEV_PRIVATE(dev);\n+\tstruct igc_2tuple_filter tuple2;\n+\tint ret;\n+\n+\tswitch (ntuple->flags) {\n+\tcase RTE_NTUPLE_FLAGS_DST_PORT:\n+\tcase RTE_NTUPLE_FLAGS_DST_PORT | RTE_NTUPLE_FLAGS_TCP_FLAG:\n+\tcase RTE_NTUPLE_FLAGS_PROTO:\n+\tcase RTE_NTUPLE_FLAGS_PROTO | RTE_NTUPLE_FLAGS_TCP_FLAG:\n+\tcase RTE_2TUPLE_FLAGS:\n+\tcase RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG:\n+\t\tmemset(&tuple2, 0, sizeof(tuple2));\n+\t\tret = filter_ntuple_to_2tuple(ntuple, &tuple2);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\n+\t\tret = igc_2tuple_filter_lookup(igc, &tuple2, NULL);\n+\t\tif (ret < 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"filter doesn't exist.\");\n+\t\t\treturn -ENOENT;\n+\t\t}\n+\t\tntuple->queue = igc->tuple2_filters[ret].queue;\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"unsupported flags %u.\", ntuple->flags);\n+\t\tret = -EINVAL;\n+\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* Set hardware register values */\n+static void\n+igc_enable_2tuple_filter(struct rte_eth_dev *dev,\n+\t\t\tconst struct igc_adapter *igc, uint8_t index)\n+{\n+\tstruct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);\n+\tconst struct igc_2tuple_filter *filter = &igc->tuple2_filters[index];\n+\tconst struct igc_2tuple_info *info = &filter->tuple2_info;\n+\tuint32_t ttqf, imir, imir_ext = IGC_IMIREXT_SIZE_BP;\n+\n+\timir = info->dst_port;\n+\timir |= info->priority << IGC_IMIR_PRIORITY_SHIFT;\n+\n+\t/* 1b means not compare. */\n+\tif (info->dst_port_mask)\n+\t\timir |= IGC_IMIR_PORT_BP;\n+\n+\tttqf = IGC_TTQF_DISABLE_MASK | IGC_TTQF_QUEUE_ENABLE;\n+\tttqf |= filter->queue << IGC_TTQF_QUEUE_SHIFT;\n+\tttqf |= info->proto;\n+\n+\tif (info->proto_mask == 0)\n+\t\tttqf &= ~IGC_TTQF_MASK_ENABLE;\n+\n+\t/* TCP flags bits setting. */\n+\tif (info->tcp_flags & RTE_NTUPLE_TCP_FLAGS_MASK) {\n+\t\tif (info->tcp_flags & RTE_TCP_URG_FLAG)\n+\t\t\timir_ext |= IGC_IMIREXT_CTRL_URG;\n+\t\tif (info->tcp_flags & RTE_TCP_ACK_FLAG)\n+\t\t\timir_ext |= IGC_IMIREXT_CTRL_ACK;\n+\t\tif (info->tcp_flags & RTE_TCP_PSH_FLAG)\n+\t\t\timir_ext |= IGC_IMIREXT_CTRL_PSH;\n+\t\tif (info->tcp_flags & RTE_TCP_RST_FLAG)\n+\t\t\timir_ext |= IGC_IMIREXT_CTRL_RST;\n+\t\tif (info->tcp_flags & RTE_TCP_SYN_FLAG)\n+\t\t\timir_ext |= IGC_IMIREXT_CTRL_SYN;\n+\t\tif (info->tcp_flags & RTE_TCP_FIN_FLAG)\n+\t\t\timir_ext |= IGC_IMIREXT_CTRL_FIN;\n+\t} else {\n+\t\timir_ext |= IGC_IMIREXT_CTRL_BP;\n+\t}\n+\n+\tIGC_WRITE_REG(hw, IGC_IMIR(index), imir);\n+\tIGC_WRITE_REG(hw, IGC_TTQF(index), ttqf);\n+\tIGC_WRITE_REG(hw, IGC_IMIREXT(index), imir_ext);\n+\tIGC_WRITE_FLUSH(hw);\n+}\n+\n+/* Reset hardware register values */\n+static void\n+igc_disable_2tuple_filter(struct rte_eth_dev *dev, uint8_t index)\n+{\n+\tstruct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);\n+\n+\tIGC_WRITE_REG(hw, IGC_TTQF(index), IGC_TTQF_DISABLE_MASK);\n+\tIGC_WRITE_REG(hw, IGC_IMIR(index), 0);\n+\tIGC_WRITE_REG(hw, IGC_IMIREXT(index), 0);\n+\tIGC_WRITE_FLUSH(hw);\n+}\n+\n+static int\n+igc_add_2tuple_filter(struct rte_eth_dev *dev,\n+\t\tconst struct igc_2tuple_filter *tuple2)\n+{\n+\tstruct igc_adapter *igc = IGC_DEV_PRIVATE(dev);\n+\tint ret, empty;\n+\n+\tret = igc_2tuple_filter_lookup(igc, tuple2, &empty);\n+\tif (ret >= 0) {\n+\t\tPMD_DRV_LOG(ERR, \"filter exists.\");\n+\t\treturn -EEXIST;\n+\t}\n+\n+\tif (empty < 0) {\n+\t\tPMD_DRV_LOG(ERR, \"filter no entry.\");\n+\t\treturn -ENOSPC;\n+\t}\n+\n+\tret = empty;\n+\tmemcpy(&igc->tuple2_filters[ret], tuple2, sizeof(*tuple2));\n+\tigc_enable_2tuple_filter(dev, igc, (uint8_t)ret);\n+\treturn 0;\n+}\n+\n+static int\n+igc_del_2tuple_filter(struct rte_eth_dev *dev,\n+\t\tconst struct igc_2tuple_filter *tuple2)\n+{\n+\tstruct igc_adapter *igc = IGC_DEV_PRIVATE(dev);\n+\tint ret;\n+\n+\tret = igc_2tuple_filter_lookup(igc, tuple2, NULL);\n+\tif (ret < 0) {\n+\t\tPMD_DRV_LOG(ERR, \"filter not exists.\");\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tmemset(&igc->tuple2_filters[ret], 0, sizeof(*tuple2));\n+\tigc_disable_2tuple_filter(dev, (uint8_t)ret);\n+\treturn 0;\n+}\n+\n+int\n+igc_add_del_ntuple_filter(struct rte_eth_dev *dev,\n+\t\t\tconst struct rte_eth_ntuple_filter *ntuple,\n+\t\t\tbool add)\n+{\n+\tstruct igc_2tuple_filter tuple2;\n+\tint ret;\n+\n+\tswitch (ntuple->flags) {\n+\tcase RTE_NTUPLE_FLAGS_DST_PORT:\n+\tcase RTE_NTUPLE_FLAGS_DST_PORT | RTE_NTUPLE_FLAGS_TCP_FLAG:\n+\tcase RTE_NTUPLE_FLAGS_PROTO:\n+\tcase RTE_NTUPLE_FLAGS_PROTO | RTE_NTUPLE_FLAGS_TCP_FLAG:\n+\tcase RTE_2TUPLE_FLAGS:\n+\tcase RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG:\n+\t\tmemset(&tuple2, 0, sizeof(tuple2));\n+\t\tret = filter_ntuple_to_2tuple(ntuple, &tuple2);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\t\tif (add)\n+\t\t\tret = igc_add_2tuple_filter(dev, &tuple2);\n+\t\telse\n+\t\t\tret = igc_del_2tuple_filter(dev, &tuple2);\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"unsupported flags %u.\", ntuple->flags);\n+\t\tret = -EINVAL;\n+\t\tbreak;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+/* Clear all the n-tuple filters */\n+static void\n+igc_clear_all_ntuple_filter(struct rte_eth_dev *dev)\n+{\n+\tstruct igc_adapter *igc = IGC_DEV_PRIVATE(dev);\n+\tint i;\n+\n+\tfor (i = 0; i < IGC_MAX_2TUPLE_FILTERS; i++)\n+\t\tigc_disable_2tuple_filter(dev, i);\n+\n+\tmemset(&igc->tuple2_filters, 0, sizeof(igc->tuple2_filters));\n+}\n+\n+static int\n+igc_ntuple_filter_handle(struct rte_eth_dev *dev,\n+\t\t\tenum rte_filter_op filter_op,\n+\t\t\tstruct rte_eth_ntuple_filter *filter)\n+{\n+\tint ret;\n+\n+\tif (filter_op == RTE_ETH_FILTER_NOP)\n+\t\treturn 0;\n+\n+\tif (filter == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"filter shouldn't be NULL for operation %u.\",\n+\t\t\tfilter_op);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tswitch (filter_op) {\n+\tcase RTE_ETH_FILTER_ADD:\n+\t\tret = igc_add_del_ntuple_filter(dev, filter, true);\n+\t\tbreak;\n+\tcase RTE_ETH_FILTER_DELETE:\n+\t\tret = igc_add_del_ntuple_filter(dev, filter, false);\n+\t\tbreak;\n+\tcase RTE_ETH_FILTER_GET:\n+\t\tret = igc_get_ntuple_filter(dev, filter);\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"unsupported operation %u.\", filter_op);\n+\t\tret = -EINVAL;\n+\t\tbreak;\n+\t}\n+\treturn ret;\n+}\n+\n void\n igc_clear_all_filter(struct rte_eth_dev *dev)\n {\n \tigc_clear_all_ethertype_filter(dev);\n+\tigc_clear_all_ntuple_filter(dev);\n }\n \n int\n@@ -227,6 +564,10 @@\n \t\tret = igc_ethertype_filter_handle(dev, filter_op,\n \t\t\t(struct rte_eth_ethertype_filter *)arg);\n \t\tbreak;\n+\tcase RTE_ETH_FILTER_NTUPLE:\n+\t\tret = igc_ntuple_filter_handle(dev, filter_op,\n+\t\t\t(struct rte_eth_ntuple_filter *)arg);\n+\t\tbreak;\n \tdefault:\n \t\tPMD_DRV_LOG(WARNING, \"Filter type (%d) not supported\",\n \t\t\t\t\t\t\tfilter_type);\ndiff --git a/drivers/net/igc/igc_filter.h b/drivers/net/igc/igc_filter.h\nindex eff0e47..7c5e843 100644\n--- a/drivers/net/igc/igc_filter.h\n+++ b/drivers/net/igc/igc_filter.h\n@@ -17,6 +17,9 @@ int igc_add_ethertype_filter(struct rte_eth_dev *dev,\n \t\tconst struct rte_eth_ethertype_filter *filter);\n int igc_del_ethertype_filter(struct rte_eth_dev *dev,\n \t\tconst struct rte_eth_ethertype_filter *filter);\n+int igc_add_del_ntuple_filter(struct rte_eth_dev *dev,\n+\t\t\tconst struct rte_eth_ntuple_filter *ntuple,\n+\t\t\tbool add);\n void\n igc_clear_all_filter(struct rte_eth_dev *dev);\n \n",
    "prefixes": [
        "v2",
        "11/14"
    ]
}