]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: introduce link_drop_foreign_addresses()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 2 Oct 2020 02:26:12 +0000 (11:26 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 6 Oct 2020 17:44:43 +0000 (02:44 +0900)
src/network/networkd-address.c
src/network/networkd-address.h
src/network/networkd-link.c
src/network/networkd-link.h

index 454be9a066f465df0b69e4ab4cb9bcb7051967b2..86ea5c2da17c47afbb6904ea770573ed055c49c2 100644 (file)
@@ -542,6 +542,85 @@ int address_remove(
         return 0;
 }
 
+static bool link_is_static_address_configured(Link *link, Address *address) {
+        Address *net_address;
+
+        assert(link);
+        assert(address);
+
+        if (!link->network)
+                return false;
+
+        LIST_FOREACH(addresses, net_address, link->network->static_addresses)
+                if (address_equal(net_address, address))
+                        return true;
+                else if (address->family == AF_INET6 && net_address->family == AF_INET6 &&
+                         in_addr_equal(AF_INET6, &address->in_addr, &net_address->in_addr_peer) > 0)
+                        return true;
+
+        return false;
+}
+
+static bool link_address_is_dynamic(Link *link, Address *address) {
+        Route *route;
+
+        assert(link);
+        assert(address);
+
+        if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
+                return true;
+
+        /* Even when the address is leased from a DHCP server, networkd assign the address
+         * without lifetime when KeepConfiguration=dhcp. So, let's check that we have
+         * corresponding routes with RTPROT_DHCP. */
+        SET_FOREACH(route, link->routes_foreign) {
+                if (route->protocol != RTPROT_DHCP)
+                        continue;
+
+                if (address->family != route->family)
+                        continue;
+
+                if (in_addr_equal(address->family, &address->in_addr, &route->prefsrc))
+                        return true;
+        }
+
+        return false;
+}
+
+int link_drop_foreign_addresses(Link *link) {
+        Address *address;
+        int k, r = 0;
+
+        assert(link);
+
+        SET_FOREACH(address, link->addresses_foreign) {
+                /* we consider IPv6LL addresses to be managed by the kernel */
+                if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1 && link_ipv6ll_enabled(link))
+                        continue;
+
+                if (link_address_is_dynamic(link, address)) {
+                        if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
+                                continue;
+                } else if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
+                        continue;
+
+                if (link_is_static_address_configured(link, address)) {
+                        k = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL);
+                        if (k < 0) {
+                                log_link_error_errno(link, k, "Failed to add address: %m");
+                                if (r >= 0)
+                                        r = k;
+                        }
+                } else {
+                        k = address_remove(address, link, NULL);
+                        if (k < 0 && r >= 0)
+                                r = k;
+                }
+        }
+
+        return r;
+}
+
 static int address_acquire(Link *link, Address *original, Address **ret) {
         union in_addr_union in_addr = IN_ADDR_NULL;
         struct in_addr broadcast = {};
index b8a397d6cbe78ecc08ee828708c193cd018a2be1..66334239372ffe5f5e98b2156bfd3addb1ac0a28 100644 (file)
@@ -76,6 +76,7 @@ int generate_ipv6_eui_64_address(Link *link, struct in6_addr *ret);
 DEFINE_NETWORK_SECTION_FUNCTIONS(Address, address_free);
 
 int link_set_addresses(Link *link);
+int link_drop_foreign_addresses(Link *link);
 
 void address_hash_func(const Address *a, struct siphash *state);
 int address_compare_func(const Address *a1, const Address *a2);
index 929fbddd9cbb3163c900ff0767d14ad6be6c484f..4ea97b2acb3acb05c7358df979c5fb3aa0ca80dc 100644 (file)
@@ -163,7 +163,7 @@ bool link_ipv4ll_enabled(Link *link, AddressFamily mask) {
         return link->network->link_local & mask;
 }
 
-static bool link_ipv6ll_enabled(Link *link) {
+bool link_ipv6ll_enabled(Link *link) {
         assert(link);
 
         if (!socket_ipv6_is_supported())
@@ -2320,51 +2320,6 @@ static int link_set_ipv4_accept_local(Link *link) {
         return 0;
 }
 
-static bool link_is_static_address_configured(Link *link, Address *address) {
-        Address *net_address;
-
-        assert(link);
-        assert(address);
-
-        if (!link->network)
-                return false;
-
-        LIST_FOREACH(addresses, net_address, link->network->static_addresses)
-                if (address_equal(net_address, address))
-                        return true;
-                else if (address->family == AF_INET6 && net_address->family == AF_INET6 &&
-                         in_addr_equal(AF_INET6, &address->in_addr, &net_address->in_addr_peer) > 0)
-                        return true;
-
-        return false;
-}
-
-static bool link_address_is_dynamic(Link *link, Address *address) {
-        Route *route;
-
-        assert(link);
-        assert(address);
-
-        if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
-                return true;
-
-        /* Even when the address is leased from a DHCP server, networkd assign the address
-         * without lifetime when KeepConfiguration=dhcp. So, let's check that we have
-         * corresponding routes with RTPROT_DHCP. */
-        SET_FOREACH(route, link->routes_foreign) {
-                if (route->protocol != RTPROT_DHCP)
-                        continue;
-
-                if (address->family != route->family)
-                        continue;
-
-                if (in_addr_equal(address->family, &address->in_addr, &route->prefsrc))
-                        return true;
-        }
-
-        return false;
-}
-
 static int link_enumerate_ipv6_tentative_addresses(Link *link) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
         sd_netlink_message *addr;
@@ -2408,7 +2363,6 @@ static int link_enumerate_ipv6_tentative_addresses(Link *link) {
 }
 
 static int link_drop_foreign_config(Link *link) {
-        Address *address;
         int r;
 
         /* The kernel doesn't notify us about tentative addresses;
@@ -2419,27 +2373,9 @@ static int link_drop_foreign_config(Link *link) {
                         return r;
         }
 
-        SET_FOREACH(address, link->addresses_foreign) {
-                /* we consider IPv6LL addresses to be managed by the kernel */
-                if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1 && link_ipv6ll_enabled(link))
-                        continue;
-
-                if (link_address_is_dynamic(link, address)) {
-                        if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
-                                continue;
-                } else if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
-                        continue;
-
-                if (link_is_static_address_configured(link, address)) {
-                        r = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL);
-                        if (r < 0)
-                                return log_link_error_errno(link, r, "Failed to add address: %m");
-                } else {
-                        r = address_remove(address, link, NULL);
-                        if (r < 0)
-                                return r;
-                }
-        }
+        r = link_drop_foreign_addresses(link);
+        if (r < 0)
+                return r;
 
         r = link_drop_foreign_neighbors(link);
         if (r < 0)
index aadbddc910c8e018a467e603df12aad5943580d4..670ae9783d2bbdfe148254ac9a5e43cbdae6bede 100644 (file)
@@ -226,6 +226,7 @@ int link_save_and_clean(Link *link);
 int link_carrier_reset(Link *link);
 bool link_has_carrier(Link *link);
 
+bool link_ipv6ll_enabled(Link *link);
 int link_ipv6ll_gained(Link *link, const struct in6_addr *address);
 
 int link_set_mtu(Link *link, uint32_t mtu);