[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
|