From patchwork Thu Jun 8 00:00:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Ga=C3=ABtan_Rivet?= X-Patchwork-Id: 25156 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 867157CF5; Thu, 8 Jun 2017 02:01:17 +0200 (CEST) Received: from mail-wm0-f52.google.com (mail-wm0-f52.google.com [74.125.82.52]) by dpdk.org (Postfix) with ESMTP id 8CE867CF1 for ; Thu, 8 Jun 2017 02:01:14 +0200 (CEST) Received: by mail-wm0-f52.google.com with SMTP id 7so127795782wmo.1 for ; Wed, 07 Jun 2017 17:01:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=io9OsDeJjxNQ3AQxDzL2R7+mtECiy0DgXWQMeYI815g=; b=qYsON/NRxg00xXM7KZucZjPciLSe6DZObj11uIddgQHito2+lSfjC0TbKX49y4G1w5 +5xvDFGPOjzXqgmTW+lSA4dbS3F/hc+hGKyyRQZeNgS51TSoGaIzP/pB1nkKCf06H/C+ 69bt2nlM6NzaeGVvc6FV0Z/MqKl4FN87NFApMhvmBPVnvUtO1PNeKbIZ5mpAYaqzWYTr SzDqYIYKCYoRxEdZuQiE61byfbSj+3PYIQxF3Uj3SOhuAefVOXsdM9iJT3RBRg0ElgbU LjYrmaC9MdVXqBTT/iRBS+qXMxEbrmy9KoFz9vmp4/YdegJaoqBmWM1Njk7/pzVN0zWH ri1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=io9OsDeJjxNQ3AQxDzL2R7+mtECiy0DgXWQMeYI815g=; b=MkvwlQY86egRL2eOujYnmwsuCuw6ddrVOAvjXMwSyU8y5aj9A4GMdzqIBxi+vVMKSt u7ipwp7AP64arxwiPmwHs8dszjYqtO8HACsgI4jW/+T1eU0UTfaOZPKdV36iJKgXPo86 NUCUW97rKAgD7GjD197CziRIvBhBJJLAKTvcctbVjWuTm4W5BokmkJzl1OYCnOFPxsJh xeVTEhex4DHYEgZ33VBOtZbpziObVvNLqOX+PchO861yuypjqsWfzf1pUWCVvSo3E9df NAniBX4lmKTiJkMfKaro00cu8VxbfXJekBd9vLbA5sElcQJHWYegailDWJjZGDVvAcJS W77A== X-Gm-Message-State: AODbwcB6GKgM13KyHIMz8EVOWWEdQ+hl99+ATTCvcUm1487vGC7+wXEU OEF5yaDempjWJ3DGmks= X-Received: by 10.28.232.8 with SMTP id f8mr1320735wmh.51.1496880073249; Wed, 07 Jun 2017 17:01:13 -0700 (PDT) Received: from bidouze.dev.6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id y42sm4266707wrc.51.2017.06.07.17.01.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 07 Jun 2017 17:01:12 -0700 (PDT) From: Gaetan Rivet To: dev@dpdk.org Cc: Gaetan Rivet Date: Thu, 8 Jun 2017 02:00:58 +0200 Message-Id: X-Mailer: git-send-email 2.1.4 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH v2 1/4] bus/net: introduce net bus 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" Signed-off-by: Gaetan Rivet --- MAINTAINERS | 6 + config/common_linuxapp | 2 + drivers/bus/Makefile | 2 + drivers/bus/net/Makefile | 66 +++++++ drivers/bus/net/bsd/Makefile | 33 ++++ drivers/bus/net/bsd/rte_bus_net_version.map | 14 ++ drivers/bus/net/include/rte_bus_net.h | 205 ++++++++++++++++++++ drivers/bus/net/linux/Makefile | 35 ++++ drivers/bus/net/linux/rte_bus_net.c | 225 ++++++++++++++++++++++ drivers/bus/net/linux/rte_bus_net_version.map | 14 ++ drivers/bus/net/private.h | 144 ++++++++++++++ drivers/bus/net/rte_bus_net.c | 265 ++++++++++++++++++++++++++ mk/rte.app.mk | 1 + 13 files changed, 1012 insertions(+) create mode 100644 drivers/bus/net/Makefile create mode 100644 drivers/bus/net/bsd/Makefile create mode 100644 drivers/bus/net/bsd/rte_bus_net_version.map create mode 100644 drivers/bus/net/include/rte_bus_net.h create mode 100644 drivers/bus/net/linux/Makefile create mode 100644 drivers/bus/net/linux/rte_bus_net.c create mode 100644 drivers/bus/net/linux/rte_bus_net_version.map create mode 100644 drivers/bus/net/private.h create mode 100644 drivers/bus/net/rte_bus_net.c diff --git a/MAINTAINERS b/MAINTAINERS index 6d23022..c726322 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -253,6 +253,12 @@ F: lib/librte_eventdev/ F: drivers/event/skeleton/ F: test/test/test_eventdev.c +Bus Drivers +----------- + +Net +M: Gaetan Rivet +F: drivers/bus/net/ Networking Drivers ------------------ diff --git a/config/common_linuxapp b/config/common_linuxapp index cc85cc6..fe13f38 100644 --- a/config/common_linuxapp +++ b/config/common_linuxapp @@ -48,3 +48,5 @@ CONFIG_RTE_LIBRTE_AVP_PMD=y CONFIG_RTE_LIBRTE_NFP_PMD=y CONFIG_RTE_LIBRTE_POWER=y CONFIG_RTE_VIRTIO_USER=y +CONFIG_RTE_LIBRTE_NET_BUS=y +CONFIG_RTE_LIBRTE_NET_BUS_DEBUG=n diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index 1d1ddae..26cb9e2 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile @@ -37,5 +37,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc DEPDIRS-fslmc = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci DEPDIRS-pci = $(core-libs) +DIRS-$(CONFIG_RTE_LIBRTE_NET_BUS) += net +DEPDIRS-net = $(core-libs) pci include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/drivers/bus/net/Makefile b/drivers/bus/net/Makefile new file mode 100644 index 0000000..a643ab0 --- /dev/null +++ b/drivers/bus/net/Makefile @@ -0,0 +1,66 @@ +# BSD LICENSE +# +# Copyright(c) 2017 6WIND S.A. +# Author: Gaetan Rivet +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of 6WIND nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(RTE_SDK)/mk/rte.vars.mk + +LIB = librte_bus_net.a +LIBABIVER := 1 + +CFLAGS += $(WERROR_FLAGS) +ifeq ($(DEBUG),1) +CONFIG_RTE_LIBRTE_NET_BUS_DEBUG := y +endif +ifeq ($(CONFIG_RTE_LIBRTE_NET_BUS_DEBUG),y) +CFLAGS += -UNDEBUG -g -O0 +else +CFLAGS += -DNDEBUG -O3 +endif +CFLAGS += -I$(RTE_SDK)/drivers/bus/net +CFLAGS += -I$(RTE_SDK)/drivers/bus/net/include + +ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),) +SYSTEM := linux +endif +ifneq ($(CONFIG_RTE_EXEC_ENV_BDSAPP),) +SYSTEM := bsd +endif + +EXPORT_MAP := $(SYSTEM)/rte_bus_net_version.map +CFLAGS += -I$(RTE_SDK)/drivers/bus/net/$(SYSTEM) + +include $(RTE_SDK)/drivers/bus/net/$(SYSTEM)/Makefile +SRCS-$(CONFIG_RTE_LIBRTE_NET_BUS) := $(addprefix $(SYSTEM)/,$(SRCS)) +SRCS-$(CONFIG_RTE_LIBRTE_NET_BUS) += rte_bus_net.c + +SYMLINK-$(CONFIG_RTE_LIBRTE_PCI_BUS)-include += include/rte_bus_net.h + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/bus/net/bsd/Makefile b/drivers/bus/net/bsd/Makefile new file mode 100644 index 0000000..435ef57 --- /dev/null +++ b/drivers/bus/net/bsd/Makefile @@ -0,0 +1,33 @@ +# BSD LICENSE +# +# Copyright(c) 2017 6WIND S.A. +# Author: Gaetan Rivet +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of 6WIND nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +$(error Net BUS not supported on BSD yet) diff --git a/drivers/bus/net/bsd/rte_bus_net_version.map b/drivers/bus/net/bsd/rte_bus_net_version.map new file mode 100644 index 0000000..f0be361 --- /dev/null +++ b/drivers/bus/net/bsd/rte_bus_net_version.map @@ -0,0 +1,14 @@ +DPDK_17.08 { + global: + + rte_net_register; + rte_net_unregister; + rte_bus_net_dev_stat; + rte_bus_net_driver; + rte_bus_net_pci_loc; + rte_bus_net_virtual_xfrm; + rte_bus_net_pci_xfrm; + rte_bus_net_path_read; + + local: *; +}; diff --git a/drivers/bus/net/include/rte_bus_net.h b/drivers/bus/net/include/rte_bus_net.h new file mode 100644 index 0000000..3d960f8 --- /dev/null +++ b/drivers/bus/net/include/rte_bus_net.h @@ -0,0 +1,205 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2017 6WIND S.A. + * Author: Gaetan Rivet + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of 6WIND nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTE_NET_BUS_H_ +#define _RTE_NET_BUS_H_ + +#include +#include + +#include +#include +#include + +/** + * @file + * + * RTE Net bus. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Name of net bus. */ +#define RTE_BUS_NET_NAME "net" + +/** + * Structure describing an RTE net device. + */ +struct rte_net_device { + TAILQ_ENTRY(rte_net_device) next; /**< Next net device. */ + struct rte_device device; /**< Inherit core device. */ + struct rte_net_driver *driver; /**< Associated driver. */ + struct rte_devargs *da; /**< Device parameters. */ + struct rte_device *sh_dev; /**< Shadow device. */ + char name[33]; /**< Kernel netdev name. */ +}; + +/** + * Name transform callback. + * Transform a netdevice name into its DPDK counterpart. + * + * @param[in] src + * original devargs to transform. + * + * @param[out] dst + * rte_devargs resulting from the transformation. + * + * @return + * 0 for no error. + * !0 otherwise. + */ +typedef int (*rte_bus_net_xfrm_t)(const struct rte_devargs *src, + struct rte_devargs *dst); + +/** + * Name transform base implementations. + */ +int rte_bus_net_virtual_xfrm(const struct rte_devargs *src, + struct rte_devargs *dst); +int rte_bus_net_pci_xfrm(const struct rte_devargs *src, + struct rte_devargs *dst); + +/** + * Structure describing an RTE net driver. + */ +struct rte_net_driver { + TAILQ_ENTRY(rte_net_driver) next; /**< Next net driver. */ + struct rte_driver driver; /**< Inherit core driver. */ + char kmod[33]; /**< Kernel driver name. */ + rte_bus_net_xfrm_t xfrm; /**< Name transform. */ +}; + +/** + * Register a net driver. + * + * @param driver + * A pointer to an rte_net_driver structure describing the driver + * to be registered. + */ +void rte_net_register(struct rte_net_driver *driver); + +/** Helper for net device registration from driver instance. */ +#define RTE_PMD_REGISTER_NET(nm, net_drv) \ +RTE_INIT(netinitfn_ ##nm); \ +static void netinitfn_ ##nm(void) \ +{ \ + (net_drv).driver.name = RTE_STR(nm); \ + rte_net_register(&net_drv); \ +} \ +RTE_PMD_EXPORT_NAME(netdev_ ##nm, __COUNTER__) + +/** + * Unregister a net driver. + * + * @param driver + * A pointer to an rte_net_driver structure describing the driver + * to be unregistered. + */ +void rte_net_unregister(struct rte_net_driver *driver); + +/** + * Get netdevice status. + * + * @param name + * Net device name. + * + * @return + * 0 if device exist as a net device. + * !0 otherwise. + */ +int rte_bus_net_dev_stat(const char *name); + +/** + * Get netdevice driver name. + * + * @param[in] name + * Net device name. + * + * @param[out] out + * Buffer to write the driver name to. + * + * @param[in] size + * Buffer length. + * + * @return + * 0 if driver was successfully written. + * !0 otherwise. + */ +int rte_bus_net_driver(const char *name, char *out, size_t size); + +/** + * Get netdevice PCI location. + * + * @param[in] name + * Net device name. + * + * @param[out] out + * Buffer to write the PCI address to. + * + * @param[in] size + * Buffer length. + * + * @return + * 0 if PCI address was successfully written. + * !0 otherwise. + */ +int rte_bus_net_pci_loc(const char *name, char *out, size_t size); + +/** + * Read the content of a file. + * + * @param[out] out + * Buffer to write the content to. + * + * @param[in] size + * Buffer length. + * + * @param[in] format + * printf-like format string describing the path + * of the file to read. + * + * @return + * 0 if all was written successfully. + * !0 otherwise. errno is set. + */ +int rte_bus_net_path_read(char *out, size_t size, + const char *format, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_NET_BUS_H_ */ diff --git a/drivers/bus/net/linux/Makefile b/drivers/bus/net/linux/Makefile new file mode 100644 index 0000000..37af5fc --- /dev/null +++ b/drivers/bus/net/linux/Makefile @@ -0,0 +1,35 @@ +# BSD LICENSE +# +# Copyright(c) 2017 6WIND S.A. +# Author: Gaetan Rivet +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of 6WIND nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +SRCS += rte_bus_net.c + +CFLAGS += -D_GNU_SOURCE diff --git a/drivers/bus/net/linux/rte_bus_net.c b/drivers/bus/net/linux/rte_bus_net.c new file mode 100644 index 0000000..2d42ca9 --- /dev/null +++ b/drivers/bus/net/linux/rte_bus_net.c @@ -0,0 +1,225 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2017 6WIND S.A. + * Author: Gaetan Rivet + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of 6WIND nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "rte_bus_net.h" +#include "private.h" + +/* Default path */ +const char SYSFS_NET_DEVICES[] = "/sys/class/net"; + +int +rte_bus_net_path_read(char *out, size_t size, + const char *format, ...) +{ + va_list ap; + va_start(ap, format); + char path[vsnprintf(NULL, 0, format, ap) + 1]; + FILE *file; + int ret; + int err; + + va_end(ap); + va_start(ap, format); + vsnprintf(path, sizeof(path), format, ap); + file = fopen(path, "rb"); + if (file == NULL) { + ERROR("failed to open file %s (%s)", + path, strerror(errno)); + va_end(ap); + return -1; + } + ret = fread(out, size, 1, file); + err = errno; + if (((size_t)ret < size) && (ferror(file))) { + va_end(ap); + ret = -1; + } + fclose(file); + errno = err; + va_end(ap); + return ret; +} + +static int +parse_u32(const char *val, uint32_t *out) +{ + char *end; + uint64_t tmp; + + errno = 0; + tmp = strtoull(val, &end, 0); + if (errno != 0 || val[0] == '\0' || end == NULL) + return -EINVAL; + if (tmp > UINT32_MAX) + return -ERANGE; + *out = (uint32_t) tmp; + return 0; +} + +static uint32_t +dev_flags(const char *name) +{ + char buf[32] = ""; + uint32_t val; + + if (rte_bus_net_path_read(buf, sizeof(buf), "%s/%s/flags", + net_get_sysfs_path(), name)) { + ERROR("failed to read flags on device %s", name); + return 0; + } + if (parse_u32(buf, &val)) { + ERROR("failed to parse %s", buf); + return 0; + } + return val; +} + +int +net_scan(void) +{ + struct dirent *e; + DIR *dir; + const char *path; + int ret = 0; + int scan_blist = 0; + + path = net_get_sysfs_path(); + dir = opendir(path); + if (dir == NULL) { + ret = errno; + ERROR("opendir %s failed: %s", path, strerror(errno)); + return -1; + } + if (rte_bus_net.conf.scan_mode == RTE_BUS_SCAN_BLACKLIST) + scan_blist = 1; + while ((e = readdir(dir)) != NULL) { + if (e->d_name[0] == '.') + continue; + if (dev_flags(e->d_name) & 0x8) + continue; + if (scan_blist ^ + !net_devargs_lookup(e->d_name)) + continue; + /* Scan errors are ignored in blacklist mode. */ + if (!net_scan_one(e->d_name) && !scan_blist) + goto out; + } +out: + closedir(dir); + return ret; +} + +int +rte_bus_net_dev_stat(const char *name) +{ + struct stat buf; + int err; + MKSTR(path, "%s/%s", net_get_sysfs_path(), name); + + if (name[0] == '\0') + return -1; + snprintf(path, sizeof(path), "%s/%s", + net_get_sysfs_path(), name); + err = errno; + errno = 0; + if (stat(path, &buf)) { + if (errno != ENOENT) + ERROR("stat(%s) failed: %s", path, strerror(errno)); + errno = err; + return -1; + } + return 0; +} + +static int +link_read(const char *path, char *out, size_t size) +{ + struct stat buf; + int err; + + err = errno; + errno = 0; + if (stat(path, &buf)) { + if (errno != ENOENT) + ERROR("stat(%s) failed: %s", path, strerror(errno)); + errno = err; + return -1; + } + if (size > 0) { + char buf[PATH_MAX + 1] = ""; + ssize_t wlen; + char *s; + + wlen = readlink(path, buf, sizeof(buf) - 1); + if (wlen > 0) { + out[wlen] = '\0'; + } else { + ERROR("readlink(%s) failed: %s", path, + strerror(errno)); + errno = err; + return -1; + } + for (s = &buf[wlen]; *s != '/'; s--) + ; + snprintf(out, size, "%s", &s[1]); + } + return 0; +} + +int +rte_bus_net_driver(const char *name, char *out, size_t size) +{ + MKSTR(path, "%s/%s/device/driver", net_get_sysfs_path(), name); + + return link_read(path, out, size); +} + +int +rte_bus_net_pci_loc(const char *name, char *out, size_t size) +{ + MKSTR(path, "%s/%s/device", net_get_sysfs_path(), name); + + return link_read(path, out, size); +} diff --git a/drivers/bus/net/linux/rte_bus_net_version.map b/drivers/bus/net/linux/rte_bus_net_version.map new file mode 100644 index 0000000..f0be361 --- /dev/null +++ b/drivers/bus/net/linux/rte_bus_net_version.map @@ -0,0 +1,14 @@ +DPDK_17.08 { + global: + + rte_net_register; + rte_net_unregister; + rte_bus_net_dev_stat; + rte_bus_net_driver; + rte_bus_net_pci_loc; + rte_bus_net_virtual_xfrm; + rte_bus_net_pci_xfrm; + rte_bus_net_path_read; + + local: *; +}; diff --git a/drivers/bus/net/private.h b/drivers/bus/net/private.h new file mode 100644 index 0000000..f666b52 --- /dev/null +++ b/drivers/bus/net/private.h @@ -0,0 +1,144 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2017 6WIND S.A. + * Author: Gaetan Rivet + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of 6WIND nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _NET_PRIVATE_H_ +#define _NET_PRIVATE_H_ + +#include + +#include +#include + +#include "rte_bus_net.h" + +/* Double linked list of devices. */ +TAILQ_HEAD(net_device_list, rte_net_device); +/* Double linked list of drivers. */ +TAILQ_HEAD(net_driver_list, rte_net_driver); + +extern struct net_device_list net_device_list; +extern struct net_driver_list net_driver_list; + +/* Bus handle. */ +extern struct rte_bus rte_bus_net; + +/** Default net devices path. */ +extern const char SYSFS_NET_DEVICES[]; + +/* Find the rte_net_driver of a kernel device. */ +struct rte_net_driver *net_drv_find(const char *name); + +/* Parse device name. */ +int net_parse(const char *name, void *addr); + +/* Scan a single device. */ +struct rte_net_device *net_scan_one(const char *name); + +/* Scan sysfs. */ +int net_scan(void); + +/* Get sysfs path. */ +const char *net_get_sysfs_path(void); + +/* Find devargs of a device. */ +struct rte_devargs *net_devargs_lookup(const char *name); + +/* Read file content. */ +int path_read(char *out, size_t size, const char *format, ...) + __attribute__((format(printf, 3, 0))); + +/* Net Bus iterators. */ +#define FOREACH_NET_DEVICE(p) \ + TAILQ_FOREACH(p, &(net_device_list), next) + +#define FOREACH_NET_DEVICE_SAFE(p, tmp) \ + TAILQ_FOREACH_SAFE(p, &(net_device_list), next, tmp) + +#define FOREACH_NET_DRIVER(p) \ + TAILQ_FOREACH(p, &(net_driver_list), next) + +#define FOREACH_NET_DRIVER_SAFE(p, tmp) \ + TAILQ_FOREACH_SAFE(p, &(net_driver_list), next, tmp) + +/* Net lists operators. */ +#define INSERT_NET_DEVICE(dev) \ + TAILQ_INSERT_TAIL(&net_device_list, dev, next) + +#define REMOVE_NET_DEVICE(dev) \ + TAILQ_REMOVE(&net_device_list, dev, next) + +#define INSERT_NET_DRIVER(drv) \ + TAILQ_INSERT_TAIL(&net_driver_list, drv, next) + +#define REMOVE_NET_DRIVER(drv) \ + TAILQ_REMOVE(&net_driver_list, drv, next) + +/* Debugging */ +#ifndef NDEBUG +#include +#define DEBUG__(m, ...) \ + (fprintf(stderr, "%s:%d: %s(): " m "%c", \ + __FILE__, __LINE__, __func__, __VA_ARGS__), \ + fflush(stderr), \ + (void)0) +/* + * Save/restore errno around DEBUG__(). + * XXX somewhat undefined behavior, but works. + */ +#define DEBUG_(...) \ + (errno = ((int []){ \ + *(volatile int *)&errno, \ + (DEBUG__(__VA_ARGS__), 0) \ + })[0]) +#define DEBUG(...) DEBUG_(__VA_ARGS__, '\n') +#define INFO(...) DEBUG(__VA_ARGS__) +#define WARN(...) DEBUG(__VA_ARGS__) +#define ERROR(...) DEBUG(__VA_ARGS__) +#else /* NDEBUG */ +#define LOG__(level, m, ...) \ + RTE_LOG(level, EAL, "NET: " m "%c", __VA_ARGS__) +#define LOG_(level, ...) LOG__(level, __VA_ARGS__, '\n') +#define DEBUG(...) (void)0 +#define INFO(...) LOG_(INFO, __VA_ARGS__) +#define WARN(...) LOG_(WARNING, "WARNING: " __VA_ARGS__) +#define ERROR(...) LOG_(ERR, "ERROR: " __VA_ARGS__) +#endif /* NDEBUG */ + +/* Allocate a buffer on the stack and fill it with a printf format string. */ +#define MKSTR(name, ...) \ + char name[snprintf(NULL, 0, __VA_ARGS__) + 1]; \ + \ + snprintf(name, sizeof(name), __VA_ARGS__) + +#endif /* _NET_PRIVATE_H_ */ diff --git a/drivers/bus/net/rte_bus_net.c b/drivers/bus/net/rte_bus_net.c new file mode 100644 index 0000000..27a43f4 --- /dev/null +++ b/drivers/bus/net/rte_bus_net.c @@ -0,0 +1,265 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2017 6WIND S.A. + * Author: Gaetan Rivet + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of 6WIND nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include +#include +#include +#include + +#include "rte_bus_net.h" +#include "private.h" + +struct net_device_list net_device_list = + TAILQ_HEAD_INITIALIZER(net_device_list); +struct net_driver_list net_driver_list = + TAILQ_HEAD_INITIALIZER(net_driver_list); + +struct rte_devargs * +net_devargs_lookup(const char *name) +{ + struct rte_devargs *da; + + TAILQ_FOREACH(da, &devargs_list, next) { + if (da->bus != &rte_bus_net) + continue; + if (!strcmp(da->name, name)) + return da; + } + return NULL; +} + +struct rte_net_driver * +net_drv_find(const char *name) +{ + struct rte_net_driver *drv = NULL; + char drv_kmod[32] = ""; + + if (rte_bus_net_driver(name, drv_kmod, sizeof(drv_kmod))) + return NULL; + FOREACH_NET_DRIVER(drv) + if (!strcmp(drv->kmod, drv_kmod)) + break; + return drv; +} + +/* + * typeof(addr): struct rte_net_device * + */ +int +net_parse(const char *name, void *addr) +{ + struct rte_net_device *dev = addr; + struct rte_net_driver *drv = NULL; + struct rte_devargs devargs; + struct rte_devargs *da; + struct rte_devargs *sub; + + if (rte_bus_net_dev_stat(name)) + return 1; + if (addr == NULL) + return 0; + drv = net_drv_find(name); + if (drv == NULL) { + DEBUG("unable to find driver"); + rte_errno = EFAULT; + return -1; + } + dev->driver = drv; + da = dev->device.devargs; + if (!da) { + da = &devargs; + snprintf(da->name, sizeof(da->name), "%s", name); + da->args = NULL; + sub = calloc(1, sizeof(*sub)); + dev->device.name = sub->name; + } else { + sub = rte_eal_devargs_clone(da); + dev->device.name = da->name; + } + if (sub == NULL) { + DEBUG("unable to clone devargs"); + rte_errno = ENOMEM; + return -1; + } + dev->da = sub; + if (drv->xfrm(da, sub)) { + DEBUG("unable to parse device name"); + rte_errno = ENODEV; + return -1; + } + sub->bus = rte_bus_from_dev(sub->name); + return !sub->bus; +} + +struct rte_net_device * +net_scan_one(const char *name) +{ + struct rte_net_device *dev; + + dev = calloc(1, sizeof(*dev)); + if (dev == NULL) { + ERROR("failed to allocate memory"); + return NULL; + } + snprintf(dev->name, sizeof(dev->name), "%s", name); + dev->device.devargs = net_devargs_lookup(dev->name); + if (!net_parse(dev->name, dev)) { + INSERT_NET_DEVICE(dev); + return dev; + } + free(dev); + return NULL; +} + +static int +net_probe_one(struct rte_net_device *dev) +{ + struct rte_devargs *da; + struct rte_device *rdev; + struct rte_bus *bus; + int ret; + + da = dev->da; + bus = da->bus; + if (bus->plug == NULL) { + ERROR("bus %s does not support plugin", bus->name); + return -1; + } + rdev = bus->plug(da); + ret = rdev ? 0 : -rte_errno; + if (rdev) + dev->sh_dev = rdev; + return ret; +} + +static int +net_probe(void) +{ + struct rte_net_device *dev; + int ret; + + FOREACH_NET_DEVICE(dev) { + ret = net_probe_one(dev); + if (ret < 0) + return ret; + } + return 0; +} + +static struct rte_device * +net_find_device(int (*match)(const struct rte_device *dev, const void *data), + const void *data) +{ + struct rte_net_device *dev; + + FOREACH_NET_DEVICE(dev) + if (match(&dev->device, data)) + return &dev->device; + return NULL; +} + +void +rte_net_register(struct rte_net_driver *driver) +{ + if (driver->xfrm == NULL) + driver->xfrm = rte_bus_net_pci_xfrm; + INSERT_NET_DRIVER(driver); +} + +void +rte_net_unregister(struct rte_net_driver *driver) +{ + REMOVE_NET_DRIVER(driver); +} + +const char * +net_get_sysfs_path(void) +{ + const char *path = NULL; + + path = getenv("SYSFS_NET_DEVICES"); + if (path == NULL) + return SYSFS_NET_DEVICES; + return path; +} + +int +rte_bus_net_virtual_xfrm(const struct rte_devargs *src, + struct rte_devargs *dst) +{ + size_t argslen; + + /* dev name. */ + snprintf(dst->name, sizeof(dst->name), + "net_tap_%s", src->name); + /* dev args. */ + if (dst->args) + free(dst->args); + argslen = snprintf(NULL, 0, "iface=tap_%s,remote=%s,%s", + src->name, src->name, src->args) + 1; + dst->args = calloc(1, argslen); + if (dst->args == NULL) + return -1; + snprintf(dst->args, argslen, "iface=tap_%s,remote=%s,%s", + src->name, src->name, src->args); + return 0; +} + +int +rte_bus_net_pci_xfrm(const struct rte_devargs *src, + struct rte_devargs *dst) +{ + char buf[32] = ""; + int ret; + + ret = rte_bus_net_pci_loc(src->name, buf, sizeof(buf)); + if (ret) + return ret; + ret = snprintf(dst->name, sizeof(dst->name), "%s", buf); + dst->args = strdup(src->args); + return ret < 0 || ret > (int)sizeof(dst->name) || dst->args == NULL; +} + +struct rte_bus rte_bus_net = { + .scan = net_scan, + .probe = net_probe, + .find_device = net_find_device, + .parse = net_parse, + .conf = { + .scan_mode = RTE_BUS_SCAN_UNDEFINED, + }, +}; +RTE_REGISTER_BUS(RTE_BUS_NET_NAME, rte_bus_net); diff --git a/mk/rte.app.mk b/mk/rte.app.mk index d536a20..ad6a9c6 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -104,6 +104,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI) += -lrte_kni endif _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += -lrte_bus_pci +_LDLIBS-$(CONFIG_RTE_LIBRTE_NET_BUS) += -lrte_bus_net ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n) # plugins (link only if static libraries)