get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 80690,
    "url": "http://patches.dpdk.org/api/patches/80690/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20201014084131.72035-5-simonx.lu@intel.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": "<20201014084131.72035-5-simonx.lu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20201014084131.72035-5-simonx.lu@intel.com",
    "date": "2020-10-14T08:41:27",
    "name": "[v1,4/8] net/ixgbe: define the mirror filter paser",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "1a0f97ac9d2adbc0a31663b03067c54adc671ba2",
    "submitter": {
        "id": 2016,
        "url": "http://patches.dpdk.org/api/people/2016/?format=api",
        "name": "SimonX Lu",
        "email": "simonx.lu@intel.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/20201014084131.72035-5-simonx.lu@intel.com/mbox/",
    "series": [
        {
            "id": 12943,
            "url": "http://patches.dpdk.org/api/series/12943/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12943",
            "date": "2020-10-14T08:41:23",
            "name": "use generic flow command to re-realize mirror rule",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/12943/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/80690/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/80690/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 77DECA04B7;\n\tWed, 14 Oct 2020 10:44:30 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id DAD711DD09;\n\tWed, 14 Oct 2020 10:43:21 +0200 (CEST)",
            "from mga04.intel.com (mga04.intel.com [192.55.52.120])\n by dpdk.org (Postfix) with ESMTP id 127A81DD08\n for <dev@dpdk.org>; Wed, 14 Oct 2020 10:43:18 +0200 (CEST)",
            "from fmsmga008.fm.intel.com ([10.253.24.58])\n by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 14 Oct 2020 01:43:18 -0700",
            "from intel-npg-odc-srv01.cd.intel.com ([10.240.178.136])\n by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 14 Oct 2020 01:43:15 -0700"
        ],
        "IronPort-SDR": [
            "\n jDedO+K/Q6H4sBcTZTtNOk32PTLF7I2f0I0iNhxjNX5pO/h/Ji/cMmB7FRUeaqeGD3fPLA5uTd\n K9Vj6HVTWKdA==",
            "\n LvdhE9Zr6sMaLh9U0o417If1Xij2xm+JYVonLrmNyfFwASiDNBh67r1M8pKG5oFgAxWWjbqi7h\n EtFZy+bru1Vg=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9773\"; a=\"163432220\"",
            "E=Sophos;i=\"5.77,374,1596524400\"; d=\"scan'208\";a=\"163432220\"",
            "E=Sophos;i=\"5.77,374,1596524400\"; d=\"scan'208\";a=\"299864561\""
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "From": "SimonX Lu <simonx.lu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "jia.guo@intel.com, haiyue.wang@intel.com, qiming.yang@intel.com,\n beilei.xing@intel.com, orika@nvidia.com, Simon Lu <simonx.lu@intel.com>",
        "Date": "Wed, 14 Oct 2020 08:41:27 +0000",
        "Message-Id": "<20201014084131.72035-5-simonx.lu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20201014084131.72035-1-simonx.lu@intel.com>",
        "References": "<20201014084131.72035-1-simonx.lu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v1 4/8] net/ixgbe: define the mirror filter paser",
        "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: Simon Lu <simonx.lu@intel.com>\n\ndefine the mirror filter parser, it will divide to two pharse, the one is\nmirror attributions pattern parsing, and the mirror config will be filled\nin according to pattern type VF/PF/VLAN.\nthe another is mirror action parsing that the dst_pool of mirror config\nwill be filled in according to action type VF/PF.\n\nSigned-off-by: Simon Lu <simonx.lu@intel.com>\n---\n drivers/net/ixgbe/ixgbe_flow.c | 239 +++++++++++++++++++++++++++++++++\n 1 file changed, 239 insertions(+)",
    "diff": "diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c\nindex b2a2bfc02..0b0e7c630 100644\n--- a/drivers/net/ixgbe/ixgbe_flow.c\n+++ b/drivers/net/ixgbe/ixgbe_flow.c\n@@ -49,6 +49,18 @@\n #define IXGBE_MAX_N_TUPLE_PRIO 7\n #define IXGBE_MAX_FLX_SOURCE_OFF 62\n \n+#define NEXT_ITEM_OF_ACTION(act, actions, index)\t\t\t\\\n+\tdo {\t\t\t\t\t\t\t\t\\\n+\t\tact = (actions) + (index);\t\t\t\t\\\n+\t\twhile (act->type == RTE_FLOW_ACTION_TYPE_VOID) {\t\\\n+\t\t\t(index)++;\t\t\t\t\t\\\n+\t\t\tact = (actions) + (index);\t\t\t\\\n+\t\t}\t\t\t\t\t\t\t\\\n+\t} while (0)\n+\n+#define GET_VLAN_ID_FROM_TCI(vlan_item, default_vid) \\\n+\t((vlan_item) ? ntohs((vlan_item)->tci) & 0x0fff : (default_vid))\n+\n /* ntuple filter list structure */\n struct ixgbe_ntuple_filter_ele {\n \tTAILQ_ENTRY(ixgbe_ntuple_filter_ele) entries;\n@@ -79,6 +91,11 @@ struct ixgbe_rss_conf_ele {\n \tTAILQ_ENTRY(ixgbe_rss_conf_ele) entries;\n \tstruct ixgbe_rte_flow_rss_conf filter_info;\n };\n+/* rss filter list structure */\n+struct ixgbe_mirror_conf_ele {\n+\tTAILQ_ENTRY(ixgbe_mirror_conf_ele) entries;\n+\tstruct ixgbe_flow_mirror_conf filter_info;\n+};\n /* ixgbe_flow memory list structure */\n struct ixgbe_flow_mem {\n \tTAILQ_ENTRY(ixgbe_flow_mem) entries;\n@@ -91,6 +108,7 @@ TAILQ_HEAD(ixgbe_syn_filter_list, ixgbe_eth_syn_filter_ele);\n TAILQ_HEAD(ixgbe_fdir_rule_filter_list, ixgbe_fdir_rule_ele);\n TAILQ_HEAD(ixgbe_l2_tunnel_filter_list, ixgbe_eth_l2_tunnel_conf_ele);\n TAILQ_HEAD(ixgbe_rss_filter_list, ixgbe_rss_conf_ele);\n+TAILQ_HEAD(ixgbe_mirror_filter_list, ixgbe_mirror_conf_ele);\n TAILQ_HEAD(ixgbe_flow_mem_list, ixgbe_flow_mem);\n \n static struct ixgbe_ntuple_filter_list filter_ntuple_list;\n@@ -2931,6 +2949,227 @@ ixgbe_clear_rss_filter(struct rte_eth_dev *dev)\n \t\tixgbe_config_rss_filter(dev, &filter_info->rss_info, FALSE);\n }\n \n+static int\n+ixgbe_flow_parse_mirror_attr_pattern(struct rte_eth_dev *dev,\n+\t\t\t\t    const struct rte_flow_attr *attr,\n+\t\t\t\t    const struct rte_flow_item pattern[],\n+\t\t\t\t    struct rte_flow_error *error,\n+\t\t\t\t    struct ixgbe_flow_mirror_conf *conf)\n+{\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tconst struct rte_flow_item *item = pattern;\n+\tconst struct rte_flow_item *next_item = pattern + 1;\n+\tenum rte_flow_item_type item_type, next_item_type;\n+\tconst struct rte_flow_item_vf *vf_spec, *vf_mask, *vf_last;\n+\tconst struct rte_flow_item_vlan *vlan_spec, *vlan_mask, *vlan_last;\n+\tstruct ixgbe_flow_mirror_conf *mirror_config = conf;\n+\tuint16_t vf_id, vf_id_last;\n+\tuint16_t vlan_id, vlan_id_mask, vlan_id_last;\n+\tuint16_t i, j = 0, k = 0;\n+\n+\tif (attr->priority) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,\n+\t\t\t\t   attr, \"Not support priority.\");\n+\t\treturn -rte_errno;\n+\t}\n+\tif (attr->group) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_ATTR_GROUP,\n+\t\t\t\t   attr, \"Not support group.\");\n+\t\treturn -rte_errno;\n+\t}\n+\tif (attr->transfer) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,\n+\t\t\t\t   attr, \"Not support group.\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\titem_type = item->type;\n+\tnext_item_type = next_item->type;\n+\tif (!(next_item_type == RTE_FLOW_ITEM_TYPE_END &&\n+\t      (item_type == RTE_FLOW_ITEM_TYPE_PF ||\n+\t       item_type == RTE_FLOW_ITEM_TYPE_VF ||\n+\t       item_type == RTE_FLOW_ITEM_TYPE_VLAN))) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t   item,\n+\t\t\t\t   \"Only support pf or vf or vlan pattern.\");\n+\t\treturn -rte_errno;\n+\t}\n+\tif (item_type == RTE_FLOW_ITEM_TYPE_PF) {\n+\t\tif (!attr->ingress && attr->egress) {\n+\t\t\tmirror_config->rule_type = IXGBE_MRCTL_DPME;\n+\t\t} else if (attr->ingress && !attr->egress) {\n+\t\t\tmirror_config->rule_type = IXGBE_MRCTL_UPME;\n+\t\t} else {\n+\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ATTR,\n+\t\t\t\t\t   attr,\n+\t\t\t\t\t   \"Only support ingress or egress attribute PF mirror.\");\n+\t\t\treturn -rte_errno;\n+\t\t}\n+\t} else if (item_type == RTE_FLOW_ITEM_TYPE_VF) {\n+\t\tif (attr->ingress && !attr->egress) {\n+\t\t\tmirror_config->rule_type = IXGBE_MRCTL_VPME;\n+\t\t} else {\n+\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ATTR,\n+\t\t\t\t\t   attr,\n+\t\t\t\t\t   \"Only support ingress attribute for VF mirror.\");\n+\t\t\treturn -rte_errno;\n+\t\t}\n+\n+\t\tvf_spec = item->spec;\n+\t\tvf_last = item->last;\n+\t\tvf_mask = item->mask;\n+\t\tif (item->spec || item->last) {\n+\t\t\tvf_id = (vf_spec ? vf_spec->id : 0);\n+\t\t\tvf_id_last = (vf_last ? vf_last->id : vf_id);\n+\t\t\tif (vf_id >= pci_dev->max_vfs ||\n+\t\t\t    vf_id_last >= pci_dev->max_vfs ||\n+\t\t\t    vf_id_last < vf_id) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ITEM_SPEC,\n+\t\t\t\t\titem,\n+\t\t\t\t\t\"VF ID is out of range.\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\t\t\tmirror_config->pool_mask = 0;\n+\t\t\tfor (i = vf_id, k = 0; i <= vf_id_last; i++, k++)\n+\t\t\t\tif (!vf_mask || (vf_mask->id & (1 << k)))\n+\t\t\t\t\tmirror_config->pool_mask |= (1ULL << i);\n+\t\t} else if (item->mask) {\n+\t\t\tif (vf_mask->id >= (uint32_t)(1 << pci_dev->max_vfs)) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ITEM_MASK,\n+\t\t\t\t\titem,\n+\t\t\t\t\t\"VF ID mask is out of range.\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\t\t\tmirror_config->pool_mask = vf_mask->id;\n+\t\t}\n+\t} else if (item_type == RTE_FLOW_ITEM_TYPE_VLAN) {\n+\t\tif (attr->ingress && !attr->egress) {\n+\t\t\tmirror_config->rule_type = IXGBE_MRCTL_VLME;\n+\t\t} else {\n+\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_ATTR,\n+\t\t\t\t\t   attr,\n+\t\t\t\t\t   \"Only support ingress attribute for VLAN mirror.\");\n+\t\t\treturn -rte_errno;\n+\t\t}\n+\n+\t\tvlan_spec = item->spec;\n+\t\tvlan_last = item->last;\n+\t\tvlan_mask = item->mask;\n+\t\tif (item->spec || item->last) {\n+\t\t\tvlan_id =  GET_VLAN_ID_FROM_TCI(vlan_spec, 0);\n+\t\t\tvlan_id_last = GET_VLAN_ID_FROM_TCI(vlan_last, vlan_id);\n+\t\t\tvlan_id_mask = GET_VLAN_ID_FROM_TCI(vlan_mask, 0x0fff);\n+\n+\t\t\tif (vlan_id >= ETH_MIRROR_MAX_VLANS ||\n+\t\t\t    vlan_id_last >= ETH_MIRROR_MAX_VLANS ||\n+\t\t\t    vlan_id_last < vlan_id) {\n+\t\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ITEM_SPEC,\n+\t\t\t\t\titem,\n+\t\t\t\t\t\"VLAN ID is out of range.\");\n+\t\t\t\treturn -rte_errno;\n+\t\t\t}\n+\t\t\tfor (i = vlan_id; i <= vlan_id_last; i++, k++)\n+\t\t\t\tif (vlan_id_mask & (1 << k))\n+\t\t\t\t\tmirror_config->vlan_id[j++] = i;\n+\n+\t\t\tmirror_config->vlan_mask = (1 << j) - 1;\n+\t\t} else if (item->mask) {\n+\t\t\tvlan_id_mask = GET_VLAN_ID_FROM_TCI(vlan_mask, 0);\n+\t\t\tfor (i = 0; i < ETH_MIRROR_MAX_VLANS; i++) {\n+\t\t\t\tif (vlan_id_mask & (1 << i))\n+\t\t\t\t\tmirror_config->vlan_id[j++] = i;\n+\t\t\t}\n+\t\t\tmirror_config->vlan_mask = (1 << j) - 1;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+ixgbe_flow_parse_mirror_action(struct rte_eth_dev *dev,\n+\t\t\t      const struct rte_flow_action *actions,\n+\t\t\t      struct rte_flow_error *error,\n+\t\t\t      struct ixgbe_flow_mirror_conf *conf)\n+{\n+\tconst struct rte_flow_action *act;\n+\tconst struct rte_flow_action_vf *act_q;\n+\tstruct ixgbe_flow_mirror_conf *mirror_config = conf;\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tuint32_t index = 0;\n+\n+\tNEXT_ITEM_OF_ACTION(act, actions, index);\n+\tif (act->type != RTE_FLOW_ACTION_TYPE_MIRROR) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\tRTE_FLOW_ERROR_TYPE_ACTION, act,\n+\t\t\t\"Not supported parameter.\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\tindex++;\n+\tNEXT_ITEM_OF_ACTION(act, actions, index);\n+\tif (act->type == RTE_FLOW_ACTION_TYPE_PF) {\n+\t\tmirror_config->dst_pool = pci_dev->max_vfs;\n+\t} else if (act->type == RTE_FLOW_ACTION_TYPE_VF) {\n+\t\tact_q = act->conf;\n+\t\tif (act_q->id >= pci_dev->max_vfs) {\n+\t\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_ACTION_CONF, act,\n+\t\t\t\t\"Invalid VF ID for mirror action\");\n+\t\t\treturn -rte_errno;\n+\t\t}\n+\t\tmirror_config->dst_pool = act_q->id;\n+\t} else {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\tRTE_FLOW_ERROR_TYPE_ACTION, act,\n+\t\t\t\"Only support a parameter that is pf or vf.\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\t/* Check if the next non-void item is END */\n+\tindex++;\n+\tNEXT_ITEM_OF_ACTION(act, actions, index);\n+\tif (act->type != RTE_FLOW_ACTION_TYPE_END) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\tRTE_FLOW_ERROR_TYPE_ACTION, act,\n+\t\t\t\"Only support a action item that is pf or vf.\");\n+\t\treturn -rte_errno;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+ixgbe_parse_mirror_filter(struct rte_eth_dev *dev,\n+\t\t\t  const struct rte_flow_attr *attr,\n+\t\t\t  const struct rte_flow_item pattern[],\n+\t\t\t  const struct rte_flow_action actions[],\n+\t\t\t  struct ixgbe_flow_mirror_conf *conf,\n+\t\t\t  struct rte_flow_error *error)\n+{\n+\tint ret;\n+\n+\tret = ixgbe_flow_parse_mirror_attr_pattern(dev,\n+\t\t\t\t\t\t   attr,\n+\t\t\t\t\t\t   pattern,\n+\t\t\t\t\t\t   error,\n+\t\t\t\t\t\t   conf);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn ixgbe_flow_parse_mirror_action(dev, actions, error, conf);\n+}\n+\n void\n ixgbe_filterlist_init(void)\n {\n",
    "prefixes": [
        "v1",
        "4/8"
    ]
}