diff options
author | Luca Boccassi <luca.boccassi@gmail.com> | 2018-08-14 18:52:30 +0100 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2018-08-14 18:53:17 +0100 |
commit | b63264c8342e6a1b6971c79550d2af2024b6a4de (patch) | |
tree | 83114aac64286fe616506c0b3dfaec2ab86ef835 /examples/ip_pipeline/pipeline/pipeline_routing.c | |
parent | ca33590b6af032bff57d9cc70455660466a654b2 (diff) |
New upstream version 18.08upstream/18.08
Change-Id: I32fdf5e5016556d9c0a6d88ddaf1fc468961790a
Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
Diffstat (limited to 'examples/ip_pipeline/pipeline/pipeline_routing.c')
-rw-r--r-- | examples/ip_pipeline/pipeline/pipeline_routing.c | 1613 |
1 files changed, 0 insertions, 1613 deletions
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.c b/examples/ip_pipeline/pipeline/pipeline_routing.c deleted file mode 100644 index 0562c63a..00000000 --- a/examples/ip_pipeline/pipeline/pipeline_routing.c +++ /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, -}; |