From patchwork Tue Dec 17 10:09:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1211252 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cambridgegreys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Agb6flIF"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47cYlh45P9z9sRm for ; Tue, 17 Dec 2019 21:09:36 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=0d/Fi9NfZAE7OhxAceJxpjhf/chZQCj2KsKZ+yTeI7Q=; b=Agb6flIFhMEGUs vjQfwl01Mgz9TegWX5kfS5Oz6zjxLzt7Gff/zyl/I+UhELQv5IrfgxvJ7ctVTdaCYZfRZ+spt2Sb6 N7FzD+/UIzw9TIuN+z4FFEONBIckCbaMpX4RxOxY+Lr3ChYqQ7xnHb2Pnms/mmFIq7x89GpRjTmoN 9t4oE3t1hxcDWv9Fzj8ZzCa1zv/jL8pLdw5nWzWF+e9PPQO1huE2u+IfzOgbb0BDcCrmPAH/3mXYc HrYq2e7yuk4/iEyrK1QIBGlFN+SnSZun9l1XgRS9am/irzV1j9wtX0VFmdWP9sx0X5iu+5WCCD86Z x7dL7HksZ5lJA7VoPRrA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nD-0002Ym-FR; Tue, 17 Dec 2019 10:09:27 +0000 Received: from ivanoab7.miniserver.com ([37.128.132.42] helo=www.kot-begemot.co.uk) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9n7-0002Wm-Ou for linux-um@lists.infradead.org; Tue, 17 Dec 2019 10:09:25 +0000 Received: from tun252.jain.kot-begemot.co.uk ([192.168.18.6] helo=jain.kot-begemot.co.uk) by www.kot-begemot.co.uk with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ih9n4-0003oW-Cv; Tue, 17 Dec 2019 10:09:19 +0000 Received: from jain.kot-begemot.co.uk ([192.168.3.3]) by jain.kot-begemot.co.uk with esmtp (Exim 4.92) (envelope-from ) id 1ih9n0-0000uG-OQ; Tue, 17 Dec 2019 10:09:16 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v4 1/9] um: Migrate pcap to vector IO Date: Tue, 17 Dec 2019 10:09:05 +0000 Message-Id: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-Spam-Score: -1.0 X-Spam-Score: -1.0 X-Clacks-Overhead: GNU Terry Pratchett X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191217_020922_952653_858B0FB8 X-CRM114-Status: GOOD ( 18.05 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard@nod.at, brendanhiggins@google.com, Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Anton Ivanov Migrates UML PCAP driver to the new vector IO network backend. Signed-off-by: Anton Ivanov --- 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, ð_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(ð->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, ð_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 -#include -#include -#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 #include #include -#include "pcap_user.h" +#include +#include #include -#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 - -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 #include #include +#include #include #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 From patchwork Tue Dec 17 10:09:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1211251 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cambridgegreys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="o5Qs1oIk"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47cYlg4qgwz9sRh for ; Tue, 17 Dec 2019 21:09:35 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=b7njD9SXQuc1wejAjeSdh8dtsrqSNky+DgVf3N23SZc=; b=o5Qs1oIki4iAN+ YHaN16w64GxTKMZ+jDX9X5zxjRQDaMIheTm1Z1PyI4ew+IJUTzdfzeW2DumzzWyVNeNKAQSGMJDIG k/0YOovlAF/WmviZEHEdfY074beZqZjZtGYtWEwij6CgkxbvNRMOJXoV2M7hIsyAJqHPWOS3+KELx y4o9qEAGoymxnDFclD7WivvRK5L8qWMumkKBCH33E6OcApBwAwOGpbydhsc16j5XbhrreJsyX/0GZ 34nmdBeWAgjpyPPHtVb1Vliov4alUpV9ru07JQQa+SHM1qdtuui/oBSJqVx7NbVwfGke2FjN1k8kK 61QSTMl52YYa11w6W/zA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nD-0002Yd-8N; Tue, 17 Dec 2019 10:09:27 +0000 Received: from ivanoab7.miniserver.com ([37.128.132.42] helo=www.kot-begemot.co.uk) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9n7-0002X5-Ow for linux-um@lists.infradead.org; Tue, 17 Dec 2019 10:09:25 +0000 Received: from tun252.jain.kot-begemot.co.uk ([192.168.18.6] helo=jain.kot-begemot.co.uk) by www.kot-begemot.co.uk with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ih9n6-0003ob-ER; Tue, 17 Dec 2019 10:09:20 +0000 Received: from jain.kot-begemot.co.uk ([192.168.3.3]) by jain.kot-begemot.co.uk with esmtp (Exim 4.92) (envelope-from ) id 1ih9n2-0000uG-Rc; Tue, 17 Dec 2019 10:09:19 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v4 2/9] um: vector: Add UCAST and MCAST trasnports Date: Tue, 17 Dec 2019 10:09:06 +0000 Message-Id: <20191217100913.3422-2-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> References: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> MIME-Version: 1.0 X-Spam-Score: -1.0 X-Spam-Score: -1.0 X-Clacks-Overhead: GNU Terry Pratchett X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191217_020922_958467_60BC3F65 X-CRM114-Status: GOOD ( 15.89 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard@nod.at, brendanhiggins@google.com, Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Anton Ivanov Add Unicast "bare" packet and Multicast "bare" packet transports compatible with legacy QEMU and UML Signed-off-by: Anton Ivanov --- 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 - 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 From patchwork Tue Dec 17 10:09:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1211253 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cambridgegreys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="EvyE3xco"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47cYlj6M4zz9sRp for ; Tue, 17 Dec 2019 21:09:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=HuJXXtexmkakrg490j7BXQcufonxlXsWXgzoDGgD6xY=; b=EvyE3xcocQyfKo F9Mb3xsVbYF3lX4k7hrrCZCdq3bRiln/fUT8nUlsMrZd5BPLJG3DupGx62v1hbShK5zP870Xt6EcH p8nKhFGmPDSLsfLDQ8r8WUoSaYB78/JUStVrChIdSVHgpsulsAaoY8rq1wxc/dueq+9NHMavmJEuy 5AKsmPRlSwn0iSmuVGZL7XiIzgIqF+EXd8yRW9Thl2k2QOPilAnNIThCkl28OJJJ5P7Ig3xbW5SZk Tr1NL/px9xyZiLjiRMoJkWf5+a5wZ47K9AU96v+osZEsb5he0/XHBo4pwHk1FWO9TPBguRnYUOFXg wWonygyGiS91NFC9ziqg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nF-0002Zz-Hq; Tue, 17 Dec 2019 10:09:29 +0000 Received: from ivanoab7.miniserver.com ([37.128.132.42] helo=www.kot-begemot.co.uk) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nA-0002Xa-PL for linux-um@lists.infradead.org; Tue, 17 Dec 2019 10:09:27 +0000 Received: from tun252.jain.kot-begemot.co.uk ([192.168.18.6] helo=jain.kot-begemot.co.uk) by www.kot-begemot.co.uk with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ih9n8-0003oh-G1; Tue, 17 Dec 2019 10:09:23 +0000 Received: from jain.kot-begemot.co.uk ([192.168.3.3]) by jain.kot-begemot.co.uk with esmtp (Exim 4.92) (envelope-from ) id 1ih9n5-0000uG-0z; Tue, 17 Dec 2019 10:09:21 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v4 3/9] um: Migrate socket transport to Vector backend Date: Tue, 17 Dec 2019 10:09:07 +0000 Message-Id: <20191217100913.3422-3-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> References: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> MIME-Version: 1.0 X-Spam-Score: -1.0 X-Spam-Score: -1.0 X-Clacks-Overhead: GNU Terry Pratchett X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191217_020925_106408_26D0DFF6 X-CRM114-Status: GOOD ( 15.17 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard@nod.at, brendanhiggins@google.com, Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Anton Ivanov Moves legacy socket transport to the vector IO backend Signed-off-by: Anton Ivanov --- 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 - -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 - * 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 -#include -#include "umcast.h" -#include - -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 - * - * 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 -#include -#include -#include "umcast.h" -#include -#include - -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); From patchwork Tue Dec 17 10:09:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1211254 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cambridgegreys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="sqR+T3U5"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47cYlk2QKHz9sS6 for ; Tue, 17 Dec 2019 21:09:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=2eCWwRjAvct7wa1zW/lVHJm3/8OkE0rsNV09jxjI+t8=; b=sqR+T3U5zAbcJ2 DXCTF98mA10/uutpbco+OXtX/QNR8jZXgt+O2JtbY6YjOVlELrY1s+VV7tMfWYolH6HKxZkmOqDLT wDAqVj4I6IQJRFeE5sR+u+9f6BgTbxVuUSxsZP6hoF8RyHQVZaUyCNMXzHXzLk/vr0PMFpDwWrYYc pmgEqaBj3OnqppqqyfgIxM1POhZOodL2vuXLZRnXVeEXo5RgxfIxhhBEG4Cf3cWMLS4ay8SAjoHSq ZTEGaIjnEDj4zwtz+3/3LpMZQX4xbLS26kd8T01Yg/pVX1Uj7bX58kPKmzndyDAJFGOSgWcDXKVy/ q3oS3OSt9gXkO88TuFyQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nG-0002ac-0q; Tue, 17 Dec 2019 10:09:30 +0000 Received: from ivanoab7.miniserver.com ([37.128.132.42] helo=www.kot-begemot.co.uk) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nC-0002YK-TM for linux-um@lists.infradead.org; Tue, 17 Dec 2019 10:09:28 +0000 Received: from tun252.jain.kot-begemot.co.uk ([192.168.18.6] helo=jain.kot-begemot.co.uk) by www.kot-begemot.co.uk with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ih9nB-0003os-OU; Tue, 17 Dec 2019 10:09:25 +0000 Received: from jain.kot-begemot.co.uk ([192.168.3.3]) by jain.kot-begemot.co.uk with esmtp (Exim 4.92) (envelope-from ) id 1ih9n8-0000uG-VE; Tue, 17 Dec 2019 10:09:24 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v4 5/9] um: vector: Add dynamic tap interfaces and scripting Date: Tue, 17 Dec 2019 10:09:09 +0000 Message-Id: <20191217100913.3422-5-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> References: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> MIME-Version: 1.0 X-Spam-Score: -1.0 X-Spam-Score: -1.0 X-Clacks-Overhead: GNU Terry Pratchett X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191217_020926_943250_563BD199 X-CRM114-Status: GOOD ( 15.27 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard@nod.at, brendanhiggins@google.com, Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Anton Ivanov 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 --- 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; } From patchwork Tue Dec 17 10:09:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1211255 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cambridgegreys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="lkcnaVt7"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47cYll0tSxz9sRh for ; Tue, 17 Dec 2019 21:09:39 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=xUwFg0sCGUlhsFdBWqGSwQdtEE9uMBGG7joiN6du+KQ=; b=lkcnaVt7gwBis2 eBMdxdKiMichtYmbCvyPY25xVA9nltOy0cjQ6D9mb+c55fI+jvx5Ljhx8S/ER1hnDAtViasVcqYcq xT1P1cWOyftFbYy28hz5xDccuAf7z9HaswJLjHH7ijCUyL42JLLFqFruIrKH07NQh4k98QoH27Llz CvqEQCfoMyQME6oNU3NHVfygzNbieKDu+Ntnm4/CawdluonhY0TKnqioYxtM6oe6L8E3fL8BA+J7P Jrsqhyy+2v1MoBgWMpdePJMGvxJO2JZl5rJnUpD+I5fn86KU2/QwiOZHZN5zHThM54mL6Bruda7+8 EIbGfW4ZwD0eYxLagyKg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nI-0002bg-8G; Tue, 17 Dec 2019 10:09:32 +0000 Received: from ivanoab7.miniserver.com ([37.128.132.42] helo=www.kot-begemot.co.uk) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nF-0002Zh-Cm for linux-um@lists.infradead.org; Tue, 17 Dec 2019 10:09:31 +0000 Received: from tun252.jain.kot-begemot.co.uk ([192.168.18.6] helo=jain.kot-begemot.co.uk) by www.kot-begemot.co.uk with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ih9nD-0003p1-Vw; Tue, 17 Dec 2019 10:09:28 +0000 Received: from jain.kot-begemot.co.uk ([192.168.3.3]) by jain.kot-begemot.co.uk with esmtp (Exim 4.92) (envelope-from ) id 1ih9nA-0000uG-OL; Tue, 17 Dec 2019 10:09:26 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v4 6/9] um: Migrate tap to vector IO Date: Tue, 17 Dec 2019 10:09:10 +0000 Message-Id: <20191217100913.3422-6-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> References: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> MIME-Version: 1.0 X-Spam-Score: -1.0 X-Spam-Score: -1.0 X-Clacks-Overhead: GNU Terry Pratchett X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191217_020929_597383_5D0975FB X-CRM114-Status: GOOD ( 16.29 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard@nod.at, brendanhiggins@google.com, Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Anton Ivanov Migrates tuntap to the vector IO backend Signed-off-by: Anton Ivanov --- 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, ð_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(ð->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 - -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 -#include -#include -#include -#include -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; From patchwork Tue Dec 17 10:09:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1211256 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cambridgegreys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Egycozq0"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47cYlq15kWz9sRh for ; Tue, 17 Dec 2019 21:09:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=3131EGR624Qx4TTv67j6YN3VP0nrJGlWzzgdESHyYwY=; b=Egycozq0BMrOIO kRZqM7Ra6JspIJc73haDGzDQXyoA6cWhszxkGUiK7I0eHDcdwwjNFpHfoJhav4wl6//GVNg98ngtk dEH2911YoIxfw5HaNYV2icsJKJHUlwa2+CbdK/ViUdVaHooIMtyPiacXyz1aalwAarUKvZ1KId9C+ qgkXoULqIHhl76wK5IZ1dn8bzdVnWIAA0hHYfC3xF4YkiVxzfiBbydDM/iWfyiBeCSXYCXGjQgn1P jsXBvXGqgtkGwIOuBPz3PF3XmfYXfWM53OV8LFjdpKZoxyKU3busA5ldmMFC9NROTjfrSIHRzePO8 LYwWRP4yBGS/WaQ+p10g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nL-0002dk-FE; Tue, 17 Dec 2019 10:09:35 +0000 Received: from ivanoab7.miniserver.com ([37.128.132.42] helo=www.kot-begemot.co.uk) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nI-0002bT-6Y for linux-um@lists.infradead.org; Tue, 17 Dec 2019 10:09:34 +0000 Received: from tun252.jain.kot-begemot.co.uk ([192.168.18.6] helo=jain.kot-begemot.co.uk) by www.kot-begemot.co.uk with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ih9nG-0003p7-Nc; Tue, 17 Dec 2019 10:09:31 +0000 Received: from jain.kot-begemot.co.uk ([192.168.3.3]) by jain.kot-begemot.co.uk with esmtp (Exim 4.92) (envelope-from ) id 1ih9nC-0000uG-ON; Tue, 17 Dec 2019 10:09:29 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v4 7/9] um: Remove ethertap driver and remaining legacy tap/ethertap code Date: Tue, 17 Dec 2019 10:09:11 +0000 Message-Id: <20191217100913.3422-7-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> References: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> MIME-Version: 1.0 X-Spam-Score: -1.0 X-Spam-Score: -1.0 X-Clacks-Overhead: GNU Terry Pratchett X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191217_020932_508891_EAB59499 X-CRM114-Status: GOOD ( 16.11 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard@nod.at, brendanhiggins@google.com, Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Anton Ivanov Ethertap is no longer present in the host kernels and tap has been migrated to the vector IO backend. Signed-off-by: Anton Ivanov --- 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 - 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 #include -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 - -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 -#include -#include "etap.h" -#include - -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 = ðertap_user_info, - .kern = ðertap_kern_info, - .private_size = sizeof(struct ethertap_data), - .setup_size = sizeof(struct ethertap_init), -}; - -static int register_ethertap(void) -{ - register_transport(ðertap_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 -#include -#include -#include -#include -#include -#include "etap.h" -#include -#include -#include - -#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, -}; From patchwork Tue Dec 17 10:09:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1211257 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cambridgegreys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="MYEPwfI7"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47cYlq6FXGz9sRl for ; Tue, 17 Dec 2019 21:09:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=BA3KS4WSkA+0yOigGT5UC7GR4rk9sYXBSKnsUeBzLRE=; b=MYEPwfI7hblMB3 cElXoJ/JyvdDiwVXLbSpdmWgVwFa0oS2/Y6Wfl2bzTMWMcu1nakzFXcGtx9vBmAEwHyTTcM2wwGi2 KmuitP9AOkowCK8vr2QgHLNpjWB6Icf9QAD+yCU9kiesJ3Vu7ZCSAcyWuihY48g6WQiFE6pDr+/FB MCPQfiulJJWvt9xz4iGWSO5hzDPNv8pT1fsWL36qGfqymRIkist1WPwgZjgrz1xnEdkZUbDCo9KLj J5c+3fG4nV69PyV4zywhq2ep8kYyITGX0lpHEPxemXtlgiTXc9k+7DVmvlAG0pdvzW9inttjPBF/o JCQdICODaUK9K6nTHszA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nM-0002eV-LD; Tue, 17 Dec 2019 10:09:36 +0000 Received: from ivanoab7.miniserver.com ([37.128.132.42] helo=www.kot-begemot.co.uk) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nJ-0002cL-Bi for linux-um@lists.infradead.org; Tue, 17 Dec 2019 10:09:35 +0000 Received: from tun252.jain.kot-begemot.co.uk ([192.168.18.6] helo=jain.kot-begemot.co.uk) by www.kot-begemot.co.uk with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ih9nI-0003pC-3X; Tue, 17 Dec 2019 10:09:32 +0000 Received: from jain.kot-begemot.co.uk ([192.168.3.3]) by jain.kot-begemot.co.uk with esmtp (Exim 4.92) (envelope-from ) id 1ih9nF-0000uG-1h; Tue, 17 Dec 2019 10:09:30 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v4 8/9] um: Add daemon transport to vector subsystem Date: Tue, 17 Dec 2019 10:09:12 +0000 Message-Id: <20191217100913.3422-8-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> References: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> MIME-Version: 1.0 X-Spam-Score: -1.0 X-Spam-Score: -1.0 X-Clacks-Overhead: GNU Terry Pratchett X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191217_020933_529273_EE5481C9 X-CRM114-Status: GOOD ( 17.65 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard@nod.at, brendanhiggins@google.com, Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Anton Ivanov Adds a transport compatible with the old uml_switch from uml-utilities package to the vector subsystem. Signed-off-by: Anton Ivanov --- 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 #include #include +#include #include #include #include @@ -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 From patchwork Tue Dec 17 10:09:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1211258 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cambridgegreys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="a7xBV5A7"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47cYls4h9yz9sRh for ; Tue, 17 Dec 2019 21:09:45 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=YJn8J4y2gPWvpcZmv+wTur8aTPJHtCxaGpMJomnXiFg=; b=a7xBV5A7zOueL4 +hJlgXe39j46hhMbCnYotw4oyjU74WGKvJrIfVqLkwfDPx5R57FzVFTNWsnOHLz2Jk/YSQwefqlE5 RgO/HXBTBpVyasDzFE9WWt8k8JRcuxtM/QZSKFoz1ZKmzwcD+XwpZfMH3mq4nOvwKZ3GRKZgcHD0D DmLlqcVwmuUgfxpd8CFqaUwNLbn9UByxm8VkpOU/LU3DOBSePrEpgV6uffPIItpgcLR0zk9GB38Gc nEfaqMnaAN8mjC46C/3jXlvp4or1WqgxF6ynhukD71ECWd/PboKYqu2GmEY+TIwF40qujFEd51X5f vfcMiHfuBqckacudxCmA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nO-0002fF-Qt; Tue, 17 Dec 2019 10:09:38 +0000 Received: from ivanoab7.miniserver.com ([37.128.132.42] helo=www.kot-begemot.co.uk) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ih9nL-0002dY-La for linux-um@lists.infradead.org; Tue, 17 Dec 2019 10:09:37 +0000 Received: from tun252.jain.kot-begemot.co.uk ([192.168.18.6] helo=jain.kot-begemot.co.uk) by www.kot-begemot.co.uk with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ih9nK-0003pI-9K; Tue, 17 Dec 2019 10:09:34 +0000 Received: from jain.kot-begemot.co.uk ([192.168.3.3]) by jain.kot-begemot.co.uk with esmtp (Exim 4.92) (envelope-from ) id 1ih9nG-0000uG-V2; Tue, 17 Dec 2019 10:09:32 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v4 9/9] um: migrate daemon to vector backend Date: Tue, 17 Dec 2019 10:09:13 +0000 Message-Id: <20191217100913.3422-9-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> References: <20191217100913.3422-1-anton.ivanov@cambridgegreys.com> MIME-Version: 1.0 X-Spam-Score: -1.0 X-Spam-Score: -1.0 X-Clacks-Overhead: GNU Terry Pratchett X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191217_020935_840555_5C0B89D4 X-CRM114-Status: GOOD ( 12.79 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard@nod.at, brendanhiggins@google.com, Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Anton Ivanov Removes old daemon packet-a-time code and migrates it to vector backend Signed-off-by: Anton Ivanov --- 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 - -#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 -#include -#include -#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 -#include -#include -#include -#include -#include -#include -#include "daemon.h" -#include -#include -#include - -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;