1

I am trying to create a simulated VLAN using socket networking, and the only way to connect multiple VMs in one network in QEMU using socket networking is by using the multicast mcast option of the socket network backend, to create a shared BUS.

However, when I try to use the following arguments in QEMU to create a multicast socket network:

-device e1000,netdev=sock-0 -netdev id=sock-0,mcast=230.0.0.1:1234

it fails with:

can't bind ip=230.0.0.1 to socket: Unknown error in my Windows host.

Is this is a QEMU bug, or am I missing a prerequisite before running the QEMU command (such as expecting a multicast listener running, ...etc.)?

By the way, I am using Windows 10, and running a cross-compiled QEMU 4.2.0. I printed the error right before the failure on bind in net/socket.c of the QEMU source code in line 256, and WSAGetLastError returns WSAEADDRNOTAVAIL.

falhumai96
  • 123
  • 6

1 Answers1

1

Apparently, QEMU 4.2.0 has a bug with socket networking using multicast. It does not use INADDR_ANY (or 0.0.0.0) for the listening socket, but rather the multicast group address passed-in by the user. To fix this issue, I changed the following source code lines in net/socket.c (from 256 to 261, inclusive):

   ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
    if (ret < 0) {
        error_setg_errno(errp, errno, "can't bind ip=%s to socket",
                         inet_ntoa(mcastaddr->sin_addr));
        goto fail;
    }

to

    struct in_addr group_addr = mcastaddr->sin_addr;
    if (localaddr) {
        mcastaddr->sin_addr = *localaddr;
    } else {
        mcastaddr->sin_addr.s_addr = htonl(INADDR_ANY);
    }
    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
    if (ret < 0) {
        error_setg_errno(errp, errno, "can't bind ip=%s to socket",
                         inet_ntoa(mcastaddr->sin_addr));
        goto fail;
    }
    mcastaddr->sin_addr = group_addr;

where I would preserve the group's address in a variable, set the socket address to either INADDR_ANY or a user-passed-in local address, create the listening socket, and then revert to the group's address so I can join the group later on. The solution works in Windows built binaries, but I believe it would work on other operating systems as well.

falhumai96
  • 123
  • 6