net: Add option to set outgoing multicast TTL

Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/engines/net.c b/engines/net.c
index 4804a20..0c90e1c 100644
--- a/engines/net.c
+++ b/engines/net.c
@@ -37,6 +37,7 @@
 	unsigned int listen;
 	unsigned int pingpong;
 	unsigned int nodelay;
+	unsigned int ttl;
 	char * interface;
 };
 
@@ -139,6 +140,17 @@
 		.group	= FIO_OPT_G_NETIO,
 	},
 	{
+		.name	= "ttl",
+		.lname	= "net engine multicast ttl",
+		.type	= FIO_OPT_INT,
+		.off1	= offsetof(struct netio_options, ttl),
+		.def    = "1",
+		.minval	= 0,
+		.help	= "Time-to-live value for outgoing UDP multicast packets",
+		.category = FIO_OPT_C_ENGINE,
+		.group	= FIO_OPT_G_NETIO,
+	},
+	{
 		.name	= NULL,
 	},
 };
@@ -542,7 +554,10 @@
 #endif
 
 	if (o->proto == FIO_TYPE_UDP) {
-		if (o->interface && fio_netio_is_multicast(td->o.filename)) {
+		if (!fio_netio_is_multicast(td->o.filename))
+			return 0;
+
+		if (o->interface) {
 			struct in_addr interface_addr;
 			if (inet_aton(o->interface, &interface_addr) == 0) {
 				log_err("fio: interface not valid interface IP\n");
@@ -555,6 +570,11 @@
 				return 1;
 			}
 		}
+		if (setsockopt(f->fd, IPPROTO_IP, IP_MULTICAST_TTL, &o->ttl, sizeof(o->ttl)) < 0) {
+			td_verror(td, errno, "setsockopt IP_MULTICAST_TTL");
+			close(f->fd);
+			return 1;
+		}
 		return 0;
 	} else if (o->proto == FIO_TYPE_TCP) {
 		socklen_t len = sizeof(nd->addr);