[dpdk-dev] [PATCH v5 2/2] librte_pipeline: add new API functions for pipeline action handlers

Jasvinder Singh jasvinder.singh at intel.com
Tue Mar 8 19:07:49 CET 2016


Two new pipeline API functions have been added to the library. The packet
hijack API function can be called by any input/output port or table action
handler to remove selected packets from the burst of packets read from one
of the pipeline input ports and then either send these packets out through
any pipeline output port or drop them.

Another packet drop API function can be used by the pipeline action
handlers (port in/out, table) to drop the packets selected using packet
mask. This function updates the drop statistics counters correctly.

Signed-off-by: Jasvinder Singh <jasvinder.singh at intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu at intel.com>
---
 app/test/test_table_pipeline.c                     |  53 +++++-----
 .../ip_pipeline/pipeline/pipeline_actions_common.h |   8 +-
 lib/librte_pipeline/rte_pipeline.c                 |  20 ++++
 lib/librte_pipeline/rte_pipeline.h                 | 107 +++++++++++++++++----
 lib/librte_pipeline/rte_pipeline_version.map       |   8 ++
 5 files changed, 149 insertions(+), 47 deletions(-)

diff --git a/app/test/test_table_pipeline.c b/app/test/test_table_pipeline.c
index 4bcce2b..36bfeda 100644
--- a/app/test/test_table_pipeline.c
+++ b/app/test/test_table_pipeline.c
@@ -91,53 +91,59 @@ rte_pipeline_port_out_action_handler port_action_stub(struct rte_mbuf **pkts,
 #endif
 
 rte_pipeline_table_action_handler_hit
-table_action_0x00(struct rte_mbuf **pkts, uint64_t *pkts_mask,
-	struct rte_pipeline_table_entry **actions, uint32_t action_mask);
+table_action_0x00(struct rte_pipeline *p, struct rte_mbuf **pkts,
+	uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
 
 rte_pipeline_table_action_handler_hit
-table_action_stub_hit(struct rte_mbuf **pkts, uint64_t *pkts_mask,
-	struct rte_pipeline_table_entry **actions, uint32_t action_mask);
+table_action_stub_hit(struct rte_pipeline *p, struct rte_mbuf **pkts,
+	uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
 
 rte_pipeline_table_action_handler_miss
-table_action_stub_miss(struct rte_mbuf **pkts, uint64_t *pkts_mask,
-	struct rte_pipeline_table_entry *action, uint32_t action_mask);
+table_action_stub_miss(struct rte_pipeline *p, struct rte_mbuf **pkts,
+	uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
 
 rte_pipeline_table_action_handler_hit
-table_action_0x00(__attribute__((unused)) struct rte_mbuf **pkts,
-	uint64_t *pkts_mask,
-	__attribute__((unused)) struct rte_pipeline_table_entry **actions,
-	__attribute__((unused)) uint32_t action_mask)
+table_action_0x00(__attribute__((unused)) struct rte_pipeline *p,
+	__attribute__((unused)) struct rte_mbuf **pkts,
+	uint64_t pkts_mask,
+	__attribute__((unused)) struct rte_pipeline_table_entry **entry,
+	__attribute__((unused)) void *arg)
 {
 	printf("Table Action, setting pkts_mask to 0x00\n");
-	*pkts_mask = 0x00;
+	pkts_mask = ~0x00;
+	rte_pipeline_ah_packet_drop(p, pkts_mask);
 	return 0;
 }
 
 rte_pipeline_table_action_handler_hit
-table_action_stub_hit(__attribute__((unused)) struct rte_mbuf **pkts,
-	uint64_t *pkts_mask,
-	__attribute__((unused)) struct rte_pipeline_table_entry **actions,
-	__attribute__((unused)) uint32_t action_mask)
+table_action_stub_hit(__attribute__((unused)) struct rte_pipeline *p,
+	__attribute__((unused)) struct rte_mbuf **pkts,
+	uint64_t pkts_mask,
+	__attribute__((unused)) struct rte_pipeline_table_entry **entry,
+	__attribute__((unused)) void *arg)
 {
 	printf("STUB Table Action Hit - doing nothing\n");
 	printf("STUB Table Action Hit - setting mask to 0x%"PRIx64"\n",
 		override_hit_mask);
-	*pkts_mask = override_hit_mask;
+	pkts_mask = (~override_hit_mask) & 0x3;
+	rte_pipeline_ah_packet_drop(p, pkts_mask);
 	return 0;
 }
+
 rte_pipeline_table_action_handler_miss
-table_action_stub_miss(__attribute__((unused)) struct rte_mbuf **pkts,
-	uint64_t *pkts_mask,
-	__attribute__((unused)) struct rte_pipeline_table_entry *action,
-	__attribute__((unused)) uint32_t action_mask)
+table_action_stub_miss(struct rte_pipeline *p,
+	__attribute__((unused)) struct rte_mbuf **pkts,
+	uint64_t pkts_mask,
+	__attribute__((unused)) struct rte_pipeline_table_entry **entry,
+	__attribute__((unused)) void *arg)
 {
 	printf("STUB Table Action Miss - setting mask to 0x%"PRIx64"\n",
 		override_miss_mask);
-	*pkts_mask = override_miss_mask;
+	pkts_mask = (~override_miss_mask) & 0x3;
+	rte_pipeline_ah_packet_drop(p, pkts_mask);
 	return 0;
 }
 
-
 enum e_test_type {
 	e_TEST_STUB = 0,
 	e_TEST_LPM,
@@ -537,7 +543,6 @@ test_table_pipeline(void)
 	setup_pipeline(e_TEST_STUB);
 	if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
 		return -1;
-#if 0
 
 	/* TEST - one packet per port */
 	action_handler_hit = NULL;
@@ -585,8 +590,6 @@ test_table_pipeline(void)
 		return -1;
 	connect_miss_action_to_table = 0;
 
-#endif
-
 	if (check_pipeline_invalid_params()) {
 		RTE_LOG(INFO, PIPELINE, "%s: Check pipeline invalid params "
 			"failed.\n", __func__);
diff --git a/examples/ip_pipeline/pipeline/pipeline_actions_common.h b/examples/ip_pipeline/pipeline/pipeline_actions_common.h
index 73cf562..9958758 100644
--- a/examples/ip_pipeline/pipeline/pipeline_actions_common.h
+++ b/examples/ip_pipeline/pipeline/pipeline_actions_common.h
@@ -122,7 +122,7 @@ f_ah(									\
 #define PIPELINE_TABLE_AH_HIT_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work)	\
 static int								\
 f_ah(									\
-	__rte_unused struct rte_pipeline *p,			\
+	struct rte_pipeline *p,						\
 	struct rte_mbuf **pkts,						\
 	uint64_t pkts_mask,						\
 	struct rte_pipeline_table_entry **entries,			\
@@ -158,13 +158,15 @@ f_ah(									\
 			pkts_out_mask ^= mask << pos;			\
 		}							\
 									\
+	rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask);	\
+									\
 	return 0;							\
 }
 
 #define PIPELINE_TABLE_AH_MISS_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work)	\
 static int								\
 f_ah(									\
-	__rte_unused struct rte_pipeline *p,			\
+	struct rte_pipeline *p,						\
 	struct rte_mbuf **pkts,						\
 	uint64_t pkts_mask,						\
 	struct rte_pipeline_table_entry *entry,				\
@@ -199,6 +201,8 @@ f_ah(									\
 			pkts_out_mask ^= mask << pos;			\
 		}							\
 									\
+	rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask);	\
+									\
 	return 0;							\
 }
 
diff --git a/lib/librte_pipeline/rte_pipeline.c b/lib/librte_pipeline/rte_pipeline.c
index b7a02d6..7f8fbac 100644
--- a/lib/librte_pipeline/rte_pipeline.c
+++ b/lib/librte_pipeline/rte_pipeline.c
@@ -1512,6 +1512,26 @@ rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
 	return 0;
 }
 
+int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
+	uint64_t pkts_mask)
+{
+	pkts_mask &= p->pkts_mask;
+	p->pkts_mask &= ~pkts_mask;
+
+	return 0;
+}
+
+int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
+	uint64_t pkts_mask)
+{
+	pkts_mask &= p->pkts_mask;
+	p->pkts_mask &= ~pkts_mask;
+	p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= pkts_mask;
+
+	RTE_PIPELINE_STATS_AH_DROP_WRITE(p, pkts_mask);
+	return 0;
+}
+
 int rte_pipeline_port_in_stats_read(struct rte_pipeline *p, uint32_t port_id,
 	struct rte_pipeline_port_in_stats *stats, int clear)
 {
diff --git a/lib/librte_pipeline/rte_pipeline.h b/lib/librte_pipeline/rte_pipeline.h
index 0b02969..84d1802 100644
--- a/lib/librte_pipeline/rte_pipeline.h
+++ b/lib/librte_pipeline/rte_pipeline.h
@@ -759,14 +759,38 @@ int rte_pipeline_port_out_create(struct rte_pipeline *p,
 	uint32_t *port_id);
 
 /**
- * Pipeline output port packet insert
+ * Read pipeline port out stats.
+ *
+ * This function reads port out statistics identified by *port_id* of given
+ * pipeline *p*.
+ *
+ * @param p
+ *   Handle to pipeline instance.
+ * @param port_id
+ *   Port ID what stats will be returned.
+ * @param stats
+ *   Statistics buffer.
+ * @param clear
+ *   If not 0 clear stats after reading.
+ * @return
+ *   0 on success, error code otherwise
+ */
+int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
+	struct rte_pipeline_port_out_stats *stats, int clear);
+
+/*
+ * Functions to be called as part of the port IN/OUT or table action handlers
  *
- * This function is called by the table action handler whenever it generates a
- * new packet to be sent out though one of the pipeline output ports. This
- * packet is not part of the burst of input packets read from any of the
- * pipeline input ports, so it is not an element of the pkts array input
- * parameter of the table action handler. This packet can be dropped by the
- * output port action handler.
+ */
+/**
+ * Action handler packet insert to output port
+ *
+ * This function can be called by any input/output port or table action handler
+ * to send a packet out through one of the pipeline output ports. This packet is
+ * generated by the action handler, i.e. this packet is not part of the burst of
+ * packets read from one of the pipeline input ports and currently processed by
+ * the pipeline (this packet is not an element of the pkts array input parameter
+ * of the action handler).
  *
  * @param p
  *   Handle to pipeline instance
@@ -774,7 +798,7 @@ int rte_pipeline_port_out_create(struct rte_pipeline *p,
  *   Output port ID (returned by previous invocation of pipeline output port
  *   create) to send the packet specified by pkt
  * @param pkt
- *   New packet generated by the table action handler
+ *   New packet generated by the action handler
  * @return
  *   0 on success, error code otherwise
  */
@@ -782,25 +806,68 @@ int rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
 	uint32_t port_id,
 	struct rte_mbuf *pkt);
 
+#define rte_pipeline_ah_port_out_packet_insert \
+	rte_pipeline_port_out_packet_insert
+
 /**
- * Read pipeline port out stats.
+ * Action handler packet hijack
  *
- * This function reads port out statistics identified by *port_id* of given
- * pipeline *p*.
+ * This function can be called by any input/output port or table action handler
+ * to hijack selected packets from the burst of packets read from one of the
+ * pipeline input ports and currently processed by the pipeline. The hijacked
+ * packets are removed from any further pipeline processing, with the action
+ * handler now having the full ownership for these packets.
+ *
+ * The action handler can further send the hijacked packets out through any
+ * pipeline output port by calling the rte_pipeline_ah_port_out_packet_insert()
+ * function. The action handler can also drop these packets by calling the
+ * rte_pktmbuf_free() function, although a better alternative is provided by
+ * the action handler using the rte_pipeline_ah_packet_drop() function.
  *
  * @param p
- *   Handle to pipeline instance.
- * @param port_id
- *   Port ID what stats will be returned.
- * @param stats
- *   Statistics buffer.
- * @param clear
- *   If not 0 clear stats after reading.
+ *   Handle to pipeline instance
+ * @param pkts_mask
+ *   64-bit bitmask specifying which of the packets handed over for processing
+ *   to the action handler is to be hijacked by the action handler. When
+ *   pkts_mask bit n is set, then element n of the pkts array (input argument to
+ *   the action handler) is hijacked.
  * @return
  *   0 on success, error code otherwise
  */
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
-	struct rte_pipeline_port_out_stats *stats, int clear);
+int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
+	uint64_t pkts_mask);
+
+/**
+ * Action handler packet drop
+ *
+ * This function is called by the pipeline action handlers (port in/out, table)
+ * to drop the packets selected using packet mask.
+ *
+ * This function can be called by any input/output port or table action handler
+ * to drop selected packets from the burst of packets read from one of the
+ * pipeline input ports and currently processed by the pipeline. The dropped
+ * packets are removed from any further pipeline processing and the packet
+ * buffers are eventually freed to their buffer pool.
+ *
+ * This function updates the drop statistics counters correctly, therefore the
+ * recommended approach for dropping packets by the action handlers is to call
+ * this function as opposed to the action handler hijacking the packets first
+ * and then dropping them invisibly to the pipeline (by using the
+ * rte_pktmbuf_free() function).
+ *
+ * @param p
+ *   Handle to pipeline instance
+ * @param pkts_mask
+ *   64-bit bitmask specifying which of the packets handed over for processing
+ *   to the action handler is to be dropped by the action handler. When
+ *   pkts_mask bit n is set, then element n of the pkts array (input argument to
+ *   the action handler) is dropped.
+ * @return
+ *   0 on success, error code otherwise
+ */
+int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
+	uint64_t pkts_mask);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index 4cc86f6..e4ee154 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -37,3 +37,11 @@ DPDK_2.2 {
 	rte_pipeline_table_entry_delete_bulk;
 
 } DPDK_2.1;
+
+DPDK_16.04 {
+	global:
+
+	rte_pipeline_ah_packet_hijack;
+	rte_pipeline_ah_packet_drop;
+
+} DPDK_2.2;
-- 
2.5.0



More information about the dev mailing list