summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorsten Kukuk <kukuk@suse.de>2014-12-16 12:58:48 -0500
committerSteve Dickson <steved@redhat.com>2014-12-16 13:08:27 -0500
commit606cd5e780b3077d31c3ccc3b360a44a08c2e172 (patch)
tree3eacdb24ac9dfde532297b424ea7f5550d1cd46b
parentf4af0213b938a2f3a52ff20d0a9433bff3833a5d (diff)
downloadrpcbind-606cd5e780b3077d31c3ccc3b360a44a08c2e172.tar.gz
rpcbind: IPv4/IPv6 dualmode
Systemd will, by default, pass a socket that provides both IPv4 and IPv6 services. RPC netconfig requires that sockets be either IPv4 or IPv6. Adjust the rpcbind.socket unit file and add a warning to rpcbind should the user encounter an issue. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Signed-off-by: Steve Dickson <steved@redhat.com>
-rw-r--r--src/rpcbind.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/rpcbind.c b/src/rpcbind.c
index f7c71ee..f5159c7 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -50,6 +50,7 @@
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <netinet/in.h>
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
#ifdef PORTMAP
@@ -277,6 +278,31 @@ main(int argc, char *argv[])
}
/*
+ * Normally systemd will open sockets in dual ipv4/ipv6 mode.
+ * That won't work with netconfig and we'll only match
+ * the ipv6 socket. Convert it to IPV6_V6ONLY and issue
+ * a warning for the user to fix their systemd config.
+ */
+static int
+handle_ipv6_socket(int fd)
+{
+ int opt;
+ socklen_t len = sizeof(opt);
+
+ if (getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, &len)) {
+ syslog(LOG_ERR, "failed to get ipv6 socket opts: %m");
+ return -1;
+ }
+
+ if (opt) /* socket is already in V6ONLY mode */
+ return 0;
+
+ syslog(LOG_ERR, "systemd has passed an IPv4/IPv6 dual-mode socket.");
+ syslog(LOG_ERR, "Please fix your systemd config by specifying IPv4 and IPv6 sockets separately and using BindIPv6Only=ipv6-only.");
+ return -1;
+}
+
+/*
* Adds the entry into the rpcbind database.
* If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
* Returns 0 if succeeds, else fails
@@ -361,6 +387,9 @@ init_transport(struct netconfig *nconf)
goto error;
}
+ if (sa.sa.sa_family == AF_INET6 && handle_ipv6_socket(fd))
+ goto error;
+
/* Copy the address */
taddr.addr.maxlen = taddr.addr.len = addrlen;
taddr.addr.buf = malloc(addrlen);