All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/9] um: Migrate pcap to vector IO
@ 2019-12-17 10:09 anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 2/9] um: vector: Add UCAST and MCAST trasnports anton.ivanov
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: anton.ivanov @ 2019-12-17 10:09 UTC (permalink / raw)
  To: linux-um; +Cc: richard, brendanhiggins, Anton Ivanov

From: Anton Ivanov <anton.ivanov@cambridgegreys.com>

Migrates UML PCAP driver to the new vector IO network backend.

Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
---
 arch/um/drivers/Makefile          |   4 +-
 arch/um/drivers/net_kern.c        |  33 ++++++-
 arch/um/drivers/pcap_kern.c       | 113 -----------------------
 arch/um/drivers/pcap_user.c       | 144 +++++++-----------------------
 arch/um/drivers/pcap_user.h       |  21 -----
 arch/um/drivers/vector_kern.c     | 100 +++++++++++++++++++--
 arch/um/drivers/vector_kern.h     |   3 -
 arch/um/drivers/vector_user.c     |  12 +++
 arch/um/drivers/vector_user.h     |   1 -
 arch/um/include/shared/net_kern.h |   2 +-
 arch/um/include/shared/net_user.h |   2 +
 11 files changed, 173 insertions(+), 262 deletions(-)
 delete mode 100644 arch/um/drivers/pcap_kern.c
 delete mode 100644 arch/um/drivers/pcap_user.h

diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index a290821e355c..ea449dc72236 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -22,9 +22,9 @@ LDFLAGS_pcap.o := -r $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libpcap.a)
 
 LDFLAGS_vde.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libvdeplug.a)
 
-targets := pcap_kern.o pcap_user.o vde_kern.o vde_user.o
+targets := pcap_user.o vde_kern.o vde_user.o
 
-$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o
+$(obj)/pcap.o: $(obj)/pcap_user.o
 	$(LD) -r -dp -o $@ $^ $(ld_flags)
 
 $(obj)/vde.o: $(obj)/vde_kern.o $(obj)/vde_user.o
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 327b728f7244..821107c75582 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -42,6 +42,9 @@ static DEFINE_SPINLOCK(drop_lock);
 static struct sk_buff *drop_skb;
 static int drop_max;
 
+static const char *migrated_to_vector[] = {"pcap"};
+#define MAX_MIGRATED 1
+
 static int update_drop_skb(int max)
 {
 	struct sk_buff *new;
@@ -581,6 +584,26 @@ static int check_transport(struct transport *transport, char *eth, int n,
 	}
 	return 1;
 }
