net: Allow setting network interface to use for multicast
Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/HOWTO b/HOWTO
index 3791e7d..38eafdd 100644
--- a/HOWTO
+++ b/HOWTO
@@ -1444,6 +1444,10 @@
[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.
diff --git a/engines/net.c b/engines/net.c
index b2c1283..4804a20 100644
--- a/engines/net.c
+++ b/engines/net.c
@@ -37,6 +37,7 @@
unsigned int listen;
unsigned int pingpong;
unsigned int nodelay;
+ char * interface;
};
struct udp_close_msg {
@@ -129,6 +130,15 @@
.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 @@
}
#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 @@
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 eba748b..ca8a5ca 100644
--- a/fio.1
+++ b/fio.1
@@ -1221,6 +1221,10 @@
.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