Imported Upstream version 16.07-rc1
[deb_dpdk.git] / examples / ip_pipeline / app.h
index 55a9841..6a6fdd9 100644 (file)
 #include <cmdline_parse.h>
 
 #include <rte_ethdev.h>
+#ifdef RTE_LIBRTE_KNI
+#include <rte_kni.h>
+#endif
 
 #include "cpu_core_map.h"
 #include "pipeline.h"
 
 #define APP_PARAM_NAME_SIZE                      PIPELINE_NAME_SIZE
 #define APP_LINK_PCI_BDF_SIZE                    16
+
+#ifndef APP_LINK_MAX_HWQ_IN
+#define APP_LINK_MAX_HWQ_IN                      128
+#endif
+
+#ifndef APP_LINK_MAX_HWQ_OUT
+#define APP_LINK_MAX_HWQ_OUT                     128
+#endif
+
 struct app_mempool_params {
        char *name;
        uint32_t parsed;
@@ -69,6 +81,12 @@ struct app_link_params {
        uint32_t tcp_local_q; /* 0 = Disabled (pkts go to default queue 0) */
        uint32_t udp_local_q; /* 0 = Disabled (pkts go to default queue 0) */
        uint32_t sctp_local_q; /* 0 = Disabled (pkts go to default queue 0) */
+       uint32_t rss_qs[APP_LINK_MAX_HWQ_IN];
+       uint32_t n_rss_qs;
+       uint64_t rss_proto_ipv4;
+       uint64_t rss_proto_ipv6;
+       uint64_t rss_proto_l2;
+       uint32_t promisc;
        uint32_t state; /* DOWN = 0, UP = 1 */
        uint32_t ip; /* 0 = Invalid */
        uint32_t depth; /* Valid only when IP is valid */
@@ -76,7 +94,6 @@ struct app_link_params {
        char pci_bdf[APP_LINK_PCI_BDF_SIZE];
 
        struct rte_eth_conf conf;
-       uint8_t promisc;
 };
 
 struct app_pktq_hwq_in_params {
@@ -118,6 +135,22 @@ struct app_pktq_swq_params {
        uint32_t mempool_indirect_id;
 };
 
+struct app_pktq_kni_params {
+       char *name;
+       uint32_t parsed;
+
+       uint32_t socket_id;
+       uint32_t core_id;
+       uint32_t hyper_th_id;
+       uint32_t force_bind;
+
+       uint32_t mempool_id; /* Position in the app->mempool_params */
+       uint32_t burst_read;
+       uint32_t burst_write;
+       uint32_t dropless;
+       uint64_t n_retries;
+};
+
 #ifndef APP_FILE_NAME_SIZE
 #define APP_FILE_NAME_SIZE                       256
 #endif
@@ -171,6 +204,7 @@ enum app_pktq_in_type {
        APP_PKTQ_IN_HWQ,
        APP_PKTQ_IN_SWQ,
        APP_PKTQ_IN_TM,
+       APP_PKTQ_IN_KNI,
        APP_PKTQ_IN_SOURCE,
 };
 
@@ -183,6 +217,7 @@ enum app_pktq_out_type {
        APP_PKTQ_OUT_HWQ,
        APP_PKTQ_OUT_SWQ,
        APP_PKTQ_OUT_TM,
+       APP_PKTQ_OUT_KNI,
        APP_PKTQ_OUT_SINK,
 };
 
@@ -191,9 +226,7 @@ struct app_pktq_out_params {
        uint32_t id; /* Position in the appropriate app array */
 };
 
-#ifndef APP_PIPELINE_TYPE_SIZE
-#define APP_PIPELINE_TYPE_SIZE                   64
-#endif
+#define APP_PIPELINE_TYPE_SIZE                   PIPELINE_TYPE_SIZE
 
 #define APP_MAX_PIPELINE_PKTQ_IN                 PIPELINE_MAX_PORT_IN
 #define APP_MAX_PIPELINE_PKTQ_OUT                PIPELINE_MAX_PORT_OUT
@@ -229,6 +262,22 @@ struct app_pipeline_params {
        uint32_t n_args;
 };
 
+struct app_params;
+
+typedef void (*app_link_op)(struct app_params *app,
+       uint32_t link_id,
+       uint32_t up,
+       void *arg);
+
+#ifndef APP_MAX_PIPELINES
+#define APP_MAX_PIPELINES                        64
+#endif
+
+struct app_link_data {
+       app_link_op f_link[APP_MAX_PIPELINES];
+       void *arg[APP_MAX_PIPELINES];
+};
+
 struct app_pipeline_data {
        void *be;
        void *fe;
@@ -247,7 +296,7 @@ struct app_thread_pipeline_data {
 };
 
 #ifndef APP_MAX_THREAD_PIPELINES
-#define APP_MAX_THREAD_PIPELINES                 16
+#define APP_MAX_THREAD_PIPELINES                 64
 #endif
 
 #ifndef APP_THREAD_TIMER_PERIOD
@@ -272,7 +321,7 @@ struct app_thread_data {
        uint64_t headroom_time;
        uint64_t headroom_cycles;
        double headroom_ratio;
-};
+} __rte_cache_aligned;
 
 #ifndef APP_MAX_LINKS
 #define APP_MAX_LINKS                            16
@@ -370,6 +419,8 @@ struct app_eal_params {
        /* Support running on Xen dom0 without hugetlbfs */
        uint32_t xen_dom0_present;
        int xen_dom0;
+
+       uint32_t parsed;
 };
 
 #ifndef APP_APPNAME_SIZE
@@ -380,17 +431,9 @@ struct app_eal_params {
 #define APP_MAX_MEMPOOLS                         8
 #endif
 
-#ifndef APP_LINK_MAX_HWQ_IN
-#define APP_LINK_MAX_HWQ_IN                      64
-#endif
+#define APP_MAX_HWQ_IN                  (APP_MAX_LINKS * APP_LINK_MAX_HWQ_IN)
 
-#ifndef APP_LINK_MAX_HWQ_OUT
-#define APP_LINK_MAX_HWQ_OUT                     64
-#endif
-
-#define APP_MAX_HWQ_IN                     (APP_MAX_LINKS * APP_LINK_MAX_HWQ_IN)
-
-#define APP_MAX_HWQ_OUT                   (APP_MAX_LINKS * APP_LINK_MAX_HWQ_OUT)
+#define APP_MAX_HWQ_OUT                 (APP_MAX_LINKS * APP_LINK_MAX_HWQ_OUT)
 
 #ifndef APP_MAX_PKTQ_SWQ
 #define APP_MAX_PKTQ_SWQ                         256
@@ -398,24 +441,22 @@ struct app_eal_params {
 
 #define APP_MAX_PKTQ_TM                          APP_MAX_LINKS
 
+#define APP_MAX_PKTQ_KNI                         APP_MAX_LINKS
+
 #ifndef APP_MAX_PKTQ_SOURCE
-#define APP_MAX_PKTQ_SOURCE                      16
+#define APP_MAX_PKTQ_SOURCE                      64
 #endif
 
 #ifndef APP_MAX_PKTQ_SINK
-#define APP_MAX_PKTQ_SINK                        16
+#define APP_MAX_PKTQ_SINK                        64
 #endif
 
 #ifndef APP_MAX_MSGQ
-#define APP_MAX_MSGQ                             64
-#endif
-
-#ifndef APP_MAX_PIPELINES
-#define APP_MAX_PIPELINES                        64
+#define APP_MAX_MSGQ                             256
 #endif
 
 #ifndef APP_EAL_ARGC
-#define APP_EAL_ARGC                             32
+#define APP_EAL_ARGC                             64
 #endif
 
 #ifndef APP_MAX_PIPELINE_TYPES
@@ -453,6 +494,7 @@ struct app_params {
        struct app_pktq_hwq_out_params hwq_out_params[APP_MAX_HWQ_OUT];
        struct app_pktq_swq_params swq_params[APP_MAX_PKTQ_SWQ];
        struct app_pktq_tm_params tm_params[APP_MAX_PKTQ_TM];
+       struct app_pktq_kni_params kni_params[APP_MAX_PKTQ_KNI];
        struct app_pktq_source_params source_params[APP_MAX_PKTQ_SOURCE];
        struct app_pktq_sink_params sink_params[APP_MAX_PKTQ_SINK];
        struct app_msgq_params msgq_params[APP_MAX_MSGQ];
@@ -464,6 +506,7 @@ struct app_params {
        uint32_t n_pktq_hwq_out;
        uint32_t n_pktq_swq;
        uint32_t n_pktq_tm;
+       uint32_t n_pktq_kni;
        uint32_t n_pktq_source;
        uint32_t n_pktq_sink;
        uint32_t n_msgq;
@@ -474,8 +517,12 @@ struct app_params {
        struct cpu_core_map *core_map;
        uint64_t core_mask;
        struct rte_mempool *mempool[APP_MAX_MEMPOOLS];
+       struct app_link_data link_data[APP_MAX_LINKS];
        struct rte_ring *swq[APP_MAX_PKTQ_SWQ];
        struct rte_sched_port *tm[APP_MAX_PKTQ_TM];
+#ifdef RTE_LIBRTE_KNI
+       struct rte_kni *kni[APP_MAX_PKTQ_KNI];
+#endif /* RTE_LIBRTE_KNI */
        struct rte_ring *msgq[APP_MAX_MSGQ];
        struct pipeline_type pipeline_type[APP_MAX_PIPELINE_TYPES];
        struct app_pipeline_data pipeline_data[APP_MAX_PIPELINES];
@@ -529,28 +576,6 @@ do                                                                 \
        sscanf(obj->name, prefix "%" SCNu32, &id);                              \
 while (0)                                                              \
 
-#define APP_PARAM_ADD(obj_array, obj_name)                             \
-({                                                                     \
-       ssize_t obj_idx;                                                \
-       const ssize_t obj_count = RTE_DIM(obj_array);                   \
-                                                                       \
-       obj_idx = APP_PARAM_FIND(obj_array, obj_name);                  \
-       if (obj_idx < 0) {                                              \
-               for (obj_idx = 0; obj_idx < obj_count; obj_idx++) {     \
-                       if (!APP_PARAM_VALID(&((obj_array)[obj_idx])))  \
-                               break;                                  \
-               }                                                       \
-                                                                       \
-               if (obj_idx < obj_count) {                              \
-                       (obj_array)[obj_idx].name = strdup(obj_name);   \
-                       if ((obj_array)[obj_idx].name == NULL)          \
-                               obj_idx = -EINVAL;                      \
-               } else                                                  \
-                       obj_idx = -ENOMEM;                              \
-       }                                                               \
-       obj_idx;                                                        \
-})
-
 #define        APP_CHECK(exp, fmt, ...)                                        \
 do {                                                                   \
        if (!(exp)) {                                                   \
@@ -665,6 +690,41 @@ app_swq_get_readers(struct app_params *app, struct app_pktq_swq_params *swq)
        return n_readers;
 }
 
+static inline struct app_pipeline_params *
+app_swq_get_reader(struct app_params *app,
+       struct app_pktq_swq_params *swq,
+       uint32_t *pktq_in_id)
+{
+       struct app_pipeline_params *reader = NULL;
+       uint32_t pos = swq - app->swq_params;
+       uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+               RTE_DIM(app->pipeline_params));
+       uint32_t n_readers = 0, id = 0, i;
+
+       for (i = 0; i < n_pipelines; i++) {
+               struct app_pipeline_params *p = &app->pipeline_params[i];
+               uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
+               uint32_t j;
+
+               for (j = 0; j < n_pktq_in; j++) {
+                       struct app_pktq_in_params *pktq = &p->pktq_in[j];
+
+                       if ((pktq->type == APP_PKTQ_IN_SWQ) &&
+                               (pktq->id == pos)) {
+                               n_readers++;
+                               reader = p;
+                               id = j;
+                       }
+               }
+       }
+
+       if (n_readers != 1)
+               return NULL;
+
+       *pktq_in_id = id;
+       return reader;
+}
+
 static inline uint32_t
 app_tm_get_readers(struct app_params *app, struct app_pktq_tm_params *tm)
 {
@@ -690,6 +750,101 @@ app_tm_get_readers(struct app_params *app, struct app_pktq_tm_params *tm)
        return n_readers;
 }
 
+static inline struct app_pipeline_params *
+app_tm_get_reader(struct app_params *app,
+       struct app_pktq_tm_params *tm,
+       uint32_t *pktq_in_id)
+{
+       struct app_pipeline_params *reader = NULL;
+       uint32_t pos = tm - app->tm_params;
+       uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+               RTE_DIM(app->pipeline_params));
+       uint32_t n_readers = 0, id = 0, i;
+
+       for (i = 0; i < n_pipelines; i++) {
+               struct app_pipeline_params *p = &app->pipeline_params[i];
+               uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
+               uint32_t j;
+
+               for (j = 0; j < n_pktq_in; j++) {
+                       struct app_pktq_in_params *pktq = &p->pktq_in[j];
+
+                       if ((pktq->type == APP_PKTQ_IN_TM) &&
+                               (pktq->id == pos)) {
+                               n_readers++;
+                               reader = p;
+                               id = j;
+                       }
+               }
+       }
+
+       if (n_readers != 1)
+               return NULL;
+
+       *pktq_in_id = id;
+       return reader;
+}
+
+static inline uint32_t
+app_kni_get_readers(struct app_params *app, struct app_pktq_kni_params *kni)
+{
+       uint32_t pos = kni - app->kni_params;
+       uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+               RTE_DIM(app->pipeline_params));
+       uint32_t n_readers = 0, i;
+
+       for (i = 0; i < n_pipelines; i++) {
+               struct app_pipeline_params *p = &app->pipeline_params[i];
+               uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
+               uint32_t j;
+
+               for (j = 0; j < n_pktq_in; j++) {
+                       struct app_pktq_in_params *pktq = &p->pktq_in[j];
+
+                       if ((pktq->type == APP_PKTQ_IN_KNI) &&
+                               (pktq->id == pos))
+                               n_readers++;
+               }
+       }
+
+       return n_readers;
+}
+
+static inline struct app_pipeline_params *
+app_kni_get_reader(struct app_params *app,
+                                 struct app_pktq_kni_params *kni,
+                                 uint32_t *pktq_in_id)
+{
+       struct app_pipeline_params *reader = NULL;
+       uint32_t pos = kni - app->kni_params;
+       uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+               RTE_DIM(app->pipeline_params));
+       uint32_t n_readers = 0, id = 0, i;
+
+       for (i = 0; i < n_pipelines; i++) {
+               struct app_pipeline_params *p = &app->pipeline_params[i];
+               uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
+               uint32_t j;
+
+               for (j = 0; j < n_pktq_in; j++) {
+                       struct app_pktq_in_params *pktq = &p->pktq_in[j];
+
+                       if ((pktq->type == APP_PKTQ_IN_KNI) &&
+                               (pktq->id == pos)) {
+                               n_readers++;
+                               reader = p;
+                               id = j;
+                       }
+               }
+       }
+
+       if (n_readers != 1)
+               return NULL;
+
+       *pktq_in_id = id;
+       return reader;
+}
+
 static inline uint32_t
 app_source_get_readers(struct app_params *app,
 struct app_pktq_source_params *source)
@@ -789,6 +944,42 @@ app_swq_get_writers(struct app_params *app, struct app_pktq_swq_params *swq)
        return n_writers;
 }
 
+static inline struct app_pipeline_params *
+app_swq_get_writer(struct app_params *app,
+       struct app_pktq_swq_params *swq,
+       uint32_t *pktq_out_id)
+{
+       struct app_pipeline_params *writer = NULL;
+       uint32_t pos = swq - app->swq_params;
+       uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+               RTE_DIM(app->pipeline_params));
+       uint32_t n_writers = 0, id = 0, i;
+
+       for (i = 0; i < n_pipelines; i++) {
+               struct app_pipeline_params *p = &app->pipeline_params[i];
+               uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
+                       RTE_DIM(p->pktq_out));
+               uint32_t j;
+
+               for (j = 0; j < n_pktq_out; j++) {
+                       struct app_pktq_out_params *pktq = &p->pktq_out[j];
+
+                       if ((pktq->type == APP_PKTQ_OUT_SWQ) &&
+                               (pktq->id == pos)) {
+                               n_writers++;
+                               writer = p;
+                               id = j;
+                       }
+               }
+       }
+
+       if (n_writers != 1)
+               return NULL;
+
+       *pktq_out_id = id;
+       return writer;
+}
+
 static inline uint32_t
 app_tm_get_writers(struct app_params *app, struct app_pktq_tm_params *tm)
 {
@@ -815,6 +1006,104 @@ app_tm_get_writers(struct app_params *app, struct app_pktq_tm_params *tm)
        return n_writers;
 }
 
+static inline struct app_pipeline_params *
+app_tm_get_writer(struct app_params *app,
+       struct app_pktq_tm_params *tm,
+       uint32_t *pktq_out_id)
+{
+       struct app_pipeline_params *writer = NULL;
+       uint32_t pos = tm - app->tm_params;
+       uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+               RTE_DIM(app->pipeline_params));
+       uint32_t n_writers = 0, id = 0, i;
+
+       for (i = 0; i < n_pipelines; i++) {
+               struct app_pipeline_params *p = &app->pipeline_params[i];
+               uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
+                       RTE_DIM(p->pktq_out));
+               uint32_t j;
+
+               for (j = 0; j < n_pktq_out; j++) {
+                       struct app_pktq_out_params *pktq = &p->pktq_out[j];
+
+                       if ((pktq->type == APP_PKTQ_OUT_TM) &&
+                               (pktq->id == pos)) {
+                               n_writers++;
+                               writer = p;
+                               id = j;
+                       }
+               }
+       }
+
+       if (n_writers != 1)
+               return NULL;
+
+       *pktq_out_id = id;
+       return writer;
+}
+
+static inline uint32_t
+app_kni_get_writers(struct app_params *app, struct app_pktq_kni_params *kni)
+{
+       uint32_t pos = kni - app->kni_params;
+       uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+               RTE_DIM(app->pipeline_params));
+       uint32_t n_writers = 0, i;
+
+       for (i = 0; i < n_pipelines; i++) {
+               struct app_pipeline_params *p = &app->pipeline_params[i];
+               uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
+                       RTE_DIM(p->pktq_out));
+               uint32_t j;
+
+               for (j = 0; j < n_pktq_out; j++) {
+                       struct app_pktq_out_params *pktq = &p->pktq_out[j];
+
+                       if ((pktq->type == APP_PKTQ_OUT_KNI) &&
+                               (pktq->id == pos))
+                               n_writers++;
+               }
+       }
+
+       return n_writers;
+}
+
+static inline struct app_pipeline_params *
+app_kni_get_writer(struct app_params *app,
+                                 struct app_pktq_kni_params *kni,
+                                 uint32_t *pktq_out_id)
+{
+       struct app_pipeline_params *writer = NULL;
+       uint32_t pos = kni - app->kni_params;
+       uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+               RTE_DIM(app->pipeline_params));
+       uint32_t n_writers = 0, id = 0, i;
+
+       for (i = 0; i < n_pipelines; i++) {
+               struct app_pipeline_params *p = &app->pipeline_params[i];
+               uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
+                       RTE_DIM(p->pktq_out));
+               uint32_t j;
+
+               for (j = 0; j < n_pktq_out; j++) {
+                       struct app_pktq_out_params *pktq = &p->pktq_out[j];
+
+                       if ((pktq->type == APP_PKTQ_OUT_KNI) &&
+                               (pktq->id == pos)) {
+                               n_writers++;
+                               writer = p;
+                               id = j;
+                       }
+               }
+       }
+
+       if (n_writers != 1)
+               return NULL;
+
+       *pktq_out_id = id;
+       return writer;
+}
+
 static inline uint32_t
 app_sink_get_writers(struct app_params *app, struct app_pktq_sink_params *sink)
 {
@@ -913,6 +1202,26 @@ app_get_link_for_tm(struct app_params *app, struct app_pktq_tm_params *p_tm)
        return &app->link_params[link_param_idx];
 }
 
+static inline struct app_link_params *
+app_get_link_for_kni(struct app_params *app, struct app_pktq_kni_params *p_kni)
+{
+       char link_name[APP_PARAM_NAME_SIZE];
+       uint32_t link_id;
+       ssize_t link_param_idx;
+
+       sscanf(p_kni->name, "KNI%" PRIu32, &link_id);
+       sprintf(link_name, "LINK%" PRIu32, link_id);
+       link_param_idx = APP_PARAM_FIND(app->link_params, link_name);
+       APP_CHECK((link_param_idx >= 0),
+                         "Cannot find %s for %s", link_name, p_kni->name);
+
+       return &app->link_params[link_param_idx];
+}
+
+void app_pipeline_params_get(struct app_params *app,
+       struct app_pipeline_params *p_in,
+       struct pipeline_params *p_out);
+
 int app_config_init(struct app_params *app);
 
 int app_config_args(struct app_params *app,
@@ -932,6 +1241,8 @@ int app_config_check(struct app_params *app);
 
 int app_init(struct app_params *app);
 
+int app_post_init(struct app_params *app);
+
 int app_thread(void *arg);
 
 int app_pipeline_type_register(struct app_params *app,