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;
};
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) ||
(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);
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;
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)
{
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
*
};
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,
((((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
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;
/*
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_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,
};
/*
/* 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;
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);
/* 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
/* 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;
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);
/* 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;
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
/* 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;
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);
/* 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];
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);
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,