linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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)

  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).