From patchwork Fri Dec 13 16:08:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1209249 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="YFaXDg+P"; 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 47ZFwh0842z9sPc for ; Sat, 14 Dec 2019 03:09:24 +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=YFaXDg+PS25+3P fhMHGzaewMa18qJIPBNlWK/SHY0LJ21p/lDgZLlMNI7VN6L2ixawZ7xMD0bxu1ASkBY8yy5bqI1ft 8fGLq0mgi3uBtAHvXEVH8x19VXPIZseVnnXZ5qB3VTC0IO5wTVacOINbDAC8z5nPK+CrmWmP5BMqs jVx/2Zg71PuoyfEWIGlHK9r1TP1sBgMfAyXmEoSffXy+5Ao1rw3IC6lFt7nMBlMb2LoKVfi8WRYK8 qEcZ/OXO2Bx1dS6N2oIiH+eWyyRAkb2MmSqpToSk+G13P5BhwhS7wzl0EpO7ZGTXdpj/0hVJzkbKS BzV6DJg2LLOz0v/m15iw==; 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 1ifnVE-0006nm-Ns; Fri, 13 Dec 2019 16:09:16 +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 1ifnV8-0006hq-5G for linux-um@lists.infradead.org; Fri, 13 Dec 2019 16:09:14 +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 1ifnV2-0005sR-JF; Fri, 13 Dec 2019 16:09:05 +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 1ifnUy-0007W4-VY; Fri, 13 Dec 2019 16:09:03 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH 1/3] um: Migrate pcap to vector IO Date: Fri, 13 Dec 2019 16:08:56 +0000 Message-Id: <20191213160858.28840-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-20191213_080910_476009_ECFD10A6 X-CRM114-Status: GOOD ( 17.77 ) 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_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO 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 Fri Dec 13 16:08:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1209248 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="EttWIRqF"; 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 47ZFwf0Wn7z9sPT for ; Sat, 14 Dec 2019 03:09:22 +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=iWks74FVU/UAnbc/4Sm2FDOCNaCHh4kriSIWpIiTZqw=; b=EttWIRqF2zuOWx 6pXPXvpUSKb1FQuuEtQoLbXK7/4jEiqr82qIYcEmOSU9gHdDVa3PVxWzNvNEoOGVchPcWQ0+2uL8g zgyViRSeJT8L2Ys+8FC9Mh3yXHrI0nJ8om4+tnjqTgArg5goAaB3D76y4wK16kXkY3VfOg1SWqP4V 7qod7QKe+mnwq7oUHl4Ya+QC7VShy8l9QyFLYDlgHNytS/NmyfUgnr0PqA6G6Z7Ymlc3LTVBxr5ay DvfUw85L3GortTvnMWSkJMLU81/kHYeo/Uo0Fen8lAq2k/cdwfOQGaG2bPjEN+cmSNWAfydFi6NBK QG0QyksHJDJRdjcEgGDQ==; 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 1ifnVC-0006me-6V; Fri, 13 Dec 2019 16:09:14 +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 1ifnV8-0006hr-5D for linux-um@lists.infradead.org; Fri, 13 Dec 2019 16:09:12 +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 1ifnV4-0005sU-M3; Fri, 13 Dec 2019 16:09:06 +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 1ifnV1-0007W4-44; Fri, 13 Dec 2019 16:09:05 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH 2/3] um: vector: Add UCAST and MCAST trasnports Date: Fri, 13 Dec 2019 16:08:57 +0000 Message-Id: <20191213160858.28840-2-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191213160858.28840-1-anton.ivanov@cambridgegreys.com> References: <20191213160858.28840-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-20191213_080910_329773_9E451393 X-CRM114-Status: GOOD ( 15.93 ) 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_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO 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 | 21 ++++----- 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, 80 insertions(+), 23 deletions(-) diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig index 388096fb45a2..a84b806212a3 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,20 +293,17 @@ 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. - - For more information, see - That site - has examples of the UML command line to use to enable this option. + 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. - If you intend to use UML as a network monitor for the host, say - Y here. Otherwise, say N. + It is recommended to use VECTOR RAW directly instead because + it provides a number of options which are otherwise unavailable + via this interface. + config UML_NET_SLIRP bool "SLiRP transport" depends on UML_NET 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..59e756df9af9 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 Fri Dec 13 16:08:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1209250 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="GcaN7im8"; 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 47ZFwk45Pzz9sPT for ; Sat, 14 Dec 2019 03:09:26 +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=GcaN7im8BWiIKA AgFlHKvmA1vwpcLynKH2OltccHA8/BgWw/cMblLLdNqfgv0BK3eY4WH+Vo1OTdplaDU+IIM75hqNy bYBvqS5TNyCly/4rEF1pw8wznl0Uh+iF5AxVpPR9x1UmrPMv9CJvPQV554mIyCwU/O9f0YdkQ4qfW nSVHzRVxy3kkL3zgAszJL1IgPmZb5COdGYVKXWebheV1HTOaetku287eGXu/dTVRUNxphAPa/wzUJ DXtvURcnHmfGj5XfOFFy4Vk58CMtUIG4//6IGf/pO07I0Symv5QbgmRH4Yk+8aYS50OGZIU1M/10B ldyk1w/dyAR4apCCLF4g==; 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 1ifnVE-0006nY-Ef; Fri, 13 Dec 2019 16:09:16 +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 1ifnV8-0006iP-8y for linux-um@lists.infradead.org; Fri, 13 Dec 2019 16:09:14 +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 1ifnV6-0005sb-L6; Fri, 13 Dec 2019 16:09:09 +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 1ifnV3-0007W4-8o; Fri, 13 Dec 2019 16:09:07 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH 3/3] um: Migrate socket transport to Vector backend Date: Fri, 13 Dec 2019 16:08:58 +0000 Message-Id: <20191213160858.28840-3-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191213160858.28840-1-anton.ivanov@cambridgegreys.com> References: <20191213160858.28840-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-20191213_080910_460732_D5EF068D X-CRM114-Status: GOOD ( 14.24 ) 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_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO 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);