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