[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v2 05/12] plat/xen/drivers/net: Configure netfront device
Netfront devices are configured using information provided by Xenstore. Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx> Signed-off-by: Razvan Cojocaru <razvan.cojocaru93@xxxxxxxxx> --- plat/xen/Makefile.uk | 1 + plat/xen/drivers/net/netfront.c | 100 ++++++++++++++++++ plat/xen/drivers/net/netfront.h | 66 ++++++++++++ plat/xen/drivers/net/netfront_xb.h | 43 ++++++++ plat/xen/drivers/net/netfront_xs.c | 205 +++++++++++++++++++++++++++++++++++++ 5 files changed, 415 insertions(+) create mode 100644 plat/xen/drivers/net/netfront.h create mode 100644 plat/xen/drivers/net/netfront_xb.h create mode 100644 plat/xen/drivers/net/netfront_xs.c diff --git a/plat/xen/Makefile.uk b/plat/xen/Makefile.uk index e920a13e..d64e939a 100644 --- a/plat/xen/Makefile.uk +++ b/plat/xen/Makefile.uk @@ -106,4 +106,5 @@ LIBXENNETFRONT_ASINCLUDES-y += $(LIBXENPLAT_ASINCLUDES-y) LIBXENNETFRONT_CFLAGS-y += $(LIBXENPLAT_CFLAGS-y) LIBXENNETFRONT_CINCLUDES-y += $(LIBXENPLAT_CINCLUDES-y) LIBXENNETFRONT_SRCS-y += $(LIBXENPLAT_BASE)/drivers/net/netfront.c +LIBXENNETFRONT_SRCS-y += $(LIBXENPLAT_BASE)/drivers/net/netfront_xs.c endif diff --git a/plat/xen/drivers/net/netfront.c b/plat/xen/drivers/net/netfront.c index 203ffeae..f6ec8497 100644 --- a/plat/xen/drivers/net/netfront.c +++ b/plat/xen/drivers/net/netfront.c @@ -33,21 +33,121 @@ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. */ +#include <uk/assert.h> +#include <uk/print.h> +#include <uk/alloc.h> +#include <uk/netdev_driver.h> #include <xenbus/xenbus.h> +#include "netfront.h" +#include "netfront_xb.h" #define DRIVER_NAME "xen-netfront" +#define to_netfront_dev(dev) \ + __containerof(dev, struct netfront_dev, netdev) + static struct uk_alloc *drv_allocator; +static const void *netfront_einfo_get(struct uk_netdev *n, + enum uk_netdev_einfo_type einfo_type) +{ + struct netfront_dev *nfdev; + + UK_ASSERT(n != NULL); + + nfdev = to_netfront_dev(n); + switch (einfo_type) { + case UK_NETDEV_IPV4_ADDR_STR: + return nfdev->econf.ipv4addr; + case UK_NETDEV_IPV4_MASK_STR: + return nfdev->econf.ipv4mask; + case UK_NETDEV_IPV4_GW_STR: + return nfdev->econf.ipv4gw; + default: + break; + } + + /* type not supported */ + return NULL; +} + +static const struct uk_hwaddr *netfront_mac_get(struct uk_netdev *n) +{ + struct netfront_dev *nfdev; + + UK_ASSERT(n != NULL); + nfdev = to_netfront_dev(n); + return &nfdev->hw_addr; +} + +static uint16_t netfront_mtu_get(struct uk_netdev *n) +{ + struct netfront_dev *nfdev; + + UK_ASSERT(n != NULL); + nfdev = to_netfront_dev(n); + return nfdev->mtu; +} + +static unsigned int netfront_promisc_get(struct uk_netdev *n) +{ + struct netfront_dev *nfdev; + + UK_ASSERT(n != NULL); + nfdev = to_netfront_dev(n); + return nfdev->promisc; +} + +static const struct uk_netdev_ops netfront_ops = { + .einfo_get = netfront_einfo_get, + .hwaddr_get = netfront_mac_get, + .mtu_get = netfront_mtu_get, + .promiscuous_get = netfront_promisc_get, +}; static int netfront_add_dev(struct xenbus_device *xendev) { + struct netfront_dev *nfdev; int rc = 0; UK_ASSERT(xendev != NULL); + nfdev = uk_calloc(drv_allocator, 1, sizeof(*nfdev)); + if (!nfdev) { + rc = -ENOMEM; + goto err_out; + } + + nfdev->xendev = xendev; + nfdev->mtu = ETH_PKT_PAYLOAD_LEN; + + /* Xenbus initialization */ + rc = netfront_xb_init(nfdev, drv_allocator); + if (rc) { + uk_pr_err("Error initializing Xenbus data: %d\n", rc); + goto err_xenbus; + } + + /* register netdev */ + nfdev->netdev.ops = &netfront_ops; + rc = uk_netdev_drv_register(&nfdev->netdev, drv_allocator, DRIVER_NAME); + if (rc < 0) { + uk_pr_err("Failed to register %s device with libuknetdev\n", + DRIVER_NAME); + goto err_register; + } + nfdev->uid = rc; + rc = 0; + +out: return rc; +err_register: + netfront_xb_fini(nfdev, drv_allocator); +err_xenbus: + uk_free(drv_allocator, nfdev); +err_out: + goto out; } static int netfront_drv_init(struct uk_alloc *allocator) diff --git a/plat/xen/drivers/net/netfront.h b/plat/xen/drivers/net/netfront.h new file mode 100644 index 00000000..362440f6 --- /dev/null +++ b/plat/xen/drivers/net/netfront.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Costin Lupu <costin.lupu@xxxxxxxxx> + * Razvan Cojocaru <razvan.cojocaru93@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. + */ + +#ifndef __NETFRONT_H__ +#define __NETFRONT_H__ + +#include <uk/netdev.h> + +struct xs_econf { + char *ipv4addr; + char *ipv4mask; + char *ipv4gw; +}; + +struct netfront_dev { + /* Xenbus device */ + struct xenbus_device *xendev; + /* Network device */ + struct uk_netdev netdev; + + /* Configuration parameters */ + struct xs_econf econf; + + /* The netdevice identifier */ + uint16_t uid; + /* The mtu */ + uint16_t mtu; + /* The hw address of the netdevice */ + struct uk_hwaddr hw_addr; + /* RX promiscuous mode. */ + uint8_t promisc : 1; +}; + +#endif /* __NETFRONT_H__ */ diff --git a/plat/xen/drivers/net/netfront_xb.h b/plat/xen/drivers/net/netfront_xb.h new file mode 100644 index 00000000..013c0e3c --- /dev/null +++ b/plat/xen/drivers/net/netfront_xb.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Costin Lupu <costin.lupu@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. + */ + +#ifndef __NETFRONT_XB_H__ +#define __NETFRONT_XB_H__ + +#include "netfront.h" + +int netfront_xb_init(struct netfront_dev *netdev, struct uk_alloc *a); +void netfront_xb_fini(struct netfront_dev *netdev, struct uk_alloc *a); + +#endif /* __NETFRONT_XB_H__ */ diff --git a/plat/xen/drivers/net/netfront_xs.c b/plat/xen/drivers/net/netfront_xs.c new file mode 100644 index 00000000..24a6e428 --- /dev/null +++ b/plat/xen/drivers/net/netfront_xs.c @@ -0,0 +1,205 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Costin Lupu <costin.lupu@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 <inttypes.h> +#include <stdio.h> +#include <string.h> +#include <uk/errptr.h> +#include <uk/print.h> +#include <uk/assert.h> +#include <xenbus/xs.h> +#include "netfront_xb.h" + + +static int xs_read_backend_id(const char *nodename, domid_t *domid) +{ + char path[strlen(nodename) + sizeof("/backend-id")]; + int value, rc; + + sprintf(path, "%s/backend-id", nodename); + + rc = xs_read_integer(XBT_NIL, path, &value); + if (!rc) + *domid = (domid_t) value; + + return rc; +} + +static void xs_econf_fini(struct xs_econf *econf, + struct uk_alloc *a) +{ + if (econf->ipv4addr) { + uk_free(a, econf->ipv4addr); + econf->ipv4addr = NULL; + } + if (econf->ipv4mask) { + uk_free(a, econf->ipv4mask); + econf->ipv4mask = NULL; + } + if (econf->ipv4gw) { + uk_free(a, econf->ipv4gw); + econf->ipv4gw = NULL; + } +} + +static int xs_econf_init(struct xs_econf *econf, char *ip_str, + struct uk_alloc *a) +{ + int rc = -1; + char *ip_addr = NULL, *ip_gw_str = NULL, *ip_mask_str = NULL; + + /* IP */ + ip_addr = strtok(ip_str, " "); + if (ip_addr == NULL) + goto out_err; + econf->ipv4addr = uk_malloc(a, strlen(ip_addr) + 1); + if (!econf->ipv4addr) { + uk_pr_err("Error allocating ip config.\n"); + goto out_err; + } + memcpy(econf->ipv4addr, ip_addr, strlen(ip_addr) + 1); + + /* Mask */ + ip_mask_str = strtok(NULL, " "); + if (ip_mask_str == NULL) + goto out_err; + econf->ipv4mask = uk_malloc(a, strlen(ip_mask_str) + 1); + if (!econf->ipv4mask) { + uk_pr_err("Error allocating ip mask config.\n"); + goto out_err; + } + memcpy(econf->ipv4mask, ip_mask_str, strlen(ip_mask_str) + 1); + + /* Gateway */ + ip_gw_str = strtok(NULL, " "); + if (ip_gw_str == NULL) + goto out_err; + econf->ipv4gw = uk_malloc(a, strlen(ip_gw_str) + 1); + if (!econf->ipv4gw) { + uk_pr_err("Error allocating ip gateway config.\n"); + goto out_err; + } + memcpy(econf->ipv4gw, ip_gw_str, strlen(ip_gw_str) + 1); + + rc = 0; +out: + return rc; +out_err: + xs_econf_fini(econf, a); + goto out; +} + +int netfront_xb_init(struct netfront_dev *nfdev, struct uk_alloc *a) +{ + struct xenbus_device *xendev; + char *mac_str, *p, *ip_str; + int rc; + + UK_ASSERT(nfdev != NULL); + + xendev = nfdev->xendev; + UK_ASSERT(xendev != NULL); + + rc = xs_read_backend_id(xendev->nodename, &xendev->otherend_id); + if (rc) + goto out; + + /* read backend path */ + xendev->otherend = xs_read(XBT_NIL, xendev->nodename, "backend"); + if (PTRISERR(xendev->otherend)) { + uk_pr_err("Error reading backend path.\n"); + rc = PTR2ERR(xendev->otherend); + xendev->otherend = NULL; + goto out; + } + + /* read MAC address */ + mac_str = xs_read(XBT_NIL, xendev->nodename, "mac"); + if (PTRISERR(mac_str)) { + uk_pr_err("Error reading MAC address.\n"); + rc = PTR2ERR(mac_str); + goto no_conf; + } + uk_pr_info("\tMAC %s\n", mac_str); + + p = mac_str; + for (int i = 0; i < UK_NETDEV_HWADDR_LEN; i++) { + nfdev->hw_addr.addr_bytes[i] = (uint8_t) strtoul(p, &p, 16); + p++; + } + free(mac_str); + + /* read IP address */ + ip_str = xs_read(XBT_NIL, xendev->otherend, "ip"); + if (PTRISERR(ip_str)) { + uk_pr_err("Error reading IP address.\n"); + rc = PTR2ERR(ip_str); + goto no_conf; + } + uk_pr_info("\tIP: %s\n", ip_str); + + rc = xs_econf_init(&nfdev->econf, ip_str, a); + if (rc) + goto no_conf; + free(ip_str); + + /* TODO spit event channels */ + + /* TODO netmap */ + +out: + return rc; +no_conf: + if (xendev->otherend) { + free(xendev->otherend); + xendev->otherend = NULL; + } + goto out; +} + +void netfront_xb_fini(struct netfront_dev *nfdev, struct uk_alloc *a) +{ + struct xenbus_device *xendev; + + UK_ASSERT(nfdev != NULL); + + xendev = nfdev->xendev; + UK_ASSERT(xendev != NULL); + + xs_econf_fini(&nfdev->econf, a); + + if (xendev->otherend) { + free(xendev->otherend); + xendev->otherend = NULL; + } +} -- 2.11.0 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |