From patchwork Mon Dec 16 17:03:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1210609 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="FF23apY9"; 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 47c7090XHQz9sRl for ; Tue, 17 Dec 2019 04:03:53 +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=gENN6fP2ij24Oq8Yu3kRB89EpZFwYy+ioHuAz3NnJd4=; b=FF23apY97D6MkY Hf0j0dJAcsKdoHN3x32nxRku8AbiUpPSXVoIn/ddNj5Xc+EVr++AdThCRwbfbhD4BHifDfULt50Jh 4nDTHmvINhRInM3A7wZv7bZiNcW5X3LJSbpOxv6A3onhQ0HmeFbhnaaqY1I/YtWaIFxGTLBQMGJ7x MND2B7vazWVteMLakpasDQUAGRK8EtiW3VERe8+xwbo0NxrzwhqPNX7qCpXRHdD/3bXACA6umivRI WbEZV7bEOaC8JiNsIvkMJR9bSWv+rt6pgaCh/oRf7NIsaNTKlEu9CAsePFO0sM6lo6TQgcr0yphQQ XTX2NayM3Astrd8qTf0Q==; 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 1igtmU-0001dz-LU; Mon, 16 Dec 2019 17:03: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 1igtmP-0001aN-B2 for linux-um@lists.infradead.org; Mon, 16 Dec 2019 17:03: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 1igtmI-00010n-SU; Mon, 16 Dec 2019 17:03:27 +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 1igtmF-0003g4-4c; Mon, 16 Dec 2019 17:03:25 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v3 1/6] um: Migrate pcap to vector IO Date: Mon, 16 Dec 2019 17:03:16 +0000 Message-Id: <20191216170321.14056-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-20191216_090333_647215_A47B1203 X-CRM114-Status: GOOD ( 18.09 ) 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..7df7344f2194 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 Mon Dec 16 17:03:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1210607 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="Ew+0mw4C"; 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 47c7081dyPz9sRd for ; Tue, 17 Dec 2019 04:03:52 +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=nwQh0ull7hCIiN+UtJTrGMR7tLBMQzMYzfXJl3lj3J4=; b=Ew+0mw4C/UF27S J183C+IOLQTXvIuZQVPe/I2VYUaJBywlUg8Th206jopETjRzXRE3rJwh46qJd65vUzdrQplNw7Qkv 2h40ad2Z8YZMVskIBnmtkfNDpM7B5t7J0zvbXQS/8SLIYAo3a5JFFE7tbBYoTvIQ1VbGLEaY39zGS 4CmeXIHSxRDYiCkij868BCVuYaRFkzd3mv99jgCf0BDcCDZ1jiBSb3OgbfB8cBIcinLazFWF9vhTC MypEhjp0Zt2MhJB/rxFr0qm2A+thZxjgb4viT/Q0dpPfsDGlf45B8b9Gr2qKscpj52J/8TzMBaK4D lEvtFvEWMQPVqvTq3QzA==; 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 1igtmU-0001dH-6I; Mon, 16 Dec 2019 17:03: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 1igtmP-0001an-Mv for linux-um@lists.infradead.org; Mon, 16 Dec 2019 17:03: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 1igtmM-00010x-Uq; Mon, 16 Dec 2019 17:03: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 1igtmJ-0003g4-GI; Mon, 16 Dec 2019 17:03:29 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v3 3/6] um: Migrate socket transport to Vector backend Date: Mon, 16 Dec 2019 17:03:18 +0000 Message-Id: <20191216170321.14056-3-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216170321.14056-1-anton.ivanov@cambridgegreys.com> References: <20191216170321.14056-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-20191216_090333_876662_1978EE92 X-CRM114-Status: GOOD ( 14.45 ) 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/umcast.h | 27 ----- arch/um/drivers/umcast_kern.c | 188 ---------------------------------- arch/um/drivers/umcast_user.c | 184 --------------------------------- arch/um/drivers/vector_kern.c | 31 ++++++ 5 files changed, 31 insertions(+), 401 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/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 Mon Dec 16 17:03:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1210601 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="uD0LE1IK"; 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 47c7031RbJz9sRc for ; Tue, 17 Dec 2019 04:03:47 +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=oQbBG7O2x3dt/SofgfBcXkUNMMLFPYptlqXsj1PJLt4=; b=uD0LE1IKCYapE9 PMF1BckAU+byuY/HDUoUi7AYsjw+vxHGujnERzKJjXiOTwrSOGCGIszfoJIWeD7R9cgP8fFNq+zpa 1IHQoQ+xcQNcnWamerMzHxxha2HJJ2Xovk4wYRgTyYwkZw6Fw7FUop2+VS2WGLLK0TYjtPg7Sl/7l 1O+8JpJGdF6aRYUf+6TDzNLBjbB9bML3uFseROj0Pnv9F1LSZsw3+4n9n2FQGcT0dRUR0UxYd/Jrr +cPTj/gp2xnMX5CCKAUeaO1aXs2w7GoceVyrlEdUj6Q0h0UBlXopX6B5T+5fTpWySc8c0Lkc8nGF6 Ttcf7RMvufxXqXwibxeQ==; 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 1igtmS-0001cL-Ol; Mon, 16 Dec 2019 17:03: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 1igtmP-0001ay-FN for linux-um@lists.infradead.org; Mon, 16 Dec 2019 17:03: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 1igtmO-000114-DY; Mon, 16 Dec 2019 17:03: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 1igtmL-0003g4-JZ; Mon, 16 Dec 2019 17:03:31 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v3 4/6] um: Enable GRO by default when using raw in pcap compat mode Date: Mon, 16 Dec 2019 17:03:19 +0000 Message-Id: <20191216170321.14056-4-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216170321.14056-1-anton.ivanov@cambridgegreys.com> References: <20191216170321.14056-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-20191216_090333_507829_37577DF4 X-CRM114-Status: UNSURE ( 6.53 ) X-CRM114-Notice: Please train this message. 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 GRO is enabled nearly everywhere in Linux nowdays, not having it on by default results in packet drops across the board. Signed-off-by: Anton Ivanov --- arch/um/drivers/vector_kern.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index 234081ad4f02..d52c24874f2a 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -1717,9 +1717,9 @@ int vector_compat_eth_configure(char *str, int index) &options[0], &options[1], &mac, NULL); if ((mac != NULL) && strlen(mac) > 0) - snprintf(tempargs, MAX_COMPAT_ARG, "transport=raw,ifname=%s,mac=%s", ifname, mac); + snprintf(tempargs, MAX_COMPAT_ARG, "transport=raw,gro=1,ifname=%s,mac=%s", ifname, mac); else - snprintf(tempargs, MAX_COMPAT_ARG, "transport=raw,ifname=%s", ifname); + snprintf(tempargs, MAX_COMPAT_ARG, "transport=raw,gro=1,ifname=%s", ifname); strcpy(newargs, tempargs); From patchwork Mon Dec 16 17:03:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1210603 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="BsuZgZzl"; 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 47c7030XXTz9sRM for ; Tue, 17 Dec 2019 04:03:47 +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=Y+4NNtHlpKXdcMYyhvY9MaO0+Kfkzn2z/ToGyf8RaHo=; b=BsuZgZzl+2/Iw3 wq7/AO/oy7i2trwbUWSKDg1i+cB0bi1nV1P9yL7DDGElnKiOml4OT7XvPS1nnZxxfr8aLoLAmRQSM VGyr90iMJ2zHtIQkEcNXR45XD+Zh7t+8Uw4rTDLRGpDG1kzpB700fCoiUlDabuSdAD2KdkwRdTD40 c4Xhg/QptQUMw6OatVw8s6QotGbHn977S9nftrUZLkC+Y6XoTpheUD+wsv2cGmyYHAYvQjNhCQcf3 W5yhEri2plOKCB5KeHbP72a+GzEPDwxpVUpCMBgSKuk8lJfp6X4X3B8L6Y83ciV+iGIoYABBJU4fy RjttTbNQwz0b4D5Kuz+w==; 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 1igtmU-0001dY-Ca; Mon, 16 Dec 2019 17:03: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 1igtmR-0001bs-CG for linux-um@lists.infradead.org; Mon, 16 Dec 2019 17:03:36 +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 1igtmQ-000119-8F; Mon, 16 Dec 2019 17:03: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 1igtmN-0003g4-C4; Mon, 16 Dec 2019 17:03:33 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v3 5/6] um: vector: Add dynamic tap interfaces and scripting Date: Mon, 16 Dec 2019 17:03:20 +0000 Message-Id: <20191216170321.14056-5-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216170321.14056-1-anton.ivanov@cambridgegreys.com> References: <20191216170321.14056-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-20191216_090335_412407_6FAEF5CB X-CRM114-Status: GOOD ( 15.19 ) 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 59e756df9af9..ea79887f1c9b 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 Mon Dec 16 17:03:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1210605 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="pFYUoP0D"; 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 47c7042MNQz9sRk for ; Tue, 17 Dec 2019 04:03:48 +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=eL4x+y1jmugVI9hFNex0z/zDtuvXgEQhJp9iQ4E8EuQ=; b=pFYUoP0DSnQ6xX 4mXOJ5yKGCGbMqbuBtamuPXQlgMOcB8ZhHq4B5pIKlnxZaTHLjDUeurgKh1mMV3pMHNQ+1qtnCQBi x9qwUYoNJuhNGdORR9+i8v55j+r0/RUJx2JOmzdL6KkDluc1e6FcX2YktHSxQWhhXdvMDZtNqyLvD vDKj95KZuXjSvsMi85eRN0GfjAS6jLlOYKplPWUYD32dJtA8u3p7vFOiBPM1+l8oIR7CMAFhFWNxw FMA8pngu8dMve4UYtuznm/BgheTv7o6C0Y0VAKTFlg54CMi65h9R1e+H2KHf+mk8dkV2Q6gyXgBQx B6VeonSyk5skas0JgtUw==; 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 1igtmW-0001fA-Uf; Mon, 16 Dec 2019 17:03:40 +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 1igtmT-0001cr-QS for linux-um@lists.infradead.org; Mon, 16 Dec 2019 17:03:39 +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 1igtmS-00011G-EF; Mon, 16 Dec 2019 17:03:36 +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 1igtmP-0003g4-7O; Mon, 16 Dec 2019 17:03:35 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH v3 6/6] um: Migrate tap to vector IO Date: Mon, 16 Dec 2019 17:03:21 +0000 Message-Id: <20191216170321.14056-6-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216170321.14056-1-anton.ivanov@cambridgegreys.com> References: <20191216170321.14056-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-20191216_090337_988114_29FDA6F9 X-CRM114-Status: GOOD ( 16.20 ) 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 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 a84b806212a3..74b76ac0a2fe 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 7df7344f2194..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"}; -#define MAX_MIGRATED 1 +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, -};