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
c62b8e
index 58e44b89b2..0c0fa0f506 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
c62b8e
index baab6353e1..b14e368176 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
c62b8e
index 6bfb677fb5..9200ce8822 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_;