+static int register_compat(void)
+{
+	struct list_head *ele, *next;
+	struct eth_init *eth;
+	int compat;
+
+	list_for_each_safe(ele, next, &eth_cmd_line) {
+		eth = list_entry(ele, struct eth_init, list);
+		for (compat = 0; compat < MAX_MIGRATED; compat++) {
+			if (strncmp(eth->init, &migrated_to_vector[compat], strlen(&migrated_to_vector[compat])) == 0) {
+				vector_compat_eth_configure(eth->init, eth->index);
+				list_del(&eth->list);
+				continue;
+			}
+		}
+	}
+	return 0;
+}
+
+late_initcall(register_compat);
 
 void register_transport(struct transport *new)
 {
@@ -597,8 +620,9 @@ void register_transport(struct transport *new)
 
 	list_for_each_safe(ele, next, &eth_cmd_line) {
 		eth = list_entry(ele, struct eth_init, list);
+
 		match = check_transport(new, eth->init, eth->index, &init,
-					&mac, GFP_KERNEL);
+				&mac, GFP_KERNEL);
 		if (!match)
 			continue;
 		else if (init != NULL) {
@@ -615,7 +639,12 @@ static int eth_setup_common(char *str, int index)
 	struct transport *transport;
 	void *init;
 	char *mac = NULL;
-	int found = 0;
+	int found = 0, compat;
+
+	for (compat = 0; compat < MAX_MIGRATED; compat++) {
+		if (strncmp(str, &migrated_to_vector[compat], strlen(&migrated_to_vector[compat])) == 0)
+			return vector_compat_eth_configure(str, index);
+	}
 
 	spin_lock(&transports_lock);
 	list_for_each(ele, &transports) {
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
deleted file mode 100644
index cfe4cb17694c..000000000000
--- a/arch/um/drivers/pcap_kern.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- */
-
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <net_kern.h>
-#include "pcap_user.h"
-
-struct pcap_init {
-	char *host_if;
-	int promisc;
-	int optimize;
-	char *filter;
-};
-
-void pcap_init(struct net_device *dev, void *data)
-{
-	struct uml_net_private *pri;
-	struct pcap_data *ppri;
-	struct pcap_init *init = data;
-
-	pri = netdev_priv(dev);
-	ppri = (struct pcap_data *) pri->user;
-	ppri->host_if = init->host_if;
-	ppri->promisc = init->promisc;
-	ppri->optimize = init->optimize;
-	ppri->filter = init->filter;
-
-	printk("pcap backend, host interface %s\n", ppri->host_if);
-}
-
-static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	return pcap_user_read(fd, skb_mac_header(skb),
-			      skb->dev->mtu + ETH_HEADER_OTHER,
-			      (struct pcap_data *) &lp->user);
-}
-
-static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	return -EPERM;
-}
-
-static const struct net_kern_info pcap_kern_info = {
-	.init			= pcap_init,
-	.protocol		= eth_protocol,
-	.read			= pcap_read,
-	.write			= pcap_write,
-};
-
-int pcap_setup(char *str, char **mac_out, void *data)
-{
-	struct pcap_init *init = data;
-	char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
-	int i;
-
-	*init = ((struct pcap_init)
-		{ .host_if 	= "eth0",
-		  .promisc 	= 1,
-		  .optimize 	= 0,
-		  .filter 	= NULL });
-
-	remain = split_if_spec(str, &host_if, &init->filter,
-			       &options[0], &options[1], mac_out, NULL);
-	if (remain != NULL) {
-		printk(KERN_ERR "pcap_setup - Extra garbage on "
-		       "specification : '%s'\n", remain);
-		return 0;
-	}
-
-	if (host_if != NULL)
-		init->host_if = host_if;
-
-	for (i = 0; i < ARRAY_SIZE(options); i++) {
-		if (options[i] == NULL)
-			continue;
-		if (!strcmp(options[i], "promisc"))
-			init->promisc = 1;
-		else if (!strcmp(options[i], "nopromisc"))
-			init->promisc = 0;
-		else if (!strcmp(options[i], "optimize"))
-			init->optimize = 1;
-		else if (!strcmp(options[i], "nooptimize"))
-			init->optimize = 0;
-		else {
-			printk(KERN_ERR "pcap_setup : bad option - '%s'\n",
-			       options[i]);
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-static struct transport pcap_transport = {
-	.list 		= LIST_HEAD_INIT(pcap_transport.list),
-	.name 		= "pcap",
-	.setup  	= pcap_setup,
-	.user 		= &pcap_user_info,
-	.kern 		= &pcap_kern_info,
-	.private_size 	= sizeof(struct pcap_data),
-	.setup_size 	= sizeof(struct pcap_init),
-};
-
-static int register_pcap(void)
-{
-	register_transport(&pcap_transport);
-	return 0;
-}
-
-late_initcall(register_pcap);
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index bbd20638788a..0b49a2e76c9a 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -8,130 +8,50 @@
 #include <string.h>
 #include <asm/types.h>
 #include <net_user.h>
-#include "pcap_user.h"
+#include <sys/socket.h>
+#include <linux/filter.h>
 #include <um_malloc.h>
 
-#define PCAP_FD(p) (*(int *)(p))
-
-static int pcap_user_init(void *data, void *dev)
+void *uml_vector_compile_pcap(char *filter, int optimize)
 {
-	struct pcap_data *pri = data;
-	pcap_t *p;
-	char errors[PCAP_ERRBUF_SIZE];
-
-	p = pcap_open_live(pri->host_if, ETH_MAX_PACKET + ETH_HEADER_OTHER,
-			   pri->promisc, 0, errors);
-	if (p == NULL) {
-		printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
-		       "'%s'\n", errors);
-		return -EINVAL;
-	}
+	struct sock_fprog *bpf_prog = NULL;
+	struct bpf_program *pcap_prog = NULL;
 
-	pri->dev = dev;
-	pri->pcap = p;
-	return 0;
-}
-
-static int pcap_open(void *data)
-{
-	struct pcap_data *pri = data;
-	__u32 netmask;
-	int err;
+	if (filter == NULL)
+		return NULL;
 
-	if (pri->pcap == NULL)
-		return -ENODEV;
+	pcap_prog = uml_kmalloc(sizeof(struct bpf_program), UM_GFP_KERNEL);
+	if (!pcap_prog)
+		goto pcap_failed;
 
-	if (pri->filter != NULL) {
-		err = dev_netmask(pri->dev, &netmask);
-		if (err < 0) {
-			printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n");
-			return -EIO;
-		}
+	bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL);
+	if (!bpf_prog)
+		goto pcap_failed;
+	else
+		bpf_prog->filter = NULL;
 
-		pri->compiled = uml_kmalloc(sizeof(struct bpf_program),
-					UM_GFP_KERNEL);
-		if (pri->compiled == NULL) {
-			printk(UM_KERN_ERR "pcap_open : kmalloc failed\n");
-			return -ENOMEM;
-		}
-
-		err = pcap_compile(pri->pcap,
-				   (struct bpf_program *) pri->compiled,
-				   pri->filter, pri->optimize, netmask);
-		if (err < 0) {
-			printk(UM_KERN_ERR "pcap_open : pcap_compile failed - "
-			       "'%s'\n", pcap_geterr(pri->pcap));
-			goto out;
-		}
-
-		err = pcap_setfilter(pri->pcap, pri->compiled);
-		if (err < 0) {
-			printk(UM_KERN_ERR "pcap_open : pcap_setfilter "
-			       "failed - '%s'\n", pcap_geterr(pri->pcap));
-			goto out;
-		}
+	if (pcap_compile_nopcap((1 < 16) - 1, DLT_EN10MB, pcap_prog, filter, optimize, PCAP_NETMASK_UNKNOWN)) {
+		printk(KERN_ERR "Failed to compile filter");
+		goto pcap_failed;
 	}
 
-	return PCAP_FD(pri->pcap);
-
- out:
-	kfree(pri->compiled);
-	return -EIO;
-}
-
-static void pcap_remove(void *data)
-{
-	struct pcap_data *pri = data;
-
-	if (pri->compiled != NULL)
-		pcap_freecode(pri->compiled);
-
-	if (pri->pcap != NULL)
-		pcap_close(pri->pcap);
-}
-
-struct pcap_handler_data {
-	char *buffer;
-	int len;
-};
+	bpf_prog->filter = uml_kmalloc(pcap_prog->bf_len * sizeof(struct bpf_insn), UM_GFP_KERNEL);
 
-static void handler(u_char *data, const struct pcap_pkthdr *header,
-		    const u_char *packet)
-{
-	int len;
+	if (bpf_prog->filter == NULL) {
+		printk(KERN_ERR "Failed to allocate bpf buffer");
+		pcap_freecode(pcap_prog);
+		goto pcap_failed;
+	}
+	bpf_prog->len = pcap_prog->bf_len;
+	memcpy(bpf_prog->filter, pcap_prog->bf_insns, pcap_prog->bf_len * sizeof(struct bpf_insn));
 
-	struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
+	pcap_freecode(pcap_prog);
+	return bpf_prog;
 
-	len = hdata->len < header->caplen ? hdata->len : header->caplen;
-	memcpy(hdata->buffer, packet, len);
-	hdata->len = len;
+pcap_failed:
+	kfree(pcap_prog);
+	kfree(bpf_prog);
+	return NULL;
 }
 
-int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
-{
-	struct pcap_handler_data hdata = ((struct pcap_handler_data)
-		                          { .buffer  	= buffer,
-					    .len 	= len });
-	int n;
-
-	n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
-	if (n < 0) {
-		printk(UM_KERN_ERR "pcap_dispatch failed - %s\n",
-		       pcap_geterr(pri->pcap));
-		return -EIO;
-	}
-	else if (n == 0)
-		return 0;
-	return hdata.len;
-}
 
-const struct net_user_info pcap_user_info = {
-	.init		= pcap_user_init,
-	.open		= pcap_open,
-	.close	 	= NULL,
-	.remove	 	= pcap_remove,
-	.add_address	= NULL,
-	.delete_address = NULL,
-	.mtu		= ETH_MAX_PACKET,
-	.max_packet	= ETH_MAX_PACKET + ETH_HEADER_OTHER,
-};
diff --git a/arch/um/drivers/pcap_user.h b/arch/um/drivers/pcap_user.h
deleted file mode 100644
index 216246f5f09b..000000000000
--- a/arch/um/drivers/pcap_user.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- */
-
-#include <net_user.h>
-
-struct pcap_data {
-	char *host_if;
-	int promisc;
-	int optimize;
-	char *filter;
-	void *compiled;
-	void *pcap;
-	void *dev;
-};
-
-extern const struct net_user_info pcap_user_info;
-
-extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
-
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index 92617e16829e..933adf2009dc 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -28,6 +28,7 @@
 #include <irq_kern.h>
 #include <irq_user.h>
 #include <net_kern.h>
+#include <net_user.h>
 #include <os.h>
 #include "mconsole_kern.h"
 #include "vector_user.h"
@@ -46,6 +47,7 @@
 
 
 #define DRIVER_NAME "uml-vector"
+#define DRIVER_CNAME "uml-vector-compat"
 #define DRIVER_VERSION "01"
 struct vector_cmd_line_arg {
 	struct list_head list;
@@ -68,7 +70,7 @@ static LIST_HEAD(vector_devices);
 
 static int driver_registered;
 
-static void vector_eth_configure(int n, struct arglist *def);
+static void vector_eth_configure(int n, struct arglist *def, bool compat);
 
 /* Argument accessors to set variables (and/or set default values)
  * mtu, buffer sizing, default headroom, etc
@@ -101,6 +103,7 @@ static const struct {
 };
 
 #define VECTOR_NUM_STATS	ARRAY_SIZE(ethtool_stats_keys)
+#define MAX_COMPAT_ARG 256
 
 static void vector_reset_stats(struct vector_private *vp)
 {
@@ -131,11 +134,28 @@ static int get_mtu(struct arglist *def)
 	return ETH_MAX_PACKET;
 }
 
+static int get_optimize(struct arglist *def)
+{
+	char *opt = uml_vector_fetch_arg(def, "optimize");
+	long result;
+
+	if (opt != NULL) {
+		if (kstrtoul(opt, 10, &result) == 0)
+			return result;
+	}
+	return 0;
+}
+
 static char *get_bpf_file(struct arglist *def)
 {
 	return uml_vector_fetch_arg(def, "bpffile");
 }
 
+static char *get_pcap_filter(struct arglist *def)
+{
+	return uml_vector_fetch_arg(def, "filter");
+}
+
 static bool get_bpf_flash(struct arglist *def)
 {
 	char *allow = uml_vector_fetch_arg(def, "bpfflash");
@@ -772,7 +792,7 @@ static int vector_config(char *str, char **error_out)
 		return -EINVAL;
 	}
 
-	vector_eth_configure(n, parsed);
+	vector_eth_configure(n, parsed, false);
 	return 0;
 }
 
@@ -1225,7 +1245,14 @@ static int vector_net_open(struct net_device *dev)
 	vp->opened = true;
 	spin_unlock_irqrestore(&vp->lock, flags);
 
-	vp->bpf = uml_vector_user_bpf(get_bpf_file(vp->parsed));
+#ifdef CONFIG_UML_NET_PCAP
+	vp->bpf = uml_vector_compile_pcap(get_pcap_filter(vp->parsed), get_optimize(vp->parsed));
+#else
+	vp->bpf = NULL;
+#endif
+
+	if (!vp->bpf)
+		vp->bpf = uml_vector_user_bpf(get_bpf_file(vp->parsed));
 
 	vp->fds = uml_vector_user_open(vp->unit, vp->parsed);
 
@@ -1547,7 +1574,8 @@ static void vector_timer_expire(struct timer_list *t)
 
 static void vector_eth_configure(
 		int n,
-		struct arglist *def
+		struct arglist *def,
+		bool compat
 	)
 {
 	struct vector_device *device;
@@ -1577,7 +1605,10 @@ static void vector_eth_configure(
 	 * netdevice, that is OK, register_netdev{,ice}() will notice this
 	 * and fail.
 	 */
-	snprintf(dev->name, sizeof(dev->name), "vec%d", n);
+	if (compat)
+		snprintf(dev->name, sizeof(dev->name), "eth%d", n);
+	else
+		snprintf(dev->name, sizeof(dev->name), "vec%d", n);
 	uml_net_setup_etheraddr(dev, uml_vector_fetch_arg(def, "mac"));
 	vp = netdev_priv(dev);
 
@@ -1587,7 +1618,10 @@ static void vector_eth_configure(
 		driver_registered = 1;
 	}
 	device->pdev.id = n;
-	device->pdev.name = DRIVER_NAME;
+	if (compat)
+		device->pdev.name = DRIVER_CNAME;
+	else
+		device->pdev.name = DRIVER_NAME;
 	device->pdev.dev.release = vector_device_release;
 	dev_set_drvdata(&device->pdev.dev, device);
 	if (platform_device_register(&device->pdev))
@@ -1660,7 +1694,59 @@ static void vector_eth_configure(
 	kfree(device);
 }
 
+int vector_compat_eth_configure(char *str, int index)
+{
+	char *newargs, *tempargs;
+	char *remain;
+	int do_compat = 0;
+	struct arglist *parsed;
+	newargs = kmalloc(GFP_KERNEL, MAX_COMPAT_ARG);
+	if (!newargs)
+		return -ENOMEM;
+	tempargs = kmalloc(GFP_KERNEL, MAX_COMPAT_ARG);
+	if (!tempargs) {
+		kfree(newargs);
+		return -ENOMEM;
+	}
+	if (strncmp(str, "pcap", strlen("pcap")) == 0) {
+		char *ifname = NULL, *filter = NULL, *transport = NULL, *mac = NULL;
+		char *options[2] = { NULL, NULL};
+
+		remain = split_if_spec(str, &transport, &ifname, &filter,
+			       &options[0], &options[1], &mac, NULL);
+
+		if ((mac != NULL) && strlen(mac) > 0)
+			snprintf(tempargs, MAX_COMPAT_ARG, "transport=raw,ifname=%s,mac=%s", ifname, mac);
+		else
+			snprintf(tempargs, MAX_COMPAT_ARG, "transport=raw,ifname=%s", ifname);
+
+		strcpy(newargs, tempargs);
+
+		if (filter != NULL) {
+			snprintf(tempargs, MAX_COMPAT_ARG, "%s,filter=%s", newargs, filter);
+			strcpy(newargs, tempargs);
+		}
 
+		if (options[0] != NULL) {
+			snprintf(tempargs, MAX_COMPAT_ARG, "%s,%s=1", newargs, options[0]);
+			strcpy(newargs, tempargs);
+		}
+		if (options[1] != NULL) {
+			snprintf(tempargs, MAX_COMPAT_ARG, "%s,%s=1", newargs, options[1]);
+			strcpy(newargs, tempargs);
+		}
+		do_compat = 1;
+
+	}
+	if (do_compat) {
+		parsed = uml_parse_vector_ifspec(newargs);
+		vector_eth_configure(index, parsed, true);
+	} else
+		kfree(newargs);
+
+	kfree(tempargs);
+	return 0;
+}
 
 
 /*
@@ -1677,7 +1763,7 @@ static int __init vector_init(void)
 		def = list_entry(ele, struct vector_cmd_line_arg, list);
 		parsed = uml_parse_vector_ifspec(def->arguments);
 		if (parsed != NULL)
-			vector_eth_configure(def->unit, parsed);
+			vector_eth_configure(def->unit, parsed, false);
 	}
 	return 0;
 }
diff --git a/arch/um/drivers/vector_kern.h b/arch/um/drivers/vector_kern.h
index d0159082faf0..e643423dfc2f 100644
--- a/arch/um/drivers/vector_kern.h
+++ b/arch/um/drivers/vector_kern.h
@@ -31,9 +31,6 @@
 #define VECTOR_QDISC_BYPASS (1 << 3)
 #define VECTOR_BPF_FLASH (1 << 4)
 
-#define ETH_MAX_PACKET 1500
-#define ETH_HEADER_OTHER 32 /* just in case someone decides to go mad on QnQ */
-
 #define MAX_FILTER_PROG (2 << 16)
 
 struct vector_queue {
diff --git a/arch/um/drivers/vector_user.c b/arch/um/drivers/vector_user.c
index ddcd917be0af..c8a11df080d2 100644
--- a/arch/um/drivers/vector_user.c
+++ b/arch/um/drivers/vector_user.c
@@ -367,6 +367,17 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
 		err = -errno;
 		goto raw_cleanup;
 	}
+
+	if (uml_vector_fetch_arg(ifspec, "promisc")) {
+		struct ifreq ifopts;
+
+		memset(&ifopts, 0, sizeof(struct ifreq));
+		strncpy(ifopts.ifr_name, iface, IFNAMSIZ-1);
+		ioctl(rxfd, SIOCGIFFLAGS, &ifopts);
+		ifopts.ifr_flags |= IFF_PROMISC;
+		ioctl(rxfd, SIOCSIFFLAGS, &ifopts);
+	}
+
 	txfd = create_raw_fd(iface, 0, ETH_P_IP); /* Turn off RX on this fd */
 	if (txfd == -1) {
 		err = -errno;
@@ -764,3 +775,4 @@ void *uml_vector_user_bpf(char *filename)
 	kfree(bpf_prog);
 	return NULL;
 }
+
diff --git a/arch/um/drivers/vector_user.h b/arch/um/drivers/vector_user.h
index 91f35b266aba..a4acfebd28d5 100644
--- a/arch/um/drivers/vector_user.h
+++ b/arch/um/drivers/vector_user.h
@@ -105,5 +105,4 @@ extern bool uml_raw_enable_qdisc_bypass(int fd);
 extern bool uml_raw_enable_vnet_headers(int fd);
 extern bool uml_tap_enable_vnet_headers(int fd);
 
-
 #endif
diff --git a/arch/um/include/shared/net_kern.h b/arch/um/include/shared/net_kern.h
index a87be13c5b87..f9389a2ec2d8 100644
--- a/arch/um/include/shared/net_kern.h
+++ b/arch/um/include/shared/net_kern.h
@@ -66,6 +66,6 @@ extern int tap_setup_common(char *str, char *type, char **dev_name,
 extern void register_transport(struct transport *new);
 extern unsigned short eth_protocol(struct sk_buff *skb);
 extern void uml_net_setup_etheraddr(struct net_device *dev, char *str);
-
+extern int vector_compat_eth_configure(char *str, int index);
 
 #endif
diff --git a/arch/um/include/shared/net_user.h b/arch/um/include/shared/net_user.h
index 1b0531769a5e..b523e469256c 100644
--- a/arch/um/include/shared/net_user.h
+++ b/arch/um/include/shared/net_user.h
@@ -50,4 +50,6 @@ extern char *split_if_spec(char *str, ...);
 
 extern int dev_netmask(void *d, void *m);
 
+extern void *uml_vector_compile_pcap(char *filter, int optimize);
+
 #endif
-- 
2.20.1


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 2/9] um: vector: Add UCAST and MCAST trasnports
  2019-12-17 10:09 [PATCH v4 1/9] um: Migrate pcap to vector IO anton.ivanov
@ 2019-12-17 10:09 ` anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 3/9] um: Migrate socket transport to Vector backend anton.ivanov
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: anton.ivanov @ 2019-12-17 10:09 UTC (permalink / raw)
  To: linux-um; +Cc: richard, brendanhiggins, Anton Ivanov

From: Anton Ivanov <anton.ivanov@cambridgegreys.com>

Add Unicast "bare" packet and Multicast "bare" packet transports
compatible with legacy QEMU and UML

Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
---
 arch/um/drivers/Kconfig             | 19 ++++-----
 arch/um/drivers/vector_kern.c       |  2 +
 arch/um/drivers/vector_transports.c |  8 +++-
 arch/um/drivers/vector_user.c       | 66 +++++++++++++++++++++++++----
 arch/um/drivers/vector_user.h       |  6 +++
 5 files changed, 79 insertions(+), 22 deletions(-)

diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig
index 388096fb45a2..494c778893ce 100644
--- a/arch/um/drivers/Kconfig
+++ b/arch/um/drivers/Kconfig
@@ -268,7 +268,7 @@ config UML_NET_VDE
 
 config UML_NET_MCAST
 	bool "Multicast transport"
-	depends on UML_NET
+	depends on UML_NET && UML_NET_VECTOR
 	help
 	  This Multicast User-Mode Linux network transport allows multiple
 	  UMLs (even ones running on different host machines!) to talk to
@@ -293,19 +293,16 @@ config UML_NET_MCAST
 
 config UML_NET_PCAP
 	bool "pcap transport"
-	depends on UML_NET
+	depends on UML_NET && UML_NET_VECTOR
 	help
-	The pcap transport makes a pcap packet stream on the host look
-	like an ethernet device inside UML.  This is useful for making
-	UML act as a network monitor for the host.  You must have libcap
-	installed in order to build the pcap transport into UML.
+	 The PCAP transport provides emulation for the old PCAP transport
+	 behaviour using the new VECTOR RAW backend so that any existing
+	 scripts or setups which rely on ethX=pcap still work.
 
-	  For more information, see
-	  <http://user-mode-linux.sourceforge.net/old/networking.html>  That site
-	  has examples of the UML command line to use to enable this option.
+	 It is recommended to use VECTOR RAW directly instead because
+	 it provides a number of options which are otherwise unavailable
+	 via this interface.
 
-	If you intend to use UML as a network monitor for the host, say
-	Y here.  Otherwise, say N.
 
 config UML_NET_SLIRP
 	bool "SLiRP transport"
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index 933adf2009dc..1388f09e09ea 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -1708,6 +1708,7 @@ int vector_compat_eth_configure(char *str, int index)
 		kfree(newargs);
 		return -ENOMEM;
 	}
+#ifdef CONFIG_UML_NET_PCAP
 	if (strncmp(str, "pcap", strlen("pcap")) == 0) {
 		char *ifname = NULL, *filter = NULL, *transport = NULL, *mac = NULL;
 		char *options[2] = { NULL, NULL};
@@ -1738,6 +1739,7 @@ int vector_compat_eth_configure(char *str, int index)
 		do_compat = 1;
 
 	}
+#endif
 	if (do_compat) {
 		parsed = uml_parse_vector_ifspec(newargs);
 		vector_eth_configure(index, parsed, true);
diff --git a/arch/um/drivers/vector_transports.c b/arch/um/drivers/vector_transports.c
index 0794d23f07cb..e99d3baec80b 100644
--- a/arch/um/drivers/vector_transports.c
+++ b/arch/um/drivers/vector_transports.c
@@ -465,7 +465,7 @@ static int build_tap_transport_data(struct vector_private *vp)
 }
 
 
-static int build_bess_transport_data(struct vector_private *vp)
+static int build_no_header_transport_data(struct vector_private *vp)
 {
 	vp->form_header = NULL;
 	vp->verify_header = NULL;
@@ -489,7 +489,11 @@ int build_transport_data(struct vector_private *vp)
 	if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0)
 		return build_hybrid_transport_data(vp);
 	if (strncmp(transport, TRANS_BESS, TRANS_BESS_LEN) == 0)
-		return build_bess_transport_data(vp);
+		return build_no_header_transport_data(vp);
+	if (strncmp(transport, TRANS_UCAST, TRANS_UCAST_LEN) == 0)
+		return build_no_header_transport_data(vp);
+	if (strncmp(transport, TRANS_MCAST, TRANS_MCAST_LEN) == 0)
+		return build_no_header_transport_data(vp);
 	return 0;
 }
 
diff --git a/arch/um/drivers/vector_user.c b/arch/um/drivers/vector_user.c
index c8a11df080d2..7f95318d88d2 100644
--- a/arch/um/drivers/vector_user.c
+++ b/arch/um/drivers/vector_user.c
@@ -35,7 +35,9 @@
 #define ID_GRE 0
 #define ID_L2TPV3 1
 #define ID_BESS 2
-#define ID_MAX 2
+#define ID_UCAST 3
+#define ID_MCAST 4
+#define ID_MAX 4
 
 #define TOKEN_IFNAME "ifname"
 
@@ -44,7 +46,7 @@
 
 #define VNET_HDR_FAIL "could not enable vnet headers on fd %d"
 #define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s"
-#define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i"
+#define SOCK_BIND_FAIL "socket_open : could not bind socket err=%i"
 #define UNIX_BIND_FAIL "unix_open : could not bind socket err=%i"
 #define BPF_ATTACH_FAIL "Failed to attach filter size %d prog %px to %d, err %d\n"
 #define BPF_DETACH_FAIL "Failed to detach filter size %d prog %px to %d, err %d\n"
@@ -443,7 +445,7 @@ bool uml_tap_enable_vnet_headers(int fd)
 static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id)
 {
 	int err = -ENOMEM;
-	int fd = -1, gairet;
+	int fd = -1, gairet, ttl = 1, yes = 1;
 	struct addrinfo srchints;
 	struct addrinfo dsthints;
 	bool v6, udp;
@@ -473,10 +475,10 @@ static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id)
 
 	memset(&dsthints, 0, sizeof(dsthints));
 
-	if (v6)
-		dsthints.ai_family = AF_INET6;
-	else
+	if ((!v6) || (id == ID_MCAST))
 		dsthints.ai_family = AF_INET;
+	else
+		dsthints.ai_family = AF_INET6;
 
 	switch (id) {
 	case ID_GRE:
@@ -492,13 +494,18 @@ static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id)
 			dsthints.ai_protocol = IPPROTO_L2TP;
 		}
 		break;
+	case ID_UCAST:
+	case ID_MCAST:
+		dsthints.ai_socktype = SOCK_DGRAM;
+		dsthints.ai_protocol = 0;
+		break;
 	default:
 		printk(KERN_ERR "Unsupported socket type\n");
 		return NULL;
 	}
 	memcpy(&srchints, &dsthints, sizeof(struct addrinfo));
 
-	gairet = getaddrinfo(src, srcport, &dsthints, &gairesult);
+	gairet = getaddrinfo(src, srcport, &srchints, &gairesult);
 	if ((gairet != 0) || (gairesult == NULL)) {
 		printk(UM_KERN_ERR
 			"socket_open : could not resolve src, error = %s",
@@ -515,12 +522,50 @@ static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id)
 		);
 		goto cleanup;
 	}
+	if (id == ID_MCAST) {
+		value = uml_vector_fetch_arg(ifspec, "ttl");
+		if (value != NULL) {
+			ttl = strtol((const char *) value, NULL, 10);
+			if ((ttl < 1) || (ttl > 255))
+				ttl = 1;
+		}
+		if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) {
+			err = -errno;
+			printk(UM_KERN_ERR "umcast_open: IP_MULTICAST_TTL "
+			       "failed, error = %d\n", errno);
+			goto cleanup;
+		}
+		if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
+			err = -errno;
+			printk(UM_KERN_ERR "umcast_open: IP_MULTICAST_LOOP "
+			       "failed, error = %d\n", errno);
+			goto cleanup;
+		}
+	}
 	if (bind(fd,
 		(struct sockaddr *) gairesult->ai_addr,
 		gairesult->ai_addrlen)) {
-		printk(UM_KERN_ERR L2TPV3_BIND_FAIL, errno);
+		printk(UM_KERN_ERR SOCK_BIND_FAIL, errno);
 		goto cleanup;
 	}
+	if (id == ID_MCAST) {
+		struct ip_mreq mreq;
+
+		mreq.imr_multiaddr = ((struct sockaddr_in *) gairesult->ai_addr)->sin_addr;
+		mreq.imr_interface.s_addr = 0;
+		if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
+			err = -errno;
+			printk(UM_KERN_ERR "umcast_open: IP_ADD_MEMBERSHIP "
+			       "failed, error = %d\n", errno);
+			printk(UM_KERN_ERR "There appears not to be a "
+			       "multicast-capable network interface on the "
+			       "host.\n");
+			printk(UM_KERN_ERR "eth0 should be configured in order "
+			       "to use the multicast transport.\n");
+			goto cleanup;
+		}
+
+	}
 
 	if (gairesult != NULL)
 		freeaddrinfo(gairesult);
@@ -594,6 +639,10 @@ struct vector_fds *uml_vector_user_open(
 		return user_init_socket_fds(parsed, ID_L2TPV3);
 	if (strncmp(transport, TRANS_BESS, TRANS_BESS_LEN) == 0)
 		return user_init_unix_fds(parsed, ID_BESS);
+	if (strncmp(transport, TRANS_UCAST, TRANS_UCAST_LEN) == 0)
+		return user_init_socket_fds(parsed, ID_UCAST);
+	if (strncmp(transport, TRANS_MCAST, TRANS_MCAST_LEN) == 0)
+		return user_init_socket_fds(parsed, ID_MCAST);
 	return NULL;
 }
 
@@ -775,4 +824,3 @@ void *uml_vector_user_bpf(char *filename)
 	kfree(bpf_prog);
 	return NULL;
 }
-
diff --git a/arch/um/drivers/vector_user.h b/arch/um/drivers/vector_user.h
index a4acfebd28d5..3b05850a9c46 100644
--- a/arch/um/drivers/vector_user.h
+++ b/arch/um/drivers/vector_user.h
@@ -28,6 +28,12 @@
 #define TRANS_BESS "bess"
 #define TRANS_BESS_LEN strlen(TRANS_BESS)
 
+#define TRANS_UCAST "ucast"
+#define TRANS_UCAST_LEN strlen(TRANS_UCAST)
+
+#define TRANS_MCAST "mcast"
+#define TRANS_MCAST_LEN strlen(TRANS_MCAST)
+
 #define DEFAULT_BPF_LEN 6
 
 #ifndef IPPROTO_GRE
-- 
2.20.1


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 3/9] um: Migrate socket transport to Vector backend
  2019-12-17 10:09 [PATCH v4 1/9] um: Migrate pcap to vector IO anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 2/9] um: vector: Add UCAST and MCAST trasnports anton.ivanov
@ 2019-12-17 10:09 ` anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 4/9] um: Enable GRO by default when using raw in pcap compat mode anton.ivanov
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: anton.ivanov @ 2019-12-17 10:09 UTC (permalink / raw)
  To: linux-um; +Cc: richard, brendanhiggins, Anton Ivanov

From: Anton Ivanov <anton.ivanov@cambridgegreys.com>

Moves legacy socket transport to the vector IO backend

Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
---
 arch/um/drivers/Makefile      |   2 -
 arch/um/drivers/net_kern.c    |   4 +-
 arch/um/drivers/umcast.h      |  27 -----
 arch/um/drivers/umcast_kern.c | 188 ----------------------------------
 arch/um/drivers/umcast_user.c | 184 ---------------------------------
 arch/um/drivers/vector_kern.c |  31 ++++++
 6 files changed, 33 insertions(+), 403 deletions(-)
 delete mode 100644 arch/um/drivers/umcast.h
 delete mode 100644 arch/um/drivers/umcast_kern.c
 delete mode 100644 arch/um/drivers/umcast_user.c

diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index ea449dc72236..a283b395b4da 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -10,7 +10,6 @@ slip-objs := slip_kern.o slip_user.o
 slirp-objs := slirp_kern.o slirp_user.o
 daemon-objs := daemon_kern.o daemon_user.o
 vector-objs := vector_kern.o vector_user.o vector_transports.o
-umcast-objs := umcast_kern.o umcast_user.o
 net-objs := net_kern.o net_user.o
 mconsole-objs := mconsole_kern.o mconsole_user.o
 hostaudio-objs := hostaudio_kern.o
@@ -46,7 +45,6 @@ obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
 obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
 obj-$(CONFIG_UML_NET_VECTOR) += vector.o
 obj-$(CONFIG_UML_NET_VDE) += vde.o
-obj-$(CONFIG_UML_NET_MCAST) += umcast.o
 obj-$(CONFIG_UML_NET_PCAP) += pcap.o
 obj-$(CONFIG_UML_NET) += net.o 
 obj-$(CONFIG_MCONSOLE) += mconsole.o
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 821107c75582..597c38d517fc 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -42,8 +42,8 @@ static DEFINE_SPINLOCK(drop_lock);
 static struct sk_buff *drop_skb;
 static int drop_max;
 
-static const char *migrated_to_vector[] = {"pcap"};
-#define MAX_MIGRATED 1
+static const char *migrated_to_vector[] = {"pcap", "ucast", "mcast"};
+#define MAX_MIGRATED 3
 
 static int update_drop_skb(int max)
 {
diff --git a/arch/um/drivers/umcast.h b/arch/um/drivers/umcast.h
deleted file mode 100644
index fe39bee1e3bd..000000000000
--- a/arch/um/drivers/umcast.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- */
-
-#ifndef __DRIVERS_UMCAST_H
-#define __DRIVERS_UMCAST_H
-
-#include <net_user.h>
-
-struct umcast_data {
-	char *addr;
-	unsigned short lport;
-	unsigned short rport;
-	void *listen_addr;
-	void *remote_addr;
-	int ttl;
-	int unicast;
-	void *dev;
-};
-
-extern const struct net_user_info umcast_user_info;
-
-extern int umcast_user_write(int fd, void *buf, int len,
-			     struct umcast_data *pri);
-
-#endif
diff --git a/arch/um/drivers/umcast_kern.c b/arch/um/drivers/umcast_kern.c
deleted file mode 100644
index 595a54f2b9c6..000000000000
--- a/arch/um/drivers/umcast_kern.c
+++ /dev/null
@@ -1,188 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * user-mode-linux networking multicast transport
- * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- *
- * based on the existing uml-networking code, which is
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
- * James Leu (jleu@mindspring.net).
- * Copyright (C) 2001 by various other people who didn't put their name here.
- *
- */
-
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include "umcast.h"
-#include <net_kern.h>
-
-struct umcast_init {
-	char *addr;
-	int lport;
-	int rport;
-	int ttl;
-	bool unicast;
-};
-
-static void umcast_init(struct net_device *dev, void *data)
-{
-	struct uml_net_private *pri;
-	struct umcast_data *dpri;
-	struct umcast_init *init = data;
-
-	pri = netdev_priv(dev);
-	dpri = (struct umcast_data *) pri->user;
-	dpri->addr = init->addr;
-	dpri->lport = init->lport;
-	dpri->rport = init->rport;
-	dpri->unicast = init->unicast;
-	dpri->ttl = init->ttl;
-	dpri->dev = dev;
-
-	if (dpri->unicast) {
-		printk(KERN_INFO "ucast backend address: %s:%u listen port: "
-		       "%u\n", dpri->addr, dpri->rport, dpri->lport);
-	} else {
-		printk(KERN_INFO "mcast backend multicast address: %s:%u, "
-		       "TTL:%u\n", dpri->addr, dpri->lport, dpri->ttl);
-	}
-}
-
-static int umcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	return net_recvfrom(fd, skb_mac_header(skb),
-			    skb->dev->mtu + ETH_HEADER_OTHER);
-}
-
-static int umcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	return umcast_user_write(fd, skb->data, skb->len,
-				(struct umcast_data *) &lp->user);
-}
-
-static const struct net_kern_info umcast_kern_info = {
-	.init			= umcast_init,
-	.protocol		= eth_protocol,
-	.read			= umcast_read,
-	.write			= umcast_write,
-};
-
-static int mcast_setup(char *str, char **mac_out, void *data)
-{
-	struct umcast_init *init = data;
-	char *port_str = NULL, *ttl_str = NULL, *remain;
-	char *last;
-
-	*init = ((struct umcast_init)
-		{ .addr	= "239.192.168.1",
-		  .lport	= 1102,
-		  .ttl	= 1 });
-
-	remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
-			       NULL);
-	if (remain != NULL) {
-		printk(KERN_ERR "mcast_setup - Extra garbage on "
-		       "specification : '%s'\n", remain);
-		return 0;
-	}
-
-	if (port_str != NULL) {
-		init->lport = simple_strtoul(port_str, &last, 10);
-		if ((*last != '\0') || (last == port_str)) {
-			printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
-			       port_str);
-			return 0;
-		}
-	}
-
-	if (ttl_str != NULL) {
-		init->ttl = simple_strtoul(ttl_str, &last, 10);
-		if ((*last != '\0') || (last == ttl_str)) {
-			printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
-			       ttl_str);
-			return 0;
-		}
-	}
-
-	init->unicast = false;
-	init->rport = init->lport;
-
-	printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
-	       init->lport, init->ttl);
-
-	return 1;
-}
-
-static int ucast_setup(char *str, char **mac_out, void *data)
-{
-	struct umcast_init *init = data;
-	char *lport_str = NULL, *rport_str = NULL, *remain;
-	char *last;
-
-	*init = ((struct umcast_init)
-		{ .addr		= "",
-		  .lport	= 1102,
-		  .rport	= 1102 });
-
-	remain = split_if_spec(str, mac_out, &init->addr,
-			       &lport_str, &rport_str, NULL);
-	if (remain != NULL) {
-		printk(KERN_ERR "ucast_setup - Extra garbage on "
-		       "specification : '%s'\n", remain);
-		return 0;
-	}
-
-	if (lport_str != NULL) {
-		init->lport = simple_strtoul(lport_str, &last, 10);
-		if ((*last != '\0') || (last == lport_str)) {
-			printk(KERN_ERR "ucast_setup - Bad listen port : "
-			       "'%s'\n", lport_str);
-			return 0;
-		}
-	}
-
-	if (rport_str != NULL) {
-		init->rport = simple_strtoul(rport_str, &last, 10);
-		if ((*last != '\0') || (last == rport_str)) {
-			printk(KERN_ERR "ucast_setup - Bad remote port : "
-			       "'%s'\n", rport_str);
-			return 0;
-		}
-	}
-
-	init->unicast = true;
-
-	printk(KERN_INFO "Configured ucast device: :%u -> %s:%u\n",
-	       init->lport, init->addr, init->rport);
-
-	return 1;
-}
-
-static struct transport mcast_transport = {
-	.list	= LIST_HEAD_INIT(mcast_transport.list),
-	.name	= "mcast",
-	.setup	= mcast_setup,
-	.user	= &umcast_user_info,
-	.kern	= &umcast_kern_info,
-	.private_size	= sizeof(struct umcast_data),
-	.setup_size	= sizeof(struct umcast_init),
-};
-
-static struct transport ucast_transport = {
-	.list	= LIST_HEAD_INIT(ucast_transport.list),
-	.name	= "ucast",
-	.setup	= ucast_setup,
-	.user	= &umcast_user_info,
-	.kern	= &umcast_kern_info,
-	.private_size	= sizeof(struct umcast_data),
-	.setup_size	= sizeof(struct umcast_init),
-};
-
-static int register_umcast(void)
-{
-	register_transport(&mcast_transport);
-	register_transport(&ucast_transport);
-	return 0;
-}
-
-late_initcall(register_umcast);
diff --git a/arch/um/drivers/umcast_user.c b/arch/um/drivers/umcast_user.c
deleted file mode 100644
index b50b13cff04e..000000000000
--- a/arch/um/drivers/umcast_user.c
+++ /dev/null
@@ -1,184 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * user-mode-linux networking multicast transport
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
- *
- * based on the existing uml-networking code, which is
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
- * James Leu (jleu@mindspring.net).
- * Copyright (C) 2001 by various other people who didn't put their name here.
- *
- *
- */
-
-#include <unistd.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include "umcast.h"
-#include <net_user.h>
-#include <um_malloc.h>
-
-static struct sockaddr_in *new_addr(char *addr, unsigned short port)
-{
-	struct sockaddr_in *sin;
-
-	sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
-	if (sin == NULL) {
-		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
-		       "failed\n");
-		return NULL;
-	}
-	sin->sin_family = AF_INET;
-	if (addr)
-		sin->sin_addr.s_addr = in_aton(addr);
-	else
-		sin->sin_addr.s_addr = INADDR_ANY;
-	sin->sin_port = htons(port);
-	return sin;
-}
-
-static int umcast_user_init(void *data, void *dev)
-{
-	struct umcast_data *pri = data;
-
-	pri->remote_addr = new_addr(pri->addr, pri->rport);
-	if (pri->unicast)
-		pri->listen_addr = new_addr(NULL, pri->lport);
-	else
-		pri->listen_addr = pri->remote_addr;
-	pri->dev = dev;
-	return 0;
-}
-
-static void umcast_remove(void *data)
-{
-	struct umcast_data *pri = data;
-
-	kfree(pri->listen_addr);
-	if (pri->unicast)
-		kfree(pri->remote_addr);
-	pri->listen_addr = pri->remote_addr = NULL;
-}
-
-static int umcast_open(void *data)
-{
-	struct umcast_data *pri = data;
-	struct sockaddr_in *lsin = pri->listen_addr;
-	struct sockaddr_in *rsin = pri->remote_addr;
-	struct ip_mreq mreq;
-	int fd, yes = 1, err = -EINVAL;
-
-
-	if ((!pri->unicast && lsin->sin_addr.s_addr == 0) ||
-	    (rsin->sin_addr.s_addr == 0) ||
-	    (lsin->sin_port == 0) || (rsin->sin_port == 0))
-		goto out;
-
-	fd = socket(AF_INET, SOCK_DGRAM, 0);
-
-	if (fd < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "umcast_open : data socket failed, "
-		       "errno = %d\n", errno);
-		goto out;
-	}
-
-	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "umcast_open: SO_REUSEADDR failed, "
-		       "errno = %d\n", errno);
-		goto out_close;
-	}
-
-	if (!pri->unicast) {
-		/* set ttl according to config */
-		if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
-			       sizeof(pri->ttl)) < 0) {
-			err = -errno;
-			printk(UM_KERN_ERR "umcast_open: IP_MULTICAST_TTL "
-			       "failed, error = %d\n", errno);
-			goto out_close;
-		}
-
-		/* set LOOP, so data does get fed back to local sockets */
-		if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP,
-			       &yes, sizeof(yes)) < 0) {
-			err = -errno;
-			printk(UM_KERN_ERR "umcast_open: IP_MULTICAST_LOOP "
-			       "failed, error = %d\n", errno);
-			goto out_close;
-		}
-	}
-
-	/* bind socket to the address */
-	if (bind(fd, (struct sockaddr *) lsin, sizeof(*lsin)) < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "umcast_open : data bind failed, "
-		       "errno = %d\n", errno);
-		goto out_close;
-	}
-
-	if (!pri->unicast) {
-		/* subscribe to the multicast group */
-		mreq.imr_multiaddr.s_addr = lsin->sin_addr.s_addr;
-		mreq.imr_interface.s_addr = 0;
-		if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
-			       &mreq, sizeof(mreq)) < 0) {
-			err = -errno;
-			printk(UM_KERN_ERR "umcast_open: IP_ADD_MEMBERSHIP "
-			       "failed, error = %d\n", errno);
-			printk(UM_KERN_ERR "There appears not to be a "
-			       "multicast-capable network interface on the "
-			       "host.\n");
-			printk(UM_KERN_ERR "eth0 should be configured in order "
-			       "to use the multicast transport.\n");
-			goto out_close;
-		}
-	}
-
-	return fd;
-
- out_close:
-	close(fd);
- out:
-	return err;
-}
-
-static void umcast_close(int fd, void *data)
-{
-	struct umcast_data *pri = data;
-
-	if (!pri->unicast) {
-		struct ip_mreq mreq;
-		struct sockaddr_in *lsin = pri->listen_addr;
-
-		mreq.imr_multiaddr.s_addr = lsin->sin_addr.s_addr;
-		mreq.imr_interface.s_addr = 0;
-		if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
-			       &mreq, sizeof(mreq)) < 0) {
-			printk(UM_KERN_ERR "umcast_close: IP_DROP_MEMBERSHIP "
-			       "failed, error = %d\n", errno);
-		}
-	}
-
-	close(fd);
-}
-
-int umcast_user_write(int fd, void *buf, int len, struct umcast_data *pri)
-{
-	struct sockaddr_in *data_addr = pri->remote_addr;
-
-	return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
-}
-
-const struct net_user_info umcast_user_info = {
-	.init	= umcast_user_init,
-	.open	= umcast_open,
-	.close	= umcast_close,
-	.remove	= umcast_remove,
-	.add_address	= NULL,
-	.delete_address = NULL,
-	.mtu	= ETH_MAX_PACKET,
-	.max_packet	= ETH_MAX_PACKET + ETH_HEADER_OTHER,
-};
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index 1388f09e09ea..234081ad4f02 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -1740,6 +1740,37 @@ int vector_compat_eth_configure(char *str, int index)
 
 	}
 #endif
