|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH v3 03/16] plat/driver: Add tap device to the uk_netdev
The patch provides the implementation to parse the user provided tap
device information. The tap device detected are registered to the
uk_netdev.
Signed-off-by: Sharan Santhanam <sharan.santhanam@xxxxxxxxx>
---
plat/drivers/include/tap/tap.h | 43 ++++++++++
plat/drivers/tap/tap.c | 140 +++++++++++++++++++++++++++++++++
plat/linuxu/Config.uk | 8 ++
plat/linuxu/Makefile.uk | 6 ++
4 files changed, 197 insertions(+)
create mode 100644 plat/drivers/include/tap/tap.h
diff --git a/plat/drivers/include/tap/tap.h b/plat/drivers/include/tap/tap.h
new file mode 100644
index 00000000..6786e7de
--- /dev/null
+++ b/plat/drivers/include/tap/tap.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Sharan Santhanam <sharan.santhanam@xxxxxxxxx>
+ *
+ * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the copyright holder 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 HOLDER 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 __PLAT_DRV_TAP_H
+#define __PLAT_DRV_TAP_H
+
+#include <uk/arch/types.h>
+
+/**
+ * Using the musl as reference for the data structure definition
+ * Commit-id: 39ef612aa193
+ */
+#define IFNAMSIZ 16
+
+#endif /* __PLAT_DRV_TAP_H */
diff --git a/plat/drivers/tap/tap.c b/plat/drivers/tap/tap.c
index 3435e846..f817c32a 100644
--- a/plat/drivers/tap/tap.c
+++ b/plat/drivers/tap/tap.c
@@ -31,23 +31,77 @@
*
*/
#include <errno.h>
+#include <string.h>
#include <uk/alloc.h>
#include <uk/arch/types.h>
#include <uk/netdev_core.h>
#include <uk/netdev_driver.h>
#include <uk/netbuf.h>
#include <uk/errptr.h>
+#include <uk/libparam.h>
#include <uk/bus.h>
+#include <tap/tap.h>
+
+#define DRIVER_NAME "tap-net"
+
+#define ETH_PKT_PAYLOAD_LEN 1500
+
+/**
+ * TODO: Find a better way of forwarding the command line argument to the
+ * driver. For now they are defined as macros from this driver.
+ */
+struct tap_net_dev {
+ /* Net device structure */
+ struct uk_netdev ndev;
+ /* max number of queues */
+ __u16 max_qpairs;
+ /* Number of rxq configured */
+ /* The list of the tap device */
+ UK_TAILQ_ENTRY(struct tap_net_dev) next;
+ /* Tap Device identifier */
+ __u16 tid;
+ /* UK Netdevice identifier */
+ __u16 id;
+ /* Name of the character device */
+ char name[IFNAMSIZ];
+ /* MTU of the device */
+ __u16 mtu;
+ /* RX promiscuous mode */
+ __u8 promisc : 1;
+ /* State of the net device */
+ __u8 state;
+};
struct tap_net_drv {
/* allocator to initialize the driver data structure */
struct uk_alloc *a;
+ /* list of tap device */
+ UK_TAILQ_HEAD(tdev_list, struct tap_net_dev) tap_dev_list;
+ /* Number of tap devices */
+ __u16 tap_dev_cnt;
+ /* A list of bridges associated with the bridge */
+ char **bridge_ifs;
};
/**
* Module level variables
*/
static struct tap_net_drv tap_drv = {0};
+static const char *drv_name = DRIVER_NAME;
+static int tap_dev_cnt;
+static char *bridgenames;
+
+/**
+ * Module Parameters.
+ */
+/**
+ * tap.tap_dev_cnt=<# of tap device>
+ */
+UK_LIB_PARAM(tap_dev_cnt, __u32);
+/**
+ * tap.bridgenames="br0 br1 ... brn"
+ */
+UK_LIB_PARAM_STR(bridgenames);
/**
* Module functions
@@ -226,6 +280,52 @@ static const struct uk_netdev_ops tap_netdev_ops = {
.rxq_info_get = tap_netdev_rxq_info_get,
};
+/**
+ * Registering the network device.
+ */
+static int tap_dev_init(int id)
+{
+ struct tap_net_dev *tdev;
+ int rc = 0;
+
+ tdev = uk_zalloc(tap_drv.a, sizeof(*tdev));
+ if (!tdev) {
+ uk_pr_err(DRIVER_NAME": Failed to allocate tap_device\n");
+ rc = -ENOMEM;
+ goto exit;
+ }
+ tdev->ndev.rx_one = tap_netdev_recv;
+ tdev->ndev.tx_one = tap_netdev_xmit;
+ tdev->ndev.ops = &tap_netdev_ops;
+ tdev->tid = id;
+ /**
+ * TODO:
+ * As an initial implementation we have limit on the number of queues.
+ */
+ tdev->max_qpairs = 1;
+
+ /* Registering the tap device with libuknet*/
+ rc = uk_netdev_drv_register(&tdev->ndev, tap_drv.a, drv_name);
+ if (rc < 0) {
+ uk_pr_err(DRIVER_NAME": Failed to register the network
device\n");
+ goto free_tdev;
+ }
+ tdev->id = rc;
+ rc = 0;
+ tdev->mtu = ETH_PKT_PAYLOAD_LEN;
+ tdev->promisc = 0;
+ uk_pr_info(DRIVER_NAME": device(%d) registered with the libuknet\n",
+ tdev->id);
+
+ /* Adding the list of devices maintained by this driver */
+ UK_TAILQ_INSERT_TAIL(&tap_drv.tap_dev_list, tdev, next);
+exit:
+ return rc;
+free_tdev:
+ uk_free(tap_drv.a, tdev);
+ goto exit;
+}
+
/**
* Register a tap driver as bus. Currently in Unikraft, the uk_bus interface
* provides the necessary to provide callbacks for bring a pseudo device. In
the
@@ -233,12 +333,52 @@ static const struct uk_netdev_ops tap_netdev_ops = {
*/
static int tap_drv_probe(void)
{
+ int i;
+ int rc = 0;
+ char *idx = NULL, *prev_idx;
+
+ if (tap_dev_cnt > 0) {
+ tap_drv.bridge_ifs = uk_calloc(tap_drv.a, tap_dev_cnt,
+ sizeof(char *));
+ if (!tap_drv.bridge_ifs) {
+ uk_pr_err(DRIVER_NAME": Failed to allocate
brigde_ifs\n");
+ return -ENOMEM;
+ }
+ }
+
+ idx = bridgenames;
+ for (i = 0; i < tap_dev_cnt; i++) {
+ if (idx) {
+ prev_idx = idx;
+ idx = strchr(idx, ' ');
+ if (idx) {
+ *idx = '\0';
+ idx++;
+ }
+ tap_drv.bridge_ifs[i] = prev_idx;
+ uk_pr_debug(DRIVER_NAME": Adding bridge %s\n",
+ prev_idx);
+ } else {
+ uk_pr_warn(DRIVER_NAME": Adding tap device %d without
bridge\n",
+ i);
+ tap_drv.bridge_ifs[i] = NULL;
+ }
+
+ rc = tap_dev_init(i);
+ if (rc < 0) {
+ uk_pr_err(DRIVER_NAME": Failed to initialize the tap
dev id: %d\n",
+ i);
+ return rc;
+ }
+ tap_drv.tap_dev_cnt++;
+ }
return 0;
}
static int tap_drv_init(struct uk_alloc *_a)
{
tap_drv.a = _a;
+ UK_TAILQ_INIT(&tap_drv.tap_dev_list);
return 0;
}
diff --git a/plat/linuxu/Config.uk b/plat/linuxu/Config.uk
index 3900e8bc..9de0364a 100644
--- a/plat/linuxu/Config.uk
+++ b/plat/linuxu/Config.uk
@@ -23,8 +23,16 @@ if (PLAT_LINUXU)
default y if LIBUKNETDEV
depends on LIBUKNETDEV
select LIBUKBUS
+ imply LIBUKLIBPARAM
help
Enable drivers to support tap device on the linuxu platform. The
driver implements the uknetdev interface and provides an
interface
for the network stack to send/receive network packets.
+
+ config TAP_DEV_DEBUG
+ bool "Tap Device Debug"
+ default n
+ depends on TAP_NET
+ help
+ Enable debug messages from the tap device.
endif
diff --git a/plat/linuxu/Makefile.uk b/plat/linuxu/Makefile.uk
index 0850fd99..cdb7cd00 100644
--- a/plat/linuxu/Makefile.uk
+++ b/plat/linuxu/Makefile.uk
@@ -11,6 +11,8 @@ $(eval $(call
addplatlib_s,linuxu,liblinuxutapnet,$(CONFIG_TAP_NET)))
## Adding libparam for the linuxu platform
$(eval $(call addlib_paramprefix,liblinuxuplat,linuxu))
+$(eval $(call addlib_paramprefix,liblinuxutapnet,tap))
+
##
## Platform library definitions
##
@@ -51,6 +53,10 @@ LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_ARM_32) += \
##
## LINUXUTAPNET Source
LIBLINUXUTAPNET_ASINCLUED-y += -I$(LIBLINUXUPLAT_BASE)/include
+LIBLINUXUTAPNET_ASINCLUDES-y += -I$(UK_PLAT_DRIVERS_BASE)/include
LIBLINUXUTAPNET_CINCLUDES-y += -I$(LIBLINUXUPLAT_BASE)/include
+LIBLINUXUTAPNET_CINCLUDES-y += -I$(UK_PLAT_DRIVERS_BASE)/include
+
+LIBLINUXUTAPNET_CFLAGS-$(CONFIG_TAP_DEV_DEBUG) += -DUK_DEBUG
LIBLINUXUTAPNET_SRCS-y += $(UK_PLAT_DRIVERS_BASE)/tap/tap.c
--
2.20.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |