diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index afcdc658b5..1ab6bcbfc8 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -146,11 +146,21 @@ endif
 ifeq ($(subdir),socket)
 sysdep_headers += net/if_ppp.h net/ppp-comp.h \
 		  net/ppp_defs.h net/if_arp.h net/route.h net/ethernet.h \
-		  net/if_slip.h net/if_packet.h net/if_shaper.h
+		  net/if_slip.h net/if_packet.h net/if_shaper.h \
+		  bits/socket-constants.h
 sysdep_routines += cmsg_nxthdr
 CFLAGS-recvmmsg.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-sendmmsg.c = -fexceptions -fasynchronous-unwind-tables
-endif
+
+tests-special += $(objpfx)tst-socket-consts.out
+$(objpfx)tst-socket-consts.out: ../sysdeps/unix/sysv/linux/tst-socket-consts.py
+	PYTHONPATH=../scripts \
+	$(PYTHON) ../sysdeps/unix/sysv/linux/tst-socket-consts.py \
+		   --cc="$(CC) $(patsubst -DMODULE_NAME=%, \
+					  -DMODULE_NAME=testsuite, \
+					  $(CPPFLAGS)) -D_ISOMAC" \
+	< /dev/null > $@ 2>&1; $(evaluate-test)
+endif # $(subdir) == socket
 
 ifeq ($(subdir),sunrpc)
 sysdep_headers += nfs/nfs.h
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/socket-constants.h b/sysdeps/unix/sysv/linux/alpha/bits/socket-constants.h
new file mode 100644
index 0000000000..571196756e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/bits/socket-constants.h
@@ -0,0 +1,38 @@
+/* Socket constants which vary among Linux architectures.  Version for alpha.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket-constants.h> directly; use <sys/socket.h> instead."
+#endif
+
+#define SOL_SOCKET 65535
+#define SO_ACCEPTCONN 4116
+#define SO_BROADCAST 32
+#define SO_DONTROUTE 16
+#define SO_ERROR 4103
+#define SO_KEEPALIVE 8
+#define SO_LINGER 128
+#define SO_OOBINLINE 256
+#define SO_RCVBUF 4098
+#define SO_RCVLOWAT 4112
+#define SO_RCVTIMEO 4114
+#define SO_REUSEADDR 4
+#define SO_SNDBUF 4097
+#define SO_SNDLOWAT 4113
+#define SO_SNDTIMEO 4115
+#define SO_TYPE 4104
diff --git a/sysdeps/unix/sysv/linux/bits/socket-constants.h b/sysdeps/unix/sysv/linux/bits/socket-constants.h
new file mode 100644
index 0000000000..b231342102
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/socket-constants.h
@@ -0,0 +1,38 @@
+/* Socket constants which vary among Linux architectures.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket-constants.h> directly; use <sys/socket.h> instead."
+#endif
+
+#define SOL_SOCKET 1
+#define SO_ACCEPTCONN 30
+#define SO_BROADCAST 6
+#define SO_DONTROUTE 5
+#define SO_ERROR 4
+#define SO_KEEPALIVE 9
+#define SO_LINGER 13
+#define SO_OOBINLINE 10
+#define SO_RCVBUF 8
+#define SO_RCVLOWAT 18
+#define SO_RCVTIMEO 20
+#define SO_REUSEADDR 2
+#define SO_SNDBUF 7
+#define SO_SNDLOWAT 19
+#define SO_SNDTIMEO 21
+#define SO_TYPE 3
diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
index 99af01d2a4..082f8b9031 100644
--- a/sysdeps/unix/sysv/linux/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/bits/socket.h
@@ -349,98 +349,12 @@ struct ucred
 };
 #endif
 
-/* Ugly workaround for unclean kernel headers.  */
-#ifndef __USE_MISC
-# ifndef FIOGETOWN
-#  define __SYS_SOCKET_H_undef_FIOGETOWN
-# endif
-# ifndef FIOSETOWN
-#  define __SYS_SOCKET_H_undef_FIOSETOWN
-# endif
-# ifndef SIOCATMARK
-#  define __SYS_SOCKET_H_undef_SIOCATMARK
-# endif
-# ifndef SIOCGPGRP
-#  define __SYS_SOCKET_H_undef_SIOCGPGRP
-# endif
-# ifndef SIOCGSTAMP
-#  define __SYS_SOCKET_H_undef_SIOCGSTAMP
-# endif
-# ifndef SIOCGSTAMPNS
-#  define __SYS_SOCKET_H_undef_SIOCGSTAMPNS
-# endif
-# ifndef SIOCSPGRP
-#  define __SYS_SOCKET_H_undef_SIOCSPGRP
-# endif
-#endif
-#ifndef IOCSIZE_MASK
-# define __SYS_SOCKET_H_undef_IOCSIZE_MASK
-#endif
-#ifndef IOCSIZE_SHIFT
-# define __SYS_SOCKET_H_undef_IOCSIZE_SHIFT
-#endif
-#ifndef IOC_IN
-# define __SYS_SOCKET_H_undef_IOC_IN
-#endif
-#ifndef IOC_INOUT
-# define __SYS_SOCKET_H_undef_IOC_INOUT
-#endif
-#ifndef IOC_OUT
-# define __SYS_SOCKET_H_undef_IOC_OUT
-#endif
-
-/* Get socket manipulation related informations from kernel headers.  */
-#include <asm/socket.h>
-
-#ifndef __USE_MISC
-# ifdef __SYS_SOCKET_H_undef_FIOGETOWN
-#  undef __SYS_SOCKET_H_undef_FIOGETOWN
-#  undef FIOGETOWN
-# endif
-# ifdef __SYS_SOCKET_H_undef_FIOSETOWN
-#  undef __SYS_SOCKET_H_undef_FIOSETOWN
-#  undef FIOSETOWN
-# endif
-# ifdef __SYS_SOCKET_H_undef_SIOCATMARK
-#  undef __SYS_SOCKET_H_undef_SIOCATMARK
-#  undef SIOCATMARK
-# endif
-# ifdef __SYS_SOCKET_H_undef_SIOCGPGRP
-#  undef __SYS_SOCKET_H_undef_SIOCGPGRP
-#  undef SIOCGPGRP
-# endif
-# ifdef __SYS_SOCKET_H_undef_SIOCGSTAMP
-#  undef __SYS_SOCKET_H_undef_SIOCGSTAMP
-#  undef SIOCGSTAMP
-# endif
-# ifdef __SYS_SOCKET_H_undef_SIOCGSTAMPNS
-#  undef __SYS_SOCKET_H_undef_SIOCGSTAMPNS
-#  undef SIOCGSTAMPNS
-# endif
-# ifdef __SYS_SOCKET_H_undef_SIOCSPGRP
-#  undef __SYS_SOCKET_H_undef_SIOCSPGRP
-#  undef SIOCSPGRP
-# endif
-#endif
-#ifdef __SYS_SOCKET_H_undef_IOCSIZE_MASK
-# undef __SYS_SOCKET_H_undef_IOCSIZE_MASK
-# undef IOCSIZE_MASK
-#endif
-#ifdef __SYS_SOCKET_H_undef_IOCSIZE_SHIFT
-# undef __SYS_SOCKET_H_undef_IOCSIZE_SHIFT
-# undef IOCSIZE_SHIFT
-#endif
-#ifdef __SYS_SOCKET_H_undef_IOC_IN
-# undef __SYS_SOCKET_H_undef_IOC_IN
-# undef IOC_IN
-#endif
-#ifdef __SYS_SOCKET_H_undef_IOC_INOUT
-# undef __SYS_SOCKET_H_undef_IOC_INOUT
-# undef IOC_INOUT
-#endif
-#ifdef __SYS_SOCKET_H_undef_IOC_OUT
-# undef __SYS_SOCKET_H_undef_IOC_OUT
-# undef IOC_OUT
+#ifdef __USE_MISC
+# include <bits/types/time_t.h>
+# include <asm/socket.h>
+#else
+# define SO_DEBUG 1
+# include <bits/socket-constants.h>
 #endif
 
 /* Structure used to manipulate the SO_LINGER option.  */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h b/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h
