get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 27032,
    "url": "http://patches.dpdk.org/api/patches/27032/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1500388981-23938-1-git-send-email-reshma.pattan@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": "<1500388981-23938-1-git-send-email-reshma.pattan@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1500388981-23938-1-git-send-email-reshma.pattan@intel.com",
    "date": "2017-07-18T14:43:01",
    "name": "[dpdk-dev,RFC,v3] ethdev: add IF-MIB attributes implementation",
    "commit_ref": null,
    "pull_url": null,
    "state": "not-applicable",
    "archived": true,
    "hash": "f57312e64de15952736075c164d9c3c7402e7d08",
    "submitter": {
        "id": 70,
        "url": "http://patches.dpdk.org/api/people/70/?format=api",
        "name": "Pattan, Reshma",
        "email": "reshma.pattan@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/1500388981-23938-1-git-send-email-reshma.pattan@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/27032/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/27032/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id A8CA856A1;\n\tTue, 18 Jul 2017 16:43:09 +0200 (CEST)",
            "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n\tby dpdk.org (Postfix) with ESMTP id 338433977\n\tfor <dev@dpdk.org>; Tue, 18 Jul 2017 16:43:06 +0200 (CEST)",
            "from orsmga005.jf.intel.com ([10.7.209.41])\n\tby orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t18 Jul 2017 07:43:06 -0700",
            "from sivswdev02.ir.intel.com (HELO localhost.localdomain)\n\t([10.237.217.46])\n\tby orsmga005.jf.intel.com with ESMTP; 18 Jul 2017 07:43:03 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.40,378,1496127600\"; d=\"scan'208\";a=\"126487963\"",
        "From": "Reshma Pattan <reshma.pattan@intel.com>",
        "To": "stephen@networkplumber.org, thomas@monjalon.net,\n\tbruce.richardson@intel.com, ferruh.yigit@intel.com,\n\tradu.nicolau@intel.com",
        "Cc": "john.mcnamara@intel.com, dev@dpdk.org,\n\tReshma Pattan <reshma.pattan@intel.com>",
        "Date": "Tue, 18 Jul 2017 15:43:01 +0100",
        "Message-Id": "<1500388981-23938-1-git-send-email-reshma.pattan@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "In-Reply-To": "<1499963067-32504-1-git-send-email-reshma.pattan@intel.com>",
        "References": "<1499963067-32504-1-git-send-email-reshma.pattan@intel.com>",
        "Subject": "[dpdk-dev] [RFC v3] ethdev: add IF-MIB attributes implementation",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "The RFC shows implementation of IF-MIB attributes in ethdev layer.\nThese attributes are implemented from the information available from\nrte_eth_dev_data struct.\n\nThe new APIs are added, to allow applications to trigger IF-MIB attribute\ninitialization and the implementation based on the port id.\nIF-MIB attributes are allocated in shared memory to support multi process\naccess.\n\nFor not to expose IF-MIB attributes structs to user, the structs are kept\ninternal. Making use of the metrics library to register attributes names to\nmetrics library and update their values to metrics library by calling\nrte_metrics_reg_names() and rte_metrics_update_values() respectively.\nApplications should call rte_metrics_get_values() and\nrte_metrics_get_names() to view IF-MIB info.\n\nThe above approach need, making ethdev librray dependent on metrics\nlibrary. Is this acceptable? Comments are welcome.\n\nIf not, we can move all the implementation to new library similar to\nbitrate and latency libraries. With this approach new library needs\nthe access to rte_eth_devices[] to access rte_eth_dev_data. But AFAIK\nrte_eth_devices[] is not allowed to be accessed outside of PMDs and\nethdev layer. Any comments here?\n\nAdded rte_clock.h with wrapper function for clock_gettime(CLOCK_MONOTONIC).\n\nQuestion:\nSince ifLastChange and ifDiscontinuityTime IF-MIB attributes\nimplementation should be based on the SysUpTime that is\n\"The time since the network management portion of the system\nwas last reinitialized\". Since DPDK doesn't know about the\nthe Network Management Portion, I assume these 2 attributes\nshould not be implemented in DPDK. Please clarify.\n\nLooking forward to hear opinions.\n\nSigned-off-by: Reshma Pattan <reshma.pattan@intel.com>\n---\nv3:\n*Added new file rte_clock.h to provide wrapper for\nclock_gettime(CLOCK_MONOTONIC).\n*Used new wrapper function to get the dev start time\ninstead of TSC counter.\n*Renamed the new struct members.\n*Update the commit message.\n*Added a new question and seeking the clarification on the same.\n\nv2: Corrected typos and description of the commit message.\n---\n lib/Makefile                              |   6 +-\n lib/librte_eal/common/Makefile            |   2 +-\n lib/librte_eal/common/include/rte_clock.h |  68 ++++++++++++\n lib/librte_ether/rte_ethdev.c             | 172 +++++++++++++++++++++++++++++-\n lib/librte_ether/rte_ethdev.h             |   7 ++\n lib/librte_ether/rte_ethdev_pci.h         |   1 +\n mk/rte.app.mk                             |   2 +-\n 7 files changed, 252 insertions(+), 6 deletions(-)\n create mode 100644 lib/librte_eal/common/include/rte_clock.h",
    "diff": "diff --git a/lib/Makefile b/lib/Makefile\nindex 07e1fd0..aa2be5b 100644\n--- a/lib/Makefile\n+++ b/lib/Makefile\n@@ -35,6 +35,8 @@ DIRS-y += librte_compat\n DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal\n DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring\n DEPDIRS-librte_ring := librte_eal\n+DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics\n+DEPDIRS-librte_metrics := librte_eal\n DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool\n DEPDIRS-librte_mempool := librte_eal librte_ring\n DIRS-$(CONFIG_RTE_LIBRTE_MBUF) += librte_mbuf\n@@ -46,7 +48,7 @@ DEPDIRS-librte_cfgfile := librte_eal\n DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline\n DEPDIRS-librte_cmdline := librte_eal\n DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether\n-DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring\n+DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring librte_metrics\n DEPDIRS-librte_ether += librte_mbuf\n DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev\n DEPDIRS-librte_cryptodev := librte_eal librte_mempool librte_ring librte_mbuf\n@@ -70,8 +72,6 @@ DEPDIRS-librte_ip_frag := librte_eal librte_mempool librte_mbuf librte_ether\n DEPDIRS-librte_ip_frag += librte_hash\n DIRS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += librte_jobstats\n DEPDIRS-librte_jobstats := librte_eal\n-DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics\n-DEPDIRS-librte_metrics := librte_eal\n DIRS-$(CONFIG_RTE_LIBRTE_BITRATE) += librte_bitratestats\n DEPDIRS-librte_bitratestats := librte_eal librte_metrics librte_ether\n DIRS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS) += librte_latencystats\ndiff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile\nindex a5bd108..8dd438a 100644\n--- a/lib/librte_eal/common/Makefile\n+++ b/lib/librte_eal/common/Makefile\n@@ -40,7 +40,7 @@ INC += rte_string_fns.h rte_version.h\n INC += rte_eal_memconfig.h rte_malloc_heap.h\n INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h\n INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h\n-INC += rte_malloc.h rte_keepalive.h rte_time.h\n+INC += rte_malloc.h rte_keepalive.h rte_time.h rte_clock.h\n \n GENERIC_INC := rte_atomic.h rte_byteorder.h rte_cycles.h rte_prefetch.h\n GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h\ndiff --git a/lib/librte_eal/common/include/rte_clock.h b/lib/librte_eal/common/include/rte_clock.h\nnew file mode 100644\nindex 0000000..8b22a37\n--- /dev/null\n+++ b/lib/librte_eal/common/include/rte_clock.h\n@@ -0,0 +1,68 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017-2018 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _RTE_CLOCK_H_\n+#define _RTE_CLOCK_H_\n+\n+/**\n+ * @file\n+ *\n+ * Retrieves the time of the monotonic clock.\n+ */\n+#include <time.h>\n+\n+struct rte_timespec {\n+\ttime_t   tv_sec;        /* seconds */\n+\tlong     tv_nsec;       /* nanoseconds */\n+};\n+\n+/**\n+ * Gets the time of the monotonic clock.\n+ *\n+ * @return\n+ *   The number of cycles\n+ */\n+static int\n+rte_clock_monotonic_gettime(struct rte_timespec *time)\n+{\n+\tif (time == NULL)\n+\t\treturn -1;\n+\n+\tstruct timespec *sp = (struct timespec *)time;\n+\tif (clock_gettime(CLOCK_MONOTONIC, sp) != 0)\n+\t\treturn -1;\n+\n+\treturn 0;\n+}\n+\n+#endif /* _RTE_CLOCK_H_ */\ndiff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c\nindex 71a576c..14581d0 100644\n--- a/lib/librte_ether/rte_ethdev.c\n+++ b/lib/librte_ether/rte_ethdev.c\n@@ -64,6 +64,10 @@\n #include <rte_errno.h>\n #include <rte_spinlock.h>\n #include <rte_string_fns.h>\n+#include <rte_cycles.h>\n+#include <rte_metrics.h>\n+#include <rte_clock.h>\n+#include <rte_time.h>\n \n #include \"rte_ether.h\"\n #include \"rte_ethdev.h\"\n@@ -118,7 +122,8 @@ static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = {\n #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) /\t\\\n \t\tsizeof(rte_txq_stats_strings[0]))\n \n-\n+#define RTE_MIB_ATTR_NAME_SIZE 32\n+#define RTE_IF_TYPE_ETHERNETCSMACD 6\n /**\n  * The user application callback description.\n  *\n@@ -139,6 +144,11 @@ enum {\n \tSTAT_QMAP_RX\n };\n \n+enum {\n+\tOPER_STATUS_UP = 1,\n+\tOPER_STATUS_DOWN\n+};\n+\n uint8_t\n rte_eth_find_next(uint8_t port_id)\n {\n@@ -218,6 +228,7 @@ rte_eth_dev_allocate(const char *name)\n {\n \tuint8_t port_id;\n \tstruct rte_eth_dev *eth_dev;\n+\tstruct rte_timespec tsp;\n \n \tport_id = rte_eth_dev_find_free_port();\n \tif (port_id == RTE_MAX_ETHPORTS) {\n@@ -239,6 +250,13 @@ rte_eth_dev_allocate(const char *name)\n \tsnprintf(eth_dev->data->name, sizeof(eth_dev->data->name), \"%s\", name);\n \teth_dev->data->port_id = port_id;\n \teth_dev->data->mtu = ETHER_MTU;\n+\tif (rte_clock_monotonic_gettime(&tsp) != 0) {\n+\t\tRTE_PMD_DEBUG_TRACE(\"Failed to get monotonic clock time: \"\n+\t\t\t\t\"%s\\n\", __func__);\n+\t\treturn NULL;\n+\t}\n+\teth_dev->data->sys_up_time_start =\n+\t\ttsp.tv_sec * NSEC_PER_SEC + tsp.tv_nsec;\n \n \treturn eth_dev;\n }\n@@ -898,6 +916,7 @@ rte_eth_dev_start(uint8_t port_id)\n {\n \tstruct rte_eth_dev *dev;\n \tint diag;\n+\tstruct rte_timespec tsp;\n \n \tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);\n \n@@ -923,6 +942,13 @@ rte_eth_dev_start(uint8_t port_id)\n \tif (dev->data->dev_conf.intr_conf.lsc == 0) {\n \t\tRTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);\n \t\t(*dev->dev_ops->link_update)(dev, 0);\n+\t\tif (rte_clock_monotonic_gettime(&tsp) != 0) {\n+\t\t\tRTE_PMD_DEBUG_TRACE(\"Failed to get monotonic clock time\"\n+\t\t\t\t\": %s\\n\", __func__);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tdev->data->if_last_change = tsp.tv_sec * NSEC_PER_SEC +\n+\t\t\t\ttsp.tv_nsec - dev->data->sys_up_time_start;\n \t}\n \treturn 0;\n }\n@@ -1295,6 +1321,7 @@ void\n rte_eth_link_get(uint8_t port_id, struct rte_eth_link *eth_link)\n {\n \tstruct rte_eth_dev *dev;\n+\tstruct rte_timespec tsp;\n \n \tRTE_ETH_VALID_PORTID_OR_RET(port_id);\n \tdev = &rte_eth_devices[port_id];\n@@ -1305,6 +1332,12 @@ rte_eth_link_get(uint8_t port_id, struct rte_eth_link *eth_link)\n \t\tRTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update);\n \t\t(*dev->dev_ops->link_update)(dev, 1);\n \t\t*eth_link = dev->data->dev_link;\n+\n+\t\tif (rte_clock_monotonic_gettime(&tsp) != 0)\n+\t\t\tRTE_PMD_DEBUG_TRACE(\"Failed to get monotonic clock time\"\n+\t\t\t\t\": %s\\n\", __func__);\n+\t\tdev->data->if_last_change = tsp.tv_sec * NSEC_PER_SEC +\n+\t\t\ttsp.tv_nsec - dev->data->sys_up_time_start;\n \t}\n }\n \n@@ -1312,6 +1345,7 @@ void\n rte_eth_link_get_nowait(uint8_t port_id, struct rte_eth_link *eth_link)\n {\n \tstruct rte_eth_dev *dev;\n+\tstruct rte_timespec tsp;\n \n \tRTE_ETH_VALID_PORTID_OR_RET(port_id);\n \tdev = &rte_eth_devices[port_id];\n@@ -1322,6 +1356,14 @@ rte_eth_link_get_nowait(uint8_t port_id, struct rte_eth_link *eth_link)\n \t\tRTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update);\n \t\t(*dev->dev_ops->link_update)(dev, 0);\n \t\t*eth_link = dev->data->dev_link;\n+\n+\t\tif (rte_clock_monotonic_gettime(&tsp) != 0) {\n+\t\t\tRTE_PMD_DEBUG_TRACE(\"Failed to get monotonic clock time\"\n+\t\t\t\t\": %s\\n\", __func__);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tdev->data->if_last_change = tsp.tv_sec * NSEC_PER_SEC +\n+\t\t\ttsp.tv_nsec - dev->data->sys_up_time_start;\n \t}\n }\n \n@@ -1345,12 +1387,20 @@ void\n rte_eth_stats_reset(uint8_t port_id)\n {\n \tstruct rte_eth_dev *dev;\n+\tstruct rte_timespec tsp;\n \n \tRTE_ETH_VALID_PORTID_OR_RET(port_id);\n \tdev = &rte_eth_devices[port_id];\n \n \tRTE_FUNC_PTR_OR_RET(*dev->dev_ops->stats_reset);\n \t(*dev->dev_ops->stats_reset)(dev);\n+\n+\tif (rte_clock_monotonic_gettime(&tsp) != 0) {\n+\t\tRTE_PMD_DEBUG_TRACE(\"Failed to get monotonic clock time: \"\n+\t\t\t\t\"%s\\n\", __func__);\n+\t}\n+\tdev->data->if_cntr_disc_time = tsp.tv_sec * NSEC_PER_SEC + tsp.tv_nsec -\n+\t\t\tdev->data->sys_up_time_start;\n \tdev->data->rx_mbuf_alloc_failed = 0;\n }\n \n@@ -1822,6 +1872,7 @@ void\n rte_eth_xstats_reset(uint8_t port_id)\n {\n \tstruct rte_eth_dev *dev;\n+\tstruct rte_timespec tsp;\n \n \tRTE_ETH_VALID_PORTID_OR_RET(port_id);\n \tdev = &rte_eth_devices[port_id];\n@@ -1829,6 +1880,13 @@ rte_eth_xstats_reset(uint8_t port_id)\n \t/* implemented by the driver */\n \tif (dev->dev_ops->xstats_reset != NULL) {\n \t\t(*dev->dev_ops->xstats_reset)(dev);\n+\n+\tif (rte_clock_monotonic_gettime(&tsp) != 0)\n+\t\tRTE_PMD_DEBUG_TRACE(\"Failed to get monotonic clock time: \"\n+\t\t\t\t\"%s\\n\", __func__);\n+\tdev->data->if_cntr_disc_time = tsp.tv_sec * NSEC_PER_SEC + tsp.tv_nsec -\n+\t\tdev->data->sys_up_time_start;\n+\n \t\treturn;\n \t}\n \n@@ -3354,3 +3412,115 @@ rte_eth_dev_l2_tunnel_offload_set(uint8_t port_id,\n \t\t\t\t-ENOTSUP);\n \treturn (*dev->dev_ops->l2_tunnel_offload_set)(dev, l2_tunnel, mask, en);\n }\n+\n+/* IF-MIB attributes*/\n+struct rte_if_mib_attrs {\n+\tuint64_t if_number;\t\t\t/* ifNumber */\n+\tuint64_t if_index;\t\t\t/* ifIndex */\n+\tuint64_t if_type;\t\t\t/* ifType */\n+\tuint64_t if_mtu;\t\t\t/* ifMtu */\n+\tuint64_t if_speed;\t\t\t/* ifSpeed */\n+\tuint64_t if_phys_address;\t\t/* ifPhysAddress */\n+\tuint64_t if_oper_status;\t\t/* ifOperStatus */\n+\tuint64_t if_last_change;\t\t/* ifLastChange */\n+\tuint64_t if_high_speed;\t\t\t/* ifHighSpeed */\n+\tuint64_t if_cnctr_present;\t\t/* ifConnectorPresent */\n+\tuint64_t if_cntr_disc_time;\t/* ifCounterDiscontinuityTime */\n+};\n+\n+static struct rte_if_mib_attrs *if_mib_attrs;\n+\n+struct if_mib_attrs_nameoff {\n+\tchar name[RTE_MIB_ATTR_NAME_SIZE];\n+\tunsigned int offset;\n+};\n+\n+static const struct if_mib_attrs_nameoff if_mib_attrs_strings[] = {\n+\t{\"ifNumber\", offsetof(struct rte_if_mib_attrs, if_number)},\n+\t{\"ifIndex\", offsetof(struct rte_if_mib_attrs, if_index)},\n+\t{\"ifType\", offsetof(struct rte_if_mib_attrs, if_type)},\n+\t{\"ifMtu\", offsetof(struct rte_if_mib_attrs, if_mtu)},\n+\t{\"ifSpeed\", offsetof(struct rte_if_mib_attrs, if_speed)},\n+\t{\"ifPhysAddress\", offsetof(struct rte_if_mib_attrs, if_phys_address)},\n+\t{\"ifOperStatus\", offsetof(struct rte_if_mib_attrs, if_oper_status)},\n+\t{\"ifLastChange\", offsetof(struct rte_if_mib_attrs, if_last_change)},\n+\t{\"ifHighSpeed\", offsetof(struct rte_if_mib_attrs, if_high_speed)},\n+\t{\"ifConnectorPresent\", offsetof(struct rte_if_mib_attrs,\n+\t\tif_cnctr_present)},\n+\t{\"ifCounterDiscontinuityTime\", offsetof(struct rte_if_mib_attrs,\n+\t\tif_cntr_disc_time)},\n+};\n+\n+#define NUM_IF_MIB_ATTRS (sizeof(if_mib_attrs_strings) / \\\n+\tsizeof(if_mib_attrs_strings[0]))\n+\n+int\n+rte_eth_ifmib_attr_init(void) {\n+\tif_mib_attrs = rte_zmalloc(NULL, sizeof(struct rte_if_mib_attrs),\n+\t\tRTE_CACHE_LINE_SIZE);\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_eth_ifmib_attr_reg(uint8_t port_id) {\n+\n+\tint idx;\n+\tunsigned int i;\n+\tuint64_t *attr_ptr = NULL;\n+\tconst char *ptr_strings[NUM_IF_MIB_ATTRS] = {0};\n+\tstruct rte_eth_dev *eth_dev;\n+\tstruct rte_device *device;\n+\tstruct rte_eth_dev_data *data;\n+\tuint64_t values[NUM_IF_MIB_ATTRS] = {0};\n+\n+\tfor (i = 0; i < NUM_IF_MIB_ATTRS; i++)\n+\t\tptr_strings[i] = if_mib_attrs_strings[i].name;\n+\n+\t/* register names with metrics library */\n+\tidx = rte_metrics_reg_names(ptr_strings, NUM_IF_MIB_ATTRS);\n+\n+\teth_dev = eth_dev_get(port_id);\n+\tdata = eth_dev->data;\n+\tdevice = eth_dev->device;\n+\n+\t/* implement if mib attributes */\n+\tif_mib_attrs->if_number = rte_eth_dev_count();\n+\n+\tif_mib_attrs->if_index = data->port_id + 1;\n+\n+\tif_mib_attrs->if_type = RTE_IF_TYPE_ETHERNETCSMACD;\n+\n+\tif_mib_attrs->if_mtu = data->mtu;\n+\n+\tif_mib_attrs->if_speed =\n+\t\t\t(data->dev_link.link_speed < (UINT32_MAX / 1000000)) ?\n+\t\t\t(data->dev_link.link_speed * 1000000) : UINT32_MAX;\n+\n+\tif_mib_attrs->if_phys_address = 0;\n+\tether_addr_copy(data->mac_addrs,\n+\t\t(struct ether_addr *)if_mib_attrs->if_phys_address);\n+\n+\tif_mib_attrs->if_oper_status = data->dev_link.link_status ?\n+\t\t\t\t\tOPER_STATUS_UP : OPER_STATUS_DOWN;\n+\n+\tif_mib_attrs->if_last_change = data->if_last_change;\n+\n+\tif_mib_attrs->if_high_speed = data->dev_link.link_speed;\n+\n+\tif_mib_attrs->if_cnctr_present =\n+\t\t(device->devargs->type == RTE_DEVTYPE_VIRTUAL) ?\n+\t\t\t\t\tOPER_STATUS_UP : OPER_STATUS_DOWN;\n+\n+\tif_mib_attrs->if_cntr_disc_time = data->if_cntr_disc_time;\n+\n+\tfor (i = 0; i < NUM_IF_MIB_ATTRS; i++) {\n+\t\tattr_ptr = RTE_PTR_ADD(if_mib_attrs,\n+\t\t\t\t\tif_mib_attrs_strings[i].offset);\n+\t\tvalues[i] = *attr_ptr;\n+\t}\n+\t/* update values to metrics library */\n+\trte_metrics_update_values(port_id, idx, values, NUM_IF_MIB_ATTRS);\n+\n+\treturn 0;\n+}\ndiff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h\nindex 1446540..7ddbc41 100644\n--- a/lib/librte_ether/rte_ethdev.h\n+++ b/lib/librte_ether/rte_ethdev.h\n@@ -1674,6 +1674,10 @@ struct rte_eth_dev_data {\n \tuint32_t dev_flags; /**< Capabilities */\n \tenum rte_kernel_driver kdrv;    /**< Kernel driver passthrough */\n \tint numa_node;  /**< NUMA node connection */\n+\t/** IF-MIB attributes ifLastChange and ifCounterDiscontinuityTime */\n+\tuint64_t sys_up_time_start;\n+\tuint64_t if_cntr_disc_time;\n+\tuint64_t if_last_change;\n };\n \n /** Device supports hotplug detach */\n@@ -4375,6 +4379,9 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id);\n int\n rte_eth_dev_get_name_by_port(uint8_t port_id, char *name);\n \n+int rte_eth_ifmib_attr_init(void);\n+int rte_eth_ifmib_attr_reg(uint8_t port_id);\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h\nindex 69aab03..e6e757f 100644\n--- a/lib/librte_ether/rte_ethdev_pci.h\n+++ b/lib/librte_ether/rte_ethdev_pci.h\n@@ -37,6 +37,7 @@\n #include <rte_malloc.h>\n #include <rte_pci.h>\n #include <rte_ethdev.h>\n+#include <rte_cycles.h>\n \n /**\n  * Copy pci device info to the Ethernet device data.\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex 7d71a49..9dc9597 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -73,7 +73,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL)            += --whole-archive\n _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL)            += -lrte_acl\n _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL)            += --no-whole-archive\n _LDLIBS-$(CONFIG_RTE_LIBRTE_JOBSTATS)       += -lrte_jobstats\n-_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS)        += -lrte_metrics\n _LDLIBS-$(CONFIG_RTE_LIBRTE_BITRATE)        += -lrte_bitratestats\n _LDLIBS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS)  += -lrte_latencystats\n _LDLIBS-$(CONFIG_RTE_LIBRTE_POWER)          += -lrte_power\n@@ -95,6 +94,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev\n _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool\n _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring\n _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS)        += -lrte_metrics\n _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal\n _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline\n _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder\n",
    "prefixes": [
        "dpdk-dev",
        "RFC",
        "v3"
    ]
}