diff options
author | Kevin Vigor <kvigor@fb.com> | 2017-04-28 16:44:29 -0700 |
---|---|---|
committer | Amar Tumballi <amarts@redhat.com> | 2017-10-24 09:28:08 +0000 |
commit | 1260ee53b1674234e6f083563bdcd258e46a6faa (patch) | |
tree | a1e31987357722438f603622a43151839c83a13e | |
parent | 738c38f0efa7b4d4dab0cf23d00589d68e4eb88d (diff) | |
download | glusterfs-1260ee53b1674234e6f083563bdcd258e46a6faa.tar.gz glusterfs-1260ee53b1674234e6f083563bdcd258e46a6faa.tar.xz glusterfs-1260ee53b1674234e6f083563bdcd258e46a6faa.zip |
gluster: IPv6 single stack support
Summary:
- This diff changes all locations in the code to prefer inet6 family
instead of inet. This will allow change GlusterFS to operate
via IPv6 instead of IPv4 for all internal operations while still
being able to serve (FUSE or NFS) clients via IPv4.
- The changes apply to NFS as well.
- This diff ports D1892990, D1897341 & D1896522 to the 3.8 branch.
Test Plan: Prove tests!
Reviewers: dph, rwareing
Signed-off-by: Shreyas Siravara <sshreyas@fb.com>
Change-Id: I34fdaaeb33c194782255625e00616faf75d60c33
BUG: 1406898
Reviewed-on-3.8-fb: http://review.gluster.org/16059
Reviewed-by: Shreyas Siravara <sshreyas@fb.com>
Tested-by: Shreyas Siravara <sshreyas@fb.com>
-rw-r--r-- | cli/src/cli.c | 4 | ||||
-rw-r--r-- | configure.ac | 22 | ||||
-rw-r--r-- | glusterfs.spec.in | 13 | ||||
-rw-r--r-- | libglusterfs/src/compat.h | 4 | ||||
-rw-r--r-- | rpc/rpc-lib/src/rpc-transport.c | 4 | ||||
-rw-r--r-- | rpc/rpc-lib/src/rpcsvc.c | 88 | ||||
-rw-r--r-- | rpc/rpc-lib/src/rpcsvc.h | 5 | ||||
-rw-r--r-- | rpc/rpc-transport/socket/src/name.c | 6 | ||||
-rw-r--r-- | rpc/rpc-transport/socket/src/socket.c | 13 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 4 | ||||
-rw-r--r-- | xlators/nfs/server/src/mount3.c | 9 | ||||
-rw-r--r-- | xlators/nfs/server/src/nfs.c | 23 |
12 files changed, 194 insertions, 1 deletions
diff --git a/cli/src/cli.c b/cli/src/cli.c index 224db54604..66cc91f3a4 100644 --- a/cli/src/cli.c +++ b/cli/src/cli.c @@ -617,7 +617,11 @@ cli_rpc_init (struct cli_state *state) int ret = -1; int port = CLI_GLUSTERD_PORT; xlator_t *this = NULL; +#ifdef IPV6_DEFAULT + char *addr_family = "inet6"; +#else char *addr_family = "inet"; +#endif this = THIS; cli_rpc_prog = &cli_prog; diff --git a/configure.ac b/configure.ac index 418ded7fe8..cc1410f9e8 100644 --- a/configure.ac +++ b/configure.ac @@ -312,6 +312,20 @@ else CFLAGS="${CFLAGS} -g -rdynamic" fi +AC_ARG_WITH([ipv6-default], AC_HELP_STRING([--with-ipv6-default], [Set IPv6 as default.])) +if test "x$with_ipv6_default" = "xyes"; then + IPV6_DEFAULT=yes +else + IPV6_DEFAULT=no +fi +if test "x$ac_cv_file__etc_redhat_release" = "xyes"; then + if rpm -qa centos-release | grep centos; then + if rpm -q centos-release | grep "release-6"; then + IPV6_DEFAULT=no; + fi + fi +fi + AC_ARG_ENABLE([privport_tracking], AC_HELP_STRING([--disable-privport_tracking], [Disable internal tracking of privileged ports.])) @@ -1071,6 +1085,14 @@ AC_SUBST(GF_DISTRIBUTION) GF_HOST_OS="" GF_LDFLAGS="-rdynamic" +dnl include tirpc for IPv6 builds +if test "x$IPV6_DEFAULT" = "xyes"; then + AC_CHECK_LIB([tirpc], [xdr_string], , AC_MSG_ERROR([libtirpc is required to build glusterfs with IPv6 default])) + TIRPC_CFLAGS="-I/usr/include/tirpc" + GF_LDFLAGS="-ltirpc $GF_LDFLAGS" + GF_CFLAGS="$GF_CFLAGS $TIRPC_CFLAGS -DIPV6_DEFAULT" +fi + dnl check for gcc -Werror=format-security saved_CFLAGS=$CFLAGS CFLAGS="-Wformat -Werror=format-security" diff --git a/glusterfs.spec.in b/glusterfs.spec.in index 96a5eba05e..d53e108990 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in @@ -17,6 +17,10 @@ # rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with valgrind %{?_with_valgrind:%global _with_valgrind --enable-valgrind} +# if you wish to compile an rpm with IPv6 default... +# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with ipv6default +%{?_with_ipv6default:%global _with_ipv6default --with-ipv6default} + # if you wish to compile an rpm with cmocka unit testing... # rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with cmocka %{?_with_cmocka:%global _with_cmocka --enable-cmocka} @@ -215,6 +219,9 @@ BuildRequires: python2-devel %if ( 0%{?fedora} && 0%{?fedora} < 26 ) || ( 0%{?rhel} ) BuildRequires: python-ctypes %endif +%if ( 0%{?_with_ipv6default:1} ) +BuildRequires: libtirpc libtirpc-devel +%endif BuildRequires: userspace-rcu-devel >= 0.7 %if ( 0%{?rhel} && 0%{?rhel} <= 6 ) BuildRequires: automake @@ -553,6 +560,9 @@ Requires: %{name}-cli%{?_isa} = %{version}-%{release} Requires: %{name}-libs%{?_isa} = %{version}-%{release} # some daemons (like quota) use a fuse-mount, glusterfsd is part of -fuse Requires: %{name}-fuse%{?_isa} = %{version}-%{release} +%if ( 0%{?_with_ipv6default:1} ) +Requires: libtirpc +%endif # self-heal daemon, rebalance, nfs-server etc. are actually clients Requires: %{name}-api%{?_isa} = %{version}-%{release} Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release} @@ -669,7 +679,8 @@ export CFLAGS %{?_without_ocf} \ %{?_without_rdma} \ %{?_without_syslog} \ - %{?_without_tiering} + %{?_without_tiering} \ + %{?_with_ipv6default} # fix hardening and remove rpath in shlibs %if ( 0%{?fedora} && 0%{?fedora} > 17 ) || ( 0%{?rhel} && 0%{?rhel} > 6 ) diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h index 1d0ac27e83..0cf19b099f 100644 --- a/libglusterfs/src/compat.h +++ b/libglusterfs/src/compat.h @@ -490,6 +490,8 @@ int gf_mkostemp (char *tmpl, int suffixlen, int flags); #define ST_CTIM_NSEC_SET(stbuf, val) do { } while (0); #endif +#ifndef IPV6_DEFAULT + #ifndef IXDR_GET_LONG #define IXDR_GET_LONG(buf) ((long)IXDR_GET_U_INT32(buf)) #endif @@ -506,6 +508,8 @@ int gf_mkostemp (char *tmpl, int suffixlen, int flags); #define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG(buf, (long)(v)) #endif +#endif /* IPV6_DEFAULT */ + #if defined(__GNUC__) && !defined(RELAX_POISONING) /* Use run API, see run.h */ #include <stdlib.h> /* system(), mkostemp() */ diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c index fc26f462c3..4c3d5279fe 100644 --- a/rpc/rpc-lib/src/rpc-transport.c +++ b/rpc/rpc-lib/src/rpc-transport.c @@ -656,7 +656,11 @@ rpc_transport_inet_options_build (dict_t **options, const char *hostname, dict_t *dict = NULL; char *host = NULL; int ret = -1; +#ifdef IPV6_DEFAULT + char *addr_family = "inet6"; +#else char *addr_family = "inet"; +#endif GF_ASSERT (options); GF_ASSERT (hostname); diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c index 68e27ab9e3..82202dbb01 100644 --- a/rpc/rpc-lib/src/rpcsvc.c +++ b/rpc/rpc-lib/src/rpcsvc.c @@ -37,6 +37,10 @@ #include <stdarg.h> #include <stdio.h> +#ifdef IPV6_DEFAULT +#include <netconfig.h> +#endif + #include "xdr-rpcclnt.h" #include "glusterfs-acl.h" @@ -1402,6 +1406,82 @@ rpcsvc_error_reply (rpcsvc_request_t *req) return rpcsvc_submit_generic (req, &dummyvec, 0, NULL, 0, NULL); } +#ifdef IPV6_DEFAULT +int +rpcsvc_program_register_rpcbind6 (rpcsvc_program_t *newprog, uint32_t port) +{ + const int IP_BUF_LEN = 64; + char addr_buf[IP_BUF_LEN]; + + int err = 0; + bool_t success = 0; + struct netconfig *nc; + struct netbuf *nb; + + if (!newprog) { + goto out; + } + + nc = getnetconfigent ("tcp6"); + if (!nc) { + err = -1; + goto out; + } + + + err = sprintf (addr_buf, "::.%d.%d", port >> 8 & 0xff, + port & 0xff); + if (err < 0) { + err = -1; + goto out; + } + + nb = uaddr2taddr (nc, addr_buf); + if (!nb) { + err = -1; + goto out; + } + + success = rpcb_set (newprog->prognum, newprog->progver, nc, nb); + if (!success) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Could not register the IPv6" + " service with rpcbind"); + } + + err = 0; + +out: + return err; +} + +int +rpcsvc_program_unregister_rpcbind6 (rpcsvc_program_t *newprog) +{ + int err = 0; + bool_t success = 0; + struct netconfig *nc; + + if (!newprog) { + goto out; + } + + nc = getnetconfigent ("tcp6"); + if (!nc) { + err = -1; + goto out; + } + + success = rpcb_unset (newprog->prognum, newprog->progver, nc); + if (!success) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Could not unregister the IPv6" + " service with rpcbind"); + } + + err = 0; +out: + return err; +} +#endif /* Register the program with the local portmapper service. */ int @@ -1566,6 +1646,14 @@ rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t *program) " program failed"); goto out; } +#ifdef IPV6_DEFAULT + ret = rpcsvc_program_unregister_rpcbind6 (program); + if (ret == -1) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "rpcbind (ipv6)" + " unregistration of program failed"); + goto out; + } +#endif pthread_mutex_lock (&svc->rpclock); { list_for_each_entry (prog, &svc->programs, program) { diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h index 73507b6538..37244be536 100644 --- a/rpc/rpc-lib/src/rpcsvc.h +++ b/rpc/rpc-lib/src/rpcsvc.h @@ -445,6 +445,11 @@ rpcsvc_listener_destroy (rpcsvc_listener_t *listener); extern int rpcsvc_program_register_portmap (rpcsvc_program_t *newprog, uint32_t port); +#ifdef IPV6_DEFAULT +extern int +rpcsvc_program_register_rpcbind6 (rpcsvc_program_t *newprog, uint32_t port); +#endif + extern int rpcsvc_program_unregister_portmap (rpcsvc_program_t *newprog); diff --git a/rpc/rpc-transport/socket/src/name.c b/rpc/rpc-transport/socket/src/name.c index b604bb5701..f6125b0ed9 100644 --- a/rpc/rpc-transport/socket/src/name.c +++ b/rpc/rpc-transport/socket/src/name.c @@ -561,8 +561,14 @@ server_fill_address_family (rpc_transport_t *this, sa_family_t *sa_family) { data_t *address_family_data = NULL; int32_t ret = -1; + +#ifdef IPV6_DEFAULT + char *addr_family = "inet6"; + sa_family_t default_family = AF_INET6; +#else char *addr_family = "inet"; sa_family_t default_family = AF_INET; +#endif GF_VALIDATE_OR_GOTO ("socket", sa_family, out); diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c index 26fdc83dd6..88901e75e9 100644 --- a/rpc/rpc-transport/socket/src/socket.c +++ b/rpc/rpc-transport/socket/src/socket.c @@ -3202,6 +3202,19 @@ socket_connect (rpc_transport_t *this, int port) } } + /* Make sure we are not vulnerable to someone setting + * net.ipv6.bindv6only to 1 so that gluster services are + * avalable over IPv4 & IPv6. + */ + int disable_v6only = 0; + + if (setsockopt (priv->sock, IPPROTO_IPV6, IPV6_V6ONLY, + (void *)&disable_v6only, + sizeof (disable_v6only)) < 0) { + gf_log (this->name, GF_LOG_WARNING, + "Error disabling sockopt IPV6_V6ONLY: \"%s\"", + strerror (errno)); + } if (priv->nodelay && (sa_family != AF_UNIX)) { ret = __socket_nodelay (priv->sock); diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 4cc6769749..fa9a68caf2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -289,7 +289,11 @@ __glusterd_handle_create_volume (rpcsvc_request_t *req) int32_t type = 0; char *username = NULL; char *password = NULL; +#ifdef IPV6_DEFAULT + char *addr_family = "inet6"; +#else char *addr_family = "inet"; +#endif GF_ASSERT (req); diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c index 64f1094842..db416be609 100644 --- a/xlators/nfs/server/src/mount3.c +++ b/xlators/nfs/server/src/mount3.c @@ -4169,6 +4169,15 @@ mnt1svc_init (xlator_t *nfsx) } } +#ifdef IPV6_DEFAULT + ret = dict_set_str (options, "transport.address-family", "inet6"); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, + "dict_set_str error when trying to enable ipv6"); + goto err; + } +#endif + ret = rpcsvc_create_listeners (nfs->rpcsvc, options, nfsx->name); if (ret == -1) { gf_msg (GF_NFS, GF_LOG_ERROR, errno, diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c index c2c3c863b0..daa8366f19 100644 --- a/xlators/nfs/server/src/nfs.c +++ b/xlators/nfs/server/src/nfs.c @@ -204,6 +204,10 @@ nfs_program_register_portmap_all (struct nfs_state *nfs) if (nfs->override_portnum) prog->progport = nfs->override_portnum; (void) rpcsvc_program_register_portmap (prog, prog->progport); +#ifdef IPV6_DEFAULT + (void) rpcsvc_program_register_rpcbind6 (prog, prog->progport); +#endif + } return (0); @@ -339,6 +343,17 @@ nfs_init_versions (struct nfs_state *nfs, xlator_t *this) if (version->required) goto err; } +#ifdef IPV6_DEFAULT + ret = rpcsvc_program_register_rpcbind6 (prog, + prog->progport); + if (ret == -1) { + gf_msg (GF_NFS, GF_LOG_ERROR, 0, + NFS_MSG_PGM_REG_FAIL, + "Program (ipv6) %s registration failed", + prog->progname); + goto err; + } +#endif } } @@ -901,6 +916,14 @@ nfs_init_state (xlator_t *this) } } +#ifdef IPV6_DEFAULT + ret = dict_set_str (this->options, "transport.address-family", + "inet6"); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error"); + goto free_foppool; + } +#endif /* Right only socket support exists between nfs client and * gluster nfs, so we can set default value as socket |