]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #14381 from keszybz/ifindex-cleanup
authorLennart Poettering <lennart@poettering.net>
Mon, 13 Jan 2020 16:57:59 +0000 (17:57 +0100)
committerGitHub <noreply@github.com>
Mon, 13 Jan 2020 16:57:59 +0000 (17:57 +0100)
Resolve alternative names

37 files changed:
src/activate/activate.c
src/basic/in-addr-util.c
src/basic/in-addr-util.h
src/basic/parse-util.c
src/basic/parse-util.h
src/basic/socket-label.c
src/basic/socket-util.c
src/basic/socket-util.h
src/core/dbus-socket.c
src/core/load-fragment.c
src/core/socket.c
src/journal-remote/journal-remote-main.c
src/libsystemd/sd-device/sd-device.c
src/libsystemd/sd-login/sd-login.c
src/libsystemd/sd-netlink/netlink-util.c
src/libsystemd/sd-netlink/netlink-util.h
src/libsystemd/sd-network/sd-network.c
src/machine/machine.c
src/machine/machinectl.c
src/network/networkctl.c
src/network/networkd-link-bus.c
src/network/networkd-manager-bus.c
src/network/networkd-route.c
src/nspawn/nspawn-network.c
src/resolve/resolvectl.c
src/resolve/resolved-bus.c
src/resolve/resolved-etc-hosts.c
src/resolve/resolved-link-bus.c
src/resolve/resolved-manager.c
src/resolve/resolved-util.c
src/shared/meson.build
src/shared/socket-netlink.c [new file with mode: 0644]
src/shared/socket-netlink.h [new file with mode: 0644]
src/test/meson.build
src/test/test-socket-netlink.c [new file with mode: 0644]
src/test/test-socket-util.c
src/timedate/timedatectl.c

index 77b9a055ca2374d2446cb4c9bc5f1395c1d32afd..5d796ab38dfb0c639940d951922f3f470faef736 100644 (file)
@@ -17,6 +17,7 @@
 #include "pretty-print.h"
 #include "process-util.h"
 #include "signal-util.h"
+#include "socket-netlink.h"
 #include "socket-util.h"
 #include "string-util.h"
 #include "strv.h"
index 06b92db579fda40e2a728eab9a963d32f41e37b5..bfe855fb4b9ca9ed0bd7d59508beb2c9eec7868d 100644 (file)
@@ -439,52 +439,6 @@ int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union
         return -EINVAL;
 }
 
-int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex) {
-        _cleanup_free_ char *buf = NULL;
-        const char *suffix;
-        int r, ifi = 0;
-
-        assert(s);
-        assert(family);
-        assert(ret);
-
-        /* Similar to in_addr_from_string_auto() but also parses an optionally appended IPv6 zone suffix ("scope id")
-         * if one is found. */
-
-        suffix = strchr(s, '%');
-        if (suffix) {
-
-                if (ifindex) {
-                        /* If we shall return the interface index, try to parse it */
-                        r = parse_ifindex(suffix + 1, &ifi);
-                        if (r < 0) {
-                                unsigned u;
-
-                                u = if_nametoindex(suffix + 1);
-                                if (u <= 0)
-                                        return -errno;
-
-                                ifi = (int) u;
-                        }
-                }
-
-                buf = strndup(s, suffix - s);
-                if (!buf)
-                        return -ENOMEM;
-
-                s = buf;
-        }
-
-        r = in_addr_from_string_auto(s, family, ret);
-        if (r < 0)
-                return r;
-
-        if (ifindex)
-                *ifindex = ifi;
-
-        return r;
-}
-
 unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr) {
         assert(addr);
 
index 28afc7d86cfd91485d6f1fba8c871830d22434d6..ae2dad0bb1e92280cb6efe34b8e9e94dbd6e8949 100644 (file)
@@ -42,7 +42,7 @@ int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned
 int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret);
 int in_addr_from_string(int family, const char *s, union in_addr_union *ret);
 int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret);
-int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex);
+
 unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr);
 struct in_addr* in4_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen);
 int in4_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen);
index b81db04989fb11851ef500e8fb8507e723df6385..b644c4a4d6043eb51069c55e112d93158d69cc13 100644 (file)
@@ -79,11 +79,10 @@ int parse_mode(const char *s, mode_t *ret) {
         return 0;
 }
 
