From 1f277fa81af91a4b8384313c7ef158bc2aadf002 Mon Sep 17 00:00:00 2001 From: Jasvinder Singh Date: Wed, 1 Jun 2016 15:01:00 +0100 Subject: [PATCH] examples/ip_pipeline: assign MAC address to routing ports As a result of tracking, output ports of routing pipelines are linked with physical nic ports (potentially through other pipeline instances). Thus, the mac addresses of the NIC ports are assigned to routing pipeline out ports which are connected to them and are further used in routing table entries instead of hardcoded default values. Signed-off-by: Jasvinder Singh Acked-by: Cristian Dumitrescu --- doc/guides/rel_notes/release_16_07.rst | 1 + .../ip_pipeline/pipeline/pipeline_routing.c | 89 +++++++++++++++++-- .../ip_pipeline/pipeline/pipeline_routing.h | 7 ++ .../pipeline/pipeline_routing_be.c | 61 +++++++++---- .../pipeline/pipeline_routing_be.h | 15 ++++ 5 files changed, 150 insertions(+), 23 deletions(-) diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst index 4919b04b4f..68efcd49a4 100644 --- a/doc/guides/rel_notes/release_16_07.rst +++ b/doc/guides/rel_notes/release_16_07.rst @@ -61,6 +61,7 @@ New Features The following features have been added to ip_pipeline application: + * Configure the MAC address in the routing pipeline. * Enable RSS per network interface through the configuration file. * Streamline the CLI code. diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.c b/examples/ip_pipeline/pipeline/pipeline_routing.c index 4d074c170f..80f029dc56 100644 --- a/examples/ip_pipeline/pipeline/pipeline_routing.c +++ b/examples/ip_pipeline/pipeline/pipeline_routing.c @@ -58,8 +58,11 @@ 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; /* Routes */ TAILQ_HEAD(, app_pipeline_routing_route) routes; @@ -79,11 +82,13 @@ struct pipeline_routing { }; 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 +96,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,9 +105,16 @@ 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; @@ -110,6 +124,18 @@ pipeline_routing_init(struct pipeline_params *params, 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) { @@ -848,6 +874,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 +1464,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, diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.h b/examples/ip_pipeline/pipeline/pipeline_routing.h index fa41642b8b..0197449b73 100644 --- a/examples/ip_pipeline/pipeline/pipeline_routing.h +++ b/examples/ip_pipeline/pipeline/pipeline_routing.h @@ -85,6 +85,13 @@ 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 */ diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.c b/examples/ip_pipeline/pipeline/pipeline_routing_be.c index e7542a8f2b..a448157844 100644 --- a/examples/ip_pipeline/pipeline/pipeline_routing_be.c +++ b/examples/ip_pipeline/pipeline/pipeline_routing_be.c @@ -65,7 +65,9 @@ ((((uint64_t) (pipe)) & 0xFFFFFFFF) << 32)) -#define MAC_SRC_DEFAULT 0x112233445566ULL +/* 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 @@ -75,6 +77,7 @@ 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; /* @@ -132,6 +135,10 @@ 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, @@ -149,6 +156,8 @@ static pipeline_msg_req_handler custom_handlers[] = { 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, }; /* @@ -1513,7 +1522,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) /* Ether - ARP off */ if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) && (p_rt->params.n_arp_entries == 0)) { - uint64_t macaddr_src = MAC_SRC_DEFAULT; + uint64_t macaddr_src = p_rt->macaddr[req->data.port_id]; uint64_t macaddr_dst; uint64_t ethertype = ETHER_TYPE_IPv4; @@ -1521,7 +1530,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) macaddr_dst = rte_bswap64(macaddr_dst << 16); entry_arp0.slab[0] = - rte_bswap64((macaddr_src << 16) | ethertype); + 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); @@ -1535,11 +1544,11 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) /* Ether - ARP on */ if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) && p_rt->params.n_arp_entries) { - uint64_t macaddr_src = MAC_SRC_DEFAULT; + uint64_t macaddr_src = p_rt->macaddr[req->data.port_id]; uint64_t ethertype = ETHER_TYPE_IPv4; - entry_arp1.slab[0] = rte_bswap64((macaddr_src << 16) | - ethertype); + 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 @@ -1550,7 +1559,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) /* 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 = MAC_SRC_DEFAULT; + 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; @@ -1567,8 +1576,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) ethertype_ipv4); entry_arp0.slab_offset[0] = p_rt->params.ip_hdr_offset - 8; - entry_arp0.slab[1] = rte_bswap64((macaddr_src << 16) | - ethertype_qinq); + 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); @@ -1582,7 +1591,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) /* Ether QinQ - ARP on */ if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) && p_rt->params.n_arp_entries) { - uint64_t macaddr_src = MAC_SRC_DEFAULT; + 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; @@ -1595,8 +1604,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) ethertype_ipv4); entry_arp1.slab_offset[0] = p_rt->params.ip_hdr_offset - 8; - entry_arp1.slab[1] = rte_bswap64((macaddr_src << 16) | - ethertype_qinq); + 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 @@ -1607,7 +1616,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) /* 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 = MAC_SRC_DEFAULT; + uint64_t macaddr_src = p_rt->macaddr[req->data.port_id]; uint64_t macaddr_dst; uint64_t ethertype_mpls = 0x8847; @@ -1676,8 +1685,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) return rsp; } - entry_arp0.slab[2] = rte_bswap64((macaddr_src << 16) | - ethertype_mpls); + 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); @@ -1693,7 +1702,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) /* Ether MPLS - ARP on */ if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) && p_rt->params.n_arp_entries) { - uint64_t macaddr_src = MAC_SRC_DEFAULT; + 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]; @@ -1758,8 +1767,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg) return rsp; } - entry_arp1.slab[2] = rte_bswap64((macaddr_src << 16) | - ethertype_mpls); + 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); @@ -1940,6 +1949,22 @@ pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p, void *msg) 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, diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.h b/examples/ip_pipeline/pipeline/pipeline_routing_be.h index ec767b240e..822995b77f 100644 --- a/examples/ip_pipeline/pipeline/pipeline_routing_be.h +++ b/examples/ip_pipeline/pipeline/pipeline_routing_be.h @@ -160,6 +160,7 @@ enum pipeline_routing_msg_req_type { 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 }; @@ -291,6 +292,20 @@ 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 -- 2.20.1