diff --git a/lib/librte_pipeline/Makefile b/lib/librte_pipeline/Makefile
index c0eaa09..84afe98 100644
--- a/lib/librte_pipeline/Makefile
+++ b/lib/librte_pipeline/Makefile
@@ -22,9 +22,10 @@ LIBABIVER := 3
 # all source are stored in SRCS-y
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) := rte_pipeline.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += rte_port_in_action.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += rte_table_action.c
 
 # install includes
-SYMLINK-$(CONFIG_RTE_LIBRTE_PIPELINE)-include += rte_pipeline.h rte_table_action.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_PIPELINE)-include += rte_pipeline.h rte_port_in_action.h rte_table_action.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_pipeline/meson.build b/lib/librte_pipeline/meson.build
index 1ee276f..dc16ab4 100644
--- a/lib/librte_pipeline/meson.build
+++ b/lib/librte_pipeline/meson.build
@@ -3,6 +3,6 @@
 
 version = 3
 allow_experimental_apis = true
-sources = files('rte_pipeline.c', 'rte_table_action.c')
-headers = files('rte_pipeline.h', 'rte_table_action.h')
+sources = files('rte_pipeline.c', 'rte_port_in_action.c', 'rte_table_action.c')
+headers = files('rte_pipeline.h', 'rte_port_in_action.h', 'rte_table_action.h')
 deps += ['port', 'table', 'meter', 'sched']
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index 4e948b8..53d31a9 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -49,6 +49,14 @@ DPDK_16.04 {
 EXPERIMENTAL {
 	global:
 
+	rte_port_in_action_apply;
+	rte_port_in_action_create;
+	rte_port_in_action_free;
+	rte_port_in_action_params_get;
+	rte_port_in_action_profile_action_register;
+	rte_port_in_action_profile_create;
+	rte_port_in_action_profile_free;
+	rte_port_in_action_profile_freeze;
 	rte_table_action_apply;
 	rte_table_action_create;
 	rte_table_action_dscp_table_update;
diff --git a/lib/librte_pipeline/rte_port_in_action.c b/lib/librte_pipeline/rte_port_in_action.c
new file mode 100644
index 0000000..e3b00df
--- /dev/null
+++ b/lib/librte_pipeline/rte_port_in_action.c
@@ -0,0 +1,531 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+
+#include "rte_port_in_action.h"
+
+/**
+ * RTE_PORT_IN_ACTION_FLTR
+ */
+static int
+fltr_cfg_check(struct rte_port_in_action_fltr_config *cfg)
+{
+	if (cfg == NULL)
+		return -1;
+
+	return 0;
+}
+
+struct fltr_data {
+	uint32_t port_id;
+};
+
+static void
+fltr_init(struct fltr_data *data,
+	struct rte_port_in_action_fltr_config *cfg)
+{
+	data->port_id = cfg->port_id;
+}
+
+static int
+fltr_apply(struct fltr_data *data,
+	struct rte_port_in_action_fltr_params *p)
+{
+	/* Check input arguments */
+	if (p == NULL)
+		return -1;
+
+	data->port_id = p->port_id;
+
+	return 0;
+}
+
+/**
+ * RTE_PORT_IN_ACTION_LB
+ */
+static int
+lb_cfg_check(struct rte_port_in_action_lb_config *cfg)
+{
+	if ((cfg == NULL) ||
+		(cfg->key_size < RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN) ||
+		(cfg->key_size > RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX) ||
+		(!rte_is_power_of_2(cfg->key_size)) ||
+		(cfg->f_hash == NULL))
+		return -1;
+
+	return 0;
+}
+
+struct lb_data {
+	uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
+};
+
+static void
+lb_init(struct lb_data *data,
+	struct rte_port_in_action_lb_config *cfg)
+{
+	memcpy(data->port_id, cfg->port_id, sizeof(cfg->port_id));
+}
+
+static int
+lb_apply(struct lb_data *data,
+	struct rte_port_in_action_lb_params *p)
+{
+	/* Check input arguments */
+	if (p == NULL)
+		return -1;
+
+	memcpy(data->port_id, p->port_id, sizeof(p->port_id));
+
+	return 0;
+}
+
+/**
+ * Action profile
+ */
+static int
+action_valid(enum rte_port_in_action_type action)
+{
+	switch (action) {
+	case RTE_PORT_IN_ACTION_FLTR:
+	case RTE_PORT_IN_ACTION_LB:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+#define RTE_PORT_IN_ACTION_MAX                             64
+
+struct ap_config {
+	uint64_t action_mask;
+	struct rte_port_in_action_fltr_config fltr;
+	struct rte_port_in_action_lb_config lb;
+};
+
+static size_t
+action_cfg_size(enum rte_port_in_action_type action)
+{
+	switch (action) {
+	case RTE_PORT_IN_ACTION_FLTR:
+		return sizeof(struct rte_port_in_action_fltr_config);
+	case RTE_PORT_IN_ACTION_LB:
+		return sizeof(struct rte_port_in_action_lb_config);
+	default:
+		return 0;
+	}
+}
+
+static void*
+action_cfg_get(struct ap_config *ap_config,
+	enum rte_port_in_action_type type)
+{
+	switch (type) {
+	case RTE_PORT_IN_ACTION_FLTR:
+		return &ap_config->fltr;
+
+	case RTE_PORT_IN_ACTION_LB:
+		return &ap_config->lb;
+
+	default:
+		return NULL;
+	}
+}
+
+static void
+action_cfg_set(struct ap_config *ap_config,
+	enum rte_port_in_action_type type,
+	void *action_cfg)
+{
+	void *dst = action_cfg_get(ap_config, type);
+
+	if (dst)
+		memcpy(dst, action_cfg, action_cfg_size(type));
+
+	ap_config->action_mask |= 1LLU << type;
+}
+
+struct ap_data {
+	size_t offset[RTE_PORT_IN_ACTION_MAX];
+	size_t total_size;
+};
+
+static size_t
+action_data_size(enum rte_port_in_action_type action,
+	struct ap_config *ap_config __rte_unused)
+{
+	switch (action) {
+	case RTE_PORT_IN_ACTION_FLTR:
+		return sizeof(struct fltr_data);
+
+	case RTE_PORT_IN_ACTION_LB:
+		return sizeof(struct lb_data);
+
+	default:
+		return 0;
+	}
+}
+
+static void
+action_data_offset_set(struct ap_data *ap_data,
+	struct ap_config *ap_config)
+{
+	uint64_t action_mask = ap_config->action_mask;
+	size_t offset;
+	uint32_t action;
+
+	memset(ap_data->offset, 0, sizeof(ap_data->offset));
+
+	offset = 0;
+	for (action = 0; action < RTE_PORT_IN_ACTION_MAX; action++)
+		if (action_mask & (1LLU << action)) {
+			ap_data->offset[action] = offset;
+			offset += action_data_size((enum rte_port_in_action_type)action,
+				ap_config);
+		}
+
+	ap_data->total_size = offset;
+}
+
+struct rte_port_in_action_profile {
+	struct ap_config cfg;
+	struct ap_data data;
+	int frozen;
+};
+
+struct rte_port_in_action_profile *
+rte_port_in_action_profile_create(uint32_t socket_id)
+{
+	struct rte_port_in_action_profile *ap;
+
+	/* Memory allocation */
+	ap = rte_zmalloc_socket(NULL,
+		sizeof(struct rte_port_in_action_profile),
+		RTE_CACHE_LINE_SIZE,
+		socket_id);
+	if (ap == NULL)
+		return NULL;
+
+	return ap;
+}
+
+int
+rte_port_in_action_profile_action_register(struct rte_port_in_action_profile *profile,
+	enum rte_port_in_action_type type,
+	void *action_config)
+{
+	int status;
+
+	/* Check input arguments */
+	if ((profile == NULL) ||
+		profile->frozen ||
+		(action_valid(type) == 0) ||
+		(profile->cfg.action_mask & (1LLU << type)) ||
+		((action_cfg_size(type) == 0) && action_config) ||
+		(action_cfg_size(type) && (action_config == NULL)))
+		return -EINVAL;
+
+	switch (type) {
+	case RTE_PORT_IN_ACTION_FLTR:
+		status = fltr_cfg_check(action_config);
+		break;
+
+	case RTE_PORT_IN_ACTION_LB:
+		status = lb_cfg_check(action_config);
+		break;
+
+	default:
+		status = 0;
+		break;
+	}
+
+	if (status)
+		return status;
+
+	/* Action enable */
+	action_cfg_set(&profile->cfg, type, action_config);
+
+	return 0;
+}
+
+int
+rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile)
+{
+	if (profile->frozen)
+		return -EBUSY;
+
+	action_data_offset_set(&profile->data, &profile->cfg);
+	profile->frozen = 1;
+
+	return 0;
+}
+
+int
+rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile)
+{
+	if (profile == NULL)
+		return 0;
+
+	free(profile);
+	return 0;
+}
+
+/**
+ * Action
+ */
+struct rte_port_in_action {
+	struct ap_config cfg;
+	struct ap_data data;
+	uint8_t memory[0] __rte_cache_aligned;
+};
+
+static __rte_always_inline void *
+action_data_get(struct rte_port_in_action *action,
+	enum rte_port_in_action_type type)
+{
+	size_t offset = action->data.offset[type];
+
+	return &action->memory[offset];
+}
+
+static void
+action_data_init(struct rte_port_in_action *action,
+	enum rte_port_in_action_type type)
+{
+	void *data = action_data_get(action, type);
+
+	switch (type) {
+	case RTE_PORT_IN_ACTION_FLTR:
+		fltr_init(data, &action->cfg.fltr);
+		return;
+
+	case RTE_PORT_IN_ACTION_LB:
+		lb_init(data, &action->cfg.lb);
+		return;
+
+	default:
+		return;
+	}
+}
+
+struct rte_port_in_action *
+rte_port_in_action_create(struct rte_port_in_action_profile *profile,
+	uint32_t socket_id)
+{
+	struct rte_port_in_action *action;
+	size_t size;
+	uint32_t i;
+
+	/* Check input arguments */
+	if ((profile == NULL) ||
+		(profile->frozen == 0))
+		return NULL;
+
+	/* Memory allocation */
+	size = sizeof(struct rte_port_in_action) + profile->data.total_size;
+	size = RTE_CACHE_LINE_ROUNDUP(size);
+
+	action = rte_zmalloc_socket(NULL,
+		size,
+		RTE_CACHE_LINE_SIZE,
+		socket_id);
+	if (action == NULL)
+		return NULL;
+
+	/* Initialization */
+	memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
+	memcpy(&action->data, &profile->data, sizeof(profile->data));
+
+	for (i = 0; i < RTE_PORT_IN_ACTION_MAX; i++)
+		if (action->cfg.action_mask & (1LLU << i))
+			action_data_init(action,
+				(enum rte_port_in_action_type)i);
+
+	return action;
+}
+
+int
+rte_port_in_action_apply(struct rte_port_in_action *action,
+	enum rte_port_in_action_type type,
+	void *action_params)
+{
+	void *action_data;
+
+	/* Check input arguments */
+	if ((action == NULL) ||
+		(action_valid(type) == 0) ||
+		((action->cfg.action_mask & (1LLU << type)) == 0) ||
+		(action_params == NULL))
+		return -EINVAL;
+
+	/* Data update */
+	action_data = action_data_get(action, type);
+
+	switch (type) {
+	case RTE_PORT_IN_ACTION_FLTR:
+		return fltr_apply(action_data,
+			action_params);
+
+	case RTE_PORT_IN_ACTION_LB:
+		return lb_apply(action_data,
+			action_params);
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+ah_filter_on_match(struct rte_pipeline *p,
+	struct rte_mbuf **pkts,
+	uint32_t n_pkts,
+	void *arg)
+{
+	struct rte_port_in_action *action = arg;
+	struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
+	uint64_t *key_mask = (uint64_t *) cfg->key_mask;
+	uint64_t *key = (uint64_t *) cfg->key;
+	uint32_t key_offset = cfg->key_offset;
+	struct fltr_data *data = action_data_get(action,
+						RTE_PORT_IN_ACTION_FLTR);
+	uint32_t i;
+
+	for (i = 0; i < n_pkts; i++) {
+		struct rte_mbuf *pkt = pkts[i];
+		uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
+					key_offset);
+
+		uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
+		uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
+		uint64_t or = xor0 | xor1;
+
+		if (or == 0) {
+			rte_pipeline_ah_packet_hijack(p, 1LLU << i);
+			rte_pipeline_port_out_packet_insert(p,
+				data->port_id, pkt);
+		}
+	}
+
+	return 0;
+}
+
+static int
+ah_filter_on_mismatch(struct rte_pipeline *p,
+	struct rte_mbuf **pkts,
+	uint32_t n_pkts,
+	void *arg)
+{
+	struct rte_port_in_action *action = arg;
+	struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
+	uint64_t *key_mask = (uint64_t *) cfg->key_mask;
+	uint64_t *key = (uint64_t *) cfg->key;
+	uint32_t key_offset = cfg->key_offset;
+	struct fltr_data *data = action_data_get(action,
+						RTE_PORT_IN_ACTION_FLTR);
+	uint32_t i;
+
+	for (i = 0; i < n_pkts; i++) {
+		struct rte_mbuf *pkt = pkts[i];
+		uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
+						key_offset);
+
+		uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
+		uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
+		uint64_t or = xor0 | xor1;
+
+		if (or) {
+			rte_pipeline_ah_packet_hijack(p, 1LLU << i);
+			rte_pipeline_port_out_packet_insert(p,
+				data->port_id, pkt);
+		}
+	}
+
+	return 0;
+}
+
+static int
+ah_lb(struct rte_pipeline *p,
+	struct rte_mbuf **pkts,
+	uint32_t n_pkts,
+	void *arg)
+{
+	struct rte_port_in_action *action = arg;
+	struct rte_port_in_action_lb_config *cfg = &action->cfg.lb;
+	struct lb_data *data = action_data_get(action, RTE_PORT_IN_ACTION_LB);
+	uint64_t pkt_mask = RTE_LEN2MASK(n_pkts, uint64_t);
+	uint32_t i;
+
+	rte_pipeline_ah_packet_hijack(p, pkt_mask);
+
+	for (i = 0; i < n_pkts; i++) {
+		struct rte_mbuf *pkt = pkts[i];
+		uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(pkt,
+					cfg->key_offset);
+
+		uint64_t digest = cfg->f_hash(pkt_key,
+			cfg->key_mask,
+			cfg->key_size,
+			cfg->seed);
+		uint64_t pos = digest & (RTE_PORT_IN_ACTION_LB_TABLE_SIZE - 1);
+		uint32_t port_id = data->port_id[pos];
+
+		rte_pipeline_port_out_packet_insert(p, port_id, pkt);
+	}
+
+	return 0;
+}
+
+static rte_pipeline_port_in_action_handler
+ah_selector(struct rte_port_in_action *action)
+{
+	if (action->cfg.action_mask == 0)
+		return NULL;
+
+	if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_FLTR)
+		return (action->cfg.fltr.filter_on_match) ?
+			ah_filter_on_match : ah_filter_on_mismatch;
+
+	if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_LB)
+		return ah_lb;
+
+	return NULL;
+}
+
+int
+rte_port_in_action_params_get(struct rte_port_in_action *action,
+	struct rte_pipeline_port_in_params *params)
+{
+	rte_pipeline_port_in_action_handler f_action;
+
+	/* Check input arguments */
+	if ((action == NULL) ||
+		(params == NULL))
+		return -EINVAL;
+
+	f_action = ah_selector(action);
+
+	/* Fill in params */
+	params->f_action = f_action;
+	params->arg_ah = (f_action) ? action : NULL;
+
+	return 0;
+}
+
+int
+rte_port_in_action_free(struct rte_port_in_action *action)
+{
+	if (action == NULL)
+		return 0;
+
+	rte_free(action);
+
+	return 0;
+}
diff --git a/lib/librte_pipeline/rte_port_in_action.h b/lib/librte_pipeline/rte_port_in_action.h
new file mode 100644
index 0000000..da5320b
--- /dev/null
+++ b/lib/librte_pipeline/rte_port_in_action.h
@@ -0,0 +1,301 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef __INCLUDE_RTE_PORT_IN_ACTION_H__
+#define __INCLUDE_RTE_PORT_IN_ACTION_H__
+
+/**
+ * @file
+ * RTE Pipeline Input Port Actions
+ *
+ * This API provides a common set of actions for pipeline input ports to speed
+ * up application development.
+ *
+ * Each pipeline input port can be assigned an action handler to be executed
+ * on every input packet during the pipeline execution. The pipeline library
+ * allows the user to define his own input port actions by providing customized
+ * input port action handler. While the user can still follow this process, this
+ * API is intended to provide a quicker development alternative for a set of
+ * predefined actions.
+ *
+ * The typical steps to use this API are:
+ *  - Define an input port action profile. This is a configuration template that
+ *    can potentially be shared by multiple input ports from the same or
+ *    different pipelines, with different input ports from the same pipeline
+ *    able to use different action profiles. For every input port using a given
+ *    action profile, the profile defines the set of actions and the action
+ *    configuration to be executed by the input port. API functions:
+ *    rte_port_in_action_profile_create(),
+ *    rte_port_in_action_profile_action_register(),
+ *    rte_port_in_action_profile_freeze().
+ *
+ *  - Instantiate the input port action profile to create input port action
+ *    objects. Each pipeline input port has its own action object.
+ *    API functions: rte_port_in_action_create().
+ *
+ *  - Use the input port action object to generate the input port action handler
+ *    invoked by the pipeline. API functions:
+ *    rte_port_in_action_params_get().
+ *
+ *  - Use the input port action object to generate the internal data structures
+ *    used by the input port action handler based on given action parameters.
+ *    API functions: rte_port_in_action_apply().
+ *
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#include <rte_compat.h>
+#include <rte_table_hash.h>
+
+#include "rte_pipeline.h"
+
+/** Input port actions. */
+enum rte_port_in_action_type {
+	/** Filter selected input packets. */
+	RTE_PORT_IN_ACTION_FLTR = 0,
+
+	/**  Load balance. */
+	RTE_PORT_IN_ACTION_LB,
+};
+
+/**
+ * RTE_PORT_IN_ACTION_FLTR
+ */
+/** Filter key size (number of bytes) */
+#define RTE_PORT_IN_ACTION_FLTR_KEY_SIZE                   16
+
+/** Filter action configuration (per action profile). */
+struct rte_port_in_action_fltr_config {
+	/** Key offset within the input packet buffer. Offset 0 points to the
+	 * first byte of the MBUF structure.
+	 */
+	uint32_t key_offset;
+
+	/** Key mask. */
+	uint8_t key_mask[RTE_PORT_IN_ACTION_FLTR_KEY_SIZE];
+
+	/** Key value. */
+	uint8_t key[RTE_PORT_IN_ACTION_FLTR_KEY_SIZE];
+
+	/** When non-zero, all the input packets that match the *key* (with the
+	* *key_mask* applied) are sent to the pipeline output port *port_id*.
+	* When zero, all the input packets that do NOT match the *key* (with the
+	* *key_mask* applied) are sent to the pipeline output port *port_id*.
+	*/
+	int filter_on_match;
+
+	/** Pipeline output port ID to send the filtered input packets to.
+	 * Can be updated later.
+	 *
+	 * @see struct rte_port_in_action_fltr_params
+	 */
+	uint32_t port_id;
+};
+
+/** Filter action parameters (per action). */
+struct rte_port_in_action_fltr_params {
+	/** Pipeline output port ID to send the filtered input packets to. */
+	uint32_t port_id;
+};
+
+/**
+ * RTE_PORT_IN_ACTION_LB
+ */
+/** Load balance key size min (number of bytes). */
+#define RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN                    8
+
+/** Load balance key size max (number of bytes). */
+#define RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX                    64
+
+/** Load balance table size. */
+#define RTE_PORT_IN_ACTION_LB_TABLE_SIZE                   16
+
+/** Load balance action configuration (per action profile). */
+struct rte_port_in_action_lb_config {
+	/** Key size (number of bytes). */
+	uint32_t key_size;
+
+	/** Key offset within the input packet buffer. Offset 0 points to the
+	 * first byte of the MBUF structure.
+	 */
+	uint32_t key_offset;
+
+	/** Key mask(*key_size* bytes are valid). */
+	uint8_t key_mask[RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX];
+
+	/** Hash function. */
+	rte_table_hash_op_hash f_hash;
+
+	/** Seed value for *f_hash*. */
+	uint64_t seed;
+
+	/** Table defining the weight of each pipeline output port. The weights
+	 * are set in 1/RTE_PORT_IN_ACTION_LB_TABLE_SIZE increments. To assign a
+	 * weight of N/RTE_PORT_IN_ACTION_LB_TABLE_SIZE to a given output port
+	 * (0 <= N <= RTE_PORT_IN_ACTION_LB_TABLE_SIZE), the output port needs
+	 * to show up exactly N times in this table. Can be updated later.
+	 *
+	 * @see struct rte_port_in_action_lb_params
+	 */
+	uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
+};
+
+/** Load balance action parameters (per action). */
+struct rte_port_in_action_lb_params {
+	/** Table defining the weight of each pipeline output port. The weights
+	 * are set in 1/RTE_PORT_IN_ACTION_LB_TABLE_SIZE increments. To assign a
+	 * weight of N/RTE_PORT_IN_ACTION_LB_TABLE_SIZE to a given output port
+	 * (0 <= N <= RTE_PORT_IN_ACTION_LB_TABLE_SIZE), the output port needs
+	 * to show up exactly N times in this table.
+	 */
+	uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
+};
+
+/**
+ * Input port action profile.
+ */
+struct rte_port_in_action_profile;
+
+/**
+ * Input port action profile create.
+ *
+ * @param[in] socket_id
+ *   CPU socket ID for the internal data structures memory allocation.
+ * @return
+ *   Input port action profile handle on success, NULL otherwise.
+ */
+struct rte_port_in_action_profile * __rte_experimental
+rte_port_in_action_profile_create(uint32_t socket_id);
+
+/**
+ * Input port action profile free.
+ *
+ * @param[in] profile
+ *   Input port action profile handle (needs to be valid).
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int __rte_experimental
+rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile);
+
+/**
+ * Input port action profile action register.
+ *
+ * @param[in] profile
+ *   Input port action profile handle (needs to be valid and not in frozen
+ *   state).
+ * @param[in] type
+ *   Specific input port action to be registered for *profile*.
+ * @param[in] action_config
+ *   Configuration for the *type* action.
+ *   If struct rte_port_in_action_*type*_config is defined, it needs to point to
+ *   a valid instance of this structure, otherwise it needs to be set to NULL.
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int __rte_experimental
+rte_port_in_action_profile_action_register(
+	struct rte_port_in_action_profile *profile,
+	enum rte_port_in_action_type type,
+	void *action_config);
+
+/**
+ * Input port action profile freeze.
+ *
+ * Once this function is called successfully, the given profile enters the
+ * frozen state with the following immediate effects: no more actions can be
+ * registered for this profile, so the profile can be instantiated to create
+ * input port action objects.
+ *
+ * @param[in] profile
+ *   Input port profile action handle (needs to be valid and not in frozen
+ *   state).
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ *
+ * @see rte_port_in_action_create()
+ */
+int __rte_experimental
+rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile);
+
+/**
+ * Input port action.
+ */
+struct rte_port_in_action;
+
+/**
+ * Input port action create.
+ *
+ * Instantiates the given input port action profile to create an input port
+ * action object.
+ *
+ * @param[in] profile
+ *   Input port profile action handle (needs to be valid and in frozen state).
+ * @param[in] socket_id
+ *   CPU socket ID where the internal data structures required by the new input
+ *   port action object should be allocated.
+ * @return
+ *   Handle to input port action object on success, NULL on error.
+ */
+struct rte_port_in_action * __rte_experimental
+rte_port_in_action_create(struct rte_port_in_action_profile *profile,
+	uint32_t socket_id);
+
+/**
+ * Input port action free.
+ *
+ * @param[in] action
+ *   Handle to input port action object (needs to be valid).
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int __rte_experimental
+rte_port_in_action_free(struct rte_port_in_action *action);
+
+/**
+ * Input port params get.
+ *
+ * @param[in] action
+ *   Handle to input port action object (needs to be valid).
+ * @param[inout] params
+ *   Pipeline input port parameters (needs to be pre-allocated).
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int __rte_experimental
+rte_port_in_action_params_get(struct rte_port_in_action *action,
+	struct rte_pipeline_port_in_params *params);
+
+/**
+ * Input port action apply.
+ *
+ * @param[in] action
+ *   Handle to input port action object (needs to be valid).
+ * @param[in] type
+ *   Specific input port action previously registered for the input port action
+ *   profile of the *action* object.
+ * @param[in] action_params
+ *   Parameters for the *type* action.
+ *   If struct rte_port_in_action_*type*_params is defined, it needs to point to
+ *   a valid instance of this structure, otherwise it needs to be set to NULL.
+ * @return
+ *   Zero on success, non-zero error code otherwise.
+ */
+int __rte_experimental
+rte_port_in_action_apply(struct rte_port_in_action *action,
+	enum rte_port_in_action_type type,
+	void *action_params);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_RTE_PORT_IN_ACTION_H__ */
