From 994e57f91c58e9e88c9f793e948e8d3af6ff4528 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Tue, 20 Aug 2013 15:20:13 +0200 Subject: [PATCH 11/13] 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 --- 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 32e6deb..d2b25fa 100644 --- a/src/rpcbind.c +++ b/src/rpcbind.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #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