From: Hajime Tazaki <thehajime@gmail.com>
To: linux-um@lists.infradead.org
Cc: Octavian Purdila <tavi.purdila@gmail.com>,
Akira Moroo <retrage01@gmail.com>,
linux-kernel-library@freelists.org, linux-arch@vger.kernel.org,
Hajime Tazaki <thehajime@gmail.com>
Subject: [RFC v4 15/25] lkl tools: host lib: networking helpers
Date: Mon, 30 Mar 2020 23:45:47 +0900 [thread overview]
Message-ID: <94b12a3395df2184c2faa9a95393166fc7fca46a.1585579244.git.thehajime@gmail.com> (raw)
In-Reply-To: <cover.1585579244.git.thehajime@gmail.com>
This commit adds LKL application APIs to control network related
resources of kernel via LKL syscall, ioctl, and via netlink messages.
Signed-off-by: Hajime Tazaki <thehajime@gmail.com>
---
tools/lkl/include/lkl.h | 241 ++++++++++
tools/lkl/include/lkl_host.h | 85 ++++
tools/lkl/lib/Build | 1 +
tools/lkl/lib/net.c | 826 +++++++++++++++++++++++++++++++++++
4 files changed, 1153 insertions(+)
create mode 100644 tools/lkl/lib/net.c
diff --git a/tools/lkl/include/lkl.h b/tools/lkl/include/lkl.h
index cdae92300320..1f4291ad9455 100644
--- a/tools/lkl/include/lkl.h
+++ b/tools/lkl/include/lkl.h
@@ -516,6 +516,247 @@ int lkl_dirfd(struct lkl_dir *dir);
*/
int lkl_mount_fs(char *fstype);
+/**
+ * lkl_if_up - activate network interface
+ *
+ * @ifindex - the ifindex of the interface
+ * @returns - return 0 if no error: otherwise negative value returns
+ */
+int lkl_if_up(int ifindex);
+
+/**
+ * lkl_if_down - deactivate network interface
+ *
+ * @ifindex - the ifindex of the interface
+ * @returns - return 0 if no error: otherwise negative value returns
+ */
+int lkl_if_down(int ifindex);
+
+/**
+ * lkl_if_set_mtu - set MTU on interface
+ *
+ * @ifindex - the ifindex of the interface
+ * @mtu - the requested MTU size
+ * @returns - return 0 if no error: otherwise negative value returns
+ */
+int lkl_if_set_mtu(int ifindex, int mtu);
+
+/**
+ * lkl_if_set_ipv4 - set IPv4 address on interface
+ *
+ * @ifindex - the ifindex of the interface
+ * @addr - 4-byte IP address (i.e., struct in_addr)
+ * @netmask_len - prefix length of the @addr
+ * @returns - return 0 if no error: otherwise negative value returns
+ */
+int lkl_if_set_ipv4(int ifindex, unsigned int addr, unsigned int netmask_len);
+
+/**
+ * lkl_set_ipv4_gateway - add an IPv4 default route
+ *
+ * @addr - 4-byte IP address of the gateway (i.e., struct in_addr)
+ * @returns - return 0 if no error: otherwise negative value returns
+ */
+int lkl_set_ipv4_gateway(unsigned int addr);
+
+/**
+ * lkl_if_set_ipv4_gateway - add an IPv4 default route in rule table
+ *
+ * @ifindex - the ifindex of the interface, used for tableid calculation
+ * @addr - 4-byte IP address of the interface
+ * @netmask_len - prefix length of the @addr
+ * @gw_addr - 4-byte IP address of the gateway
+ * @returns - return 0 if no error: otherwise negative value returns
+ */
+int lkl_if_set_ipv4_gateway(int ifindex, unsigned int addr,
+ unsigned int netmask_len, unsigned int gw_addr);
+
+/**
+ * lkl_if_set_ipv6 - set IPv6 address on interface
+ * must be called after interface is up.
+ *
+ * @ifindex - the ifindex of the interface
+ * @addr - 16-byte IPv6 address (i.e., struct in6_addr)
+ * @netprefix_len - prefix length of the @addr
+ * @returns - return 0 if no error: otherwise negative value returns
+ */
+int lkl_if_set_ipv6(int ifindex, void *addr, unsigned int netprefix_len);
+
+/**
+ * lkl_set_ipv6_gateway - add an IPv6 default route
+ *
+ * @addr - 16-byte IPv6 address of the gateway (i.e., struct in6_addr)
+ * @returns - return 0 if no error: otherwise negative value returns
+ */
+int lkl_set_ipv6_gateway(void *addr);
+
+/**
+ * lkl_if_set_ipv6_gateway - add an IPv6 default route in rule table
+ *
+ * @ifindex - the ifindex of the interface, used for tableid calculation
+ * @addr - 16-byte IP address of the interface
+ * @netmask_len - prefix length of the @addr
+ * @gw_addr - 16-byte IP address of the gateway (i.e., struct in_addr)
+ * @returns - return 0 if no error: otherwise negative value returns
+ */
+int lkl_if_set_ipv6_gateway(int ifindex, void *addr,
+ unsigned int netmask_len, void *gw_addr);
+
+/**
+ * lkl_ifname_to_ifindex - obtain ifindex of an interface by name
+ *
+ * @name - string of an interface
+ * @returns - return an integer of ifindex if no error
+ */
+int lkl_ifname_to_ifindex(const char *name);
+
+/**
+ * lkl_netdev_get_ifindex - retrieve the interface index for a given network
+ * device id
+ *
+ * @id - the network device id
+ * @returns the interface index or a stricly negative value in case of error
+ */
+int lkl_netdev_get_ifindex(int id);
+
+/**
+ * lkl_add_neighbor - add a permanent arp entry
+ * @ifindex - the ifindex of the interface
+ * @af - address family of the ip address. Must be LKL_AF_INET or LKL_AF_INET6
+ * @ip - ip address of the entry in network byte order
+ * @mac - mac address of the entry
+ */
+int lkl_add_neighbor(int ifindex, int af, void *addr, void *mac);
+
+/**
+ * lkl_if_add_ip - add an ip address
+ * @ifindex - the ifindex of the interface
+ * @af - address family of the ip address. Must be LKL_AF_INET or LKL_AF_INET6
+ * @addr - ip address of the entry in network byte order
+ * @netprefix_len - prefix length of the @addr
+ */
+int lkl_if_add_ip(int ifindex, int af, void *addr, unsigned int netprefix_len);
+
+/**
+ * lkl_if_del_ip - add an ip address
+ * @ifindex - the ifindex of the interface
+ * @af - address family of the ip address. Must be LKL_AF_INET or LKL_AF_INET6
+ * @addr - ip address of the entry in network byte order
+ * @netprefix_len - prefix length of the @addr
+ */
+int lkl_if_del_ip(int ifindex, int af, void *addr, unsigned int netprefix_len);
+
+/**
+ * lkl_add_gateway - add a gateway
+ * @af - address family of the ip address. Must be LKL_AF_INET or LKL_AF_INET6
+ * @gwaddr - 4-byte IP address of the gateway (i.e., struct in_addr)
+ */
+int lkl_add_gateway(int af, void *gwaddr);
+
+/**
+ * XXX Should I use OIF selector?
+ * temporary table idx = ifindex * 2 + 0 <- ipv4
+ * temporary table idx = ifindex * 2 + 1 <- ipv6
+ */
+/**
+ * lkl_if_add_rule_from_addr - create an ip rule table with "from" selector
+ * @ifindex - the ifindex of the interface, used for table id calculation
+ * @af - address family of the ip address. Must be LKL_AF_INET or LKL_AF_INET6
+ * @saddr - network byte order ip address, "from" selector address of this rule
+ */
+int lkl_if_add_rule_from_saddr(int ifindex, int af, void *saddr);
+
+/**
+ * lkl_if_add_gateway - add gateway to rule table
+ * @ifindex - the ifindex of the interface, used for table id calculation
+ * @af - address family of the ip address. Must be LKL_AF_INET or LKL_AF_INET6
+ * @gwaddr - 4-byte IP address of the gateway (i.e., struct in_addr)
+ */
+int lkl_if_add_gateway(int ifindex, int af, void *gwaddr);
+
+/**
+ * lkl_if_add_linklocal - add linklocal route to rule table
+ * @ifindex - the ifindex of the interface, used for table id calculation
+ * @af - address family of the ip address. Must be LKL_AF_INET or LKL_AF_INET6
+ * @addr - ip address of the entry in network byte order
+ * @netprefix_len - prefix length of the @addr
+ */
+int lkl_if_add_linklocal(int ifindex, int af, void *addr, int netprefix_len);
+
+/**
+ * lkl_if_wait_ipv6_dad - wait for DAD to be done for a ipv6 address
+ * must be called after interface is up
+ *
+ * @ifindex - the ifindex of the interface
+ * @addr - ip address of the entry in network byte order
+ */
+int lkl_if_wait_ipv6_dad(int ifindex, void *addr);
+
+/**
+ * lkl_set_fd_limit - set the maximum number of file descriptors allowed
+ * @fd_limit - fd max limit
+ */
+int lkl_set_fd_limit(unsigned int fd_limit);
+
+/**
+ * lkl_qdisc_add - set qdisc rule onto an interface
+ *
+ * @ifindex - the ifindex of the interface
+ * @root - the name of root class (e.g., "root");
+ * @type - the type of qdisc (e.g., "fq")
+ */
+int lkl_qdisc_add(int ifindex, const char *root, const char *type);
+
+/**
+ * lkl_qdisc_parse_add - Add a qdisc entry for an interface with strings
+ *
+ * @ifindex - the ifindex of the interface
+ * @entries - strings of qdisc configurations in the form of
+ * "root|type;root|type;..."
+ */
+void lkl_qdisc_parse_add(int ifindex, const char *entries);
+
+/**
+ * lkl_netdev - host network device handle, defined in lkl_host.h.
+ */
+struct lkl_netdev;
+
+/**
+ * lkl_netdev_args - arguments to lkl_netdev_add
+ * @mac - optional MAC address for the device
+ * @offload - offload bits for the device
+ */
+struct lkl_netdev_args {
+ void *mac;
+ unsigned int offload;
+};
+
+/*
+ * lkl_register_dbg_handler- register a signal handler that loads a debug lib.
+ *
+ * The signal handler is triggered by Ctrl-Z. It creates a new pthread which
+ * call dbg_entrance().
+ *
+ * If you run the program from shell script, make sure you ignore SIGTSTP by
+ * "trap '' TSTP" in the shell script.
+ */
+void lkl_register_dbg_handler(void);
+
+/**
+ * lkl_sysctl - write a sysctl value
+ *
+ * @path - the path to an sysctl entry (e.g., "net.ipv4.tcp_wmem");
+ * @value - the value of the sysctl (e.g., "4096 87380 2147483647")
+ */
+int lkl_sysctl(const char *path, const char *value);
+
+/**
+ * lkl_sysctl_parse_write - Configure sysctl parameters with strings
+ *
+ * @sysctls - Configure sysctl parameters as the form of "key=value;..."
+ */
+void lkl_sysctl_parse_write(const char *sysctls);
+
#ifdef __cplusplus
}
#endif
diff --git a/tools/lkl/include/lkl_host.h b/tools/lkl/include/lkl_host.h
index 85e80eb4ad0d..4e6d6e031498 100644
--- a/tools/lkl/include/lkl_host.h
+++ b/tools/lkl/include/lkl_host.h
@@ -18,6 +18,91 @@ extern struct lkl_host_operations lkl_host_ops;
*/
int lkl_printf(const char *fmt, ...);
+#ifdef LKL_HOST_CONFIG_POSIX
+#include <sys/uio.h>
+#else
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
+#endif
+
+struct lkl_netdev {
+ struct lkl_dev_net_ops *ops;
+ int id;
+ uint8_t has_vnet_hdr: 1;
+};
+
+/**
+ * struct lkl_dev_net_ops - network device host operations
+ */
+struct lkl_dev_net_ops {
+ /**
+ * @tx: writes a L2 packet into the net device
+ *
+ * The data buffer can only hold 0 or 1 complete packets.
+ *
+ * @nd - pointer to the network device;
+ * @iov - pointer to the buffer vector;
+ * @cnt - # of vectors in iov.
+ *
+ * @returns number of bytes transmitted
+ */
+ int (*tx)(struct lkl_netdev *nd, struct iovec *iov, int cnt);
+
+ /**
+ * @rx: reads a packet from the net device.
+ *
+ * It must only read one complete packet if present.
+ *
+ * If the buffer is too small for the packet, the implementation may
+ * decide to drop it or trim it.
+ *
+ * @nd - pointer to the network device
+ * @iov - pointer to the buffer vector to store the packet
+ * @cnt - # of vectors in iov.
+ *
+ * @returns number of bytes read for success or < 0 if error
+ */
+ int (*rx)(struct lkl_netdev *nd, struct iovec *iov, int cnt);
+
+#define LKL_DEV_NET_POLL_RX 1
+#define LKL_DEV_NET_POLL_TX 2
+#define LKL_DEV_NET_POLL_HUP 4
+
+ /**
+ * @poll: polls a net device
+ *
+ * Supports the following events: LKL_DEV_NET_POLL_RX
+ * (readable), LKL_DEV_NET_POLL_TX (writable) or
+ * LKL_DEV_NET_POLL_HUP (the close operations has been issued
+ * and we need to clean up). Blocks until one event is
+ * available.
+ *
+ * @nd - pointer to the network device
+ *
+ * @returns - LKL_DEV_NET_POLL_RX, LKL_DEV_NET_POLL_TX,
+ * LKL_DEV_NET_POLL_HUP or a negative value for errors
+ */
+ int (*poll)(struct lkl_netdev *nd);
+
+ /**
+ * @poll_hup: make poll wakeup and return LKL_DEV_NET_POLL_HUP
+ *
+ * @nd - pointer to the network device
+ */
+ void (*poll_hup)(struct lkl_netdev *nd);
+
+ /**
+ * @free: frees a network device
+ *
+ * Implementation must release its resources and free the network device
+ * structure.
+ *
+ * @nd - pointer to the network device
+ */
+ void (*free)(struct lkl_netdev *nd);
+};
#ifdef __cplusplus
}
diff --git a/tools/lkl/lib/Build b/tools/lkl/lib/Build
index 4a444337b0e7..dba530424e4a 100644
--- a/tools/lkl/lib/Build
+++ b/tools/lkl/lib/Build
@@ -1,6 +1,7 @@
CFLAGS_config.o += -I$(srctree)/tools/perf/pmu-events
liblkl-y += fs.o
+liblkl-y += net.o
liblkl-y += jmp_buf.o
liblkl-y += utils.o
liblkl-y += dbg.o
diff --git a/tools/lkl/lib/net.c b/tools/lkl/lib/net.c
new file mode 100644
index 000000000000..cf6894c35e46
--- /dev/null
+++ b/tools/lkl/lib/net.c
@@ -0,0 +1,826 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <string.h>
+#include <stdio.h>
+#include "endian.h"
+#include <lkl_host.h>
+
+#ifdef __MINGW32__
+#include <ws2tcpip.h>
+
+int lkl_inet_pton(int af, const char *src, void *dst)
+{
+ struct addrinfo hint, *res = NULL;
+ int err;
+
+ memset(&hint, 0, sizeof(struct addrinfo));
+
+ hint.ai_family = af;
+ hint.ai_flags = AI_NUMERICHOST;
+
+ err = getaddrinfo(src, NULL, &hint, &res);
+ if (err)
+ return 0;
+
+ switch (af) {
+ case AF_INET:
+ *(struct in_addr *)dst =
+ ((struct sockaddr_in *)&res->ai_addr)->sin_addr;
+ break;
+ case AF_INET6:
+ *(struct in6_addr *)dst =
+ ((struct sockaddr_in6 *)&res->ai_addr)->sin6_addr;
+ break;
+ default:
+ freeaddrinfo(res);
+ return 0;
+ }
+
+ freeaddrinfo(res);
+ return 1;
+}
+#endif
+
+static inline void set_sockaddr(struct lkl_sockaddr_in *sin, unsigned int addr,
+ unsigned short port)
+{
+ sin->sin_family = LKL_AF_INET;
+ sin->sin_addr.lkl_s_addr = addr;
+ sin->sin_port = port;
+}
+
+static inline int ifindex_to_name(int sock, struct lkl_ifreq *ifr, int ifindex)
+{
+ ifr->lkl_ifr_ifindex = ifindex;
+ return lkl_sys_ioctl(sock, LKL_SIOCGIFNAME, (long)ifr);
+}
+
+int lkl_ifname_to_ifindex(const char *name)
+{
+ struct lkl_ifreq ifr;
+ int fd, ret;
+
+ fd = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
+ if (fd < 0)
+ return fd;
+
+ if (strlen(name) >= LKL_IFNAMSIZ)
+ return -LKL_ENAMETOOLONG;
+
+ strcpy(ifr.lkl_ifr_name, name);
+
+ ret = lkl_sys_ioctl(fd, LKL_SIOCGIFINDEX, (long)&ifr);
+ if (ret < 0)
+ return ret;
+
+ return ifr.lkl_ifr_ifindex;
+}
+
+int lkl_if_up(int ifindex)
+{
+ struct lkl_ifreq ifr;
+ int err, sock = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
+
+ if (sock < 0)
+ return sock;
+ err = ifindex_to_name(sock, &ifr, ifindex);
+ if (err < 0)
+ return err;
+
+ err = lkl_sys_ioctl(sock, LKL_SIOCGIFFLAGS, (long)&ifr);
+ if (!err) {
+ ifr.lkl_ifr_flags |= LKL_IFF_UP;
+ err = lkl_sys_ioctl(sock, LKL_SIOCSIFFLAGS, (long)&ifr);
+ }
+
+ lkl_sys_close(sock);
+
+ return err;
+}
+
+int lkl_if_down(int ifindex)
+{
+ struct lkl_ifreq ifr;
+ int err, sock;
+
+ sock = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
+ if (sock < 0)
+ return sock;
+
+ err = ifindex_to_name(sock, &ifr, ifindex);
+ if (err < 0)
+ return err;
+
+ err = lkl_sys_ioctl(sock, LKL_SIOCGIFFLAGS, (long)&ifr);
+ if (!err) {
+ ifr.lkl_ifr_flags &= ~LKL_IFF_UP;
+ err = lkl_sys_ioctl(sock, LKL_SIOCSIFFLAGS, (long)&ifr);
+ }
+
+ lkl_sys_close(sock);
+
+ return err;
+}
+
+int lkl_if_set_mtu(int ifindex, int mtu)
+{
+ struct lkl_ifreq ifr;
+ int err, sock;
+
+ sock = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
+ if (sock < 0)
+ return sock;
+
+ err = ifindex_to_name(sock, &ifr, ifindex);
+ if (err < 0)
+ return err;
+
+ ifr.lkl_ifr_mtu = mtu;
+
+ err = lkl_sys_ioctl(sock, LKL_SIOCSIFMTU, (long)&ifr);
+
+ lkl_sys_close(sock);
+
+ return err;
+}
+
+int lkl_if_set_ipv4(int ifindex, unsigned int addr, unsigned int netmask_len)
+{
+ return lkl_if_add_ip(ifindex, LKL_AF_INET, &addr, netmask_len);
+}
+
+int lkl_if_set_ipv4_gateway(int ifindex, unsigned int src_addr,
+ unsigned int src_masklen, unsigned int via_addr)
+{
+ int err;
+
+ err = lkl_if_add_rule_from_saddr(ifindex, LKL_AF_INET, &src_addr);
+ if (err)
+ return err;
+ err = lkl_if_add_linklocal(ifindex, LKL_AF_INET,
+ &src_addr, src_masklen);
+ if (err)
+ return err;
+ return lkl_if_add_gateway(ifindex, LKL_AF_INET, &via_addr);
+}
+
+int lkl_set_ipv4_gateway(unsigned int addr)
+{
+ return lkl_add_gateway(LKL_AF_INET, &addr);
+}
+
+int lkl_netdev_get_ifindex(int id)
+{
+ struct lkl_ifreq ifr;
+ int sock, ret;
+
+ sock = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
+ if (sock < 0)
+ return sock;
+
+ snprintf(ifr.lkl_ifr_name, sizeof(ifr.lkl_ifr_name), "eth%d", id);
+ ret = lkl_sys_ioctl(sock, LKL_SIOCGIFINDEX, (long)&ifr);
+ lkl_sys_close(sock);
+
+ return ret < 0 ? ret : ifr.lkl_ifr_ifindex;
+}
+
+static int netlink_sock(unsigned int groups)
+{
+ struct lkl_sockaddr_nl la;
+ int fd, err;
+
+ fd = lkl_sys_socket(LKL_AF_NETLINK, LKL_SOCK_DGRAM, LKL_NETLINK_ROUTE);
+ if (fd < 0)
+ return fd;
+
+ memset(&la, 0, sizeof(la));
+ la.nl_family = LKL_AF_NETLINK;
+ la.nl_groups = groups;
+ err = lkl_sys_bind(fd, (struct lkl_sockaddr *)&la, sizeof(la));
+ if (err < 0)
+ return err;
+
+ return fd;
+}
+
+static int parse_rtattr(struct lkl_rtattr *tb[], int max,
+ struct lkl_rtattr *rta, int len)
+{
+ unsigned short type;
+
+ memset(tb, 0, sizeof(struct lkl_rtattr *) * (max + 1));
+ while (LKL_RTA_OK(rta, len)) {
+ type = rta->rta_type;
+ if ((type <= max) && (!tb[type]))
+ tb[type] = rta;
+ rta = LKL_RTA_NEXT(rta, len);
+ }
+ if (len)
+ lkl_printf("!!!Deficit %d, rta_len=%d\n", len,
+ rta->rta_len);
+ return 0;
+}
+
+struct addr_filter {
+ unsigned int ifindex;
+ void *addr;
+};
+
+static unsigned int get_ifa_flags(struct lkl_ifaddrmsg *ifa,
+ struct lkl_rtattr *ifa_flags_attr)
+{
+ return ifa_flags_attr ? *(unsigned int *)LKL_RTA_DATA(ifa_flags_attr) :
+ ifa->ifa_flags;
+}
+
+/* returns:
+ * 0 - dad succeed.
+ * -1 - dad failed or other error.
+ * 1 - should wait for new msg.
+ */
+static int check_ipv6_dad(struct lkl_sockaddr_nl *nladdr,
+ struct lkl_nlmsghdr *n, void *arg)
+{
+ struct addr_filter *filter = arg;
+ struct lkl_ifaddrmsg *ifa = LKL_NLMSG_DATA(n);
+ struct lkl_rtattr *rta_tb[LKL_IFA_MAX+1];
+ unsigned int ifa_flags;
+ int len = n->nlmsg_len;
+
+ if (n->nlmsg_type != LKL_RTM_NEWADDR)
+ return 1;
+
+ len -= LKL_NLMSG_LENGTH(sizeof(*ifa));
+ if (len < 0) {
+ lkl_printf("BUG: wrong nlmsg len %d\n", len);
+ return -1;
+ }
+
+ parse_rtattr(rta_tb, LKL_IFA_MAX, LKL_IFA_RTA(ifa),
+ n->nlmsg_len - LKL_NLMSG_LENGTH(sizeof(*ifa)));
+
+ ifa_flags = get_ifa_flags(ifa, rta_tb[LKL_IFA_FLAGS]);
+
+ if (ifa->ifa_index != filter->ifindex)
+ return 1;
+ if (ifa->ifa_family != LKL_AF_INET6)
+ return 1;
+
+ if (!rta_tb[LKL_IFA_LOCAL])
+ rta_tb[LKL_IFA_LOCAL] = rta_tb[LKL_IFA_ADDRESS];
+
+ if (!rta_tb[LKL_IFA_LOCAL] ||
+ (filter->addr && memcmp(LKL_RTA_DATA(rta_tb[LKL_IFA_LOCAL]),
+ filter->addr, 16))) {
+ return 1;
+ }
+ if (ifa_flags & LKL_IFA_F_DADFAILED) {
+ lkl_printf("IPV6 DAD failed.\n");
+ return -1;
+ }
+ if (!(ifa_flags & LKL_IFA_F_TENTATIVE))
+ return 0;
+ return 1;
+}
+
+/* Copied from iproute2/lib/ */
+static int rtnl_listen(int fd, int (*handler)(struct lkl_sockaddr_nl *nladdr,
+ struct lkl_nlmsghdr *, void *),
+ void *arg)
+{
+ int status;
+ struct lkl_nlmsghdr *h;
+ struct lkl_sockaddr_nl nladdr = { .nl_family = LKL_AF_NETLINK };
+ struct lkl_iovec iov;
+ struct lkl_user_msghdr msg = {
+ .msg_name = &nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ };
+ char buf[16384];
+
+ iov.iov_base = buf;
+ while (1) {
+ iov.iov_len = sizeof(buf);
+ status = lkl_sys_recvmsg(fd, &msg, 0);
+
+ if (status < 0) {
+ if (status == -LKL_EINTR || status == -LKL_EAGAIN)
+ continue;
+ lkl_printf("netlink receive error %s (%d)\n",
+ lkl_strerror(status), status);
+ if (status == -LKL_ENOBUFS)
+ continue;
+ return status;
+ }
+ if (status == 0) {
+ lkl_printf("EOF on netlink\n");
+ return -1;
+ }
+ if (msg.msg_namelen != sizeof(nladdr)) {
+ lkl_printf("Sender address length == %d\n",
+ msg.msg_namelen);
+ return -1;
+ }
+
+ for (h = (struct lkl_nlmsghdr *)buf;
+ (unsigned int)status >= sizeof(*h);) {
+ int err;
+ int len = h->nlmsg_len;
+ int l = len - sizeof(*h);
+
+ if (l < 0 || len > status) {
+ if (msg.msg_flags & LKL_MSG_TRUNC) {
+ lkl_printf("Truncated message\n");
+ return -1;
+ }
+ lkl_printf("!!!malformed message: len=%d\n",
+ len);
+ return -1;
+ }
+
+ err = handler(&nladdr, h, arg);
+ if (err <= 0)
+ return err;
+
+ status -= LKL_NLMSG_ALIGN(len);
+ h = (struct lkl_nlmsghdr *)((char *)h +
+ LKL_NLMSG_ALIGN(len));
+ }
+ if (msg.msg_flags & LKL_MSG_TRUNC) {
+ lkl_printf("Message truncated\n");
+ continue;
+ }
+ if (status) {
+ lkl_printf("!!!Remnant of size %d\n", status);
+ return -1;
+ }
+ }
+}
+
+int lkl_if_wait_ipv6_dad(int ifindex, void *addr)
+{
+ struct addr_filter filter = {.ifindex = ifindex, .addr = addr};
+ int fd, ret;
+ struct {
+ struct lkl_nlmsghdr nlmsg_info;
+ struct lkl_ifaddrmsg ifaddrmsg_info;
+ } req;
+
+ fd = netlink_sock(1 << (LKL_RTNLGRP_IPV6_IFADDR - 1));
+ if (fd < 0)
+ return fd;
+
+ memset(&req, 0, sizeof(req));
+ req.nlmsg_info.nlmsg_len =
+ LKL_NLMSG_LENGTH(sizeof(struct lkl_ifaddrmsg));
+ req.nlmsg_info.nlmsg_flags = LKL_NLM_F_REQUEST | LKL_NLM_F_DUMP;
+ req.nlmsg_info.nlmsg_type = LKL_RTM_GETADDR;
+ req.ifaddrmsg_info.ifa_family = LKL_AF_INET6;
+ req.ifaddrmsg_info.ifa_index = ifindex;
+ ret = lkl_sys_send(fd, &req, req.nlmsg_info.nlmsg_len, 0);
+ if (ret < 0) {
+ lkl_perror("lkl_sys_send", ret);
+ return ret;
+ }
+ ret = rtnl_listen(fd, check_ipv6_dad, (void *)&filter);
+ lkl_sys_close(fd);
+ return ret;
+}
+
+int lkl_if_set_ipv6(int ifindex, void *addr, unsigned int netprefix_len)
+{
+ int err = lkl_if_add_ip(ifindex, LKL_AF_INET6, addr, netprefix_len);
+
+ if (err)
+ return err;
+ return lkl_if_wait_ipv6_dad(ifindex, addr);
+}
+
+int lkl_if_set_ipv6_gateway(int ifindex, void *src_addr,
+ unsigned int src_masklen, void *via_addr)
+{
+ int err;
+
+ err = lkl_if_add_rule_from_saddr(ifindex, LKL_AF_INET6, src_addr);
+ if (err)
+ return err;
+ err = lkl_if_add_linklocal(ifindex, LKL_AF_INET6,
+ src_addr, src_masklen);
+ if (err)
+ return err;
+ return lkl_if_add_gateway(ifindex, LKL_AF_INET6, via_addr);
+}
+
+int lkl_set_ipv6_gateway(void *addr)
+{
+ return lkl_add_gateway(LKL_AF_INET6, addr);
+}
+
+/* returns:
+ * 0 - succeed.
+ * < 0 - error number.
+ * 1 - should wait for new msg.
+ */
+static int check_error(struct lkl_sockaddr_nl *nladdr, struct lkl_nlmsghdr *n,
+ void *arg)
+{
+ unsigned int s = *(unsigned int *)arg;
+
+ if (nladdr->nl_pid != 0 || n->nlmsg_seq != s) {
+ /* Don't forget to skip that message. */
+ return 1;
+ }
+
+ if (n->nlmsg_type == LKL_NLMSG_ERROR) {
+ struct lkl_nlmsgerr *err =
+ (struct lkl_nlmsgerr *)LKL_NLMSG_DATA(n);
+ int l = n->nlmsg_len - sizeof(*n);
+
+ if (l < (int)sizeof(struct lkl_nlmsgerr))
+ lkl_printf("ERROR truncated\n");
+ else if (!err->error)
+ return 0;
+
+ lkl_printf("RTNETLINK answers: %s\n",
+ lkl_strerror(-err->error));
+ return err->error;
+ }
+ lkl_printf("Unexpected reply!!!\n");
+ return -1;
+}
+
+static unsigned int seq;
+static int rtnl_talk(int fd, struct lkl_nlmsghdr *n)
+{
+ int status;
+ struct lkl_sockaddr_nl nladdr = {.nl_family = LKL_AF_NETLINK};
+ struct lkl_iovec iov = {.iov_base = (void *)n, .iov_len = n->nlmsg_len};
+ struct lkl_user_msghdr msg = {
+ .msg_name = &nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ };
+
+ n->nlmsg_seq = seq;
+ n->nlmsg_flags |= LKL_NLM_F_ACK;
+
+ status = lkl_sys_sendmsg(fd, &msg, 0);
+ if (status < 0) {
+ lkl_perror("Cannot talk to rtnetlink", status);
+ return status;
+ }
+
+ status = rtnl_listen(fd, check_error, (void *)&seq);
+ seq++;
+ return status;
+}
+
+static int addattr_l(struct lkl_nlmsghdr *n, unsigned int maxlen,
+ int type, const void *data, int alen)
+{
+ int len = LKL_RTA_LENGTH(alen);
+ struct lkl_rtattr *rta;
+
+ if (LKL_NLMSG_ALIGN(n->nlmsg_len) + LKL_RTA_ALIGN(len) > maxlen) {
+ lkl_printf("%s ERROR: message exceeded bound of %d\n", __func__,
+ maxlen);
+ return -1;
+ }
+ rta = ((struct lkl_rtattr *) (((void *) (n)) +
+ LKL_NLMSG_ALIGN(n->nlmsg_len)));
+ rta->rta_type = type;
+ rta->rta_len = len;
+ memcpy(LKL_RTA_DATA(rta), data, alen);
+ n->nlmsg_len = LKL_NLMSG_ALIGN(n->nlmsg_len) + LKL_RTA_ALIGN(len);
+ return 0;
+}
+
+int lkl_add_neighbor(int ifindex, int af, void *ip, void *mac)
+{
+ struct {
+ struct lkl_nlmsghdr n;
+ struct lkl_ndmsg r;
+ char buf[1024];
+ } req = {
+ .n.nlmsg_len = LKL_NLMSG_LENGTH(sizeof(struct lkl_ndmsg)),
+ .n.nlmsg_type = LKL_RTM_NEWNEIGH,
+ .n.nlmsg_flags = LKL_NLM_F_REQUEST |
+ LKL_NLM_F_CREATE | LKL_NLM_F_REPLACE,
+ .r.ndm_family = af,
+ .r.ndm_ifindex = ifindex,
+ .r.ndm_state = LKL_NUD_PERMANENT,
+
+ };
+ int err, addr_sz;
+ int fd;
+
+ if (af == LKL_AF_INET)
+ addr_sz = 4;
+ else if (af == LKL_AF_INET6)
+ addr_sz = 16;
+ else {
+ lkl_printf("Bad address family: %d\n", af);
+ return -1;
+ }
+
+ fd = netlink_sock(0);
+ if (fd < 0)
+ return fd;
+
+ // create the IP attribute
+ addattr_l(&req.n, sizeof(req), LKL_NDA_DST, ip, addr_sz);
+
+ // create the MAC attribute
+ addattr_l(&req.n, sizeof(req), LKL_NDA_LLADDR, mac, 6);
+
+ err = rtnl_talk(fd, &req.n);
+ lkl_sys_close(fd);
+ return err;
+}
+
+static int ipaddr_modify(int cmd, int flags, int ifindex, int af, void *addr,
+ unsigned int netprefix_len)
+{
+ struct {
+ struct lkl_nlmsghdr n;
+ struct lkl_ifaddrmsg ifa;
+ char buf[256];
+ } req = {
+ .n.nlmsg_len = LKL_NLMSG_LENGTH(sizeof(struct lkl_ifaddrmsg)),
+ .n.nlmsg_flags = LKL_NLM_F_REQUEST | flags,
+ .n.nlmsg_type = cmd,
+ .ifa.ifa_family = af,
+ .ifa.ifa_prefixlen = netprefix_len,
+ .ifa.ifa_index = ifindex,
+ };
+ int err, addr_sz;
+ int fd;
+
+ if (af == LKL_AF_INET)
+ addr_sz = 4;
+ else if (af == LKL_AF_INET6)
+ addr_sz = 16;
+ else {
+ lkl_printf("Bad address family: %d\n", af);
+ return -1;
+ }
+
+ fd = netlink_sock(0);
+ if (fd < 0)
+ return fd;
+
+ // create the IP attribute
+ addattr_l(&req.n, sizeof(req), LKL_IFA_LOCAL, addr, addr_sz);
+
+ err = rtnl_talk(fd, &req.n);
+
+ lkl_sys_close(fd);
+ return err;
+}
+
+int lkl_if_add_ip(int ifindex, int af, void *addr, unsigned int netprefix_len)
+{
+ return ipaddr_modify(LKL_RTM_NEWADDR, LKL_NLM_F_CREATE | LKL_NLM_F_EXCL,
+ ifindex, af, addr, netprefix_len);
+}
+
+int lkl_if_del_ip(int ifindex, int af, void *addr, unsigned int netprefix_len)
+{
+ return ipaddr_modify(LKL_RTM_DELADDR, 0, ifindex, af,
+ addr, netprefix_len);
+}
+
+static int iproute_modify(int cmd, unsigned int flags, int ifindex, int af,
+ void *route_addr, int route_masklen, void *gwaddr)
+{
+ struct {
+ struct lkl_nlmsghdr n;
+ struct lkl_rtmsg r;
+ char buf[1024];
+ } req = {
+ .n.nlmsg_len = LKL_NLMSG_LENGTH(sizeof(struct lkl_rtmsg)),
+ .n.nlmsg_flags = LKL_NLM_F_REQUEST | flags,
+ .n.nlmsg_type = cmd,
+ .r.rtm_family = af,
+ .r.rtm_table = LKL_RT_TABLE_MAIN,
+ .r.rtm_scope = LKL_RT_SCOPE_UNIVERSE,
+ };
+ int err, addr_sz;
+ int i, fd;
+
+ fd = netlink_sock(0);
+ if (fd < 0) {
+ lkl_printf("netlink_sock error: %d\n", fd);
+ return fd;
+ }
+
+ if (af == LKL_AF_INET)
+ addr_sz = 4;
+ else if (af == LKL_AF_INET6)
+ addr_sz = 16;
+ else {
+ lkl_printf("Bad address family: %d\n", af);
+ return -1;
+ }
+
+ if (cmd != LKL_RTM_DELROUTE) {
+ req.r.rtm_protocol = LKL_RTPROT_BOOT;
+ req.r.rtm_scope = LKL_RT_SCOPE_UNIVERSE;
+ req.r.rtm_type = LKL_RTN_UNICAST;
+ }
+
+ if (gwaddr)
+ addattr_l(&req.n, sizeof(req),
+ LKL_RTA_GATEWAY, gwaddr, addr_sz);
+
+ if (af == LKL_AF_INET && route_addr) {
+ unsigned int netaddr = *(unsigned int *)route_addr;
+
+ netaddr = ntohl(netaddr);
+ netaddr = (netaddr >> (32 - route_masklen));
+ netaddr = (netaddr << (32 - route_masklen));
+ netaddr = htonl(netaddr);
+ *(unsigned int *)route_addr = netaddr;
+ req.r.rtm_dst_len = route_masklen;
+ addattr_l(&req.n, sizeof(req), LKL_RTA_DST,
+ route_addr, addr_sz);
+ }
+
+ if (af == LKL_AF_INET6 && route_addr) {
+ struct lkl_in6_addr netaddr =
+ *(struct lkl_in6_addr *)route_addr;
+ int rmbyte = route_masklen/8;
+ int rmbit = route_masklen%8;
+
+ for (i = 0; i < rmbyte; i++)
+ netaddr.in6_u.u6_addr8[15-i] = 0;
+ netaddr.in6_u.u6_addr8[15-rmbyte] =
+ (netaddr.in6_u.u6_addr8[15-rmbyte] >> rmbit);
+ netaddr.in6_u.u6_addr8[15-rmbyte] =
+ (netaddr.in6_u.u6_addr8[15-rmbyte] << rmbit);
+ *(struct lkl_in6_addr *)route_addr = netaddr;
+ req.r.rtm_dst_len = route_masklen;
+ addattr_l(&req.n, sizeof(req), LKL_RTA_DST,
+ route_addr, addr_sz);
+ }
+
+ if (ifindex != LKL_RT_TABLE_MAIN) {
+ if (af == LKL_AF_INET)
+ req.r.rtm_table = ifindex * 2;
+ else if (af == LKL_AF_INET6)
+ req.r.rtm_table = ifindex * 2 + 1;
+ addattr_l(&req.n, sizeof(req), LKL_RTA_OIF, &ifindex, addr_sz);
+ }
+ err = rtnl_talk(fd, &req.n);
+ lkl_sys_close(fd);
+ return err;
+}
+
+int lkl_if_add_linklocal(int ifindex, int af, void *addr, int netprefix_len)
+{
+ return iproute_modify(LKL_RTM_NEWROUTE, LKL_NLM_F_CREATE|LKL_NLM_F_EXCL,
+ ifindex, af, addr, netprefix_len, NULL);
+}
+
+int lkl_if_add_gateway(int ifindex, int af, void *gwaddr)
+{
+ return iproute_modify(LKL_RTM_NEWROUTE, LKL_NLM_F_CREATE|LKL_NLM_F_EXCL,
+ ifindex, af, NULL, 0, gwaddr);
+}
+
+int lkl_add_gateway(int af, void *gwaddr)
+{
+ return iproute_modify(LKL_RTM_NEWROUTE, LKL_NLM_F_CREATE|LKL_NLM_F_EXCL,
+ LKL_RT_TABLE_MAIN, af, NULL, 0, gwaddr);
+}
+
+static int iprule_modify(int cmd, int ifindex, int af, void *saddr)
+{
+ struct {
+ struct lkl_nlmsghdr n;
+ struct lkl_rtmsg r;
+ char buf[1024];
+ } req = {
+ .n.nlmsg_type = cmd,
+ .n.nlmsg_len = LKL_NLMSG_LENGTH(sizeof(struct lkl_rtmsg)),
+ .n.nlmsg_flags = LKL_NLM_F_REQUEST,
+ .r.rtm_protocol = LKL_RTPROT_BOOT,
+ .r.rtm_scope = LKL_RT_SCOPE_UNIVERSE,
+ .r.rtm_family = af,
+ .r.rtm_type = LKL_RTN_UNSPEC,
+ };
+ int fd, err;
+ int addr_sz;
+
+ if (af == LKL_AF_INET)
+ addr_sz = 4;
+ else if (af == LKL_AF_INET6)
+ addr_sz = 16;
+ else {
+ lkl_printf("Bad address family: %d\n", af);
+ return -1;
+ }
+
+ fd = netlink_sock(0);
+ if (fd < 0)
+ return fd;
+
+ if (cmd == LKL_RTM_NEWRULE) {
+ req.n.nlmsg_flags |= LKL_NLM_F_CREATE|LKL_NLM_F_EXCL;
+ req.r.rtm_type = LKL_RTN_UNICAST;
+ }
+
+ //set from address
+ req.r.rtm_src_len = 8 * addr_sz;
+ addattr_l(&req.n, sizeof(req), LKL_FRA_SRC, saddr, addr_sz);
+
+ //use ifindex as table id
+ if (af == LKL_AF_INET)
+ req.r.rtm_table = ifindex * 2;
+ else if (af == LKL_AF_INET6)
+ req.r.rtm_table = ifindex * 2 + 1;
+ err = rtnl_talk(fd, &req.n);
+
+ lkl_sys_close(fd);
+ return err;
+}
+
+int lkl_if_add_rule_from_saddr(int ifindex, int af, void *saddr)
+{
+ return iprule_modify(LKL_RTM_NEWRULE, ifindex, af, saddr);
+}
+
+static int qdisc_add(int cmd, int flags, int ifindex,
+ const char *root, const char *type)
+{
+ struct {
+ struct lkl_nlmsghdr n;
+ struct lkl_tcmsg tc;
+ char buf[2*1024];
+ } req = {
+ .n.nlmsg_len = LKL_NLMSG_LENGTH(sizeof(struct lkl_tcmsg)),
+ .n.nlmsg_flags = LKL_NLM_F_REQUEST|flags,
+ .n.nlmsg_type = cmd,
+ .tc.tcm_family = LKL_AF_UNSPEC,
+ };
+ int err, fd;
+
+ if (!root || !type) {
+ lkl_printf("root and type arguments\n");
+ return -1;
+ }
+
+ if (strcmp(root, "root") == 0)
+ req.tc.tcm_parent = LKL_TC_H_ROOT;
+ req.tc.tcm_ifindex = ifindex;
+
+ fd = netlink_sock(0);
+ if (fd < 0)
+ return fd;
+
+ // create the qdisc attribute
+ addattr_l(&req.n, sizeof(req), LKL_TCA_KIND, type, strlen(type)+1);
+
+ err = rtnl_talk(fd, &req.n);
+ lkl_sys_close(fd);
+ return err;
+}
+
+int lkl_qdisc_add(int ifindex, const char *root, const char *type)
+{
+ return qdisc_add(LKL_RTM_NEWQDISC, LKL_NLM_F_CREATE | LKL_NLM_F_EXCL,
+ ifindex, root, type);
+}
+
+/* Add a qdisc entry for an interface in the form of
+ * "root|type;root|type;..."
+ */
+void lkl_qdisc_parse_add(int ifindex, const char *entries)
+{
+ char *saveptr = NULL, *token = NULL;
+ char *root = NULL, *type = NULL;
+ char strings[256];
+ int ret = 0;
+
+ if (strlen(entries) >= sizeof(strings)) {
+ lkl_printf("Error: long strings of input: %s\n", entries);
+ return;
+ }
+
+ strcpy(strings, entries);
+
+ for (token = strtok_r(strings, ";", &saveptr); token;
+ token = strtok_r(NULL, ";", &saveptr)) {
+ root = strtok(token, "|");
+ type = strtok(NULL, "|");
+ ret = lkl_qdisc_add(ifindex, root, type);
+ if (ret) {
+ lkl_printf("Failed to add qdisc entry: %s\n",
+ lkl_strerror(ret));
+ return;
+ }
+ }
+}
--
2.21.0 (Apple Git-122.2)
next prev parent reply other threads:[~2020-03-30 14:48 UTC|newest]
Thread overview: 251+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-05 7:30 [RFC v3 00/26] Unifying LKL into UML Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 01/26] asm-generic: atomic64: allow using generic atomic64 on 64bit platforms Hajime Tazaki
2020-02-05 9:34 ` Peter Zijlstra
2020-02-05 12:24 ` Octavian Purdila
2020-02-05 12:29 ` Anton Ivanov
2020-02-05 12:49 ` Peter Zijlstra
2020-02-05 14:00 ` Octavian Purdila
2020-02-05 17:13 ` Peter Zijlstra
2020-02-07 12:32 ` Octavian Purdila
[not found] ` <cover.1580882335.git.thehajime-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2020-02-05 7:30 ` [RFC v3 02/26] arch: add __SYSCALL_DEFINE_ARCH Hajime Tazaki
2020-02-05 7:30 ` Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 03/26] um lkl: architecture skeleton for Linux kernel library Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 04/26] um lkl: host interface Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 05/26] um lkl: memory handling Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 06/26] um lkl: kernel threads support Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 07/26] um lkl: interrupt support Hajime Tazaki
2020-02-05 10:47 ` Anton Ivanov
2020-02-05 14:46 ` Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 08/26] um lkl: system call interface and application API Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 09/26] um lkl: timers, time and delay support Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 10/26] um lkl: basic kernel console support Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 11/26] um lkl: initialization and cleanup Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 12/26] um lkl: plug in the build system Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 13/26] lkl tools: skeleton for host side library Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 14/26] lkl tools: host lib: add utilities functions Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 15/26] lkl tools: host lib: filesystem helpers Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 16/26] lkl tools: host lib: networking helpers Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 17/26] lkl tools: host lib: posix host operations Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 18/26] lkl tools: add test programs Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 19/26] lkl tools: cptofs that reads/writes to/from a filesystem image Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 20/26] lkl tools: fs2tar that converts a filesystem image to tar Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 21/26] lkl tools: add lklfuse Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 22/26] um lkl: add documentation Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 23/26] um lkl: add CI scripts to conduct regression tests Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 24/26] um lkl: add UML network driver for lkl Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 25/26] um lkl: add UML block device driver (ubd) " Hajime Tazaki
2020-02-05 7:30 ` [RFC v3 26/26] um: fix clone flags to be familar with valgrind Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 00/25] Unifying LKL into UML Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 01/25] arch: add __SYSCALL_DEFINE_ARCH Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 02/25] um lkl: architecture skeleton for Linux kernel library Hajime Tazaki
2020-03-30 21:53 ` Johannes Berg
2020-03-30 22:12 ` Richard Weinberger
2020-03-30 22:12 ` Richard Weinberger
2020-03-31 7:08 ` Hajime Tazaki
2020-03-31 20:16 ` Johannes Berg
2020-04-02 6:44 ` Hajime Tazaki
2020-04-07 19:25 ` Octavian Purdila
2020-04-07 19:25 ` Octavian Purdila
2020-03-30 14:45 ` [RFC v4 03/25] um lkl: host interface Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 04/25] um lkl: memory handling Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 05/25] um lkl: kernel threads support Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 06/25] um lkl: interrupt support Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 07/25] um lkl: system call interface and application API Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 08/25] um lkl: timers, time and delay support Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 09/25] um lkl: basic kernel console support Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 10/25] um lkl: initialization and cleanup Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 11/25] um lkl: plug in the build system Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 12/25] lkl tools: skeleton for host side library Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 13/25] lkl tools: host lib: add utilities functions Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 14/25] lkl tools: host lib: filesystem helpers Hajime Tazaki
2020-03-30 14:45 ` Hajime Tazaki [this message]
2020-03-30 14:45 ` [RFC v4 16/25] lkl tools: host lib: posix host operations Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 17/25] lkl tools: add test programs Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 18/25] lkl tools: cptofs that reads/writes to/from a filesystem image Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 19/25] lkl tools: fs2tar that converts a filesystem image to tar Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 20/25] lkl tools: add lklfuse Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 21/25] um lkl: add documentation Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 22/25] um lkl: add CI scripts to conduct regression tests Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 23/25] um lkl: add UML network driver for lkl Hajime Tazaki
2020-03-30 21:31 ` Johannes Berg
2020-03-31 2:38 ` Hajime Tazaki
2020-03-31 19:52 ` Johannes Berg
2020-03-30 14:45 ` [RFC v4 24/25] um lkl: add UML block device driver (ubd) " Hajime Tazaki
2020-03-30 14:45 ` [RFC v4 25/25] um: fix clone flags to be familiar with valgrind Hajime Tazaki
2020-07-02 14:06 ` [RFC v5 00/21] Unifying LKL into UML Hajime Tazaki
2020-07-02 14:06 ` [RFC v5 01/21] um: split build in kernel and host parts Hajime Tazaki
2020-09-21 16:01 ` Anton Ivanov
2020-09-21 22:27 ` Hajime Tazaki
2020-07-02 14:06 ` [RFC v5 02/21] um: add os init and exit calls Hajime Tazaki
2020-07-02 14:06 ` [RFC v5 03/21] um: move arch/um/os-Linux dir to tools/um/uml Hajime Tazaki
2020-07-02 14:06 ` [RFC v5 04/21] um: host: implement os_initcalls and os_exitcalls Hajime Tazaki
2020-07-02 14:06 ` [RFC v5 05/21] um: move arch/x86/um/os-Linux to tools/um/uml/ Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 06/21] scritps: um: suppress warnings if SRCARCH=um Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 07/21] um: extend arch_switch_to for alternate SUBARCH Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 08/21] um: add nommu mode for UML library mode Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 09/21] um: nommu: host interface Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 10/21] um: nommu: memory handling Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 11/21] um: nommu: kernel thread support Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 12/21] um: nommu: system call interface and application API Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 13/21] um: nommu: basic console support Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 14/21] um: nommu: initialization and cleanup Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 15/21] um: nommu: integrate with irq infrastructure of UML Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 16/21] um: nommu: plug in the build system Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 17/21] um: host: add nommu build for ARCH=um Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 18/21] um: host: add utilities functions Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 19/21] um: host: posix host operations Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 20/21] um: host: add test programs Hajime Tazaki
2020-07-02 14:07 ` [RFC v5 21/21] um: nommu: add block device support of UML Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 00/21] Unifying LKL into UML Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 01/21] um: split build in kernel and host parts Hajime Tazaki
2020-09-24 7:33 ` Anton Ivanov
2020-09-24 8:26 ` Hajime Tazaki
2020-09-24 8:37 ` Anton Ivanov
2020-09-24 7:36 ` Anton Ivanov
2020-09-24 8:13 ` Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 02/21] um: add os init and exit calls Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 03/21] um: move arch/um/os-Linux dir to tools/um/uml Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 04/21] um: host: implement os_initcalls and os_exitcalls Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 05/21] um: move arch/x86/um/os-Linux to tools/um/uml/ Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 06/21] scritps: um: suppress warnings if SRCARCH=um Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 07/21] um: extend arch_switch_to for alternate SUBARCH Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 08/21] um: add nommu mode for UML library mode Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 09/21] um: nommu: host interface Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 10/21] um: nommu: memory handling Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 11/21] um: nommu: kernel thread support Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 12/21] um: nommu: system call interface and application API Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 13/21] um: nommu: basic console support Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 14/21] um: nommu: initialization and cleanup Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 15/21] um: nommu: integrate with irq infrastructure of UML Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 16/21] um: nommu: plug in the build system Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 17/21] um: host: add nommu build for ARCH=um Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 18/21] um: host: add utilities functions Hajime Tazaki
2020-09-24 7:12 ` [RFC v6 19/21] um: host: posix host operations Hajime Tazaki
2020-09-24 7:13 ` [RFC v6 20/21] um: host: add test programs Hajime Tazaki
2020-09-24 7:13 ` [RFC v6 21/21] um: nommu: add block device support of UML Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 00/21] Unifying LKL into UML Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 01/21] um: split build in kernel and host parts Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 02/21] um: add os init and exit calls Hajime Tazaki
2020-10-07 15:13 ` Johannes Berg
2020-10-08 13:18 ` Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 03/21] um: move arch/um/os-Linux dir to tools/um/uml Hajime Tazaki
2020-10-07 15:20 ` Johannes Berg
2020-10-08 17:48 ` Octavian Purdila
2020-10-08 19:46 ` Johannes Berg
2020-10-08 20:53 ` Octavian Purdila
2020-10-09 15:59 ` Johannes Berg
2020-10-06 9:44 ` [RFC v7 04/21] um: host: implement os_initcalls and os_exitcalls Hajime Tazaki
2020-10-07 15:22 ` Johannes Berg
2020-10-08 13:16 ` Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 05/21] um: move arch/x86/um/os-Linux to tools/um/uml/ Hajime Tazaki
2020-10-07 15:23 ` Johannes Berg
2020-10-06 9:44 ` [RFC v7 06/21] scritps: um: suppress warnings if SRCARCH=um Hajime Tazaki
2020-10-07 15:24 ` Johannes Berg
2020-10-09 1:13 ` Hajime Tazaki
2020-10-09 16:00 ` Johannes Berg
2020-10-06 9:44 ` [RFC v7 07/21] um: extend arch_switch_to for alternate SUBARCH Hajime Tazaki
2020-10-07 15:25 ` Johannes Berg
2020-10-09 1:24 ` Hajime Tazaki
2020-10-09 16:02 ` Johannes Berg
2020-10-06 9:44 ` [RFC v7 08/21] um: add nommu mode for UML library mode Hajime Tazaki
2020-10-07 15:44 ` Johannes Berg
2020-10-09 3:38 ` Hajime Tazaki
2020-10-09 16:06 ` Johannes Berg
2020-10-20 8:44 ` Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 09/21] um: nommu: host interface Hajime Tazaki
2020-10-07 15:45 ` Johannes Berg
2020-10-08 18:10 ` Octavian Purdila
2020-10-06 9:44 ` [RFC v7 10/21] um: nommu: memory handling Hajime Tazaki
2020-10-07 15:47 ` Johannes Berg
2020-10-08 18:07 ` Octavian Purdila
2020-10-06 9:44 ` [RFC v7 11/21] um: nommu: kernel thread support Hajime Tazaki
2020-10-07 18:57 ` Johannes Berg
2020-10-08 18:54 ` Octavian Purdila
2020-10-08 19:39 ` Johannes Berg
2020-10-08 20:25 ` Octavian Purdila
2020-10-06 9:44 ` [RFC v7 12/21] um: nommu: system call interface and application API Hajime Tazaki
2020-10-07 19:05 ` Johannes Berg
2020-10-08 19:03 ` Octavian Purdila
2020-10-08 19:40 ` Johannes Berg
2020-10-06 9:44 ` [RFC v7 13/21] um: nommu: basic console support Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 14/21] um: nommu: initialization and cleanup Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 15/21] um: nommu: integrate with irq infrastructure of UML Hajime Tazaki
2020-10-07 19:09 ` Johannes Berg
2020-10-06 9:44 ` [RFC v7 16/21] um: nommu: plug in the build system Hajime Tazaki
2020-10-07 19:20 ` Johannes Berg
2020-10-09 7:40 ` Hajime TAZAKI
2020-10-06 9:44 ` [RFC v7 17/21] um: host: add nommu build for ARCH=um Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 18/21] um: host: add utilities functions Hajime Tazaki
2020-10-07 14:53 ` Anton Ivanov
2020-10-07 15:02 ` Johannes Berg
2020-10-07 15:03 ` Johannes Berg
2020-10-07 15:10 ` Anton Ivanov
2020-10-08 12:52 ` Hajime Tazaki
2020-10-08 19:19 ` Octavian Purdila
2020-10-08 12:53 ` Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 19/21] um: host: posix host operations Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 20/21] um: host: add test programs Hajime Tazaki
2020-10-07 19:23 ` Johannes Berg
2020-10-09 6:24 ` Hajime Tazaki
2020-10-06 9:44 ` [RFC v7 21/21] um: nommu: add block device support of UML Hajime Tazaki
2020-10-07 14:17 ` Anton Ivanov
2020-10-08 12:13 ` Hajime Tazaki
2020-10-07 13:30 ` [RFC v7 00/21] Unifying LKL into UML Anton Ivanov
2020-10-08 12:12 ` Hajime Tazaki
2020-10-08 12:50 ` Anton Ivanov
2020-10-08 17:13 ` Octavian Purdila
2020-10-08 17:18 ` Anton Ivanov
2020-10-08 17:24 ` Octavian Purdila
2021-01-20 2:27 ` [RFC v8 00/20] " Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 01/20] um: split build in kernel and host parts Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 02/20] um: move arch/um/os-Linux dir to tools/um/uml Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 03/20] um: move arch/x86/um/os-Linux to tools/um/uml/ Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 04/20] um: implement os_initcalls and os_exitcalls Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 05/20] um: extend arch_switch_to for alternate SUBARCH Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 06/20] um: add UML library mode Hajime Tazaki
2021-03-14 16:49 ` Johannes Berg
2021-03-16 1:17 ` Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 07/20] um: lkl: host interface Hajime Tazaki
2021-03-14 16:50 ` Johannes Berg
2021-03-16 1:17 ` Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 08/20] um: lkl: memory handling Hajime Tazaki
2021-03-14 16:53 ` Johannes Berg
2021-03-16 1:18 ` Hajime Tazaki
2021-03-16 21:31 ` Johannes Berg
2021-03-18 0:12 ` Hajime Tazaki
2021-03-18 8:00 ` Johannes Berg
2021-01-20 2:27 ` [RFC v8 09/20] um: lkl: kernel thread support Hajime Tazaki
2021-03-14 17:01 ` Johannes Berg
2021-03-16 1:18 ` Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 10/20] um: lkl: system call interface and application API Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 11/20] um: lkl: basic console support Hajime Tazaki
2021-03-14 20:42 ` Johannes Berg
2021-03-16 1:19 ` Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 12/20] um: lkl: initialization and cleanup Hajime Tazaki
2021-03-14 20:40 ` Johannes Berg
2021-03-16 1:19 ` Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 13/20] um: lkl: integrate with irq infrastructure of UML Hajime Tazaki
2021-03-14 20:45 ` Johannes Berg
2021-03-16 1:20 ` Hajime Tazaki
2021-03-16 21:36 ` Johannes Berg
2021-01-20 2:27 ` [RFC v8 14/20] um: lkl: plug in the build system Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 15/20] um: host: add library mode build for ARCH=um Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 16/20] um: host: add utilities functions Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 17/20] um: host: posix host operations Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 18/20] selftests/um: lkl: add test programs for library mode of UML Hajime Tazaki
2021-01-20 2:27 ` [RFC v8 19/20] um: lkl: add block device support " Hajime Tazaki
2021-03-14 20:37 ` Johannes Berg
2021-03-16 1:19 ` Hajime Tazaki
2021-03-16 21:32 ` Johannes Berg
2021-03-17 14:19 ` Octavian Purdila
2021-03-17 14:28 ` Johannes Berg
2021-03-18 0:15 ` Hajime Tazaki
2021-03-18 0:43 ` Octavian Purdila
2021-01-20 2:27 ` [RFC v8 20/20] um: lkl: add documentation Hajime Tazaki
2021-03-14 21:03 ` [RFC v8 00/20] Unifying LKL into UML Johannes Berg
2021-03-16 1:17 ` Hajime Tazaki
2021-03-16 21:29 ` Johannes Berg
2021-03-17 14:03 ` Octavian Purdila
2021-03-17 14:24 ` Johannes Berg
2021-03-18 14:17 ` Hajime Tazaki
2021-03-18 16:28 ` Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=94b12a3395df2184c2faa9a95393166fc7fca46a.1585579244.git.thehajime@gmail.com \
--to=thehajime@gmail.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel-library@freelists.org \
--cc=linux-um@lists.infradead.org \
--cc=retrage01@gmail.com \
--cc=tavi.purdila@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).