From 6b1b3c3c9d30fea58064fd8d61e11cd0e6157203 Mon Sep 17 00:00:00 2001 From: Jasvinder Singh Date: Thu, 29 Mar 2018 19:31:52 +0100 Subject: [PATCH] examples/ip_pipeline: add port enable and disable commands Add commands to enable and disable the pipeline ports. Signed-off-by: Cristian Dumitrescu Signed-off-by: Jasvinder Singh Signed-off-by: Fan Zhang --- examples/ip_pipeline/cli.c | 112 ++++++++++++++++++++++ examples/ip_pipeline/pipeline.h | 8 ++ examples/ip_pipeline/thread.c | 165 +++++++++++++++++++++++++++++++- 3 files changed, 284 insertions(+), 1 deletion(-) diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c index 2032563a90..c3adc17895 100644 --- a/examples/ip_pipeline/cli.c +++ b/examples/ip_pipeline/cli.c @@ -1937,6 +1937,100 @@ cmd_pipeline_port_in_table(char **tokens, } } +/** + * pipeline port in enable + */ +static void +cmd_pipeline_port_in_enable(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size) +{ + char *pipeline_name; + uint32_t port_id; + int status; + + if (n_tokens != 6) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + pipeline_name = tokens[1]; + + if (strcmp(tokens[2], "port") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port"); + return; + } + + if (strcmp(tokens[3], "in") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in"); + return; + } + + if (parser_read_uint32(&port_id, tokens[4]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "port_id"); + return; + } + + if (strcmp(tokens[5], "enable") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable"); + return; + } + + status = pipeline_port_in_enable(pipeline_name, port_id); + if (status) { + snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); + return; + } +} + +/** + * pipeline port in disable + */ +static void +cmd_pipeline_port_in_disable(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size) +{ + char *pipeline_name; + uint32_t port_id; + int status; + + if (n_tokens != 6) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + pipeline_name = tokens[1]; + + if (strcmp(tokens[2], "port") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port"); + return; + } + + if (strcmp(tokens[3], "in") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in"); + return; + } + + if (parser_read_uint32(&port_id, tokens[4]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "port_id"); + return; + } + + if (strcmp(tokens[5], "disable") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable"); + return; + } + + status = pipeline_port_in_disable(pipeline_name, port_id); + if (status) { + snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); + return; + } +} + /** * thread pipeline enable */ @@ -2148,6 +2242,24 @@ cli_process(char *in, char *out, size_t out_size) out, out_size); return; } + + if ((n_tokens >= 6) && + (strcmp(tokens[2], "port") == 0) && + (strcmp(tokens[3], "in") == 0) && + (strcmp(tokens[5], "enable") == 0)) { + cmd_pipeline_port_in_enable(tokens, n_tokens, + out, out_size); + return; + } + + if ((n_tokens >= 6) && + (strcmp(tokens[2], "port") == 0) && + (strcmp(tokens[3], "in") == 0) && + (strcmp(tokens[5], "disable") == 0)) { + cmd_pipeline_port_in_disable(tokens, n_tokens, + out, out_size); + return; + } } if (strcmp(tokens[0], "thread") == 0) { diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h index 39e100856b..08b2555c1e 100644 --- a/examples/ip_pipeline/pipeline.h +++ b/examples/ip_pipeline/pipeline.h @@ -269,4 +269,12 @@ struct table_rule_action { struct rte_table_action_time_params time; }; +int +pipeline_port_in_enable(const char *pipeline_name, + uint32_t port_id); + +int +pipeline_port_in_disable(const char *pipeline_name, + uint32_t port_id); + #endif /* _INCLUDE_PIPELINE_H_ */ diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c index 6c555dc6c9..35c4de3731 100644 --- a/examples/ip_pipeline/thread.c +++ b/examples/ip_pipeline/thread.c @@ -477,19 +477,148 @@ thread_msg_handle(struct thread_data *t) /** * Master thread & data plane threads: message passing */ - enum pipeline_req_type { + /* Port IN */ + PIPELINE_REQ_PORT_IN_ENABLE, + PIPELINE_REQ_PORT_IN_DISABLE, + PIPELINE_REQ_MAX }; struct pipeline_msg_req { enum pipeline_req_type type; + uint32_t id; /* Port IN, port OUT or table ID */ }; struct pipeline_msg_rsp { int status; }; +/** + * Master thread + */ +static struct pipeline_msg_req * +pipeline_msg_alloc(void) +{ + size_t size = RTE_MAX(sizeof(struct pipeline_msg_req), + sizeof(struct pipeline_msg_rsp)); + + return calloc(1, size); +} + +static void +pipeline_msg_free(struct pipeline_msg_rsp *rsp) +{ + free(rsp); +} + +static struct pipeline_msg_rsp * +pipeline_msg_send_recv(struct pipeline *p, + struct pipeline_msg_req *req) +{ + struct rte_ring *msgq_req = p->msgq_req; + struct rte_ring *msgq_rsp = p->msgq_rsp; + struct pipeline_msg_rsp *rsp; + int status; + + /* send */ + do { + status = rte_ring_sp_enqueue(msgq_req, req); + } while (status == -ENOBUFS); + + /* recv */ + do { + status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp); + } while (status != 0); + + return rsp; +} + +int +pipeline_port_in_enable(const char *pipeline_name, + uint32_t port_id) +{ + struct pipeline *p; + struct pipeline_msg_req *req; + struct pipeline_msg_rsp *rsp; + int status; + + /* Check input params */ + if (pipeline_name == NULL) + return -1; + + p = pipeline_find(pipeline_name); + if ((p == NULL) || + (p->enabled == 0) || + (port_id >= p->n_ports_in)) + return -1; + + /* Allocate request */ + req = pipeline_msg_alloc(); + if (req == NULL) + return -1; + + /* Write request */ + req->type = PIPELINE_REQ_PORT_IN_ENABLE; + req->id = port_id; + + /* Send request and wait for response */ + rsp = pipeline_msg_send_recv(p, req); + if (rsp == NULL) + return -1; + + /* Read response */ + status = rsp->status; + + /* Free response */ + pipeline_msg_free(rsp); + + return status; +} + +int +pipeline_port_in_disable(const char *pipeline_name, + uint32_t port_id) +{ + struct pipeline *p; + struct pipeline_msg_req *req; + struct pipeline_msg_rsp *rsp; + int status; + + /* Check input params */ + if (pipeline_name == NULL) + return -1; + + p = pipeline_find(pipeline_name); + if ((p == NULL) || + (p->enabled == 0) || + (port_id >= p->n_ports_in)) + return -1; + + /* Allocate request */ + req = pipeline_msg_alloc(); + if (req == NULL) + return -1; + + /* Write request */ + req->type = PIPELINE_REQ_PORT_IN_DISABLE; + req->id = port_id; + + /* Send request and wait for response */ + rsp = pipeline_msg_send_recv(p, req); + if (rsp == NULL) + return -1; + + /* Read response */ + status = rsp->status; + + /* Free response */ + pipeline_msg_free(rsp); + + return status; +} + + /** * Data plane threads: message handling */ @@ -517,6 +646,32 @@ pipeline_msg_send(struct rte_ring *msgq_rsp, } while (status == -ENOBUFS); } +static struct pipeline_msg_rsp * +pipeline_msg_handle_port_in_enable(struct pipeline_data *p, + struct pipeline_msg_req *req) +{ + struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req; + uint32_t port_id = req->id; + + rsp->status = rte_pipeline_port_in_enable(p->p, + port_id); + + return rsp; +} + +static struct pipeline_msg_rsp * +pipeline_msg_handle_port_in_disable(struct pipeline_data *p, + struct pipeline_msg_req *req) +{ + struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req; + uint32_t port_id = req->id; + + rsp->status = rte_pipeline_port_in_disable(p->p, + port_id); + + return rsp; +} + static void pipeline_msg_handle(struct pipeline_data *p) { @@ -529,6 +684,14 @@ pipeline_msg_handle(struct pipeline_data *p) break; switch (req->type) { + case PIPELINE_REQ_PORT_IN_ENABLE: + rsp = pipeline_msg_handle_port_in_enable(p, req); + break; + + case PIPELINE_REQ_PORT_IN_DISABLE: + rsp = pipeline_msg_handle_port_in_disable(p, req); + break; + default: rsp = (struct pipeline_msg_rsp *) req; rsp->status = -1; -- 2.20.1