From 9ef2593651f916516f8b191c2aa050bd42d31898 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Wed, 18 Nov 2015 17:09:23 +0000 Subject: [PATCH] examples/ip_pipeline: add flow actions pipeline 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 Signed-off-by: Fan Zhang Acked-by: Cristian Dumitrescu --- examples/ip_pipeline/Makefile | 2 + examples/ip_pipeline/init.c | 2 + .../pipeline/pipeline_actions_common.h | 83 +++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile index c8e80b51d4..10fe1ba91a 100644 --- a/examples/ip_pipeline/Makefile +++ b/examples/ip_pipeline/Makefile @@ -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 diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c index 23fd561b05..52aab53ed2 100644 --- a/examples/ip_pipeline/init.c +++ b/examples/ip_pipeline/init.c @@ -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); diff --git a/examples/ip_pipeline/pipeline/pipeline_actions_common.h b/examples/ip_pipeline/pipeline/pipeline_actions_common.h index 4b5d5c4419..aa1dd59a37 100644 --- a/examples/ip_pipeline/pipeline/pipeline_actions_common.h +++ b/examples/ip_pipeline/pipeline/pipeline_actions_common.h @@ -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 -- 2.20.1