pipeline: add new functions for action handlers

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@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
This commit is contained in:
Jasvinder Singh 2016-03-08 18:07:49 +00:00 committed by Thomas Monjalon
parent 88ac2fd99f
commit 4c387fcdf7
5 changed files with 158 additions and 56 deletions

View File

@ -91,52 +91,58 @@ 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;
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)
{
printf("STUB Table Action Miss - setting mask to 0x%"PRIx64"\n",
override_miss_mask);
*pkts_mask = override_miss_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(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) & 0x3;
rte_pipeline_ah_packet_drop(p, pkts_mask);
return 0;
}
enum e_test_type {
e_TEST_STUB = 0,
@ -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__);

View File

@ -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; \
}

View File

@ -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)
{

View File

@ -758,30 +758,6 @@ int rte_pipeline_port_out_create(struct rte_pipeline *p,
struct rte_pipeline_port_out_params *params,
uint32_t *port_id);
/**
* Pipeline output port packet insert
*
* 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.
*
* @param p
* Handle to pipeline instance
* @param port_id
* 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
* @return
* 0 on success, error code otherwise
*/
int rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
uint32_t port_id,
struct rte_mbuf *pkt);
/**
* Read pipeline port out stats.
*
@ -801,6 +777,97 @@ int rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
*/
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
*
*/
/**
* 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
* @param port_id
* 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 action handler
* @return
* 0 on success, error code otherwise
*/
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
/**
* Action handler packet hijack
*
* 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 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_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

View File

@ -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;