[dpdk-dev,RFC,2/3] ethdev: add new rte_mtr API for traffic metering and policing

Message ID 1496162653-137817-3-git-send-email-cristian.dumitrescu@intel.com (mailing list archive)
State Superseded, archived
Headers

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK

Commit Message

Cristian Dumitrescu May 30, 2017, 4:44 p.m. UTC
  Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 MAINTAINERS                            |   4 +
 lib/librte_ether/Makefile              |   7 +-
 lib/librte_ether/rte_ether_version.map |   8 +
 lib/librte_ether/rte_mtr.c             | 184 +++++++++++++
 lib/librte_ether/rte_mtr.h             | 465 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_mtr_driver.h      | 188 +++++++++++++
 6 files changed, 854 insertions(+), 2 deletions(-)
 create mode 100644 lib/librte_ether/rte_mtr.c
 create mode 100644 lib/librte_ether/rte_mtr.h
 create mode 100644 lib/librte_ether/rte_mtr_driver.h
  

Comments

Cristian Dumitrescu Aug. 26, 2017, 12:06 a.m. UTC | #1
This patch set introduces an ethdev-based generic API for Traffic
Metering and Policing (MTR), which is yet another standard RX offload for
Ethernet devices.

Similar to rte_flow and rte_tm APIs, the configuration of MTR objects is
done in their own namespace (rte_mtr) within the librte_ether library.
Metering and policing action typically sits on top of flow classification,
which is why MTR objects are enabled through a newly introduced rte_flow
action, which is the only impact to rte_flow API.

Q1: Why introduce ethdev-based traffic metering ad policing API?
A1: Traffic metering and policing is a standard RX offload for Ethernet
devices present in NICs, SoCs and NPUs across the industry.

Q2: What's the connection between the new rte_mtr API and the existing
librte_meter library?
A2: The existing librte_meter library provides a SW implementation for a
subset of the features exposed by this API. The rte_mtr API is agnostic to
whether the implementation is HW, SW or mixed HW-SW.

Q3: What's the connection between the new rte_mtr API and the existing
rte_flow API?
A3: The MTR object is hooked into ethdev RX processing path using a newly
introduced rte_flow action, which is the only impact to the rte_flow API.
The configuration of MTR objects is done in separate namespace (rte_mtr)
outside of rte_flow API.

Q4: Can the new rte_flow meter action drop packets? Is this a terminating
action or not?
A4: Although packets can be dropped by the newly introduced rte_flow meter
action, this action is non-terminating, i.e. the action list typically
contains at least one more action, which is a terminating action.
Depending on the policer actions configured for the MTR object, some
packets might be dropped while some packets passed to the next flow action
with their color set in the packet mbuf. For example, a typical policer
configuration is to drop the red packets while passing the green packets,
therefore a subsequent rte_flow action needs to be configured to determine
the final destination of green packets.

Q5: Which are the main operations exposed for the MTR object?
A5: Traffic metering, policing and statistics update. Traffic metering
determines the color for the current packet (green, yellow, red) based on
the previous history for this flow as maintained by the MTR object.
The policer can do nothing, recolor or drop the packet. Stats are
maintained for MTR object, as configured.

Q6: Where is the output color stored for the current packet.
A6: struct rte_mbuf::sched::color.

Q7: Which are the supported metering algorithms?
A7: srTCM (RFC 2697), trTCM (RFC 2698).

Q8: Which are the supported policer actions?
A8: Recolor the packet (keep or change the color determined by metering)
or drop the packet.

Cristian Dumitrescu (3):
  ethdev: add new eth_dev_ops function for mtr ops get
  ethdev: add new rte_mtr API for traffic metering and policing
  rte_flow: add new action for traffic metering and policing

 MAINTAINERS                            |   4 +
 doc/api/doxy-api-index.md              |   1 +
 lib/librte_ether/Makefile              |   5 +-
 lib/librte_ether/rte_ethdev.h          |   6 +
 lib/librte_ether/rte_ether_version.map |  15 ++
 lib/librte_ether/rte_flow.h            |  22 ++
 lib/librte_ether/rte_mtr.c             | 184 +++++++++++++
 lib/librte_ether/rte_mtr.h             | 471 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_mtr_driver.h      | 188 +++++++++++++
 9 files changed, 895 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_ether/rte_mtr.c
 create mode 100644 lib/librte_ether/rte_mtr.h
 create mode 100644 lib/librte_ether/rte_mtr_driver.h
  