new file mode 100644
index 0000000000..0b652b81be
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h
@@ -0,0 +1,38 @@
+/* Socket constants which vary among Linux architectures.  Version for hppa.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket-constants.h> directly; use <sys/socket.h> instead."
+#endif
+
+#define SOL_SOCKET 65535
+#define SO_ACCEPTCONN 16412
+#define SO_BROADCAST 32
+#define SO_DONTROUTE 16
+#define SO_ERROR 4103
+#define SO_KEEPALIVE 8
+#define SO_LINGER 128
+#define SO_OOBINLINE 256
+#define SO_RCVBUF 4098
+#define SO_RCVLOWAT 4100
+#define SO_RCVTIMEO 4102
+#define SO_REUSEADDR 4
+#define SO_SNDBUF 4097
+#define SO_SNDLOWAT 4099
+#define SO_SNDTIMEO 4101
+#define SO_TYPE 4104
diff --git a/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h b/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h
new file mode 100644
index 0000000000..2c504499cb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h
@@ -0,0 +1,38 @@
+/* Socket constants which vary among Linux architectures.  Version for MIPS.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket-constants.h> directly; use <sys/socket.h> instead."
+#endif
+
+#define SOL_SOCKET 65535
+#define SO_ACCEPTCONN 4105
+#define SO_BROADCAST 32
+#define SO_DONTROUTE 16
+#define SO_ERROR 4103
+#define SO_KEEPALIVE 8
+#define SO_LINGER 128
+#define SO_OOBINLINE 256
+#define SO_RCVBUF 4098
+#define SO_RCVLOWAT 4100
+#define SO_RCVTIMEO 4102
+#define SO_REUSEADDR 4
+#define SO_SNDBUF 4097
+#define SO_SNDLOWAT 4099
+#define SO_SNDTIMEO 4101
+#define SO_TYPE 4104
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h b/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h
new file mode 100644
index 0000000000..6d4301b1fd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h
@@ -0,0 +1,38 @@
+/* Socket constants which vary among Linux architectures.  Version for POWER.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket-constants.h> directly; use <sys/socket.h> instead."
+#endif
+
+#define SOL_SOCKET 1
+#define SO_ACCEPTCONN 30
+#define SO_BROADCAST 6
+#define SO_DONTROUTE 5
+#define SO_ERROR 4
+#define SO_KEEPALIVE 9
+#define SO_LINGER 13
+#define SO_OOBINLINE 10
+#define SO_RCVBUF 8
+#define SO_RCVLOWAT 16
+#define SO_RCVTIMEO 18
+#define SO_REUSEADDR 2
+#define SO_SNDBUF 7
+#define SO_SNDLOWAT 17
+#define SO_SNDTIMEO 19
+#define SO_TYPE 3
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h b/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h
new file mode 100644
index 0000000000..a663e11210
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h
@@ -0,0 +1,38 @@
+/* Socket constants which vary among Linux architectures.  Version for SPARC.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket-constants.h> directly; use <sys/socket.h> instead."
+#endif
+
+#define SOL_SOCKET 65535
+#define SO_ACCEPTCONN 32768
+#define SO_BROADCAST 32
+#define SO_DONTROUTE 16
+#define SO_ERROR 4103
+#define SO_KEEPALIVE 8
+#define SO_LINGER 128
+#define SO_OOBINLINE 256
+#define SO_RCVBUF 4098
+#define SO_RCVLOWAT 2048
+#define SO_RCVTIMEO 8192
+#define SO_REUSEADDR 4
+#define SO_SNDBUF 4097
+#define SO_SNDLOWAT 4096
+#define SO_SNDTIMEO 16384
+#define SO_TYPE 4104
diff --git a/sysdeps/unix/sysv/linux/tst-socket-consts.py b/sysdeps/unix/sysv/linux/tst-socket-consts.py
new file mode 100644
index 0000000000..ca2634110c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-socket-consts.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python3
+# Test that glibc's sys/socket.h SO_* constants match the kernel's.
+# Copyright (C) 2018-2019 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+import argparse
+import sys
+
+import glibcextract
+
+def main():
+    """The main entry point."""
+    parser = argparse.ArgumentParser(
+        description="Test that glibc's sys/socket.h constants "
+        "match the kernel's.")
+    parser.add_argument('--cc', metavar='CC',
+                        help='C compiler (including options) to use')
+    args = parser.parse_args()
+
+    def check(define):
+        return glibcextract.compare_macro_consts(
+            source_1=define + '#include <sys/socket.h>\n',
+            # Some constants in <asm/socket.h> may depend on the size
+            # of pid_t or time_t.
+            source_2='#include <sys/types.h>\n'
+            '#include <asm/socket.h>\n',
+            cc=args.cc,
+            # We cannot compare all macros because some macros cannot
+            # be expanded as constants, and glibcextract currently is
+            # not able to isolate errors.
+            macro_re='SOL?_.*',
+            # <sys/socket.h> and <asm/socket.h> are not a good match.
+            # Most socket-related constants are not defined in any
+            # UAPI header.  Check only the intersection of the macros
+            # in both headers.  Regular tests ensure that expected
+            # macros for _GNU_SOURCE are present, and the conformance
+            # tests cover most of the other modes.
+            allow_extra_1=True,
+            allow_extra_2=True)
+    # _GNU_SOURCE is defined by include/libc-symbols.h, which is
+    # included by the --cc command.  Defining _ISOMAC does not prevent
+    # that.
+    status = max(
+        check(''),
+        check('#undef _GNU_SOURCE\n'),
+        check('#undef _GNU_SOURCE\n'
+              '#define _POSIX_SOURCE 1\n'))
+    sys.exit(status)
+
+if __name__ == '__main__':
+    main()
