[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[UNIKRAFT/LIBLWIP 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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.