+#ifdef CONFIG_UM_NET_MCAST
+	if ((strncmp(str, "ucast", strlen("ucast")) == 0) || (strncmp(str, "mcast", strlen("mcast")) == 0)) {
+		char *src, *addr = NULL, *transport = NULL, *mac = NULL, *srcport = NULL, *dstport = NULL;
+
+		if (strncmp(str, "ucast", strlen("ucast")) == 0)
+			src = "0.0.0.0";
+		else
+			src = addr;
+
+		remain = split_if_spec(str, &transport, &addr, &srcport, &dstport, &mac, NULL);
+
+		if (!srcport)
+			srcport = "1102";
+
+		if (!dstport)
+			dstport = "1102";
+
+		if ((mac != NULL) && strlen(mac) > 0)
+			snprintf(tempargs, MAX_COMPAT_ARG, "transport=%s,src=%s,dst=%s,srcport=%s,dstport=%s,mac=%s",
+					transport, src, addr, srcport, dstport, mac);
+		else
+			snprintf(tempargs, MAX_COMPAT_ARG, "transport=%s,src=%s,dst=%s,srcport=%s,dstrport=%s",
+					transport, src, addr, srcport, dstport);
+
+		strcpy(newargs, tempargs);
+
+
+		do_compat = 1;
+
+	}
+#endif
 	if (do_compat) {
 		parsed = uml_parse_vector_ifspec(newargs);
 		vector_eth_configure(index, parsed, true);
-- 
2.20.1


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 4/9] um: Enable GRO by default when using raw in pcap compat mode
  2019-12-17 10:09 [PATCH v4 1/9] um: Migrate pcap to vector IO anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 2/9] um: vector: Add UCAST and MCAST trasnports anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 3/9] um: Migrate socket transport to Vector backend anton.ivanov
