examples/ip_pipeline: add flow actions pipeline
authorFan Zhang <roy.fan.zhang@intel.com>
Wed, 18 Nov 2015 17:09:23 +0000 (17:09 +0000)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Mon, 7 Dec 2015 01:35:56 +0000 (02:35 +0100)
Flow actions pipeline is an extension of flow-classification pipeline.
Some of the operations of flow classification pipeline such as traffic
metering/marking(for e.g. Single Rate Three Color Marker (srTCM), Two
Rate Three Color Marker trTCM)), policer can be performed separately in
flow action pipeline to avoid excessive computational burden on the CPU
core running the flow-classification pipeline. The Flow action pipeline
implements various function such as traffic metering, policer, stats.
Traffic mettering can configured as per the required context, for
examples- per user, per traffic class or both. These contexts can be
applied by specifying parameters in configuration file as shown below;

[PIPELINE1]
type = FLOW_ACTIONS
core = 1
pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0
n_flows = 65536
n_meters_per_flow = 1
flow_id_offset = 158
ip_hdr_offset = 142
color_offset = 64

The entries of flow and dscp tables of flow actions pipeline can be
modified through command-line interface. The commands to add or delete
entries to the flow table, DSCP(differentiated services code point)
table and for statistics collection, etc have been included. The key
functions such as Traffic Metering/marking and policer functions have
been implemented as flow-table action handler.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
examples/ip_pipeline/Makefile
examples/ip_pipeline/init.c
examples/ip_pipeline/pipeline/pipeline_actions_common.h

index c8e80b5..10fe1ba 100644 (file)
@@ -67,6 +67,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_firewall_be.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_firewall.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_flow_classification_be.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_flow_classification.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_flow_actions_be.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_flow_actions.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_routing_be.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_routing.c
 
index 23fd561..52aab53 100644 (file)
@@ -49,6 +49,7 @@
 #include "pipeline_passthrough.h"
 #include "pipeline_firewall.h"
 #include "pipeline_flow_classification.h"
+#include "pipeline_flow_actions.h"
 #include "pipeline_routing.h"
 #include "thread_fe.h"
 
@@ -1436,6 +1437,7 @@ int app_init(struct app_params *app)
        app_pipeline_type_register(app, &pipeline_master);
        app_pipeline_type_register(app, &pipeline_passthrough);
        app_pipeline_type_register(app, &pipeline_flow_classification);
+       app_pipeline_type_register(app, &pipeline_flow_actions);
        app_pipeline_type_register(app, &pipeline_firewall);
        app_pipeline_type_register(app, &pipeline_routing);
 
index 4b5d5c4..aa1dd59 100644 (file)
@@ -116,4 +116,87 @@ f_ah(                                                                      \
        return 0;                                                       \
 }
 
+#define PIPELINE_TABLE_AH_HIT_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work) \
+static int                                                             \
+f_ah(                                                                  \
+       struct rte_mbuf **pkts,                                         \
+       uint64_t *pkts_mask,                                            \
+       struct rte_pipeline_table_entry **entries,                      \
+       void *arg)                                                      \
+{                                                                      \
+       uint64_t pkts_in_mask = *pkts_mask;                             \
+       uint64_t pkts_out_mask = *pkts_mask;                            \
+       uint64_t time = rte_rdtsc();                                    \
+                                                                       \
+       if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {                 \
+               uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);   \
+               uint32_t i;                                             \
+                                                                       \
+               for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {         \
+                       uint64_t mask = f_pkt4_work(&pkts[i],           \
+                               &entries[i], arg, time);        \
+                       pkts_out_mask ^= mask << i;                     \
+               }                                                       \
+                                                                       \
+               for ( ; i < n_pkts; i++) {                              \
+                       uint64_t mask = f_pkt_work(pkts[i],             \
+                               entries[i], arg, time);         \
+                       pkts_out_mask ^= mask << i;                     \
+               }                                                       \
+       } else                                                          \
+               for ( ; pkts_in_mask; ) {                               \
+                       uint32_t pos = __builtin_ctzll(pkts_in_mask);   \
+                       uint64_t pkt_mask = 1LLU << pos;                \
+                       uint64_t mask = f_pkt_work(pkts[pos],           \
+                               entries[pos], arg, time);               \
+                                                                       \
+                       pkts_in_mask &= ~pkt_mask;                      \
+                       pkts_out_mask ^= mask << pos;                   \
+               }                                                       \
+                                                                       \
+       *pkts_mask = pkts_out_mask;                                     \
+       return 0;                                                       \
+}
+
+#define PIPELINE_TABLE_AH_MISS_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work)        \
+static int                                                             \
+f_ah(                                                                  \
+       struct rte_mbuf **pkts,                                         \
+       uint64_t *pkts_mask,                                            \
+       struct rte_pipeline_table_entry *entry,                         \
+       void *arg)                                                      \
+{                                                                      \
+       uint64_t pkts_in_mask = *pkts_mask;                             \
+       uint64_t pkts_out_mask = *pkts_mask;                            \
+       uint64_t time = rte_rdtsc();                                    \
+                                                                       \
+       if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {                 \
+               uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);   \
+               uint32_t i;                                             \
+                                                                       \
+               for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {         \
+                       uint64_t mask = f_pkt4_work(&pkts[i],           \
+                               entry, arg, time);                      \
+                       pkts_out_mask ^= mask << i;                     \
+               }                                                       \
+                                                                       \
+               for ( ; i < n_pkts; i++) {                              \
+                       uint64_t mask = f_pkt_work(pkts[i], entry, arg, time);\
+                       pkts_out_mask ^= mask << i;                     \
+               }                                                       \
+       } else                                                          \
+               for ( ; pkts_in_mask; ) {                               \
+                       uint32_t pos = __builtin_ctzll(pkts_in_mask);   \
+                       uint64_t pkt_mask = 1LLU << pos;                \
+                       uint64_t mask = f_pkt_work(pkts[pos],           \
+                               entry, arg, time);              \
+                                                                       \
+                       pkts_in_mask &= ~pkt_mask;                      \
+                       pkts_out_mask ^= mask << pos;                   \
+               }                                                       \
+                                                                       \
+       *pkts_mask = pkts_out_mask;                                     \
+       return 0;                                                       \
+}
+
 #endif