From: Mike Ryan <mikeryan@isi.edu>
To: qemu-devel@nongnu.org
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Subject: Re: [Qemu-devel] [PATCH] add a command line option to specify the IP address to send multicast packets from
Date: Mon, 22 Nov 2010 10:48:45 -0800 [thread overview]
Message-ID: <20101122184845.GC10730@zzz.isi.edu> (raw)
In-Reply-To: <20101118011626.GA2304@zzz.isi.edu>
Michael, this patch implements the feature with a bind address instead
of a bind interface. It should address the cross-platform issues that
were raised.
Others: any comments?
On Wed, Nov 17, 2010 at 05:16:26PM -0800, Mike Ryan wrote:
> Add an option to specify the host IP to send multicast packets from when
> using a multicast socket for networking. The option takes an IP address
> and sets the IP_MULTICAST_IF socket option, which causes the packets to
> use that IP's interface as an egress.
>
> This is useful if the host machine has several interfaces with several
> virtual networks across disparate interfaces.
> ---
> net.c | 4 ++++
> net/socket.c | 46 ++++++++++++++++++++++++++++++++++------------
> qemu-options.hx | 11 +++++++++--
> 3 files changed, 47 insertions(+), 14 deletions(-)
>
> diff --git a/net.c b/net.c
> index c5e6063..9ba5be2 100644
> --- a/net.c
> +++ b/net.c
> @@ -1050,6 +1050,10 @@ static const struct {
> .name = "mcast",
> .type = QEMU_OPT_STRING,
> .help = "UDP multicast address and port number",
> + }, {
> + .name = "localaddr",
> + .type = QEMU_OPT_STRING,
> + .help = "source address for multicast packets",
> },
> { /* end of list */ }
> },
> diff --git a/net/socket.c b/net/socket.c
> index 1c4e153..d443f4c 100644
> --- a/net/socket.c
> +++ b/net/socket.c
> @@ -149,7 +149,7 @@ static void net_socket_send_dgram(void *opaque)
> qemu_send_packet(&s->nc, s->buf, size);
> }
>
> -static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
> +static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr *localaddr)
> {
> struct ip_mreq imr;
> int fd;
> @@ -201,6 +201,15 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
> goto fail;
> }
>
> + /* If a bind address is given, only send packets from that address */
> + if (localaddr != NULL) {
> + ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, localaddr, sizeof(*localaddr));
> + if (ret < 0) {
> + perror("setsockopt(IP_MULTICAST_IF)");
> + goto fail;
> + }
> + }
> +
> socket_set_nonblock(fd);
> return fd;
> fail:
> @@ -248,7 +257,7 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
> return NULL;
> }
> /* clone dgram socket */
> - newfd = net_socket_mcast_create(&saddr);
> + newfd = net_socket_mcast_create(&saddr, NULL);
> if (newfd < 0) {
> /* error already reported by net_socket_mcast_create() */
> close(fd);
> @@ -468,17 +477,26 @@ static int net_socket_connect_init(VLANState *vlan,
> static int net_socket_mcast_init(VLANState *vlan,
> const char *model,
> const char *name,
> - const char *host_str)
> + const char *host_str,
> + const char *localaddr_str)
> {
> NetSocketState *s;
> int fd;
> struct sockaddr_in saddr;
> + struct in_addr localaddr, *param_localaddr;
>
> if (parse_host_port(&saddr, host_str) < 0)
> return -1;
>
> + if (localaddr_str != NULL) {
> + if (inet_aton(localaddr_str, &localaddr) == 0)
> + return -1;
> + param_localaddr = &localaddr;
> + } else {
> + param_localaddr = NULL;
> + }
>
> - fd = net_socket_mcast_create(&saddr);
> + fd = net_socket_mcast_create(&saddr, param_localaddr);
> if (fd < 0)
> return -1;
>
> @@ -505,8 +523,9 @@ int net_init_socket(QemuOpts *opts,
>
> if (qemu_opt_get(opts, "listen") ||
> qemu_opt_get(opts, "connect") ||
> - qemu_opt_get(opts, "mcast")) {
> - error_report("listen=, connect= and mcast= is invalid with fd=");
> + qemu_opt_get(opts, "mcast") ||
> + qemu_opt_get(opts, "localaddr")) {
> + error_report("listen=, connect=, mcast= and localaddr= is invalid with fd=\n");
> return -1;
> }
>
> @@ -524,8 +543,9 @@ int net_init_socket(QemuOpts *opts,
>
> if (qemu_opt_get(opts, "fd") ||
> qemu_opt_get(opts, "connect") ||
> - qemu_opt_get(opts, "mcast")) {
> - error_report("fd=, connect= and mcast= is invalid with listen=");
> + qemu_opt_get(opts, "mcast") ||
> + qemu_opt_get(opts, "localaddr")) {
> + error_report("fd=, connect=, mcast= and localaddr= is invalid with listen=\n");
> return -1;
> }
>
> @@ -539,8 +559,9 @@ int net_init_socket(QemuOpts *opts,
>
> if (qemu_opt_get(opts, "fd") ||
> qemu_opt_get(opts, "listen") ||
> - qemu_opt_get(opts, "mcast")) {
> - error_report("fd=, listen= and mcast= is invalid with connect=");
> + qemu_opt_get(opts, "mcast") ||
> + qemu_opt_get(opts, "localaddr")) {
> + error_report("fd=, listen=, mcast= and localaddr= is invalid with connect=\n");
> return -1;
> }
>
> @@ -550,7 +571,7 @@ int net_init_socket(QemuOpts *opts,
> return -1;
> }
> } else if (qemu_opt_get(opts, "mcast")) {
> - const char *mcast;
> + const char *mcast, *localaddr;
>
> if (qemu_opt_get(opts, "fd") ||
> qemu_opt_get(opts, "connect") ||
> @@ -560,8 +581,9 @@ int net_init_socket(QemuOpts *opts,
> }
>
> mcast = qemu_opt_get(opts, "mcast");
> + localaddr = qemu_opt_get(opts, "localaddr");
>
> - if (net_socket_mcast_init(vlan, "socket", name, mcast) == -1) {
> + if (net_socket_mcast_init(vlan, "socket", name, mcast, localaddr) == -1) {
> return -1;
> }
> } else {
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 4d99a58..accd16a 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1061,8 +1061,9 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
> #endif
> "-net socket[,vlan=n][,name=str][,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][,name=str][,fd=h][,mcast=maddr:port]\n"
> + "-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"
> #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"
> @@ -1256,7 +1257,7 @@ 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=@var{n}][,name=@var{name}][,fd=@var{h}] [,mcast=@var{maddr}:@var{port}]
> +@item -net socket[,vlan=@var{n}][,name=@var{name}][,fd=@var{h}][,mcast=@var{maddr}:@var{port}[,localaddr=@var{addr}]]
>
> Create a VLAN @var{n} shared with another QEMU virtual
> machines using a UDP multicast socket, effectively making a bus for
> @@ -1296,6 +1297,12 @@ qemu linux.img -net nic,macaddr=52:54:00:12:34:56 \
> /path/to/linux ubd0=/path/to/root_fs eth0=mcast
> @end example
>
> +Example (send packets from host's 1.2.3.4):
> +@example
> +qemu linux.img -net nic,macaddr=52:54:00:12:34:56 \
> + -net socket,mcast=239.192.168.1:1102,localaddr=1.2.3.4
> +@end example
> +
> @item -net vde[,vlan=@var{n}][,name=@var{name}][,sock=@var{socketpath}] [,port=@var{n}][,group=@var{groupname}][,mode=@var{octalmode}]
> Connect VLAN @var{n} to PORT @var{n} of a vde switch running on host and
> listening for incoming connections on @var{socketpath}. Use GROUP @var{groupname}
> --
> 1.7.0.4
>
next prev parent reply other threads:[~2010-11-22 18:49 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-11 1:47 [Qemu-devel] [PATCH] add a command line option to specify the interface to send multicast packets on Mike Ryan
2010-11-15 18:54 ` Mike Ryan
2010-11-15 19:36 ` Anthony Liguori
2010-11-15 19:52 ` Mike Ryan
2010-11-15 21:07 ` Anthony Liguori
2010-11-15 21:22 ` Stefan Weil
2010-11-15 21:34 ` Mike Ryan
2010-11-16 9:26 ` [Qemu-devel] " Paolo Bonzini
2010-11-16 17:54 ` Michael S. Tsirkin
2010-11-16 19:10 ` Mike Ryan
2010-11-18 1:16 ` [Qemu-devel] [PATCH] add a command line option to specify the IP address to send multicast packets from Mike Ryan
2010-11-22 18:48 ` Mike Ryan [this message]
2010-11-23 13:05 ` Michael S. Tsirkin
2010-11-23 23:49 ` Mike Ryan
2010-11-24 5:32 ` [Qemu-devel] " Michael S. Tsirkin
2010-11-29 19:12 ` [Qemu-devel] " Mike Ryan
2010-12-01 19:16 ` Mike Ryan
2010-12-02 19:19 ` [Qemu-devel] " Michael S. Tsirkin
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=20101122184845.GC10730@zzz.isi.edu \
--to=mikeryan@isi.edu \
--cc=mst@redhat.com \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.