f0bf933e69
- qemu-user: add device mapper and loopback ioctls, enabling kpatkx OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=40
352 lines
11 KiB
Diff
352 lines
11 KiB
Diff
From 15d6a32b38abc6c2f8143ebccfcdd05d204f0fcd Mon Sep 17 00:00:00 2001
|
|
From: Benjamin <mlspirat42@gmail.com>
|
|
Date: Sat, 8 Oct 2011 07:31:33 +0000
|
|
Subject: [PATCH] Integrating Dynamips and GNS3 UDP tunnels (Patches)
|
|
|
|
On 10/07/11 10:35, Jan Kiszka wrote:
|
|
>
|
|
> You should send out the changes as proper patch series, rebased on
|
|
> current git head. See http://wiki.qemu.org/Contribute/SubmitAPatch for
|
|
> further requirements. And make sure that no patch breaks the build so
|
|
> that bisectability is preserved.
|
|
>
|
|
> Jan
|
|
>
|
|
|
|
Tested and used for several years by GNS3, it doesn't break the build.
|
|
|
|
I could not access http://git.qemu.org/qemu.git/plain/CODING_STYLE and
|
|
http://git.qemu.org/qemu.git/plain/HACKING (404) so these patches may
|
|
not be 100% conform. The script didn't report any error though.
|
|
|
|
Signed-off-by: Benjamin MARSILI <marsil_b@epitech.eu>
|
|
|
|
"-net tap[,vlan=n][,name=str],ifname=name\n"
|
|
" connect the host TAP network interface to VLAN 'n'\n"
|
|
|
|
----
|
|
|
|
[agraf] I combined the upstream submitted mail header with the 0.14 Uli
|
|
version of the patch. If this isn't upstream by 1.1, remove in
|
|
the next round!
|
|
---
|
|
Makefile.objs | 1 +
|
|
block/raw-win32.c | 4 +-
|
|
hw/e1000.c | 2 +-
|
|
net.c | 25 ++++++++++
|
|
net.h | 1 +
|
|
net/udp.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
net/udp.h | 32 ++++++++++++
|
|
qemu-options.hx | 2 +
|
|
8 files changed, 202 insertions(+), 3 deletions(-)
|
|
create mode 100644 net/udp.c
|
|
create mode 100644 net/udp.h
|
|
|
|
diff --git a/Makefile.objs b/Makefile.objs
|
|
index d7a6539..1a28830 100644
|
|
--- a/Makefile.objs
|
|
+++ b/Makefile.objs
|
|
@@ -46,6 +46,7 @@ net-obj-y = net.o
|
|
net-nested-y = queue.o checksum.o util.o
|
|
net-nested-y += socket.o
|
|
net-nested-y += dump.o
|
|
+net-nested-y += udp.o
|
|
net-nested-$(CONFIG_POSIX) += tap.o
|
|
net-nested-$(CONFIG_LINUX) += tap-linux.o
|
|
net-nested-$(CONFIG_WIN32) += tap-win32.o
|
|
diff --git a/block/raw-win32.c b/block/raw-win32.c
|
|
index e4b0b75..09528ac 100644
|
|
--- a/block/raw-win32.c
|
|
+++ b/block/raw-win32.c
|
|
@@ -97,7 +97,7 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
|
|
if (!(flags & BDRV_O_CACHE_WB))
|
|
overlapped |= FILE_FLAG_WRITE_THROUGH;
|
|
s->hfile = CreateFile(filename, access_flags,
|
|
- FILE_SHARE_READ, NULL,
|
|
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
|
OPEN_EXISTING, overlapped, NULL);
|
|
if (s->hfile == INVALID_HANDLE_VALUE) {
|
|
int err = GetLastError();
|
|
@@ -387,7 +387,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
|
|
if (!(flags & BDRV_O_CACHE_WB))
|
|
overlapped |= FILE_FLAG_WRITE_THROUGH;
|
|
s->hfile = CreateFile(filename, access_flags,
|
|
- FILE_SHARE_READ, NULL,
|
|
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
|
create_flags, overlapped, NULL);
|
|
if (s->hfile == INVALID_HANDLE_VALUE) {
|
|
int err = GetLastError();
|
|
diff --git a/hw/e1000.c b/hw/e1000.c
|
|
index 986ed9c..19ca5bf 100644
|
|
--- a/hw/e1000.c
|
|
+++ b/hw/e1000.c
|
|
@@ -577,7 +577,7 @@ receive_filter(E1000State *s, const uint8_t *buf, int size)
|
|
if (rctl & E1000_RCTL_UPE) // promiscuous
|
|
return 1;
|
|
|
|
- if ((buf[0] & 1) && (rctl & E1000_RCTL_MPE)) // promiscuous mcast
|
|
+ if ((buf[0] & 1)) //&& (rctl & E1000_RCTL_MPE)) // promiscuous mcast
|
|
return 1;
|
|
|
|
if ((rctl & E1000_RCTL_BAM) && !memcmp(buf, bcast, sizeof bcast))
|
|
diff --git a/net.c b/net.c
|
|
index cb52050..dc1689c 100644
|
|
--- a/net.c
|
|
+++ b/net.c
|
|
@@ -30,6 +30,7 @@
|
|
#include "net/dump.h"
|
|
#include "net/slirp.h"
|
|
#include "net/vde.h"
|
|
+#include "net/udp.h"
|
|
#include "net/util.h"
|
|
#include "monitor.h"
|
|
#include "qemu-common.h"
|
|
@@ -1031,6 +1032,29 @@ static const struct {
|
|
},
|
|
},
|
|
#endif
|
|
+
|
|
+ [NET_CLIENT_TYPE_UDP] = {
|
|
+ .type = "udp",
|
|
+ .init = net_init_udp,
|
|
+ .desc = {
|
|
+ NET_COMMON_PARAMS_DESC,
|
|
+ {
|
|
+ .name = "sport",
|
|
+ .type = QEMU_OPT_NUMBER,
|
|
+
|
|
+ .help = "source port number",
|
|
+ }, {
|
|
+ .name = "daddr",
|
|
+ .type = QEMU_OPT_STRING,
|
|
+ .help = "destination IP address",
|
|
+ }, {
|
|
+ .name = "dport",
|
|
+ .type = QEMU_OPT_NUMBER,
|
|
+ .help = "destination port number",
|
|
+ },
|
|
+ { /* end of list */ }
|
|
+ },
|
|
+ },
|
|
[NET_CLIENT_TYPE_DUMP] = {
|
|
.type = "dump",
|
|
.init = net_init_dump,
|
|
@@ -1348,6 +1372,7 @@ void net_check_clients(void)
|
|
case NET_CLIENT_TYPE_USER:
|
|
case NET_CLIENT_TYPE_TAP:
|
|
case NET_CLIENT_TYPE_SOCKET:
|
|
+ case NET_CLIENT_TYPE_UDP:
|
|
case NET_CLIENT_TYPE_VDE:
|
|
has_host_dev = 1;
|
|
break;
|
|
diff --git a/net.h b/net.h
|
|
index 9f633f8..ac6118c 100644
|
|
--- a/net.h
|
|
+++ b/net.h
|
|
@@ -35,6 +35,7 @@ typedef enum {
|
|
NET_CLIENT_TYPE_TAP,
|
|
NET_CLIENT_TYPE_SOCKET,
|
|
NET_CLIENT_TYPE_VDE,
|
|
+ NET_CLIENT_TYPE_UDP,
|
|
NET_CLIENT_TYPE_DUMP,
|
|
|
|
NET_CLIENT_TYPE_MAX
|
|
diff --git a/net/udp.c b/net/udp.c
|
|
new file mode 100644
|
|
index 0000000..6080919
|
|
--- /dev/null
|
|
+++ b/net/udp.c
|
|
@@ -0,0 +1,138 @@
|
|
+/*
|
|
+ * QEMU System Emulator
|
|
+ *
|
|
+ * Copyright (c) 2003-2008 Fabrice Bellard
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
+ * of this software and associated documentation files (the "Software"), to deal
|
|
+ * in the Software without restriction, including without limitation the rights
|
|
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
+ * copies of the Software, and to permit persons to whom the Software is
|
|
+ * furnished to do so, subject to the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be included in
|
|
+ * all copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
+ * THE SOFTWARE.
|
|
+ */
|
|
+#include "net/udp.h"
|
|
+
|
|
+#include "config-host.h"
|
|
+
|
|
+#ifndef _WIN32
|
|
+#include <arpa/inet.h>
|
|
+#include <netinet/in.h>
|
|
+#include <netinet/udp.h>
|
|
+#endif
|
|
+
|
|
+#include "net.h"
|
|
+#include "qemu-char.h"
|
|
+#include "qemu-common.h"
|
|
+#include "qemu-option.h"
|
|
+#include "qemu_socket.h"
|
|
+#include "sysemu.h"
|
|
+
|
|
+
|
|
+typedef struct UDPState {
|
|
+ VLANClientState nc;
|
|
+ int rfd;
|
|
+ struct sockaddr_in sender;
|
|
+} UDPState;
|
|
+
|
|
+static void udp_to_qemu(void *opaque)
|
|
+{
|
|
+ UDPState *s = opaque;
|
|
+ uint8_t buf[4096];
|
|
+ int size;
|
|
+
|
|
+ size = recvfrom(s->rfd, (char *)buf, sizeof(buf), 0, NULL, NULL);
|
|
+ if (size > 0) {
|
|
+ qemu_send_packet(&s->nc, buf, size);
|
|
+ }
|
|
+}
|
|
+
|
|
+static ssize_t udp_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
|
+{
|
|
+ UDPState *s = DO_UPCAST(UDPState, nc, nc);
|
|
+ int ret;
|
|
+
|
|
+ do {
|
|
+ ret = sendto(s->rfd, (const char *)buf, size, 0, (struct sockaddr *)&s->sender, sizeof (s->sender));
|
|
+ } while (ret < 0 && errno == EINTR);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void udp_cleanup(VLANClientState *nc)
|
|
+{
|
|
+ UDPState *s = DO_UPCAST(UDPState, nc, nc);
|
|
+ qemu_set_fd_handler(s->rfd, NULL, NULL, NULL);
|
|
+ close(s->rfd);
|
|
+}
|
|
+
|
|
+static NetClientInfo net_udp_info = {
|
|
+ .type = NET_CLIENT_TYPE_UDP,
|
|
+ .size = sizeof(UDPState),
|
|
+ .receive = udp_receive,
|
|
+ .cleanup = udp_cleanup,
|
|
+};
|
|
+
|
|
+static int net_udp_init(VLANState *vlan, const char *model,
|
|
+ const char *name, int sport,
|
|
+ const char *daddr, int dport)
|
|
+{
|
|
+ VLANClientState *nc;
|
|
+ UDPState *s;
|
|
+ struct sockaddr_in receiver;
|
|
+ int ret;
|
|
+
|
|
+ nc = qemu_new_net_client(&net_udp_info, vlan, NULL, model, name);
|
|
+
|
|
+ snprintf(nc->info_str, sizeof(nc->info_str),"udp: %i->%s:%i",
|
|
+ sport, daddr, dport);
|
|
+
|
|
+ s = DO_UPCAST(UDPState, nc, nc);
|
|
+
|
|
+ s->rfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
|
|
+ receiver.sin_family = AF_INET;
|
|
+ receiver.sin_addr.s_addr = INADDR_ANY;
|
|
+ receiver.sin_port = htons(sport);
|
|
+ ret = bind(s->rfd, (struct sockaddr *)&receiver, sizeof(receiver));
|
|
+
|
|
+ if (ret == -1) {
|
|
+ fprintf (stderr, "bind error:%s\n", strerror(errno));
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ memset((char*)&s->sender, 0,sizeof(s->sender));
|
|
+ s->sender.sin_family = AF_INET;
|
|
+ s->sender.sin_port = htons(dport);
|
|
+ inet_aton(daddr, &s->sender.sin_addr);
|
|
+
|
|
+ qemu_set_fd_handler(s->rfd, udp_to_qemu, NULL, s);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int net_init_udp(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan)
|
|
+{
|
|
+ const char *daddr;
|
|
+ int sport, dport;
|
|
+
|
|
+ daddr = qemu_opt_get(opts, "daddr");
|
|
+
|
|
+ sport = qemu_opt_get_number(opts, "sport", 0);
|
|
+ dport = qemu_opt_get_number(opts, "dport", 0);
|
|
+
|
|
+ if (net_udp_init(vlan, "udp", name, sport, daddr, dport) == -1) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
diff --git a/net/udp.h b/net/udp.h
|
|
new file mode 100644
|
|
index 0000000..9e92852
|
|
--- /dev/null
|
|
+++ b/net/udp.h
|
|
@@ -0,0 +1,32 @@
|
|
+/*
|
|
+ * QEMU System Emulator
|
|
+ *
|
|
+ * Copyright (c) 2003-2008 Fabrice Bellard
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
+ * of this software and associated documentation files (the "Software"), to deal
|
|
+ * in the Software without restriction, including without limitation the rights
|
|
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
+ * copies of the Software, and to permit persons to whom the Software is
|
|
+ * furnished to do so, subject to the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be included in
|
|
+ * all copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
+ * THE SOFTWARE.
|
|
+ */
|
|
+#ifndef QEMU_NET_UDP_H
|
|
+#define QEMU_NET_UDP_H
|
|
+
|
|
+#include "qemu-common.h"
|
|
+#include "qemu-option.h"
|
|
+
|
|
+int net_init_udp(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan);
|
|
+
|
|
+#endif /* QEMU_NET_UDP_H */
|
|
diff --git a/qemu-options.hx b/qemu-options.hx
|
|
index 83b1f38..94f946e 100644
|
|
--- a/qemu-options.hx
|
|
+++ b/qemu-options.hx
|
|
@@ -1226,6 +1226,8 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
|
|
"-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port[,localaddr=addr]]\n"
|
|
" connect the vlan 'n' to multicast maddr and port\n"
|
|
" use 'localaddr=addr' to specify the host address to send packets from\n"
|
|
+ "-net udp[,vlan=n]sport=sport,dport=dport,daddr=host\n"
|
|
+ " connect the vlan 'n' to a UDP tunnel (for Dynamips/GNS3)\n"
|
|
#ifdef CONFIG_VDE
|
|
"-net vde[,vlan=n][,name=str][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
|
|
" connect the vlan 'n' to port 'n' of a vde switch running\n"
|
|
--
|
|
1.6.0.2
|
|
|