This patch makes TCP send out any packet fragments when TCP_NOPUSH
is turned off, in the manner of Linux's TCP_CORK.

--- /usr/src/sys/netinet/tcp_usrreq.c	2000/01/09 19:17:28	1.51
+++ /usr/src/sys/netinet/tcp_usrreq.c	2001/02/02 01:36:30
@@ -919,8 +919,11 @@
 
 			if (optval)
 				tp->t_flags |= opt;
-			else
+			else {
 				tp->t_flags &= ~opt;
+				if (opt == TF_NOPUSH)
+					error = tcp_output(tp);
+			}
 			break;
 
 		case TCP_MAXSEG:
--- /usr/src/share/man/man4/tcp.4	2001/01/16 10:41:21	1.11.2.2
+++ /usr/src/share/man/man4/tcp.4	2001/02/05 23:01:45
@@ -163,6 +163,8 @@
 .Tn TCP
 will delay sending any data at all until either the socket is closed,
 or the internal send buffer is filled.
+When the option is reset to zero, any buffered data is immediately
+pushed out.
 .El
 .Pp
 The option level for the
--- /usr/src/sys/i386/linux/linux.h	2000/05/09 17:41:24	1.41.2.1
+++ /usr/src/sys/i386/linux/linux.h	2001/02/05 23:35:24
@@ -375,6 +375,10 @@
 #define	LINUX_IP_ADD_MEMBERSHIP		35
 #define	LINUX_IP_DROP_MEMBERSHIP	36
 
+#define LINUX_TCP_NODELAY	1
+#define LINUX_TCP_MAXSEG	2
+#define LINUX_TCP_CORK		3
+
 struct linux_sockaddr {
 	u_short	sa_family;
 	char	sa_data[14];
--- /usr/src/sys/alpha/linux/linux.h	2000/11/22 15:22:43	1.46.2.2
+++ /usr/src/sys/alpha/linux/linux.h	2001/02/05 23:35:51
@@ -377,6 +377,10 @@
 #define	LINUX_IP_ADD_MEMBERSHIP		35
 #define	LINUX_IP_DROP_MEMBERSHIP	36
 
+#define LINUX_TCP_NODELAY	1
+#define LINUX_TCP_MAXSEG	2
+#define LINUX_TCP_CORK		3
+
 struct linux_sockaddr {
 	u_short	sa_family;
 	char	sa_data[14];
--- /usr/src/sys/compat/linux/linux_socket.c	2000/11/22 15:39:01	1.19.2.3
+++ /usr/src/sys/compat/linux/linux_socket.c	2001/02/05 23:36:07
@@ -46,6 +46,7 @@
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#include <netinet/tcp.h>
 
 #include <machine/../linux/linux.h>
 #ifdef __alpha__
@@ -89,6 +90,21 @@
 }
 
 static int
+linux_to_bsd_tcp_sockopt(int opt)
+{
+
+	switch (opt) {
+	case LINUX_TCP_NODELAY:
+		return (TCP_NODELAY);
+	case LINUX_TCP_MAXSEG:
+		return (TCP_MAXSEG);
+	case LINUX_TCP_CORK:
+		return (TCP_NOPUSH);
+	}
+	return (-1);
+}
+
+static int
 linux_to_bsd_ip_sockopt(int opt)
 {
 
@@ -768,8 +784,7 @@
 		name = linux_to_bsd_ip_sockopt(linux_args.optname);
 		break;
 	case IPPROTO_TCP:
-		/* Linux TCP option values match BSD's */
-		name = linux_args.optname;
+		name = linux_to_bsd_tcp_sockopt(linux_args.optname);
 		break;
 	default:
 		name = -1;
