[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