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

Re: [Minios-devel] [UNIKRAFT PATCH 05/15] plat/tap: Get/Set hw_addr



Hi Sharan,


See inline.


Roxana

On 10/7/19 12:46 PM, Sharan Santhanam wrote:
The patch implements support for generating a default hw_addr. The
patch also implements get and set netdev api.

I think the message should specify the creation of the control socket and the introduction of `netif_configure` function,

since these are really important in the next patches.

Or maybe split the patch in two, what do you think?

Signed-off-by: Sharan Santhanam<sharan.santhanam@xxxxxxxxx>
---
  plat/drivers/tap/tap.c                      | 89 ++++++++++++++++++++++++++++-
  plat/linuxu/include/linuxu/syscall-arm_32.h |  1 +
  plat/linuxu/include/linuxu/syscall-x86_64.h |  1 +
  plat/linuxu/include/linuxu/syscall.h        | 25 ++++++++
  plat/linuxu/include/linuxu/tap.h            |  9 +++
  plat/linuxu/tap_io.c                        | 42 ++++++++++++++
  6 files changed, 165 insertions(+), 2 deletions(-)

diff --git a/plat/drivers/tap/tap.c b/plat/drivers/tap/tap.c
index 8c10502..cfee936 100644
--- a/plat/drivers/tap/tap.c
+++ b/plat/drivers/tap/tap.c
@@ -96,12 +96,16 @@ struct tap_net_dev {
        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;
+       /* Mac address of the device */
+       struct uk_hwaddr hw_addr;
        /* UK Netdevice identifier */
        __u16 tid;
        /* UK Netdevice identifier */
        __u16 id;
        /* File Descriptor for the tap device */
        int tap_fd;
+       /* Control socket descriptor */
+       int ctrl_sock;
        /* Name of the character device */
        char name[IFNAMSIZ];
        /* MTU of the device */
@@ -164,6 +168,7 @@ static int tap_netdev_rxq_info_get(struct uk_netdev *dev, 
__u16 queue_id,
  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);
+static int tap_mac_generate(__u8 *addr, int len, int dev_id);
/**
   * Local function definitions
@@ -278,16 +283,76 @@ static int tap_netdev_mtu_set(struct uk_netdev *n,  __u16 
mtu __unused)
static const struct uk_hwaddr *tap_netdev_mac_get(struct uk_netdev *n)
  {
+       struct tap_net_dev *tdev;
+
        UK_ASSERT(n);
-       return NULL;
+       tdev = to_tapnetdev(n);
+       return &tdev->hw_addr;
  }
static int tap_netdev_mac_set(struct uk_netdev *n,
                              const struct uk_hwaddr *hwaddr)
  {
-       int rc = -EINVAL;
+       int rc = 0;
+       struct tap_net_dev *tdev;
+       struct uk_ifreq ifrq = {0};
UK_ASSERT(n && hwaddr);
+       tdev = to_tapnetdev(n);
+
+       snprintf(ifrq.ifr_name, sizeof(ifrq.ifr_name), "%s", tdev->name);
+       uk_pr_info("Setting mac address on tap device %s\n", tdev->name);
+
+#ifdef CONFIG_TAP_DEV_DEBUG
+       int  i;
Get rid off the checkpatch warning caused by this variable.
+       for (i = 0; i < UK_NETDEV_HWADDR_LEN; i++) {
+               uk_pr_debug("hw_address: %d - %d\n", i,
+                           hwaddr->addr_bytes[i] & 0xFF);
+       }
+#endif /* CONFIG_TAP_DEV_DEBUG */
+
+       ifrq.ifr_hwaddr.sa_family = AF_LOCAL;
+       memcpy(&ifrq.ifr_hwaddr.sa_data[0], &hwaddr->addr_bytes[0],
+               UK_NETDEV_HWADDR_LEN);
+       rc = tap_netif_configure(tdev->ctrl_sock, UK_SIOCSIFHWADDR, &ifrq);
+       if (rc < 0) {
+               uk_pr_err(DRIVER_NAME": Failed(%d) to set the hardware 
address\n",
+                         rc);
+               goto exit;
+       }
+       memcpy(&tdev->hw_addr, hwaddr, sizeof(*hwaddr));
+
+exit:
+       return rc;
+}
+
+static int tap_mac_generate(__u8 *addr, int len, int dev_id)
+{
+       const char fmt[] = {0x2, 0x0, 0x0, 0x0, 0x0, 0x0};
+
+       UK_ASSERT(addr && len > 0);
+
+       if (len < UK_NETDEV_HWADDR_LEN) {
+               uk_pr_err("Failed to generate the mac address\n");
+               return -ENOSPC;
+       }git@xxxxxxxxx-net:sys/unikraft/libs/lwip.git
+       memcpy(addr, fmt, UK_NETDEV_HWADDR_LEN - 1);
+       *(addr + UK_NETDEV_HWADDR_LEN - 1) = (__u8) (dev_id + 1);
+       return 0;
+}
+
+static int tapdev_ctrlsock_create(struct tap_net_dev *tdev)
+{
+       int rc = 0;
+
+       rc = sys_socket(AF_INET, SOCK_DGRAM, 0);
+       if (rc < 0) {
+               uk_pr_err(DRIVER_NAME": Failed to create a control socket\n");
+               goto exit;
+       }
+       tdev->ctrl_sock = rc;
+       rc = 0;
+exit:
        return rc;
  }
