X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fip_pipeline%2Fpipeline%2Fpipeline_routing.c;h=3aadbf91439901ea60596028a9d87588116445a7;hb=99c12dcca65d;hp=4d074c170fe706819e9d9997b625b298dd10c138;hpb=760064838ec06cbdbe96375930237510e260d09e;p=dpdk.git diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.c b/examples/ip_pipeline/pipeline/pipeline_routing.c index 4d074c170f..3aadbf9143 100644 --- a/examples/ip_pipeline/pipeline/pipeline_routing.c +++ b/examples/ip_pipeline/pipeline/pipeline_routing.c @@ -58,8 +58,14 @@ struct app_pipeline_routing_arp_entry { 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; @@ -78,12 +84,151 @@ struct pipeline_routing { 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 * -pipeline_routing_init(struct pipeline_params *params, - __rte_unused void *arg) +app_pipeline_routing_init(struct pipeline_params *params, + void *arg) { + struct app_params *app = (struct app_params *) arg; struct pipeline_routing *p; - uint32_t size; + uint32_t pipeline_id, size; + int status; /* Check input arguments */ if ((params == NULL) || @@ -91,6 +236,8 @@ pipeline_routing_init(struct pipeline_params *params, (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); @@ -98,18 +245,39 @@ pipeline_routing_init(struct pipeline_params *params, 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) { @@ -197,7 +365,9 @@ print_route(const struct app_pipeline_routing_route *route) key->depth, route->data.port_id); - if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP) + 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, @@ -848,6 +1018,59 @@ app_pipeline_routing_delete_default_arp_entry(struct app_params *app, 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 * @@ -1385,8 +1608,8 @@ static cmdline_parse_ctx_t pipeline_cmds[] = { }; static struct pipeline_fe_ops pipeline_routing_fe_ops = { - .f_init = pipeline_routing_init, - .f_post_init = NULL, + .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,