]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: delay dropping addresses or so on reloading .network files
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 25 Oct 2021 17:29:09 +0000 (02:29 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 25 Oct 2021 23:20:22 +0000 (08:20 +0900)
When a .network file is updated but its change is not so big, it is not
necessary to first drop all configs and then reassign later again.
This slightly optimize such situation. First foreignize all configs, and
then drop later when it is not requested by the updated .network file.

src/network/networkd-address.c
src/network/networkd-address.h
src/network/networkd-link.c
src/network/networkd-neighbor.c
src/network/networkd-neighbor.h
src/network/networkd-nexthop.c
src/network/networkd-nexthop.h
src/network/networkd-route.c
src/network/networkd-route.h
src/network/networkd-routing-policy-rule.c
src/network/networkd-routing-policy-rule.h

index 78e011a85541d444a4c7667d0b9f70d67a34064a..a89bdcac95c2b8e5d9e65b1044276785e05e93a7 100644 (file)
@@ -910,6 +910,15 @@ int link_drop_addresses(Link *link) {
         return r;
 }
 
+void link_foreignize_addresses(Link *link) {
+        Address *address;
+
+        assert(link);
+
+        SET_FOREACH(address, link->addresses)
+                address->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+}
+
 static int address_acquire(Link *link, const Address *original, Address **ret) {
         _cleanup_(address_freep) Address *na = NULL;
         union in_addr_union in_addr;
index 75edfd70dc1ce5bf691f8e8c1b9f6ffd37a2fd1e..64ed6164b5d84b85982bdb935f2d1291cbad0a5e 100644 (file)
@@ -75,6 +75,7 @@ DEFINE_NETWORK_SECTION_FUNCTIONS(Address, address_free);
 int link_drop_addresses(Link *link);
 int link_drop_foreign_addresses(Link *link);
 int link_drop_ipv6ll_addresses(Link *link);
+void link_foreignize_addresses(Link *link);
 bool link_address_is_dynamic(const Link *link, const Address *address);
 int link_get_ipv6_address(Link *link, const struct in6_addr *address, Address **ret);
 int link_get_ipv4_address(Link *link, const struct in_addr *address, unsigned char prefixlen, Address **ret);
index ab75ac47d5ee16ab3c089a25f06dfd6c1c9c6b83..49239236eca2e573b9ad678ffa719f4bb8424a36 100644 (file)
@@ -1051,6 +1051,17 @@ static int link_drop_config(Link *link) {
         return r;
 }
 
+static void link_foreignize_config(Link *link) {
+        assert(link);
+        assert(link->manager);
+
+        link_foreignize_routes(link);
+        link_foreignize_nexthops(link);
+        link_foreignize_addresses(link);
+        link_foreignize_neighbors(link);
+        link_foreignize_routing_policy_rules(link);
+}
+
 static int link_configure(Link *link) {
         int r;
 
@@ -1249,9 +1260,16 @@ static int link_reconfigure_impl(Link *link, bool force) {
 
         link_drop_requests(link);
 
-        r = link_drop_config(link);
-        if (r < 0)
-                return r;
+        if (network && !force)
+                /* When a new/updated .network file is assigned, first make all configs (addresses,
+                 * routes, and so on) foreign, and then drop unnecessary configs later by
+                 * link_drop_foreign_config() in link_configure(). */
+                link_foreignize_config(link);
+        else {
+                r = link_drop_config(link);
+                if (r < 0)
+                        return r;
+        }
 
         link_free_carrier_maps(link);
         link_free_engines(link);
index b8d1045f1a0d6e8765e8ea056e6c10b8388a6252..aaa3f2f1ada36bce052c43ab367da49e99b35e2c 100644 (file)
@@ -437,6 +437,15 @@ int link_drop_neighbors(Link *link) {
         return r;
 }
 
+void link_foreignize_neighbors(Link *link) {
+        Neighbor *neighbor;
+
+        assert(link);
+
+        SET_FOREACH(neighbor, link->neighbors)
+                neighbor->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+}
+
 int request_process_neighbor(Request *req) {
         int r;
 
index 9c122f341bc41299619174c725514992c0878c7e..d4f2ff55f2e49657c840ba8741244c17fcb5099f 100644 (file)
@@ -42,6 +42,7 @@ void network_drop_invalid_neighbors(Network *network);
 
 int link_drop_neighbors(Link *link);
 int link_drop_foreign_neighbors(Link *link);
+void link_foreignize_neighbors(Link *link);
 
 int link_request_static_neighbors(Link *link);
 int request_process_neighbor(Request *req);
index 267efb56208f67bb2245fa9a5ec6cb92f6e20275..55fad8a63685e34caf09504bd1d045877d57a52e 100644 (file)
@@ -602,10 +602,9 @@ int link_request_static_nexthops(Link *link, bool only_ipv4) {
         return 0;
 }
 
-static int manager_drop_nexthops(Manager *manager, bool foreign, const Link *except) {
+static void manager_mark_nexthops(Manager *manager, bool foreign, const Link *except) {
         NextHop *nexthop;
         Link *link;
-        int k, r = 0;
 
         assert(manager);
 
@@ -641,8 +640,14 @@ static int manager_drop_nexthops(Manager *manager, bool foreign, const Link *exc
                                 nexthop_unmark(existing);
                 }
         }
+}
+
+static int manager_drop_nexthops(Manager *manager) {
+        NextHop *nexthop;
+        int k, r = 0;
+
+        assert(manager);
 
-        /* Finally, remove all marked nexthops. */
         SET_FOREACH(nexthop, manager->nexthops) {
                 if (!nexthop_is_marked(nexthop))
                         continue;
@@ -698,7 +703,9 @@ int link_drop_foreign_nexthops(Link *link) {
                         r = k;
         }
 
-        k = manager_drop_nexthops(link->manager, /* foreign = */ true, NULL);
+        manager_mark_nexthops(link->manager, /* foreign = */ true, NULL);
+
+        k = manager_drop_nexthops(link->manager);
         if (k < 0 && r >= 0)
                 r = k;
 
@@ -726,13 +733,33 @@ int link_drop_nexthops(Link *link) {
                         r = k;
         }
 
-        k = manager_drop_nexthops(link->manager, /* foreign = */ false, link);
+        manager_mark_nexthops(link->manager, /* foreign = */ false, link);
+
+        k = manager_drop_nexthops(link->manager);
         if (k < 0 && r >= 0)
                 r = k;
 
         return r;
 }
 
+void link_foreignize_nexthops(Link *link) {
+        NextHop *nexthop;
+
+        assert(link);
+
+        SET_FOREACH(nexthop, link->nexthops)
+                nexthop->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+
+        manager_mark_nexthops(link->manager, /* foreign = */ false, link);
+
+        SET_FOREACH(nexthop, link->manager->nexthops) {
+                if (!nexthop_is_marked(nexthop))
+                        continue;
+
+                nexthop->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+        }
+}
+
 static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
         struct nexthop_grp *nhg;
 
index a63ca56d262585b73301101fef17b41b1a1ba778..3cc177fc54a7da3a1163f9d808990036b7203f7b 100644 (file)
@@ -45,6 +45,7 @@ void network_drop_invalid_nexthops(Network *network);
 
 int link_drop_nexthops(Link *link);
 int link_drop_foreign_nexthops(Link *link);
+void link_foreignize_nexthops(Link *link);
 
 int link_request_static_nexthops(Link *link, bool only_ipv4);
 int request_process_nexthop(Request *req);
index 4dc6ecda622938d092b893c2dd82f3a98992daf1..e5c95d734ed8710684ede894c0170dbd8cd043ab 100644 (file)
@@ -1037,10 +1037,10 @@ int route_remove(Route *route) {
         return 0;
 }
 
-static int manager_drop_routes(Manager *manager, bool foreign, const Link *except) {
+static void manager_mark_routes(Manager *manager, bool foreign, const Link *except) {
         Route *route;
         Link *link;
-        int k, r;
+        int r;
 
         assert(manager);
 
@@ -1090,9 +1090,14 @@ static int manager_drop_routes(Manager *manager, bool foreign, const Link *excep
                                         route_unmark(existing);
                 }
         }
+}
+
+static int manager_drop_routes(Manager *manager) {
+        Route *route;
+        int k, r = 0;
+
+        assert(manager);
 
-        /* Finally, remove all marked routes. */
-        r = 0;
         SET_FOREACH(route, manager->routes) {
                 if (!route_is_marked(route))
                         continue;
@@ -1182,7 +1187,9 @@ int link_drop_foreign_routes(Link *link) {
                         r = k;
         }
 
-        k = manager_drop_routes(link->manager, /* foreign = */ true, NULL);
+        manager_mark_routes(link->manager, /* foreign = */ true, NULL);
+
+        k = manager_drop_routes(link->manager);
         if (k < 0 && r >= 0)
                 r = k;
 
@@ -1208,13 +1215,33 @@ int link_drop_routes(Link *link) {
                         r = k;
         }
 
-        k = manager_drop_routes(link->manager, /* foreign = */ false, link);
+        manager_mark_routes(link->manager, /* foreign = */ false, link);
+
+        k = manager_drop_routes(link->manager);
         if (k < 0 && r >= 0)
                 r = k;
 
         return r;
 }
 
+void link_foreignize_routes(Link *link) {
+        Route *route;
+
+        assert(link);
+
+        SET_FOREACH(route, link->routes)
+                route->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+
+        manager_mark_routes(link->manager, /* foreign = */ false, link);
+
+        SET_FOREACH(route, link->manager->routes) {
+                if (!route_is_marked(route))
+                        continue;
+
+                route->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+        }
+}
+
 static int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata) {
         Route *route = userdata;
         int r;
index 612d7d28099f121754f9e621d403c29fcd85d381..c9144702268a1fce5a37f217cff60cdd3be9af67 100644 (file)
@@ -85,6 +85,7 @@ bool gateway_is_ready(Link *link, int onlink, int family, const union in_addr_un
 
 int link_drop_routes(Link *link);
 int link_drop_foreign_routes(Link *link);
+void link_foreignize_routes(Link *link);
 
 void route_cancel_request(Route *route);
 int link_request_route(
index e3b57814f50cc66cf63eef0740ee6faa5ffb6d71..35808b10f72405496343747213811a5f93b42358 100644 (file)
@@ -619,10 +619,9 @@ static int routing_policy_rule_configure(
         return r;
 }
 
-int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const Link *except) {
+static void manager_mark_routing_policy_rules(Manager *m, bool foreign, const Link *except) {
         RoutingPolicyRule *rule;
         Link *link;
-        int k, r;
 
         assert(m);
 
@@ -671,9 +670,16 @@ int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const L
                         }
                 }
         }
+}
+
+int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const Link *except) {
+        RoutingPolicyRule *rule;
+        int k, r = 0;
+
+        assert(m);
+
+        manager_mark_routing_policy_rules(m, foreign, except);
 
-        /* Finally, remove all marked rules. */
-        r = 0;
         SET_FOREACH(rule, m->rules) {
                 if (!routing_policy_rule_is_marked(rule))
                         continue;
@@ -686,6 +692,22 @@ int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const L
         return r;
 }
 
+void link_foreignize_routing_policy_rules(Link *link) {
+        RoutingPolicyRule *rule;
+
+        assert(link);
+        assert(link->manager);
+
+        manager_mark_routing_policy_rules(link->manager, /* foreign = */ false, link);
+
+        SET_FOREACH(rule, link->manager->rules) {
+                if (!routing_policy_rule_is_marked(rule))
+                        continue;
+
+                rule->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+        }
+}
+
 static int static_routing_policy_rule_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
index 043909782e186cba303b8ad061451e89f8aaafa7..89f49fcb86cd1992e1a69cffab911f7dfd354666 100644 (file)
@@ -72,6 +72,7 @@ static inline int link_drop_routing_policy_rules(Link *link) {
         assert(link);
         return manager_drop_routing_policy_rules_internal(link->manager, false, link);
 }
+void link_foreignize_routing_policy_rules(Link *link);
 
 DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(RoutingPolicyRule, routing_policy_rule);