examples/ip_pipeline: remove routing pipeline
authorJasvinder Singh <jasvinder.singh@intel.com>
Thu, 29 Mar 2018 18:31:33 +0000 (19:31 +0100)
committerCristian Dumitrescu <cristian.dumitrescu@intel.com>
Wed, 4 Apr 2018 10:26:21 +0000 (12:26 +0200)
Remove routing pipeline.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
examples/ip_pipeline/Makefile
examples/ip_pipeline/init.c
examples/ip_pipeline/meson.build
examples/ip_pipeline/pipeline/pipeline_routing.c [deleted file]
examples/ip_pipeline/pipeline/pipeline_routing.h [deleted file]
examples/ip_pipeline/pipeline/pipeline_routing_be.c [deleted file]
examples/ip_pipeline/pipeline/pipeline_routing_be.h [deleted file]

index 089c269..f67cfe6 100644 (file)
@@ -25,8 +25,6 @@ SRCS-y += pipeline_flow_classification_be.c
 SRCS-y += pipeline_flow_classification.c
 SRCS-y += pipeline_flow_actions_be.c
 SRCS-y += pipeline_flow_actions.c
-SRCS-y += pipeline_routing_be.c
-SRCS-y += pipeline_routing.c
 
 # Build using pkg-config variables if possible
 $(shell pkg-config --exists libdpdk)
index 73b93d7..241d80a 100644 (file)
@@ -29,7 +29,6 @@
 #include "pipeline_firewall.h"
 #include "pipeline_flow_classification.h"
 #include "pipeline_flow_actions.h"
-#include "pipeline_routing.h"
 #include "thread_fe.h"
 
 #define APP_NAME_SIZE  32
@@ -1824,7 +1823,6 @@ int app_init(struct app_params *app)
        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);
 
        app_init_pipelines(app);
        app_init_threads(app);
