Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/66966/?format=api
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" ] }{ "id": 66966, "url": "