@ 2019-12-17 10:09 ` anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 5/9] um: vector: Add dynamic tap interfaces and scripting anton.ivanov
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: anton.ivanov @ 2019-12-17 10:09 UTC (permalink / raw)
  To: linux-um; +Cc: richard, brendanhiggins, Anton Ivanov

From: Anton Ivanov <anton.ivanov@cambridgegreys.com>

GRO is enabled nearly everywhere in Linux nowdays, not having
it on by default results in packet drops across the board.

Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
---
 arch/um/drivers/vector_kern.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index 234081ad4f02..d52c24874f2a 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -1717,9 +1717,9 @@ int vector_compat_eth_configure(char *str, int index)
 			       &options[0], &options[1], &mac, NULL);
 
 		if ((mac != NULL) && strlen(mac) > 0)
-			snprintf(tempargs, MAX_COMPAT_ARG, "transport=raw,ifname=%s,mac=%s", ifname, mac);
+			snprintf(tempargs, MAX_COMPAT_ARG, "transport=raw,gro=1,ifname=%s,mac=%s", ifname, mac);
 		else
-			snprintf(tempargs, MAX_COMPAT_ARG, "transport=raw,ifname=%s", ifname);
+			snprintf(tempargs, MAX_COMPAT_ARG, "transport=raw,gro=1,ifname=%s", ifname);
 
 		strcpy(newargs, tempargs);
 
-- 
2.20.1


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 5/9] um: vector: Add dynamic tap interfaces and scripting
  2019-12-17 10:09 [PATCH v4 1/9] um: Migrate pcap to vector IO anton.ivanov
                   ` (2 preceding siblings ...)
  2019-12-17 10:09 ` [PATCH v4 4/9] um: Enable GRO by default when using raw in pcap compat mode anton.ivanov
@ 2019-12-17 10:09 ` anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 6/9] um: Migrate tap to vector IO anton.ivanov
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: anton.ivanov @ 2019-12-17 10:09 UTC (permalink / raw)
  To: linux-um; +Cc: richard, brendanhiggins, Anton Ivanov

From: Anton Ivanov <anton.ivanov@cambridgegreys.com>

In order to be compatible with the existing tap driver
we need to be able to allocate a tap on the fly and tear it
down once we are done with it.

We also need to be able to add that interface to a bridge.
Instead of backwards compatibility with the old UML options
and net helper behaviour this patch introduces semantics
identical to qemu ifup scripts.

Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
---
 arch/um/drivers/vector_user.c | 57 +++++++++++++++++++++++++++++------
 1 file changed, 48 insertions(+), 9 deletions(-)

diff --git a/arch/um/drivers/vector_user.c b/arch/um/drivers/vector_user.c
index 7f95318d88d2..ab01c194fba5 100644
--- a/arch/um/drivers/vector_user.c
+++ b/arch/um/drivers/vector_user.c
@@ -40,6 +40,7 @@
 #define ID_MAX 4
 
 #define TOKEN_IFNAME "ifname"
+#define TOKEN_SCRIPT "script"
 
 #define TRANS_RAW "raw"
 #define TRANS_RAW_LEN strlen(TRANS_RAW)
@@ -53,6 +54,9 @@
 
 #define MAX_UN_LEN 107
 
+static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+static const char *template = "tapXXXXXX";
+
 /* This is very ugly and brute force lookup, but it is done
  * only once at initialization so not worth doing hashes or
  * anything more intelligent
@@ -189,16 +193,21 @@ static int create_raw_fd(char *iface, int flags, int proto)
 	return err;
 }
 
+
 static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
 {
-	int fd = -1;
+	int fd = -1, i;
 	char *iface;
 	struct vector_fds *result = NULL;
+	bool dynamic = false;
+	char dynamic_ifname[IFNAMSIZ];
+	char *argv[] = {"/bin/sh", NULL, NULL, NULL};
 
 	iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
 	if (iface == NULL) {
-		printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n");
-		goto tap_cleanup;
+		dynamic = true;
+		iface = dynamic_ifname;
+		srand(getpid());
 	}
 
 	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
@@ -212,14 +221,30 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
 	result->remote_addr_size = 0;
 
 	/* TAP */
+	do {
+		if (dynamic) {
+			strcpy(iface, template);
+			for (i = 0; i < strlen(iface); i++) {
+				if (iface[i] == 'X') {
+					iface[i] = padchar[rand() % strlen(padchar)];
+				}
+			}
+		}
+		fd = create_tap_fd(iface);
+		if ((fd < 0) && (!dynamic)) {
+			printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n");
+			goto tap_cleanup;
+		}
+		result->tx_fd = fd;
+		result->rx_fd = fd;
+	} while (fd < 0);
 
-	fd = create_tap_fd(iface);
-	if (fd < 0) {
-		printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n");
-		goto tap_cleanup;
+	argv[1] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
+	if (argv[1]) {
+		argv[2] = iface;
+		run_helper(NULL, NULL, argv);
 	}
-	result->tx_fd = fd;
-	result->rx_fd = fd;
+
 	return result;
 tap_cleanup:
 	printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd);
@@ -232,6 +257,7 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
 {
 	char *iface;
 	struct vector_fds *result = NULL;
+	char *argv[2];
 
 	iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
 	if (iface == NULL) {
@@ -265,6 +291,12 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
 			"uml_tap: failed to create paired raw socket: %i\n", result->rx_fd);
 		goto hybrid_cleanup;
 	}
+
+	argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
+	if (argv[0]) {
+		argv[1] = iface;
+		run_helper(NULL, NULL, argv);
+	}
 	return result;
 hybrid_cleanup:
 	printk(UM_KERN_ERR "user_init_hybrid: init failed");
