summaryrefslogtreecommitdiffstats
path: root/rpc
diff options
context:
space:
mode:
authorKevin Vigor <kvigor@fb.com>2017-04-28 16:44:29 -0700
committerAmar Tumballi <amarts@redhat.com>2017-10-24 09:28:08 +0000
commit1260ee53b1674234e6f083563bdcd258e46a6faa (patch)
treea1e31987357722438f603622a43151839c83a13e /rpc
parent738c38f0efa7b4d4dab0cf23d00589d68e4eb88d (diff)
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>
Diffstat (limited to 'rpc')
-rw-r--r--rpc/rpc-lib/src/rpc-transport.c4
-rw-r--r--rpc/rpc-lib/src/rpcsvc.c88
-rw-r--r--rpc/rpc-lib/src/rpcsvc.h5
-rw-r--r--rpc/rpc-transport/socket/src/name.c6
-rw-r--r--rpc/rpc-transport/socket/src/socket.c13
5 files changed, 116 insertions, 0 deletions
diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c
index fc26f462c31..4c3d5279fe1 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 68e27ab9e3f..82202dbb013 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 73507b6538b..37244be5361 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 b604bb57015..f6125b0ed95 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 26fdc83dd65..88901e75e98 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);