net: Allow setting network interface to use for multicast
authorShawn Bohrer <sbohrer@rgmadvisors.com>
Fri, 19 Jul 2013 18:24:07 +0000 (13:24 -0500)
committerJens Axboe <axboe@kernel.dk>
Mon, 22 Jul 2013 15:04:36 +0000 (09:04 -0600)
Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
HOWTO
engines/net.c
fio.1

diff --git a/HOWTO b/HOWTO
index 3791e7d52af3da59b9ca7bcad47eb56e33c94fe0..38eafdd3b49e7e5c9e4aa8672a59d5592b76b76e 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -1444,6 +1444,10 @@ that defines them is selected.
 [netsplice] port=int
 [net] port=int The TCP or UDP port to bind to or connect to.
 
+[netsplice] interface=str
+[net] interface=str  The IP address of the network interface used to send or
+               receive UDP multicast
+
 [netsplice] nodelay=bool
 [net] nodelay=bool     Set TCP_NODELAY on TCP connections.
 
index b2c1283454090ed42554908c6642dd130e37cc59..4804a206bad73cbd549f2c6e0fbf03daeb342448 100644 (file)
@@ -37,6 +37,7 @@ struct netio_options {
        unsigned int listen;
        unsigned int pingpong;
        unsigned int nodelay;
+       char * interface;
 };
 
 struct udp_close_msg {
@@ -128,6 +129,15 @@ static struct fio_option options[] = {
                .category = FIO_OPT_C_ENGINE,
                .group  = FIO_OPT_G_NETIO,
        },
+       {
+               .name   = "interface",
+               .lname  = "net engine interface",
+               .type   = FIO_OPT_STR_STORE,
+               .off1   = offsetof(struct netio_options, interface),
+               .help   = "Network interface to use",
+               .category = FIO_OPT_C_ENGINE,
+               .group  = FIO_OPT_G_NETIO,
+       },
        {
                .name   = NULL,
        },
@@ -531,9 +541,22 @@ static int fio_netio_connect(struct thread_data *td, struct fio_file *f)
        }
 #endif
 
-       if (o->proto == FIO_TYPE_UDP)
+       if (o->proto == FIO_TYPE_UDP) {
+               if (o->interface && fio_netio_is_multicast(td->o.filename)) {
+                       struct in_addr interface_addr;
+                       if (inet_aton(o->interface, &interface_addr) == 0) {
+                               log_err("fio: interface not valid interface IP\n");
+                               close(f->fd);
+                               return 1;
+                       }
+                       if (setsockopt(f->fd, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr)) < 0) {
+                               td_verror(td, errno, "setsockopt IP_MULTICAST_IF");
+                               close(f->fd);
+                               return 1;
+                       }
+               }
                return 0;
-       else if (o->proto == FIO_TYPE_TCP) {
+       else if (o->proto == FIO_TYPE_TCP) {
                socklen_t len = sizeof(nd->addr);
 
                if (connect(f->fd, (struct sockaddr *) &nd->addr, len) < 0) {
@@ -841,7 +864,15 @@ static int fio_netio_setup_listen_inet(struct thread_data *td, short port)
                inet_aton(td->o.filename, &sin.sin_addr);
 
                mr.imr_multiaddr = sin.sin_addr;
-               mr.imr_interface.s_addr = htonl(INADDR_ANY);
+               if (o->interface) {
+                       if (inet_aton(o->interface, &mr.imr_interface) == 0) {
+                               log_err("fio: interface not valid interface IP\n");
+                               close(fd);
+                               return 1;
+                       }
+               } else {
+                       mr.imr_interface.s_addr = htonl(INADDR_ANY);
+               }
                if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0) {
                        td_verror(td, errno, "setsockopt IP_ADD_MEMBERSHIP");
                        close(fd);
diff --git a/fio.1 b/fio.1
index eba748b9c4d0a79762a4b036ab4fc56f8951ea98..ca8a5ca53509332f0728de2bf563538b200a64c8 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -1221,6 +1221,10 @@ used and must be omitted unless it is a valid UDP multicast address.
 .BI (net,netsplice)port \fR=\fPint
 The TCP or UDP port to bind to or connect to.
 .TP
+.BI (net,netsplice)interface \fR=\fPstr
+The IP address of the network interface used to send or receive UDP multicast
+packets.
+.TP
 .BI (net,netsplice)nodelay \fR=\fPbool
 Set TCP_NODELAY on TCP connections.
 .TP