From: Jasvinder Singh Date: Thu, 29 Mar 2018 18:31:46 +0000 (+0100) Subject: examples/ip_pipeline: add KNI object X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=9a408cc8acc8808e237dceae4bedb7d1b66d3e94;p=dpdk.git examples/ip_pipeline: add KNI object Add kni object implementation to the application. Signed-off-by: Cristian Dumitrescu Signed-off-by: Jasvinder Singh Signed-off-by: Kevin Laatz --- diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile index 0f6bb786e4..dc56ebfbf6 100644 --- a/examples/ip_pipeline/Makefile +++ b/examples/ip_pipeline/Makefile @@ -7,6 +7,7 @@ APP = ip_pipeline # all source are stored in SRCS-y SRCS-y := cli.c SRCS-y += conn.c +SRCS-y += kni.c SRCS-y += link.c SRCS-y += main.c SRCS-y += mempool.c diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c index 430b49d801..522164835d 100644 --- a/examples/ip_pipeline/cli.c +++ b/examples/ip_pipeline/cli.c @@ -10,6 +10,7 @@ #include #include "cli.h" +#include "kni.h" #include "link.h" #include "mempool.h" #include "parser.h" @@ -630,6 +631,65 @@ cmd_tap(char **tokens, } } +/** + * kni + * link + * mempool + * [thread ] + */ +static void +cmd_kni(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size) +{ + struct kni_params p; + char *name; + struct kni *kni; + + if ((n_tokens != 6) && (n_tokens != 8)) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + name = tokens[1]; + + if (strcmp(tokens[2], "link") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "link"); + return; + } + + p.link_name = tokens[3]; + + if (strcmp(tokens[4], "mempool") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mempool"); + return; + } + + p.mempool_name = tokens[5]; + + if (n_tokens == 8) { + if (strcmp(tokens[6], "thread") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "thread"); + return; + } + + if (parser_read_uint32(&p.thread_id, tokens[7]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); + return; + } + + p.force_bind = 1; + } else + p.force_bind = 0; + + kni = kni_create(name, &p); + if (kni == NULL) { + snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); + return; + } +} + void cli_process(char *in, char *out, size_t out_size) { @@ -703,6 +763,11 @@ cli_process(char *in, char *out, size_t out_size) return; } + if (strcmp(tokens[0], "kni") == 0) { + cmd_kni(tokens, n_tokens, out, out_size); + return; + } + snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]); } diff --git a/examples/ip_pipeline/kni.c b/examples/ip_pipeline/kni.c new file mode 100644 index 0000000000..ebc8c7904e --- /dev/null +++ b/examples/ip_pipeline/kni.c @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2018 Intel Corporation + */ + +#include +#include + +#include +#include + +#include "kni.h" +#include "mempool.h" +#include "link.h" + +static struct kni_list kni_list; + +#ifndef KNI_MAX +#define KNI_MAX 16 +#endif + +int +kni_init(void) +{ + TAILQ_INIT(&kni_list); + +#ifdef RTE_LIBRTE_KNI + rte_kni_init(KNI_MAX); +#endif + + return 0; +} + +struct kni * +kni_find(const char *name) +{ + struct kni *kni; + + if (name == NULL) + return NULL; + + TAILQ_FOREACH(kni, &kni_list, node) + if (strcmp(kni->name, name) == 0) + return kni; + + return NULL; +} + +#ifndef RTE_LIBRTE_KNI + +struct kni * +kni_create(const char *name __rte_unused, + struct kni_params *params __rte_unused) +{ + return NULL; +} + +void +kni_handle_request(void) +{ + return; +} + +#else + +static int +kni_config_network_interface(uint16_t port_id, uint8_t if_up) +{ + int ret = 0; + + if (port_id >= rte_eth_dev_count()) + return -EINVAL; + + ret = (if_up) ? + rte_eth_dev_set_link_up(port_id) : + rte_eth_dev_set_link_down(port_id); + + return ret; +} + +static int +kni_change_mtu(uint16_t port_id, unsigned int new_mtu) +{ + int ret; + + if (port_id >= rte_eth_dev_count()) + return -EINVAL; + + if (new_mtu > ETHER_MAX_LEN) + return -EINVAL; + + /* Set new MTU */ + ret = rte_eth_dev_set_mtu(port_id, new_mtu); + if (ret < 0) + return ret; + + return 0; +} + +struct kni * +kni_create(const char *name, struct kni_params *params) +{ + struct rte_eth_dev_info dev_info; + struct rte_kni_conf kni_conf; + struct rte_kni_ops kni_ops; + struct kni *kni; + struct mempool *mempool; + struct link *link; + struct rte_kni *k; + + /* Check input params */ + if ((name == NULL) || + kni_find(name) || + (params == NULL)) + return NULL; + + mempool = mempool_find(params->mempool_name); + link = link_find(params->link_name); + if ((mempool == NULL) || + (link == NULL)) + return NULL; + + /* Resource create */ + rte_eth_dev_info_get(link->port_id, &dev_info); + + memset(&kni_conf, 0, sizeof(kni_conf)); + snprintf(kni_conf.name, RTE_KNI_NAMESIZE, "%s", name); + kni_conf.force_bind = params->force_bind; + kni_conf.core_id = params->thread_id; + kni_conf.group_id = link->port_id; + kni_conf.mbuf_size = mempool->buffer_size; + kni_conf.addr = dev_info.pci_dev->addr; + kni_conf.id = dev_info.pci_dev->id; + + memset(&kni_ops, 0, sizeof(kni_ops)); + kni_ops.port_id = link->port_id; + kni_ops.config_network_if = kni_config_network_interface; + kni_ops.change_mtu = kni_change_mtu; + + k = rte_kni_alloc(mempool->m, &kni_conf, &kni_ops); + if (k == NULL) + return NULL; + + /* Node allocation */ + kni = calloc(1, sizeof(struct kni)); + if (kni == NULL) + return NULL; + + /* Node fill in */ + strncpy(kni->name, name, sizeof(kni->name)); + kni->k = k; + + /* Node add to list */ + TAILQ_INSERT_TAIL(&kni_list, kni, node); + + return kni; +} + +void +kni_handle_request(void) +{ + struct kni *kni; + + TAILQ_FOREACH(kni, &kni_list, node) + rte_kni_handle_request(kni->k); +} + +#endif diff --git a/examples/ip_pipeline/kni.h b/examples/ip_pipeline/kni.h new file mode 100644 index 0000000000..c3856456d6 --- /dev/null +++ b/examples/ip_pipeline/kni.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2018 Intel Corporation + */ + +#ifndef _INCLUDE_KNI_H_ +#define _INCLUDE_KNI_H_ + +#include +#include + +#ifdef RTE_LIBRTE_KNI +#include +#endif + +#include "common.h" + +struct kni { + TAILQ_ENTRY(kni) node; + char name[NAME_SIZE]; +#ifdef RTE_LIBRTE_KNI + struct rte_kni *k; +#endif +}; + +TAILQ_HEAD(kni_list, kni); + +int +kni_init(void); + +struct kni * +kni_find(const char *name); + +struct kni_params { + const char *link_name; + const char *mempool_name; + int force_bind; + uint32_t thread_id; +}; + +struct kni * +kni_create(const char *name, struct kni_params *params); + +void +kni_handle_request(void); + +#endif /* _INCLUDE_KNI_H_ */ diff --git a/examples/ip_pipeline/main.c b/examples/ip_pipeline/main.c index 33c3354778..b65762e747 100644 --- a/examples/ip_pipeline/main.c +++ b/examples/ip_pipeline/main.c @@ -12,6 +12,7 @@ #include "cli.h" #include "conn.h" +#include "kni.h" #include "link.h" #include "mempool.h" #include "swq.h" @@ -199,6 +200,13 @@ main(int argc, char **argv) return status; } + /* KNI */ + status = kni_init(); + if (status) { + printf("Error: KNI initialization failed (%d)\n", status); + return status; + } + /* Script */ if (app.script_name) cli_script_process(app.script_name, @@ -210,5 +218,7 @@ main(int argc, char **argv) conn_poll_for_conn(conn); conn_poll_for_msg(conn); + + kni_handle_request(); } } diff --git a/examples/ip_pipeline/meson.build b/examples/ip_pipeline/meson.build index e87581126b..5ad79b28c4 100644 --- a/examples/ip_pipeline/meson.build +++ b/examples/ip_pipeline/meson.build @@ -10,6 +10,7 @@ deps += ['pipeline', 'bus_pci'] sources = files( 'cli.c', 'conn.c', + 'kni.c', 'link.c', 'main.c', 'mempool.c',