@@ -359,6 +391,7 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
 	int err = -ENOMEM;
 	char *iface;
 	struct vector_fds *result = NULL;
+	char *argv[2];
 
 	iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
 	if (iface == NULL)
@@ -392,6 +425,11 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
 		result->remote_addr = NULL;
 		result->remote_addr_size = 0;
 	}
+	argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
+	if (argv[0]) {
+		argv[1] = iface;
+		run_helper(NULL, NULL, argv);
+	}
 	return result;
 raw_cleanup:
 	printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
@@ -643,6 +681,7 @@ struct vector_fds *uml_vector_user_open(
 		return user_init_socket_fds(parsed, ID_UCAST);
 	if (strncmp(transport, TRANS_MCAST, TRANS_MCAST_LEN) == 0)
 		return user_init_socket_fds(parsed, ID_MCAST);
+
 	return NULL;
 }
 
-- 
2.20.1


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 6/9] um: Migrate tap to vector IO
  2019-12-17 10:09 [PATCH v4 1/9] um: Migrate pcap to vector IO anton.ivanov
                   ` (3 preceding siblings ...)
  2019-12-17 10:09 ` [PATCH v4 5/9] um: vector: Add dynamic tap interfaces and scripting anton.ivanov
@ 2019-12-17 10:09 ` anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 7/9] um: Remove ethertap driver and remaining legacy tap/ethertap code anton.ivanov
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: anton.ivanov @ 2019-12-17 10:09 UTC (permalink / raw)
  To: linux-um; +Cc: richard, brendanhiggins, Anton Ivanov

From: Anton Ivanov <anton.ivanov@cambridgegreys.com>

Migrates tuntap to the vector IO backend

Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
---
 arch/um/drivers/Kconfig                |   4 +-
 arch/um/drivers/net_kern.c             |   8 +-
 arch/um/drivers/vector_kern.c          |  26 +++
 arch/um/os-Linux/drivers/Makefile      |   2 -
 arch/um/os-Linux/drivers/tuntap.h      |  21 ---
 arch/um/os-Linux/drivers/tuntap_kern.c |  86 ----------
 arch/um/os-Linux/drivers/tuntap_user.c | 215 -------------------------
 7 files changed, 31 insertions(+), 331 deletions(-)
 delete mode 100644 arch/um/os-Linux/drivers/tuntap.h
 delete mode 100644 arch/um/os-Linux/drivers/tuntap_kern.c
 delete mode 100644 arch/um/os-Linux/drivers/tuntap_user.c

diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig
index 494c778893ce..d8e59bf08d63 100644
--- a/arch/um/drivers/Kconfig
+++ b/arch/um/drivers/Kconfig
@@ -178,9 +178,7 @@ config UML_NET_TUNTAP
 	depends on UML_NET
 	help
 	  The UML TUN/TAP network transport allows a UML instance to exchange
-	  packets with the host over a TUN/TAP device.  This option will only
-	  work with a 2.4 host, unless you've applied the TUN/TAP patch to
-	  your 2.2 host kernel.
+	  packets with the host over a TUN/TAP device. 
 
 	  To use this transport, your host kernel must have support for TUN/TAP
 	  devices, either built-in or as a module.
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 597c38d517fc..21de09942ea6 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -42,8 +42,8 @@ static DEFINE_SPINLOCK(drop_lock);
 static struct sk_buff *drop_skb;
 static int drop_max;
 
-static const char *migrated_to_vector[] = {"pcap", "ucast", "mcast"};
-#define MAX_MIGRATED 3
+static const char *migrated_to_vector[] = {"pcap", "ucast", "mcast", "tuntap"};
+#define MAX_MIGRATED 4
 
 static int update_drop_skb(int max)
 {
@@ -593,7 +593,7 @@ static int register_compat(void)
 	list_for_each_safe(ele, next, &eth_cmd_line) {
 		eth = list_entry(ele, struct eth_init, list);
 		for (compat = 0; compat < MAX_MIGRATED; compat++) {
-			if (strncmp(eth->init, &migrated_to_vector[compat], strlen(&migrated_to_vector[compat])) == 0) {
+			if (strncmp(eth->init, migrated_to_vector[compat], strlen(migrated_to_vector[compat])) == 0) {
 				vector_compat_eth_configure(eth->init, eth->index);
 				list_del(&eth->list);
 				continue;
@@ -642,7 +642,7 @@ static int eth_setup_common(char *str, int index)
 	int found = 0, compat;
 
 	for (compat = 0; compat < MAX_MIGRATED; compat++) {
-		if (strncmp(str, &migrated_to_vector[compat], strlen(&migrated_to_vector[compat])) == 0)
+		if (strncmp(str, migrated_to_vector[compat], strlen(migrated_to_vector[compat])) == 0)
 			return vector_compat_eth_configure(str, index);
 	}
 
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index d52c24874f2a..224db8833b8e 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -1708,6 +1708,32 @@ int vector_compat_eth_configure(char *str, int index)
 		kfree(newargs);
 		return -ENOMEM;
 	}
+#ifdef CONFIG_UML_NET_TUNTAP
+	if (strncmp(str, "tuntap", strlen("tuntap")) == 0) {
+		char *ifname = NULL, *script = NULL, *gateway = NULL, *transport = NULL, *mac = NULL;
+
+		remain = split_if_spec(str, &transport, &ifname, &script, &gateway, &mac, NULL);
+
+		if ((mac != NULL) && strlen(mac) > 0)
+			snprintf(tempargs, MAX_COMPAT_ARG, "transport=tap,gro=1,mac=%s", mac);
+		else
+			snprintf(tempargs, MAX_COMPAT_ARG, "transport=tap,gro=1");
+
+		strcpy(newargs, tempargs);
+
+		if (ifname != NULL) {
+			snprintf(tempargs, MAX_COMPAT_ARG, "%s,ifname=%s", newargs, ifname);
+			strcpy(newargs, tempargs);
+		}
+
+		if (script != NULL) {
+			snprintf(tempargs, MAX_COMPAT_ARG, "%s,script=%s", newargs, script);
+			strcpy(newargs, tempargs);
+		}
+
+		do_compat = 1;
+	}
+#endif
 #ifdef CONFIG_UML_NET_PCAP
 	if (strncmp(str, "pcap", strlen("pcap")) == 0) {
 		char *ifname = NULL, *filter = NULL, *transport = NULL, *mac = NULL;
diff --git a/arch/um/os-Linux/drivers/Makefile b/arch/um/os-Linux/drivers/Makefile
index d79e75f1b69a..924c42641170 100644
--- a/arch/um/os-Linux/drivers/Makefile
+++ b/arch/um/os-Linux/drivers/Makefile
@@ -4,10 +4,8 @@
 #
 
 ethertap-objs := ethertap_kern.o ethertap_user.o
-tuntap-objs := tuntap_kern.o tuntap_user.o
 
 obj-y = 
 obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
-obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
 
 include arch/um/scripts/Makefile.rules
diff --git a/arch/um/os-Linux/drivers/tuntap.h b/arch/um/os-Linux/drivers/tuntap.h
deleted file mode 100644
index e364e42abfc5..000000000000
--- a/arch/um/os-Linux/drivers/tuntap.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* 
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- */
-
-#ifndef __UM_TUNTAP_H
-#define __UM_TUNTAP_H
-
-#include <net_user.h>
-
-struct tuntap_data {
-	char *dev_name;
-	int fixed_config;
-	char *gate_addr;
-	int fd;
-	void *dev;
-};
-
-extern const struct net_user_info tuntap_user_info;
-
-#endif
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
deleted file mode 100644
index adcb6717be6f..000000000000
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ /dev/null
@@ -1,86 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- */
-
-#include <linux/netdevice.h>
-#include <linux/init.h>
-#include <linux/skbuff.h>
-#include <asm/errno.h>
-#include <net_kern.h>
-#include "tuntap.h"
-
-struct tuntap_init {
-	char *dev_name;
-	char *gate_addr;
-};
-
-static void tuntap_init(struct net_device *dev, void *data)
-{
-	struct uml_net_private *pri;
-	struct tuntap_data *tpri;
-	struct tuntap_init *init = data;
-
-	pri = netdev_priv(dev);
-	tpri = (struct tuntap_data *) pri->user;
-	tpri->dev_name = init->dev_name;
-	tpri->fixed_config = (init->dev_name != NULL);
-	tpri->gate_addr = init->gate_addr;
-	tpri->fd = -1;
-	tpri->dev = dev;
-
-	printk(KERN_INFO "TUN/TAP backend - ");
-	if (tpri->gate_addr != NULL)
-		printk(KERN_CONT "IP = %s", tpri->gate_addr);
-	printk(KERN_CONT "\n");
-}
-
-static int tuntap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	return net_read(fd, skb_mac_header(skb),
-			skb->dev->mtu + ETH_HEADER_OTHER);
-}
-
-static int tuntap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	return net_write(fd, skb->data, skb->len);
-}
-
-const struct net_kern_info tuntap_kern_info = {
-	.init			= tuntap_init,
-	.protocol		= eth_protocol,
-	.read			= tuntap_read,
-	.write 			= tuntap_write,
-};
-
-int tuntap_setup(char *str, char **mac_out, void *data)
-{
-	struct tuntap_init *init = data;
-
-	*init = ((struct tuntap_init)
-		{ .dev_name 	= NULL,
-		  .gate_addr 	= NULL });
-	if (tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
-			    &init->gate_addr))
-		return 0;
-
-	return 1;
-}
-
-static struct transport tuntap_transport = {
-	.list 		= LIST_HEAD_INIT(tuntap_transport.list),
-	.name 		= "tuntap",
-	.setup  	= tuntap_setup,
-	.user 		= &tuntap_user_info,
-	.kern 		= &tuntap_kern_info,
-	.private_size 	= sizeof(struct tuntap_data),
-	.setup_size 	= sizeof(struct tuntap_init),
-};
-
-static int register_tuntap(void)
-{
-	register_transport(&tuntap_transport);
-	return 0;
-}
-
-late_initcall(register_tuntap);
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
deleted file mode 100644
index 53eb3d508645..000000000000
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ /dev/null
@@ -1,215 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* 
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <linux/if_tun.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <sys/uio.h>
-#include <kern_util.h>
-#include <os.h>
-#include "tuntap.h"
-
-static int tuntap_user_init(void *data, void *dev)
-{
-	struct tuntap_data *pri = data;
-
-	pri->dev = dev;
-	return 0;
-}
-
-static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
-			    void *data)
-{
-	struct tuntap_data *pri = data;
-
-	tap_check_ips(pri->gate_addr, addr);
-	if ((pri->fd == -1) || pri->fixed_config)
-		return;
-	open_addr(addr, netmask, pri->dev_name);
-}
-
-static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
-			    void *data)
-{
-	struct tuntap_data *pri = data;
-
-	if ((pri->fd == -1) || pri->fixed_config)
-		return;
-	close_addr(addr, netmask, pri->dev_name);
-}
-
-struct tuntap_pre_exec_data {
-	int stdout_fd;
-	int close_me;
-};
-
-static void tuntap_pre_exec(void *arg)
-{
-	struct tuntap_pre_exec_data *data = arg;
-
-	dup2(data->stdout_fd, 1);
-	close(data->close_me);
-}
-
-static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
-			     char *buffer, int buffer_len, int *used_out)
-{
-	struct tuntap_pre_exec_data data;
-	char version_buf[sizeof("nnnnn\0")];
-	char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
-			 NULL };
-	char buf[CMSG_SPACE(sizeof(*fd_out))];
-	struct msghdr msg;
-	struct cmsghdr *cmsg;
-	struct iovec iov;
-	int pid, n, err;
-
-	sprintf(version_buf, "%d", UML_NET_VERSION);
-
-	data.stdout_fd = remote;
-	data.close_me = me;
-
-	pid = run_helper(tuntap_pre_exec, &data, argv);
-
-	if (pid < 0)
-		return pid;
-
-	close(remote);
-
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	if (buffer != NULL) {
-		iov = ((struct iovec) { buffer, buffer_len });
-		msg.msg_iov = &iov;
-		msg.msg_iovlen = 1;
-	}
-	else {
-		msg.msg_iov = NULL;
-		msg.msg_iovlen = 0;
-	}
-	msg.msg_control = buf;
-	msg.msg_controllen = sizeof(buf);
-	msg.msg_flags = 0;
-	n = recvmsg(me, &msg, 0);
-	*used_out = n;
-	if (n < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "tuntap_open_tramp : recvmsg failed - "
-		       "errno = %d\n", errno);
-		return err;
-	}
-	helper_wait(pid);
-
-	cmsg = CMSG_FIRSTHDR(&msg);
-	if (cmsg == NULL) {
-		printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
-		       "message\n");
-		return -EINVAL;
-	}
-	if ((cmsg->cmsg_level != SOL_SOCKET) ||
-	   (cmsg->cmsg_type != SCM_RIGHTS)) {
-		printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
-		       "descriptor\n");
-		return -EINVAL;
-	}
-	*fd_out = ((int *) CMSG_DATA(cmsg))[0];
-	os_set_exec_close(*fd_out);
-	return 0;
-}
-
-static int tuntap_open(void *data)
-{
-	struct ifreq ifr;
-	struct tuntap_data *pri = data;
-	char *output, *buffer;
-	int err, fds[2], len, used;
-
-	err = tap_open_common(pri->dev, pri->gate_addr);
-	if (err < 0)
-		return err;
-
-	if (pri->fixed_config) {
-		pri->fd = os_open_file("/dev/net/tun",
-				       of_cloexec(of_rdwr(OPENFLAGS())), 0);
-		if (pri->fd < 0) {
-			printk(UM_KERN_ERR "Failed to open /dev/net/tun, "
-			       "err = %d\n", -pri->fd);
-			return pri->fd;
-		}
-		memset(&ifr, 0, sizeof(ifr));
-		ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
-		strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
-		if (ioctl(pri->fd, TUNSETIFF, &ifr) < 0) {
-			err = -errno;
-			printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n",
-			       errno);
-			close(pri->fd);
-			return err;
-		}
-	}
-	else {
-		err = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds);
-		if (err) {
-			err = -errno;
-			printk(UM_KERN_ERR "tuntap_open : socketpair failed - "
-			       "errno = %d\n", errno);
-			return err;
-		}
-
-		buffer = get_output_buffer(&len);
-		if (buffer != NULL)
-			len--;
-		used = 0;
-
-		err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
-					fds[1], buffer, len, &used);
-
-		output = buffer;
-		if (err < 0) {
-			printk("%s", output);
-			free_output_buffer(buffer);
-			printk(UM_KERN_ERR "tuntap_open_tramp failed - "
-			       "err = %d\n", -err);
-			return err;
-		}
-
-		pri->dev_name = uml_strdup(buffer);
-		output += IFNAMSIZ;
-		printk("%s", output);
-		free_output_buffer(buffer);
-
-		close(fds[0]);
-		iter_addresses(pri->dev, open_addr, pri->dev_name);
-	}
-
-	return pri->fd;
-}
-
-static void tuntap_close(int fd, void *data)
-{
-	struct tuntap_data *pri = data;
-
-	if (!pri->fixed_config)
-		iter_addresses(pri->dev, close_addr, pri->dev_name);
-	close(fd);
-	pri->fd = -1;
-}
-
-const struct net_user_info tuntap_user_info = {
-	.init		= tuntap_user_init,
-	.open		= tuntap_open,
-	.close	 	= tuntap_close,
-	.remove	 	= NULL,
-	.add_address	= tuntap_add_addr,
-	.delete_address = tuntap_del_addr,
-	.mtu		= ETH_MAX_PACKET,
-	.max_packet	= ETH_MAX_PACKET + ETH_HEADER_OTHER,
-};
-- 
2.20.1


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 7/9] um: Remove ethertap driver and remaining legacy tap/ethertap code
  2019-12-17 10:09 [PATCH v4 1/9] um: Migrate pcap to vector IO anton.ivanov
                   ` (4 preceding siblings ...)
  2019-12-17 10:09 ` [PATCH v4 6/9] um: Migrate tap to vector IO anton.ivanov
@ 2019-12-17 10:09 ` anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 8/9] um: Add daemon transport to vector subsystem anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 9/9] um: migrate daemon to vector backend anton.ivanov
  7 siblings, 0 replies; 9+ messages in thread
