diff --git a/lib/librte_pipeline/rte_pdev.h b/lib/librte_pipeline/rte_pdev.h
new file mode 100644
index 0000000..7095197
--- /dev/null
+++ b/lib/librte_pipeline/rte_pdev.h
@@ -0,0 +1,1654 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef __INCLUDE_RTE_PDEV_H__
+#define __INCLUDE_RTE_PDEV_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ * RTE Pipeline Device (PDEV)
+ *
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ */
+
+#include <stdint.h>
+
+#include <rte_common.h>
+#include <rte_dev.h>
+#include <rte_ether.h>
+
+/** PDEV device handle data type. */
+struct rte_pdev;
+
+/**
+ * PDEV Capability API
+ */
+
+/** PDEV capabilities. */
+struct rte_pdev_capabilities {
+	/** Number of built-in pipelines.
+	 * @see rte_pdev_next_get()
+	 */
+	uint32_t n_pipelines_builtin;
+
+	/** Non-zero when new pipelines can be created, zero otherwise.
+	 * @see rte_pdev_create()
+	 */
+	int create;
+};
+
+/**
+ * PDEV capabilities get
+ *
+ * @param[in] dev
+ *   Current device.
+ * @param[out] cap
+ *   PDEV capabilities. Must be non-NULL.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_capabilities_get(struct rte_device *dev,
+	struct rte_pdev_capabilities *cap);
+
+/**
+ * PDEV Discovery API
+ *
+ */
+
+/**
+ * PDEV get next
+ *
+ * This API is used to discover pre-existent pipelines on given device. This is
+ * typically the case for built-in HW pipelines.
+ *
+ * @param[in] dev
+ *   Current device.
+ * @param[in] pdev
+ *   Handle to current PDEV on *dev*. Set to NULL during the first invocation
+ *   for *dev* device.
+ * @return
+ *   When non-NULL, handle to next PDEV, otherwise no more PDEV.
+ *
+ * @see struct rte_pdev_capabilities::n_pipelines_builtin
+ */
+struct rte_pdev *
+rte_pdev_next_get(struct rte_device *dev, struct rte_pdev *pdev);
+
+/**
+ * PDEV Create API
+ */
+
+/** PDEV statistics counter type. */
+enum rte_pdev_stats_type {
+	/** Number of packets. */
+	RTE_PDEV_STATS_N_PKTS = 1 << 0,
+
+	/** Number of packet bytes. */
+	RTE_PDEV_STATS_N_BYTES = 1 << 1,
+};
+
+/** PDEV parameters. */
+struct rte_pdev_params {
+	/** PDEV name. */
+	const char *name;
+
+	/** Statistics counters to be enabled.
+	 * @see enum rte_pdev_stats_type
+	 */
+	uint64_t stats_mask;
+};
+
+/**
+ * PDEV create
+ *
+ * This API is to be called to create new pipelines on given device. This is
+ * typically supported by reconfigurable HW devices and SW pipelines.
+ *
+ * @param[in] dev
+ *   Current device.
+ * @param[in] params
+ *   PDEV parameters. Must be non-NULL and valid.
+ * @return
+ *   When non-NULL, handle to created PDEV, otherwise error.
+ *
+ * @see struct rte_pdev_capabilities::create
+ */
+struct rte_pdev *
+rte_pdev_create(struct rte_device *dev,
+	struct rte_pdev_params *params);
+
+/**
+ * PDEV free
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_free(struct rte_pdev *pdev);
+
+/**
+ * PDEV start
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_start(struct rte_pdev *pdev);
+
+/** PDEV input port types. */
+enum rte_pdev_port_in_type {
+	/** Builtin device. */
+	RTE_PDEV_PORT_IN_BUILTIN = 0,
+
+	/** Ethernet device. */
+	RTE_PDEV_PORT_IN_ETHDEV,
+};
+
+/** PDEV input port parameters. */
+struct rte_pdev_port_in_params {
+	/** Type. */
+	enum rte_pdev_port_in_type type;
+
+	/** Device specific parameters. */
+	union {
+		/** Builtin device. */
+		struct {
+			/** Builtin device name. */
+			const char *name;
+		} builtin;
+
+		/** Ethernet device. */
+		struct {
+			/** Ethernet device name. */
+			const char *name;
+
+			/** Reception side queue ID. */
+			uint32_t rx_queue_id;
+
+			/** Burst size. */
+			uint32_t burst_size;
+		} ethdev;
+	} dev;
+};
+
+/**
+ * PDEV input port create
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] port_id
+ *   PDEV input port ID. Must not be used by any existing *pdev* input port.
+ * @params[in] params
+ *   Input port parameters. Must be non-NULL and valid.
+ * @params[in] enable
+ *   When non-zero, the new input port is initially enabled, otherwise disabled.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_in_create(struct rte_pdev *pdev,
+	uint32_t port_id,
+	struct rte_pdev_port_in_params *params,
+	int enable);
+
+/**
+ * PDEV input port connect to table
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] port_id
+ *   Input port ID.
+ * @params[in] table_id
+ *   Table ID.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_in_connect(struct rte_pdev *pdev,
+	uint32_t port_id,
+	uint32_t table_id);
+
+/** PDEV table match type. */
+enum rte_pdev_table_match_type {
+	/**  Wildcard match. */
+	RTE_PDEV_TABLE_MATCH_WILDCARD = 0,
+
+	/** Exact match. */
+	RTE_PDEV_TABLE_MATCH_EXACT,
+
+	/** Longest Prefix Match (LPM). */
+	RTE_PDEV_TABLE_MATCH_LPM,
+
+	/** Index match. */
+	RTE_PDEV_TABLE_MATCH_INDEX,
+
+	/** Stub match. No real match process: the default rule is always hit. */
+	RTE_PDEV_TABLE_MATCH_STUB,
+};
+
+/** PDEV table match parameters. */
+struct rte_pdev_table_match_params {
+	/** Packet field or packet meta-data field name at match offset 0. */
+	const char *start;
+
+	/** Match size (in bits).
+	 *
+	 * For LPM match type, typical values are 32 bits to match a single IPv4
+	 * address and 128 bits to match a single IPv6 address, but other values
+	 * are possible, for example for Virtual Routing and Forwarding (VRF).
+	 *
+	 * For INDEX match type, the maximum allowed value is 32 bits.
+	 */
+	uint32_t size;
+
+	/** Match mask (*size* bits are used and must be valid).
+	 *
+	 * For LPM match type, this parameter is ignored, as *size* implicitly
+	 * defines *mask* as *size* bits of 1.
+	 */
+	uint8_t *mask;
+};
+
+/** PDEV exact match table parameters. */
+struct rte_pdev_table_exact_match_params {
+	/** Number of hash table buckets. This parameter represents a hint that
+	 * the underlying implementation may ignore.
+	 */
+	uint32_t n_buckets;
+
+	/** Hash table type. Non-zero for extendable bucket hash table, zero for
+	 * Least Recently Used (LRU) hash table.
+	 */
+	int extendable_bucket;
+};
+
+/** PDEV table parameters. */
+struct rte_pdev_table_params {
+	/** Match type. */
+	enum rte_pdev_table_match_type match_type;
+
+	/** Match parameters. Ignored for STUB match type. */
+	struct rte_pdev_table_match_params match;
+
+	/** Match type specific parameters. */
+	RTE_STD_C11
+	union {
+		/** Exact match table specific parameters. */
+		struct rte_pdev_table_exact_match_params exact;
+	};
+
+	/** Maximum number of rules to be stored in the current table. */
+	uint32_t n_rules;
+};
+
+/**
+ * PDEV table create
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] table_id
+ *   PDEV table ID. Must not be used by any existing *pdev* table.
+ * @params[in] params
+ *   Table parameters. Must be non-NULL and valid.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_create(struct rte_pdev *pdev,
+	uint32_t table_id,
+	struct rte_pdev_table_params *params);
+
+/** PDEV output port type. */
+enum rte_pdev_port_out_type {
+	/** Builtin device. */
+	RTE_PDEV_PORT_OUT_BUILTIN = 0,
+
+	/** Ethernet device. */
+	RTE_PDEV_PORT_OUT_ETHDEV,
+
+	/** Drop all packets device. */
+	RTE_PDEV_PORT_OUT_DROP,
+};
+
+/** PDEV output port parameters. */
+struct rte_pdev_port_out_params {
+	/** Type. */
+	enum rte_pdev_port_out_type type;
+
+	/** Device specific parameters. */
+	union {
+		/** Builtin device. */
+		struct {
+			/** Builtin device name. */
+			const char *name;
+		} builtin;
+
+		/** Ethernet device. */
+		struct {
+			/** Ethernet device name. */
+			const char *name;
+
+			/** Transmission side queue ID. */
+			uint32_t tx_queue_id;
+
+			/** Burst size. */
+			uint32_t burst_size;
+		} ethdev;
+	} dev;
+};
+
+/**
+ * PDEV output port create
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] port_id
+ *   PDEV output port ID. Must not be used by any existing *pdev* output port.
+ * @params[in] params
+ *   Output port parameters. Must be non-NULL and valid.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_out_create(struct rte_pdev *pdev,
+	uint32_t port_id,
+	struct rte_pdev_port_out_params *params);
+
+/**
+ * PDEV meta-data definition API
+ */
+
+/**
+ * PDEV packet field registration.
+ *
+ * Create symbolic alias for a protocol header or header field in the input
+ * packet. This alias can then be used as part of assignment actions registered
+ * for PDEV input ports, tables or output ports, either as left hand side value
+ * or as one of the right hand side expression operands, as appropriate. The
+ * packet field registered with the name of "x" is used as "pkt.x".
+ *
+ * This alias is typically translated to its offset and size, which are then
+ * used during the execution of assignment actions to access the associated data
+ * bytes within the packet.
+ *
+ * The scope of the packet field aliases is the PDEV instance. The attributes
+ * such as offset or size cannot be changed after the alias registration. This
+ * approach assumes the input packet type is known in advance, as opposed to
+ * having each input packet parsed to detect its type. This is a reasonable
+ * assumption, given that NIC capabilities to filter each packet type to a
+ * different RX queue are quite common; the NIC is configured transparently to
+ * the PDEV, with each NIC RX queue mapped as different PDEV input port.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] name
+ *   Symbolic alias for the input packet header or header field.
+ * @params[in] offset
+ *   Byte offset within the input packet. Offset 0 points to the first byte of
+ *   the packet.
+ * @params[in] size
+ *   Field size (in bytes).
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_pkt_field_register(struct rte_pdev *pdev,
+	const char *name,
+	uint32_t offset,
+	uint32_t size);
+
+/**
+ * PDEV packet meta-data field registration.
+ *
+ * Reserve field into the packet meta-data and assign a symbolic alias to it.
+ * This alias can then be used as part of assignment actions registered for PDEV
+ * input ports, tables and output ports, either as left hand side value or as
+ * one of the right hand side expression operands, as appropriate. The packet
+ * meta-data field registered with the name of "x" is used as "meta.x".
+ *
+ * Each input packet has its own private memory area reserved to store its
+ * meta-data, which is valid for the lifetime of the packet within the PDEV.
+ * This alias is typically translated to its offset and size, which are then
+ * used during the execution of assignment actions to access the associated
+ * packet meta-data bytes.
+ *
+ * The scope of the packet meta-data field aliases is the PDEV instance,
+ * therefore the meta-data layout is commmon for all the PDEV input packets.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] name
+ *   Symbolic alias for the packet meta-data field.
+ * @params[in] size
+ *   Field size (in bytes).
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_pkt_meta_field_register(struct rte_pdev *pdev,
+	const char *name,
+	uint32_t size);
+
+/**
+ * PDEV table rule data field registration.
+ *
+ * Reserve field into the table rule data and assign a symbolic alias to it.
+ * This alias can then be used as part of assignment actions registered for PDEV
+ * tables, either as left hand side value or as one of the right hand side
+ * expression operands, as appropriate. The table rule data field registered
+ * with the name of "x" is used as "table.x".
+ *
+ * This alias is typically translated to its offset and size, which are then
+ * used during the execution of assignment actions to access the associated
+ * table rule data bytes.
+ *
+ * The table rule data layout is common for all the rules of a given table that
+ * share the same action profile, therefore the scope of the table rule data
+ * field alias is its (table, action profile) pair.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] table_id
+ *   PDEV table ID.
+ * @params[in] action_profile_id
+ *   Table action profile ID.
+ * @params[in] name
+ *   Symbolic alias for the table rule data field.
+ * @params[in] size
+ *   Field size (in bytes).
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_field_register(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint32_t action_profile_id,
+	const char *name,
+	uint32_t size);
+
+/**
+ * PDEV input port action API
+ */
+enum rte_pdev_port_in_action_type {
+	/** Assignment: lvalue = expression. */
+	RTE_PDEV_PORT_IN_ACTION_ASSIGN = 0,
+};
+
+/**
+ * RTE_PDEV_PORT_IN_ACTION_ASSIGN
+ */
+struct rte_pdev_port_in_action_assign_config {
+	/** Left hand side value for the assignment. Must be one of the
+	 * pre-registered packet meta-data field symbolic aliases. Packet field
+	 * and table rule data field symbolic aliases are not allowed.
+	 */
+	const char *lvalue;
+
+	/** Expression with operands and operators. The operands must be
+	 * pre-registered packet or packet meta-data field symbolic aliases.
+	 * Table rule data field aliases are not allowed.
+	 */
+	const char *expression;
+};
+
+/**
+ * PDEV input port action profile create
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] profile_id
+ *   Input port action profile ID. Must not be used by any existing *pdev* input
+ *   port action profile.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_in_action_profile_create(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/**
+ * PDEV input port action profile action register
+ *
+ * The action registration order is important, as it determines the action
+ * execution order. The same action type can be registered several times for the
+ * same profile.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] profile_id
+ *   Input port action profile ID.
+ * @params[in] action_type
+ *   Input port action type.
+ * @params[in] action_config
+ *   Input port action configuration. For input port action X, this parameter
+ *   needs to point to pre-allocated and valid instance of struct
+ *   rte_pdev_port_in_action_X_config.
+ *   Input port action configuration. For input port action X, this parameter
+ *   must point to valid instance of struct rte_pdev_port_in_action_X_config
+ *   when this structure is defined by the API or to NULL otherwise.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_in_action_profile_action_register(struct rte_pdev *pdev,
+	uint32_t profile_id,
+	enum rte_pdev_port_in_action_type action_type,
+	void *action_config);
+
+/**
+ * PDEV input port action profile freeze
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] profile_id
+ *   Input port action profile ID.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_in_action_profile_freeze(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/**
+ * PDEV input port action profile register
+ *
+ * Zero or at most one action profile can be registered for each input port.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] port_id
+ *   PDEV input port ID.
+ * @params[in] profile_id
+ *   Input port action profile ID.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_in_action_profile_register(struct rte_pdev *pdev,
+	uint32_t port_id,
+	uint32_t profile_id);
+
+/**
+ * PDEV table action API
+ *
+ * For some actions below (e.g. packet encapsulations, NAT, statistics, etc),
+ * the same effect can be obtained through a sequence of assignment actions, but
+ * usually this approach is significantly less performant than using specialized
+ * actions.
+ *
+ * Some of the actions below (e.g. metering, timestamp update, etc) require the
+ * definition of specialized actions.
+ */
+enum rte_pdev_table_action_type {
+	/** Assignment: lvalue = expression. */
+	RTE_PDEV_TABLE_ACTION_ASSIGN = 0,
+
+	/** Load balancing. */
+	RTE_PDEV_TABLE_ACTION_LB,
+
+	/** Traffic metering and policing. */
+	RTE_PDEV_TABLE_ACTION_METER,
+
+	/** Packet encapsulation. */
+	RTE_PDEV_TABLE_ACTION_ENCAP,
+
+	/** Network Address Translation (NAT). */
+	RTE_PDEV_TABLE_ACTION_NAT,
+
+	/** Time to Leave (TTL) update. */
+	RTE_PDEV_TABLE_ACTION_TTL,
+
+	/** Statistics per table rule. */
+	RTE_PDEV_TABLE_ACTION_STATS,
+
+	/** Time stamp update. */
+	RTE_PDEV_TABLE_ACTION_TIME,
+};
+
+/**
+ * RTE_PDEV_TABLE_ACTION_ASSIGN
+ */
+struct rte_pdev_table_action_assign_config {
+	/** Left hand side value for the assignment. Must be one of the
+	 * pre-registered packet, packet meta-data or table field symbolic
+	 * aliases.
+	 */
+	const char *lvalue;
+
+	/** Expression with operands and operators. The operands must be
+	 * pre-registered packet, packet meta-data or table field symbolic
+	 * aliases.
+	 */
+	const char *expression;
+};
+
+/**
+ * RTE_PDEV_TABLE_ACTION_LB
+ */
+/** Load balance action configuration (per table action profile). */
+struct rte_pdev_table_action_lb_config {
+	/** Hash key parameters. */
+	struct rte_pdev_table_match_params hash_key;
+
+	/** Hash function name. This parameter represents a hint that the
+	 * underlying implementation may ignore.
+	 */
+	const char *hash_func;
+
+	/** Hash function seed value. This parameter represents a hint that the
+	 * underlying implementation may ignore.
+	 */
+	uint64_t hash_seed;
+
+	/** Number of elements in the table storing the output values. */
+	uint32_t table_size;
+
+	/** Packet meta-data field name where the output value should be saved. */
+	const char *out;
+};
+
+/** Load balance action parameters (per table rule). */
+struct rte_pdev_table_action_lb_params {
+	/** Table defining the output values and their weights. Needs to be
+	 * pre-allocated with exactly *table_size* elements. The weights are set
+	 * in 1 / *table_size* increments. To assign a weight of N / *table_size*
+	 * to a given output value (0 <= N <= *table_size*), the same output
+	 * value needs to show up exactly N times in this table.
+	 */
+	uint32_t *table;
+};
+
+/**
+ * RTE_PDEV_TABLE_ACTION_MTR
+ */
+/** Packet color. */
+enum rte_pdev_meter_color {
+	RTE_PDEV_METER_COLOR_GREEN = 0, /**< Green. */
+	RTE_PDEV_METER_COLOR_YELLOW, /**< Yellow. */
+	RTE_PDEV_METER_COLOR_RED, /**< Red. */
+	RTE_PDEV_METER_COLORS /**< Number of colors. */
+};
+
+/** Differentiated Services Code Point (DSCP) translation table entry. */
+struct rte_pdev_dscp_table_entry {
+	/** Traffic class ID. Has to be strictly less than *n_tc*. */
+	uint32_t tc_id;
+
+	/** Packet input color. Used by the traffic metering algorithm in
+	 * color aware mode.
+	 */
+	enum rte_pdev_meter_color color;
+};
+
+/** DSCP translation table. */
+struct rte_pdev_dscp_table {
+	/** Array of DSCP table entries */
+	struct rte_pdev_dscp_table_entry entry[64];
+};
+
+/** Supported traffic metering algorithms. */
+enum rte_pdev_meter_algorithm {
+	/** Single Rate Three Color Marker (srTCM) - IETF RFC 2697. */
+	RTE_PDEV_METER_SRTCM_RFC2697,
+
+	/** Two Rate Three Color Marker (trTCM) - IETF RFC 2698. */
+	RTE_PDEV_METER_TRTCM_RFC2698,
+
+	/** Two Rate Three Color Marker (trTCM) - IETF RFC 4115. */
+	RTE_PDEV_METER_TRTCM_RFC4115,
+};
+
+/** Traffic metering profile (configuration template). */
+struct rte_pdev_meter_profile {
+	/** Traffic metering algorithm. */
+	enum rte_pdev_meter_algorithm alg;
+
+	RTE_STD_C11
+	union {
+		/** Items only valid when *alg* is set to srTCM - RFC 2697. */
+		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;
+		} srtcm_rfc2697;
+
+		/** Items only valid when *alg* is set to trTCM - RFC 2698. */
+		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;
+		} trtcm_rfc2698;
+
+		/** Items only valid when *alg* is set to trTCM - RFC 4115. */
+		struct {
+			/** Committed Information Rate (CIR) (bytes/second). */
+			uint64_t cir;
+
+			/** Excess Information Rate (EIR) (bytes/second). */
+			uint64_t eir;
+
+			/** Committed Burst Size (CBS) (byes). */
+			uint64_t cbs;
+
+			/** Excess Burst Size (EBS) (bytes). */
+			uint64_t ebs;
+		} trtcm_rfc4115;
+	};
+};
+
+/** Policer actions. */
+enum rte_pdev_policer {
+	/** Recolor the packet as green. */
+	RTE_PDEV_POLICER_COLOR_GREEN = 0,
+
+	/** Recolor the packet as yellow. */
+	RTE_PDEV_POLICER_COLOR_YELLOW,
+
+	/** Recolor the packet as red. */
+	RTE_PDEV_POLICER_COLOR_RED,
+
+	/** Drop the packet. */
+	RTE_PDEV_POLICER_DROP,
+};
+
+/** Meter action configuration per traffic class. */
+struct rte_pdev_table_action_mtr_tc_params {
+	/** Meter profile ID. */
+	uint32_t meter_profile_id;
+
+	/** Policer actions. */
+	enum rte_pdev_policer policer[RTE_PDEV_METER_COLORS];
+};
+
+/** Meter action statistics counters per traffic class. */
+struct rte_pdev_table_action_mtr_tc_counters {
+	/** Number of packets per color at the output of the traffic metering
+	 * and before the policer actions are executed. Only valid when
+	 * *n_packets_valid* is non-zero.
+	 */
+	uint64_t n_packets[RTE_PDEV_METER_COLORS];
+
+	/** Number of packet bytes per color at the output of the traffic
+	 * metering and before the policer actions are executed. Only valid when
+	 * *n_bytes_valid* is non-zero.
+	 */
+	uint64_t n_bytes[RTE_PDEV_METER_COLORS];
+
+	/** When non-zero, the *n_packets* field is valid. */
+	int n_packets_valid;
+
+	/** When non-zero, the *n_bytes* field is valid. */
+	int n_bytes_valid;
+};
+
+/** Meter action configuration (per table action profile). */
+struct rte_pdev_table_action_mtr_config {
+	/** Packet field for IP header. */
+	const char *ip;
+
+	/** IP protocol version. Non-zero for IPv4, zero for IPv6. */
+	int ip_version;
+
+	/** DSCP translation table. */
+	struct rte_pdev_dscp_table *dscp_table;
+
+	/** Number of traffic classes. Each traffic class has its own traffic
+	 * meter and policer instances.
+	 */
+	uint32_t n_tc;
+
+	/** Meter algorithm. */
+	enum rte_pdev_meter_algorithm alg;
+
+	/** When non-zero, the *n_packets* meter stats counter is enabled,
+	 * otherwise it is disabled.
+	 *
+	 * @see struct rte_pdev_table_action_mtr_tc_counters
+	 */
+	int n_packets_enabled;
+
+	/** When non-zero, the *n_bytes* meter stats counter is enabled,
+	 * otherwise it is disabled.
+	 *
+	 * @see struct rte_pdev_table_action_mtr_tc_counters
+	 */
+	int n_bytes_enabled;
+};
+
+/** Meter action parameters (per table rule). */
+struct rte_pdev_table_action_mtr_params {
+	/** Traffic meter and policer parameters for all traffic classes. Array
+	 * of *n_tc* elements.
+	 */
+	struct rte_pdev_table_action_mtr_tc_params *mtr;
+};
+
+/** Meter action statistics counters (per table rule). */
+struct rte_pdev_table_action_mtr_counters {
+	/** Stats counters for all traffic classes. Array of *n_tc* elements. */
+	struct rte_pdev_table_action_mtr_tc_counters *stats;
+};
+
+/**
+ * RTE_PDEV_TABLE_ACTION_ENCAP
+ */
+/** Supported packet encapsulation types. */
+enum rte_pdev_encap_type {
+	/** IP -> { Ether | IP } */
+	RTE_PDEV_ENCAP_ETHER = 0,
+
+	/** IP -> { Ether | VLAN | IP } */
+	RTE_PDEV_ENCAP_VLAN,
+
+	/** IP -> { Ether | S-VLAN | C-VLAN | IP } */
+	RTE_PDEV_ENCAP_QINQ,
+
+	/** IP -> { Ether | MPLS | IP } */
+	RTE_PDEV_ENCAP_MPLS,
+
+	/** IP -> { Ether | PPPoE | PPP | IP } */
+	RTE_PDEV_ENCAP_PPPOE,
+};
+
+/** Pre-computed Ethernet header fields for encapsulation action. */
+struct rte_pdev_ether_hdr {
+	struct ether_addr da; /**< Destination address. */
+	struct ether_addr sa; /**< Source address. */
+};
+
+/** Pre-computed VLAN header fields for encapsulation action. */
+struct rte_pdev_vlan_hdr {
+	uint8_t pcp; /**< Priority Code Point (PCP). */
+	uint8_t dei; /**< Drop Eligibility Indicator (DEI). */
+	uint16_t vid; /**< VLAN Identifier (VID). */
+};
+
+/** Pre-computed MPLS header fields for encapsulation action. */
+struct rte_pdev_mpls_hdr {
+	uint32_t label; /**< Label. */
+	uint8_t tc; /**< Traffic Class (TC). */
+	uint8_t ttl; /**< Time to Live (TTL). */
+};
+
+/** Pre-computed PPPoE header fields for encapsulation action. */
+struct rte_pdev_pppoe_hdr {
+	uint16_t session_id; /**< Session ID. */
+};
+
+/** Ether encap parameters. */
+struct rte_pdev_encap_ether_params {
+	struct rte_pdev_ether_hdr ether; /**< Ethernet header. */
+};
+
+/** VLAN encap parameters. */
+struct rte_pdev_encap_vlan_params {
+	struct rte_pdev_ether_hdr ether; /**< Ethernet header. */
+	struct rte_pdev_vlan_hdr vlan; /**< VLAN header. */
+};
+
+/** QinQ encap parameters. */
+struct rte_pdev_encap_qinq_params {
+	struct rte_pdev_ether_hdr ether; /**< Ethernet header. */
+	struct rte_pdev_vlan_hdr svlan; /**< Service VLAN header. */
+	struct rte_pdev_vlan_hdr cvlan; /**< Customer VLAN header. */
+};
+
+/** Max number of MPLS labels per output packet for MPLS encapsulation. */
+#ifndef RTE_PDEV_MPLS_LABELS_MAX
+#define RTE_PDEV_MPLS_LABELS_MAX                            4
+#endif
+
+/** MPLS encap parameters. */
+struct rte_pdev_encap_mpls_params {
+	/** Ethernet header. */
+	struct rte_pdev_ether_hdr ether;
+
+	/** MPLS header. */
+	struct rte_pdev_mpls_hdr mpls[RTE_PDEV_MPLS_LABELS_MAX];
+
+	/** Number of MPLS labels in MPLS header. */
+	uint32_t mpls_count;
+
+	/** Non-zero for MPLS unicast, zero for MPLS multicast. */
+	int unicast;
+};
+
+/** PPPoE encap parameters. */
+struct rte_pdev_encap_pppoe_params {
+	struct rte_pdev_ether_hdr ether; /**< Ethernet header. */
+	struct rte_pdev_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */
+};
+
+/** Encap action configuration (per table action profile). */
+struct rte_pdev_table_action_encap_config {
+	/** Packet field for IP header. */
+	const char *ip;
+
+	/** IP protocol version. Non-zero for IPv4, zero for IPv6. */
+	int ip_version;
+
+	/** Bit mask defining the set of packet encapsulations enabled for the
+	 * current table action profile. If bit (1 << N) is set in *encap_mask*,
+	 * then packet encapsulation N is enabled, otherwise it is disabled.
+	 *
+	 * @see enum rte_pdev_encap_type
+	 */
+	uint64_t encap_mask;
+};
+
+/** Encap action parameters (per table rule). */
+struct rte_pdev_table_action_encap_params {
+	/** Encapsulation type. */
+	enum rte_pdev_encap_type type;
+
+	RTE_STD_C11
+	union {
+		/** Only valid when *type* is set to Ether. */
+		struct rte_pdev_encap_ether_params ether;
+
+		/** Only valid when *type* is set to VLAN. */
+		struct rte_pdev_encap_vlan_params vlan;
+
+		/** Only valid when *type* is set to QinQ. */
+		struct rte_pdev_encap_qinq_params qinq;
+
+		/** Only valid when *type* is set to MPLS. */
+		struct rte_pdev_encap_mpls_params mpls;
+
+		/** Only valid when *type* is set to PPPoE. */
+		struct rte_pdev_encap_pppoe_params pppoe;
+	};
+};
+
+/**
+ * RTE_PDEV_TABLE_ACTION_NAT
+ */
+/** NAT action configuration (per table action profile). */
+struct rte_pdev_table_action_nat_config {
+	/** Packet field for IP header. */
+	const char *ip;
+
+	/** IP protocol version. Non-zero for IPv4, zero for IPv6. */
+	int ip_version;
+
+	/** When non-zero, the IP source address and L4 protocol source port are
+	 * translated. When zero, the IP destination address and L4 protocol
+	 * destination port are translated.
+	 */
+	int source_nat;
+
+	/** Layer 4 protocol, for example TCP (0x06) or UDP (0x11). The checksum
+	 * field is computed differently and placed at different header offset
+	 * by each layer 4 protocol.
+	 */
+	uint8_t proto;
+};
+
+/** NAT action parameters (per table rule). */
+struct rte_pdev_table_action_nat_params {
+	/** IP version for *addr*: non-zero for IPv4, zero for IPv6. */
+	int ip_version;
+
+	/** IP address. */
+	union {
+		/** IPv4 address; only valid when *ip_version* is IPv4. */
+		uint32_t ipv4;
+
+		/** IPv6 address; only valid when *ip_version* is IPv6. */
+		uint8_t ipv6[16];
+	} addr;
+
+	/** Port. */
+	uint16_t port;
+};
+
+/**
+ * RTE_PDEV_TABLE_ACTION_TTL
+ */
+/** TTL action configuration (per table action profile). */
+struct rte_pdev_table_action_ttl_config {
+	/** Packet field for IP header. */
+	const char *ip;
+
+	/** IP protocol version. Non-zero for IPv4, zero for IPv6. */
+	int ip_version;
+
+	/** Packet meta-data field to be set to *port_out_id* when the updated
+	 * IPv4 Time to Live (TTL) field or IPv6 Hop Limit (HL) field is zero.
+	 */
+	const char *port_out;
+
+	/** Output port ID to be stored into *port_out* packet meta-data field
+	 * when the updated IPv4 TTL field or IPv6 HL field is zero.
+	 */
+	uint32_t port_out_id;
+
+	/** When non-zero, the *n_packets* stats counter for TTL action is
+	 * enabled, otherwise disabled.
+	 *
+	 * @see struct rte_pdev_table_action_ttl_counters
+	 */
+	int n_packets_enabled;
+};
+
+/** TTL action parameters (per table rule). */
+struct rte_pdev_table_action_ttl_params {
+	/** When non-zero, decrement the IPv4 TTL field and update the checksum
+	 * field, or decrement the IPv6 HL field. When zero, the IPv4 TTL field
+	 * or the IPv6 HL field is not changed.
+	 */
+	int decrement;
+};
+
+/** TTL action statistics packets (per table rule). */
+struct rte_pdev_table_action_ttl_counters {
+	/** Number of IPv4 packets whose updated TTL field is zero or IPv6
+	 * packets whose updated HL field is zero.
+	 */
+	uint64_t n_packets;
+};
+
+/**
+ * RTE_PDEV_TABLE_ACTION_STATS
+ */
+/** Stats action configuration (per table action profile). */
+struct rte_pdev_table_action_stats_config {
+	/** Packet field for IP header. */
+	const char *ip;
+
+	/** IP protocol version. Non-zero for IPv4, zero for IPv6. */
+	int ip_version;
+
+	/** When non-zero, the *n_packets* stats counter is enabled, otherwise
+	 * disabled.
+	 *
+	 * @see struct rte_pdev_table_action_stats_counters
+	 */
+	int n_packets_enabled;
+
+	/** When non-zero, the *n_bytes* stats counter is enabled, otherwise
+	 * disabled.
+	 *
+	 * @see struct rte_pdev_table_action_stats_counters
+	 */
+	int n_bytes_enabled;
+};
+
+/** Stats action parameters (per table rule). */
+struct rte_pdev_table_action_stats_params {
+	/** Initial value for the *n_packets* stats counter. Typically set to 0.
+	 *
+	 * @see struct rte_pdev_table_action_stats_counters
+	 */
+	uint64_t n_packets;
+
+	/** Initial value for the *n_bytes* stats counter. Typically set to 0.
+	 *
+	 * @see struct rte_pdev_table_action_stats_counters
+	 */
+	uint64_t n_bytes;
+};
+
+/** Stats action counters (per table rule). */
+struct rte_pdev_table_action_stats_counters {
+	/** Number of packets. Valid only when *n_packets_valid* is non-zero. */
+	uint64_t n_packets;
+
+	/** Number of bytes. Valid only when *n_bytes_valid* is non-zero. */
+	uint64_t n_bytes;
+
+	/** When non-zero, the *n_packets* field is valid, otherwise invalid. */
+	int n_packets_valid;
+
+	/** When non-zero, the *n_bytes* field is valid, otherwise invalid. */
+	int n_bytes_valid;
+};
+
+/**
+ * RTE_PDEV_TABLE_ACTION_TIME
+ */
+/** Timestamp action parameters (per table rule). */
+struct rte_pdev_table_action_time_params {
+	/** Initial timestamp value. Typically set to current time. */
+	uint64_t time;
+};
+
+/**
+ * PDEV table action profile create
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] profile_id
+ *   Table action profile ID. Must not be used by any existing *pdev* table
+ *   action profile.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_action_profile_create(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/**
+ * PDEV table action profile action register
+ *
+ * The action registration order is important, as it determines the action
+ * execution order. The same action type can be registered several times for the
+ * same profile. 
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] profile_id
+ *   Table action profile ID.
+ * @params[in] action_type
+ *   Table action type.
+ * @params[in] action_config
+ *   Table action configuration. For table action X, this parameter must point
+ *   to valid instance of struct rte_pdev_table_action_X_config when this
+ *   structure is defined by the API or to NULL otherwise.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_action_profile_action_register(struct rte_pdev *pdev,
+	uint32_t profile_id,
+	enum rte_pdev_table_action_type action_type,
+	void *action_config);
+
+/**
+ * PDEV table action profile freeze
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] profile_id
+ *   Table action profile ID.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_action_profile_freeze(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/**
+ * PDEV table action profile register
+ *
+ * Zero or several action profiles can be registered for each table.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] table_id
+ *   PDEV table ID.
+ * @params[in] profile_id
+ *   Table action profile ID.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_action_profile_register(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint32_t profile_id);
+
+/**
+ * PDEV output port action API
+ */
+enum rte_pdev_port_out_action_type {
+	/** Assignment: lvalue = expression. */
+	RTE_PDEV_PORT_OUT_ACTION_ASSIGN = 0,
+};
+
+/**
+ * RTE_PDEV_PORT_OUT_ACTION_ASSIGN
+ */
+struct rte_pdev_port_out_action_assign_config {
+	/** Left hand side value for the assignment. Must be one of the
+	 * pre-registered packet field symbolic aliases. Packet meta-data field
+	 * and table rule data field aliases are not allowed.
+	 */
+	const char *lvalue;
+
+	/** Expression with operands and operators. The operands must be
+	 * pre-registered packet or packet meta-data field symbolic aliases.
+	 * Table rule data field aliases are not allowed.
+	 */
+	const char *expression;
+};
+
+/**
+ * PDEV output port action profile create
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] profile_id
+ *   Output port action profile ID. Must not be used by any existing *pdev*
+ *   output port action profile.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_out_action_profile_create(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/**
+ * PDEV output port action profile action register
+ *
+ * The action registration order is important, as it determines the action
+ * execution order. The same action type can be registered several times for the
+ * same profile. 
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] profile_id
+ *   Output port action profile ID.
+ * @params[in] action_type
+ *   Output port action type.
+ * @params[in] action_config
+ *   Output port action configuration. For output port action X, this parameter
+ *   must point to valid instance of struct rte_pdev_port_out_action_X_config
+ *   when this structure is defined by the API or to NULL otherwise. 
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_out_action_profile_action_register(struct rte_pdev *pdev,
+	uint32_t profile_id,
+	enum rte_pdev_port_out_action_type action_type,
+	void *action_config);
+
+/**
+ * PDEV output port action profile freeze
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] profile_id
+ *   Output port action profile ID.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_out_action_profile_freeze(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/**
+ * PDEV output port action profile register
+ *
+ * Zero or at most one action profile can be registered for each output port.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] port_id
+ *   PDEV output port ID.
+ * @params[in] profile_id
+ *   Output port action profile ID.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_out_action_profile_register(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint32_t profile_id);
+
+/**
+ * PDEV input port run-time API
+ */
+
+/**
+ * PDEV input port enable
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] port_id
+ *   PDEV input port ID.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_in_enable(struct rte_pdev *pdev,
+	uint32_t port_id);
+
+/**
+ * PDEV input port disable
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] port_id
+ *   PDEV input port ID.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_in_disable(struct rte_pdev *pdev,
+	uint32_t port_id);
+
+/** PDEV input port statistics counters. */
+struct rte_pdev_port_in_stats {
+	/** Number of packets read from this input port. */
+	uint64_t n_packets;
+
+	/** Number of bytes associated with *n_packets*. */
+	uint64_t n_bytes;
+};
+
+/**
+ * PDEV input port statistics counters read
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] port_id
+ *   PDEV input port ID.
+ * @params[out] stats
+ *   When non-NULL, the statistics counters are read and saved here.
+ * @params[in] clear
+ *   When non-zero, the statistics counters are cleared after read, otherwise
+ *   they are not modified.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_in_stats_read(struct rte_pdev *pdev,
+	uint32_t port_id,
+	struct rte_pdev_port_in_stats *stats,
+	int clear);
+
+/**
+ * PDEV table run-time API
+ */
+
+/**
+ * PDEV table rule add.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @param[in] table_id
+ *   PDEV table ID.
+ * @param[in] match
+ *   Rule match. For any match type, the NULL value indicates the default rule.
+ * @param[in] match_mask
+ *   Rule match bit-mask. Ignored when *match* is set to NULL. Ignored when
+ *   *table_id* match type is not WILDCARD or LPM.
+ * @param[in] match_priority
+ *   Rule match priority. Ignored when *match* is set to NULL. Ignored when
+ *   *table_id* match type is not WILDCARD.
+ * @param[in] action_profile_id
+ *   Table action profile ID.
+ * @param[in] action_params
+ *   Array of action parameters. The number of elements must be equal to the
+ *   number of actions registered for the *action_profile_id* table action
+ *   profile. If X is the N-th action registered for *action_profile_id*, then
+ *   the N-th element of this array needs to be pointer to valid instance of
+ *   struct rte_pdev_table_action_X_params when defined by the API or to NULL
+ *   otherwise.
+ * @param[out] rule_handle
+ *   Rule handle.
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_rule_add(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint8_t *match,
+	uint8_t *match_mask,
+	uint32_t match_priority,
+	uint32_t action_profile_id,
+	void **action_params,
+	void **rule_handle);
+
+/**
+ * PDEV table rule delete.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @param[in] table_id
+ *   PDEV table ID.
+ * @param[in] match
+ *   Rule match. For any match type, the NULL value indicates the default rule.
+ * @param[in] match_mask
+ *   Rule match bit-mask. Ignored when *match* is set to NULL. Ignored when
+ *   *table_id* match type is not WILDCARD or LPM.
+  * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_rule_delete(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint8_t *match,
+	uint8_t *match_mask);
+
+/**
+ * PDEV table DSCP table update.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @param[in] table_id
+ *   PDEV table ID.
+ * @param[in] dscp_table
+ *   DSCP table. Must be pre-allocated and valid.
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_dscp_table_update(struct rte_pdev *pdev,
+	uint32_t table_id,
+	struct rte_pdev_dscp_table *dscp_table);
+
+/**
+ * PDEV table meter profile add.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @param[in] table_id
+ *   PDEV table ID.
+ * @param[in] meter_profile_id
+ *   Meter profile ID. Must not be used by any existing *table_id* meter
+ *   profile.
+ * @param[in] profile
+ *   Meter profile parameters.
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_meter_profile_add(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint32_t meter_profile_id,
+	struct rte_pdev_meter_profile *profile);
+
+/**
+ * PDEV table meter profile delete.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @param[in] table_id
+ *   PDEV table ID.
+ * @param[in] meter_profile_id
+ *   Meter profile ID. Must be one of the existing *table_id* meter profiles.
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_meter_profile_delete(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint32_t meter_profile_id);
+
+/**
+ * PDEV table rule meter statistics counters read.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @param[in] table_id
+ *   PDEV table ID.
+ * @param[in] rule_handle
+ *   Rule handle.
+ * @params[out] stats
+ *   When non-NULL, the statistics counters are read and saved here.
+ * @params[in] clear
+ *   When non-zero, the statistics counters are cleared after read, otherwise
+ *   they are not modified.
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_rule_meter_read(struct rte_pdev *pdev,
+	uint32_t table_id,
+	void *rule_handle,
+	struct rte_pdev_table_action_mtr_counters *stats,
+	int clear);
+
+/**
+ * PDEV table rule TTL statistics counters read.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @param[in] table_id
+ *   PDEV table ID.
+ * @param[in] rule_handle
+ *   Rule handle.
+ * @params[out] stats
+ *   When non-NULL, the statistics counters are read and saved here.
+ * @params[in] clear
+ *   When non-zero, the statistics counters are cleared after read, otherwise
+ *   they are not modified.
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_rule_ttl_read(struct rte_pdev *pdev,
+	uint32_t table_id,
+	void *rule_handle,
+	struct rte_pdev_table_action_ttl_counters *stats,
+	int clear);
+
+/**
+ * PDEV table rule statistics counters read.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @param[in] table_id
+ *   PDEV table ID.
+ * @param[in] rule_handle
+ *   Rule handle.
+ * @params[out] stats
+ *   When non-NULL, the statistics counters are read and saved here.
+ * @params[in] clear
+ *   When non-zero, the statistics counters are cleared after read, otherwise
+ *   they are not modified.
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_rule_stats_read(struct rte_pdev *pdev,
+	uint32_t table_id,
+	void *rule_handle,
+	struct rte_pdev_table_action_stats_counters *stats,
+	int clear);
+
+/**
+ * PDEV table rule timestamp read.
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @param[in] table_id
+ *   PDEV table ID.
+ * @param[in] rule_handle
+ *   Rule handle.
+ * @param[out] timestamp
+ *   Current timestamp value. Must be non-NULL.
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_rule_timestamp_read(struct rte_pdev *pdev,
+	uint32_t table_id,
+	void *rule_handle,
+	uint64_t *timestamp);
+
+/** PDEV table statistics counters. */
+struct rte_pdev_table_stats {
+	/** Number of packets looked up in this table. */
+	uint64_t n_packets;
+
+	/** Number of bytes associated with *n_packets*. */
+	uint64_t n_bytes;	
+};
+
+/**
+ * PDEV table statistics counters read
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] table_id
+ *   PDEV table ID.
+ * @params[out] stats
+ *   When non-NULL, the statistics counters are read and saved here.
+ * @params[in] clear
+ *   When non-zero, the statistics counters are cleared after read, otherwise
+ *   they are not modified.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_table_stats_read(struct rte_pdev *pdev,
+	uint32_t table_id,
+	struct rte_pdev_table_stats *stats,
+	int clear);
+
+/**
+ * PDEV output port run-time API
+ */
+
+/** PDEV output port statistics counters. */
+struct rte_pdev_port_out_stats {
+	/** Number of packets written to this output port. */
+	uint64_t n_packets;
+
+	/** Number of bytes associated with *n_packets*. */
+	uint64_t n_bytes;
+};
+
+/**
+ * PDEV output port statistics counters read
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ * @params[in] port_id
+ *   PDEV output port ID.
+ * @params[out] stats
+ *   When non-NULL, the statistics counters are read and saved here.
+ * @params[in] clear
+ *   When non-zero, the statistics counters are cleared after read, otherwise
+ *   they are not modified.
+ * @return
+ *   0 on success, non-zero error code otherwise.
+ */
+int
+rte_pdev_port_out_stats_read(struct rte_pdev *pdev,
+	uint32_t port_id,
+	struct rte_pdev_port_out_stats *stats,
+	int clear);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_pipeline/rte_pdev_driver.h b/lib/librte_pipeline/rte_pdev_driver.h
new file mode 100644
index 0000000..4b97784
--- /dev/null
+++ b/lib/librte_pipeline/rte_pdev_driver.h
@@ -0,0 +1,283 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef __INCLUDE_RTE_PDEV_DRIVER_H__
+#define __INCLUDE_RTE_PDEV_DRIVER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ * RTE Pipeline Device (PDEV) - Device Driver Interface
+ */
+
+#include <stdint.h>
+
+#include "rte_pdev.h"
+
+/** @internal PDEV create */
+typedef struct rte_pdev * (*rte_pdev_create_t)(struct rte_device *dev,
+	struct rte_pdev_params *params);
+
+/** @internal PDEV free */
+typedef int (*rte_pdev_free_t)(struct rte_pdev *pdev);
+
+/** @internal PDEV start */
+typedef int (*rte_pdev_start_t)(struct rte_pdev *pdev);
+
+/** @internal PDEV input port create */
+typedef int (*rte_pdev_port_in_create_t)(struct rte_pdev *pdev,
+	uint32_t port_id,
+	struct rte_pdev_port_in_params *params,
+	int enable);
+
+/** @internal PDEV input port connect */
+typedef int (*rte_pdev_port_in_connect_t)(struct rte_pdev *pdev,
+	uint32_t port_id,
+	uint32_t table_id);
+
+/** @internal PDEV table create */
+typedef int (*rte_pdev_table_create_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	struct rte_pdev_table_params *params);
+
+/** @internal PDEV output port create */
+typedef int (*rte_pdev_port_out_create_t)(struct rte_pdev *pdev,
+	uint32_t port_id,
+	struct rte_pdev_port_out_params *params);
+
+/** @internal PDEV packet field register */
+typedef int (*rte_pdev_pkt_field_register_t)(struct rte_pdev *pdev,
+	const char *name,
+	uint32_t offset,
+	uint32_t size);
+
+/** @internal PDEV packet meta-data field register */
+typedef int (*rte_pdev_pkt_meta_field_register_t)(struct rte_pdev *pdev,
+	const char *name,
+	uint32_t size);
+
+/** @internal PDEV table rule data field register */
+typedef int (*rte_pdev_table_field_register_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint32_t action_profile_id,
+	const char *name,
+	uint32_t size);
+
+/** @internal PDEV input port action profile create */
+typedef int (*rte_pdev_port_in_action_profile_create_t)(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/** @internal PDEV input port action profile action register */
+typedef int (*rte_pdev_port_in_action_profile_action_register_t)(struct rte_pdev *pdev,
+	uint32_t profile_id,
+	enum rte_pdev_port_in_action_type action_type,
+	void *action_config);
+
+/** @internal PDEV input port action profile freeze */
+typedef int (*rte_pdev_port_in_action_profile_freeze_t)(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/** @internal PDEV input port action profile register */
+typedef int (*rte_pdev_port_in_action_profile_register_t)(struct rte_pdev *pdev,
+	uint32_t port_id,
+	uint32_t profile_id);
+
+/** @internal PDEV table action profile create */
+typedef int (*rte_pdev_table_action_profile_create_t)(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/** @internal PDEV table action profile action register */
+typedef int (*rte_pdev_table_action_profile_action_register_t)(struct rte_pdev *pdev,
+	uint32_t profile_id,
+	enum rte_pdev_table_action_type action_type,
+	void *action_config);
+
+/** @internal PDEV table action profile freeze */
+typedef int (*rte_pdev_table_action_profile_freeze_t)(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/** @internal PDEV table action profile register */
+typedef int (*rte_pdev_table_action_profile_register_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint32_t profile_id);
+
+/** @internal PDEV output port action profile create */
+typedef int (*rte_pdev_port_out_action_profile_create_t)(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/** @internal PDEV output port action profile action register */
+typedef int (*rte_pdev_port_out_action_profile_action_register_t)(struct rte_pdev *pdev,
+	uint32_t profile_id,
+	enum rte_pdev_port_out_action_type action_type,
+	void *action_config);
+
+/** @internal PDEV output port action profile freeze */
+typedef int (*rte_pdev_port_out_action_profile_freeze_t)(struct rte_pdev *pdev,
+	uint32_t profile_id);
+
+/** @internal PDEV output port action profile register */
+typedef int (*rte_pdev_port_out_action_profile_register_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint32_t profile_id);
+
+/** @internal PDEV input port enable */
+typedef int (*rte_pdev_port_in_enable_t)(struct rte_pdev *pdev,
+	uint32_t port_id);
+
+/** @internal PDEV input port disable */
+typedef int (*rte_pdev_port_in_disable_t)(struct rte_pdev *pdev,
+	uint32_t port_id);
+
+/** @internal PDEV input port stats read */
+typedef int (*rte_pdev_port_in_stats_read_t)(struct rte_pdev *pdev,
+	uint32_t port_id,
+	struct rte_pdev_port_in_stats *stats,
+	int clear);
+
+/** @internal PDEV table rule add */
+typedef int (*rte_pdev_table_rule_add_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint8_t *match,
+	uint8_t *match_mask,
+	uint32_t match_priority,
+	uint32_t action_profile_id,
+	void **action_params,
+	void **rule_handle);
+
+/** @internal PDEV table rule delete */
+typedef int (*rte_pdev_table_rule_delete_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint8_t *match,
+	uint8_t *match_mask);
+
+/** @internal PDEV table DSCP table update */
+typedef int (*rte_pdev_table_dscp_table_update_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	struct rte_pdev_dscp_table *dscp_table);
+
+/** @internal PDEV table meter profile add */
+typedef int (*rte_pdev_table_meter_profile_add_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint32_t meter_profile_id,
+	struct rte_pdev_meter_profile *profile);
+
+/** @internal PDEV table meter profile delete */
+typedef int (*rte_pdev_table_meter_profile_delete_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	uint32_t meter_profile_id);
+
+/** @internal PDEV table rule meter stats read */
+typedef int (*rte_pdev_table_rule_meter_read_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	void *rule_handle,
+	struct rte_pdev_table_action_mtr_counters *stats,
+	int clear);
+
+/** @internal PDEV table rule TTL stats read */
+typedef int (*rte_pdev_table_rule_ttl_read_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	void *rule_handle,
+	struct rte_pdev_table_action_ttl_counters *stats,
+	int clear);
+
+/** @internal PDEV table rule stats read */
+typedef int (*rte_pdev_table_rule_stats_read_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	void *rule_handle,
+	struct rte_pdev_table_action_stats_counters *stats,
+	int clear);
+
+/** @internal PDEV table rule tiemstamp read */
+typedef int (*rte_pdev_table_rule_timestamp_read_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	void *rule_handle,
+	uint64_t *timestamp);
+
+/** @internal PDEV table stats read */
+typedef int (*rte_pdev_table_stats_read_t)(struct rte_pdev *pdev,
+	uint32_t table_id,
+	struct rte_pdev_table_stats *stats,
+	int clear);
+
+/** @internal PDEV output port stats read */
+typedef int (*rte_pdev_port_out_stats_read_t)(struct rte_pdev *pdev,
+	uint32_t port_id,
+	struct rte_pdev_port_out_stats *stats,
+	int clear);
+
+/** PDEV ops */
+struct rte_pdev_ops {
+	/** PDEV create API */
+	rte_pdev_create_t create;
+	rte_pdev_free_t free;
+	rte_pdev_start_t start;
+	rte_pdev_port_in_create_t port_in_create;
+	rte_pdev_port_in_connect_t port_in_connect;
+	rte_pdev_table_create_t table_create;
+	rte_pdev_port_out_create_t port_out_create;
+
+	/** PDEV meta-data API */
+	rte_pdev_pkt_field_register_t pkt_field_register;
+	rte_pdev_pkt_meta_field_register_t pkt_meta_field_register;
+	rte_pdev_table_field_register_t table_field_register;
+
+	/** PDEV input port action API */
+	rte_pdev_port_in_action_profile_create_t port_in_action_profile_create;
+	rte_pdev_port_in_action_profile_action_register_t port_in_action_profile_action_register;
+	rte_pdev_port_in_action_profile_freeze_t port_in_action_profile_freeze;
+	rte_pdev_port_in_action_profile_register_t port_in_action_profile_register;
+
+	/** PDEV table action API */
+	rte_pdev_table_action_profile_create_t table_action_profile_create;
+	rte_pdev_table_action_profile_action_register_t table_action_profile_action_register;
+	rte_pdev_table_action_profile_freeze_t table_action_profile_freeze;
+	rte_pdev_table_action_profile_register_t table_action_profile_register;
+
+	/** PDEV output port action API */
+	rte_pdev_port_out_action_profile_create_t port_out_action_profile_create;
+	rte_pdev_port_out_action_profile_action_register_t port_out_action_profile_action_register;
+	rte_pdev_port_out_action_profile_freeze_t port_out_action_profile_freeze;
+	rte_pdev_port_out_action_profile_register_t port_out_action_profile_register;
+
+	/** PDEV input port run-time API */
+	rte_pdev_port_in_enable_t port_in_enable;
+	rte_pdev_port_in_disable_t port_in_disable;
+	rte_pdev_port_in_stats_read_t port_in_stats_read;
+
+	/** PDEV table run-time API */
+	rte_pdev_table_rule_add_t table_rule_add;
+	rte_pdev_table_rule_delete_t table_rule_delete;
+	rte_pdev_table_dscp_table_update_t table_dscp_table_update;
+	rte_pdev_table_meter_profile_add_t table_meter_profile_add;
+	rte_pdev_table_meter_profile_delete_t table_meter_profile_delete;
+	rte_pdev_table_rule_meter_read_t table_rule_meter_read;
+	rte_pdev_table_rule_ttl_read_t table_rule_ttl_read;
+	rte_pdev_table_rule_stats_read_t table_rule_stats_read;
+	rte_pdev_table_rule_timestamp_read_t table_rule_timestamp_read;
+	rte_pdev_table_stats_read_t table_stats_read;
+
+	/** PDEV output port run-time API */
+	rte_pdev_port_out_stats_read_t port_out_stats_read;	
+};
+
+/**
+ * Get PDEV ops
+ *
+ * @param[in] pdev
+ *   PDEV handle.
+ *
+ * @return
+ *   PDEV ops on success, NULL otherwise.
+ */
+const struct rte_pdev_ops *
+rte_pdev_ops_get(struct rte_pdev *pdev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