Thomas Monjalon Sept. 21, 2017, 1:28 p.m. UTC | #2
26/08/2017 02:06, Cristian Dumitrescu:
> This patch set introduces an ethdev-based generic API for Traffic
> Metering and Policing (MTR), which is yet another standard RX offload for
> Ethernet devices.

Thanks for bringing yet another offload API.

What are the expected devices to implement this API?

It would be nice to have reviews and acks from other vendors.
  

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index afb4cab..b025a7b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -240,6 +240,10 @@  Flow API
 M: Adrien Mazarguil <adrien.mazarguil@6wind.com>
 F: lib/librte_ether/rte_flow*
 
+Traffic metering and policing API
+M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
+F: lib/librte_ether/rte_mtr*
+
 Crypto API
 M: Declan Doherty <declan.doherty@intel.com>
 F: lib/librte_cryptodev/
diff --git a/lib/librte_ether/Makefile b/lib/librte_ether/Makefile
index 93fdde1..48f1098 100644
--- a/lib/librte_ether/Makefile
+++ b/lib/librte_ether/Makefile
@@ -1,6 +1,6 @@ 
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -41,10 +41,11 @@  CFLAGS += $(WERROR_FLAGS)
 
 EXPORT_MAP := rte_ether_version.map
 
-LIBABIVER := 6
+LIBABIVER := 7
 
 SRCS-y += rte_ethdev.c
 SRCS-y += rte_flow.c
+SRCS-y += rte_mtr.c
 
 #
 # Export include files
@@ -56,5 +57,7 @@  SYMLINK-y-include += rte_eth_ctrl.h
 SYMLINK-y-include += rte_dev_info.h
 SYMLINK-y-include += rte_flow.h
 SYMLINK-y-include += rte_flow_driver.h
+SYMLINK-y-include += rte_mtr.h
+SYMLINK-y-include += rte_mtr_driver.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 9783aa1..89ea2ed 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -161,4 +161,12 @@  DPDK_17.08 {
     global:
 
 	rte_eth_dev_mtr_ops_get;
+	rte_mtr_meter_profile_add;
+	rte_mtr_meter_profile_delete;
+	rte_mtr_create;
+	rte_mtr_destroy;
+	rte_mtr_meter_profile_update;
+	rte_mtr_policer_action_update;
+	rte_mtr_stats_update;
+	rte_mtr_stats_read;
 } DPDK_17.05;
