From patchwork Fri Mar 9 18:24:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jasvinder Singh X-Patchwork-Id: 35895 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id BA255AAF3; Fri, 9 Mar 2018 19:24:54 +0100 (CET) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id EB3685F5F for ; Fri, 9 Mar 2018 19:24:48 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Mar 2018 10:24:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,446,1515484800"; d="scan'208";a="181382326" Received: from silpixa00381635.ir.intel.com (HELO silpixa00381635.ger.corp.intel.com) ([10.237.222.149]) by orsmga004.jf.intel.com with ESMTP; 09 Mar 2018 10:24:47 -0800 From: Jasvinder Singh To: dev@dpdk.org Cc: cristian.dumitrescu@intel.com, Kevin Laatz Date: Fri, 9 Mar 2018 18:24:06 +0000 Message-Id: <20180309182426.135278-18-jasvinder.singh@intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20180309182426.135278-1-jasvinder.singh@intel.com> References: <20180309182426.135278-1-jasvinder.singh@intel.com> Subject: [dpdk-dev] [PATCH 17/37] ip_pipeline: add kni object X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add kni object implementation to the application. Signed-off-by: Cristian Dumitrescu Signed-off-by: Jasvinder Singh Signed-off-by: Kevin Laatz --- examples/ip_pipeline/Makefile | 1 + examples/ip_pipeline/cli.c | 65 +++++++++++++++ examples/ip_pipeline/kni.c | 165 +++++++++++++++++++++++++++++++++++++++ examples/ip_pipeline/kni.h | 44 +++++++++++ examples/ip_pipeline/main.c | 10 +++ examples/ip_pipeline/meson.build | 1 + 6 files changed, 286 insertions(+) create mode 100644 examples/ip_pipeline/kni.c create mode 100644 examples/ip_pipeline/kni.h diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile index 0f6bb78..dc56ebf 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 5dbd576..a5308bc 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 0000000..8a14aca --- /dev/null +++ b/examples/ip_pipeline/kni.c @@ -0,0 +1,165 @@ +/* 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 0; +} + +#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 0000000..e53de12 --- /dev/null +++ b/examples/ip_pipeline/kni.h @@ -0,0 +1,44 @@ +/* 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]; + struct rte_kni *k; +}; + +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 33c3354..b65762e 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 e875811..5ad79b2 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',