[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 04/15] plat/driver: Create a tap dev during configuration
The patch creates a tap device while configuring the net device. Signed-off-by: Sharan Santhanam <sharan.santhanam@xxxxxxxxx> --- plat/drivers/tap/tap.c | 92 ++++++++++++++++++++++++++++++- plat/linuxu/Makefile.uk | 1 + plat/linuxu/include/linuxu/syscall.h | 27 +++++++++ plat/linuxu/include/linuxu/tap.h | 103 +++++++++++++++++++++++++++++++++++ plat/linuxu/tap_io.c | 67 +++++++++++++++++++++++ 5 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 plat/linuxu/tap_io.c diff --git a/plat/drivers/tap/tap.c b/plat/drivers/tap/tap.c index 2f49788..8c10502 100644 --- a/plat/drivers/tap/tap.c +++ b/plat/drivers/tap/tap.c @@ -67,18 +67,41 @@ #define to_tapnetdev(dev) \ __containerof(dev, struct tap_net_dev, ndev) +struct uk_netdev_tx_queue { + int queue_id; + UK_TAILQ_ENTRY(struct uk_netdev_tx_queue) next; + struct uk_alloc *a; + /* Set the file descriptor for the tap device */ + int fd; +}; + +struct uk_netdev_rx_queue { + int queue_id; + UK_TAILQ_ENTRY(struct uk_netdev_rx_queue) next; + struct uk_alloc *a; + /* Set the file descriptor for the tap device */ + int fd; +}; + struct tap_net_dev { /* Net device structure */ struct uk_netdev ndev; /* max number of queues */ __u16 max_qpairs; /* Number of rxq configured */ + __u16 rxq_cnt; + UK_TAILQ_HEAD(tap_rxqs, struct uk_netdev_rx_queue) rxqs; + /* Number of txq configured */ + __u16 txq_cnt; + UK_TAILQ_HEAD(tap_txqs, struct uk_netdev_tx_queue) txqs; /* The list of the tap device */ UK_TAILQ_ENTRY(struct tap_net_dev) next; /* UK Netdevice identifier */ __u16 tid; /* UK Netdevice identifier */ __u16 id; + /* File Descriptor for the tap device */ + int tap_fd; /* Name of the character device */ char name[IFNAMSIZ]; /* MTU of the device */ @@ -140,6 +163,7 @@ static int tap_netdev_rxq_info_get(struct uk_netdev *dev, __u16 queue_id, struct uk_netdev_queue_info *qinfo); static int tap_netdev_txq_info_get(struct uk_netdev *dev, __u16 queue_id, struct uk_netdev_queue_info *qinfo); +static int tap_device_create(struct tap_net_dev *tdev, __u32 feature_flags); /** * Local function definitions @@ -223,6 +247,10 @@ static void tap_netdev_info_get(struct uk_netdev *dev __unused, struct uk_netdev_info *dev_info) { UK_ASSERT(dev_info); + dev_info->max_rx_queues = 1; + dev_info->max_tx_queues = 1; + dev_info->nb_encap_tx = 0; + dev_info->nb_encap_rx = 0; } static unsigned int tap_netdev_promisc_get(struct uk_netdev *n) @@ -266,10 +294,72 @@ static int tap_netdev_mac_set(struct uk_netdev *n, static int tap_netdev_configure(struct uk_netdev *n, const struct uk_netdev_conf *conf) { - int rc = -EINVAL; + int rc = 0; + struct tap_net_dev *tdev = NULL; + __u32 feature_flag = 0; UK_ASSERT(n && conf); + tdev = to_tapnetdev(n); + + if (conf->nb_rx_queues > tdev->max_qpairs + || conf->nb_tx_queues > tdev->max_qpairs) { + uk_pr_err(DRIVER_NAME": rx-queue:%d, tx-queue:%d not supported", + conf->nb_rx_queues, conf->nb_tx_queues); + rc = -ENOTSUP; + goto exit; + } else if (conf->nb_rx_queues > 1 || conf->nb_tx_queues > 1) { + feature_flag = UK_IFF_MULTI_QUEUE; + } + + /* Open the device and set the interface */ + rc = tap_device_create(tdev, feature_flag); + if (rc < 0) { + uk_pr_err(DRIVER_NAME": Failed to configure the tap device\n"); + goto exit; + } + + /* Initialize the tx/rx queues */ + UK_TAILQ_INIT(&tdev->rxqs); + tdev->rxq_cnt = 0; + UK_TAILQ_INIT(&tdev->txqs); + tdev->txq_cnt = 0; +exit: return rc; +close_tap_dev: + tap_close(tdev->tap_fd); + goto exit; +} + +static int tap_device_create(struct tap_net_dev *tdev, __u32 feature_flags) +{ + int rc = 0; + struct uk_ifreq ifreq = {0}; + + /* Open the tap device */ + rc = tap_open(O_RDWR | O_NONBLOCK); + if (rc < 0) { + uk_pr_err(DRIVER_NAME": Failed(%d) to open the tap device\n", + rc); + goto exit; + } + + tdev->tap_fd = rc; + + rc = tap_dev_configure(tdev->tap_fd, feature_flags, &ifreq); + if (rc < 0) { + uk_pr_err(DRIVER_NAME": Failed to setup the tap device\n"); + goto close_tap; + } + + snprintf(tdev->name, sizeof(tdev->name), "%s", ifreq.ifr_name); + uk_pr_info(DRIVER_NAME": Configuring tap device %s\n", tdev->name); + +exit: + return rc; +close_tap: + tap_close(tdev->tap_fd); + tdev->tap_fd = -1; + goto exit; } static const struct uk_netdev_ops tap_netdev_ops = { diff --git a/plat/linuxu/Makefile.uk b/plat/linuxu/Makefile.uk index 561909e..2568d0d 100644 --- a/plat/linuxu/Makefile.uk +++ b/plat/linuxu/Makefile.uk @@ -45,6 +45,7 @@ LIBLINUXUPLAT_SRCS-y += $(LIBLINUXUPLAT_BASE)/time.c LIBLINUXUPLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/lcpu.c|common LIBLINUXUPLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/memory.c|common LIBLINUXUPLAT_SRCS-y += $(LIBLINUXUPLAT_BASE)/io.c +LIBLINUXUPLAT_SRCS-$(CONFIG_TAP_NET) += $(LIBLINUXUPLAT_BASE)/tap_io.c LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_X86_64) += \ $(LIBLINUXUPLAT_BASE)/x86/link64.lds.S LIBLINUXUPLAT_SRCS-$(CONFIG_ARCH_ARM_32) += \ diff --git a/plat/linuxu/include/linuxu/syscall.h b/plat/linuxu/include/linuxu/syscall.h index 0dca7c5..1604712 100644 --- a/plat/linuxu/include/linuxu/syscall.h +++ b/plat/linuxu/include/linuxu/syscall.h @@ -64,6 +64,33 @@ static inline ssize_t sys_write(int fd, const char *buf, size_t len) (long) (len)); } +#ifndef O_RDONLY +#define O_RDONLY 00000000 +#endif /* O_RDONLY */ + +#ifndef O_WRONLY +#define O_WRONLY 00000001 +#endif /* O_WRONLY */ +#ifndef O_RDWR +#define O_RDWR 00000002 +#endif /* O_RDWR */ + +#ifndef O_NONBLOCK +#define O_NONBLOCK 04000 +#endif /* O_NONBLOCK */ +static inline int sys_open(const char *pathname, int flags) +{ + return (ssize_t) syscall2(__SC_OPEN, + (long) pathname, + (long) flags); +} + +static inline int sys_close(int fd) +{ + return (ssize_t) syscall1(__SC_CLOSE, + (long) fd); +} + static inline int sys_exit(int status) { return (int) syscall1(__SC_EXIT, diff --git a/plat/linuxu/include/linuxu/tap.h b/plat/linuxu/include/linuxu/tap.h index 83116f5..a80c2b7 100644 --- a/plat/linuxu/include/linuxu/tap.h +++ b/plat/linuxu/include/linuxu/tap.h @@ -35,6 +35,13 @@ #define __TAP_H__ #include <uk/arch/types.h> +#include <linuxu/syscall.h> +#include <linuxu/ioctl.h> + +/** + * TAP Device Path + */ +#define TAPDEV_PATH "/dev/net/tun" /** * Using the musl as reference for the data structure definition @@ -42,4 +49,100 @@ */ #define IFNAMSIZ 16 +typedef __u16 uk_in_port_t; +typedef __u32 uk_in_addr_t; +typedef __u16 uk_sa_family_t; + +struct uk_in_addr { + uk_in_addr_t s_addr; +}; + +struct uk_sockaddr { + uk_sa_family_t sa_family; + char sa_data[14]; +}; + +struct uk_ifmap { + unsigned long int mem_start; + unsigned long int mem_end; + unsigned short int base_addr; + unsigned char irq; + unsigned char dma; + unsigned char port; +}; + +struct uk_ifreq { + union { + char ifrn_name[IFNAMSIZ]; + } uk_ifr_ifrn; + + union { + struct uk_sockaddr ifru_addr; + struct uk_sockaddr ifru_dstaddr; + struct uk_sockaddr ifru_broadaddr; + struct uk_sockaddr ifru_netmask; + struct uk_sockaddr ifru_hwaddr; + short int ifru_flags; + int ifru_ivalue; + int ifru_mtu; + struct uk_ifmap ifru_map; + char ifru_slave[IFNAMSIZ]; + char ifru_newname[IFNAMSIZ]; + char *ifru_data; + } uk_ifr_ifru; +}; + +#define ifr_name uk_ifr_ifrn.ifrn_name +#define ifr_hwaddr uk_ifr_ifru.ifru_hwaddr +#define ifr_addr uk_ifr_ifru.ifru_addr +#define ifr_dstaddr uk_ifr_ifru.ifru_dstaddr +#define ifr_broadaddr uk_ifr_ifru.ifru_broadaddr +#define ifr_netmask uk_ifr_ifru.ifru_netmask +#define ifr_flags uk_ifr_ifru.ifru_flags +#define ifr_metric uk_ifr_ifru.ifru_ivalue +#define ifr_mtu uk_ifr_ifru.ifru_mtu +#define ifr_map uk_ifr_ifru.ifru_map +#define ifr_slave uk_ifr_ifru.ifru_slave +#define ifr_data uk_ifr_ifru.ifru_data +#define ifr_ifindex uk_ifr_ifru.ifru_ivalue +#define ifr_bandwidth uk_ifr_ifru.ifru_ivalue +#define ifr_qlen uk_ifr_ifru.ifru_ivalue +#define ifr_newname uk_ifr_ifru.ifru_newname + +#define UK_TUNSETIFF (0x400454ca) +#define UK_SIOCGIFNAME (0x8910) +#define UK_SIOCGIFFLAGS (0x8913) +#define UK_SIOCSIFFLAGS (0x8914) +#define UK_SIOCGIFADDR (0x8915) +#define UK_SIOCSIFADDR (0x8916) +#define UK_SIOCGIFMTU (0x8921) +#define UK_SIOCSIFMTU (0x8922) +#define UK_SIOCSIFHWADDR (0x8924) +#define UK_SIOCGIFHWADDR (0x8927) +#define UK_SIOCGIFTXQLEN (0x8942) +#define UK_SIOCSIFTXQLEN (0x8943) +#define UK_SIOCGIFINDEX (0x8933) +/* TUNSETIFF ifr flags */ +#define UK_IFF_TUN (0x0001) +#define UK_IFF_TAP (0x0002) +#define UK_IFF_NO_PI (0x1000) +/* This flag has no real effect */ +#define UK_IFF_ONE_QUEUE (0x2000) +#define UK_IFF_VNET_HDR (0x4000) +#define UK_IFF_TUN_EXCL (0x8000) +#define UK_IFF_MULTI_QUEUE (0x0100) +#define UK_IFF_ATTACH_QUEUE (0x0200) +#define UK_IFF_DETACH_QUEUE (0x0400) +/* read-only flag */ +#define UK_IFF_PERSIST (0x0800) +#define UK_IFF_NOFILTER (0x1000) +#define UK_IFF_UP (0x1) +#define UK_IFF_PROMISC (0x100) + +/* Adding the bridge interface */ +#define UK_SIOCBRADDIF (0x89a2) + +int tap_open(__u32 flags); +int tap_close(int fd); +int tap_dev_configure(int fd, __u32 feature_flags, void *arg); #endif /* LINUXU_TAP_H */ diff --git a/plat/linuxu/tap_io.c b/plat/linuxu/tap_io.c new file mode 100644 index 0000000..a394134 --- /dev/null +++ b/plat/linuxu/tap_io.c @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Sharan Santhanam <sharan.santhanam@xxxxxxxxx> + * + * Copyright (c) 2019, 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. + * + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. + */ + +#include <errno.h> +#include <stdio.h> +#include <uk/print.h> +#include <uk/arch/types.h> +#include <linuxu/tap.h> + +int tap_open(__u32 flags) +{ + int rc = 0; + + rc = sys_open(TAPDEV_PATH, flags); + if (rc < 0) + uk_pr_err("Error in opening the tap device\n"); + return rc; +} + +int tap_dev_configure(int fd, __u32 feature_flags, void *arg) +{ + int rc = 0; + struct uk_ifreq *ifreq = (struct uk_ifreq *) arg; + + /* Set the tap device configuration */ + ifreq->ifr_flags = UK_IFF_TAP | UK_IFF_NO_PI | feature_flags; + if ((rc = sys_ioctl(fd, UK_TUNSETIFF, ifreq)) < 0) + uk_pr_err("Failed to tap device configure %d\n", rc); + + return rc; +} + +int tap_close(int fd) +{ + return sys_close(fd); +} -- 2.7.4 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |