[dpdk-dev] [PATCH 1/3] bus/net: introduce net bus

Gaetan Rivet gaetan.rivet at 6wind.com
Thu Jun 1 12:44:31 CEST 2017


Signed-off-by: Gaetan Rivet <gaetan.rivet at 6wind.com>
---
 MAINTAINERS                                   |   6 +
 config/common_linuxapp                        |   2 +
 drivers/bus/Makefile                          |   2 +
 drivers/bus/net/Makefile                      |  66 +++++++
 drivers/bus/net/bsd/Makefile                  |  33 ++++
 drivers/bus/net/include/rte_bus_net.h         | 145 ++++++++++++++++
 drivers/bus/net/linux/Makefile                |  35 ++++
 drivers/bus/net/linux/rte_bus_net.c           | 237 ++++++++++++++++++++++++++
 drivers/bus/net/linux/rte_bus_net_version.map |   5 +
 drivers/bus/net/private.h                     | 143 ++++++++++++++++
 drivers/bus/net/rte_bus_net.c                 | 210 +++++++++++++++++++++++
 mk/rte.app.mk                                 |   1 +
 12 files changed, 885 insertions(+)
 create mode 100644 drivers/bus/net/Makefile
 create mode 100644 drivers/bus/net/bsd/Makefile
 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 9f9b81b..67288c4 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 <gaetan.rivet at 6wind.com>
+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/include/rte_bus_net.h b/drivers/bus/net/include/rte_bus_net.h
new file mode 100644
index 0000000..38b345e
--- /dev/null
+++ b/drivers/bus/net/include/rte_bus_net.h
@@ -0,0 +1,145 @@
+/*-
+ *   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 <sys/queue.h>
+#include <stdint.h>
+
+#include <rte_devargs.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+
+/**
+ * @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] name
+ *   kernel device name.
+ *
+ * @param[out] rte_name
+ *   DPDK device name.
+ *
+ * @param[in] size
+ *   size of rte_name.
+ *
+ * @return
+ *   0 for no error.
+ *   !0 otherwise.
+ */
+typedef int (*rte_bus_net_xfrm_t)(const char *name, char *rte_name, size_t size);
+
+/**
+ * Name transform base implementations.
+ */
+int rte_bus_net_virtual_xfrm(const char *name, char *rte_name, size_t size);
+int rte_bus_net_pci_xfrm(const char *name, char *rte_name, size_t size);
+
+/**
+ * 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. */
+	struct rte_driver *sh_drv; /**< Shadow 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_VERIFY(net_drv.xfrm); \
+	rte_net_register(&net_drv); \
+} \
+RTE_PMD_EXPORT_NAME(netdev_ ##nm, __COUNTER__)
+
+#define RTE_BUS_NET_VDEV_HEADER \
+	.xfrm = rte_bus_net_virtual_xfrm,
+
+#define RTE_BUS_NET_PCI_HEADER \
+	.xfrm = rte_bus_net_pci_xfrm,
+
+/**
+ * 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);
+
+#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..bd5c481
--- /dev/null
+++ b/drivers/bus/net/linux/rte_bus_net.c
@@ -0,0 +1,237 @@
+/*-
+ *   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 <string.h>
+#include <dirent.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include <linux/limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rte_bus.h>
+
+#include "rte_bus_net.h"
+#include "private.h"
+
+/* Default path */
+const char SYSFS_NET_DEVICES[] = "/sys/class/net";
+
+int
+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 (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;
+}
+
+static int
+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 -ENOMEM;
+	}
+	snprintf(dev->name, sizeof(dev->name), "%s", name);
+	if (!net_parse(dev->name, NULL))
+		INSERT_NET_DEVICE(dev);
+	return 0;
+}
+
+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;
+		ret = net_scan_one(e->d_name);
+		if (ret)
+			goto out;
+	}
+out:
+	closedir(dir);
+	return ret;
+}
+
+int
+net_dev_stat(const char *name)
+{
+	struct stat buf;
+	int err;
+	MKSTR(path, "%s/%s", net_get_sysfs_path(), name);
+
+	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
+net_dev_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
+net_dev_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..2b933d6
--- /dev/null
+++ b/drivers/bus/net/linux/rte_bus_net_version.map
@@ -0,0 +1,5 @@
+DPDK_17.08 {
+	global:
+
+	local: *;
+};
diff --git a/drivers/bus/net/private.h b/drivers/bus/net/private.h
new file mode 100644
index 0000000..4015ddf
--- /dev/null
+++ b/drivers/bus/net/private.h
@@ -0,0 +1,143 @@
+/*-
+ *   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 <sys/queue.h>
+
+#include <rte_bus.h>
+
+#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 sysfs. */
+int net_scan(void);
+
+/* Get netdev status. */
+int net_dev_stat(const char *name);
+
+/* Get netdev driver name. */
+int net_dev_driver(const char *name, char *out, size_t size);
+
+/* Get netdev pci location */
+int net_dev_pci_loc(const char *name, char *out, size_t size);
+
+/* 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_DRIVER(p) \
+	TAILQ_FOREACH(p, &(net_driver_list), next)
+
+/* 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 <stdio.h>
+#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..c8da7b2
--- /dev/null
+++ b/drivers/bus/net/rte_bus_net.c
@@ -0,0 +1,210 @@
+/*-
+ *   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 <string.h>
+
+#include <rte_devargs.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+
+#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 (net_dev_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_devargs *
+ */
+int
+net_parse(const char *name, void *addr)
+{
+	struct rte_devargs *out = addr;
+	struct rte_net_driver *drv = NULL;
+
+	if (net_dev_stat(name))
+		return 1;
+	if (addr == NULL)
+		return 0;
+	drv = net_drv_find(name);
+	if (drv) {
+		struct rte_devargs *da;
+
+		da = net_devargs_lookup(name);
+		if (drv->xfrm(name, out->name, sizeof(out->name)))
+			return 1;
+		out->args = da->args;
+		out->bus = rte_bus_from_dev(out->name);
+		return !out->bus;
+	}
+	/* no match ! */
+	return 1;
+}
+
+static int
+net_probe_one(struct rte_net_device *dev)
+{
+	struct rte_devargs *da;
+	struct rte_bus *bus;
+
+	da = calloc(1, sizeof(*da));
+	if (da == NULL) {
+		ERROR("failed to allocate devargs for device %s",
+		      dev->name);
+		return -1;
+	}
+	if (net_parse(dev->name, da)) {
+		ERROR("unable to find DPKD handler for device %s", dev->name);
+		return -1;
+	}
+	bus = da->bus;
+	if (bus->plug == NULL) {
+		ERROR("bus %s does not support plugin", bus->name);
+		return -1;
+	}
+	return bus->plug(da);
+}
+
+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)
+{
+	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 char *name, char *rte_name, size_t size)
+{
+	int ret;
+
+	ret = snprintf(rte_name, size, "net_tap_%s,iface=tap_%s,remote=%s",
+		       name, name, name);
+	return ret < 0 || ret > (int)size;
+}
+
+int
+rte_bus_net_pci_xfrm(const char *name, char *rte_name, size_t size)
+{
+	char buf[32] = "";
+	int ret;
+
+	ret = net_dev_pci_loc(name, buf, sizeof(buf));
+	if (ret)
+		return ret;
+	ret = snprintf(rte_name, size, "%s", buf);
+	return ret < 0 || ret > (int)size;
+}
+
+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 d476068..22e4222 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)
-- 
2.1.4



More information about the dev mailing list