File 0013-socket-activation-Fix-rpcbind.service-to-use-separat.patch of Package rpcbind
From 487918f173a899ce39b426ceeaa830d3c45fbd2d Mon Sep 17 00:00:00 2001
From: Jeff Mahoney <jeffm@suse.com>
Date: Tue, 20 Aug 2013 15:20:13 +0200
Subject: [PATCH 13/24] socket-activation: Fix rpcbind.service to use separate
sockets
systemd will, by default, pass a socket that provides both IPv4 and
IPv6 services. RPC netconfig requires that sockets be either IPv4
or IPv6.
This patch fixes the rpcbind.socket unit file and adds a warning
to rpcbind should the user encounter an issue.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
src/rpcbind.c | 29 +++++++++++++++++++++++++++++
systemd/rpcbind.socket | 11 ++++++++---
2 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index baf1ac0..aec0510 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
@@ -561,6 +562,31 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
}
/*
+ * 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;
+}
+
+/*
* This will create a server socket for the given netid, bound to the
* address specified by @hostname
*
@@ -591,6 +617,9 @@ rpcbind_init_endpoint(struct netconfig *nconf, const char *hostname, int fd)
exit(1);
}
+ if (addr.ss_family == AF_INET6 && handle_ipv6_socket(fd))
+ return -1;
+
sockaddr2netbuf((struct sockaddr *) &addr, alen, &taddr.addr);
}
diff --git a/systemd/rpcbind.socket b/systemd/rpcbind.socket
index ad5fd62..0b0c1d3 100644
--- a/systemd/rpcbind.socket
+++ b/systemd/rpcbind.socket
@@ -4,9 +4,14 @@ Wants=rpcbind.target
Before=rpcbind.target
[Socket]
-ListenStream=/var/run/rpcbind.sock
-ListenStream=111
-ListenDatagram=111
+ListenStream=/run/rpcbind.sock
+
+# RPC netconfig can't handle ipv6/ipv4 dual sockets
+BindIPv6Only=ipv6-only
+ListenStream=0.0.0.0:111
+ListenDatagram=0.0.0.0:111
+ListenStream=[::]:111
+ListenDatagram=[::]:111
[Install]
WantedBy=sockets.target
--
1.7.12.4