-int parse_ifindex(const char *s, int *ret) {
+int parse_ifindex(const char *s) {
         int ifi, r;
 
         assert(s);
-        assert(ret);
 
         r = safe_atoi(s, &ifi);
         if (r < 0)
@@ -91,26 +90,7 @@ int parse_ifindex(const char *s, int *ret) {
         if (ifi <= 0)
                 return -EINVAL;
 
-        *ret = ifi;
-        return 0;
-}
-
-int parse_ifindex_or_ifname(const char *s, int *ret) {
-        int r;
-
-        assert(s);
-        assert(ret);
-
-        r = parse_ifindex(s, ret);
-        if (r >= 0)
-                return r;
-
-        r = (int) if_nametoindex(s);
-        if (r <= 0)
-                return -errno;
-
-        *ret = r;
-        return 0;
+        return ifi;
 }
 
 int parse_mtu(int family, const char *s, uint32_t *ret) {
index 3a70b792766fb10740036be3586795148eb3de49..c6d1d249672222eed0a5c0e52a1d41a05e86d8b5 100644 (file)
@@ -13,8 +13,7 @@ int parse_boolean(const char *v) _pure_;
 int parse_dev(const char *s, dev_t *ret);
 int parse_pid(const char *s, pid_t* ret_pid);
 int parse_mode(const char *s, mode_t *ret);
-int parse_ifindex(const char *s, int *ret);
-int parse_ifindex_or_ifname(const char *s, int *ret);
+int parse_ifindex(const char *s);
 int parse_mtu(int family, const char *s, uint32_t *ret);
 
 int parse_size(const char *t, uint64_t base, uint64_t *size);
index 8c087268e4b26f49c0d85dbb85a67826c14c60d5..ec52d81653694e5cbdf3df7b0ba925cfc471ce17 100644 (file)
@@ -134,31 +134,3 @@ int socket_address_listen(
 
         return r;
 }
-
-int make_socket_fd(int log_level, const char* address, int type, int flags) {
-        SocketAddress a;
-        int fd, r;
-
-        r = socket_address_parse(&a, address);
-        if (r < 0)
-                return log_error_errno(r, "Failed to parse socket address \"%s\": %m", address);
-
-        a.type = type;
-
-        fd = socket_address_listen(&a, type | flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT,
-                                   NULL, false, false, false, 0755, 0644, NULL);
-        if (fd < 0 || log_get_max_level() >= log_level) {
-                _cleanup_free_ char *p = NULL;
-
-                r = socket_address_print(&a, &p);
-                if (r < 0)
-                        return log_error_errno(r, "socket_address_print(): %m");
-
-                if (fd < 0)
-                        log_error_errno(fd, "Failed to listen on %s: %m", p);
-                else
-                        log_full(log_level, "Listening on %s", p);
-        }
-
-        return fd;
-}
index 64bc79712f10667b1d25ff3944d18a2240bd0fdf..ad467ab85119a8cf6cdeef12362e52672f483560 100644 (file)
 #endif
 
 static const char* const socket_address_type_table[] = {
-        [SOCK_STREAM] = "Stream",
-        [SOCK_DGRAM] = "Datagram",
-        [SOCK_RAW] = "Raw",
-        [SOCK_RDM] = "ReliableDatagram",
+        [SOCK_STREAM] =    "Stream",
+        [SOCK_DGRAM] =     "Datagram",
+        [SOCK_RAW] =       "Raw",
+        [SOCK_RDM] =       "ReliableDatagram",
         [SOCK_SEQPACKET] = "SequentialPacket",
-        [SOCK_DCCP] = "DatagramCongestionControl",
+        [SOCK_DCCP] =      "DatagramCongestionControl",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int);
 
-int socket_address_parse(SocketAddress *a, const char *s) {
-        _cleanup_free_ char *n = NULL;
-        char *e;
-        int r;
-
-        assert(a);
-        assert(s);
-
-        *a = (SocketAddress) {
-                .type = SOCK_STREAM,
-        };
-
-        if (*s == '[') {
-                uint16_t port;
-
-                /* IPv6 in [x:.....:z]:p notation */
-
-                e = strchr(s+1, ']');
-                if (!e)
-                        return -EINVAL;
-
-                n = strndup(s+1, e-s-1);
-                if (!n)
-                        return -ENOMEM;
-
-                errno = 0;
-                if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
-                        return errno_or_else(EINVAL);
-
-                e++;
-                if (*e != ':')
-                        return -EINVAL;
-
-                e++;
-                r = parse_ip_port(e, &port);
-                if (r < 0)
-                        return r;
-
-                a->sockaddr.in6.sin6_family = AF_INET6;
-                a->sockaddr.in6.sin6_port = htobe16(port);
-                a->size = sizeof(struct sockaddr_in6);
-
-        } else if (*s == '/') {
-                /* AF_UNIX socket */
-
-                size_t l;
-
-                l = strlen(s);
-                if (l >= sizeof(a->sockaddr.un.sun_path)) /* Note that we refuse non-NUL-terminated sockets when
-                                                           * parsing (the kernel itself is less strict here in what it
-                                                           * accepts) */
-                        return -EINVAL;
-
-                a->sockaddr.un.sun_family = AF_UNIX;
-                memcpy(a->sockaddr.un.sun_path, s, l);
-                a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
-
-        } else if (*s == '@') {
-                /* Abstract AF_UNIX socket */
-                size_t l;
-
-                l = strlen(s+1);
-                if (l >= sizeof(a->sockaddr.un.sun_path) - 1) /* Note that we refuse non-NUL-terminated sockets here
-                                                               * when parsing, even though abstract namespace sockets
-                                                               * explicitly allow embedded NUL bytes and don't consider
-                                                               * them special. But it's simply annoying to debug such
-                                                               * sockets. */
-                        return -EINVAL;
-
-                a->sockaddr.un.sun_family = AF_UNIX;
-                memcpy(a->sockaddr.un.sun_path+1, s+1, l);
-                a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
-
-        } else if (startswith(s, "vsock:")) {
-                /* AF_VSOCK socket in vsock:cid:port notation */
-                const char *cid_start = s + STRLEN("vsock:");
-                unsigned port;
-
-                e = strchr(cid_start, ':');
-                if (!e)
-                        return -EINVAL;
-
-                r = safe_atou(e+1, &port);
-                if (r < 0)
-                        return r;
-
-                n = strndup(cid_start, e - cid_start);
-                if (!n)
-                        return -ENOMEM;
-
-                if (!isempty(n)) {
-                        r = safe_atou(n, &a->sockaddr.vm.svm_cid);
-                        if (r < 0)
-                                return r;
-                } else
-                        a->sockaddr.vm.svm_cid = VMADDR_CID_ANY;
-
-                a->sockaddr.vm.svm_family = AF_VSOCK;
-                a->sockaddr.vm.svm_port = port;
-                a->size = sizeof(struct sockaddr_vm);
-
-        } else {
-                uint16_t port;
-
-                e = strchr(s, ':');
-                if (e) {
-                        r = parse_ip_port(e + 1, &port);
-                        if (r < 0)
-                                return r;
-
-                        n = strndup(s, e-s);
-                        if (!n)
-                                return -ENOMEM;
-
-                        /* IPv4 in w.x.y.z:p notation? */
-                        r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
-                        if (r < 0)
-                                return -errno;
-
-                        if (r > 0) {
-                                /* Gotcha, it's a traditional IPv4 address */
-                                a->sockaddr.in.sin_family = AF_INET;
-                                a->sockaddr.in.sin_port = htobe16(port);
-                                a->size = sizeof(struct sockaddr_in);
-                        } else {
-                                unsigned idx;
-
-                                if (strlen(n) > IF_NAMESIZE-1)
-                                        return -EINVAL;
-
-                                /* Uh, our last resort, an interface name */
-                                idx = if_nametoindex(n);
-                                if (idx == 0)
-                                        return -EINVAL;
-
-                                a->sockaddr.in6.sin6_family = AF_INET6;
-                                a->sockaddr.in6.sin6_port = htobe16(port);
-                                a->sockaddr.in6.sin6_scope_id = idx;
-                                a->sockaddr.in6.sin6_addr = in6addr_any;
-                                a->size = sizeof(struct sockaddr_in6);
-                        }
-                } else {
-
-                        /* Just a port */
-                        r = parse_ip_port(s, &port);
-                        if (r < 0)
-                                return r;
-
-                        if (socket_ipv6_is_supported()) {
-                                a->sockaddr.in6.sin6_family = AF_INET6;
-                                a->sockaddr.in6.sin6_port = htobe16(port);
-                                a->sockaddr.in6.sin6_addr = in6addr_any;
-                                a->size = sizeof(struct sockaddr_in6);
-                        } else {
-                                a->sockaddr.in.sin_family = AF_INET;
-                                a->sockaddr.in.sin_port = htobe16(port);
-                                a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
-                                a->size = sizeof(struct sockaddr_in);
-                        }
-                }
-        }
-
-        return 0;
-}
-
-int socket_address_parse_and_warn(SocketAddress *a, const char *s) {
-        SocketAddress b;
-        int r;
-
-        /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
-
-        r = socket_address_parse(&b, s);
-        if (r < 0)
-                return r;
-
-        if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) {
-                log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
-                return -EAFNOSUPPORT;
-        }
-
-        *a = b;
-        return 0;
-}
-
-int socket_address_parse_netlink(SocketAddress *a, const char *s) {
-        _cleanup_free_ char *word = NULL;
-        unsigned group = 0;
-        int family, r;
-
-        assert(a);
-        assert(s);
-
-        zero(*a);
-        a->type = SOCK_RAW;
-
-        r = extract_first_word(&s, &word, NULL, 0);
-        if (r < 0)
-                return r;
-        if (r == 0)
-                return -EINVAL;
-
-        family = netlink_family_from_string(word);
-        if (family < 0)
-                return -EINVAL;
-
-        if (!isempty(s)) {
-                r = safe_atou(s, &group);
-                if (r < 0)
-                        return r;
-        }
-
-        a->sockaddr.nl.nl_family = AF_NETLINK;
-        a->sockaddr.nl.nl_groups = group;
-
-        a->type = SOCK_RAW;
-        a->size = sizeof(struct sockaddr_nl);
-        a->protocol = family;
-
-        return 0;
-}
-
 int socket_address_verify(const SocketAddress *a, bool strict) {
         assert(a);
 
@@ -482,32 +261,6 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
         return true;
 }
 
-bool socket_address_is(const SocketAddress *a, const char *s, int type) {
-        struct SocketAddress b;
-
-        assert(a);
-        assert(s);
-
-        if (socket_address_parse(&b, s) < 0)
-                return false;
-
-        b.type = type;
-
-        return socket_address_equal(a, &b);
-}
-
-bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
-        struct SocketAddress b;
-
-        assert(a);
-        assert(s);
-
-        if (socket_address_parse_netlink(&b, s) < 0)
-                return false;
-
-        return socket_address_equal(a, &b);
-}
-
 const char* socket_address_get_path(const SocketAddress *a) {
         assert(a);
 
index 17c20abc32fd139e588261de620c1ce65e4ceafb..24e12139516e121d6fd5aeb2a2d0d67de3ed5afb 100644 (file)
@@ -41,6 +41,8 @@ union sockaddr_union {
         uint8_t un_buffer[sizeof(struct sockaddr_un) + 1];
 };
 
+#define SUN_PATH_LEN (sizeof(((struct sockaddr_un){}).sun_path))
+
 typedef struct SocketAddress {
         union sockaddr_union sockaddr;
 
@@ -68,12 +70,6 @@ typedef enum SocketAddressBindIPv6Only {
 const char* socket_address_type_to_string(int t) _const_;
 int socket_address_type_from_string(const char *s) _pure_;
 
-int socket_address_parse(SocketAddress *a, const char *s);
-int socket_address_parse_and_warn(SocketAddress *a, const char *s);
-int socket_address_parse_netlink(SocketAddress *a, const char *s);
-int socket_address_print(const SocketAddress *a, char **p);
-int socket_address_verify(const SocketAddress *a, bool strict) _pure_;
-
 int sockaddr_un_unlink(const struct sockaddr_un *sa);
 
 static inline int socket_address_unlink(const SocketAddress *a) {
@@ -94,11 +90,9 @@ int socket_address_listen(
                 mode_t directory_mode,
                 mode_t socket_mode,
                 const char *label);
-int make_socket_fd(int log_level, const char* address, int type, int flags);
-
-bool socket_address_is(const SocketAddress *a, const char *s, int type);
-bool socket_address_is_netlink(const SocketAddress *a, const char *s);
 
+int socket_address_verify(const SocketAddress *a, bool strict) _pure_;
+int socket_address_print(const SocketAddress *a, char **p);
 bool socket_address_matches_fd(const SocketAddress *a, int fd);
 
 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_;
index 25d3d71391b863419e40a5a69ec0eaf9a0853dd0..c8253c7940d77228fd3f9292185a7af4b4dadc10 100644 (file)
@@ -12,6 +12,7 @@
 #include "parse-util.h"
 #include "path-util.h"
 #include "socket.h"
+#include "socket-netlink.h"
 #include "socket-util.h"
 #include "string-util.h"
 #include "unit.h"
index 8f9a2f64dbe58ce2437f23a80e52e111e4e5624b..c5ba7b10461231d7895584ba57e2bb21ec1d595b 100644 (file)
@@ -48,6 +48,7 @@
 #endif
 #include "securebits-util.h"
 #include "signal-util.h"
+#include "socket-netlink.h"
 #include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
index c587eaebed5e2cb31e859a4fb6994b707b7a1221..633be68337014e033bb49ca183050812d5a1a6de 100644 (file)
@@ -36,6 +36,7 @@
 #include "signal-util.h"
 #include "smack-util.h"
 #include "socket.h"
+#include "socket-netlink.h"
 #include "special.h"
 #include "string-table.h"
 #include "string-util.h"
index ac2bf648d2af08173d714928fed15c1764859f10..88e42d3a984ba1b517e7a9f40ea895fb55ac222b 100644 (file)
@@ -17,6 +17,7 @@
 #include "process-util.h"
 #include "rlimit-util.h"
 #include "signal-util.h"
+#include "socket-netlink.h"
 #include "socket-util.h"
 #include "stat-util.h"
 #include "string-table.h"
index f35612fe12bc7cc2f9b3bd2f8066d59c49a4f0d4..1f2451f8e1b4e4d851571a19d858aedc9d1e9196 100644 (file)
@@ -340,17 +340,17 @@ int device_set_devtype(sd_device *device, const char *_devtype) {
         return 0;
 }
 
-int device_set_ifindex(sd_device *device, const char *_ifindex) {
-        int ifindex, r;
+int device_set_ifindex(sd_device *device, const char *name) {
+        int r, ifindex;
 
         assert(device);
-        assert(_ifindex);
+        assert(name);
 
-        r = parse_ifindex(_ifindex, &ifindex);
-        if (r < 0)
-                return r;
+        ifindex = parse_ifindex(name);
+        if (ifindex < 0)
+                return ifindex;
 
-        r = device_add_property_internal(device, "IFINDEX", _ifindex);
+        r = device_add_property_internal(device, "IFINDEX", name);
         if (r < 0)
                 return r;
 
@@ -619,7 +619,7 @@ _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) {
                 struct ifreq ifr = {};
                 int ifindex;
 
-                r = parse_ifindex(&id[1], &ifr.ifr_ifindex);
+                r = ifr.ifr_ifindex = parse_ifindex(&id[1]);
                 if (r < 0)
                         return r;
 
index fbfd89b69b1d557be99d89b69884ccf0f3a26e9d..3e96c98cd95a2b9a5afa807ebb248c6f9a140cde 100644 (file)
@@ -928,7 +928,8 @@ _public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) {
 
                 *(char*) (mempcpy(buf, word, l)) = 0;
 
-                if (parse_ifindex(buf, &ifi) < 0)
+                ifi = parse_ifindex(buf);
+                if (ifi < 0)
                         continue;
 
                 if (!GREEDY_REALLOC(ni, allocated, nr+1)) {
index a91db5df5f1f0adbf8bbc406d16a79f7c9128015..9c6a5d29f6e0f5f67d15e06c3d6901784ed87ae7 100644 (file)
@@ -167,14 +167,15 @@ int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifn
         return 0;
 }
 
-int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret) {
+int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name) {
+        _cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL;
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
-        int r;
+        int r, ret;
 
-        assert(rtnl);
         assert(name);
-        assert(ret);
 
+        if (!rtnl)
+                rtnl = &our_rtnl;
         if (!*rtnl) {
                 r = sd_netlink_open(rtnl);
                 if (r < 0)
@@ -190,10 +191,16 @@ int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int
                 return r;
 
         r = sd_netlink_call(*rtnl, message, 0, &reply);
+        if (r == -EINVAL)
+                return -ENODEV; /* The device doesn't exist */
         if (r < 0)
                 return r;
 
-        return sd_rtnl_message_link_get_ifindex(reply, ret);
+        r = sd_rtnl_message_link_get_ifindex(reply, &ret);
+        if (r < 0)
+                return r;
+        assert(ret > 0);
+        return ret;
 }
 
 int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) {
index 7b007a61c23ac04ec97f201374f2a71183c4c862..55bc12712a0c47eaf5382b098a55bc46c8db70d4 100644 (file)
@@ -51,7 +51,7 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
 int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu);
 int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
 int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char * const *alternative_names);
-int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret);
+int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name);
 
 int rtnl_log_parse_error(int r);
 int rtnl_log_create_error(int r);
index dc5ccb793bc9d7b36dc0661553b1263403c42910..b9b618e58501c7b03a4836f20b2f68f1988537d2 100644 (file)
@@ -276,7 +276,6 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
         _cleanup_free_ int *ifis = NULL;
         _cleanup_free_ char *s = NULL;
         size_t allocated = 0, c = 0;
-        const char *x;
         int r;
 
         assert_return(ifindex > 0, -EINVAL);
@@ -289,7 +288,7 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
         if (r < 0)
                 return r;
 
-        for (x = s;;) {
+        for (const char *x = s;;) {
                 _cleanup_free_ char *word = NULL;
 
                 r = extract_first_word(&x, &word, NULL, 0);
@@ -298,14 +297,12 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
                 if (r == 0)
                         break;
 
-                r = parse_ifindex(word, &ifindex);
-                if (r < 0)
-                        return r;
-
                 if (!GREEDY_REALLOC(ifis, allocated, c + 2))
                         return -ENOMEM;
 
-                ifis[c++] = ifindex;
+                r = ifis[c++] = parse_ifindex(word);
+                if (r < 0)
+                        return r;
         }
 
         if (ifis)
index efe327f381ddd1f3fa8b2831fe545ca9cfb95ba8..8154c42ed774b8ea46fc1dfcb57711f61f1b9e9c 100644 (file)
@@ -294,12 +294,11 @@ int machine_load(Machine *m) {
         if (netif) {
                 size_t allocated = 0, nr = 0;
                 const char *p;
-                int *ni = NULL;
+                _cleanup_free_ int *ni = NULL;
 
                 p = netif;
                 for (;;) {
                         _cleanup_free_ char *word = NULL;
-                        int ifi;
 
                         r = extract_first_word(&p, &word, NULL, 0);
                         if (r == 0)
@@ -311,19 +310,18 @@ int machine_load(Machine *m) {
                                 break;
                         }
 
-                        if (parse_ifindex(word, &ifi) < 0)
+                        r = parse_ifindex(word);
+                        if (r < 0)
                                 continue;
 
-                        if (!GREEDY_REALLOC(ni, allocated, nr+1)) {
-                                free(ni);
+                        if (!GREEDY_REALLOC(ni, allocated, nr + 1))
                                 return log_oom();
-                        }
 
-                        ni[nr++] = ifi;
+                        ni[nr++] = r;
                 }
 
                 free(m->netif);
-                m->netif = ni;
+                m->netif = TAKE_PTR(ni);
                 m->n_netif = nr;
         }
 
index 4b4437f91d3bd9e72a3ef587cd0142828e271f44..95d88bc543d1461cc0de5c3ffb7585506e56e7fe 100644 (file)
@@ -591,11 +591,9 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
                 printf("\t    Root: %s\n", i->root_directory);
 
         if (i->n_netif > 0) {
-                size_t c;
-
                 fputs("\t   Iface:", stdout);
 
-                for (c = 0; c < i->n_netif; c++) {
+                for (size_t c = 0; c < i->n_netif; c++) {
                         char name[IF_NAMESIZE+1];
 
                         if (format_ifname(i->netif[c], name)) {
@@ -737,7 +735,7 @@ static int show_machine(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         bool properties, new_line = false;
         sd_bus *bus = userdata;
-        int r = 0, i;
+        int r = 0;
 
         assert(bus);
 
@@ -754,7 +752,7 @@ static int show_machine(int argc, char *argv[], void *userdata) {
                         return r;
         }
 
-        for (i = 1; i < argc; i++) {
+        for (int i = 1; i < argc; i++) {
                 const char *path = NULL;
 
                 r = sd_bus_call_method(bus,
@@ -1075,7 +1073,7 @@ static int show_image(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         bool properties, new_line = false;
         sd_bus *bus = userdata;
-        int r = 0, i;
+        int r = 0;
 
         assert(bus);
 
@@ -1096,7 +1094,7 @@ static int show_image(int argc, char *argv[], void *userdata) {
                         return r;
         }
 
-        for (i = 1; i < argc; i++) {
+        for (int i = 1; i < argc; i++) {
                 const char *path = NULL;
 
                 r = sd_bus_call_method(
@@ -1127,7 +1125,7 @@ static int show_image(int argc, char *argv[], void *userdata) {
 static int kill_machine(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         sd_bus *bus = userdata;
-        int r, i;
+        int r;
 
         assert(bus);
 
@@ -1136,7 +1134,7 @@ static int kill_machine(int argc, char *argv[], void *userdata) {
         if (!arg_kill_who)
                 arg_kill_who = "all";
 
-        for (i = 1; i < argc; i++) {
+        for (int i = 1; i < argc; i++) {
                 r = sd_bus_call_method(
                                 bus,
                                 "org.freedesktop.machine1",
@@ -1170,13 +1168,13 @@ static int poweroff_machine(int argc, char *argv[], void *userdata) {
 static int terminate_machine(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         sd_bus *bus = userdata;
-        int r, i;
+        int r;
 
         assert(bus);
 
         polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
-        for (i = 1; i < argc; i++) {
+        for (int i = 1; i < argc; i++) {
                 r = sd_bus_call_method(
                                 bus,
                                 "org.freedesktop.machine1",
@@ -1541,13 +1539,13 @@ static int shell_machine(int argc, char *argv[], void *userdata) {
 
 static int remove_image(int argc, char *argv[], void *userdata) {
         sd_bus *bus = userdata;
-        int r, i;
+        int r;
 
         assert(bus);
 
         polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
-        for (i = 1; i < argc; i++) {
+        for (int i = 1; i < argc; i++) {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
 
@@ -1709,7 +1707,7 @@ static int start_machine(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
         sd_bus *bus = userdata;
-        int r, i;
+        int r;
 
         assert(bus);
 
@@ -1720,7 +1718,7 @@ static int start_machine(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return log_oom();
 
-        for (i = 1; i < argc; i++) {
+        for (int i = 1; i < argc; i++) {
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
                 _cleanup_free_ char *unit = NULL;
                 const char *object;
@@ -1772,7 +1770,7 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
         size_t n_changes = 0;
         const char *method = NULL;
         sd_bus *bus = userdata;
-        int r, i;
+        int r;
 
         assert(bus);
 
@@ -1794,7 +1792,7 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return bus_log_create_error(r);
 
-        for (i = 1; i < argc; i++) {
+        for (int i = 1; i < argc; i++) {
                 _cleanup_free_ char *unit = NULL;
 
                 r = make_service_name(argv[i], &unit);
@@ -2435,7 +2433,7 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_free_ TransferInfo *transfers = NULL;
-        size_t n_transfers = 0, n_allocated = 0, j;
+        size_t n_transfers = 0, n_allocated = 0;
         const char *type, *remote, *local;
         sd_bus *bus = userdata;
         uint32_t id, max_id = 0;
@@ -2505,7 +2503,7 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
                        (int) max_local, "LOCAL",
                        (int) max_remote, "REMOTE");
 
-        for (j = 0; j < n_transfers; j++)
+        for (size_t j = 0; j < n_transfers; j++)
 
                 if (transfers[j].progress < 0)
                         printf("%*" PRIu32 " %*s %-*s %-*s %-*s\n",
@@ -2535,13 +2533,13 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
 static int cancel_transfer(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         sd_bus *bus = userdata;
-        int r, i;
+        int r;
 
         assert(bus);
 
         polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
-        for (i = 1; i < argc; i++) {
+        for (int i = 1; i < argc; i++) {
                 uint32_t id;
 
                 r = safe_atou32(argv[i], &id);
@@ -3031,7 +3029,6 @@ static int parse_argv(int argc, char *argv[]) {
 done:
         if (shell >= 0) {
                 char *t;
-                int i;
 
                 /* We found the "shell" verb while processing the argument list. Since we turned off reordering of the
                  * argument list initially let's readjust it now, and move the "shell" verb to the back. */
@@ -3039,7 +3036,7 @@ done:
                 optind -= 1; /* place the option index where the "shell" verb will be placed */
 
                 t = argv[shell];
-                for (i = shell; i < optind; i++)
+                for (int i = shell; i < optind; i++)
                         argv[i] = argv[i+1];
                 argv[optind] = t;
         }
index 9a86dc6e8d29390edb73134b6914345c9e3a2a1c..631b12cf51a9d1833999d2914f48d766fb781fdb 100644 (file)
@@ -38,6 +38,7 @@
 #include "parse-util.h"
 #include "pretty-print.h"
 #include "set.h"
+#include "socket-netlink.h"
 #include "socket-util.h"
 #include "sort-util.h"
 #include "sparse-endian.h"
@@ -1904,12 +1905,9 @@ static int link_delete(int argc, char *argv[], void *userdata) {
                 return log_oom();
 
         for (i = 1; i < argc; i++) {
-                r = parse_ifindex_or_ifname(argv[i], &index);
-                if (r < 0) {
-                        r = rtnl_resolve_link_alternative_name(&rtnl, argv[i], &index);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to resolve interface %s", argv[i]);
-                }
+                index = resolve_interface_or_warn(&rtnl, argv[i]);
+                if (index < 0)
+                        return index;
 
                 r = set_put(indexes, INT_TO_PTR(index));
                 if (r < 0)
@@ -1960,12 +1958,9 @@ static int link_renew(int argc, char *argv[], void *userdata) {
                 return log_error_errno(r, "Failed to connect system bus: %m");
 
         for (i = 1; i < argc; i++) {
-                r = parse_ifindex_or_ifname(argv[i], &index);
-                if (r < 0) {
-                        r = rtnl_resolve_link_alternative_name(&rtnl, argv[i], &index);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to resolve interface %s", argv[i]);
-                }
+                index = resolve_interface_or_warn(&rtnl, argv[i]);
+                if (index < 0)
+                        return index;
 
                 r = link_renew_one(bus, index, argv[i]);
                 if (r < 0 && k >= 0)
@@ -2015,12 +2010,9 @@ static int verb_reconfigure(int argc, char *argv[], void *userdata) {
                 return log_oom();
 
         for (i = 1; i < argc; i++) {
-                r = parse_ifindex_or_ifname(argv[i], &index);
-                if (r < 0) {
-                        r = rtnl_resolve_link_alternative_name(&rtnl, argv[i], &index);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to resolve interface %s", argv[i]);
-                }
+                index = resolve_interface_or_warn(&rtnl, argv[i]);
+                if (index < 0)
+                        return index;
 
                 r = set_put(indexes, INT_TO_PTR(index));
                 if (r < 0)
@@ -2039,7 +2031,8 @@ static int verb_reconfigure(int argc, char *argv[], void *userdata) {
                 if (r < 0) {
                         char ifname[IF_NAMESIZE + 1];
 
-                        return log_error_errno(r, "Failed to reconfigure network interface %s: %m", format_ifname_full(index, ifname, FORMAT_IFNAME_IFINDEX));
+                        return log_error_errno(r, "Failed to reconfigure network interface %s: %m",
+                                               format_ifname_full(index, ifname, FORMAT_IFNAME_IFINDEX));
                 }
         }
 
index 356ceaf0630856639d2586441f83bf16ca4f07a9..8f3b2e92f8fff739fb6ae14b2054bea2ed754b74 100644 (file)
@@ -715,8 +715,8 @@ int link_object_find(sd_bus *bus, const char *path, const char *interface, void
         if (r <= 0)
                 return 0;
 
-        r = parse_ifindex(identifier, &ifindex);
-        if (r < 0)
+        ifindex = parse_ifindex(identifier);
+        if (ifindex < 0)
                 return 0;
 
         r = link_get(m, ifindex, &link);
index 8bcce06b854cdbf109ef713b68c9c3c44d2e47d9..660c2847eb385824fb5cc1e7ca47877de807d480 100644 (file)
@@ -7,12 +7,12 @@
 #include "alloc-util.h"
 #include "bus-common-errors.h"
 #include "bus-util.h"
-#include "netlink-util.h"
 #include "networkd-link-bus.h"
 #include "networkd-link.h"
 #include "networkd-manager-bus.h"
 #include "networkd-manager.h"
 #include "path-util.h"
+#include "socket-netlink.h"
 #include "strv.h"
 #include "user-util.h"
 
@@ -66,12 +66,9 @@ static int method_get_link_by_name(sd_bus_message *message, void *userdata, sd_b
         if (r < 0)
                 return r;
 
-        index = if_nametoindex(name);
-        if (index <= 0) {
-                r = rtnl_resolve_link_alternative_name(&manager->rtnl, name, &index);
-                if (r < 0)
-                        return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %s not known", name);
-        }
+        index = resolve_ifname(&manager->rtnl, name);
+        if (index < 0)
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %s cannot be resolved", name);
 
         link = hashmap_get(manager->links, INT_TO_PTR(index));
         if (!link)
index f94bee6d8b0d1b4859a16494291f0f16d2f02a46..2df8b864e881e8da1c8b92bd4d407abf9a387b13 100644 (file)
@@ -12,6 +12,7 @@
 #include "networkd-route.h"
 #include "parse-util.h"
 #include "set.h"
+#include "socket-netlink.h"
 #include "string-table.h"
 #include "string-util.h"
 #include "strxcpyx.h"
@@ -1646,12 +1647,13 @@ int config_parse_multipath_route(
         m->gateway.family = family;
 
         if (dev) {
-                r = parse_ifindex_or_ifname(dev, &m->ifindex);
+                r = resolve_interface(NULL, dev);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r,
                                    "Invalid interface name or index, ignoring assignment: %s", dev);
                         return 0;
                 }
+                m->ifindex = r;
         }
 
         if (!isempty(p)) {
index 0b550fd12f428f41f8fd17f83665907b2bbd52cf..a9aff9a67ffb6dde9502cebf0b4fed47573b6a18 100644 (file)
@@ -18,6 +18,7 @@
 #include "nspawn-network.h"
 #include "parse-util.h"
 #include "siphash24.h"
+#include "socket-netlink.h"
 #include "socket-util.h"
 #include "stat-util.h"
 #include "string-util.h"
@@ -280,7 +281,8 @@ int setup_veth(const char *machine_name,
         if (r < 0)
                 return r;
 
-        u = if_nametoindex(n);
+        u = if_nametoindex(n); /* We don't need to use resolve_ifname() here because the
+                                * name we assigned is always the main name. */
         if (u == 0)
                 return log_error_errno(errno, "Failed to resolve interface %s: %m", n);
 
@@ -337,9 +339,9 @@ static int join_bridge(sd_netlink *rtnl, const char *veth_name, const char *brid
         assert(veth_name);
         assert(bridge_name);
 
-        r = parse_ifindex_or_ifname(bridge_name, &bridge_ifi);
-        if (r < 0)
-                return r;
+        bridge_ifi = resolve_interface(&rtnl, bridge_name);
+        if (bridge_ifi < 0)
+                return bridge_ifi;
 
         r = sd_rtnl_message_new_link(rtnl, &m, RTM_SETLINK, 0);
         if (r < 0)
@@ -472,16 +474,6 @@ int remove_bridge(const char *bridge_name) {
         return remove_one_link(rtnl, bridge_name);
 }
 
-static int parse_interface(const char *name) {
-        int ifi, r;
-
-        r = parse_ifindex_or_ifname(name, &ifi);
-        if (r < 0)
-                return log_error_errno(r, "Failed to resolve interface %s: %m", name);
-
-        return ifi;
-}
-
 int test_network_interface_initialized(const char *name) {
         _cleanup_(sd_device_unrefp) sd_device *d = NULL;
         int ifi, r;
@@ -492,7 +484,7 @@ int test_network_interface_initialized(const char *name) {
 
         /* udev should be around. */
 
-        ifi = parse_interface(name);
+        ifi = resolve_interface_or_warn(NULL, name);
         if (ifi < 0)
                 return ifi;
 
@@ -532,7 +524,7 @@ int move_network_interfaces(int netns_fd, char **ifaces) {
                 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
                 int ifi;
 
-                ifi = parse_interface(*i);
+                ifi = resolve_interface_or_warn(&rtnl, *i);
                 if (ifi < 0)
                         return ifi;
 
@@ -571,7 +563,7 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **ifaces) {
                 struct ether_addr mac;
                 int ifi;
 
-                ifi = parse_interface(*i);
+                ifi = resolve_interface_or_warn(&rtnl, *i);
                 if (ifi < 0)
                         return ifi;
 
@@ -657,7 +649,7 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces) {
                 _cleanup_free_ char *n = NULL, *a = NULL;
                 int ifi;
 
-                ifi = parse_interface(*i);
+                ifi = resolve_interface_or_warn(&rtnl, *i);
                 if (ifi < 0)
                         return ifi;
 
index 0a96a18b3836ae1ad53c89f387f43845baaaef81..df40349e6622d312bbb033f5749cf1441b147978 100644 (file)
@@ -16,7 +16,6 @@
 #include "escape.h"
 #include "format-util.h"
 #include "gcrypt-util.h"
-#include "in-addr-util.h"
 #include "main-func.h"
 #include "missing_network.h"
 #include "netlink-util.h"
@@ -27,6 +26,8 @@
 #include "resolvectl.h"
 #include "resolved-def.h"
 #include "resolved-dns-packet.h"
+#include "socket-netlink.h"
+#include "stdio-util.h"
 #include "string-table.h"
 #include "strv.h"
 #include "terminal-util.h"
@@ -80,7 +81,7 @@ typedef enum StatusMode {
 int ifname_mangle(const char *s) {
         _cleanup_free_ char *iface = NULL;
         const char *dot;
-        int ifi, r;
+        int ifi;
 
         assert(s);
 
@@ -94,14 +95,14 @@ int ifname_mangle(const char *s) {
         if (!iface)
                 return log_oom();
 
-        r = parse_ifindex_or_ifname(iface, &ifi);
-        if (r < 0) {
-                if (r == -ENODEV && arg_ifindex_permissive) {
+        ifi = resolve_interface(NULL, iface);
+        if (ifi < 0) {
+                if (ifi == -ENODEV && arg_ifindex_permissive) {
                         log_debug("Interface '%s' not found, but -f specified, ignoring.", iface);
                         return 0; /* done */
                 }
 
-                return log_error_errno(r, "Unknown interface '%s': %m", iface);
+                return log_error_errno(ifi, "Failed to resolve interface \"%s\": %m", iface);
         }
 
         if (arg_ifindex > 0 && arg_ifindex != ifi)
@@ -1382,8 +1383,8 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
         _cleanup_(link_info_clear) struct link_info link_info = {};
-        _cleanup_free_ char *ifi = NULL, *p = NULL;
-        char ifname[IF_NAMESIZE + 1] = "";
+        _cleanup_free_ char *p = NULL;
+        char ifi[DECIMAL_STR_MAX(int)], ifname[IF_NAMESIZE + 1] = "";
         char **i;
         int r;
 
@@ -1397,9 +1398,7 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode
                 name = ifname;
         }
 
-        if (asprintf(&ifi, "%i", ifindex) < 0)
-                return log_oom();
-
+        xsprintf(ifi, "%i", ifindex);
         r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifi, &p);
         if (r < 0)
                 return log_oom();
@@ -1819,18 +1818,19 @@ static int status_all(sd_bus *bus, StatusMode mode) {
 
 static int verb_status(int argc, char **argv, void *userdata) {
         sd_bus *bus = userdata;
-        int q, r = 0;
+        _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+        int r = 0;
 
         if (argc > 1) {
                 char **ifname;
                 bool empty_line = false;
 
                 STRV_FOREACH(ifname, argv + 1) {
-                        int ifindex;
+                        int ifindex, q;
 
-                        q = parse_ifindex_or_ifname(*ifname, &ifindex);
-                        if (q < 0) {
-                                log_error_errno(q, "Unknown interface '%s', ignoring: %m", *ifname);
+                        ifindex = resolve_interface(&rtnl, *ifname);
+                        if (ifindex < 0) {
+                                log_warning_errno(ifindex, "Failed to resolve interface \"%s\", ignoring: %m", *ifname);
                                 continue;
                         }
 
index 2c1aba911ac6e24aad1c98ef7ce5c788954ca092..ff6acb2eac1fac0b14d54dde7b35f7a8fad07797 100644 (file)
@@ -12,6 +12,7 @@
 #include "resolved-dnssd-bus.h"
 #include "resolved-dnssd.h"
 #include "resolved-link-bus.h"
+#include "socket-netlink.h"
 #include "stdio-util.h"
 #include "strv.h"
 #include "user-util.h"
index 6a23d2bb8e8d40e92351eb8f373249ea26eeaa07..e6bf20db54f54210e5e1649dc38b85ea657d18eb 100644 (file)
@@ -9,6 +9,7 @@
 #include "hostname-util.h"
 #include "resolved-dns-synthesize.h"
 #include "resolved-etc-hosts.h"
+#include "socket-netlink.h"
 #include "string-util.h"
 #include "strv.h"
 #include "time-util.h"
index dae8435b45bec93d5e784ba7142e06c51204cfc8..a8480f190a6f96b04b15e55f4c85acd4573477a3 100644 (file)
@@ -712,9 +712,8 @@ const sd_bus_vtable link_vtable[] = {
 int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
         _cleanup_free_ char *e = NULL;
         Manager *m = userdata;
-        int ifindex;
         Link *link;
-        int r;
+        int ifindex, r;
 
         assert(bus);
         assert(path);
@@ -726,8 +725,8 @@ int link_object_find(sd_bus *bus, const char *path, const char *interface, void
         if (r <= 0)
                 return 0;
 
-        r = parse_ifindex(e, &ifindex);
-        if (r < 0)
+        ifindex = parse_ifindex(e);
+        if (ifindex < 0)
                 return 0;
 
         link = hashmap_get(m->links, INT_TO_PTR(ifindex));
index 95f698ab06d6498c7365cbf35043495207a8bf45..af91a8ec1a5e7d0379b432652c4482c43aa3cf41 100644 (file)
@@ -1466,7 +1466,6 @@ void manager_reset_server_features(Manager *m) {
 void manager_cleanup_saved_user(Manager *m) {
         _cleanup_closedir_ DIR *d = NULL;
         struct dirent *de;
-        int r;
 
         assert(m);
 
@@ -1494,8 +1493,8 @@ void manager_cleanup_saved_user(Manager *m) {
                 if (dot_or_dot_dot(de->d_name))
                         continue;
 
-                r = parse_ifindex(de->d_name, &ifindex);
-                if (r < 0) /* Probably some temporary file from a previous run. Delete it */
+                ifindex = parse_ifindex(de->d_name);
+                if (ifindex < 0) /* Probably some temporary file from a previous run. Delete it */
                         goto rm;
 
                 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
index 2f18f8c19d682c6062bb24e2c77807cae67a03b6..ac8df6351355310bc87a69584afd5fffbfbfffd1 100644 (file)
@@ -1,9 +1,9 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "alloc-util.h"
-#include "in-addr-util.h"
 #include "macro.h"
 #include "resolved-util.h"
+#include "socket-netlink.h"
 
 int in_addr_ifindex_name_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex, char **server_name) {
         _cleanup_free_ char *buf = NULL, *name = NULL;
index 3b53ce1a757ab5fbcc1e86fe22e7e00ca280544c..08aa480b6c8b551d465b819cdf91018a7735fc97 100644 (file)
@@ -165,6 +165,8 @@ shared_sources = files('''
         serialize.h
         sleep-config.c
         sleep-config.h
+        socket-netlink.c
+        socket-netlink.h
         spawn-ask-password-agent.c
         spawn-ask-password-agent.h
         spawn-polkit-agent.c
diff --git a/src/shared/socket-netlink.c b/src/shared/socket-netlink.c
new file mode 100644 (file)
index 0000000..5177137
--- /dev/null
@@ -0,0 +1,363 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <net/if.h>
+#include <string.h>
+
+#include "alloc-util.h"
+#include "errno-util.h"
+#include "extract-word.h"
+#include "log.h"
+#include "memory-util.h"
+#include "netlink-util.h"
+#include "parse-util.h"
+#include "socket-netlink.h"
+#include "socket-util.h"
+#include "string-util.h"
+
+int resolve_ifname(sd_netlink **rtnl, const char *name) {
+        int r;
+
+        /* Like if_nametoindex, but resolves "alternative names" too. */
+
+        assert(name);
+
+        r = if_nametoindex(name);
+        if (r > 0)
+                return r;
+
+        return rtnl_resolve_link_alternative_name(rtnl, name);
+}
+
+int resolve_interface(sd_netlink **rtnl, const char *name) {
+        int r;
+
+        /* Like resolve_ifname, but resolves interface numbers too. */
+
+        assert(name);
+
+        r = parse_ifindex(name);
+        if (r > 0)
+                return r;
+        assert(r < 0);
+
+        return resolve_ifname(rtnl, name);
+}
+
+int resolve_interface_or_warn(sd_netlink **rtnl, const char *name) {
+        int r;
+
+        r = resolve_interface(rtnl, name);
+        if (r < 0)
+                return log_error_errno(r, "Failed to resolve interface \"%s\": %m", name);
+        return r;
+}
+
+int socket_address_parse(SocketAddress *a, const char *s) {
+        _cleanup_free_ char *n = NULL;
+        char *e;
+        int r;
+
+        assert(a);
+        assert(s);
+
+        *a = (SocketAddress) {
+                .type = SOCK_STREAM,
+        };
+
+        if (*s == '[') {
+                uint16_t port;
+
+                /* IPv6 in [x:.....:z]:p notation */
+
+                e = strchr(s+1, ']');
+                if (!e)
+                        return -EINVAL;
+
+                n = strndup(s+1, e-s-1);
+                if (!n)
+                        return -ENOMEM;
+
+                errno = 0;
+                if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
+                        return errno_or_else(EINVAL);
+
+                e++;
+                if (*e != ':')
+                        return -EINVAL;
+
+                e++;
+                r = parse_ip_port(e, &port);
+                if (r < 0)
+                        return r;
+
+                a->sockaddr.in6.sin6_family = AF_INET6;
+                a->sockaddr.in6.sin6_port = htobe16(port);
+                a->size = sizeof(struct sockaddr_in6);
+
+        } else if (*s == '/') {
+                /* AF_UNIX socket */
+
+                size_t l;
+
+                l = strlen(s);
+                if (l >= sizeof(a->sockaddr.un.sun_path)) /* Note that we refuse non-NUL-terminated sockets when
+                                                           * parsing (the kernel itself is less strict here in what it
+                                                           * accepts) */
+                        return -EINVAL;
+
+                a->sockaddr.un.sun_family = AF_UNIX;
+                memcpy(a->sockaddr.un.sun_path, s, l);
+                a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
+
+        } else if (*s == '@') {
+                /* Abstract AF_UNIX socket */
+                size_t l;
+
+                l = strlen(s+1);
+                if (l >= sizeof(a->sockaddr.un.sun_path) - 1) /* Note that we refuse non-NUL-terminated sockets here
+                                                               * when parsing, even though abstract namespace sockets
+                                                               * explicitly allow embedded NUL bytes and don't consider
+                                                               * them special. But it's simply annoying to debug such
+                                                               * sockets. */
+                        return -EINVAL;
+
+                a->sockaddr.un.sun_family = AF_UNIX;
+                memcpy(a->sockaddr.un.sun_path+1, s+1, l);
+                a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
+
+        } else if (startswith(s, "vsock:")) {
+                /* AF_VSOCK socket in vsock:cid:port notation */
+                const char *cid_start = s + STRLEN("vsock:");
+                unsigned port;
+
+                e = strchr(cid_start, ':');
+                if (!e)
+                        return -EINVAL;
+
+                r = safe_atou(e+1, &port);
+                if (r < 0)
+                        return r;
+
+                n = strndup(cid_start, e - cid_start);
+                if (!n)
+                        return -ENOMEM;
+
+                if (!isempty(n)) {
+                        r = safe_atou(n, &a->sockaddr.vm.svm_cid);
+                        if (r < 0)
+                                return r;
+                } else
+                        a->sockaddr.vm.svm_cid = VMADDR_CID_ANY;
+
+                a->sockaddr.vm.svm_family = AF_VSOCK;
+                a->sockaddr.vm.svm_port = port;
+                a->size = sizeof(struct sockaddr_vm);
+
+        } else {
+                uint16_t port;
+
+                e = strchr(s, ':');
+                if (e) {
+                        r = parse_ip_port(e + 1, &port);
+                        if (r < 0)
+                                return r;
+
+                        n = strndup(s, e-s);
+                        if (!n)
+                                return -ENOMEM;
+
+                        /* IPv4 in w.x.y.z:p notation? */
+                        r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
+                        if (r < 0)
+                                return -errno;
+
+                        if (r > 0) {
+                                /* Gotcha, it's a traditional IPv4 address */
+                                a->sockaddr.in.sin_family = AF_INET;
+                                a->sockaddr.in.sin_port = htobe16(port);
+                                a->size = sizeof(struct sockaddr_in);
+                        } else {
+                                int idx;
+
+                                /* Uh, our last resort, an interface name */
+                                idx = resolve_ifname(NULL, n);
+                                if (idx < 0)
+                                        return idx;
+
+                                a->sockaddr.in6.sin6_family = AF_INET6;
+                                a->sockaddr.in6.sin6_port = htobe16(port);
+                                a->sockaddr.in6.sin6_scope_id = idx;
+                                a->sockaddr.in6.sin6_addr = in6addr_any;
+                                a->size = sizeof(struct sockaddr_in6);
+                        }
+                } else {
+
+                        /* Just a port */
+                        r = parse_ip_port(s, &port);
+                        if (r < 0)
+                                return r;
+
+                        if (socket_ipv6_is_supported()) {
+                                a->sockaddr.in6.sin6_family = AF_INET6;
+                                a->sockaddr.in6.sin6_port = htobe16(port);
+                                a->sockaddr.in6.sin6_addr = in6addr_any;
+                                a->size = sizeof(struct sockaddr_in6);
+                        } else {
+                                a->sockaddr.in.sin_family = AF_INET;
+                                a->sockaddr.in.sin_port = htobe16(port);
+                                a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
+                                a->size = sizeof(struct sockaddr_in);
+                        }
+                }
+        }
+
+        return 0;
+}
+
+int socket_address_parse_and_warn(SocketAddress *a, const char *s) {
+        SocketAddress b;
+        int r;
+
+        /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
+
+        r = socket_address_parse(&b, s);
+        if (r < 0)
+                return r;
+
+        if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) {
+                log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
+                return -EAFNOSUPPORT;
+        }
+
+        *a = b;
+        return 0;
+}
+
+int socket_address_parse_netlink(SocketAddress *a, const char *s) {
+        _cleanup_free_ char *word = NULL;
+        unsigned group = 0;
+        int family, r;
+
+        assert(a);
+        assert(s);
+
+        zero(*a);
+        a->type = SOCK_RAW;
+
+        r = extract_first_word(&s, &word, NULL, 0);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return -EINVAL;
+
+        family = netlink_family_from_string(word);
+        if (family < 0)
+                return -EINVAL;
+
+        if (!isempty(s)) {
+                r = safe_atou(s, &group);
+                if (r < 0)
+                        return r;
+        }
+
+        a->sockaddr.nl.nl_family = AF_NETLINK;
+        a->sockaddr.nl.nl_groups = group;
+
+        a->type = SOCK_RAW;
+        a->size = sizeof(struct sockaddr_nl);
+        a->protocol = family;
+
+        return 0;
+}
+
+bool socket_address_is(const SocketAddress *a, const char *s, int type) {
+        struct SocketAddress b;
+
+        assert(a);
+        assert(s);
+
+        if (socket_address_parse(&b, s) < 0)
+                return false;
+
+        b.type = type;
+
+        return socket_address_equal(a, &b);
+}
+
+bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
+        struct SocketAddress b;
+
+        assert(a);
+        assert(s);
+
+        if (socket_address_parse_netlink(&b, s) < 0)
+                return false;
+
+        return socket_address_equal(a, &b);
+}
+
+int make_socket_fd(int log_level, const char* address, int type, int flags) {
+        SocketAddress a;
+        int fd, r;
+
+        r = socket_address_parse(&a, address);
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse socket address \"%s\": %m", address);
+
+        a.type = type;
+
+        fd = socket_address_listen(&a, type | flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT,
+                                   NULL, false, false, false, 0755, 0644, NULL);
+        if (fd < 0 || log_get_max_level() >= log_level) {
+                _cleanup_free_ char *p = NULL;
+
+                r = socket_address_print(&a, &p);
+                if (r < 0)
+                        return log_error_errno(r, "socket_address_print(): %m");
+
+                if (fd < 0)
+                        log_error_errno(fd, "Failed to listen on %s: %m", p);
+                else
+                        log_full(log_level, "Listening on %s", p);
+        }
+
+        return fd;
+}
+
+int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret_addr, int *ret_ifindex) {
+        _cleanup_free_ char *buf = NULL;
+        const char *suffix;
+        int r, ifindex = 0;
+
+        assert(s);
+        assert(family);
+        assert(ret_addr);
+
+        /* Similar to in_addr_from_string_auto() but also parses an optionally appended IPv6 zone suffix ("scope id")
+         * if one is found. */
+
+        suffix = strchr(s, '%');
+        if (suffix) {
+                if (ret_ifindex) {
+                        /* If we shall return the interface index, try to parse it */
+                        ifindex = resolve_interface(NULL, suffix + 1);
+                        if (ifindex < 0)
+                                return ifindex;
+                }
+
+                s = buf = strndup(s, suffix - s);
+                if (!buf)
+                        return -ENOMEM;
+        }
+
+        r = in_addr_from_string_auto(s, family, ret_addr);
+        if (r < 0)
+                return r;
+
+        if (ret_ifindex)
+                *ret_ifindex = ifindex;
+
+        return r;
+}
diff --git a/src/shared/socket-netlink.h b/src/shared/socket-netlink.h
new file mode 100644 (file)
index 0000000..fa58409
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include "sd-netlink.h"
+
+#include "in-addr-util.h"
+#include "macro.h"
+#include "socket-util.h"
+
+int resolve_ifname(sd_netlink **rtnl, const char *name);
+int resolve_interface(sd_netlink **rtnl, const char *name);
+int resolve_interface_or_warn(sd_netlink **rtnl, const char *name);
+
+int make_socket_fd(int log_level, const char* address, int type, int flags);
+
+int socket_address_parse(SocketAddress *a, const char *s);
+int socket_address_parse_and_warn(SocketAddress *a, const char *s);
+int socket_address_parse_netlink(SocketAddress *a, const char *s);
+
+bool socket_address_is(const SocketAddress *a, const char *s, int type);
+bool socket_address_is_netlink(const SocketAddress *a, const char *s);
+
+int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex);
index 7e5a61a11e24fbc8d4608ca03e23bdde8d8a641d..5df1366561d05e3ef8d803f0985a3cd69d0bf092 100644 (file)
@@ -362,6 +362,10 @@ tests += [
          [],
          []],
 
+        [['src/test/test-socket-netlink.c'],
+         [],
+         []],
+
         [['src/test/test-in-addr-util.c'],
          [],
          []],
diff --git a/src/test/test-socket-netlink.c b/src/test/test-socket-netlink.c
new file mode 100644 (file)
index 0000000..0a2007f
--- /dev/null
@@ -0,0 +1,227 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "alloc-util.h"
+#include "tests.h"
+#include "socket-netlink.h"
+#include "string-util.h"
+
+static void test_socket_address_parse_one(const char *in, int ret, int family, const char *expected) {
+        SocketAddress a;
+        _cleanup_free_ char *out = NULL;
+        int r;
+
+        r = socket_address_parse(&a, in);
+        if (r >= 0)
+                assert_se(socket_address_print(&a, &out) >= 0);
+
+        log_info("\"%s\" → %s → \"%s\" (expect \"%s\")", in,
+                 r >= 0 ? "✓" : "✗", empty_to_dash(out), r >= 0 ? expected ?: in : "-");
+        assert_se(r == ret);
+        if (r >= 0) {
+                assert_se(a.sockaddr.sa.sa_family == family);
+                assert_se(streq(out, expected ?: in));
+        }
+}
+
+static void test_socket_address_parse(void) {
+        log_info("/* %s */", __func__);
+
+        test_socket_address_parse_one("junk", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("192.168.1.1", -EINVAL, 0, NULL);
+        test_socket_address_parse_one(".168.1.1", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("989.168.1.1", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("192.168.1.1:65536", -ERANGE, 0, NULL);
+        test_socket_address_parse_one("192.168.1.1:0", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("0", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("65536", -ERANGE, 0, NULL);
+
+        const int default_family = socket_ipv6_is_supported() ? AF_INET6 : AF_INET;
+
+        test_socket_address_parse_one("65535", 0, default_family, "[::]:65535");
+
+        /* The checks below will pass even if ipv6 is disabled in
+         * kernel. The underlying glibc's inet_pton() is just a string
+         * parser and doesn't make any syscalls. */
+
+        test_socket_address_parse_one("[::1]", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("[::1]8888", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("::1", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("[::1]:0", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("[::1]:65536", -ERANGE, 0, NULL);
+        test_socket_address_parse_one("[a:b:1]:8888", -EINVAL, 0, NULL);
+
+        test_socket_address_parse_one("8888", 0, default_family, "[::]:8888");
+        test_socket_address_parse_one("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888", 0, AF_INET6,
+                                      "[2001:db8:0:85a3::ac1f:8001]:8888");
+        test_socket_address_parse_one("[::1]:8888", 0, AF_INET6, NULL);
+        test_socket_address_parse_one("192.168.1.254:8888", 0, AF_INET, NULL);
+        test_socket_address_parse_one("/foo/bar", 0, AF_UNIX, NULL);
+        test_socket_address_parse_one("/", 0, AF_UNIX, NULL);
+        test_socket_address_parse_one("@abstract", 0, AF_UNIX, NULL);
+
+        {
+                char aaa[SUN_PATH_LEN + 1] = "@";
+
+                memset(aaa + 1, 'a', SUN_PATH_LEN - 1);
+                char_array_0(aaa);
+
+                test_socket_address_parse_one(aaa, -EINVAL, 0, NULL);
+
+                aaa[SUN_PATH_LEN - 1] = '\0';
+                test_socket_address_parse_one(aaa, 0, AF_UNIX, NULL);
+        }
+
+        test_socket_address_parse_one("vsock:2:1234", 0, AF_VSOCK, NULL);
+        test_socket_address_parse_one("vsock::1234", 0, AF_VSOCK, NULL);
+        test_socket_address_parse_one("vsock:2:1234x", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("vsock:2x:1234", -EINVAL, 0, NULL);
+        test_socket_address_parse_one("vsock:2", -EINVAL, 0, NULL);
+}
+
+static void test_socket_address_parse_netlink(void) {
+        SocketAddress a;
+
+        log_info("/* %s */", __func__);
+
+        assert_se(socket_address_parse_netlink(&a, "junk") < 0);
+        assert_se(socket_address_parse_netlink(&a, "") < 0);
+
+        assert_se(socket_address_parse_netlink(&a, "route") >= 0);
+        assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
+        assert_se(a.sockaddr.nl.nl_groups == 0);
+        assert_se(a.protocol == NETLINK_ROUTE);
+        assert_se(socket_address_parse_netlink(&a, "route") >= 0);
+        assert_se(socket_address_parse_netlink(&a, "route 10") >= 0);
+        assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
+        assert_se(a.sockaddr.nl.nl_groups == 10);
+        assert_se(a.protocol == NETLINK_ROUTE);
+
+        /* With spaces and tabs */
+        assert_se(socket_address_parse_netlink(&a, " kobject-uevent ") >= 0);
+        assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
+        assert_se(a.sockaddr.nl.nl_groups == 0);
+        assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
+        assert_se(socket_address_parse_netlink(&a, " \t kobject-uevent \t 10") >= 0);
+        assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
+        assert_se(a.sockaddr.nl.nl_groups == 10);
+        assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
+        assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10") >= 0);
+        assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
+        assert_se(a.sockaddr.nl.nl_groups == 10);
+        assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
+
+        /* trailing space is not supported */
+        assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10 ") < 0);
+
+        /* Group must be unsigned */
+        assert_se(socket_address_parse_netlink(&a, "kobject-uevent -1") < 0);
+
+        /* oss-fuzz #6884 */
+        assert_se(socket_address_parse_netlink(&a, "\xff") < 0);
+}
+
+static void test_socket_address_equal(void) {
+        SocketAddress a, b;
+
+        log_info("/* %s */", __func__);
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_parse(&b, "192.168.1.1:888") >= 0);
+        assert_se(!socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_parse(&b, "192.16.1.1:8888") >= 0);
+        assert_se(!socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_parse(&b, "8888") >= 0);
+        assert_se(!socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_parse(&b, "/foo/bar/") >= 0);
+        assert_se(!socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_parse(&b, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
+        assert_se(socket_address_parse(&b, "/foo/bar") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
+        assert_se(socket_address_parse(&b, "[::1]:8888") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "@abstract") >= 0);
+        assert_se(socket_address_parse(&b, "@abstract") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse_netlink(&a, "firewall") >= 0);
+        assert_se(socket_address_parse_netlink(&b, "firewall") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
+        assert_se(socket_address_parse(&b, "vsock:2:1234") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+        assert_se(socket_address_parse(&b, "vsock:2:1235") >= 0);
+        assert_se(!socket_address_equal(&a, &b));
+        assert_se(socket_address_parse(&b, "vsock:3:1234") >= 0);
+        assert_se(!socket_address_equal(&a, &b));
+}
+
+static void test_socket_address_get_path(void) {
+        SocketAddress a;
+
+        log_info("/* %s */", __func__);
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(!socket_address_get_path(&a));
+
+        assert_se(socket_address_parse(&a, "@abstract") >= 0);
+        assert_se(!socket_address_get_path(&a));
+
+        assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
+        assert_se(!socket_address_get_path(&a));
+
+        assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
+        assert_se(streq(socket_address_get_path(&a), "/foo/bar"));
+
+        assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
+        assert_se(!socket_address_get_path(&a));
+}
+
+static void test_socket_address_is(void) {
+        SocketAddress a;
+
+        log_info("/* %s */", __func__);
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_is(&a, "192.168.1.1:8888", SOCK_STREAM));
+        assert_se(!socket_address_is(&a, "route", SOCK_STREAM));
+        assert_se(!socket_address_is(&a, "192.168.1.1:8888", SOCK_RAW));
+}
+
+static void test_socket_address_is_netlink(void) {
+        SocketAddress a;
+
+        log_info("/* %s */", __func__);
+
+        assert_se(socket_address_parse_netlink(&a, "route 10") >= 0);
+        assert_se(socket_address_is_netlink(&a, "route 10"));
+        assert_se(!socket_address_is_netlink(&a, "192.168.1.1:8888"));
+        assert_se(!socket_address_is_netlink(&a, "route 1"));
+}
+
+int main(int argc, char *argv[]) {
+        test_setup_logging(LOG_DEBUG);
+
+        test_socket_address_parse();
+        test_socket_address_parse_netlink();
+        test_socket_address_equal();
+        test_socket_address_get_path();
+        test_socket_address_is();
+        test_socket_address_is_netlink();
+
+        return 0;
+}
index 2489d00e263b8d91095ae8d70df9a254464ae15e..d36caaa71e73375637af4cbc61d09332625c3644 100644 (file)
 #include "macro.h"
 #include "missing_network.h"
 #include "process-util.h"
+#include "socket-netlink.h"
 #include "socket-util.h"
 #include "string-util.h"
 #include "tests.h"
 #include "tmpfile-util.h"
 
+assert_cc(SUN_PATH_LEN == 108);
+
 static void test_ifname_valid(void) {
         log_info("/* %s */", __func__);
 
@@ -48,82 +51,6 @@ static void test_ifname_valid(void) {
         assert(ifname_valid_full("xxxxxxxxxxxxxxxx", true));
 }
 
-static void test_socket_address_parse_one(const char *in, int ret, int family, const char *expected) {
-        SocketAddress a;
-        _cleanup_free_ char *out = NULL;
-        int r;
-
-        r = socket_address_parse(&a, in);
-        if (r >= 0)
-                assert_se(socket_address_print(&a, &out) >= 0);
-
-        log_info("\"%s\" → %s → \"%s\" (expect \"%s\")", in,
-                 r >= 0 ? "✓" : "✗", empty_to_dash(out), r >= 0 ? expected ?: in : "-");
-        assert_se(r == ret);
-        if (r >= 0) {
-                assert_se(a.sockaddr.sa.sa_family == family);
-                assert_se(streq(out, expected ?: in));
-        }
-}
-
-#define SUN_PATH_LEN (sizeof(((struct sockaddr_un){}).sun_path))
-assert_cc(SUN_PATH_LEN == 108);
-
-static void test_socket_address_parse(void) {
-        log_info("/* %s */", __func__);
-
-        test_socket_address_parse_one("junk", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("192.168.1.1", -EINVAL, 0, NULL);
-        test_socket_address_parse_one(".168.1.1", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("989.168.1.1", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("192.168.1.1:65536", -ERANGE, 0, NULL);
-        test_socket_address_parse_one("192.168.1.1:0", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("0", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("65536", -ERANGE, 0, NULL);
-
-        const int default_family = socket_ipv6_is_supported() ? AF_INET6 : AF_INET;
-
-        test_socket_address_parse_one("65535", 0, default_family, "[::]:65535");
-
-        /* The checks below will pass even if ipv6 is disabled in
-         * kernel. The underlying glibc's inet_pton() is just a string
-         * parser and doesn't make any syscalls. */
-
-        test_socket_address_parse_one("[::1]", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("[::1]8888", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("::1", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("[::1]:0", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("[::1]:65536", -ERANGE, 0, NULL);
-        test_socket_address_parse_one("[a:b:1]:8888", -EINVAL, 0, NULL);
-
-        test_socket_address_parse_one("8888", 0, default_family, "[::]:8888");
-        test_socket_address_parse_one("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888", 0, AF_INET6,
-                                      "[2001:db8:0:85a3::ac1f:8001]:8888");
-        test_socket_address_parse_one("[::1]:8888", 0, AF_INET6, NULL);
-        test_socket_address_parse_one("192.168.1.254:8888", 0, AF_INET, NULL);
-        test_socket_address_parse_one("/foo/bar", 0, AF_UNIX, NULL);
-        test_socket_address_parse_one("/", 0, AF_UNIX, NULL);
-        test_socket_address_parse_one("@abstract", 0, AF_UNIX, NULL);
-
-        {
-                char aaa[SUN_PATH_LEN + 1] = "@";
-
-                memset(aaa + 1, 'a', SUN_PATH_LEN - 1);
-                char_array_0(aaa);
-
-                test_socket_address_parse_one(aaa, -EINVAL, 0, NULL);
-
-                aaa[SUN_PATH_LEN - 1] = '\0';
-                test_socket_address_parse_one(aaa, 0, AF_UNIX, NULL);
-        }
-
-        test_socket_address_parse_one("vsock:2:1234", 0, AF_VSOCK, NULL);
-        test_socket_address_parse_one("vsock::1234", 0, AF_VSOCK, NULL);
-        test_socket_address_parse_one("vsock:2:1234x", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("vsock:2x:1234", -EINVAL, 0, NULL);
-        test_socket_address_parse_one("vsock:2", -EINVAL, 0, NULL);
-}
-
 static void test_socket_print_unix_one(const char *in, size_t len_in, const char *expected) {
         _cleanup_free_ char *out = NULL, *c = NULL;
 
@@ -157,141 +84,6 @@ static void test_socket_print_unix(void) {
         test_socket_print_unix_one("\0\a\b\n\255", 6, "@\\a\\b\\n\\255\\000");
 }
 
-static void test_socket_address_parse_netlink(void) {
-        SocketAddress a;
-
-        log_info("/* %s */", __func__);
-
-        assert_se(socket_address_parse_netlink(&a, "junk") < 0);
-        assert_se(socket_address_parse_netlink(&a, "") < 0);
-
-        assert_se(socket_address_parse_netlink(&a, "route") >= 0);
-        assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
-        assert_se(a.sockaddr.nl.nl_groups == 0);
-        assert_se(a.protocol == NETLINK_ROUTE);
-        assert_se(socket_address_parse_netlink(&a, "route") >= 0);
-        assert_se(socket_address_parse_netlink(&a, "route 10") >= 0);
-        assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
-        assert_se(a.sockaddr.nl.nl_groups == 10);
-        assert_se(a.protocol == NETLINK_ROUTE);
-
-        /* With spaces and tabs */
-        assert_se(socket_address_parse_netlink(&a, " kobject-uevent ") >= 0);
-        assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
-        assert_se(a.sockaddr.nl.nl_groups == 0);
-        assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
-        assert_se(socket_address_parse_netlink(&a, " \t kobject-uevent \t 10") >= 0);
-        assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
-        assert_se(a.sockaddr.nl.nl_groups == 10);
-        assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
-        assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10") >= 0);
-        assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
-        assert_se(a.sockaddr.nl.nl_groups == 10);
-        assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
-
-        /* trailing space is not supported */
-        assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10 ") < 0);
-
-        /* Group must be unsigned */
-        assert_se(socket_address_parse_netlink(&a, "kobject-uevent -1") < 0);
-
-        /* oss-fuzz #6884 */
-        assert_se(socket_address_parse_netlink(&a, "\xff") < 0);
-}
-
-static void test_socket_address_equal(void) {
-        SocketAddress a, b;
-
-        log_info("/* %s */", __func__);
-
-        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
-        assert_se(socket_address_parse(&b, "192.168.1.1:888") >= 0);
-        assert_se(!socket_address_equal(&a, &b));
-
-        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
-        assert_se(socket_address_parse(&b, "192.16.1.1:8888") >= 0);
-        assert_se(!socket_address_equal(&a, &b));
-
-        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
-        assert_se(socket_address_parse(&b, "8888") >= 0);
-        assert_se(!socket_address_equal(&a, &b));
-
-        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
-        assert_se(socket_address_parse(&b, "/foo/bar/") >= 0);
-        assert_se(!socket_address_equal(&a, &b));
-
-        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
-        assert_se(socket_address_parse(&b, "192.168.1.1:8888") >= 0);
-        assert_se(socket_address_equal(&a, &b));
-
-        assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
-        assert_se(socket_address_parse(&b, "/foo/bar") >= 0);
-        assert_se(socket_address_equal(&a, &b));
-
-        assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
-        assert_se(socket_address_parse(&b, "[::1]:8888") >= 0);
-        assert_se(socket_address_equal(&a, &b));
-
-        assert_se(socket_address_parse(&a, "@abstract") >= 0);
-        assert_se(socket_address_parse(&b, "@abstract") >= 0);
-        assert_se(socket_address_equal(&a, &b));
-
-        assert_se(socket_address_parse_netlink(&a, "firewall") >= 0);
-        assert_se(socket_address_parse_netlink(&b, "firewall") >= 0);
-        assert_se(socket_address_equal(&a, &b));
-
-        assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
-        assert_se(socket_address_parse(&b, "vsock:2:1234") >= 0);
-        assert_se(socket_address_equal(&a, &b));
-        assert_se(socket_address_parse(&b, "vsock:2:1235") >= 0);
-        assert_se(!socket_address_equal(&a, &b));
-        assert_se(socket_address_parse(&b, "vsock:3:1234") >= 0);
-        assert_se(!socket_address_equal(&a, &b));
-}
-
-static void test_socket_address_get_path(void) {
-        SocketAddress a;
-
-        log_info("/* %s */", __func__);
-
-        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
-        assert_se(!socket_address_get_path(&a));
-
-        assert_se(socket_address_parse(&a, "@abstract") >= 0);
-        assert_se(!socket_address_get_path(&a));
-
-        assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
-        assert_se(!socket_address_get_path(&a));
-
-        assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
-        assert_se(streq(socket_address_get_path(&a), "/foo/bar"));
-
-        assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
-        assert_se(!socket_address_get_path(&a));
-}
-
-static void test_socket_address_is(void) {
-        SocketAddress a;
-
-        log_info("/* %s */", __func__);
-
-        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
-        assert_se(socket_address_is(&a, "192.168.1.1:8888", SOCK_STREAM));
-        assert_se(!socket_address_is(&a, "route", SOCK_STREAM));
-        assert_se(!socket_address_is(&a, "192.168.1.1:8888", SOCK_RAW));
-}
-
-static void test_socket_address_is_netlink(void) {
-        SocketAddress a;
-
-        log_info("/* %s */", __func__);
-
-        assert_se(socket_address_parse_netlink(&a, "route 10") >= 0);
-        assert_se(socket_address_is_netlink(&a, "route 10"));
-        assert_se(!socket_address_is_netlink(&a, "192.168.1.1:8888"));
-        assert_se(!socket_address_is_netlink(&a, "route 1"));
-}
-
 static void test_in_addr_is_null(void) {
         union in_addr_union i = {};
 
@@ -876,13 +668,7 @@ int main(int argc, char *argv[]) {
 
         test_ifname_valid();
 
-        test_socket_address_parse();
         test_socket_print_unix();
-        test_socket_address_parse_netlink();
-        test_socket_address_equal();
-        test_socket_address_get_path();
-        test_socket_address_is();
-        test_socket_address_is_netlink();
 
         test_in_addr_is_null();
         test_in_addr_prefix_intersect();
index 7cfeeb8532527bd0732a48a67be13277897e5294..84962248481e9960d7b1a57982dae711203be5c3 100644 (file)
@@ -829,7 +829,7 @@ static int show_timesync(int argc, char **argv, void *userdata) {
         return 0;
 }
 
-static int parse_ifindex_bus(sd_bus *bus, const char *str, int *ret) {
+static int parse_ifindex_bus(sd_bus *bus, const char *str) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         int32_t i;
@@ -837,11 +837,11 @@ static int parse_ifindex_bus(sd_bus *bus, const char *str, int *ret) {
 
         assert(bus);
         assert(str);
-        assert(ret);
 
-        r = parse_ifindex(str, ret);
-        if (r >= 0)
-                return 0;
+        r = parse_ifindex(str);
+        if (r > 0)
+                return r;
+        assert(r < 0);
 
         r = sd_bus_call_method(
                         bus,
@@ -859,8 +859,7 @@ static int parse_ifindex_bus(sd_bus *bus, const char *str, int *ret) {
         if (r < 0)
                 return bus_log_create_error(r);
 
-        *ret = i;
-        return 0;
+        return i;
 }
 
 static int verb_ntp_servers(int argc, char **argv, void *userdata) {
@@ -871,9 +870,9 @@ static int verb_ntp_servers(int argc, char **argv, void *userdata) {
 
         assert(bus);
 
-        r = parse_ifindex_bus(bus, argv[1], &ifindex);
-        if (r < 0)
-                return r;
+        ifindex = parse_ifindex_bus(bus, argv[1]);
+        if (ifindex < 0)
+                return ifindex;
 
         polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
 
@@ -909,9 +908,9 @@ static int verb_revert(int argc, char **argv, void *userdata) {
 
         assert(bus);
 
-        r = parse_ifindex_bus(bus, argv[1], &ifindex);
-        if (r < 0)
-                return r;
+        ifindex = parse_ifindex_bus(bus, argv[1]);
+        if (ifindex < 0)
+                return ifindex;
 
         polkit_agent_open_if_enabled(arg_transport, arg_ask_password);