ecbff1
From b2dfc6d1b697da2e649b04ad0b8c3aef7a7d4d88 Mon Sep 17 00:00:00 2001
ecbff1
From: Lennart Poettering <lennart@poettering.net>
ecbff1
Date: Fri, 15 May 2015 20:15:59 +0200
ecbff1
Subject: [PATCH] socket-util: socket_address_parse() should not log errors on
ecbff1
 its own
ecbff1
ecbff1
Given that socket_address_parse() is mostly a "library" call it
ecbff1
shouldn't log on its own, but leave that to its caller.
ecbff1
ecbff1
This patch removes logging from the call in case IPv6 is not available
ecbff1
but and IPv6 address shall be parsed. Instead a new call
ecbff1
socket_address_parse_and_warn() is introduced which first invokes
ecbff1
socket_address_parse() and then logs if necessary.
ecbff1
ecbff1
This should fix "make check" on ipv6-less kernels:
ecbff1
ecbff1
http://lists.freedesktop.org/archives/systemd-devel/2015-April/031385.html
ecbff1
(cherry picked from commit 7693146dee53a2b0f524e977188347166bf454ca)
ecbff1
ecbff1
Related: #1497639
ecbff1
---
ecbff1
 src/core/load-fragment.c |  2 +-
ecbff1
 src/shared/socket-util.c | 29 +++++++++++++++++++----------
ecbff1
 src/shared/socket-util.h |  1 +
ecbff1
 3 files changed, 21 insertions(+), 11 deletions(-)
ecbff1
ecbff1
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
ecbff1
index 58e44b89b..0c0fa0f50 100644
ecbff1
--- a/src/core/load-fragment.c
ecbff1
+++ b/src/core/load-fragment.c
ecbff1
@@ -365,7 +365,7 @@ int config_parse_socket_listen(const char *unit,
ecbff1
                         log_syntax(unit, LOG_ERR, filename, line, -r,
ecbff1
                                    "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
ecbff1
 
ecbff1
-                r = socket_address_parse(&p->address, k ? k : rvalue);
ecbff1
+                r = socket_address_parse_and_warn(&p->address, k ? k : rvalue);
ecbff1
                 if (r < 0) {
ecbff1
                         if (r != -EAFNOSUPPORT)
ecbff1
                                 log_syntax(unit, LOG_ERR, filename, line, -r,
ecbff1
diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c
ecbff1
index baab6353e..b14e36817 100644
ecbff1
--- a/src/shared/socket-util.c
ecbff1
+++ b/src/shared/socket-util.c
ecbff1
@@ -55,11 +55,6 @@ int socket_address_parse(SocketAddress *a, const char *s) {
ecbff1
         if (*s == '[') {
ecbff1
                 /* IPv6 in [x:.....:z]:p notation */
ecbff1
 
ecbff1
-                if (!socket_ipv6_is_supported()) {
ecbff1
-                        log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
ecbff1
-                        return -EAFNOSUPPORT;
ecbff1
-                }
ecbff1
-
ecbff1
                 e = strchr(s+1, ']');
ecbff1
                 if (!e)
ecbff1
                         return -EINVAL;
ecbff1
@@ -144,11 +139,6 @@ int socket_address_parse(SocketAddress *a, const char *s) {
ecbff1
                                 if (idx == 0)
ecbff1
                                         return -EINVAL;
ecbff1
 
ecbff1
-                                if (!socket_ipv6_is_supported()) {
ecbff1
-                                        log_warning("Binding to interface is not available since kernel does not support IPv6.");
ecbff1
-                                        return -EAFNOSUPPORT;
ecbff1
-                                }
ecbff1
-
ecbff1
                                 a->sockaddr.in6.sin6_family = AF_INET6;
ecbff1
                                 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
ecbff1
                                 a->sockaddr.in6.sin6_scope_id = idx;
ecbff1
@@ -182,6 +172,25 @@ int socket_address_parse(SocketAddress *a, const char *s) {
ecbff1
         return 0;
ecbff1
 }
ecbff1
 
ecbff1
+int socket_address_parse_and_warn(SocketAddress *a, const char *s) {
ecbff1
+        SocketAddress b;
ecbff1
+        int r;
ecbff1
+
ecbff1
+        /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
ecbff1
+
ecbff1
+        r = socket_address_parse(&b, s);
ecbff1
+        if (r < 0)
ecbff1
+                return r;
ecbff1
+
ecbff1
+        if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) {
ecbff1
+                log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
ecbff1
+                return -EAFNOSUPPORT;
ecbff1
+        }
ecbff1
+
ecbff1
+        *a = b;
ecbff1
+        return 0;
ecbff1
+}
ecbff1
+
ecbff1
 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
ecbff1
         int family;
ecbff1
         unsigned group = 0;
ecbff1
diff --git a/src/shared/socket-util.h b/src/shared/socket-util.h
ecbff1
index 6bfb677fb..9200ce882 100644
ecbff1
--- a/src/shared/socket-util.h
ecbff1
+++ b/src/shared/socket-util.h
ecbff1
@@ -67,6 +67,7 @@ typedef enum SocketAddressBindIPv6Only {
ecbff1
 #define socket_address_family(a) ((a)->sockaddr.sa.sa_family)
ecbff1
 
ecbff1
 int socket_address_parse(SocketAddress *a, const char *s);
ecbff1
+int socket_address_parse_and_warn(SocketAddress *a, const char *s);
ecbff1
 int socket_address_parse_netlink(SocketAddress *a, const char *s);
ecbff1
 int socket_address_print(const SocketAddress *a, char **p);
ecbff1
 int socket_address_verify(const SocketAddress *a) _pure_;