From: anton.ivanov @ 2019-12-17 10:09 UTC (permalink / raw)
  To: linux-um; +Cc: richard, brendanhiggins, Anton Ivanov

From: Anton Ivanov <anton.ivanov@cambridgegreys.com>

Ethertap is no longer present in the host kernels and tap has been
migrated to the vector IO backend.

Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
---
 arch/um/drivers/Kconfig                  |  26 ---
 arch/um/drivers/net_user.c               |  31 ---
 arch/um/include/shared/net_kern.h        |   2 -
 arch/um/include/shared/net_user.h        |   3 -
 arch/um/os-Linux/Makefile                |   2 +-
 arch/um/os-Linux/drivers/Makefile        |  11 -
 arch/um/os-Linux/drivers/etap.h          |  21 --
 arch/um/os-Linux/drivers/ethertap_kern.c | 100 ---------
 arch/um/os-Linux/drivers/ethertap_user.c | 248 -----------------------
 9 files changed, 1 insertion(+), 443 deletions(-)
 delete mode 100644 arch/um/os-Linux/drivers/Makefile
 delete mode 100644 arch/um/os-Linux/drivers/etap.h
 delete mode 100644 arch/um/os-Linux/drivers/ethertap_kern.c
 delete mode 100644 arch/um/os-Linux/drivers/ethertap_user.c

diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig
index d8e59bf08d63..7362ac9953fc 100644
--- a/arch/um/drivers/Kconfig
+++ b/arch/um/drivers/Kconfig
@@ -146,32 +146,6 @@ config UML_NET
 	  enable at least one of the following transport options to actually
 	  make use of UML networking.
 
-config UML_NET_ETHERTAP
-	bool "Ethertap transport"
-	depends on UML_NET
-	help
-	  The Ethertap User-Mode Linux network transport allows a single
-	  running UML to exchange packets with its host over one of the
-	  host's Ethertap devices, such as /dev/tap0.  Additional running
-	  UMLs can use additional Ethertap devices, one per running UML.
-	  While the UML believes it's on a (multi-device, broadcast) virtual
-	  Ethernet network, it's in fact communicating over a point-to-point
-	  link with the host.
-
-	  To use this, your host kernel must have support for Ethertap
-	  devices.  Also, if your host kernel is 2.4.x, it must have
-	  CONFIG_NETLINK_DEV configured as Y or M.
-
-	  For more information, see
-	  <http://user-mode-linux.sourceforge.net/old/networking.html>  That site
-	  has examples of the UML command line to use to enable Ethertap
-	  networking.
-
-	  If you'd like to set up an IP network with the host and/or the
-	  outside world, say Y to this, the Daemon Transport and/or the
-	  Slip Transport.  You'll need at least one of them, but may choose
-	  more than one without conflict.  If you don't need UML networking,
-	  say N.
 
 config UML_NET_TUNTAP
 	bool "TUN/TAP transport"
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 4c9576452ab0..4e231240fa25 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -15,37 +15,6 @@
 #include <os.h>
 #include <um_malloc.h>
 
-int tap_open_common(void *dev, char *gate_addr)
-{
-	int tap_addr[4];
-
-	if (gate_addr == NULL)
-		return 0;
-	if (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
-		  &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4) {
-		printk(UM_KERN_ERR "Invalid tap IP address - '%s'\n",
-		       gate_addr);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
-{
-	int tap_addr[4];
-
-	if ((gate_addr != NULL) &&
-	    (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
-		    &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
-	    (eth_addr[0] == tap_addr[0]) &&
-	    (eth_addr[1] == tap_addr[1]) &&
-	    (eth_addr[2] == tap_addr[2]) &&
-	    (eth_addr[3] == tap_addr[3])) {
-		printk(UM_KERN_ERR "The tap IP address and the UML eth IP "
-		       "address must be different\n");
-	}
-}
-
 /* Do reliable error handling as this fails frequently enough. */
 void read_output(int fd, char *output, int len)
 {
diff --git a/arch/um/include/shared/net_kern.h b/arch/um/include/shared/net_kern.h
index f9389a2ec2d8..0ef1021d1a7e 100644
--- a/arch/um/include/shared/net_kern.h
+++ b/arch/um/include/shared/net_kern.h
@@ -61,8 +61,6 @@ struct transport {
 
 extern struct net_device *ether_init(int);
 extern unsigned short ether_protocol(struct sk_buff *);
-extern int tap_setup_common(char *str, char *type, char **dev_name,
-			    char **mac_out, char **gate_addr);
 extern void register_transport(struct transport *new);
 extern unsigned short eth_protocol(struct sk_buff *skb);
 extern void uml_net_setup_etheraddr(struct net_device *dev, char *str);
diff --git a/arch/um/include/shared/net_user.h b/arch/um/include/shared/net_user.h
index b523e469256c..22fd80e55bd0 100644
--- a/arch/um/include/shared/net_user.h
+++ b/arch/um/include/shared/net_user.h
@@ -32,9 +32,6 @@ extern void iter_addresses(void *d, void (*cb)(unsigned char *,
 extern void *get_output_buffer(int *len_out);
 extern void free_output_buffer(void *buffer);
 
-extern int tap_open_common(void *dev, char *gate_addr);
-extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr);
-
 extern void read_output(int fd, char *output_out, int len);
 
 extern int net_read(int fd, void *buf, int len);
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 839915b8c31c..5847b6f8551d 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -8,7 +8,7 @@ KCOV_INSTRUMENT                := n
 
 obj-y = execvp.o file.o helper.o irq.o main.o mem.o process.o \
 	registers.o sigio.o signal.o start_up.o time.o tty.o \
-	umid.o user_syms.o util.o drivers/ skas/
+	umid.o user_syms.o util.o skas/
 
 obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
 
diff --git a/arch/um/os-Linux/drivers/Makefile b/arch/um/os-Linux/drivers/Makefile
deleted file mode 100644
index 924c42641170..000000000000
--- a/arch/um/os-Linux/drivers/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# 
-# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
-#
-
-ethertap-objs := ethertap_kern.o ethertap_user.o
-
-obj-y = 
-obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
-
-include arch/um/scripts/Makefile.rules
diff --git a/arch/um/os-Linux/drivers/etap.h b/arch/um/os-Linux/drivers/etap.h
deleted file mode 100644
index a475259f90e1..000000000000
--- a/arch/um/os-Linux/drivers/etap.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* 
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- */
-
-#ifndef __DRIVERS_ETAP_H
-#define __DRIVERS_ETAP_H
-
-#include <net_user.h>
-
-struct ethertap_data {
-	char *dev_name;
-	char *gate_addr;
-	int data_fd;
-	int control_fd;
-	void *dev;
-};
-
-extern const struct net_user_info ethertap_user_info;
-
-#endif
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
deleted file mode 100644
index 3182e759d8de..000000000000
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ /dev/null
@@ -1,100 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
- * James Leu (jleu@mindspring.net).
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Copyright (C) 2001 by various other people who didn't put their name here.
- */
-
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include "etap.h"
-#include <net_kern.h>
-
-struct ethertap_init {
-	char *dev_name;
-	char *gate_addr;
-};
-
-static void etap_init(struct net_device *dev, void *data)
-{
-	struct uml_net_private *pri;
-	struct ethertap_data *epri;
-	struct ethertap_init *init = data;
-
-	pri = netdev_priv(dev);
-	epri = (struct ethertap_data *) pri->user;
-	epri->dev_name = init->dev_name;
-	epri->gate_addr = init->gate_addr;
-	epri->data_fd = -1;
-	epri->control_fd = -1;
-	epri->dev = dev;
-
-	printk(KERN_INFO "ethertap backend - %s", epri->dev_name);
-	if (epri->gate_addr != NULL)
-		printk(KERN_CONT ", IP = %s", epri->gate_addr);
-	printk(KERN_CONT "\n");
-}
-
-static int etap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	int len;
-
-	len = net_recvfrom(fd, skb_mac_header(skb),
-			   skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP);
-	if (len <= 0)
-		return(len);
-
-	skb_pull(skb, 2);
-	len -= 2;
-	return len;
-}
-
-static int etap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	skb_push(skb, 2);
-	return net_send(fd, skb->data, skb->len);
-}
-
-const struct net_kern_info ethertap_kern_info = {
-	.init			= etap_init,
-	.protocol		= eth_protocol,
-	.read			= etap_read,
-	.write 			= etap_write,
-};
-
-int ethertap_setup(char *str, char **mac_out, void *data)
-{
-	struct ethertap_init *init = data;
-
-	*init = ((struct ethertap_init)
-		{ .dev_name 	= NULL,
-		  .gate_addr 	= NULL });
-	if (tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
-			    &init->gate_addr))
-		return 0;
-	if (init->dev_name == NULL) {
-		printk(KERN_ERR "ethertap_setup : Missing tap device name\n");
-		return 0;
-	}
-
-	return 1;
-}
-
-static struct transport ethertap_transport = {
-	.list 		= LIST_HEAD_INIT(ethertap_transport.list),
-	.name 		= "ethertap",
-	.setup  	= ethertap_setup,
-	.user 		= &ethertap_user_info,
-	.kern 		= &ethertap_kern_info,
-	.private_size 	= sizeof(struct ethertap_data),
-	.setup_size 	= sizeof(struct ethertap_init),
-};
-
-static int register_ethertap(void)
-{
-	register_transport(&ethertap_transport);
-	return 0;
-}
-
-late_initcall(register_ethertap);
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
deleted file mode 100644
index 9483021d86dd..000000000000
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ /dev/null
@@ -1,248 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
- * James Leu (jleu@mindspring.net).
- * Copyright (C) 2001 by various other people who didn't put their name here.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include "etap.h"
-#include <os.h>
-#include <net_user.h>
-#include <um_malloc.h>
-
-#define MAX_PACKET ETH_MAX_PACKET
-
-static int etap_user_init(void *data, void *dev)
-{
-	struct ethertap_data *pri = data;
-
-	pri->dev = dev;
-	return 0;
-}
-
-struct addr_change {
-	enum { ADD_ADDR, DEL_ADDR } what;
-	unsigned char addr[4];
-	unsigned char netmask[4];
-};
-
-static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
-			int fd)
-{
-	struct addr_change change;
-	char *output;
-	int n;
-
-	change.what = op;
-	memcpy(change.addr, addr, sizeof(change.addr));
-	memcpy(change.netmask, netmask, sizeof(change.netmask));
-	CATCH_EINTR(n = write(fd, &change, sizeof(change)));
-	if (n != sizeof(change)) {
-		printk(UM_KERN_ERR "etap_change - request failed, err = %d\n",
-		       errno);
-		return;
-	}
-
-	output = uml_kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
-	if (output == NULL)
-		printk(UM_KERN_ERR "etap_change : Failed to allocate output "
-		       "buffer\n");
-	read_output(fd, output, UM_KERN_PAGE_SIZE);
-	if (output != NULL) {
-		printk("%s", output);
-		kfree(output);
-	}
-}
-
-static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
-			   void *arg)
-{
-	etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
-}
-
-static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
-			    void *arg)
-{
-	etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
-}
-
-struct etap_pre_exec_data {
-	int control_remote;
-	int control_me;
-	int data_me;
-};
-
-static void etap_pre_exec(void *arg)
-{
-	struct etap_pre_exec_data *data = arg;
-
-	dup2(data->control_remote, 1);
-	close(data->data_me);
-	close(data->control_me);
-}
-
-static int etap_tramp(char *dev, char *gate, int control_me,
-		      int control_remote, int data_me, int data_remote)
-{
-	struct etap_pre_exec_data pe_data;
-	int pid, err, n;
-	char version_buf[sizeof("nnnnn\0")];
-	char data_fd_buf[sizeof("nnnnnn\0")];
-	char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
-	char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
-			       data_fd_buf, gate_buf, NULL };
-	char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
-				 dev, data_fd_buf, NULL };
-	char **args, c;
-
-	sprintf(data_fd_buf, "%d", data_remote);
-	sprintf(version_buf, "%d", UML_NET_VERSION);
-	if (gate != NULL) {
-		strncpy(gate_buf, gate, 15);
-		args = setup_args;
-	}
-	else args = nosetup_args;
-
-	err = 0;
-	pe_data.control_remote = control_remote;
-	pe_data.control_me = control_me;
-	pe_data.data_me = data_me;
-	pid = run_helper(etap_pre_exec, &pe_data, args);
-
-	if (pid < 0)
-		err = pid;
-	close(data_remote);
-	close(control_remote);
-	CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
-	if (n != sizeof(c)) {
-		err = -errno;
-		printk(UM_KERN_ERR "etap_tramp : read of status failed, "
-		       "err = %d\n", -err);
-		return err;
-	}
-	if (c != 1) {
-		printk(UM_KERN_ERR "etap_tramp : uml_net failed\n");
-		err = helper_wait(pid);
-	}
-	return err;
-}
-
-static int etap_open(void *data)
-{
-	struct ethertap_data *pri = data;
-	char *output;
-	int data_fds[2], control_fds[2], err, output_len;
-
-	err = tap_open_common(pri->dev, pri->gate_addr);
-	if (err)
-		return err;
-
-	err = socketpair(AF_UNIX, SOCK_DGRAM, 0, data_fds);
-	if (err) {
-		err = -errno;
-		printk(UM_KERN_ERR "etap_open - data socketpair failed - "
-		       "err = %d\n", errno);
-		return err;
-	}
-
-	err = socketpair(AF_UNIX, SOCK_STREAM, 0, control_fds);
-	if (err) {
-		err = -errno;
-		printk(UM_KERN_ERR "etap_open - control socketpair failed - "
-		       "err = %d\n", errno);
-		goto out_close_data;
-	}
-
-	err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
-			 control_fds[1], data_fds[0], data_fds[1]);
-	output_len = UM_KERN_PAGE_SIZE;
-	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
-	read_output(control_fds[0], output, output_len);
-
-	if (output == NULL)
-		printk(UM_KERN_ERR "etap_open : failed to allocate output "
-		       "buffer\n");
-	else {
-		printk("%s", output);
-		kfree(output);
-	}
-
-	if (err < 0) {
-		printk(UM_KERN_ERR "etap_tramp failed - err = %d\n", -err);
-		goto out_close_control;
-	}
-
-	pri->data_fd = data_fds[0];
-	pri->control_fd = control_fds[0];
-	iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
-	return data_fds[0];
-
-out_close_control:
-	close(control_fds[0]);
-	close(control_fds[1]);
-out_close_data:
-	close(data_fds[0]);
-	close(data_fds[1]);
-	return err;
-}
-
-static void etap_close(int fd, void *data)
-{
-	struct ethertap_data *pri = data;
-
-	iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
-	close(fd);
-
-	if (shutdown(pri->data_fd, SHUT_RDWR) < 0)
-		printk(UM_KERN_ERR "etap_close - shutdown data socket failed, "
-		       "errno = %d\n", errno);
-
-	if (shutdown(pri->control_fd, SHUT_RDWR) < 0)
-		printk(UM_KERN_ERR "etap_close - shutdown control socket "
-		       "failed, errno = %d\n", errno);
-
-	close(pri->data_fd);
-	pri->data_fd = -1;
-	close(pri->control_fd);
-	pri->control_fd = -1;
-}
-
-static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
-			  void *data)
-{
-	struct ethertap_data *pri = data;
-
-	tap_check_ips(pri->gate_addr, addr);
-	if (pri->control_fd == -1)
-		return;
-	etap_open_addr(addr, netmask, &pri->control_fd);
-}
-
-static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
-			  void *data)
-{
-	struct ethertap_data *pri = data;
-
-	if (pri->control_fd == -1)
-		return;
-
-	etap_close_addr(addr, netmask, &pri->control_fd);
-}
-
-const struct net_user_info ethertap_user_info = {
-	.init		= etap_user_init,
-	.open		= etap_open,
-	.close	 	= etap_close,
-	.remove	 	= NULL,
-	.add_address	= etap_add_addr,
-	.delete_address = etap_del_addr,
-	.mtu		= ETH_MAX_PACKET,
-	.max_packet	= ETH_MAX_PACKET + ETH_HEADER_ETHERTAP,
-};
-- 
2.20.1


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 8/9] um: Add daemon transport to vector subsystem
  2019-12-17 10:09 [PATCH v4 1/9] um: Migrate pcap to vector IO anton.ivanov
                   ` (5 preceding siblings ...)
  2019-12-17 10:09 ` [PATCH v4 7/9] um: Remove ethertap driver and remaining legacy tap/ethertap code anton.ivanov
