summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-10-26 02:29:09 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-10-26 08:20:22 +0900
commitb4564f4e8ff1a653b8bba0a13533317fe3635897 (patch)
treea72d7a944d0e5cebaa31a92c63e5b6802273d368
parent756f1f5fd0ffb4cf0af230dea5fc478d9ca5390b (diff)
downloadsystemd-b4564f4e8ff1a653b8bba0a13533317fe3635897.tar.gz
network: delay dropping addresses or so on reloading .network files
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.
-rw-r--r--src/network/networkd-address.c9
-rw-r--r--src/network/networkd-address.h1
-rw-r--r--src/network/networkd-link.c24
-rw-r--r--src/network/networkd-neighbor.c9
-rw-r--r--src/network/networkd-neighbor.h1
-rw-r--r--src/network/networkd-nexthop.c37
-rw-r--r--src/network/networkd-nexthop.h1
-rw-r--r--src/network/networkd-route.c39
-rw-r--r--src/network/networkd-route.h1
-rw-r--r--src/network/networkd-routing-policy-rule.c30
-rw-r--r--src/network/networkd-routing-policy-rule.h1
11 files changed, 135 insertions, 18 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 78e011a855..a89bdcac95 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -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;
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
index 75edfd70dc..64ed6164b5 100644
--- a/src/network/networkd-address.h
+++ b/src/network/networkd-address.h
@@ -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);
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index ab75ac47d5..49239236ec 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -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);
diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c
index b8d1045f1a..aaa3f2f1ad 100644
--- a/src/network/networkd-neighbor.c
+++ b/src/network/networkd-neighbor.c
@@ -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;
diff --git a/src/network/networkd-neighbor.h b/src/network/networkd-neighbor.h
index 9c122f341b..d4f2ff55f2 100644
--- a/src/network/networkd-neighbor.h
+++ b/src/network/networkd-neighbor.h
@@ -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);
diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c
index 267efb5620..55fad8a636 100644
--- a/src/network/networkd-nexthop.c
+++ b/src/network/networkd-nexthop.c
@@ -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;
diff --git a/src/network/networkd-nexthop.h b/src/network/networkd-nexthop.h
index a63ca56d26..3cc177fc54 100644
--- a/src/network/networkd-nexthop.h
+++ b/src/network/networkd-nexthop.h
@@ -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);
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 4dc6ecda62..e5c95d734e 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -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;
diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h
index 612d7d2809..c914470226 100644
--- a/src/network/networkd-route.h
+++ b/src/network/networkd-route.h
@@ -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(
diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c
index e3b57814f5..35808b10f7 100644
--- a/src/network/networkd-routing-policy-rule.c
+++ b/src/network/networkd-routing-policy-rule.c
@@ -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;
diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h
index 043909782e..89f49fcb86 100644
--- a/src/network/networkd-routing-policy-rule.h
+++ b/src/network/networkd-routing-policy-rule.h
@@ -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);