* [Qemu-devel] Solution for qemu mcast / ipv6?
@ 2009-03-10 15:50 Christian Perle
2009-03-10 16:11 ` Paul Brook
0 siblings, 1 reply; 5+ messages in thread
From: Christian Perle @ 2009-03-10 15:50 UTC (permalink / raw)
To: qemu-devel
Hello there,
We are using qemu's multicast networking feature (-net socket,mcast=...) to
connect some qemu instances (running linux guests) to each other. Qemu's
multicast networking code sets socket option IP_MULTICAST_LOOP to make
communication between local qemu instances possible. So each qemu gets
all the traffic, including its own.
This works fine as long as no ipv6 is used. Because ipv6 has a built-in
duplicate address detection (DAD) and each qemu instance sees its own
traffic, DAD will always detect a ipv6 address collision although there
is none.
Our solution is to patch the function qemu_send_packet() so it drops
packets from source mac address X if the network interface the packet
is being sent to has the same mac address X.
The patch adds a new member "macaddress" to the VLANClientState struct
which is filled by qemu_format_nic_info_str() during interface
initialization. An additional check in qemu_send_packet() decides if
the packet must be dropped.
----------------------------------------------------------------------
diff -ru qemu-0.10.0.orig/net.c qemu-0.10.0/net.c
--- qemu-0.10.0.orig/net.c 2009-03-04 23:54:45.000000000 +0100
+++ qemu-0.10.0/net.c 2009-03-06 16:38:09.000000000 +0100
@@ -303,6 +303,13 @@
vc->model,
macaddr[0], macaddr[1], macaddr[2],
macaddr[3], macaddr[4], macaddr[5]);
+ /* copy mac address into struct for quick matching */
+ vc->macaddress[0] = macaddr[0];
+ vc->macaddress[1] = macaddr[1];
+ vc->macaddress[2] = macaddr[2];
+ vc->macaddress[3] = macaddr[3];
+ vc->macaddress[4] = macaddr[4];
+ vc->macaddress[5] = macaddr[5];
}
static char *assign_name(VLANClientState *vc1, const char *model)
@@ -407,6 +414,19 @@
#endif
for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
if (vc != vc1 && !vc->link_down) {
+ /*
+ * Workaround for IPv6 DAD problem
+ * note: this assumes offset 6 for src mac
+ */
+ if (size >= 12) {
+ if (0 == memcmp(buf+6, &(vc->macaddress),
+ sizeof(vc->macaddress))) {
+#ifdef DEBUG_NET
+ printf("ignore own packet for %s\n", vc->info_str);
+#endif
+ continue;
+ }
+ }
vc->fd_read(vc->opaque, buf, size);
}
}
diff -ru qemu-0.10.0.orig/net.h qemu-0.10.0/net.h
--- qemu-0.10.0.orig/net.h 2009-03-04 23:54:45.000000000 +0100
+++ qemu-0.10.0/net.h 2009-03-06 16:06:04.000000000 +0100
@@ -24,6 +24,8 @@
struct VLANState *vlan;
char *model;
char *name;
+ /* mac address in binary format for quick matching */
+ uint8_t macaddress[6];
char info_str[256];
};
----------------------------------------------------------------------
Now the question: Is this a proper solution? Does it break anything?
So far we haven't seen any regression. It would be nice to have
this in standard qemu, maybe as a configurable option.
Greetings,
Chris
--
Christian Perle chris AT linuxinfotag.de
010111 http://chris.silmor.de/
101010 LinuxGuitarKitesBicyclesBeerPizzaRaytracing
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] Solution for qemu mcast / ipv6?
2009-03-10 15:50 [Qemu-devel] Solution for qemu mcast / ipv6? Christian Perle
@ 2009-03-10 16:11 ` Paul Brook
2009-03-10 20:30 ` Christian Perle
0 siblings, 1 reply; 5+ messages in thread
From: Paul Brook @ 2009-03-10 16:11 UTC (permalink / raw)
To: qemu-devel, chris
Using diff -up makes patches much easier to review.
> @@ -303,6 +303,13 @@ qemu_format_nic_info_str
> vc->model,
> macaddr[0], macaddr[1], macaddr[2],
> macaddr[3], macaddr[4], macaddr[5]);
> + /* copy mac address into struct for quick matching */
> + vc->macaddress[0] = macaddr[0];
> + vc->macaddress[1] = macaddr[1];
> + vc->macaddress[2] = macaddr[2];
> + vc->macaddress[3] = macaddr[3];
> + vc->macaddress[4] = macaddr[4];
> + vc->macaddress[5] = macaddr[5];
> }
This is almost certainly the wrong place to do this.
> Now the question: Is this a proper solution?
No.
> Does it break anything?
Yes.
You can't make any assumptions about MAC addresses. The guest may choose to
use a different MAC address, or it may be acting as a hub/switch and
generating packets from many different MAC addresses.
The bug is in the the mcast socket code. You need to fix that to stop looping
back all the packets.
Paul
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] Solution for qemu mcast / ipv6?
2009-03-10 16:11 ` Paul Brook
@ 2009-03-10 20:30 ` Christian Perle
2009-03-10 23:16 ` Paul Brook
0 siblings, 1 reply; 5+ messages in thread
From: Christian Perle @ 2009-03-10 20:30 UTC (permalink / raw)
To: qemu-devel
Hello Paul,
On Tue, Mar 10, 2009 at 16:11:37 +0000, Paul Brook wrote:
> You can't make any assumptions about MAC addresses. The guest may choose to
> use a different MAC address, or it may be acting as a hub/switch and
Okay, I didn't thought of that.
By the way, changing the MAC address seems not to work for the default
ne2k card while the e1000 card works. With ne2k everything works
(setting new MAC address, sending ARP replies with the new address)
except receiving packets sent to the new address. Maybe the MAC filter
in the ne2k emulation code is not updated. (tested with a
unpatched qemu 0.10.0)
> The bug is in the the mcast socket code. You need to fix that to stop looping
> back all the packets.
Do you mean the mcast socket code in qemu or the way IP_MULTICAST_LOOP
works in the linux kernel?
Greetings,
Chris
--
Christian Perle chris AT linuxinfotag.de
010111 http://chris.silmor.de/
101010 LinuxGuitarKitesBicyclesBeerPizzaRaytracing
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] Solution for qemu mcast / ipv6?
2009-03-10 20:30 ` Christian Perle
@ 2009-03-10 23:16 ` Paul Brook
2009-03-10 23:55 ` Jamie Lokier
0 siblings, 1 reply; 5+ messages in thread
From: Paul Brook @ 2009-03-10 23:16 UTC (permalink / raw)
To: qemu-devel, chris
> > The bug is in the the mcast socket code. You need to fix that to stop
> > looping back all the packets.
>
> Do you mean the mcast socket code in qemu or the way IP_MULTICAST_LOOP
> works in the linux kernel?
I don't know. Hacking the generic vlan code is definitely the wrong solution
though.
Paul
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] Solution for qemu mcast / ipv6?
2009-03-10 23:16 ` Paul Brook
@ 2009-03-10 23:55 ` Jamie Lokier
0 siblings, 0 replies; 5+ messages in thread
From: Jamie Lokier @ 2009-03-10 23:55 UTC (permalink / raw)
To: qemu-devel; +Cc: chris
Paul Brook wrote:
> > > The bug is in the the mcast socket code. You need to fix that to stop
> > > looping back all the packets.
> >
> > Do you mean the mcast socket code in qemu or the way IP_MULTICAST_LOOP
> > works in the linux kernel?
>
> I don't know. Hacking the generic vlan code is definitely the wrong solution
> though.
I suspect there's no suitable kernel option, and this is for all
hosts, not just Linux.
One solution is filtering in the userspace code which talks to the
socket.
Filtering by MAC address is wrong as Paul has explained.
So the filtering which comes to mind is (a) keep _strong_ checksums of
all recently sent packets, (b) discard any received packets which
match a recently sent one, and (c) make sure to remove any checksum
when it matches in (b), because it's legitimate for the _same_ packet
to arrive from another host soon after, and that should not be
filtered.
Alternatively, presuming the idea is to tunnel raw ethernet packets
into a multicast IP packet, change the tunnelled format slightly to
include a unique sender identifier, and filter on that. That's
unambiguous.
-- Jamie
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2009-03-10 23:55 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-10 15:50 [Qemu-devel] Solution for qemu mcast / ipv6? Christian Perle
2009-03-10 16:11 ` Paul Brook
2009-03-10 20:30 ` Christian Perle
2009-03-10 23:16 ` Paul Brook
2009-03-10 23:55 ` Jamie Lokier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).