[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 05/15] plat/tap: Get/Set hw_addr
The patch implements support for generating a default hw_addr. The patch also implements get and set netdev api. 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; + 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; + } + 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, void *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); -- 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 |