]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: introduce manager_has_address()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 6 May 2021 19:03:21 +0000 (04:03 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 12 May 2021 01:30:45 +0000 (10:30 +0900)
The function will be used in later commits.

src/network/networkd-address.c
src/network/networkd-address.h

index 78b9be2d542a79a8e869a65ae992f23cbb732418..262cfb47130dc4ac4cef0a652b99502f78832267 100644 (file)
@@ -485,6 +485,63 @@ int link_has_ipv6_address(Link *link, const struct in6_addr *address) {
         return address_get(link, a, NULL) >= 0;
 }
 
+static int link_get_ipv4_address(Set *addresses, const struct in_addr *address, Address **ret) {
+        Address *a;
+
+        assert(address);
+
+        SET_FOREACH(a, addresses) {
+                if (a->family != AF_INET)
+                        continue;
+
+                if (!in4_addr_equal(&a->in_addr.in, address))
+                        continue;
+
+                if (ret)
+                        *ret = a;
+
+                return 0;
+        }
+
+        return -ENOENT;
+}
+
+int manager_has_address(Manager *manager, int family, const union in_addr_union *address, bool check_ready) {
+        Link *link;
+        int r;
+
+        assert(manager);
+        assert(IN_SET(family, AF_INET, AF_INET6));
+        assert(address);
+
+        if (family == AF_INET)
+                HASHMAP_FOREACH(link, manager->links) {
+                        Address *a;
+
+                        if (link_get_ipv4_address(link->addresses, &address->in, &a) >= 0)
+                                return !check_ready || address_is_ready(a);
+                        if (link_get_ipv4_address(link->addresses_foreign, &address->in, &a) >= 0)
+                                return !check_ready || address_is_ready(a);
+                }
+        else {
+                _cleanup_(address_freep) Address *tmp = NULL;
+                Address *a;
+
+                r = address_new(&tmp);
+                if (r < 0)
+                        return r;
+
+                tmp->family = family;
+                tmp->in_addr = *address;
+
+                HASHMAP_FOREACH(link, manager->links)
+                        if (address_get(link, tmp, &a) >= 0)
+                                return !check_ready || address_is_ready(a);
+        }
+
+        return false;
+}
+
 static void log_address_debug(const Address *address, const char *str, const Link *link) {
         _cleanup_free_ char *addr = NULL, *peer = NULL;
         char valid_buf[FORMAT_TIMESPAN_MAX], preferred_buf[FORMAT_TIMESPAN_MAX];
index b8030c99df2e2a0d7103f2111e04a12505454869..d05d37da3b26b03c9c226dc08c7eb85c3bbb50b0 100644 (file)
@@ -65,6 +65,7 @@ int link_drop_addresses(Link *link);
 int link_drop_foreign_addresses(Link *link);
 bool link_address_is_dynamic(const Link *link, const Address *address);
 int link_has_ipv6_address(Link *link, const struct in6_addr *address);
+int manager_has_address(Manager *manager, int family, const union in_addr_union *address, bool check_ready);
 
 void ipv4_dad_unref(Link *link);
 int ipv4_dad_stop(Link *link);