Revision 3a75e74c net/socket.c

b/net/socket.c
149 149
    qemu_send_packet(&s->nc, s->buf, size);
150 150
}
151 151

  
152
static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
152
static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr *localaddr)
153 153
{
154 154
    struct ip_mreq imr;
155 155
    int fd;
......
183 183

  
184 184
    /* Add host to multicast group */
185 185
    imr.imr_multiaddr = mcastaddr->sin_addr;
186
    imr.imr_interface.s_addr = htonl(INADDR_ANY);
186
    if (localaddr) {
187
        imr.imr_interface = *localaddr;
188
    } else {
189
        imr.imr_interface.s_addr = htonl(INADDR_ANY);
190
    }
187 191

  
188 192
    ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
189 193
                     (const char *)&imr, sizeof(struct ip_mreq));
......
201 205
	goto fail;
202 206
    }
203 207

  
208
    /* If a bind address is given, only send packets from that address */
209
    if (localaddr != NULL) {
210
        ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, localaddr, sizeof(*localaddr));
211
        if (ret < 0) {
212
            perror("setsockopt(IP_MULTICAST_IF)");
213
            goto fail;
214
        }
215
    }
216

  
204 217
    socket_set_nonblock(fd);
205 218
    return fd;
206 219
fail:
......
248 261
		return NULL;
249 262
	    }
250 263
	    /* clone dgram socket */
251
	    newfd = net_socket_mcast_create(&saddr);
264
	    newfd = net_socket_mcast_create(&saddr, NULL);
252 265
	    if (newfd < 0) {
253 266
		/* error already reported by net_socket_mcast_create() */
254 267
		close(fd);
......
468 481
static int net_socket_mcast_init(VLANState *vlan,
469 482
                                 const char *model,
470 483
                                 const char *name,
471
                                 const char *host_str)
484
                                 const char *host_str,
485
                                 const char *localaddr_str)
472 486
{
473 487
    NetSocketState *s;
474 488
    int fd;
475 489
    struct sockaddr_in saddr;
490
    struct in_addr localaddr, *param_localaddr;
476 491

  
477 492
    if (parse_host_port(&saddr, host_str) < 0)
478 493
        return -1;
479 494

  
495
    if (localaddr_str != NULL) {
496
        if (inet_aton(localaddr_str, &localaddr) == 0)
497
            return -1;
498
        param_localaddr = &localaddr;
499
    } else {
500
        param_localaddr = NULL;
501
    }
480 502

  
481
    fd = net_socket_mcast_create(&saddr);
503
    fd = net_socket_mcast_create(&saddr, param_localaddr);
482 504
    if (fd < 0)
483 505
	return -1;
484 506

  
......
505 527

  
506 528
        if (qemu_opt_get(opts, "listen") ||
507 529
            qemu_opt_get(opts, "connect") ||
508
            qemu_opt_get(opts, "mcast")) {
509
            error_report("listen=, connect= and mcast= is invalid with fd=");
530
            qemu_opt_get(opts, "mcast") ||
531
            qemu_opt_get(opts, "localaddr")) {
532
            error_report("listen=, connect=, mcast= and localaddr= is invalid with fd=\n");
510 533
            return -1;
511 534
        }
512 535

  
......
524 547

  
525 548
        if (qemu_opt_get(opts, "fd") ||
526 549
            qemu_opt_get(opts, "connect") ||
527
            qemu_opt_get(opts, "mcast")) {
528
            error_report("fd=, connect= and mcast= is invalid with listen=");
550
            qemu_opt_get(opts, "mcast") ||
551
            qemu_opt_get(opts, "localaddr")) {
552
            error_report("fd=, connect=, mcast= and localaddr= is invalid with listen=\n");
529 553
            return -1;
530 554
        }
531 555

  
......
539 563

  
540 564
        if (qemu_opt_get(opts, "fd") ||
541 565
            qemu_opt_get(opts, "listen") ||
542
            qemu_opt_get(opts, "mcast")) {
543
            error_report("fd=, listen= and mcast= is invalid with connect=");
566
            qemu_opt_get(opts, "mcast") ||
567
            qemu_opt_get(opts, "localaddr")) {
568
            error_report("fd=, listen=, mcast= and localaddr= is invalid with connect=\n");
544 569
            return -1;
545 570
        }
546 571

  
......
550 575
            return -1;
551 576
        }
552 577
    } else if (qemu_opt_get(opts, "mcast")) {
553
        const char *mcast;
578
        const char *mcast, *localaddr;
554 579

  
555 580
        if (qemu_opt_get(opts, "fd") ||
556 581
            qemu_opt_get(opts, "connect") ||
......
560 585
        }
561 586

  
562 587
        mcast = qemu_opt_get(opts, "mcast");
588
        localaddr = qemu_opt_get(opts, "localaddr");
563 589

  
564
        if (net_socket_mcast_init(vlan, "socket", name, mcast) == -1) {
590
        if (net_socket_mcast_init(vlan, "socket", name, mcast, localaddr) == -1) {
565 591
            return -1;
566 592
        }
567 593
    } else {

Also available in: Unified diff