diff --git a/lib/librte_ether/rte_mtr.c b/lib/librte_ether/rte_mtr.c
new file mode 100644
index 0000000..efbe7fb
--- /dev/null
+++ b/lib/librte_ether/rte_mtr.c
@@ -0,0 +1,184 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+
+#include <rte_errno.h>
+#include "rte_ethdev.h"
+#include "rte_mtr_driver.h"
+#include "rte_mtr.h"
+
+/* Get generic traffic metering and policing operations structure from a port. */
+const struct rte_mtr_ops *
+rte_mtr_ops_get(uint8_t port_id, struct rte_mtr_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_mtr_ops *ops;
+
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_mtr_error_set(error,
+			ENODEV,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			rte_strerror(ENODEV));
+		return NULL;
+	}
+
+	if ((dev->dev_ops->mtr_ops_get == NULL) ||
+		(dev->dev_ops->mtr_ops_get(dev, &ops) != 0) ||
+		(ops == NULL)) {
+		rte_mtr_error_set(error,
+			ENOSYS,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			rte_strerror(ENOSYS));
+		return NULL;
+	}
+
+	return ops;
+}
+
+#define RTE_MTR_FUNC(port_id, func)			\
+({							\
+	const struct rte_mtr_ops *ops =			\
+		rte_mtr_ops_get(port_id, error);		\
+	if (ops == NULL)					\
+		return -rte_errno;			\
+							\
+	if (ops->func == NULL)				\
+		return -rte_mtr_error_set(error,		\
+			ENOSYS,				\
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,	\
+			NULL,				\
+			rte_strerror(ENOSYS));		\
+							\
+	ops->func;					\
+})
+
+/* MTR meter profile add */
+int
+rte_mtr_meter_profile_add(uint8_t port_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	return RTE_MTR_FUNC(port_id, meter_profile_add)(dev,
+		meter_profile_id, profile, error);
+}
+
+/** MTR meter profile delete */
+int
+rte_mtr_meter_profile_delete(uint8_t port_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	return RTE_MTR_FUNC(port_id, meter_profile_delete)(dev,
+		meter_profile_id, error);
+}
+
+/** MTR object create */
+int
+rte_mtr_create(uint8_t port_id,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	return RTE_MTR_FUNC(port_id, create)(dev,
+		mtr_id, params, shared, error);
+}
+
+/** MTR object destroy */
+int
+rte_mtr_destroy(uint8_t port_id,
+	uint32_t mtr_id,
+	struct rte_mtr_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	return RTE_MTR_FUNC(port_id, destroy)(dev,
+		mtr_id, error);
+}
+
+/** MTR object meter profile update */
+int
+rte_mtr_meter_profile_update(uint8_t port_id,
+	uint32_t mtr_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	return RTE_MTR_FUNC(port_id, meter_profile_update)(dev,
+		mtr_id, meter_profile_id, error);
+}
+
+/** MTR object policer action update */
+int
+rte_mtr_policer_action_update(uint8_t port_id,
+	uint32_t mtr_id,
+	enum rte_mtr_color color,
+	enum rte_mtr_policer_action action,
+	struct rte_mtr_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	return RTE_MTR_FUNC(port_id, policer_action_update)(dev,
+		mtr_id, color, action, error);
+}
+
+/** MTR object enabled stats update */
+int
+rte_mtr_stats_update(uint8_t port_id,
+	uint32_t mtr_id,
+	uint64_t stats_mask,
+	struct rte_mtr_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	return RTE_MTR_FUNC(port_id, stats_update)(dev,
+		mtr_id, stats_mask, error);
+}
+
+/** MTR object stats read */
+int
+rte_mtr_stats_read(uint8_t port_id,
+	uint32_t mtr_id,
+	struct rte_mtr_stats *stats,
+	uint64_t *stats_mask,
+	int clear,
+	struct rte_mtr_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	return RTE_MTR_FUNC(port_id, stats_read)(dev,
+		mtr_id, stats, stats_mask, clear, error);
+}
diff --git a/lib/librte_ether/rte_mtr.h b/lib/librte_ether/rte_mtr.h
new file mode 100644
index 0000000..63179d1
--- /dev/null
+++ b/lib/librte_ether/rte_mtr.h
@@ -0,0 +1,465 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __INCLUDE_RTE_MTR_H__
+#define __INCLUDE_RTE_MTR_H__
+
+/**
+ * @file
+ * RTE Generic Traffic Metering and Policing API
+ *
+ * This interface provides the ability to configure the traffic metering and
+ * policing (MTR) in a generic way.
+ *
+ * The processing done for each input packet hitting a MTR object is:
+ *    A) Traffic metering: The packet is assigned a color (the meter output
+ *       color), based on the previous history of the flow reflected in the
+ *       current state of the MTR object, according to the specific traffic
+ *       metering algorithm. The traffic metering algorithm can typically work
+ *       in color aware mode, in which case the input packet already has an
+ *       initial color (the input color), or in color blind mode, which is
+ *       equivalent to considering all input packets initially colored as green.
+ *    B) Policing: There is a separate policer action configured for each meter
+ *       output color, which can:
+ *          a) Drop the packet.
+ *          b) Keep the same packet color: the policer output color matches the
+ *             meter output color (essentially a no-op action).
+ *          c) Recolor the packet: the policer output color is different than
+ *             the meter output color.
+ *       The policer output color is the output color of the packet, which is
+ *       set in the packet meta-data (i.e. struct rte_mbuf::sched::color).
+ *    C) Statistics: The set of counters maintained for each MTR object is
+ *       configurable and subject to the implementation support. This set
+ *       includes the number of packets and bytes dropped or passed for each
+ *       output color.
+ *
+ * Once successfully created, an MTR object is linked to one or several flows
+ * through the meter action of the flow API.
+ *    A) Whether an MTR object is private to a flow or potentially shared by
+ *       several flows has to be specified at creation time.
+ *    B) Several meter actions can be potentially registered for the same flow.
+ */
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Color
+ */
+enum rte_mtr_color {
+	RTE_MTR_GREEN = 0, /**< Green */
+	RTE_MTR_YELLOW, /**< Yellow */
+	RTE_MTR_RED, /**< Red */
+	RTE_MTR_COLORS /**< Number of colors */
+};
+
+/**
+ * Statistics counter type
+ */
+enum rte_mtr_stats_type {
+	/**< Number of packets passed as green by the policer.  */
+	RTE_MTR_STATS_N_PKTS_GREEN = 1 << 0,
+
+	/**< Number of bytes passed as green by the policer.  */
+	RTE_MTR_STATS_N_BYTES_GREEN = 1 << 1,
+
+	/**< Number of packets passed as yellow by the policer.  */
+	RTE_MTR_STATS_N_PKTS_YELLOW = 1 << 2,
+
+	/**< Number of bytes passed as yellow by the policer.  */
+	RTE_MTR_STATS_N_BYTES_YELLOW = 1 << 3,
+
+	/**< Number of packets passed as red by the policer.  */
+	RTE_MTR_STATS_N_PKTS_RED = 1 << 4,
+
+	/**< Number of bytes passed as red by the policer.  */
+	RTE_MTR_STATS_N_BYTES_RED = 1 << 5,
+
+	/**< Number of packets dropped by the policer.  */
+	RTE_MTR_STATS_N_PKTS_DROPPED = 1 << 6,
+
+	/**< Number of bytes dropped by the policer.  */
+	RTE_MTR_STATS_N_BYTES_DROPPED = 1 << 7,
+};
+
+/**
+ * Statistics counters
+ */
+struct rte_mtr_stats {
+	/**< Number of packets passed by the policer (per color). */
+	uint64_t n_pkts[RTE_MTR_COLORS];
+
+	/**< Number of bytes passed by the policer (per color). */
+	uint64_t n_bytes[RTE_MTR_COLORS];
+
+	/**< Number of packets dropped by the policer. */
+	uint64_t n_pkts_dropped;
+
+	/**< Number of bytes passed by the policer. */
+	uint64_t n_bytes_dropped;
+};
+
+/**
+ * Traffic metering algorithms
+ */
+enum rte_mtr_algorithm {
+	/**< Single Rate Three Color Marker (srTCM) - IETF RFC 2697. */
+	RTE_MTR_SRTCM_RFC2697 = 0,
+
+	/**< Two Rate Three Color Marker (trTCM) - IETF RFC 2698. */
+	RTE_MTR_TRTCM_RFC2698,
+};
+
+/**
+ * Meter profile
+ */
+struct rte_mtr_meter_profile {
+	/**<  Traffic metering algorithm. */
+	enum rte_mtr_algorithm alg;
+
+	union {
+		/**< Items only valid when *alg* is set to srTCM - RFC2697. */
+		struct {
+			/**< Committed Information Rate (CIR) (bytes/second). */
+			uint64_t cir;
+
+			/**< Committed Burst Size (CBS) (bytes). */
+			uint64_t cbs;
+
+			/**< Excess Burst Size (EBS) (bytes). */
+			uint64_t ebs;
+
+			/**< Non-zero for color aware mode, zero for color blind
+			 * mode. In color aware mode, the packet input color is
+			 * read from the IPv4/IPv6 DSCP field, as defined by
+			 * IETF RFC 2597 (low/medium/high drop precedence
+			 * translates to green/yellow/red color respectively).
+			 */
+			int color_aware;
+		} srtcm_rfc2697;
+
+		/**< Items only valid when *alg* is set to trTCM - RFC2698. */
+		struct {
+			/**< Committed Information Rate (CIR) (bytes/second). */
+			uint64_t cir;
+
+			/**< Peak Information Rate (PIR) (bytes/second). */
+			uint64_t pir;
+
+			/**< Committed Burst Size (CBS) (byes). */
+			uint64_t cbs;
+
+			/**< Peak Burst Size (PBS) (bytes). */
+			uint64_t pbs;
+
+			/**< Non-zero for color aware mode, zero for color blind
+			 * mode. In color aware mode, the packet input color is
+			 * read from the IPv4/IPv6 DSCP field, as defined by
+			 * IETF RFC 2597 (low/medium/high drop precedence
+			 * translates to green/yellow/red color respectively).
+			 */
+			int color_aware;
+		} trtcm_rfc2698;
+	};
+};
+
+/**
+ * Policer actions
+ */
+enum rte_mtr_policer_action {
+	/**< Recolor the packet as green. */
+	e_MTR_POLICER_ACTION_COLOR_GREEN = 0,
+
+	/**< Recolor the packet as yellow. */
+	e_MTR_POLICER_ACTION_COLOR_YELLOW,
+
+	/**< Recolor the packet as red. */
+	e_MTR_POLICER_ACTION_COLOR_RED,
+
+	/**< Drop the packet. */
+	e_MTR_POLICER_ACTION_DROP,
+};
+
+/**
+ * Parameters for each traffic metering & policing object
+ *
+ * @see enum rte_mtr_stats_type
+ */
+struct rte_mtr_params {
+	/**< Meter profile ID. */
+	uint32_t meter_profile_id;
+
+	/**< Policer actions (per meter output color). */
+	enum rte_mtr_policer_action action[RTE_MTR_COLORS];
+
+	/**< Set of stats counters to be enabled. */
+	uint64_t stats_mask;
+};
+
+/**
+ * Verbose error types.
+ *
+ * Most of them provide the type of the object referenced by struct
+ * rte_mtr_error::cause.
+ */
+enum rte_mtr_error_type {
+	RTE_MTR_ERROR_TYPE_NONE, /**< No error. */
+	RTE_MTR_ERROR_TYPE_UNSPECIFIED, /**< Cause unspecified. */
+	RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+	RTE_MTR_ERROR_TYPE_METER_PROFILE,
+	RTE_MTR_ERROR_TYPE_MTR_ID,
+	RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+	RTE_MTR_ERROR_TYPE_POLICER_ACTION_GREEN,
+	RTE_MTR_ERROR_TYPE_POLICER_ACTION_YELLOW,
+	RTE_MTR_ERROR_TYPE_POLICER_ACTION_RED,
+	RTE_MTR_ERROR_TYPE_STATS_MASK,
+	RTE_MTR_ERROR_TYPE_STATS,
+	RTE_MTR_ERROR_TYPE_SHARED,
+};
+
+/**
+ * Verbose error structure definition.
+ *
+ * This object is normally allocated by applications and set by PMDs, the
+ * message points to a constant string which does not need to be freed by
+ * the application, however its pointer can be considered valid only as long
+ * as its associated DPDK port remains configured. Closing the underlying
+ * device or unloading the PMD invalidates it.
+ *
+ * Both cause and message may be NULL regardless of the error type.
+ */
+struct rte_mtr_error {
+	enum rte_mtr_error_type type; /**< Cause field and error type. */
+	const void *cause; /**< Object responsible for the error. */
+	const char *message; /**< Human-readable error message. */
+};
+
+/**
+ * Meter profile add
+ *
+ * Create a new meter profile with ID set to *meter_profile_id*. The new profile
+ * is used to create one or several MTR objects.
+ *
+ * @param[in] port_id
+ *   The port identifier of the Ethernet device.
+ * @param[in] meter_profile_id
+ *   ID for the new meter profile. Needs to be unused by any of the existing
+ *   meter profiles added for the current port.
+ * @param[in] profile
+ *   Meter profile parameters. Needs to be pre-allocated and valid.
+ * @param[out] error
+ *   Error details. Filled in only on error, when not NULL.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_mtr_meter_profile_add(uint8_t port_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error);
+
+/**
+ * Meter profile delete
+ *
+ * Delete an existing meter profile. This operation fails when there is
+ * currently at least one user (i.e. MTR object) of this profile.
+ *
+ * @param[in] port_id
+ *   The port identifier of the Ethernet device.
+ * @param[in] meter_profile_id
+ *   Meter profile ID. Needs to be the valid.
+ * @param[out] error
+ *   Error details. Filled in only on error, when not NULL.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_mtr_meter_profile_delete(uint8_t port_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error);
+
+/**
+ * MTR object create
+ *
+ * Create a new MTR object for the current port.
+ *
+ * @param[in] port_id
+ *   The port identifier of the Ethernet device.
+ * @param[in] mtr_id
+ *   MTR object ID. Needs to be unused by any of the existing MTR objects
+ *   created for the current port.
+ * @param[in] params
+ *   MTR object params. Needs to be pre-allocated and valid.
+ * @param[in] shared
+ *   Non-zero when this MTR object can be shared by multiple flows, zero when
+ *   this MTR object can be used by a single flow.
+ * @param[out] error
+ *   Error details. Filled in only on error, when not NULL.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_mtr_create(uint8_t port_id,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error);
+
+/**
+ * MTR object destroy
+ *
+ * Delete an existing MTR object. This operation fails when there is currently
+ * at least one user (i.e. flow) of this MTR object.
+ *
+ * @param[in] port_id
+ *   The port identifier of the Ethernet device.
+ * @param[in] mtr_id
+ *   MTR object ID. Needs to be unused by any of the existing MTR objects
+ *   created for the current port.
+ * @param[out] error
+ *   Error details. Filled in only on error, when not NULL.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_mtr_destroy(uint8_t port_id,
+	uint32_t mtr_id,
+	struct rte_mtr_error *error);
+
+/**
+ * MTR object meter profile update
+ *
+ * @param[in] port_id
+ *   The port identifier of the Ethernet device.
+ * @param[in] mtr_id
+ *   MTR object ID. Needs to be valid.
+ * @param[in] meter_profile_id
+ *   Meter profile ID for the current MTR object. Needs to be valid.
+ * @param[out] error
+ *   Error details. Filled in only on error, when not NULL.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_mtr_meter_profile_update(uint8_t port_id,
+	uint32_t mtr_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error);
+
+/**
+ * MTR object policer action update for given color
+ *
+ * @param[in] port_id
+ *   The port identifier of the Ethernet device.
+ * @param[in] mtr_id
+ *   MTR object ID. Needs to be valid.
+ * @param[in] color
+ *   Color for which the policer action is updated.
+ * @param[in] action
+ *   Policer action for specified color.
+ * @param[out] error
+ *   Error details. Filled in only on error, when not NULL.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_mtr_policer_action_update(uint8_t port_id,
+	uint32_t mtr_id,
+	enum rte_mtr_color color,
+	enum rte_mtr_policer_action action,
+	struct rte_mtr_error *error);
+
+/**
+ * MTR object enabled statistics counters update
+ *
+ * @param[in] port_id
+ *   The port identifier of the Ethernet device.
+ * @param[in] mtr_id
+ *   MTR object ID. Needs to be valid.
+ * @param[in] stats_mask
+ *   Mask of statistics counter types to be enabled for the current MTR object.
+ *   Any statistics counter type not included in this set is to be disabled for
+ *   the current MTR object.
+ * @param[out] error
+ *   Error details. Filled in only on error, when not NULL.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ *
+ * @see enum rte_mtr_stats_type
+ */
+int
+rte_mtr_stats_update(uint8_t port_id,
+	uint32_t mtr_id,
+	uint64_t stats_mask,
+	struct rte_mtr_error *error);
+
+/**
+ * MTR object statistics counters read
+ *
+ * @param[in] port_id
+ *   The port identifier of the Ethernet device.
+ * @param[in] mtr_id
+ *   MTR object ID. Needs to be valid.
+ * @param[out] stats
+ *   When non-NULL, it contains the current value for the statistics counters
+ *   enabled for the current MTR object.
+ * @param[out] stats_mask
+ *   When non-NULL, it contains the mask of statistics counter types that are
+ *   currently enabled for this MTR object, indicating which of the counters
+ *   retrieved with the *stats* structure are valid.
+ * @param[in] clear
+ *   When this parameter has a non-zero value, the statistics counters are
+ *   cleared (i.e. set to zero) immediately after they have been read,
+ *   otherwise the statistics counters are left untouched.
+ * @param[out] error
+ *   Error details. Filled in only on error, when not NULL.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ *
+ * @see enum rte_mtr_stats_type
+ */
+int
+rte_mtr_stats_read(uint8_t port_id,
+	uint32_t mtr_id,
+	struct rte_mtr_stats *stats,
+	uint64_t *stats_mask,
+	int clear,
+	struct rte_mtr_error *error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_RTE_MTR_H__ */
diff --git a/lib/librte_ether/rte_mtr_driver.h b/lib/librte_ether/rte_mtr_driver.h
new file mode 100644
index 0000000..3798cf6
--- /dev/null
+++ b/lib/librte_ether/rte_mtr_driver.h
@@ -0,0 +1,188 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __INCLUDE_RTE_MTR_DRIVER_H__
+#define __INCLUDE_RTE_MTR_DRIVER_H__
+
+/**
+ * @file
+ * RTE Generic Traffic Metering and Policing API (Driver Side)
+ *
+ * This file provides implementation helpers for internal use by PMDs, they
+ * are not intended to be exposed to applications and are not subject to ABI
+ * versioning.
+ */
+
+#include <stdint.h>
+
+#include <rte_errno.h>
+#include "rte_ethdev.h"
+#include "rte_mtr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int (*rte_mtr_meter_profile_add_t)(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error);
+/**< @internal MTR meter profile add */
+
+typedef int (*rte_mtr_meter_profile_delete_t)(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error);
+/**< @internal MTR meter profile delete */
+
+typedef int (*rte_mtr_create_t)(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error);
+/**< @internal MTR object create */
+
+typedef int (*rte_mtr_destroy_t)(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_error *error);
+/**< @internal MTR object destroy */
+
+typedef int (*rte_mtr_meter_profile_update_t)(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error);
+/**< @internal MTR object meter profile update */
+
+typedef int (*rte_mtr_policer_action_update_t)(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	enum rte_mtr_color color,
+	enum rte_mtr_policer_action action,
+	struct rte_mtr_error *error);
+/**< @internal MTR object policer action update*/
+
+typedef int (*rte_mtr_stats_update_t)(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint64_t stats_mask,
+	struct rte_mtr_error *error);
+/**< @internal MTR object enabled stats update */
+
+typedef int (*rte_mtr_stats_read_t)(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_stats *stats,
+	uint64_t *stats_mask,
+	int clear,
+	struct rte_mtr_error *error);
+/**< @internal MTR object stats read */
+
+struct rte_mtr_ops {
+	/** MTR meter profile add */
+	rte_mtr_meter_profile_add_t meter_profile_add;
+
+	/** MTR meter profile delete */
+	rte_mtr_meter_profile_delete_t meter_profile_delete;
+
+	/** MTR object create */
+	rte_mtr_create_t create;
+
+	/** MTR object destroy */
+	rte_mtr_destroy_t destroy;
+
+	/** MTR object meter profile update */
+	rte_mtr_meter_profile_update_t meter_profile_update;
+
+	/** MTR object policer action update */
+	rte_mtr_policer_action_update_t policer_action_update;
+
+	/** MTR object enabled stats update */
+	rte_mtr_stats_update_t stats_update;
+
+	/** MTR object stats read */
+	rte_mtr_stats_read_t stats_read;
+};
+
+/**
+ * Initialize generic error structure.
+ *
+ * This function also sets rte_errno to a given value.
+ *
+ * @param[out] error
+ *   Pointer to error structure (may be NULL).
+ * @param[in] code
+ *   Related error code (rte_errno).
+ * @param[in] type
+ *   Cause field and error type.
+ * @param[in] cause
+ *   Object responsible for the error.
+ * @param[in] message
+ *   Human-readable error message.
+ *
+ * @return
+ *   Error code.
+ */
+static inline int
+rte_mtr_error_set(struct rte_mtr_error *error,
+		   int code,
+		   enum rte_mtr_error_type type,
+		   const void *cause,
+		   const char *message)
+{
+	if (error) {
+		*error = (struct rte_mtr_error){
+			.type = type,
+			.cause = cause,
+			.message = message,
+		};
+	}
+	rte_errno = code;
+	return code;
+}
+
+/**
+ * Get generic traffic metering and policing operations structure from a port
+ *
+ * @param[in] port_id
+ *   The port identifier of the Ethernet device.
+ * @param[out] error
+ *   Error details
+ *
+ * @return
+ *   The traffic metering and policing operations structure associated with
+ *   port_id on success, NULL otherwise.
+ */
+const struct rte_mtr_ops *
+rte_mtr_ops_get(uint8_t port_id, struct rte_mtr_error *error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_RTE_MTR_DRIVER_H__ */