The current setsockopt() wrapper for the Linux ABI claims that Linux and 
FreeBSD use the same values for TCP socket options.  This is true for 
TCP_NODELAY and TCP_MAXSEG but not for any other options.  This patch adds a 
mapping routine for TCP options similar to that used for other socket option 
levels.  I believe this mapping to be correct in terms of which FreeBSD 
options have the same semantics as Linux options based on comparing code in 
the two kernels, but I'm not 100% certain about TCP_MD5SIG since the Linux 
code that it maps to is not as clear (it calls some function pointer and it is 
not clear if it is accepting a simple boolean value similar to FreeBSD's).

Also, almost all of the socket stuff in the linux.h headers appears to be 
identical and at least some of it are in MI headers in Linux (such as the TCP 
options).  It seems to me that a lot of that should move into linux_socket.h 
instead.

Index: amd64/linux32/linux.h
===================================================================
--- amd64/linux32/linux.h       (revision 245225)
+++ amd64/linux32/linux.h       (working copy)
@@ -725,6 +725,13 @@
 #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_KEEPIDLE      4
+#define        LINUX_TCP_KEEPINTVL     5
+#define        LINUX_TCP_KEEPCNT       6
+#define        LINUX_TCP_MD5SIG        14
+
 struct l_sockaddr {
        l_ushort        sa_family;
        char            sa_data[14];
Index: compat/linux/linux_socket.c
===================================================================
--- compat/linux/linux_socket.c (revision 245225)
+++ compat/linux/linux_socket.c (working copy)
@@ -56,6 +56,7 @@
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#include <netinet/tcp.h>
 #ifdef INET6
 #include <netinet/ip6.h>
 #include <netinet6/ip6_var.h>
@@ -326,6 +327,27 @@
 }
 
 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_KEEPIDLE:
+               return (TCP_KEEPIDLE);
+       case LINUX_TCP_KEEPINTVL:
+               return (TCP_KEEPINTVL);
+       case LINUX_TCP_KEEPCNT:
+               return (TCP_KEEPCNT);
+       case LINUX_TCP_MD5SIG:
+               return (TCP_MD5SIG);
+       }
+       return (-1);
+}
+
+static int
 linux_to_bsd_msg_flags(int flags)
 {
        int ret_flags = 0;
@@ -1496,8 +1518,7 @@
                name = linux_to_bsd_ip_sockopt(args->optname);
                break;
        case IPPROTO_TCP:
-               /* Linux TCP option values match BSD's */
-               name = args->optname;
+               name = linux_to_bsd_tcp_sockopt(args->optname);
                break;
        default:
                name = -1;
Index: i386/linux/linux.h
===================================================================
--- i386/linux/linux.h  (revision 245225)
+++ i386/linux/linux.h  (working copy)
@@ -701,6 +701,13 @@
 #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_KEEPIDLE      4
+#define        LINUX_TCP_KEEPINTVL     5
+#define        LINUX_TCP_KEEPCNT       6
+#define        LINUX_TCP_MD5SIG        14
+
 struct l_sockaddr {
        l_ushort        sa_family;
        char            sa_data[14];


-- 
John Baldwin
_______________________________________________
freebsd-emulation@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-emulation
To unsubscribe, send any mail to "freebsd-emulation-unsubscr...@freebsd.org"

Reply via email to