@@ -318,6 +383,24 @@ static int tap_netdev_configure(struct uk_netdev *n,
                goto exit;
        }
+ /* Create a control socket for the network interface */
+       rc = tapdev_ctrlsock_create(tdev);
+       if (rc != 0) {
+               uk_pr_err(DRIVER_NAME": Failed to create a control socket\n");
+               goto close_tap_dev;
+       }
+
+       /* Generate MAC address */
+       tap_mac_generate(&tdev->hw_addr.addr_bytes[0], UK_NETDEV_HWADDR_LEN,
+                        tdev->id);
+
+       /* MAC Address configuration */
+       rc = tap_netdev_mac_set(n, &tdev->hw_addr);
+       if (rc < 0) {
+               uk_pr_err(DRIVER_NAME": Failed to set the mac address\n");
+               goto close_ctrl_sock;
+       }
+
        /* Initialize the tx/rx queues */
        UK_TAILQ_INIT(&tdev->rxqs);
        tdev->rxq_cnt = 0;
@@ -325,6 +408,8 @@ static int tap_netdev_configure(struct uk_netdev *n,
        tdev->txq_cnt = 0;
  exit:
        return rc;
+close_ctrl_sock:
+       tap_close(tdev->ctrl_sock);
  close_tap_dev:
        tap_close(tdev->tap_fd);
        goto exit;
diff --git a/plat/linuxu/include/linuxu/syscall-arm_32.h 
b/plat/linuxu/include/linuxu/syscall-arm_32.h
index ef9323b..1ed9e84 100644
--- a/plat/linuxu/include/linuxu/syscall-arm_32.h
+++ b/plat/linuxu/include/linuxu/syscall-arm_32.h
@@ -55,6 +55,7 @@
  #define __SC_TIMER_GETOVERRUN 260
  #define __SC_TIMER_DELETE     261
  #define __SC_CLOCK_GETTIME    263
+#define __SC_SOCKET           281
  #define __SC_PSELECT6 335
/* NOTE: from `man syscall`:
diff --git a/plat/linuxu/include/linuxu/syscall-x86_64.h 
b/plat/linuxu/include/linuxu/syscall-x86_64.h
index 553f0ba..950abd8 100644
--- a/plat/linuxu/include/linuxu/syscall-x86_64.h
+++ b/plat/linuxu/include/linuxu/syscall-x86_64.h
@@ -47,6 +47,7 @@
  #define __SC_RT_SIGACTION   13
  #define __SC_RT_SIGPROCMASK 14
  #define __SC_IOCTL  16
+#define __SC_SOCKET 41
  #define __SC_EXIT   60
  #define __SC_ARCH_PRCTL       158
  #define __SC_TIMER_CREATE     222
diff --git a/plat/linuxu/include/linuxu/syscall.h 
b/plat/linuxu/include/linuxu/syscall.h
index 1604712..71e2def 100644
--- a/plat/linuxu/include/linuxu/syscall.h
+++ b/plat/linuxu/include/linuxu/syscall.h
@@ -91,6 +91,31 @@ static inline int sys_close(int fd)
                                  (long) fd);
  }
+#ifndef SOCK_STREAM
+#define SOCK_STREAM    1
+#endif /* SOCK_STREAM */
+#ifndef SOCK_DGRAM
+#define SOCK_DGRAM     2
+#endif /* SOCK_DGRAM */
+
+#ifndef SOCK_RAW
+#define SOCK_RAW       3
+#endif /* SOCK_RAW */
+
+#ifndef AF_LOCAL
+#define AF_LOCAL       1
+#endif /* AF_LOCAL */
+#ifndef AF_INET
+#define AF_INET        2
+#endif /* AF_INET */
+static inline int sys_socket(int domain, int type, int protocol)
+{
+       return (ssize_t) syscall3(__SC_SOCKET,
+                                 (long) domain,
+                                 (long) type,
+                                 (long) protocol);
+}
+
  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 a80c2b7..97cf4a1 100644
--- a/plat/linuxu/include/linuxu/tap.h
+++ b/plat/linuxu/include/linuxu/tap.h
@@ -57,6 +57,13 @@ struct uk_in_addr {
        uk_in_addr_t s_addr;
  };
+struct uk_sockaddr_in {
+       uk_sa_family_t sin_family;
+       uk_in_port_t sin_port;
+       struct uk_in_addr sin_addr;
+       __u8 sin_zero[8];
+};
+
  struct uk_sockaddr {
        uk_sa_family_t sa_family;
        char sa_data[14];
@@ -145,4 +152,6 @@ struct uk_ifreq {
  int tap_open(__u32 flags);
  int tap_close(int fd);
  int tap_dev_configure(int fd, __u32 feature_flags, vUK_SIOCGIFFLAGSoid *arg);
+int tap_netif_configure(int fd, __u32 request, void *arg);
+
  #endif /* LINUXU_TAP_H */
diff --git a/plat/linuxu/tap_io.c b/plat/linuxu/tap_io.c
index a394134..60f1fcc 100644
--- a/plat/linuxu/tap_io.c
+++ b/plat/linuxu/tap_io.c
@@ -61,6 +61,48 @@ int tap_dev_configure(int fd, __u32 feature_flags, void *arg)
        return rc;
  }
+int tap_netif_configure(int fd, __u32 request, void *arg)
+{
+       int rc;
+       struct uk_ifreq ifr = {0};
+       struct uk_ifreq *usr_ifr = (struct uk_ifreq *) arg;
+
+       switch (request) {
+       case UK_SIOCSIFFLAGS:
+               snprintf(ifr.ifr_name, IFNAMSIZ, "%s", usr_ifr->ifr_name);
+               rc = sys_ioctl(fd, UK_SIOCGIFFLAGS, &ifr);
+               /* fetch current flags to leave other flags untouched */
+               if (rc < 0) {
+                       uk_pr_err("Failed to read flags %d\n", rc);
+                       goto exit_error;
+               }
+               usr_ifr->ifr_flags |= ifr.ifr_flags;
+               break;
+       case UK_SIOCGIFINDEX:
+       case UK_SIOCGIFFLAGS:
+       case UK_SIOCGIFHWADDR:
+       case UK_SIOCSIFHWADDR:
+       case UK_SIOCSIFMTU:
+       case UK_SIOCSIFTXQLEN:
+       case UK_SIOCGIFTXQLEN:
+               break;
+       default:
+               rc = -EINVAL;
+               uk_pr_err("Invalid ioctl request\n");
+               goto exit_error;
+       }
+
+       if ((rc = sys_ioctl(fd, request, usr_ifr)) < 0) {
+               uk_pr_err("Failed to set device control %d\n", rc);
+               goto exit_error;
+       }
+
+       return 0;
+
+exit_error:
+       return rc;
+}
+
  int tap_close(int fd)
  {
        return sys_close(fd);

_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

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