@ 2019-12-17 10:09 ` anton.ivanov
  2019-12-17 10:09 ` [PATCH v4 9/9] um: migrate daemon to vector backend anton.ivanov
  7 siblings, 0 replies; 9+ messages in thread
From: anton.ivanov @ 2019-12-17 10:09 UTC (permalink / raw)
  To: linux-um; +Cc: richard, brendanhiggins, Anton Ivanov

From: Anton Ivanov <anton.ivanov@cambridgegreys.com>

Adds a transport compatible with the old uml_switch from
uml-utilities package to the vector subsystem.

Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
---
 arch/um/drivers/Kconfig       |   2 +-
 arch/um/drivers/vector_kern.c |   4 ++
 arch/um/drivers/vector_user.c | 110 ++++++++++++++++++++++++++++++++--
 arch/um/drivers/vector_user.h |   4 ++
 4 files changed, 115 insertions(+), 5 deletions(-)

diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig
index 7362ac9953fc..2369bdf4be91 100644
--- a/arch/um/drivers/Kconfig
+++ b/arch/um/drivers/Kconfig
@@ -152,7 +152,7 @@ config UML_NET_TUNTAP
 	depends on UML_NET
 	help
 	  The UML TUN/TAP network transport allows a UML instance to exchange
-	  packets with the host over a TUN/TAP device. 
+	  packets with the host over a TUN/TAP device.
 
 	  To use this transport, your host kernel must have support for TUN/TAP
 	  devices, either built-in or as a module.
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index 224db8833b8e..aba2dc634f44 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -1187,6 +1187,10 @@ static int vector_net_close(struct net_device *dev)
 		os_close_file(vp->fds->rx_fd);
 		vp->fds->rx_fd = -1;
 	}
