engines/net: add TCP_MAXSEG setting (mss)

Signed-off-by: Jens Axboe <axboe@fb.com>
diff --git a/engines/net.c b/engines/net.c
index ac5a93c..9a327da 100644
--- a/engines/net.c
+++ b/engines/net.c
@@ -40,6 +40,7 @@
 	unsigned int nodelay;
 	unsigned int ttl;
 	unsigned int window_size;
+	unsigned int mss;
 	char *intfc;
 };
 
@@ -178,6 +179,18 @@
 		.group	= FIO_OPT_G_NETIO,
 	},
 #endif
+#ifdef CONFIG_NET_MSS
+	{
+		.name	= "mss",
+		.lname	= "Maximum segment size",
+		.type	= FIO_OPT_INT,
+		.off1	= offsetof(struct netio_options, mss),
+		.minval	= 0,
+		.help	= "Set TCP maximum segment size",
+		.category = FIO_OPT_C_ENGINE,
+		.group	= FIO_OPT_G_NETIO,
+	},
+#endif
 	{
 		.name	= NULL,
 	},
@@ -233,6 +246,30 @@
 #endif
 }
 
+static int set_mss(struct thread_data *td, int fd)
+{
+#ifdef CONFIG_NET_MSS
+	struct netio_options *o = td->eo;
+	unsigned int mss;
+	int ret;
+
+	if (!o->mss || !is_tcp(o))
+		return 0;
+
+	mss = o->mss;
+	ret = setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, (void *) &mss,
+				sizeof(mss));
+	if (ret < 0)
+		td_verror(td, errno, "setsockopt TCP_MAXSEG");
+
+	return ret;
+#else
+	td_verror(td, -EINVAL, "setsockopt TCP_MAXSEG");
+	return -1;
+#endif
+}
+
+
 /*
  * Return -1 for error and 'nr events' for a positive number
  * of events
@@ -655,6 +692,10 @@
 		close(f->fd);
 		return 1;
 	}
+	if (set_mss(td, f->fd)) {
+		close(f->fd);
+		return 1;
+	}
 
 	if (is_udp(o)) {
 		if (!fio_netio_is_multicast(td->o.filename))
@@ -1101,6 +1142,10 @@
 		close(fd);
 		return 1;
 	}
+	if (set_mss(td, fd)) {
+		close(fd);
+		return 1;
+	}
 
 	if (td->o.filename) {
 		if (!is_udp(o) || !fio_netio_is_multicast(td->o.filename)) {