index 17f4e16..f9eab1b 100644 (file)
@@ -29,6 +29,4 @@ sources = files(
        'pipeline/pipeline_flow_classification.c',
        'pipeline/pipeline_master_be.c',
        'pipeline/pipeline_master.c',
-       'pipeline/pipeline_routing_be.c',
-       'pipeline/pipeline_routing.c',
 )
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.c b/examples/ip_pipeline/pipeline/pipeline_routing.c
deleted file mode 100644 (file)
index 0562c63..0000000
+++ /dev/null
@@ -1,1613 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <cmdline_parse.h>
-#include <cmdline_parse_num.h>
-#include <cmdline_parse_string.h>
-
-#include "app.h"
-#include "pipeline_common_fe.h"
-#include "pipeline_routing.h"
-#include "parser.h"
-
-struct app_pipeline_routing_route {
-       struct pipeline_routing_route_key key;
-       struct pipeline_routing_route_data data;
-       void *entry_ptr;
-
-       TAILQ_ENTRY(app_pipeline_routing_route) node;
-};
-
-struct app_pipeline_routing_arp_entry {
-       struct pipeline_routing_arp_key key;
-       struct ether_addr macaddr;
-       void *entry_ptr;
-
-       TAILQ_ENTRY(app_pipeline_routing_arp_entry) node;
-};
-
-struct pipeline_routing {
-       /* Parameters */
-       struct app_params *app;
-       uint32_t pipeline_id;
-       uint32_t n_ports_in;
-       uint32_t n_ports_out;
-       struct pipeline_routing_params rp;
-
-       /* Links */
-       uint32_t link_id[PIPELINE_MAX_PORT_OUT];
-
-       /* Routes */
-       TAILQ_HEAD(, app_pipeline_routing_route) routes;
-       uint32_t n_routes;
-
-       uint32_t default_route_present;
-       uint32_t default_route_port_id;
-       void *default_route_entry_ptr;
-
-       /* ARP entries */
-       TAILQ_HEAD(, app_pipeline_routing_arp_entry) arp_entries;
-       uint32_t n_arp_entries;
-
-       uint32_t default_arp_entry_present;
-       uint32_t default_arp_entry_port_id;
-       void *default_arp_entry_ptr;
-};
-
-static int
-app_pipeline_routing_find_link(struct pipeline_routing *p,
-       uint32_t link_id,
-       uint32_t *port_id)
-{
-       uint32_t i;
-
-       for (i = 0; i < p->n_ports_out; i++)
-               if (p->link_id[i] == link_id) {
-                       *port_id = i;
-                       return 0;
-               }
-
-       return -1;
-}
-
-static void
-app_pipeline_routing_link_op(__rte_unused struct app_params *app,
-       uint32_t link_id,
-       uint32_t up,
-       void *arg)
-{
-       struct pipeline_routing_route_key key0, key1;
-       struct pipeline_routing *p = arg;
-       struct app_link_params *lp;
-       uint32_t port_id, netmask;
-       int status;
-
-       if (app == NULL)
-               return;
-
-       APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, lp);
-       if (lp == NULL)
-               return;
-
-       status = app_pipeline_routing_find_link(p,
-               link_id,
-               &port_id);
-       if (status)
-               return;
-
-       netmask = (~0U) << (32 - lp->depth);
-
-       /* Local network (directly attached network) */
-       key0.type = PIPELINE_ROUTING_ROUTE_IPV4;
-       key0.key.ipv4.ip = lp->ip & netmask;
-       key0.key.ipv4.depth = lp->depth;
-
-       /* Local termination */
-       key1.type = PIPELINE_ROUTING_ROUTE_IPV4;
-       key1.key.ipv4.ip = lp->ip;
-       key1.key.ipv4.depth = 32;
-
-       if (up) {
-               struct pipeline_routing_route_data data0, data1;
-
-               /* Local network (directly attached network) */
-               memset(&data0, 0, sizeof(data0));
-               data0.flags = PIPELINE_ROUTING_ROUTE_LOCAL |
-                       PIPELINE_ROUTING_ROUTE_ARP;
-               if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ)
-                       data0.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
-               if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) {
-                       data0.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
-                       data0.l2.mpls.n_labels = 1;
-               }
-               data0.port_id = port_id;
-
-               if (p->rp.n_arp_entries)
-                       app_pipeline_routing_add_route(app,
-                               p->pipeline_id,
-                               &key0,
-                               &data0);
-
-               /* Local termination */
-               memset(&data1, 0, sizeof(data1));
-               data1.flags = PIPELINE_ROUTING_ROUTE_LOCAL |
-                       PIPELINE_ROUTING_ROUTE_ARP;
-               if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ)
-                       data1.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
-               if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) {
-                       data1.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
-                       data1.l2.mpls.n_labels = 1;
-               }
-               data1.port_id = p->rp.port_local_dest;
-
-               app_pipeline_routing_add_route(app,
-                       p->pipeline_id,
-                       &key1,
-                       &data1);
-       } else {
-               /* Local network (directly attached network) */
-               if (p->rp.n_arp_entries)
-                       app_pipeline_routing_delete_route(app,
-                               p->pipeline_id,
-                               &key0);
-
-               /* Local termination */
-               app_pipeline_routing_delete_route(app,
-                       p->pipeline_id,
-                       &key1);
-       }
-}
-
-static int
-app_pipeline_routing_set_link_op(
-       struct app_params *app,
-       struct pipeline_routing *p)
-{
-       uint32_t port_id;
-
-       for (port_id = 0; port_id < p->n_ports_out; port_id++) {
-               struct app_link_params *link;
-               uint32_t link_id;
-               int status;
-
-               link = app_pipeline_track_pktq_out_to_link(app,
-                       p->pipeline_id,
-                       port_id);
-               if (link == NULL)
-                       continue;
-
-               link_id = link - app->link_params;
-               p->link_id[port_id] = link_id;
-
-               status = app_link_set_op(app,
-                       link_id,
-                       p->pipeline_id,
-                       app_pipeline_routing_link_op,
-                       (void *) p);
-               if (status)
-                       return status;
-       }
-
-       return 0;
-}
-
-static void *
-app_pipeline_routing_init(struct pipeline_params *params,
-       void *arg)
-{
-       struct app_params *app = (struct app_params *) arg;
-       struct pipeline_routing *p;
-       uint32_t pipeline_id, size;
-       int status;
-
-       /* Check input arguments */
-       if ((params == NULL) ||
-               (params->n_ports_in == 0) ||
-               (params->n_ports_out == 0))
-               return NULL;
-
-       APP_PARAM_GET_ID(params, "PIPELINE", pipeline_id);
-
-       /* Memory allocation */
-       size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_routing));
-       p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
-       if (p == NULL)
-               return NULL;
-
-       /* Initialization */
-       p->app = app;
-       p->pipeline_id = pipeline_id;
-       p->n_ports_in = params->n_ports_in;
-       p->n_ports_out = params->n_ports_out;
-
-       status = pipeline_routing_parse_args(&p->rp, params);
-       if (status) {
-               rte_free(p);
-               return NULL;
-       }
-       TAILQ_INIT(&p->routes);
-       p->n_routes = 0;
-
-       TAILQ_INIT(&p->arp_entries);
-       p->n_arp_entries = 0;
-
-       app_pipeline_routing_set_link_op(app, p);
-
-       return p;
-}
-
-static int
-app_pipeline_routing_post_init(void *pipeline)
-{
-       struct pipeline_routing *p = pipeline;
-
-       /* Check input arguments */
-       if (p == NULL)
-               return -1;
-
-       return app_pipeline_routing_set_macaddr(p->app, p->pipeline_id);
-}
-
-static int
-app_pipeline_routing_free(void *pipeline)
-{
-       struct pipeline_routing *p = pipeline;
-
-       /* Check input arguments */
-       if (p == NULL)
-               return -1;
-
-       /* Free resources */
-       while (!TAILQ_EMPTY(&p->routes)) {
-               struct app_pipeline_routing_route *route;
-
-               route = TAILQ_FIRST(&p->routes);
-               TAILQ_REMOVE(&p->routes, route, node);
-               rte_free(route);
-       }
-
-       while (!TAILQ_EMPTY(&p->arp_entries)) {
-               struct app_pipeline_routing_arp_entry *arp_entry;
-
-               arp_entry = TAILQ_FIRST(&p->arp_entries);
-               TAILQ_REMOVE(&p->arp_entries, arp_entry, node);
-               rte_free(arp_entry);
-       }
-
-       rte_free(p);
-       return 0;
-}
-
-static struct app_pipeline_routing_route *
-app_pipeline_routing_find_route(struct pipeline_routing *p,
-               const struct pipeline_routing_route_key *key)
-{
-       struct app_pipeline_routing_route *it, *found;
-
-       found = NULL;
-       TAILQ_FOREACH(it, &p->routes, node) {
-               if ((key->type == it->key.type) &&
-                       (key->key.ipv4.ip == it->key.key.ipv4.ip) &&
-                       (key->key.ipv4.depth == it->key.key.ipv4.depth)) {
-                       found = it;
-                       break;
-               }
-       }
-
-       return found;
-}
-
-static struct app_pipeline_routing_arp_entry *
-app_pipeline_routing_find_arp_entry(struct pipeline_routing *p,
-               const struct pipeline_routing_arp_key *key)
-{
-       struct app_pipeline_routing_arp_entry *it, *found;
-
-       found = NULL;
-       TAILQ_FOREACH(it, &p->arp_entries, node) {
-               if ((key->type == it->key.type) &&
-                       (key->key.ipv4.port_id == it->key.key.ipv4.port_id) &&
-                       (key->key.ipv4.ip == it->key.key.ipv4.ip)) {
-                       found = it;
-                       break;
-               }
-       }
-
-       return found;
-}
-
-static void
-print_route(const struct app_pipeline_routing_route *route)
-{
-       if (route->key.type == PIPELINE_ROUTING_ROUTE_IPV4) {
-               const struct pipeline_routing_route_key_ipv4 *key =
-                               &route->key.key.ipv4;
-
-               printf("IP Prefix = %" PRIu32 ".%" PRIu32
-                       ".%" PRIu32 ".%" PRIu32 "/%" PRIu32
-                       " => (Port = %" PRIu32,
-
-                       (key->ip >> 24) & 0xFF,
-                       (key->ip >> 16) & 0xFF,
-                       (key->ip >> 8) & 0xFF,
-                       key->ip & 0xFF,
-
-                       key->depth,
-                       route->data.port_id);
-
-               if (route->data.flags & PIPELINE_ROUTING_ROUTE_LOCAL)
-                       printf(", Local");
-               else if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP)
-                       printf(
-                               ", Next Hop IP = %" PRIu32 ".%" PRIu32
-                               ".%" PRIu32 ".%" PRIu32,
-
-                               (route->data.ethernet.ip >> 24) & 0xFF,
-                               (route->data.ethernet.ip >> 16) & 0xFF,
-                               (route->data.ethernet.ip >> 8) & 0xFF,
-                               route->data.ethernet.ip & 0xFF);
-               else
-                       printf(
-                               ", Next Hop HWaddress = %02" PRIx32
-                               ":%02" PRIx32 ":%02" PRIx32
-                               ":%02" PRIx32 ":%02" PRIx32
-                               ":%02" PRIx32,
-
-                               route->data.ethernet.macaddr.addr_bytes[0],
-                               route->data.ethernet.macaddr.addr_bytes[1],
-                               route->data.ethernet.macaddr.addr_bytes[2],
-                               route->data.ethernet.macaddr.addr_bytes[3],
-                               route->data.ethernet.macaddr.addr_bytes[4],
-                               route->data.ethernet.macaddr.addr_bytes[5]);
-
-               if (route->data.flags & PIPELINE_ROUTING_ROUTE_QINQ)
-                       printf(", QinQ SVLAN = %" PRIu32 " CVLAN = %" PRIu32,
-                               route->data.l2.qinq.svlan,
-                               route->data.l2.qinq.cvlan);
-
-               if (route->data.flags & PIPELINE_ROUTING_ROUTE_MPLS) {
-                       uint32_t i;
-
-                       printf(", MPLS labels");
-                       for (i = 0; i < route->data.l2.mpls.n_labels; i++)
-                               printf(" %" PRIu32,
-                                       route->data.l2.mpls.labels[i]);
-               }
-
-               printf(")\n");
-       }
-}
-
-static void
-print_arp_entry(const struct app_pipeline_routing_arp_entry *entry)
-{
-       printf("(Port = %" PRIu32 ", IP = %" PRIu32 ".%" PRIu32
-               ".%" PRIu32 ".%" PRIu32
-               ") => HWaddress = %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
-               ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n",
-
-               entry->key.key.ipv4.port_id,
-               (entry->key.key.ipv4.ip >> 24) & 0xFF,
-               (entry->key.key.ipv4.ip >> 16) & 0xFF,
-               (entry->key.key.ipv4.ip >> 8) & 0xFF,
-               entry->key.key.ipv4.ip & 0xFF,
-
-               entry->macaddr.addr_bytes[0],
-               entry->macaddr.addr_bytes[1],
-               entry->macaddr.addr_bytes[2],
-               entry->macaddr.addr_bytes[3],
-               entry->macaddr.addr_bytes[4],
-               entry->macaddr.addr_bytes[5]);
-}
-
-static int
-app_pipeline_routing_route_ls(struct app_params *app, uint32_t pipeline_id)
-{
-       struct pipeline_routing *p;
-       struct app_pipeline_routing_route *it;
-
-       p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
-       if (p == NULL)
-               return -EINVAL;
-
-       TAILQ_FOREACH(it, &p->routes, node)
-               print_route(it);
-
-       if (p->default_route_present)
-               printf("Default route: port %" PRIu32 " (entry ptr = %p)\n",
-                               p->default_route_port_id,
-                               p->default_route_entry_ptr);
-       else
-               printf("Default: DROP\n");
-
-       return 0;
-}
-
-int
-app_pipeline_routing_add_route(struct app_params *app,
-       uint32_t pipeline_id,
-       struct pipeline_routing_route_key *key,
-       struct pipeline_routing_route_data *data)
-{
-       struct pipeline_routing *p;
-
-       struct pipeline_routing_route_add_msg_req *req;
-       struct pipeline_routing_route_add_msg_rsp *rsp;
-
-       struct app_pipeline_routing_route *entry;
-
-       int new_entry;
-
-       /* Check input arguments */
-       if ((app == NULL) ||
-               (key == NULL) ||
-               (data == NULL))
-               return -1;
-
-       p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
-       if (p == NULL)
-               return -1;
-
-       switch (key->type) {
-       case PIPELINE_ROUTING_ROUTE_IPV4:
-       {
-               uint32_t depth = key->key.ipv4.depth;
-               uint32_t netmask;
-
-               /* key */
-               if ((depth == 0) || (depth > 32))
-                       return -1;
-
-               netmask = (~0U) << (32 - depth);
-               key->key.ipv4.ip &= netmask;
-
-               /* data */
-               if (data->port_id >= p->n_ports_out)
-                       return -1;
-
-               /* Valid range of VLAN tags 12 bits */
-               if (data->flags & PIPELINE_ROUTING_ROUTE_QINQ)
-                       if ((data->l2.qinq.svlan & 0xF000) ||
-                                       (data->l2.qinq.cvlan & 0xF000))
-                               return -1;
-
-               /* Max number of MPLS labels supported */
-               if (data->flags & PIPELINE_ROUTING_ROUTE_MPLS) {
-                       uint32_t i;
-
-                       if (data->l2.mpls.n_labels >
-                                       PIPELINE_ROUTING_MPLS_LABELS_MAX)
-                               return -1;
-
-                       /* Max MPLS label value 20 bits */
-                       for (i = 0; i < data->l2.mpls.n_labels; i++)
-                               if (data->l2.mpls.labels[i] & 0xFFF00000)
-                                       return -1;
-               }
-       }
-       break;
-
-       default:
-               return -1;
-       }
-
-       /* Find existing rule or allocate new rule */
-       entry = app_pipeline_routing_find_route(p, key);
-       new_entry = (entry == NULL);
-       if (entry == NULL) {
-               entry = rte_malloc(NULL, sizeof(*entry), RTE_CACHE_LINE_SIZE);
-
-               if (entry == NULL)
-                       return -1;
-       }
-
-       /* Allocate and write request */
-       req = app_msg_alloc(app);
-       if (req == NULL) {
-               if (new_entry)
-                       rte_free(entry);
-               return -1;
-       }
-
-       req->type = PIPELINE_MSG_REQ_CUSTOM;
-       req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD;
-       memcpy(&req->key, key, sizeof(*key));
-       memcpy(&req->data, data, sizeof(*data));
-
-       rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
-       if (rsp == NULL) {
-               if (new_entry)
-                       rte_free(entry);
-               return -1;
-       }
-
-       /* Read response and write entry */
-       if (rsp->status ||
-               (rsp->entry_ptr == NULL) ||
-               ((new_entry == 0) && (rsp->key_found == 0)) ||
-               ((new_entry == 1) && (rsp->key_found == 1))) {
-               app_msg_free(app, rsp);
-               if (new_entry)
-                       rte_free(entry);
-               return -1;
-       }
-
-       memcpy(&entry->key, key, sizeof(*key));
-       memcpy(&entry->data, data, sizeof(*data));
-       entry->entry_ptr = rsp->entry_ptr;
-
-       /* Commit entry */
-       if (new_entry) {
-               TAILQ_INSERT_TAIL(&p->routes, entry, node);
-               p->n_routes++;
-       }
-
-       /* Message buffer free */
-       app_msg_free(app, rsp);
-       return 0;
-}
-
-int
-app_pipeline_routing_delete_route(struct app_params *app,
-       uint32_t pipeline_id,
-       struct pipeline_routing_route_key *key)
-{
-       struct pipeline_routing *p;
-
-       struct pipeline_routing_route_delete_msg_req *req;
-       struct pipeline_routing_route_delete_msg_rsp *rsp;
-
-       struct app_pipeline_routing_route *entry;
-
-       /* Check input arguments */
-       if ((app == NULL) ||
-               (key == NULL))
-               return -1;
-
-       p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
-       if (p == NULL)
-               return -1;
-
-       switch (key->type) {
-       case PIPELINE_ROUTING_ROUTE_IPV4:
-       {
-               uint32_t depth = key->key.ipv4.depth;
-               uint32_t netmask;
-
-               /* key */
-               if ((depth == 0) || (depth > 32))
-                       return -1;
-
-               netmask = (~0U) << (32 - depth);
-               key->key.ipv4.ip &= netmask;
-       }
-       break;
-
-       default:
-               return -1;
-       }
-
-       /* Find rule */
-       entry = app_pipeline_routing_find_route(p, key);
-       if (entry == NULL)
-               return 0;
-
-       /* Allocate and write request */
-       req = app_msg_alloc(app);
-       if (req == NULL)
-               return -1;
-
-       req->type = PIPELINE_MSG_REQ_CUSTOM;
-       req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL;
-       memcpy(&req->key, key, sizeof(*key));
-
-       rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
-       if (rsp == NULL)
-               return -1;
-
-       /* Read response */
-       if (rsp->status || !rsp->key_found) {
-               app_msg_free(app, rsp);
-               return -1;
-       }
-
-       /* Remove route */
-       TAILQ_REMOVE(&p->routes, entry, node);
-       p->n_routes--;
-       rte_free(entry);
-
-       /* Free response */
-       app_msg_free(app, rsp);
-
-       return 0;
-}
-
-int
-app_pipeline_routing_add_default_route(struct app_params *app,
-       uint32_t pipeline_id,
-       uint32_t port_id)
-{
-       struct pipeline_routing *p;
-
-       struct pipeline_routing_route_add_default_msg_req *req;
-       struct pipeline_routing_route_add_default_msg_rsp *rsp;
-
-       /* Check input arguments */
-       if (app == NULL)
-               return -1;
-
-       p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
-       if (p == NULL)
-               return -1;
-
-       if (port_id >= p->n_ports_out)
-               return -1;
-
-       /* Allocate and write request */
-       req = app_msg_alloc(app);
-       if (req == NULL)
-               return -1;
-
-       req->type = PIPELINE_MSG_REQ_CUSTOM;
-       req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD_DEFAULT;
-       req->port_id = port_id;
-
-       /* Send request and wait for response */
-       rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
-       if (rsp == NULL)
-               return -1;
-
-       /* Read response and write route */
-       if (rsp->status || (rsp->entry_ptr == NULL)) {
-               app_msg_free(app, rsp);
-               return -1;
-       }
-
-       p->default_route_port_id = port_id;
-       p->default_route_entry_ptr = rsp->entry_ptr;
-
-       /* Commit route */
-       p->default_route_present = 1;
-
-       /* Free response */
-       app_msg_free(app, rsp);
-
-       return 0;
-}
-
-int
-app_pipeline_routing_delete_default_route(struct app_params *app,
-       uint32_t pipeline_id)
-{
-       struct pipeline_routing *p;
-
-       struct pipeline_routing_arp_delete_default_msg_req *req;
-       struct pipeline_routing_arp_delete_default_msg_rsp *rsp;
-
-       /* Check input arguments */
-       if (app == NULL)
-               return -1;
-
-       p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
-       if (p == NULL)
-               return -1;
-
-       /* Allocate and write request */
-       req = app_msg_alloc(app);
-       if (req == NULL)
-               return -1;
-
-       req->type = PIPELINE_MSG_REQ_CUSTOM;
-       req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL_DEFAULT;
-
-       /* Send request and wait for response */
-       rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
-       if (rsp == NULL)
-               return -1;
-
-       /* Read response and write route */
-       if (rsp->status) {
-               app_msg_free(app, rsp);
-               return -1;
-       }
-
-       /* Commit route */
-       p->default_route_present = 0;
-
-       /* Free response */
-       app_msg_free(app, rsp);
-
-       return 0;
-}
-
-static int
-app_pipeline_routing_arp_ls(struct app_params *app, uint32_t pipeline_id)
-{
-       struct pipeline_routing *p;
-       struct app_pipeline_routing_arp_entry *it;
-
-       p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
-       if (p == NULL)
-               return -EINVAL;
-
-       TAILQ_FOREACH(it, &p->arp_entries, node)
-               print_arp_entry(it);
-
-       if (p->default_arp_entry_present)
-               printf("Default entry: port %" PRIu32 " (entry ptr = %p)\n",
-                               p->default_arp_entry_port_id,
-                               p->default_arp_entry_ptr);
-       else
-               printf("Default: DROP\n");
-
-       return 0;
-}
-
-int
-app_pipeline_routing_add_arp_entry(struct app_params *app, uint32_t pipeline_id,
-               struct pipeline_routing_arp_key *key,
-               struct ether_addr *macaddr)
-{
-       struct pipeline_routing *p;
-
-       struct pipeline_routing_arp_add_msg_req *req;
-       struct pipeline_routing_arp_add_msg_rsp *rsp;
-
-       struct app_pipeline_routing_arp_entry *entry;
-
-       int new_entry;
-
-       /* Check input arguments */
-       if ((app == NULL) ||
-               (key == NULL) ||
-               (macaddr == NULL))
-               return -1;
-
-       p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
-       if (p == NULL)
-               return -1;
-
-       switch (key->type) {
-       case PIPELINE_ROUTING_ARP_IPV4:
-       {
-               uint32_t port_id = key->key.ipv4.port_id;
-
-               /* key */
-               if (port_id >= p->n_ports_out)
-                       return -1;
-       }
-       break;
-
-       default:
-               return -1;
-       }
-
-       /* Find existing entry or allocate new */
-       entry = app_pipeline_routing_find_arp_entry(p, key);
-       new_entry = (entry == NULL);
-       if (entry == NULL) {
-               entry = rte_malloc(NULL, sizeof(*entry), RTE_CACHE_LINE_SIZE);
-
-               if (entry == NULL)
-                       return -1;
-       }
-
-       /* Message buffer allocation */
-       req = app_msg_alloc(app);
-       if (req == NULL) {
-               if (new_entry)
-                       rte_free(entry);
-               return -1;
-       }
-
-       req->type = PIPELINE_MSG_REQ_CUSTOM;
-       req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_ADD;
-       memcpy(&req->key, key, sizeof(*key));
-       ether_addr_copy(macaddr, &req->macaddr);
-
-       /* Send request and wait for response */
-       rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
-       if (rsp == NULL) {
-               if (new_entry)
-                       rte_free(entry);
-               return -1;
-       }
-
-       /* Read response and write entry */
-       if (rsp->status ||
-               (rsp->entry_ptr == NULL) ||
-               ((new_entry == 0) && (rsp->key_found == 0)) ||
-               ((new_entry == 1) && (rsp->key_found == 1))) {
-               app_msg_free(app, rsp);
-               if (new_entry)
-                       rte_free(entry);
-               return -1;
-       }
-
-       memcpy(&entry->key, key, sizeof(*key));
-       ether_addr_copy(macaddr, &entry->macaddr);
-       entry->entry_ptr = rsp->entry_ptr;
-
-       /* Commit entry */
-       if (new_entry) {
-               TAILQ_INSERT_TAIL(&p->arp_entries, entry, node);
-               p->n_arp_entries++;
-       }
-
-       /* Message buffer free */
-       app_msg_free(app, rsp);
-       return 0;
-}
-
-int
-app_pipeline_routing_delete_arp_entry(struct app_params *app,
-       uint32_t pipeline_id,
-       struct pipeline_routing_arp_key *key)
-{
-       struct pipeline_routing *p;
-
-       struct pipeline_routing_arp_delete_msg_req *req;
-       struct pipeline_routing_arp_delete_msg_rsp *rsp;
-
-       struct app_pipeline_routing_arp_entry *entry;
-
-       /* Check input arguments */
-       if ((app == NULL) ||
-               (key == NULL))
-               return -1;
-
-       p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
-       if (p == NULL)
-               return -EINVAL;
-
-       switch (key->type) {
-       case PIPELINE_ROUTING_ARP_IPV4:
-       {
-               uint32_t port_id = key->key.ipv4.port_id;
-
-               /* key */
-               if (port_id >= p->n_ports_out)
-                       return -1;
-       }
-       break;
-
-       default:
-               return -1;
-       }
-
-       /* Find rule */
-       entry = app_pipeline_routing_find_arp_entry(p, key);
-       if (entry == NULL)
-               return 0;
-
-       /* Allocate and write request */
-       req = app_msg_alloc(app);
-       if (req == NULL)
-               return -1;
-
-       req->type = PIPELINE_MSG_REQ_CUSTOM;
-       req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_DEL;
-       memcpy(&req->key, key, sizeof(*key));
-
-       rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
-       if (rsp == NULL)
-               return -1;
-
-       /* Read response */
-       if (rsp->status || !rsp->key_found) {
-               app_msg_free(app, rsp);
-               return -1;
-       }
-
-       /* Remove entry */
-       TAILQ_REMOVE(&p->arp_entries, entry, node);
-       p->n_arp_entries--;
-       rte_free(entry);
-
-       /* Free response */
-       app_msg_free(app, rsp);
-
-       return 0;
-}
-
-int
-app_pipeline_routing_add_default_arp_entry(struct app_params *app,
-               uint32_t pipeline_id,
-               uint32_t port_id)
-{
-       struct pipeline_routing *p;
-
-       struct pipeline_routing_arp_add_default_msg_req *req;
-       struct pipeline_routing_arp_add_default_msg_rsp *rsp;
-
-       /* Check input arguments */
-       if (app == NULL)
-               return -1;
-
-       p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
-       if (p == NULL)
-               return -1;
-
-       if (port_id >= p->n_ports_out)
-               return -1;
-
-       /* Allocate and write request */
-       req = app_msg_alloc(app);
-       if (req == NULL)
-               return -1;
-
-       req->type = PIPELINE_MSG_REQ_CUSTOM;
-       req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT;
-       req->port_id = port_id;
-
-       /* Send request and wait for response */
-       rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
-       if (rsp == NULL)
-               return -1;
-
-       /* Read response and write entry */
-       if (rsp->status || rsp->entry_ptr == NULL) {
-               app_msg_free(app, rsp);
-               return -1;
-       }
-
-       p->default_arp_entry_port_id = port_id;
-       p->default_arp_entry_ptr = rsp->entry_ptr;
-
-       /* Commit entry */
-       p->default_arp_entry_present = 1;
-
-       /* Free response */
-       app_msg_free(app, rsp);
-
-       return 0;
-}
-
-int
-app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
-       uint32_t pipeline_id)
-{
-       struct pipeline_routing *p;
-
-       struct pipeline_routing_arp_delete_default_msg_req *req;
-       struct pipeline_routing_arp_delete_default_msg_rsp *rsp;
-
-       /* Check input arguments */
-       if (app == NULL)
-               return -1;
-
-       p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
-       if (p == NULL)
-               return -EINVAL;
-
-       /* Allocate and write request */
-       req = app_msg_alloc(app);
-       if (req == NULL)
-               return -ENOMEM;
-
-       req->type = PIPELINE_MSG_REQ_CUSTOM;
-       req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT;
-
-       /* Send request and wait for response */
-       rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
-       if (rsp == NULL)
-               return -ETIMEDOUT;
-
-       /* Read response and write entry */
-       if (rsp->status) {
-               app_msg_free(app, rsp);
-               return rsp->status;
-       }
-
-       /* Commit entry */
-       p->default_arp_entry_present = 0;
-
-       /* Free response */
-       app_msg_free(app, rsp);
-
-       return 0;
-}
-
-int
-app_pipeline_routing_set_macaddr(struct app_params *app,
-       uint32_t pipeline_id)
-{
-       struct app_pipeline_params *p;
-       struct pipeline_routing_set_macaddr_msg_req *req;
-       struct pipeline_routing_set_macaddr_msg_rsp *rsp;
-       uint32_t port_id;
-
-       /* Check input arguments */
-       if (app == NULL)
-               return -EINVAL;
-
-       APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
-       if (p == NULL)
-               return -EINVAL;
-
-       /* Allocate and write request */
-       req = app_msg_alloc(app);
-       if (req == NULL)
-               return -ENOMEM;
-
-       req->type = PIPELINE_MSG_REQ_CUSTOM;
-       req->subtype = PIPELINE_ROUTING_MSG_REQ_SET_MACADDR;
-
-       memset(req->macaddr, 0, sizeof(req->macaddr));
-       for (port_id = 0; port_id < p->n_pktq_out; port_id++) {
-               struct app_link_params *link;
-
-               link = app_pipeline_track_pktq_out_to_link(app,
-                       pipeline_id,
-                       port_id);
-               if (link)
-                       req->macaddr[port_id] = link->mac_addr;
-       }
-
-       /* Send request and wait for response */
-       rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
-       if (rsp == NULL)
-               return -ETIMEDOUT;
-
-       /* Read response and write entry */
-       if (rsp->status) {
-               app_msg_free(app, rsp);
-               return rsp->status;
-       }
-
-       /* Free response */
-       app_msg_free(app, rsp);
-
-       return 0;
-}
-
-/*
- * route
- *
- * route add (ARP = ON/OFF, MPLS = ON/OFF, QINQ = ON/OFF):
- *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr>
- *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr>
- *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr> qinq <svlan> <cvlan>
- *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr> qinq <svlan> <cvlan>
- *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr> mpls <mpls labels>
- *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr> mpls <mpls labels>
- *
- * route add default:
- *    p <pipelineid> route add default <portid>
- *
- * route del:
- *    p <pipelineid> route del <ipaddr> <depth>
- *
- * route del default:
- *    p <pipelineid> route del default
- *
- * route ls:
- *    p <pipelineid> route ls
- */
-
-struct cmd_route_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t route_string;
-       cmdline_multi_string_t multi_string;
-};
-
-static void
-cmd_route_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_route_result *params = parsed_result;
-       struct app_params *app = data;
-
-       char *tokens[16];
-       uint32_t n_tokens = RTE_DIM(tokens);
-       int status;
-
-       status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
-       if (status != 0) {
-               printf(CMD_MSG_TOO_MANY_ARGS, "route");
-               return;
-       }
-
-       /* route add */
-       if ((n_tokens >= 2) &&
-               (strcmp(tokens[0], "add") == 0) &&
-               strcmp(tokens[1], "default")) {
-               struct pipeline_routing_route_key key;
-               struct pipeline_routing_route_data route_data;
-               struct in_addr ipv4, nh_ipv4;
-               struct ether_addr mac_addr;
-               uint32_t depth, port_id, svlan, cvlan, i;
-               uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
-               uint32_t n_labels = RTE_DIM(mpls_labels);
-
-               memset(&key, 0, sizeof(key));
-               memset(&route_data, 0, sizeof(route_data));
-
-               if (n_tokens < 7) {
-                       printf(CMD_MSG_NOT_ENOUGH_ARGS, "route add");
-                       return;
-               }
-
-               if (parse_ipv4_addr(tokens[1], &ipv4)) {
-                       printf(CMD_MSG_INVALID_ARG, "ipaddr");
-                       return;
-               }
-
-               if (parser_read_uint32(&depth, tokens[2])) {
-                       printf(CMD_MSG_INVALID_ARG, "depth");
-                       return;
-               }
-
-               if (strcmp(tokens[3], "port")) {
-                       printf(CMD_MSG_ARG_NOT_FOUND, "port");
-                       return;
-               }
-
-               if (parser_read_uint32(&port_id, tokens[4])) {
-                       printf(CMD_MSG_INVALID_ARG, "portid");
-                       return;
-               }
-
-               if (strcmp(tokens[5], "ether")) {
-                       printf(CMD_MSG_ARG_NOT_FOUND, "ether");
-                       return;
-               }
-
-               if (parse_mac_addr(tokens[6], &mac_addr)) {
-                       if (parse_ipv4_addr(tokens[6], &nh_ipv4)) {
-                               printf(CMD_MSG_INVALID_ARG, "nhmacaddr or nhipaddr");
-                               return;
-                       }
-
-                       route_data.flags |= PIPELINE_ROUTING_ROUTE_ARP;
-               }
-
-               if (n_tokens > 7) {
-                       if (strcmp(tokens[7], "mpls") == 0) {
-                               if (n_tokens != 9) {
-                                       printf(CMD_MSG_MISMATCH_ARGS, "route add mpls");
-                                       return;
-                               }
-
-                               if (parse_mpls_labels(tokens[8], mpls_labels, &n_labels)) {
-                                       printf(CMD_MSG_INVALID_ARG, "mpls labels");
-                                       return;
-                               }
-
-                               route_data.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
-                       } else if (strcmp(tokens[7], "qinq") == 0) {
-                               if (n_tokens != 10) {
-                                       printf(CMD_MSG_MISMATCH_ARGS, "route add qinq");
-                                       return;
-                               }
-
-                               if (parser_read_uint32(&svlan, tokens[8])) {
-                                       printf(CMD_MSG_INVALID_ARG, "svlan");
-                                       return;
-                               }
-                               if (parser_read_uint32(&cvlan, tokens[9])) {
-                                       printf(CMD_MSG_INVALID_ARG, "cvlan");
-                                       return;
-                               }
-
-                               route_data.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
-                       } else {
-                               printf(CMD_MSG_ARG_NOT_FOUND, "mpls or qinq");
-                               return;
-                       }
-               }
-
-               switch (route_data.flags) {
-               case 0:
-                       route_data.port_id = port_id;
-                       route_data.ethernet.macaddr = mac_addr;
-                       break;
-
-               case PIPELINE_ROUTING_ROUTE_ARP:
-                       route_data.port_id = port_id;
-                       route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
-                       break;
-
-               case PIPELINE_ROUTING_ROUTE_MPLS:
-                       route_data.port_id = port_id;
-                       route_data.ethernet.macaddr = mac_addr;
-                       for (i = 0; i < n_labels; i++)
-                               route_data.l2.mpls.labels[i] = mpls_labels[i];
-                       route_data.l2.mpls.n_labels = n_labels;
-                       break;
-
-               case PIPELINE_ROUTING_ROUTE_MPLS | PIPELINE_ROUTING_ROUTE_ARP:
-                       route_data.port_id = port_id;
-                       route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
-                       for (i = 0; i < n_labels; i++)
-                               route_data.l2.mpls.labels[i] = mpls_labels[i];
-                       route_data.l2.mpls.n_labels = n_labels;
-                       break;
-
-               case PIPELINE_ROUTING_ROUTE_QINQ:
-                       route_data.port_id = port_id;
-                       route_data.ethernet.macaddr = mac_addr;
-                       route_data.l2.qinq.svlan = svlan;
-                       route_data.l2.qinq.cvlan = cvlan;
-                       break;
-
-               case PIPELINE_ROUTING_ROUTE_QINQ | PIPELINE_ROUTING_ROUTE_ARP:
-               default:
-                       route_data.port_id = port_id;
-                       route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
-                       route_data.l2.qinq.svlan = svlan;
-                       route_data.l2.qinq.cvlan = cvlan;
-                       break;
-               }
-
-               key.type = PIPELINE_ROUTING_ROUTE_IPV4;
-               key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
-               key.key.ipv4.depth = depth;
-
-               status = app_pipeline_routing_add_route(app,
-                       params->p,
-                       &key,
-                       &route_data);
-               if (status != 0)
-                       printf(CMD_MSG_FAIL, "route add");
-
-               return;
-       } /* route add */
-
-       /* route add default */
-       if ((n_tokens >= 2) &&
-               (strcmp(tokens[0], "add") == 0) &&
-               (strcmp(tokens[1], "default") == 0)) {
-               uint32_t port_id;
-
-               if (n_tokens != 3) {
-                       printf(CMD_MSG_MISMATCH_ARGS, "route add default");
-                       return;
-               }
-
-               if (parser_read_uint32(&port_id, tokens[2])) {
-                       printf(CMD_MSG_INVALID_ARG, "portid");
-                       return;
-               }
-
-               status = app_pipeline_routing_add_default_route(app,
-                       params->p,
-                       port_id);
-               if (status != 0)
-                       printf(CMD_MSG_FAIL, "route add default");
-
-               return;
-       } /* route add default */
-
-       /* route del*/
-       if ((n_tokens >= 2) &&
-               (strcmp(tokens[0], "del") == 0) &&
-               strcmp(tokens[1], "default")) {
-               struct pipeline_routing_route_key key;
-               struct in_addr ipv4;
-               uint32_t depth;
-
-               memset(&key, 0, sizeof(key));
-
-               if (n_tokens != 3) {
-                       printf(CMD_MSG_MISMATCH_ARGS, "route del");
-                       return;
-               }
-
-               if (parse_ipv4_addr(tokens[1], &ipv4)) {
-                       printf(CMD_MSG_INVALID_ARG, "ipaddr");
-                       return;
-               }
-
-               if (parser_read_uint32(&depth, tokens[2])) {
-                       printf(CMD_MSG_INVALID_ARG, "depth");
-                       return;
-               }
-
-               key.type = PIPELINE_ROUTING_ROUTE_IPV4;
-               key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
-               key.key.ipv4.depth = depth;
-
-               status = app_pipeline_routing_delete_route(app, params->p, &key);
-               if (status != 0)
-                       printf(CMD_MSG_FAIL, "route del");
-
-               return;
-       } /* route del */
-
-       /* route del default */
-       if ((n_tokens >= 2) &&
-               (strcmp(tokens[0], "del") == 0) &&
-               (strcmp(tokens[1], "default") == 0)) {
-               if (n_tokens != 2) {
-                       printf(CMD_MSG_MISMATCH_ARGS, "route del default");
-                       return;
-               }
-
-               status = app_pipeline_routing_delete_default_route(app,
-                       params->p);
-               if (status != 0)
-                       printf(CMD_MSG_FAIL, "route del default");
-
-               return;
-       } /* route del default */
-
-       /* route ls */
-       if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
-               if (n_tokens != 1) {
-                       printf(CMD_MSG_MISMATCH_ARGS, "route ls");
-                       return;
-               }
-
-               status = app_pipeline_routing_route_ls(app, params->p);
-               if (status != 0)
-                       printf(CMD_MSG_FAIL, "route ls");
-
-               return;
-       } /* route ls */
-
-       printf(CMD_MSG_MISMATCH_ARGS, "route");
-}
-
-static cmdline_parse_token_string_t cmd_route_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_result, p_string, "p");
-
-static cmdline_parse_token_num_t cmd_route_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_result, route_string, "route");
-
-static cmdline_parse_token_string_t cmd_route_multi_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_result, multi_string,
-       TOKEN_STRING_MULTI);
-
-static cmdline_parse_inst_t cmd_route = {
-       .f = cmd_route_parsed,
-       .data = NULL,
-       .help_str = "route add / add default / del / del default / ls",
-       .tokens = {
-               (void *)&cmd_route_p_string,
-               (void *)&cmd_route_p,
-               (void *)&cmd_route_route_string,
-               (void *)&cmd_route_multi_string,
-               NULL,
-       },
-};
-
-/*
- * arp
- *
- * arp add:
- *    p <pipelineid> arp add <portid> <ipaddr> <macaddr>
- *
- * arp add default:
- *    p <pipelineid> arp add default <portid>
- *
- * arp del:
- *    p <pipelineid> arp del <portid> <ipaddr>
- *
- * arp del default:
- *    p <pipelineid> arp del default
- *
- * arp ls:
- *    p <pipelineid> arp ls
- */
-
-struct cmd_arp_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t arp_string;
-       cmdline_multi_string_t multi_string;
-};
-
-static void
-cmd_arp_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_arp_result *params = parsed_result;
-       struct app_params *app = data;
-
-       char *tokens[16];
-       uint32_t n_tokens = RTE_DIM(tokens);
-       int status;
-
-       status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
-       if (status != 0) {
-               printf(CMD_MSG_TOO_MANY_ARGS, "arp");
-               return;
-       }
-
-       /* arp add */
-       if ((n_tokens >= 2) &&
-               (strcmp(tokens[0], "add") == 0) &&
-               strcmp(tokens[1], "default")) {
-               struct pipeline_routing_arp_key key;
-               struct in_addr ipv4;
-               struct ether_addr mac_addr;
-               uint32_t port_id;
-
-               memset(&key, 0, sizeof(key));
-
-               if (n_tokens != 4) {
-                       printf(CMD_MSG_MISMATCH_ARGS, "arp add");
-                       return;
-               }
-
-               if (parser_read_uint32(&port_id, tokens[1])) {
-                       printf(CMD_MSG_INVALID_ARG, "portid");
-                       return;
-               }
-
-               if (parse_ipv4_addr(tokens[2], &ipv4)) {
-                       printf(CMD_MSG_INVALID_ARG, "ipaddr");
-                       return;
-               }
-
-               if (parse_mac_addr(tokens[3], &mac_addr)) {
-                       printf(CMD_MSG_INVALID_ARG, "macaddr");
-                       return;
-               }
-
-               key.type = PIPELINE_ROUTING_ARP_IPV4;
-               key.key.ipv4.port_id = port_id;
-               key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
-
-               status = app_pipeline_routing_add_arp_entry(app,
-                       params->p,
-                       &key,
-                       &mac_addr);
-               if (status != 0)
-                       printf(CMD_MSG_FAIL, "arp add");
-
-               return;
-       } /* arp add */
-
-       /* arp add default */
-       if ((n_tokens >= 2) &&
-               (strcmp(tokens[0], "add") == 0) &&
-               (strcmp(tokens[1], "default") == 0)) {
-               uint32_t port_id;
-
-               if (n_tokens != 3) {
-                       printf(CMD_MSG_MISMATCH_ARGS, "arp add default");
-                       return;
-               }
-
-               if (parser_read_uint32(&port_id, tokens[2])) {
-                       printf(CMD_MSG_INVALID_ARG, "portid");
-                       return;
-               }
-
-               status = app_pipeline_routing_add_default_arp_entry(app,
-                       params->p,
-                       port_id);
-               if (status != 0)
-                       printf(CMD_MSG_FAIL, "arp add default");
-
-               return;
-       } /* arp add default */
-
-       /* arp del*/
-       if ((n_tokens >= 2) &&
-               (strcmp(tokens[0], "del") == 0) &&
-               strcmp(tokens[1], "default")) {
-               struct pipeline_routing_arp_key key;
-               struct in_addr ipv4;
-               uint32_t port_id;
-
-               memset(&key, 0, sizeof(key));
-
-               if (n_tokens != 3) {
-                       printf(CMD_MSG_MISMATCH_ARGS, "arp del");
-                       return;
-               }
-
-               if (parser_read_uint32(&port_id, tokens[1])) {
-                       printf(CMD_MSG_INVALID_ARG, "portid");
-                       return;
-               }
-
-               if (parse_ipv4_addr(tokens[2], &ipv4)) {
-                       printf(CMD_MSG_INVALID_ARG, "ipaddr");
-                       return;
-               }
-
-               key.type = PIPELINE_ROUTING_ARP_IPV4;
-               key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
-               key.key.ipv4.port_id = port_id;
-
-               status = app_pipeline_routing_delete_arp_entry(app,
-                       params->p,
-                       &key);
-               if (status != 0)
-                       printf(CMD_MSG_FAIL, "arp del");
-
-               return;
-       } /* arp del */
-
-       /* arp del default */
-       if ((n_tokens >= 2) &&
-               (strcmp(tokens[0], "del") == 0) &&
-               (strcmp(tokens[1], "default") == 0)) {
-                       if (n_tokens != 2) {
-                               printf(CMD_MSG_MISMATCH_ARGS, "arp del default");
-                               return;
-                       }
-
-                       status = app_pipeline_routing_delete_default_arp_entry(app,
-                               params->p);
-                       if (status != 0)
-                               printf(CMD_MSG_FAIL, "arp del default");
-
-                       return;
-       } /* arp del default */
-
-       /* arp ls */
-       if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
-               if (n_tokens != 1) {
-                       printf(CMD_MSG_MISMATCH_ARGS, "arp ls");
-                       return;
-               }
-
-               status = app_pipeline_routing_arp_ls(app, params->p);
-               if (status != 0)
-                       printf(CMD_MSG_FAIL, "arp ls");
-
-               return;
-       } /* arp ls */
-
-       printf(CMD_MSG_FAIL, "arp");
-}
-
-static cmdline_parse_token_string_t cmd_arp_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_result, p_string, "p");
-
-static cmdline_parse_token_num_t cmd_arp_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_arp_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_arp_arp_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_result, arp_string, "arp");
-
-static cmdline_parse_token_string_t cmd_arp_multi_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_result, multi_string,
-       TOKEN_STRING_MULTI);
-
-static cmdline_parse_inst_t cmd_arp = {
-       .f = cmd_arp_parsed,
-       .data = NULL,
-       .help_str = "arp add / add default / del / del default / ls",
-       .tokens = {
-               (void *)&cmd_arp_p_string,
-               (void *)&cmd_arp_p,
-               (void *)&cmd_arp_arp_string,
-               (void *)&cmd_arp_multi_string,
-               NULL,
-       },
-};
-
-static cmdline_parse_ctx_t pipeline_cmds[] = {
-       (cmdline_parse_inst_t *)&cmd_route,
-       (cmdline_parse_inst_t *)&cmd_arp,
-       NULL,
-};
-
-static struct pipeline_fe_ops pipeline_routing_fe_ops = {
-       .f_init = app_pipeline_routing_init,
-       .f_post_init = app_pipeline_routing_post_init,
-       .f_free = app_pipeline_routing_free,
-       .f_track = app_pipeline_track_default,
-       .cmds = pipeline_cmds,
-};
-
-struct pipeline_type pipeline_routing = {
-       .name = "ROUTING",
-       .be_ops = &pipeline_routing_be_ops,
-       .fe_ops = &pipeline_routing_fe_ops,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.h b/examples/ip_pipeline/pipeline/pipeline_routing.h
deleted file mode 100644 (file)
index f249295..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_ROUTING_H__
-#define __INCLUDE_PIPELINE_ROUTING_H__
-
-#include "pipeline.h"
-#include "pipeline_routing_be.h"
-
-/*
- * Route
- */
-
-int
-app_pipeline_routing_add_route(struct app_params *app,
-       uint32_t pipeline_id,
-       struct pipeline_routing_route_key *key,
-       struct pipeline_routing_route_data *data);
-
-int
-app_pipeline_routing_delete_route(struct app_params *app,
-       uint32_t pipeline_id,
-       struct pipeline_routing_route_key *key);
-
-int
-app_pipeline_routing_add_default_route(struct app_params *app,
-       uint32_t pipeline_id,
-       uint32_t port_id);
-
-int
-app_pipeline_routing_delete_default_route(struct app_params *app,
-       uint32_t pipeline_id);
-
-/*
- * ARP
- */
-
-int
-app_pipeline_routing_add_arp_entry(struct app_params *app,
-       uint32_t pipeline_id,
-       struct pipeline_routing_arp_key *key,
-       struct ether_addr *macaddr);
-
-int
-app_pipeline_routing_delete_arp_entry(struct app_params *app,
-       uint32_t pipeline_id,
-       struct pipeline_routing_arp_key *key);
-
-int
-app_pipeline_routing_add_default_arp_entry(struct app_params *app,
-       uint32_t pipeline_id,
-       uint32_t port_id);
-
-int
-app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
-       uint32_t pipeline_id);
-
-/*
- * SETTINGS
- */
-int
-app_pipeline_routing_set_macaddr(struct app_params *app,
-       uint32_t pipeline_id);
-
-/*
- * Pipeline type
- */
-extern struct pipeline_type pipeline_routing;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.c b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
deleted file mode 100644 (file)
index 6258a1a..0000000
+++ /dev/null
@@ -1,1966 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-#include <rte_table_lpm.h>
-#include <rte_table_hash.h>
-#include <rte_pipeline.h>
-
-#include "pipeline_routing_be.h"
-#include "pipeline_actions_common.h"
-#include "parser.h"
-#include "hash_func.h"
-
-#define MPLS_LABEL(label, exp, s, ttl)                                 \
-       (((((uint64_t) (label)) & 0xFFFFFLLU) << 12) |          \
-       ((((uint64_t) (exp)) & 0x7LLU) << 9) |                          \
-       ((((uint64_t) (s)) & 0x1LLU) << 8) |                            \
-       (((uint64_t) (ttl)) & 0xFFLU))
-
-#define RTE_SCHED_PORT_HIERARCHY(subport, pipe,                \
-       traffic_class, queue, color)                            \
-       ((((uint64_t) (queue)) & 0x3) |                \
-       ((((uint64_t) (traffic_class)) & 0x3) << 2) |  \
-       ((((uint64_t) (color)) & 0x3) << 4) |          \
-       ((((uint64_t) (subport)) & 0xFFFF) << 16) |    \
-       ((((uint64_t) (pipe)) & 0xFFFFFFFF) << 32))
-
-
-/* Network Byte Order (NBO) */
-#define SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr, ethertype)      \
-       (((uint64_t) macaddr) | (((uint64_t) rte_cpu_to_be_16(ethertype)) << 48))
-
-#ifndef PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s
-#define PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s 256
-#endif
-
-struct pipeline_routing {
-       struct pipeline p;
-       struct pipeline_routing_params params;
-       pipeline_msg_req_handler custom_handlers[PIPELINE_ROUTING_MSG_REQS];
-       uint64_t macaddr[PIPELINE_MAX_PORT_OUT];
-} __rte_cache_aligned;
-
-/*
- * Message handlers
- */
-static void *
-pipeline_routing_msg_req_custom_handler(struct pipeline *p, void *msg);
-
-static pipeline_msg_req_handler handlers[] = {
-       [PIPELINE_MSG_REQ_PING] =
-               pipeline_msg_req_ping_handler,
-       [PIPELINE_MSG_REQ_STATS_PORT_IN] =
-               pipeline_msg_req_stats_port_in_handler,
-       [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
-               pipeline_msg_req_stats_port_out_handler,
-       [PIPELINE_MSG_REQ_STATS_TABLE] =
-               pipeline_msg_req_stats_table_handler,
-       [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
-               pipeline_msg_req_port_in_enable_handler,
-       [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
-               pipeline_msg_req_port_in_disable_handler,
-       [PIPELINE_MSG_REQ_CUSTOM] =
-               pipeline_routing_msg_req_custom_handler,
-};
-
-static void *
-pipeline_routing_msg_req_route_add_handler(struct pipeline *p,
-       void *msg);
-
-static void *
-pipeline_routing_msg_req_route_del_handler(struct pipeline *p,
-       void *msg);
-
-static void *
-pipeline_routing_msg_req_route_add_default_handler(struct pipeline *p,
-       void *msg);
-
-static void *
-pipeline_routing_msg_req_route_del_default_handler(struct pipeline *p,
-       void *msg);
-
-static void *
-pipeline_routing_msg_req_arp_add_handler(struct pipeline *p,
-       void *msg);
-
-static void *
-pipeline_routing_msg_req_arp_del_handler(struct pipeline *p,
-       void *msg);
-
-static void *
-pipeline_routing_msg_req_arp_add_default_handler(struct pipeline *p,
-       void *msg);
-
-static void *
-pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p,
-       void *msg);
-
-static void *
-pipeline_routing_msg_req_set_macaddr_handler(struct pipeline *p,
-       void *msg);
-
-static pipeline_msg_req_handler custom_handlers[] = {
-       [PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD] =
-               pipeline_routing_msg_req_route_add_handler,
-       [PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL] =
-               pipeline_routing_msg_req_route_del_handler,
-       [PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD_DEFAULT] =
-               pipeline_routing_msg_req_route_add_default_handler,
-       [PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL_DEFAULT] =
-               pipeline_routing_msg_req_route_del_default_handler,
-       [PIPELINE_ROUTING_MSG_REQ_ARP_ADD] =
-               pipeline_routing_msg_req_arp_add_handler,
-       [PIPELINE_ROUTING_MSG_REQ_ARP_DEL] =
-               pipeline_routing_msg_req_arp_del_handler,
-       [PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT] =
-               pipeline_routing_msg_req_arp_add_default_handler,
-       [PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT] =
-               pipeline_routing_msg_req_arp_del_default_handler,
-       [PIPELINE_ROUTING_MSG_REQ_SET_MACADDR] =
-               pipeline_routing_msg_req_set_macaddr_handler,
-};
-
-/*
- * Routing table
- */
-struct routing_table_entry {
-       struct rte_pipeline_table_entry head;
-       uint32_t flags;
-       uint32_t port_id; /* Output port ID */
-       uint32_t ip; /* Next hop IP address (only valid for remote routes) */
-
-       /* ether_l2 */
-       uint16_t data_offset;
-       uint16_t ether_l2_length;
-       uint64_t slab[4];
-       uint16_t slab_offset[4];
-};
-
-struct layout {
-       uint16_t a;
-       uint32_t b;
-       uint16_t c;
-} __attribute__((__packed__));
-
-#define MACADDR_DST_WRITE(slab_ptr, slab)                      \
-{                                                              \
-       struct layout *dst = (struct layout *) (slab_ptr);      \
-       struct layout *src = (struct layout *) &(slab);         \
-                                                               \
-       dst->b = src->b;                                        \
-       dst->c = src->c;                                        \
-}
-
-static __rte_always_inline void
-pkt_work_routing(
-       struct rte_mbuf *pkt,
-       struct rte_pipeline_table_entry *table_entry,
-       void *arg,
-       int arp,
-       int qinq,
-       int qinq_sched,
-       int mpls,
-       int mpls_color_mark)
-{
-       struct pipeline_routing *p_rt = arg;
-
-       struct routing_table_entry *entry =
-               (struct routing_table_entry *) table_entry;
-
-       struct ipv4_hdr *ip = (struct ipv4_hdr *)
-               RTE_MBUF_METADATA_UINT8_PTR(pkt, p_rt->params.ip_hdr_offset);
-
-       enum rte_meter_color pkt_color = (enum rte_meter_color)
-               RTE_MBUF_METADATA_UINT32(pkt, p_rt->params.color_offset);
-
-       struct pipeline_routing_arp_key_ipv4 *arp_key =
-               (struct pipeline_routing_arp_key_ipv4 *)
-               RTE_MBUF_METADATA_UINT8_PTR(pkt, p_rt->params.arp_key_offset);
-
-       uint64_t *slab0_ptr, *slab1_ptr, *slab2_ptr, *slab3_ptr, sched;
-       uint32_t ip_da, nh_ip, port_id;
-       uint16_t total_length, data_offset, ether_l2_length;
-
-       /* Read */
-       total_length = rte_bswap16(ip->total_length);
-       ip_da = ip->dst_addr;
-       data_offset = entry->data_offset;
-       ether_l2_length = entry->ether_l2_length;
-       slab0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[0]);
-       slab1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[1]);
-       slab2_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[2]);
-       slab3_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[3]);
-
-       if (arp) {
-               port_id = entry->port_id;
-               nh_ip = entry->ip;
-               if (entry->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
-                       nh_ip = ip_da;
-       }
-
-       /* Compute */
-       total_length += ether_l2_length;
-
-       if (qinq && qinq_sched) {
-               uint32_t dscp = ip->type_of_service >> 2;
-               uint32_t svlan, cvlan, tc, tc_q;
-
-               if (qinq_sched == 1) {
-                       uint64_t slab_qinq = rte_bswap64(entry->slab[0]);
-
-                       svlan = (slab_qinq >> 48) & 0xFFF;
-                       cvlan = (slab_qinq >> 16) & 0xFFF;
-                       tc = (dscp >> 2) & 0x3;
-                       tc_q = dscp & 0x3;
-               } else {
-                       uint32_t ip_src = rte_bswap32(ip->src_addr);
-
-                       svlan = 0;
-                       cvlan = (ip_src >> 16) & 0xFFF;
-                       tc = (ip_src >> 2) & 0x3;
-                       tc_q = ip_src & 0x3;
-               }
-               sched = RTE_SCHED_PORT_HIERARCHY(svlan,
-                       cvlan,
-                       tc,
-                       tc_q,
-                       e_RTE_METER_GREEN);
-       }
-
-       /* Write */
-       pkt->data_off = data_offset;
-       pkt->data_len = total_length;
-       pkt->pkt_len = total_length;
-
-       if ((qinq == 0) && (mpls == 0)) {
-               *slab0_ptr = entry->slab[0];
-
-               if (arp == 0)
-                       MACADDR_DST_WRITE(slab1_ptr, entry->slab[1]);
-       }
-
-       if (qinq) {
-               *slab0_ptr = entry->slab[0];
-               *slab1_ptr = entry->slab[1];
-
-               if (arp == 0)
-                       MACADDR_DST_WRITE(slab2_ptr, entry->slab[2]);
-
-               if (qinq_sched) {
-                       pkt->hash.sched.lo = sched & 0xFFFFFFFF;
-                       pkt->hash.sched.hi = sched >> 32;
-               }
-       }
-
-       if (mpls) {
-               if (mpls_color_mark) {
-                       uint64_t mpls_exp = rte_bswap64(
-                               (MPLS_LABEL(0, pkt_color, 0, 0) << 32) |
-                               MPLS_LABEL(0, pkt_color, 0, 0));
-
-                       *slab0_ptr = entry->slab[0] | mpls_exp;
-                       *slab1_ptr = entry->slab[1] | mpls_exp;
-                       *slab2_ptr = entry->slab[2];
-               } else {
-                       *slab0_ptr = entry->slab[0];
-                       *slab1_ptr = entry->slab[1];
-                       *slab2_ptr = entry->slab[2];
-               }
-
-               if (arp == 0)
-                       MACADDR_DST_WRITE(slab3_ptr, entry->slab[3]);
-       }
-
-       if (arp) {
-               arp_key->port_id = port_id;
-               arp_key->ip = nh_ip;
-       }
-}
-
-static __rte_always_inline void
-pkt4_work_routing(
-       struct rte_mbuf **pkts,
-       struct rte_pipeline_table_entry **table_entries,
-       void *arg,
-       int arp,
-       int qinq,
-       int qinq_sched,
-       int mpls,
-       int mpls_color_mark)
-{
-       struct pipeline_routing *p_rt = arg;
-
-       struct routing_table_entry *entry0 =
-               (struct routing_table_entry *) table_entries[0];
-       struct routing_table_entry *entry1 =
-               (struct routing_table_entry *) table_entries[1];
-       struct routing_table_entry *entry2 =
-               (struct routing_table_entry *) table_entries[2];
-       struct routing_table_entry *entry3 =
-               (struct routing_table_entry *) table_entries[3];
-
-       struct ipv4_hdr *ip0 = (struct ipv4_hdr *)
-               RTE_MBUF_METADATA_UINT8_PTR(pkts[0],
-                       p_rt->params.ip_hdr_offset);
-       struct ipv4_hdr *ip1 = (struct ipv4_hdr *)
-               RTE_MBUF_METADATA_UINT8_PTR(pkts[1],
-                       p_rt->params.ip_hdr_offset);
-       struct ipv4_hdr *ip2 = (struct ipv4_hdr *)
-               RTE_MBUF_METADATA_UINT8_PTR(pkts[2],
-                       p_rt->params.ip_hdr_offset);
-       struct ipv4_hdr *ip3 = (struct ipv4_hdr *)
-               RTE_MBUF_METADATA_UINT8_PTR(pkts[3],
-                       p_rt->params.ip_hdr_offset);
-
-       enum rte_meter_color pkt0_color = (enum rte_meter_color)
-               RTE_MBUF_METADATA_UINT32(pkts[0], p_rt->params.color_offset);
-       enum rte_meter_color pkt1_color = (enum rte_meter_color)
-               RTE_MBUF_METADATA_UINT32(pkts[1], p_rt->params.color_offset);
-       enum rte_meter_color pkt2_color = (enum rte_meter_color)
-               RTE_MBUF_METADATA_UINT32(pkts[2], p_rt->params.color_offset);
-       enum rte_meter_color pkt3_color = (enum rte_meter_color)
-               RTE_MBUF_METADATA_UINT32(pkts[3], p_rt->params.color_offset);
-
-       struct pipeline_routing_arp_key_ipv4 *arp_key0 =
-               (struct pipeline_routing_arp_key_ipv4 *)
-               RTE_MBUF_METADATA_UINT8_PTR(pkts[0],
-                       p_rt->params.arp_key_offset);
-       struct pipeline_routing_arp_key_ipv4 *arp_key1 =
-               (struct pipeline_routing_arp_key_ipv4 *)
-               RTE_MBUF_METADATA_UINT8_PTR(pkts[1],
-                       p_rt->params.arp_key_offset);
-       struct pipeline_routing_arp_key_ipv4 *arp_key2 =
-               (struct pipeline_routing_arp_key_ipv4 *)
-               RTE_MBUF_METADATA_UINT8_PTR(pkts[2],
-                       p_rt->params.arp_key_offset);
-       struct pipeline_routing_arp_key_ipv4 *arp_key3 =
-               (struct pipeline_routing_arp_key_ipv4 *)
-               RTE_MBUF_METADATA_UINT8_PTR(pkts[3],
-                       p_rt->params.arp_key_offset);
-
-       uint64_t *slab0_ptr0, *slab1_ptr0, *slab2_ptr0, *slab3_ptr0;
-       uint64_t *slab0_ptr1, *slab1_ptr1, *slab2_ptr1, *slab3_ptr1;
-       uint64_t *slab0_ptr2, *slab1_ptr2, *slab2_ptr2, *slab3_ptr2;
-       uint64_t *slab0_ptr3, *slab1_ptr3, *slab2_ptr3, *slab3_ptr3;
-       uint64_t sched0, sched1, sched2, sched3;
-
-       uint32_t ip_da0, nh_ip0, port_id0;
-       uint32_t ip_da1, nh_ip1, port_id1;
-       uint32_t ip_da2, nh_ip2, port_id2;
-       uint32_t ip_da3, nh_ip3, port_id3;
-
-       uint16_t total_length0, data_offset0, ether_l2_length0;
-       uint16_t total_length1, data_offset1, ether_l2_length1;
-       uint16_t total_length2, data_offset2, ether_l2_length2;
-       uint16_t total_length3, data_offset3, ether_l2_length3;
-
-       /* Read */
-       total_length0 = rte_bswap16(ip0->total_length);
-       total_length1 = rte_bswap16(ip1->total_length);
-       total_length2 = rte_bswap16(ip2->total_length);
-       total_length3 = rte_bswap16(ip3->total_length);
-
-       ip_da0 = ip0->dst_addr;
-       ip_da1 = ip1->dst_addr;
-       ip_da2 = ip2->dst_addr;
-       ip_da3 = ip3->dst_addr;
-
-       data_offset0 = entry0->data_offset;
-       data_offset1 = entry1->data_offset;
-       data_offset2 = entry2->data_offset;
-       data_offset3 = entry3->data_offset;
-
-       ether_l2_length0 = entry0->ether_l2_length;
-       ether_l2_length1 = entry1->ether_l2_length;
-       ether_l2_length2 = entry2->ether_l2_length;
-       ether_l2_length3 = entry3->ether_l2_length;
-
-       slab0_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
-               entry0->slab_offset[0]);
-       slab1_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
-               entry0->slab_offset[1]);
-       slab2_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
-               entry0->slab_offset[2]);
-       slab3_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
-               entry0->slab_offset[3]);
-
-       slab0_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
-               entry1->slab_offset[0]);
-       slab1_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
-               entry1->slab_offset[1]);
-       slab2_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
-               entry1->slab_offset[2]);
-       slab3_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
-               entry1->slab_offset[3]);
-
-       slab0_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
-               entry2->slab_offset[0]);
-       slab1_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
-               entry2->slab_offset[1]);
-       slab2_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
-               entry2->slab_offset[2]);
-       slab3_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
-               entry2->slab_offset[3]);
-
-       slab0_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
-               entry3->slab_offset[0]);
-       slab1_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
-               entry3->slab_offset[1]);
-       slab2_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
-               entry3->slab_offset[2]);
-       slab3_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
-               entry3->slab_offset[3]);
-
-       if (arp) {
-               port_id0 = entry0->port_id;
-               nh_ip0 = entry0->ip;
-               if (entry0->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
-                       nh_ip0 = ip_da0;
-
-               port_id1 = entry1->port_id;
-               nh_ip1 = entry1->ip;
-               if (entry1->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
-                       nh_ip1 = ip_da1;
-
-               port_id2 = entry2->port_id;
-               nh_ip2 = entry2->ip;
-               if (entry2->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
-                       nh_ip2 = ip_da2;
-
-               port_id3 = entry3->port_id;
-               nh_ip3 = entry3->ip;
-               if (entry3->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
-                       nh_ip3 = ip_da3;
-       }
-
-       /* Compute */
-       total_length0 += ether_l2_length0;
-       total_length1 += ether_l2_length1;
-       total_length2 += ether_l2_length2;
-       total_length3 += ether_l2_length3;
-
-       if (qinq && qinq_sched) {
-               uint32_t dscp0 = ip0->type_of_service >> 2;
-               uint32_t dscp1 = ip1->type_of_service >> 2;
-               uint32_t dscp2 = ip2->type_of_service >> 2;
-               uint32_t dscp3 = ip3->type_of_service >> 2;
-               uint32_t svlan0, cvlan0, tc0, tc_q0;
-               uint32_t svlan1, cvlan1, tc1, tc_q1;
-               uint32_t svlan2, cvlan2, tc2, tc_q2;
-               uint32_t svlan3, cvlan3, tc3, tc_q3;
-
-               if (qinq_sched == 1) {
-                       uint64_t slab_qinq0 = rte_bswap64(entry0->slab[0]);
-                       uint64_t slab_qinq1 = rte_bswap64(entry1->slab[0]);
-                       uint64_t slab_qinq2 = rte_bswap64(entry2->slab[0]);
-                       uint64_t slab_qinq3 = rte_bswap64(entry3->slab[0]);
-
-                       svlan0 = (slab_qinq0 >> 48) & 0xFFF;
-                       svlan1 = (slab_qinq1 >> 48) & 0xFFF;
-                       svlan2 = (slab_qinq2 >> 48) & 0xFFF;
-                       svlan3 = (slab_qinq3 >> 48) & 0xFFF;
-
-                       cvlan0 = (slab_qinq0 >> 16) & 0xFFF;
-                       cvlan1 = (slab_qinq1 >> 16) & 0xFFF;
-                       cvlan2 = (slab_qinq2 >> 16) & 0xFFF;
-                       cvlan3 = (slab_qinq3 >> 16) & 0xFFF;
-
-                       tc0 = (dscp0 >> 2) & 0x3;
-                       tc1 = (dscp1 >> 2) & 0x3;
-                       tc2 = (dscp2 >> 2) & 0x3;
-                       tc3 = (dscp3 >> 2) & 0x3;
-
-                       tc_q0 = dscp0 & 0x3;
-                       tc_q1 = dscp1 & 0x3;
-                       tc_q2 = dscp2 & 0x3;
-                       tc_q3 = dscp3 & 0x3;
-               } else {
-                       uint32_t ip_src0 = rte_bswap32(ip0->src_addr);
-                       uint32_t ip_src1 = rte_bswap32(ip1->src_addr);
-                       uint32_t ip_src2 = rte_bswap32(ip2->src_addr);
-                       uint32_t ip_src3 = rte_bswap32(ip3->src_addr);
-
-                       svlan0 = 0;
-                       svlan1 = 0;
-                       svlan2 = 0;
-                       svlan3 = 0;
-
-                       cvlan0 = (ip_src0 >> 16) & 0xFFF;
-                       cvlan1 = (ip_src1 >> 16) & 0xFFF;
-                       cvlan2 = (ip_src2 >> 16) & 0xFFF;
-                       cvlan3 = (ip_src3 >> 16) & 0xFFF;
-
-                       tc0 = (ip_src0 >> 2) & 0x3;
-                       tc1 = (ip_src1 >> 2) & 0x3;
-                       tc2 = (ip_src2 >> 2) & 0x3;
-                       tc3 = (ip_src3 >> 2) & 0x3;
-
-                       tc_q0 = ip_src0 & 0x3;
-                       tc_q1 = ip_src1 & 0x3;
-                       tc_q2 = ip_src2 & 0x3;
-                       tc_q3 = ip_src3 & 0x3;
-               }
-
-               sched0 = RTE_SCHED_PORT_HIERARCHY(svlan0,
-                       cvlan0,
-                       tc0,
-                       tc_q0,
-                       e_RTE_METER_GREEN);
-               sched1 = RTE_SCHED_PORT_HIERARCHY(svlan1,
-                       cvlan1,
-                       tc1,
-                       tc_q1,
-                       e_RTE_METER_GREEN);
-               sched2 = RTE_SCHED_PORT_HIERARCHY(svlan2,
-                       cvlan2,
-                       tc2,
-                       tc_q2,
-                       e_RTE_METER_GREEN);
-               sched3 = RTE_SCHED_PORT_HIERARCHY(svlan3,
-                       cvlan3,
-                       tc3,
-                       tc_q3,
-                       e_RTE_METER_GREEN);
-
-       }
-
-       /* Write */
-       pkts[0]->data_off = data_offset0;
-       pkts[1]->data_off = data_offset1;
-       pkts[2]->data_off = data_offset2;
-       pkts[3]->data_off = data_offset3;
-
-       pkts[0]->data_len = total_length0;
-       pkts[1]->data_len = total_length1;
-       pkts[2]->data_len = total_length2;
-       pkts[3]->data_len = total_length3;
-
-       pkts[0]->pkt_len = total_length0;
-       pkts[1]->pkt_len = total_length1;
-       pkts[2]->pkt_len = total_length2;
-       pkts[3]->pkt_len = total_length3;
-
-       if ((qinq == 0) && (mpls == 0)) {
-               *slab0_ptr0 = entry0->slab[0];
-               *slab0_ptr1 = entry1->slab[0];
-               *slab0_ptr2 = entry2->slab[0];
-               *slab0_ptr3 = entry3->slab[0];
-
-               if (arp == 0) {
-                       MACADDR_DST_WRITE(slab1_ptr0, entry0->slab[1]);
-                       MACADDR_DST_WRITE(slab1_ptr1, entry1->slab[1]);
-                       MACADDR_DST_WRITE(slab1_ptr2, entry2->slab[1]);
-                       MACADDR_DST_WRITE(slab1_ptr3, entry3->slab[1]);
-               }
-       }
-
-       if (qinq) {
-               *slab0_ptr0 = entry0->slab[0];
-               *slab0_ptr1 = entry1->slab[0];
-               *slab0_ptr2 = entry2->slab[0];
-               *slab0_ptr3 = entry3->slab[0];
-
-               *slab1_ptr0 = entry0->slab[1];
-               *slab1_ptr1 = entry1->slab[1];
-               *slab1_ptr2 = entry2->slab[1];
-               *slab1_ptr3 = entry3->slab[1];
-
-               if (arp == 0) {
-                       MACADDR_DST_WRITE(slab2_ptr0, entry0->slab[2]);
-                       MACADDR_DST_WRITE(slab2_ptr1, entry1->slab[2]);
-                       MACADDR_DST_WRITE(slab2_ptr2, entry2->slab[2]);
-                       MACADDR_DST_WRITE(slab2_ptr3, entry3->slab[2]);
-               }
-
-               if (qinq_sched) {
-                       pkts[0]->hash.sched.lo = sched0 & 0xFFFFFFFF;
-                       pkts[0]->hash.sched.hi = sched0 >> 32;
-                       pkts[1]->hash.sched.lo = sched1 & 0xFFFFFFFF;
-                       pkts[1]->hash.sched.hi = sched1 >> 32;
-                       pkts[2]->hash.sched.lo = sched2 & 0xFFFFFFFF;
-                       pkts[2]->hash.sched.hi = sched2 >> 32;
-                       pkts[3]->hash.sched.lo = sched3 & 0xFFFFFFFF;
-                       pkts[3]->hash.sched.hi = sched3 >> 32;
-               }
-       }
-
-       if (mpls) {
-               if (mpls_color_mark) {
-                       uint64_t mpls_exp0 = rte_bswap64(
-                               (MPLS_LABEL(0, pkt0_color, 0, 0) << 32) |
-                               MPLS_LABEL(0, pkt0_color, 0, 0));
-                       uint64_t mpls_exp1 = rte_bswap64(
-                               (MPLS_LABEL(0, pkt1_color, 0, 0) << 32) |
-                               MPLS_LABEL(0, pkt1_color, 0, 0));
-                       uint64_t mpls_exp2 = rte_bswap64(
-                               (MPLS_LABEL(0, pkt2_color, 0, 0) << 32) |
-                               MPLS_LABEL(0, pkt2_color, 0, 0));
-                       uint64_t mpls_exp3 = rte_bswap64(
-                               (MPLS_LABEL(0, pkt3_color, 0, 0) << 32) |
-                               MPLS_LABEL(0, pkt3_color, 0, 0));
-
-                       *slab0_ptr0 = entry0->slab[0] | mpls_exp0;
-                       *slab0_ptr1 = entry1->slab[0] | mpls_exp1;
-                       *slab0_ptr2 = entry2->slab[0] | mpls_exp2;
-                       *slab0_ptr3 = entry3->slab[0] | mpls_exp3;
-
-                       *slab1_ptr0 = entry0->slab[1] | mpls_exp0;
-                       *slab1_ptr1 = entry1->slab[1] | mpls_exp1;
-                       *slab1_ptr2 = entry2->slab[1] | mpls_exp2;
-                       *slab1_ptr3 = entry3->slab[1] | mpls_exp3;
-
-                       *slab2_ptr0 = entry0->slab[2];
-                       *slab2_ptr1 = entry1->slab[2];
-                       *slab2_ptr2 = entry2->slab[2];
-                       *slab2_ptr3 = entry3->slab[2];
-               } else {
-                       *slab0_ptr0 = entry0->slab[0];
-                       *slab0_ptr1 = entry1->slab[0];
-                       *slab0_ptr2 = entry2->slab[0];
-                       *slab0_ptr3 = entry3->slab[0];
-
-                       *slab1_ptr0 = entry0->slab[1];
-                       *slab1_ptr1 = entry1->slab[1];
-                       *slab1_ptr2 = entry2->slab[1];
-                       *slab1_ptr3 = entry3->slab[1];
-
-                       *slab2_ptr0 = entry0->slab[2];
-                       *slab2_ptr1 = entry1->slab[2];
-                       *slab2_ptr2 = entry2->slab[2];
-                       *slab2_ptr3 = entry3->slab[2];
-               }
-
-               if (arp == 0) {
-                       MACADDR_DST_WRITE(slab3_ptr0, entry0->slab[3]);
-                       MACADDR_DST_WRITE(slab3_ptr1, entry1->slab[3]);
-                       MACADDR_DST_WRITE(slab3_ptr2, entry2->slab[3]);
-                       MACADDR_DST_WRITE(slab3_ptr3, entry3->slab[3]);
-               }
-       }
-
-       if (arp) {
-               arp_key0->port_id = port_id0;
-               arp_key1->port_id = port_id1;
-               arp_key2->port_id = port_id2;
-               arp_key3->port_id = port_id3;
-
-               arp_key0->ip = nh_ip0;
-               arp_key1->ip = nh_ip1;
-               arp_key2->ip = nh_ip2;
-               arp_key3->ip = nh_ip3;
-       }
-}
-
-#define PKT_WORK_ROUTING_ETHERNET(arp)                         \
-static inline void                                             \
-pkt_work_routing_ether_arp##arp(                               \
-       struct rte_mbuf *pkt,                                   \
-       struct rte_pipeline_table_entry *table_entry,           \
-       void *arg)                                              \
-{                                                              \
-       pkt_work_routing(pkt, table_entry, arg, arp, 0, 0, 0, 0);\
-}
-
-#define PKT4_WORK_ROUTING_ETHERNET(arp)                                \
-static inline void                                             \
-pkt4_work_routing_ether_arp##arp(                              \
-       struct rte_mbuf **pkts,                                 \
-       struct rte_pipeline_table_entry **table_entries,        \
-       void *arg)                                              \
-{                                                              \
-       pkt4_work_routing(pkts, table_entries, arg, arp, 0, 0, 0, 0);\
-}
-
-#define routing_table_ah_hit_ether(arp)                                \
-PKT_WORK_ROUTING_ETHERNET(arp)                                 \
-PKT4_WORK_ROUTING_ETHERNET(arp)                                        \
-PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_arp##arp,     \
-       pkt_work_routing_ether_arp##arp,                        \
-       pkt4_work_routing_ether_arp##arp)
-
-routing_table_ah_hit_ether(0)
-routing_table_ah_hit_ether(1)
-
-#define PKT_WORK_ROUTING_ETHERNET_QINQ(sched, arp)             \
-static inline void                                             \
-pkt_work_routing_ether_qinq_sched##sched##_arp##arp(           \
-       struct rte_mbuf *pkt,                                   \
-       struct rte_pipeline_table_entry *table_entry,           \
-       void *arg)                                              \
-{                                                              \
-       pkt_work_routing(pkt, table_entry, arg, arp, 1, sched, 0, 0);\
-}
-
-#define PKT4_WORK_ROUTING_ETHERNET_QINQ(sched, arp)            \
-static inline void                                             \
-pkt4_work_routing_ether_qinq_sched##sched##_arp##arp(          \
-       struct rte_mbuf **pkts,                                 \
-       struct rte_pipeline_table_entry **table_entries,        \
-       void *arg)                                              \
-{                                                              \
-       pkt4_work_routing(pkts, table_entries, arg, arp, 1, sched, 0, 0);\
-}
-
-#define routing_table_ah_hit_ether_qinq(sched, arp)            \
-PKT_WORK_ROUTING_ETHERNET_QINQ(sched, arp)                     \
-PKT4_WORK_ROUTING_ETHERNET_QINQ(sched, arp)                    \
-PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_qinq_sched##sched##_arp##arp,\
-       pkt_work_routing_ether_qinq_sched##sched##_arp##arp,    \
-       pkt4_work_routing_ether_qinq_sched##sched##_arp##arp)
-
-routing_table_ah_hit_ether_qinq(0, 0)
-routing_table_ah_hit_ether_qinq(1, 0)
-routing_table_ah_hit_ether_qinq(2, 0)
-routing_table_ah_hit_ether_qinq(0, 1)
-routing_table_ah_hit_ether_qinq(1, 1)
-routing_table_ah_hit_ether_qinq(2, 1)
-
-#define PKT_WORK_ROUTING_ETHERNET_MPLS(color, arp)             \
-static inline void                                             \
-pkt_work_routing_ether_mpls_color##color##_arp##arp(           \
-       struct rte_mbuf *pkt,                                   \
-       struct rte_pipeline_table_entry *table_entry,           \
-       void *arg)                                              \
-{                                                              \
-       pkt_work_routing(pkt, table_entry, arg, arp, 0, 0, 1, color);\
-}
-
-#define PKT4_WORK_ROUTING_ETHERNET_MPLS(color, arp)            \
-static inline void                                             \
-pkt4_work_routing_ether_mpls_color##color##_arp##arp(          \
-       struct rte_mbuf **pkts,                                 \
-       struct rte_pipeline_table_entry **table_entries,        \
-       void *arg)                                              \
-{                                                              \
-       pkt4_work_routing(pkts, table_entries, arg, arp, 0, 0, 1, color);\
-}
-
-#define routing_table_ah_hit_ether_mpls(color, arp)            \
-PKT_WORK_ROUTING_ETHERNET_MPLS(color, arp)                     \
-PKT4_WORK_ROUTING_ETHERNET_MPLS(color, arp)                    \
-PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_mpls_color##color##_arp##arp,\
-       pkt_work_routing_ether_mpls_color##color##_arp##arp,    \
-       pkt4_work_routing_ether_mpls_color##color##_arp##arp)
-
-routing_table_ah_hit_ether_mpls(0, 0)
-routing_table_ah_hit_ether_mpls(1, 0)
-routing_table_ah_hit_ether_mpls(0, 1)
-routing_table_ah_hit_ether_mpls(1, 1)
-
-static rte_pipeline_table_action_handler_hit
-get_routing_table_ah_hit(struct pipeline_routing *p)
-{
-       if (p->params.dbg_ah_disable)
-               return NULL;
-
-       switch (p->params.encap) {
-       case PIPELINE_ROUTING_ENCAP_ETHERNET:
-               return (p->params.n_arp_entries) ?
-                       routing_table_ah_hit_ether_arp1 :
-                       routing_table_ah_hit_ether_arp0;
-
-       case PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ:
-               if (p->params.n_arp_entries)
-                       switch (p->params.qinq_sched) {
-                       case 0:
-                               return routing_table_ah_hit_ether_qinq_sched0_arp1;
-                       case 1:
-                               return routing_table_ah_hit_ether_qinq_sched1_arp1;
-                       case 2:
-                               return routing_table_ah_hit_ether_qinq_sched2_arp1;
-                       default:
-                               return NULL;
-                       }
-                else
-                       switch (p->params.qinq_sched) {
-                       case 0:
-                               return routing_table_ah_hit_ether_qinq_sched0_arp0;
-                       case 1:
-                               return routing_table_ah_hit_ether_qinq_sched1_arp0;
-                       case 2:
-                               return routing_table_ah_hit_ether_qinq_sched2_arp0;
-                       default:
-                               return NULL;
-                       }
-
-       case PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS:
-               if (p->params.n_arp_entries)
-                       if (p->params.mpls_color_mark)
-                               return routing_table_ah_hit_ether_mpls_color1_arp1;
-                       else
-                               return routing_table_ah_hit_ether_mpls_color0_arp1;
-               else
-                       if (p->params.mpls_color_mark)
-                               return routing_table_ah_hit_ether_mpls_color1_arp0;
-                       else
-                               return routing_table_ah_hit_ether_mpls_color0_arp0;
-
-       default:
-               return NULL;
-       }
-}
-
-/*
- * ARP table
- */
-struct arp_table_entry {
-       struct rte_pipeline_table_entry head;
-       uint64_t macaddr;
-};
-
-/**
- * ARP table AH
- */
-static inline void
-pkt_work_arp(
-       struct rte_mbuf *pkt,
-       struct rte_pipeline_table_entry *table_entry,
-       __rte_unused void *arg)
-{
-       struct arp_table_entry *entry = (struct arp_table_entry *) table_entry;
-
-       /* Read */
-       uint64_t macaddr_dst = entry->macaddr;
-       uint64_t *slab_ptr = (uint64_t *) ((char *) pkt->buf_addr +
-               (pkt->data_off - 2));
-
-       /* Compute */
-
-       /* Write */
-       MACADDR_DST_WRITE(slab_ptr, macaddr_dst);
-}
-
-static inline void
-pkt4_work_arp(
-       struct rte_mbuf **pkts,
-       struct rte_pipeline_table_entry **table_entries,
-       __rte_unused void *arg)
-{
-       struct arp_table_entry *entry0 =
-               (struct arp_table_entry *) table_entries[0];
-       struct arp_table_entry *entry1 =
-               (struct arp_table_entry *) table_entries[1];
-       struct arp_table_entry *entry2 =
-               (struct arp_table_entry *) table_entries[2];
-       struct arp_table_entry *entry3 =
-               (struct arp_table_entry *) table_entries[3];
-
-       /* Read */
-       uint64_t macaddr_dst0 = entry0->macaddr;
-       uint64_t macaddr_dst1 = entry1->macaddr;
-       uint64_t macaddr_dst2 = entry2->macaddr;
-       uint64_t macaddr_dst3 = entry3->macaddr;
-
-       uint64_t *slab_ptr0 = (uint64_t *) ((char *) pkts[0]->buf_addr +
-               (pkts[0]->data_off - 2));
-       uint64_t *slab_ptr1 = (uint64_t *) ((char *) pkts[1]->buf_addr +
-               (pkts[1]->data_off - 2));
-       uint64_t *slab_ptr2 = (uint64_t *) ((char *) pkts[2]->buf_addr +
-               (pkts[2]->data_off - 2));
-       uint64_t *slab_ptr3 = (uint64_t *) ((char *) pkts[3]->buf_addr +
-               (pkts[3]->data_off - 2));
-
-       /* Compute */
-
-       /* Write */
-       MACADDR_DST_WRITE(slab_ptr0, macaddr_dst0);
-       MACADDR_DST_WRITE(slab_ptr1, macaddr_dst1);
-       MACADDR_DST_WRITE(slab_ptr2, macaddr_dst2);
-       MACADDR_DST_WRITE(slab_ptr3, macaddr_dst3);
-}
-
-PIPELINE_TABLE_AH_HIT(arp_table_ah_hit,
-       pkt_work_arp,
-       pkt4_work_arp);
-
-static rte_pipeline_table_action_handler_hit
-get_arp_table_ah_hit(struct pipeline_routing *p)
-{
-       if (p->params.dbg_ah_disable)
-               return NULL;
-
-       return arp_table_ah_hit;
-}
-
-/*
- * Argument parsing
- */
-int
-pipeline_routing_parse_args(struct pipeline_routing_params *p,
-       struct pipeline_params *params)
-{
-       uint32_t n_routes_present = 0;
-       uint32_t port_local_dest_present = 0;
-       uint32_t encap_present = 0;
-       uint32_t qinq_sched_present = 0;
-       uint32_t mpls_color_mark_present = 0;
-       uint32_t n_arp_entries_present = 0;
-       uint32_t ip_hdr_offset_present = 0;
-       uint32_t arp_key_offset_present = 0;
-       uint32_t color_offset_present = 0;
-       uint32_t dbg_ah_disable_present = 0;
-       uint32_t i;
-
-       /* default values */
-       p->n_routes = PIPELINE_ROUTING_N_ROUTES_DEFAULT;
-       p->port_local_dest = params->n_ports_out - 1;
-       p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET;
-       p->qinq_sched = 0;
-       p->mpls_color_mark = 0;
-       p->n_arp_entries = 0;
-       p->dbg_ah_disable = 0;
-
-       for (i = 0; i < params->n_args; i++) {
-               char *arg_name = params->args_name[i];
-               char *arg_value = params->args_value[i];
-
-               /* n_routes */
-               if (strcmp(arg_name, "n_routes") == 0) {
-                       int status;
-
-                       PIPELINE_PARSE_ERR_DUPLICATE(
-                               n_routes_present == 0, params->name,
-                               arg_name);
-                       n_routes_present = 1;
-
-                       status = parser_read_uint32(&p->n_routes,
-                               arg_value);
-                       PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
-                               (p->n_routes != 0)), params->name,
-                               arg_name, arg_value);
-                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
-                               params->name, arg_name, arg_value);
-
-                       continue;
-               }
-               /* port_local_dest */
-               if (strcmp(arg_name, "port_local_dest") == 0) {
-                       int status;
-
-                       PIPELINE_PARSE_ERR_DUPLICATE(
-                               port_local_dest_present == 0, params->name,
-                               arg_name);
-                       port_local_dest_present = 1;
-
-                       status = parser_read_uint32(&p->port_local_dest,
-                               arg_value);
-                       PIPELINE_PARSE_ERR_INV_VAL(((status == 0) &&
-                               (p->port_local_dest < params->n_ports_out)),
-                               params->name, arg_name, arg_value);
-
-                       continue;
-               }
-
-               /* encap */
-               if (strcmp(arg_name, "encap") == 0) {
-                       PIPELINE_PARSE_ERR_DUPLICATE(encap_present == 0,
-                               params->name, arg_name);
-                       encap_present = 1;
-
-                       /* ethernet */
-                       if (strcmp(arg_value, "ethernet") == 0) {
-                               p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET;
-                               continue;
-                       }
-
-                       /* ethernet_qinq */
-                       if (strcmp(arg_value, "ethernet_qinq") == 0) {
-                               p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ;
-                               continue;
-                       }
-
-                       /* ethernet_mpls */
-                       if (strcmp(arg_value, "ethernet_mpls") == 0) {
-                               p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS;
-                               continue;
-                       }
-
-                       /* any other */
-                       PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
-                               arg_name, arg_value);
-               }
-
-               /* qinq_sched */
-               if (strcmp(arg_name, "qinq_sched") == 0) {
-                       int status;
-
-                       PIPELINE_PARSE_ERR_DUPLICATE(
-                               qinq_sched_present == 0, params->name,
-                               arg_name);
-                       qinq_sched_present = 1;
-
-                       status = parser_read_arg_bool(arg_value);
-                       if (status == -EINVAL) {
-                               if (strcmp(arg_value, "test") == 0) {
-                                       p->qinq_sched = 2;
-                                       continue;
-                               }
-                       } else {
-                               p->qinq_sched = status;
-                               continue;
-                       }
-
-                       PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
-                               arg_name, arg_value);
-               }
-
-               /* mpls_color_mark */
-               if (strcmp(arg_name, "mpls_color_mark") == 0) {
-                       int status;
-
-                       PIPELINE_PARSE_ERR_DUPLICATE(
-                               mpls_color_mark_present == 0,
-                               params->name, arg_name);
-                       mpls_color_mark_present = 1;
-
-
-                       status = parser_read_arg_bool(arg_value);
-                       if (status >= 0) {
-                               p->mpls_color_mark = status;
-                               continue;
-                       }
-
-                       PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
-                               arg_name, arg_value);
-               }
-
-               /* n_arp_entries */
-               if (strcmp(arg_name, "n_arp_entries") == 0) {
-                       int status;
-
-                       PIPELINE_PARSE_ERR_DUPLICATE(
-                               n_arp_entries_present == 0, params->name,
-                               arg_name);
-                       n_arp_entries_present = 1;
-
-                       status = parser_read_uint32(&p->n_arp_entries,
-                               arg_value);
-                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
-                               params->name, arg_name, arg_value);
-                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
-                               params->name, arg_name, arg_value);
-
-                       continue;
-               }
-
-               /* ip_hdr_offset */
-               if (strcmp(arg_name, "ip_hdr_offset") == 0) {
-                       int status;
-
-                       PIPELINE_PARSE_ERR_DUPLICATE(
-                               ip_hdr_offset_present == 0, params->name,
-                               arg_name);
-                       ip_hdr_offset_present = 1;
-
-                       status = parser_read_uint32(&p->ip_hdr_offset,
-                               arg_value);
-                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
-                               params->name, arg_name, arg_value);
-                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
-                               params->name, arg_name, arg_value);
-
-                       continue;
-               }
-
-               /* arp_key_offset */
-               if (strcmp(arg_name, "arp_key_offset") == 0) {
-                       int status;
-
-                       PIPELINE_PARSE_ERR_DUPLICATE(
-                               arp_key_offset_present == 0, params->name,
-                               arg_name);
-                       arp_key_offset_present = 1;
-
-                       status = parser_read_uint32(&p->arp_key_offset,
-                               arg_value);
-                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
-                               params->name, arg_name, arg_value);
-                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
-                               params->name, arg_name, arg_value);
-
-                       continue;
-               }
-
-               /* color_offset */
-               if (strcmp(arg_name, "color_offset") == 0) {
-                       int status;
-
-                       PIPELINE_PARSE_ERR_DUPLICATE(
-                               color_offset_present == 0, params->name,
-                               arg_name);
-                       color_offset_present = 1;
-
-                       status = parser_read_uint32(&p->color_offset,
-                               arg_value);
-                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
-                               params->name, arg_name, arg_value);
-                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
-                               params->name, arg_name, arg_value);
-
-                       continue;
-               }
-
-               /* debug */
-               if (strcmp(arg_name, "dbg_ah_disable") == 0) {
-                       int status;
-
-                       PIPELINE_PARSE_ERR_DUPLICATE(
-                               dbg_ah_disable_present == 0, params->name,
-                               arg_name);
-                       dbg_ah_disable_present = 1;
-
-                       status = parser_read_arg_bool(arg_value);
-                       if (status >= 0) {
-                               p->dbg_ah_disable = status;
-                               continue;
-                       }
-
-                       PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
-                               arg_name, arg_value);
-
-                       continue;
-               }
-
-               /* any other */
-               PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
-       }
-
-       /* Check that mandatory arguments are present */
-       PIPELINE_PARSE_ERR_MANDATORY(ip_hdr_offset_present, params->name,
-               "ip_hdr_offset");
-
-       /* Check relations between arguments */
-       switch (p->encap) {
-       case PIPELINE_ROUTING_ENCAP_ETHERNET:
-               PIPELINE_ARG_CHECK((!p->qinq_sched), "Parse error in "
-                       "section \"%s\": encap = ethernet, therefore "
-                       "qinq_sched = yes/test is not allowed",
-                       params->name);
-               PIPELINE_ARG_CHECK((!p->mpls_color_mark), "Parse error "
-                       "in section \"%s\": encap = ethernet, therefore "
-                       "mpls_color_mark = yes is not allowed",
-                       params->name);
-               PIPELINE_ARG_CHECK((!color_offset_present), "Parse error "
-                       "in section \"%s\": encap = ethernet, therefore "
-                       "color_offset is not allowed",
-                       params->name);
-               break;
-
-       case PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ:
-               PIPELINE_ARG_CHECK((!p->mpls_color_mark), "Parse error "
-                       "in section \"%s\": encap = ethernet_qinq, "
-                       "therefore mpls_color_mark = yes is not allowed",
-                       params->name);
-               PIPELINE_ARG_CHECK((!color_offset_present), "Parse error "
-                       "in section \"%s\": encap = ethernet_qinq, "
-                       "therefore color_offset is not allowed",
-                       params->name);
-               break;
-
-       case PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS:
-               PIPELINE_ARG_CHECK((!p->qinq_sched), "Parse error in "
-                       "section \"%s\": encap = ethernet_mpls, therefore "
-                       "qinq_sched  = yes/test is not allowed",
-                       params->name);
-               break;
-       }
-
-       PIPELINE_ARG_CHECK((!(p->n_arp_entries &&
-               (!arp_key_offset_present))), "Parse error in section "
-                       "\"%s\": n_arp_entries is set while "
-                       "arp_key_offset is not set", params->name);
-
-       PIPELINE_ARG_CHECK((!((p->n_arp_entries == 0) &&
-               arp_key_offset_present)), "Parse error in section "
-                       "\"%s\": arp_key_offset present while "
-                       "n_arp_entries is not set", params->name);
-
-       return 0;
-}
-
-static void *
-pipeline_routing_init(struct pipeline_params *params,
-       __rte_unused void *arg)
-{
-       struct pipeline *p;
-       struct pipeline_routing *p_rt;
-       uint32_t size, i;
-
-       /* Check input arguments */
-       if ((params == NULL) ||
-               (params->n_ports_in == 0) ||
-               (params->n_ports_out == 0))
-               return NULL;
-
-       /* Memory allocation */
-       size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_routing));
-       p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
-       p_rt = (struct pipeline_routing *) p;
-       if (p == NULL)
-               return NULL;
-
-       strcpy(p->name, params->name);
-       p->log_level = params->log_level;
-
-       PLOG(p, HIGH, "Routing");
-
-       /* Parse arguments */
-       if (pipeline_routing_parse_args(&p_rt->params, params))
-               return NULL;
-
-       /* Pipeline */
-       {
-               struct rte_pipeline_params pipeline_params = {
-                       .name = params->name,
-                       .socket_id = params->socket_id,
-                       .offset_port_id = 0,
-               };
-
-               p->p = rte_pipeline_create(&pipeline_params);
-               if (p->p == NULL) {
-                       rte_free(p);
-                       return NULL;
-               }
-       }
-
-       /* Input ports */
-       p->n_ports_in = params->n_ports_in;
-       for (i = 0; i < p->n_ports_in; i++) {
-               struct rte_pipeline_port_in_params port_params = {
-                       .ops = pipeline_port_in_params_get_ops(
-                               &params->port_in[i]),
-                       .arg_create = pipeline_port_in_params_convert(
-                               &params->port_in[i]),
-                       .f_action = NULL,
-                       .arg_ah = NULL,
-                       .burst_size = params->port_in[i].burst_size,
-               };
-
-               int status = rte_pipeline_port_in_create(p->p,
-                       &port_params,
-                       &p->port_in_id[i]);
-
-               if (status) {
-                       rte_pipeline_free(p->p);
-                       rte_free(p);
-                       return NULL;
-               }
-       }
-
-       /* Output ports */
-       p->n_ports_out = params->n_ports_out;
-       for (i = 0; i < p->n_ports_out; i++) {
-               struct rte_pipeline_port_out_params port_params = {
-                       .ops = pipeline_port_out_params_get_ops(
-                               &params->port_out[i]),
-                       .arg_create = pipeline_port_out_params_convert(
-                               &params->port_out[i]),
-                       .f_action = NULL,
-                       .arg_ah = NULL,
-               };
-
-               int status = rte_pipeline_port_out_create(p->p,
-                       &port_params,
-                       &p->port_out_id[i]);
-
-               if (status) {
-                       rte_pipeline_free(p->p);
-                       rte_free(p);
-                       return NULL;
-               }
-       }
-
-       /* Routing table */
-       p->n_tables = 1;
-       {
-               struct rte_table_lpm_params table_lpm_params = {
-                       .name = p->name,
-                       .n_rules = p_rt->params.n_routes,
-                       .number_tbl8s = PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s,
-                       .flags = 0,
-                       .entry_unique_size = sizeof(struct routing_table_entry),
-                       .offset = p_rt->params.ip_hdr_offset +
-                               __builtin_offsetof(struct ipv4_hdr, dst_addr),
-               };
-
-               struct rte_pipeline_table_params table_params = {
-                               .ops = &rte_table_lpm_ops,
-                               .arg_create = &table_lpm_params,
-                               .f_action_hit = get_routing_table_ah_hit(p_rt),
-                               .f_action_miss = NULL,
-                               .arg_ah = p_rt,
-                               .action_data_size =
-                                       sizeof(struct routing_table_entry) -
-                                       sizeof(struct rte_pipeline_table_entry),
-                       };
-
-               int status;
-
-               status = rte_pipeline_table_create(p->p,
-                       &table_params,
-                       &p->table_id[0]);
-
-               if (status) {
-                       rte_pipeline_free(p->p);
-                       rte_free(p);
-                       return NULL;
-               }
-       }
-
-       /* ARP table configuration */
-       if (p_rt->params.n_arp_entries) {
-               struct rte_table_hash_params table_arp_params = {
-                       .name = p->name,
-                       .key_size = 8,
-                       .key_offset = p_rt->params.arp_key_offset,
-                       .key_mask = NULL,
-                       .n_keys = p_rt->params.n_arp_entries,
-                       .n_buckets =
-                               rte_align32pow2(p_rt->params.n_arp_entries / 4),
-                       .f_hash = hash_default_key8,
-                       .seed = 0,
-               };
-
-               struct rte_pipeline_table_params table_params = {
-                       .ops = &rte_table_hash_key8_ext_ops,
-                       .arg_create = &table_arp_params,
-                       .f_action_hit = get_arp_table_ah_hit(p_rt),
-                       .f_action_miss = NULL,
-                       .arg_ah = p_rt,
-                       .action_data_size = sizeof(struct arp_table_entry) -
-                               sizeof(struct rte_pipeline_table_entry),
-               };
-
-               int status;
-
-               status = rte_pipeline_table_create(p->p,
-                       &table_params,
-                       &p->table_id[1]);
-
-               if (status) {
-                       rte_pipeline_free(p->p);
-                       rte_free(p);
-                       return NULL;
-               }
-
-               p->n_tables++;
-       }
-
-       /* Connecting input ports to tables */
-       for (i = 0; i < p->n_ports_in; i++) {
-               int status = rte_pipeline_port_in_connect_to_table(p->p,
-                       p->port_in_id[i],
-                       p->table_id[0]);
-
-               if (status) {
-                       rte_pipeline_free(p->p);
-                       rte_free(p);
-                       return NULL;
-               }
-       }
-
-       /* Enable input ports */
-       for (i = 0; i < p->n_ports_in; i++) {
-               int status = rte_pipeline_port_in_enable(p->p,
-                       p->port_in_id[i]);
-
-               if (status) {
-                       rte_pipeline_free(p->p);
-                       rte_free(p);
-                       return NULL;
-               }
-       }
-
-       /* Check pipeline consistency */
-       if (rte_pipeline_check(p->p) < 0) {
-               rte_pipeline_free(p->p);
-               rte_free(p);
-               return NULL;
-       }
-
-       /* Message queues */
-       p->n_msgq = params->n_msgq;
-       for (i = 0; i < p->n_msgq; i++)
-               p->msgq_in[i] = params->msgq_in[i];
-       for (i = 0; i < p->n_msgq; i++)
-               p->msgq_out[i] = params->msgq_out[i];
-
-       /* Message handlers */
-       memcpy(p->handlers, handlers, sizeof(p->handlers));
-       memcpy(p_rt->custom_handlers,
-               custom_handlers,
-               sizeof(p_rt->custom_handlers));
-
-       return p;
-}
-
-static int
-pipeline_routing_free(void *pipeline)
-{
-       struct pipeline *p = (struct pipeline *) pipeline;
-
-       /* Check input arguments */
-       if (p == NULL)
-               return -1;
-
-       /* Free resources */
-       rte_pipeline_free(p->p);
-       rte_free(p);
-       return 0;
-}
-
-static int
-pipeline_routing_timer(void *pipeline)
-{
-       struct pipeline *p = (struct pipeline *) pipeline;
-
-       pipeline_msg_req_handle(p);
-       rte_pipeline_flush(p->p);
-
-       return 0;
-}
-
-void *
-pipeline_routing_msg_req_custom_handler(struct pipeline *p,
-       void *msg)
-{
-       struct pipeline_routing *p_rt = (struct pipeline_routing *) p;
-       struct pipeline_custom_msg_req *req = msg;
-       pipeline_msg_req_handler f_handle;
-
-       f_handle = (req->subtype < PIPELINE_ROUTING_MSG_REQS) ?
-               p_rt->custom_handlers[req->subtype] :
-               pipeline_msg_req_invalid_handler;
-
-       if (f_handle == NULL)
-               f_handle = pipeline_msg_req_invalid_handler;
-
-       return f_handle(p, req);
-}
-
-void *
-pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
-{
-       struct pipeline_routing *p_rt = (struct pipeline_routing *) p;
-       struct pipeline_routing_route_add_msg_req *req = msg;
-       struct pipeline_routing_route_add_msg_rsp *rsp = msg;
-
-       struct rte_table_lpm_key key = {
-               .ip = req->key.key.ipv4.ip,
-               .depth = req->key.key.ipv4.depth,
-       };
-
-       struct routing_table_entry entry_arp0 = {
-               .head = {
-                       .action = RTE_PIPELINE_ACTION_PORT,
-                       {.port_id = p->port_out_id[req->data.port_id]},
-               },
-
-               .flags = req->data.flags,
-               .port_id = req->data.port_id,
-               .ip = 0,
-               .data_offset = 0,
-               .ether_l2_length = 0,
-               .slab = {0},
-               .slab_offset = {0},
-       };
-
-       struct routing_table_entry entry_arp1 = {
-               .head = {
-                       .action = RTE_PIPELINE_ACTION_TABLE,
-                       {.table_id = p->table_id[1]},
-               },
-
-               .flags = req->data.flags,
-               .port_id = req->data.port_id,
-               .ip = rte_bswap32(req->data.ethernet.ip),
-               .data_offset = 0,
-               .ether_l2_length = 0,
-               .slab = {0},
-               .slab_offset = {0},
-       };
-
-       struct rte_pipeline_table_entry *entry = (p_rt->params.n_arp_entries) ?
-               (struct rte_pipeline_table_entry *) &entry_arp1 :
-               (struct rte_pipeline_table_entry *) &entry_arp0;
-
-       if ((req->key.type != PIPELINE_ROUTING_ROUTE_IPV4) ||
-               ((p_rt->params.n_arp_entries == 0) &&
-                       (req->data.flags & PIPELINE_ROUTING_ROUTE_ARP)) ||
-               (p_rt->params.n_arp_entries &&
-                       ((req->data.flags & PIPELINE_ROUTING_ROUTE_ARP) == 0)) ||
-               ((p_rt->params.encap != PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
-                       (req->data.flags & PIPELINE_ROUTING_ROUTE_QINQ)) ||
-               ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
-                       ((req->data.flags & PIPELINE_ROUTING_ROUTE_QINQ) == 0)) ||
-               ((p_rt->params.encap != PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
-                       (req->data.flags & PIPELINE_ROUTING_ROUTE_MPLS)) ||
-               ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
-                       ((req->data.flags & PIPELINE_ROUTING_ROUTE_MPLS) == 0))) {
-               rsp->status = -1;
-               return rsp;
-       }
-
-       /* Ether - ARP off */
-       if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) &&
-               (p_rt->params.n_arp_entries == 0)) {
-               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
-               uint64_t macaddr_dst;
-               uint64_t ethertype = ETHER_TYPE_IPv4;
-
-               macaddr_dst = *((uint64_t *)&(req->data.ethernet.macaddr));
-               macaddr_dst = rte_bswap64(macaddr_dst << 16);
-
-               entry_arp0.slab[0] =
-                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype);
-               entry_arp0.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
-
-               entry_arp0.slab[1] = rte_bswap64(macaddr_dst);
-               entry_arp0.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
-
-               entry_arp0.data_offset = entry_arp0.slab_offset[1] + 2
-                       - sizeof(struct rte_mbuf);
-               entry_arp0.ether_l2_length = 14;
-       }
-
-       /* Ether - ARP on */
-       if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) &&
-               p_rt->params.n_arp_entries) {
-               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
-               uint64_t ethertype = ETHER_TYPE_IPv4;
-
-               entry_arp1.slab[0] =
-                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype);
-               entry_arp1.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
-
-               entry_arp1.data_offset = entry_arp1.slab_offset[0] - 6
-                       - sizeof(struct rte_mbuf);
-               entry_arp1.ether_l2_length = 14;
-       }
-
-       /* Ether QinQ - ARP off */
-       if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
-               (p_rt->params.n_arp_entries == 0)) {
-               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
-               uint64_t macaddr_dst;
-               uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
-               uint64_t ethertype_vlan = 0x8100;
-               uint64_t ethertype_qinq = 0x9100;
-               uint64_t svlan = req->data.l2.qinq.svlan;
-               uint64_t cvlan = req->data.l2.qinq.cvlan;
-
-               macaddr_dst = *((uint64_t *)&(req->data.ethernet.macaddr));
-               macaddr_dst = rte_bswap64(macaddr_dst << 16);
-
-               entry_arp0.slab[0] = rte_bswap64((svlan << 48) |
-                       (ethertype_vlan << 32) |
-                       (cvlan << 16) |
-                       ethertype_ipv4);
-               entry_arp0.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
-
-               entry_arp0.slab[1] =
-                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_qinq);
-               entry_arp0.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
-
-               entry_arp0.slab[2] = rte_bswap64(macaddr_dst);
-               entry_arp0.slab_offset[2] = p_rt->params.ip_hdr_offset - 3 * 8;
-
-               entry_arp0.data_offset = entry_arp0.slab_offset[2] + 2
-                       - sizeof(struct rte_mbuf);
-               entry_arp0.ether_l2_length = 22;
-       }
-
-       /* Ether QinQ - ARP on */
-       if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
-               p_rt->params.n_arp_entries) {
-               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
-               uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
-               uint64_t ethertype_vlan = 0x8100;
-               uint64_t ethertype_qinq = 0x9100;
-               uint64_t svlan = req->data.l2.qinq.svlan;
-               uint64_t cvlan = req->data.l2.qinq.cvlan;
-
-               entry_arp1.slab[0] = rte_bswap64((svlan << 48) |
-                       (ethertype_vlan << 32) |
-                       (cvlan << 16) |
-                       ethertype_ipv4);
-               entry_arp1.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
-
-               entry_arp1.slab[1] =
-                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_qinq);
-               entry_arp1.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
-
-               entry_arp1.data_offset = entry_arp1.slab_offset[1] - 6
-                       - sizeof(struct rte_mbuf);
-               entry_arp1.ether_l2_length = 22;
-       }
-
-       /* Ether MPLS - ARP off */
-       if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
-               (p_rt->params.n_arp_entries == 0)) {
-               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
-               uint64_t macaddr_dst;
-               uint64_t ethertype_mpls = 0x8847;
-
-               uint64_t label0 = req->data.l2.mpls.labels[0];
-               uint64_t label1 = req->data.l2.mpls.labels[1];
-               uint64_t label2 = req->data.l2.mpls.labels[2];
-               uint64_t label3 = req->data.l2.mpls.labels[3];
-               uint32_t n_labels = req->data.l2.mpls.n_labels;
-
-               macaddr_dst = *((uint64_t *)&(req->data.ethernet.macaddr));
-               macaddr_dst = rte_bswap64(macaddr_dst << 16);
-
-               switch (n_labels) {
-               case 1:
-                       entry_arp0.slab[0] = 0;
-                       entry_arp0.slab_offset[0] =
-                               p_rt->params.ip_hdr_offset - 8;
-
-                       entry_arp0.slab[1] = rte_bswap64(
-                               MPLS_LABEL(label0, 0, 1, 0));
-                       entry_arp0.slab_offset[1] =
-                               p_rt->params.ip_hdr_offset - 8;
-                       break;
-
-               case 2:
-                       entry_arp0.slab[0] = 0;
-                       entry_arp0.slab_offset[0] =
-                               p_rt->params.ip_hdr_offset - 8;
-
-                       entry_arp0.slab[1] = rte_bswap64(
-                               (MPLS_LABEL(label0, 0, 0, 0) << 32) |
-                               MPLS_LABEL(label1, 0, 1, 0));
-                       entry_arp0.slab_offset[1] =
-                               p_rt->params.ip_hdr_offset - 8;
-                       break;
-
-               case 3:
-                       entry_arp0.slab[0] = rte_bswap64(
-                               (MPLS_LABEL(label1, 0, 0, 0) << 32) |
-                               MPLS_LABEL(label2, 0, 1, 0));
-                       entry_arp0.slab_offset[0] =
-                               p_rt->params.ip_hdr_offset - 8;
-
-                       entry_arp0.slab[1] = rte_bswap64(
-                               MPLS_LABEL(label0, 0, 0, 0));
-                       entry_arp0.slab_offset[1] =
-                               p_rt->params.ip_hdr_offset - 2 * 8;
-                       break;
-
-               case 4:
-                       entry_arp0.slab[0] = rte_bswap64(
-                               (MPLS_LABEL(label2, 0, 0, 0) << 32) |
-                               MPLS_LABEL(label3, 0, 1, 0));
-                       entry_arp0.slab_offset[0] =
-                               p_rt->params.ip_hdr_offset - 8;
-
-                       entry_arp0.slab[1] = rte_bswap64(
-                               (MPLS_LABEL(label0, 0, 0, 0) << 32) |
-                               MPLS_LABEL(label1, 0, 0, 0));
-                       entry_arp0.slab_offset[1] =
-                               p_rt->params.ip_hdr_offset - 2 * 8;
-                       break;
-
-               default:
-                       rsp->status = -1;
-                       return rsp;
-               }
-
-               entry_arp0.slab[2] =
-                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_mpls);
-               entry_arp0.slab_offset[2] = p_rt->params.ip_hdr_offset -
-                       (n_labels * 4 + 8);
-
-               entry_arp0.slab[3] = rte_bswap64(macaddr_dst);
-               entry_arp0.slab_offset[3] = p_rt->params.ip_hdr_offset -
-                       (n_labels * 4 + 2 * 8);
-
-               entry_arp0.data_offset = entry_arp0.slab_offset[3] + 2
-                       - sizeof(struct rte_mbuf);
-               entry_arp0.ether_l2_length = n_labels * 4 + 14;
-       }
-
-       /* Ether MPLS - ARP on */
-       if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
-               p_rt->params.n_arp_entries) {
-               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
-               uint64_t ethertype_mpls = 0x8847;
-
-               uint64_t label0 = req->data.l2.mpls.labels[0];
-               uint64_t label1 = req->data.l2.mpls.labels[1];
-               uint64_t label2 = req->data.l2.mpls.labels[2];
-               uint64_t label3 = req->data.l2.mpls.labels[3];
-               uint32_t n_labels = req->data.l2.mpls.n_labels;
-
-               switch (n_labels) {
-               case 1:
-                       entry_arp1.slab[0] = 0;
-                       entry_arp1.slab_offset[0] =
-                               p_rt->params.ip_hdr_offset - 8;
-
-                       entry_arp1.slab[1] = rte_bswap64(
-                               MPLS_LABEL(label0, 0, 1, 0));
-                       entry_arp1.slab_offset[1] =
-                               p_rt->params.ip_hdr_offset - 8;
-                       break;
-
-               case 2:
-                       entry_arp1.slab[0] = 0;
-                       entry_arp1.slab_offset[0] =
-                               p_rt->params.ip_hdr_offset - 8;
-
-                       entry_arp1.slab[1] = rte_bswap64(
-                               (MPLS_LABEL(label0, 0, 0, 0) << 32) |
-                               MPLS_LABEL(label1, 0, 1, 0));
-                       entry_arp1.slab_offset[1] =
-                               p_rt->params.ip_hdr_offset - 8;
-                       break;
-
-               case 3:
-                       entry_arp1.slab[0] = rte_bswap64(
-                               (MPLS_LABEL(label1, 0, 0, 0) << 32) |
-                               MPLS_LABEL(label2, 0, 1, 0));
-                       entry_arp1.slab_offset[0] =
-                               p_rt->params.ip_hdr_offset - 8;
-
-                       entry_arp1.slab[1] = rte_bswap64(
-                               MPLS_LABEL(label0, 0, 0, 0));
-                       entry_arp1.slab_offset[1] =
-                               p_rt->params.ip_hdr_offset - 2 * 8;
-                       break;
-
-               case 4:
-                       entry_arp1.slab[0] = rte_bswap64(
-                               (MPLS_LABEL(label2, 0, 0, 0) << 32) |
-                               MPLS_LABEL(label3, 0, 1, 0));
-                       entry_arp1.slab_offset[0] =
-                               p_rt->params.ip_hdr_offset - 8;
-
-                       entry_arp1.slab[1] = rte_bswap64(
-                               (MPLS_LABEL(label0, 0, 0, 0) << 32) |
-                               MPLS_LABEL(label1, 0, 0, 0));
-                       entry_arp1.slab_offset[1] =
-                               p_rt->params.ip_hdr_offset - 2 * 8;
-                       break;
-
-               default:
-                       rsp->status = -1;
-                       return rsp;
-               }
-
-               entry_arp1.slab[2] =
-                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_mpls);
-               entry_arp1.slab_offset[2] = p_rt->params.ip_hdr_offset -
-                       (n_labels * 4 + 8);
-
-               entry_arp1.data_offset = entry_arp1.slab_offset[2] - 6
-                       - sizeof(struct rte_mbuf);
-               entry_arp1.ether_l2_length = n_labels * 4 + 14;
-       }
-
-       rsp->status = rte_pipeline_table_entry_add(p->p,
-               p->table_id[0],
-               &key,
-               entry,
-               &rsp->key_found,
-               (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
-       return rsp;
-}
-
-void *
-pipeline_routing_msg_req_route_del_handler(struct pipeline *p, void *msg)
-{
-       struct pipeline_routing_route_delete_msg_req *req = msg;
-       struct pipeline_routing_route_delete_msg_rsp *rsp = msg;
-
-       struct rte_table_lpm_key key = {
-               .ip = req->key.key.ipv4.ip,
-               .depth = req->key.key.ipv4.depth,
-       };
-
-       if (req->key.type != PIPELINE_ROUTING_ROUTE_IPV4) {
-               rsp->status = -1;
-               return rsp;
-       }
-
-       rsp->status = rte_pipeline_table_entry_delete(p->p,
-               p->table_id[0],
-               &key,
-               &rsp->key_found,
-               NULL);
-
-       return rsp;
-}
-
-void *
-pipeline_routing_msg_req_route_add_default_handler(struct pipeline *p,
-       void *msg)
-{
-       struct pipeline_routing_route_add_default_msg_req *req = msg;
-       struct pipeline_routing_route_add_default_msg_rsp *rsp = msg;
-
-       struct routing_table_entry default_entry = {
-               .head = {
-                       .action = RTE_PIPELINE_ACTION_PORT,
-                       {.port_id = p->port_out_id[req->port_id]},
-               },
-
-               .flags = 0,
-               .port_id = 0,
-               .ip = 0,
-       };
-
-       rsp->status = rte_pipeline_table_default_entry_add(p->p,
-               p->table_id[0],
-               (struct rte_pipeline_table_entry *) &default_entry,
-               (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
-       return rsp;
-}
-
-void *
-pipeline_routing_msg_req_route_del_default_handler(struct pipeline *p,
-       void *msg)
-{
-       struct pipeline_routing_route_delete_default_msg_rsp *rsp = msg;
-
-       rsp->status = rte_pipeline_table_default_entry_delete(p->p,
-               p->table_id[0],
-               NULL);
-
-       return rsp;
-}
-
-void *
-pipeline_routing_msg_req_arp_add_handler(struct pipeline *p, void *msg)
-{
-       struct pipeline_routing_arp_add_msg_req *req = msg;
-       struct pipeline_routing_arp_add_msg_rsp *rsp = msg;
-
-       struct pipeline_routing_arp_key_ipv4 key = {
-               .port_id = req->key.key.ipv4.port_id,
-               .ip = rte_bswap32(req->key.key.ipv4.ip),
-       };
-
-       struct arp_table_entry entry = {
-               .head = {
-                       .action = RTE_PIPELINE_ACTION_PORT,
-                       {.port_id = p->port_out_id[req->key.key.ipv4.port_id]},
-               },
-
-               .macaddr = 0, /* set below */
-       };
-
-       if (req->key.type != PIPELINE_ROUTING_ARP_IPV4) {
-               rsp->status = -1;
-               return rsp;
-       }
-
-       entry.macaddr = *((uint64_t *)&(req->macaddr));
-       entry.macaddr = entry.macaddr << 16;
-
-       rsp->status = rte_pipeline_table_entry_add(p->p,
-               p->table_id[1],
-               &key,
-               (struct rte_pipeline_table_entry *) &entry,
-               &rsp->key_found,
-               (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
-       return rsp;
-}
-
-void *
-pipeline_routing_msg_req_arp_del_handler(struct pipeline *p, void *msg)
-{
-       struct pipeline_routing_arp_delete_msg_req *req = msg;
-       struct pipeline_routing_arp_delete_msg_rsp *rsp = msg;
-
-       struct pipeline_routing_arp_key_ipv4 key = {
-               .port_id = req->key.key.ipv4.port_id,
-               .ip = rte_bswap32(req->key.key.ipv4.ip),
-       };
-
-       if (req->key.type != PIPELINE_ROUTING_ARP_IPV4) {
-               rsp->status = -1;
-               return rsp;
-       }
-
-       rsp->status = rte_pipeline_table_entry_delete(p->p,
-               p->table_id[1],
-               &key,
-               &rsp->key_found,
-               NULL);
-
-       return rsp;
-}
-
-void *
-pipeline_routing_msg_req_arp_add_default_handler(struct pipeline *p, void *msg)
-{
-       struct pipeline_routing_arp_add_default_msg_req *req = msg;
-       struct pipeline_routing_arp_add_default_msg_rsp *rsp = msg;
-
-       struct arp_table_entry default_entry = {
-               .head = {
-                       .action = RTE_PIPELINE_ACTION_PORT,
-                       {.port_id = p->port_out_id[req->port_id]},
-               },
-
-               .macaddr = 0,
-       };
-
-       rsp->status = rte_pipeline_table_default_entry_add(p->p,
-               p->table_id[1],
-               (struct rte_pipeline_table_entry *) &default_entry,
-               (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
-       return rsp;
-}
-
-void *
-pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p, void *msg)
-{
-       struct pipeline_routing_arp_delete_default_msg_rsp *rsp = msg;
-
-       rsp->status = rte_pipeline_table_default_entry_delete(p->p,
-               p->table_id[1],
-               NULL);
-
-       return rsp;
-}
-
-void *
-pipeline_routing_msg_req_set_macaddr_handler(struct pipeline *p, void *msg)
-{
-       struct pipeline_routing *p_rt = (struct pipeline_routing *) p;
-       struct pipeline_routing_set_macaddr_msg_req *req = msg;
-       struct pipeline_routing_set_macaddr_msg_rsp *rsp = msg;
-       uint32_t port_id;
-
-       for (port_id = 0; port_id < p->n_ports_out; port_id++)
-               p_rt->macaddr[port_id] = req->macaddr[port_id];
-
-       rsp->status = 0;
-
-       return rsp;
-}
-
-struct pipeline_be_ops pipeline_routing_be_ops = {
-       .f_init = pipeline_routing_init,
-       .f_free = pipeline_routing_free,
-       .f_run = NULL,
-       .f_timer = pipeline_routing_timer,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.h b/examples/ip_pipeline/pipeline/pipeline_routing_be.h
deleted file mode 100644 (file)
index 7140ee4..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_ROUTING_BE_H__
-#define __INCLUDE_PIPELINE_ROUTING_BE_H__
-
-#include <rte_ether.h>
-
-#include "pipeline_common_be.h"
-
-/*
- * Pipeline argument parsing
- */
-#ifndef PIPELINE_ROUTING_N_ROUTES_DEFAULT
-#define PIPELINE_ROUTING_N_ROUTES_DEFAULT                  4096
-#endif
-
-enum pipeline_routing_encap {
-       PIPELINE_ROUTING_ENCAP_ETHERNET = 0,
-       PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ,
-       PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS,
-};
-
-struct pipeline_routing_params {
-       /* routing */
-       uint32_t n_routes;
-       uint32_t port_local_dest;
-
-       /* routing packet encapsulation */
-       enum pipeline_routing_encap encap;
-       uint32_t qinq_sched;
-       uint32_t mpls_color_mark;
-
-       /* arp */
-       uint32_t n_arp_entries;
-
-       /* packet buffer offsets */
-       uint32_t ip_hdr_offset;
-       uint32_t arp_key_offset;
-       uint32_t color_offset;
-
-       /* debug */
-       uint32_t dbg_ah_disable;
-};
-
-int
-pipeline_routing_parse_args(struct pipeline_routing_params *p,
-       struct pipeline_params *params);
-
-/*
- * Route
- */
-enum pipeline_routing_route_key_type {
-       PIPELINE_ROUTING_ROUTE_IPV4,
-};
-
-struct pipeline_routing_route_key_ipv4 {
-       uint32_t ip;
-       uint32_t depth;
-};
-
-struct pipeline_routing_route_key {
-       enum pipeline_routing_route_key_type type;
-       union {
-               struct pipeline_routing_route_key_ipv4 ipv4;
-       } key;
-};
-
-enum pipeline_routing_route_flags {
-       PIPELINE_ROUTING_ROUTE_LOCAL = 1 << 0, /* 0 = remote; 1 = local */
-       PIPELINE_ROUTING_ROUTE_ARP = 1 << 1, /* 0 = ARP OFF; 1 = ARP ON */
-       PIPELINE_ROUTING_ROUTE_QINQ = 1 << 2, /* 0 = QINQ OFF; 1 = QINQ ON */
-       PIPELINE_ROUTING_ROUTE_MPLS = 1 << 3, /* 0 = MPLS OFF; 1 = MPLS ON */
-};
-
-#define PIPELINE_ROUTING_MPLS_LABELS_MAX         4
-
-struct pipeline_routing_route_data {
-       uint32_t flags;
-       uint32_t port_id; /* Output port ID */
-
-       union {
-               /* Next hop IP (valid only when ARP is enabled) */
-               uint32_t ip;
-
-               /* Next hop MAC address (valid only when ARP disabled */
-               struct ether_addr macaddr;
-       } ethernet;
-
-       union {
-               struct {
-                       uint16_t svlan;
-                       uint16_t cvlan;
-               } qinq;
-
-               struct {
-                       uint32_t labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
-                       uint32_t n_labels;
-               } mpls;
-       } l2;
-};
-
-/*
- * ARP
- */
-enum pipeline_routing_arp_key_type {
-       PIPELINE_ROUTING_ARP_IPV4,
-};
-
-struct pipeline_routing_arp_key_ipv4 {
-       uint32_t port_id;
-       uint32_t ip;
-};
-
-struct pipeline_routing_arp_key {
-       enum pipeline_routing_arp_key_type type;
-       union {
-               struct pipeline_routing_arp_key_ipv4 ipv4;
-       } key;
-};
-
-/*
- * Messages
- */
-enum pipeline_routing_msg_req_type {
-       PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD,
-       PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL,
-       PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD_DEFAULT,
-       PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL_DEFAULT,
-       PIPELINE_ROUTING_MSG_REQ_ARP_ADD,
-       PIPELINE_ROUTING_MSG_REQ_ARP_DEL,
-       PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT,
-       PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT,
-       PIPELINE_ROUTING_MSG_REQ_SET_MACADDR,
-       PIPELINE_ROUTING_MSG_REQS
-};
-
-/*
- * MSG ROUTE ADD
- */
-struct pipeline_routing_route_add_msg_req {
-       enum pipeline_msg_req_type type;
-       enum pipeline_routing_msg_req_type subtype;
-
-       /* key */
-       struct pipeline_routing_route_key key;
-
-       /* data */
-       struct pipeline_routing_route_data data;
-};
-
-struct pipeline_routing_route_add_msg_rsp {
-       int status;
-       int key_found;
-       void *entry_ptr;
-};
-
-/*
- * MSG ROUTE DELETE
- */
-struct pipeline_routing_route_delete_msg_req {
-       enum pipeline_msg_req_type type;
-       enum pipeline_routing_msg_req_type subtype;
-
-       /* key */
-       struct pipeline_routing_route_key key;
-};
-
-struct pipeline_routing_route_delete_msg_rsp {
-       int status;
-       int key_found;
-};
-
-/*
- * MSG ROUTE ADD DEFAULT
- */
-struct pipeline_routing_route_add_default_msg_req {
-       enum pipeline_msg_req_type type;
-       enum pipeline_routing_msg_req_type subtype;
-
-       /* data */
-       uint32_t port_id;
-};
-
-struct pipeline_routing_route_add_default_msg_rsp {
-       int status;
-       void *entry_ptr;
-};
-
-/*
- * MSG ROUTE DELETE DEFAULT
- */
-struct pipeline_routing_route_delete_default_msg_req {
-       enum pipeline_msg_req_type type;
-       enum pipeline_routing_msg_req_type subtype;
-};
-
-struct pipeline_routing_route_delete_default_msg_rsp {
-       int status;
-};
-
-/*
- * MSG ARP ADD
- */
-struct pipeline_routing_arp_add_msg_req {
-       enum pipeline_msg_req_type type;
-       enum pipeline_routing_msg_req_type subtype;
-
-       /* key */
-       struct pipeline_routing_arp_key key;
-
-       /* data */
-       struct ether_addr macaddr;
-};
-
-struct pipeline_routing_arp_add_msg_rsp {
-       int status;
-       int key_found;
-       void *entry_ptr;
-};
-
-/*
- * MSG ARP DELETE
- */
-struct pipeline_routing_arp_delete_msg_req {
-       enum pipeline_msg_req_type type;
-       enum pipeline_routing_msg_req_type subtype;
-
-       /* key */
-       struct pipeline_routing_arp_key key;
-};
-
-struct pipeline_routing_arp_delete_msg_rsp {
-       int status;
-       int key_found;
-};
-
-/*
- * MSG ARP ADD DEFAULT
- */
-struct pipeline_routing_arp_add_default_msg_req {
-       enum pipeline_msg_req_type type;
-       enum pipeline_routing_msg_req_type subtype;
-
-       /* data */
-       uint32_t port_id;
-};
-
-struct pipeline_routing_arp_add_default_msg_rsp {
-       int status;
-       void *entry_ptr;
-};
-
-/*
- * MSG ARP DELETE DEFAULT
- */
-struct pipeline_routing_arp_delete_default_msg_req {
-       enum pipeline_msg_req_type type;
-       enum pipeline_routing_msg_req_type subtype;
-};
-
-struct pipeline_routing_arp_delete_default_msg_rsp {
-       int status;
-};
-
-/*
- * MSG SET MACADDR
- */
-struct pipeline_routing_set_macaddr_msg_req {
-       enum pipeline_msg_req_type type;
-       enum pipeline_routing_msg_req_type subtype;
-
-       uint64_t macaddr[PIPELINE_MAX_PORT_OUT];
-};
-
-struct pipeline_routing_set_macaddr_msg_rsp {
-       int status;
-};
-
-extern struct pipeline_be_ops pipeline_routing_be_ops;
-
-#endif