+	if (vp->fds->control_fd > 0) {
+		os_close_file(vp->fds->control_fd);
+		vp->fds->control_fd = -1;
+	}
 	if (vp->fds->tx_fd > 0) {
 		os_close_file(vp->fds->tx_fd);
 		vp->fds->tx_fd = -1;
diff --git a/arch/um/drivers/vector_user.c b/arch/um/drivers/vector_user.c
index ab01c194fba5..20c3bb22a211 100644
--- a/arch/um/drivers/vector_user.c
+++ b/arch/um/drivers/vector_user.c
@@ -25,6 +25,7 @@
 #include <linux/if_packet.h>
 #include <sys/wait.h>
 #include <sys/uio.h>
+#include <sys/time.h>
 #include <linux/virtio_net.h>
 #include <netdb.h>
 #include <stdlib.h>
@@ -37,7 +38,8 @@
 #define ID_BESS 2
 #define ID_UCAST 3
 #define ID_MCAST 4
-#define ID_MAX 4
+#define ID_DAEMON 5
+#define ID_MAX 5
 
 #define TOKEN_IFNAME "ifname"
 #define TOKEN_SCRIPT "script"
@@ -57,6 +59,18 @@
 static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 static const char *template = "tapXXXXXX";
 
+enum request_type { REQ_NEW_CONTROL };
+
+#define SWITCH_MAGIC 0xfeedface
+
+struct request_v3 {
+	uint32_t magic;
+	uint32_t version;
+	enum request_type type;
+	struct sockaddr_un sock;
+};
+
+
 /* This is very ugly and brute force lookup, but it is done
  * only once at initialization so not worth doing hashes or
  * anything more intelligent
@@ -217,6 +231,7 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
 	}
 	result->rx_fd = -1;
 	result->tx_fd = -1;
+	result->control_fd = -1;
 	result->remote_addr = NULL;
 	result->remote_addr_size = 0;
 
@@ -272,6 +287,7 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
 	}
 	result->rx_fd = -1;
 	result->tx_fd = -1;
+	result->control_fd = -1;
 	result->remote_addr = NULL;
 	result->remote_addr_size = 0;
 
@@ -305,21 +321,35 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
 	return NULL;
 }
 
+#define SWITCH_VERSION 3
+
 static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id)
 {
-	int fd = -1;
+	int fd = -1, n;
 	int socktype;
 	char *src, *dst;
 	struct vector_fds *result = NULL;
-	struct sockaddr_un *local_addr = NULL, *remote_addr = NULL;
+	struct sockaddr_un *local_addr = NULL, *remote_addr = NULL, *control_addr = NULL;
+	struct request_v3 req;
+	struct {
+		char zero;
+		int pid;
+		int usecs;
+	} name;
+	struct timeval tv;
 
 	src = uml_vector_fetch_arg(ifspec, "src");
 	dst = uml_vector_fetch_arg(ifspec, "dst");
+
+	if (dst == NULL)
+		dst = "/tmp/uml.ctl";
+
 	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
 	if (result == NULL) {
 		printk(UM_KERN_ERR "unix open:cannot allocate remote addr");
 		goto unix_cleanup;
 	}
+	result->control_fd = -1;
 	remote_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
 	if (remote_addr == NULL) {
 		printk(UM_KERN_ERR "unix open:cannot allocate remote addr");
@@ -327,6 +357,62 @@ static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id)
 	}
 
 	switch (id) {
+	case ID_DAEMON:
+		name.zero = 0;
+		name.pid = os_getpid();
+		gettimeofday(&tv, NULL);
+		name.usecs = tv.tv_usec;
+
+		local_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+		if (local_addr == NULL) {
+			printk(UM_KERN_ERR "daemon open:cannot allocate local addr");
+			goto unix_cleanup;
+		}
+		local_addr->sun_family = AF_UNIX;
+		memcpy(local_addr->sun_path, &name, sizeof(name));
+
+		result->control_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+		if (result->control_fd < 0) {
+			printk(UM_KERN_ERR
+				"unix open: could not open socket, error = %d",
+				-errno
+			);
+			goto unix_cleanup;
+		}
+		if (strlen(dst) <= MAX_UN_LEN) {
+			control_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+			if (control_addr == NULL) {
+				printk(UM_KERN_ERR "daemon open:cannot allocate control addr");
+				goto unix_cleanup;
+			}
+			control_addr->sun_family = AF_UNIX;
+			memcpy(control_addr->sun_path, dst, strlen(dst) + 1);
+		}
+
+		if (connect(result->control_fd, (struct sockaddr *) control_addr, sizeof(*control_addr)) < 0) {
+			printk(UM_KERN_ERR "daemon_open : control connect failed, " "errno = %d\n", -errno);
+			goto unix_cleanup;
+		}
+		req.magic = SWITCH_MAGIC;
+		req.version = SWITCH_VERSION;
+		req.type = REQ_NEW_CONTROL;
+		req.sock = *local_addr;
+
+		n = write(result->control_fd, &req, sizeof(req));
+		if (n != sizeof(req)) {
+			printk(UM_KERN_ERR "daemon_open : control setup request "
+			       "failed, err = %d\n", -errno);
+			goto unix_cleanup;
+		}
+		n = read(result->control_fd, remote_addr, sizeof(struct sockaddr_un));
+		if (n != sizeof(struct sockaddr_un)) {
+			printk(UM_KERN_ERR "daemon_open : read of data socket failed, "
+			       "err = %d\n", -errno);
+			goto unix_cleanup;
+		}
+		socktype = SOCK_DGRAM;
+
+		break;
 	case ID_BESS:
 		socktype = SOCK_SEQPACKET;
 		if ((src != NULL) && (strlen(src) <= MAX_UN_LEN)) {
@@ -374,14 +460,27 @@ static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id)
 	result->tx_fd = fd;
 	result->remote_addr_size = sizeof(struct sockaddr_un);
 	result->remote_addr = remote_addr;
+
+	if (control_addr != NULL)
+		kfree(control_addr);
+	if (local_addr != NULL)
+		kfree(local_addr);
+
 	return result;
 unix_cleanup:
 	if (fd >= 0)
 		os_close_file(fd);
 	if (remote_addr != NULL)
 		kfree(remote_addr);
-	if (result != NULL)
+	if (control_addr != NULL)
+		kfree(control_addr);
+	if (local_addr != NULL)
+		kfree(local_addr);
+	if (result != NULL) {
+		if (result->control_fd > 0)
+			close(result->control_fd);
 		kfree(result);
+	}
 	return NULL;
 }
 
@@ -422,6 +521,7 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
 	if (result != NULL) {
 		result->rx_fd = rxfd;
 		result->tx_fd = txfd;
+		result->control_fd = -1;
 		result->remote_addr = NULL;
 		result->remote_addr_size = 0;
 	}
@@ -677,6 +777,8 @@ struct vector_fds *uml_vector_user_open(
 		return user_init_socket_fds(parsed, ID_L2TPV3);
 	if (strncmp(transport, TRANS_BESS, TRANS_BESS_LEN) == 0)
 		return user_init_unix_fds(parsed, ID_BESS);
+	if (strncmp(transport, TRANS_DAEMON, TRANS_DAEMON_LEN) == 0)
+		return user_init_unix_fds(parsed, ID_DAEMON);
 	if (strncmp(transport, TRANS_UCAST, TRANS_UCAST_LEN) == 0)
 		return user_init_socket_fds(parsed, ID_UCAST);
 	if (strncmp(transport, TRANS_MCAST, TRANS_MCAST_LEN) == 0)
diff --git a/arch/um/drivers/vector_user.h b/arch/um/drivers/vector_user.h
index 3b05850a9c46..590ece585929 100644
--- a/arch/um/drivers/vector_user.h
+++ b/arch/um/drivers/vector_user.h
@@ -34,6 +34,9 @@
 #define TRANS_MCAST "mcast"
 #define TRANS_MCAST_LEN strlen(TRANS_MCAST)
 
+#define TRANS_DAEMON "daemon"
+#define TRANS_DAEMON_LEN strlen(TRANS_MCAST)
+
 #define DEFAULT_BPF_LEN 6
 
 #ifndef IPPROTO_GRE
@@ -71,6 +74,7 @@ struct vector_fds {
 	int tx_fd;
 	void *remote_addr;
 	int remote_addr_size;
+	int control_fd;
 };
 
 #define VECTOR_READ	1
-- 
2.20.1


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 9/9] um: migrate daemon to vector backend
  2019-12-17 10:09 [PATCH v4 1/9] um: Migrate pcap to vector IO anton.ivanov
                   ` (6 preceding siblings ...)
  2019-12-17 10:09 ` [PATCH v4 8/9] um: Add daemon transport to vector subsystem anton.ivanov
@ 2019-12-17 10:09 ` anton.ivanov
  7 siblings, 0 replies; 9+ messages in thread
From: anton.ivanov @ 2019-12-17 10:09 UTC (permalink / raw)
  To: linux-um; +Cc: richard, brendanhiggins, Anton Ivanov

From: Anton Ivanov <anton.ivanov@cambridgegreys.com>

Removes old daemon packet-a-time code and migrates it to
vector backend

Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
---
 arch/um/drivers/Makefile      |   2 -
 arch/um/drivers/daemon.h      |  29 -----
 arch/um/drivers/daemon_kern.c |  95 -----------------
 arch/um/drivers/daemon_user.c | 193 ----------------------------------
 arch/um/drivers/net_kern.c    |   4 +-
 arch/um/drivers/vector_kern.c |  21 ++++
 6 files changed, 23 insertions(+), 321 deletions(-)
 delete mode 100644 arch/um/drivers/daemon.h
 delete mode 100644 arch/um/drivers/daemon_kern.c
 delete mode 100644 arch/um/drivers/daemon_user.c

diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index a283b395b4da..06448073dce6 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -8,7 +8,6 @@
 
 slip-objs := slip_kern.o slip_user.o
 slirp-objs := slirp_kern.o slirp_user.o
-daemon-objs := daemon_kern.o daemon_user.o
 vector-objs := vector_kern.o vector_user.o vector_transports.o
 net-objs := net_kern.o net_user.o
 mconsole-objs := mconsole_kern.o mconsole_user.o
@@ -42,7 +41,6 @@ obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
 
 obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
 obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
-obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
 obj-$(CONFIG_UML_NET_VECTOR) += vector.o
 obj-$(CONFIG_UML_NET_VDE) += vde.o
 obj-$(CONFIG_UML_NET_PCAP) += pcap.o
diff --git a/arch/um/drivers/daemon.h b/arch/um/drivers/daemon.h
deleted file mode 100644
index 1509cc7eb907..000000000000
--- a/arch/um/drivers/daemon.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- */
-
-#ifndef __DAEMON_H__
-#define __DAEMON_H__
-
-#include <net_user.h>
-
-#define SWITCH_VERSION 3
-
-struct daemon_data {
-	char *sock_type;
-	char *ctl_sock;
-	void *ctl_addr;
-	void *data_addr;
-	void *local_addr;
-	int fd;
-	int control;
-	void *dev;
-};
-
-extern const struct net_user_info daemon_user_info;
-
-extern int daemon_user_write(int fd, void *buf, int len,
-			     struct daemon_data *pri);
-
-#endif
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
deleted file mode 100644
index fd2402669c49..000000000000
--- a/arch/um/drivers/daemon_kern.c
+++ /dev/null
@@ -1,95 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
- * James Leu (jleu@mindspring.net).
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Copyright (C) 2001 by various other people who didn't put their name here.
- */
-
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <net_kern.h>
-#include "daemon.h"
-
-struct daemon_init {
-	char *sock_type;
-	char *ctl_sock;
-};
-
-static void daemon_init(struct net_device *dev, void *data)
-{
-	struct uml_net_private *pri;
-	struct daemon_data *dpri;
-	struct daemon_init *init = data;
-
-	pri = netdev_priv(dev);
-	dpri = (struct daemon_data *) pri->user;
-	dpri->sock_type = init->sock_type;
-	dpri->ctl_sock = init->ctl_sock;
-	dpri->fd = -1;
-	dpri->control = -1;
-	dpri->dev = dev;
-	/* We will free this pointer. If it contains crap we're burned. */
-	dpri->ctl_addr = NULL;
-	dpri->data_addr = NULL;
-	dpri->local_addr = NULL;
-
-	printk("daemon backend (uml_switch version %d) - %s:%s",
-	       SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
-	printk("\n");
-}
-
-static int daemon_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	return net_recvfrom(fd, skb_mac_header(skb),
-			    skb->dev->mtu + ETH_HEADER_OTHER);
-}
-
-static int daemon_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	return daemon_user_write(fd, skb->data, skb->len,
-				 (struct daemon_data *) &lp->user);
-}
-
-static const struct net_kern_info daemon_kern_info = {
-	.init			= daemon_init,
-	.protocol		= eth_protocol,
-	.read			= daemon_read,
-	.write			= daemon_write,
-};
-
-static int daemon_setup(char *str, char **mac_out, void *data)
-{
-	struct daemon_init *init = data;
-	char *remain;
-
-	*init = ((struct daemon_init)
-		{ .sock_type 		= "unix",
-		  .ctl_sock 		= "/tmp/uml.ctl" });
-
-	remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
-			       NULL);
-	if (remain != NULL)
-		printk(KERN_WARNING "daemon_setup : Ignoring data socket "
-		       "specification\n");
-
-	return 1;
-}
-
-static struct transport daemon_transport = {
-	.list 		= LIST_HEAD_INIT(daemon_transport.list),
-	.name 		= "daemon",
-	.setup  	= daemon_setup,
-	.user 		= &daemon_user_info,
-	.kern 		= &daemon_kern_info,
-	.private_size 	= sizeof(struct daemon_data),
-	.setup_size 	= sizeof(struct daemon_init),
-};
-
-static int register_daemon(void)
-{
-	register_transport(&daemon_transport);
-	return 0;
-}
-
-late_initcall(register_daemon);
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
deleted file mode 100644
index 3695821d06a2..000000000000
--- a/arch/um/drivers/daemon_user.c
+++ /dev/null
@@ -1,193 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
- * James Leu (jleu@mindspring.net).
- * Copyright (C) 2001 by various other people who didn't put their name here.
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include "daemon.h"
-#include <net_user.h>
-#include <os.h>
-#include <um_malloc.h>
-
-enum request_type { REQ_NEW_CONTROL };
-
-#define SWITCH_MAGIC 0xfeedface
-
-struct request_v3 {
-	uint32_t magic;
-	uint32_t version;
-	enum request_type type;
-	struct sockaddr_un sock;
-};
-
-static struct sockaddr_un *new_addr(void *name, int len)
-{
-	struct sockaddr_un *sun;
-
-	sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
-	if (sun == NULL) {
-		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
-		       "failed\n");
-		return NULL;
-	}
-	sun->sun_family = AF_UNIX;
-	memcpy(sun->sun_path, name, len);
-	return sun;
-}
-
-static int connect_to_switch(struct daemon_data *pri)
-{
-	struct sockaddr_un *ctl_addr = pri->ctl_addr;
-	struct sockaddr_un *local_addr = pri->local_addr;
-	struct sockaddr_un *sun;
-	struct request_v3 req;
-	int fd, n, err;
-
-	pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
-	if (pri->control < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "daemon_open : control socket failed, "
-		       "errno = %d\n", -err);
-		return err;
-	}
-
-	if (connect(pri->control, (struct sockaddr *) ctl_addr,
-		   sizeof(*ctl_addr)) < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "daemon_open : control connect failed, "
-		       "errno = %d\n", -err);
-		goto out;
-	}
-
-	fd = socket(AF_UNIX, SOCK_DGRAM, 0);
-	if (fd < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "daemon_open : data socket failed, "
-		       "errno = %d\n", -err);
-		goto out;
-	}
-	if (bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "daemon_open : data bind failed, "
-		       "errno = %d\n", -err);
-		goto out_close;
-	}
-
-	sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
-	if (sun == NULL) {
-		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
-		       "failed\n");
-		err = -ENOMEM;
-		goto out_close;
-	}
-
-	req.magic = SWITCH_MAGIC;
-	req.version = SWITCH_VERSION;
-	req.type = REQ_NEW_CONTROL;
-	req.sock = *local_addr;
-	n = write(pri->control, &req, sizeof(req));
-	if (n != sizeof(req)) {
-		printk(UM_KERN_ERR "daemon_open : control setup request "
-		       "failed, err = %d\n", -errno);
-		err = -ENOTCONN;
-		goto out_free;
-	}
-
-	n = read(pri->control, sun, sizeof(*sun));
-	if (n != sizeof(*sun)) {
-		printk(UM_KERN_ERR "daemon_open : read of data socket failed, "
-		       "err = %d\n", -errno);
-		err = -ENOTCONN;
-		goto out_free;
-	}
-
-	pri->data_addr = sun;
-	return fd;
-
- out_free:
-	kfree(sun);
- out_close:
-	close(fd);
- out:
-	close(pri->control);
-	return err;
-}
-
-static int daemon_user_init(void *data, void *dev)
-{
-	struct daemon_data *pri = data;
-	struct timeval tv;
-	struct {
-		char zero;
-		int pid;
-		int usecs;
-	} name;
-
-	if (!strcmp(pri->sock_type, "unix"))
-		pri->ctl_addr = new_addr(pri->ctl_sock,
-					 strlen(pri->ctl_sock) + 1);
-	name.zero = 0;
-	name.pid = os_getpid();
-	gettimeofday(&tv, NULL);
-	name.usecs = tv.tv_usec;
-	pri->local_addr = new_addr(&name, sizeof(name));
-	pri->dev = dev;
-	pri->fd = connect_to_switch(pri);
-	if (pri->fd < 0) {
-		kfree(pri->local_addr);
-		pri->local_addr = NULL;
-		return pri->fd;
-	}
-
-	return 0;
-}
-
-static int daemon_open(void *data)
-{
-	struct daemon_data *pri = data;
-	return pri->fd;
-}
-
-static void daemon_remove(void *data)
-{
-	struct daemon_data *pri = data;
-
-	close(pri->fd);
-	pri->fd = -1;
-	close(pri->control);
-	pri->control = -1;
-
-	kfree(pri->data_addr);
-	pri->data_addr = NULL;
-	kfree(pri->ctl_addr);
-	pri->ctl_addr = NULL;
-	kfree(pri->local_addr);
-	pri->local_addr = NULL;
-}
-
-int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
-{
-	struct sockaddr_un *data_addr = pri->data_addr;
-
-	return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
-}
-
-const struct net_user_info daemon_user_info = {
-	.init		= daemon_user_init,
-	.open		= daemon_open,
-	.close	 	= NULL,
-	.remove	 	= daemon_remove,
-	.add_address	= NULL,
-	.delete_address = NULL,
-	.mtu		= ETH_MAX_PACKET,
-	.max_packet	= ETH_MAX_PACKET + ETH_HEADER_OTHER,
-};
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 21de09942ea6..b5de5ad43547 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -42,8 +42,8 @@ static DEFINE_SPINLOCK(drop_lock);
 static struct sk_buff *drop_skb;
 static int drop_max;
 
-static const char *migrated_to_vector[] = {"pcap", "ucast", "mcast", "tuntap"};
-#define MAX_MIGRATED 4
+static const char *migrated_to_vector[] = {"pcap", "ucast", "mcast", "tuntap", "daemon"};
+#define MAX_MIGRATED 5
 
 static int update_drop_skb(int max)
 {
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index aba2dc634f44..fcd8465fe335 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -1712,6 +1712,27 @@ int vector_compat_eth_configure(char *str, int index)
 		kfree(newargs);
 		return -ENOMEM;
 	}
+#ifdef CONFIG_UML_NET_DAEMON
+	if (strncmp(str, "daemon", strlen("daemon")) == 0) {
+		char *proto = NULL, *control = NULL, *transport = NULL, *mac = NULL;
+
+		remain = split_if_spec(str, &transport, &proto, &control, &mac, NULL);
+
+		if ((mac != NULL) && strlen(mac) > 0)
+			snprintf(tempargs, MAX_COMPAT_ARG, "transport=daemon,mac=%s", mac);
+		else
+			snprintf(tempargs, MAX_COMPAT_ARG, "transport=daemon");
+
+		strcpy(newargs, tempargs);
+
+		if (control != NULL) {
+			snprintf(tempargs, MAX_COMPAT_ARG, "%s,dst=%s", newargs, control);
+			strcpy(newargs, tempargs);
+		}
+
+		do_compat = 1;
+	}
+#endif
 #ifdef CONFIG_UML_NET_TUNTAP
 	if (strncmp(str, "tuntap", strlen("tuntap")) == 0) {
 		char *ifname = NULL, *script = NULL, *gateway = NULL, *transport = NULL, *mac = NULL;
-- 
2.20.1


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-12-17 10:09 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-17 10:09 [PATCH v4 1/9] um: Migrate pcap to vector IO anton.ivanov
2019-12-17 10:09 ` [PATCH v4 2/9] um: vector: Add UCAST and MCAST trasnports anton.ivanov
2019-12-17 10:09 ` [PATCH v4 3/9] um: Migrate socket transport to Vector backend anton.ivanov
2019-12-17 10:09 ` [PATCH v4 4/9] um: Enable GRO by default when using raw in pcap compat mode anton.ivanov
2019-12-17 10:09 ` [PATCH v4 5/9] um: vector: Add dynamic tap interfaces and scripting anton.ivanov
2019-12-17 10:09 ` [PATCH v4 6/9] um: Migrate tap to vector IO anton.ivanov
2019-12-17 10:09 ` [PATCH v4 7/9] um: Remove ethertap driver and remaining legacy tap/ethertap code anton.ivanov
2019-12-17 10:09 ` [PATCH v4 8/9] um: Add daemon transport to vector subsystem anton.ivanov
2019-12-17 10:09 ` [PATCH v4 9/9] um: migrate daemon to vector backend anton.ivanov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.