From: JuanJo <juanjosec@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] QEMU multicast socket support v2
Date: Wed, 7 Dec 2005 13:05:25 -0300 [thread overview]
Message-ID: <1be1aa250512070805w24a17ecaqad491a2335ac3973@mail.gmail.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 799 bytes --]
Hi.
Attached patch (against CVS) implements UDP multicast support for creating
virtual BUSes.
Excerpt from qemu-doc.texi diff (indeed tested w/these QEMUs):
# launch one QEMU instance
qemu linux.img -net nic,macaddr=52:54:00:12:34:56 -net socket,mcast=
230.0.0.1:1234
# launch another QEMU instance on same "bus"
qemu linux.img -net nic,macaddr=52:54:00:12:34:57 -net
socket,mcast=230.0.0.1:1234
# launch yet another QEMU instance on same "bus"
qemu linux.img -net nic,macaddr=52:54:00:12:34:58 -net socket,mcast=
230.0.0.1:1234
Enjoy
--
--Juanjo
# Juan Jose Ciarlante (JuanJo) jjo ;at; mendoza.gov.ar
#
# GnuPG Public Key: gpg --keyserver wwwkeys.eu.pgp.net --recv-key 66727177
#
# Key fingerprint: 0D2F 3E5D 8B5C 729E 0560 F453 A3F7 E249 6672 7177
#
[-- Attachment #1.2: Type: text/html, Size: 1603 bytes --]
[-- Attachment #2: qemu-socket_mcast.jjo.v2.diff.asc --]
[-- Type: text/plain, Size: 5840 bytes --]
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Index: vl.c
===================================================================
RCS file: /cvsroot/qemu/qemu/vl.c,v
retrieving revision 1.152
diff -u -r1.152 vl.c
- --- vl.c 5 Dec 2005 20:31:52 -0000 1.152
+++ vl.c 7 Dec 2005 15:02:09 -0000
@@ -2131,8 +2131,14 @@
int index;
int packet_len;
uint8_t buf[4096];
+ struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
} NetSocketState;
+static int qemu_socket_is_dgram(const struct NetSocketState *s)
+{
+ return (s->dgram_dst.sin_addr.s_addr!=0);
+}
+
typedef struct NetSocketListenState {
VLANState *vlan;
int fd;
@@ -2145,8 +2151,12 @@
uint32_t len;
len = htonl(size);
- - unix_write(s->fd, (const uint8_t *)&len, sizeof(len));
- - unix_write(s->fd, buf, size);
+ if (qemu_socket_is_dgram(s)) {
+ sendto(s->fd, buf, size, 0, (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
+ } else {
+ unix_write(s->fd, (const uint8_t *)&len, sizeof(len));
+ unix_write(s->fd, buf, size);
+ }
}
static void net_socket_send(void *opaque)
@@ -2164,6 +2174,11 @@
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
return;
}
+ if (qemu_socket_is_dgram(s)) {
+ s->index = 0;
+ s->state = 1;
+ s->packet_len = size;
+ }
buf = buf1;
while (size > 0) {
/* reassemble a packet from the network */
@@ -2336,6 +2351,72 @@
return 0;
}
+static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
+{
+ NetSocketState *s;
+ int fd, ret, val;
+ struct sockaddr_in saddr, bindaddr;
+ struct ip_mreq imr;
+
+ if (parse_host_port(&saddr, host_str) < 0)
+ return -1;
+
+ if (!IN_MULTICAST(ntohl(saddr.sin_addr.s_addr))) {
+ fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
+ inet_ntoa(saddr.sin_addr), ntohl(saddr.sin_addr.s_addr));
+ return -1;
+
+ }
+ fd = socket(PF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ perror("socket");
+ return -1;
+ }
+
+ imr.imr_multiaddr = saddr.sin_addr;
+ imr.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *) &imr, sizeof(struct ip_mreq));
+ if (ret < 0) {
+ perror("setsockopt(IP_ADD_MEMBERSHIP)");
+ return -1;
+ }
+
+ fcntl(fd, F_SETFL, O_NONBLOCK);
+
+ val = 1;
+ ret=setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &val, sizeof(val));
+ if (ret < 0) {
+ perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
+ return -1;
+ }
+ ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+ if (ret < 0) {
+ perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
+ return -1;
+ }
+
+ bindaddr = saddr;
+ bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ ret = bind(fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr));
+ if (ret < 0) {
+ perror("bind");
+ return -1;
+ }
+
+ s = net_socket_fd_init(vlan, fd, 1);
+ if (!s)
+ return -1;
+
+ s->dgram_dst = saddr;
+
+ snprintf(s->vc->info_str, sizeof(s->vc->info_str),
+ "socket: mcast at %s:%d",
+ inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
+ return 0;
+}
+
#endif /* !_WIN32 */
static int get_param_value(char *buf, int buf_size,
@@ -2472,6 +2553,8 @@
ret = net_socket_listen_init(vlan, buf);
} else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
ret = net_socket_connect_init(vlan, buf);
+ } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
+ ret = net_socket_mcast_init(vlan, buf);
} else {
fprintf(stderr, "Unknown socket options: %s\n", p);
return -1;
@@ -3810,6 +3893,8 @@
" use 'fd=h' to connect to an already opened TAP interface\n"
"-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
" connect the vlan 'n' to another VLAN using a socket connection\n"
+ "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
+ " create a vlan 'n' with another QEMUs on multicast maddr and port\n"
#endif
"-net none use it alone to have zero network devices; if no -net option\n"
" is provided, the default is '-net nic -net user'\n"
Index: qemu-doc.texi
===================================================================
RCS file: /cvsroot/qemu/qemu/qemu-doc.texi,v
retrieving revision 1.73
diff -u -r1.73 qemu-doc.texi
- --- qemu-doc.texi 19 Nov 2005 17:42:52 -0000 1.73
+++ qemu-doc.texi 7 Dec 2005 15:02:10 -0000
@@ -293,6 +293,22 @@
qemu linux.img -net nic,macaddr=52:54:00:12:34:57 -net socket,connect=127.0.0.1:1234
@end example
+@item -net socket[,vlan=n][,fd=h][,mcast=maddr:port]
+
+Create a VLAN @var{n} shared with another QEMU virtual
+machines using a UDP multicast socket, effectively making a bus for
+every QEMU with same multicast address @var{maddr} and @var{port}.
+
+Example:
+@example
+# launch one QEMU instance
+qemu linux.img -net nic,macaddr=52:54:00:12:34:56 -net socket,mcast=230.0.0.1:1234
+# launch another QEMU instance on same "bus"
+qemu linux.img -net nic,macaddr=52:54:00:12:34:57 -net socket,mcast=230.0.0.1:1234
+# launch yet another QEMU instance on same "bus"
+qemu linux.img -net nic,macaddr=52:54:00:12:34:58 -net socket,mcast=230.0.0.1:1234
+@end example
+
@item -net none
Indicate that no network devices should be configured. It is used to
override the default configuration which is activated if no
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.7 (GNU/Linux)
iD8DBQFDlvwwo/fiSWZycXcRAiJWAJ0e7CSd9UK3Zkz7BcCJxl34yYt6wwCgh4th
Mah0xd5tIzfjsrhFahAAVp4=
=0Ct2
-----END PGP SIGNATURE-----
reply other threads:[~2005-12-07 16:05 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1be1aa250512070805w24a17ecaqad491a2335ac3973@mail.gmail.com \
--to=juanjosec@gmail.com \
--cc=jjo@mendoza.gov.ar \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).