summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/network/networkd-address.c13
-rw-r--r--src/network/networkd-address.h2
-rw-r--r--src/network/networkd-link.c18
-rw-r--r--src/network/networkd-neighbor.c6
-rw-r--r--src/network/networkd-neighbor.h2
-rw-r--r--src/network/networkd-nexthop.c16
-rw-r--r--src/network/networkd-nexthop.h2
-rw-r--r--src/network/networkd-route.c16
-rw-r--r--src/network/networkd-route.h2
-rw-r--r--src/network/networkd-routing-policy-rule.c4
-rw-r--r--src/network/networkd-routing-policy-rule.h2
-rwxr-xr-xtest/test-network/systemd-networkd-tests.py2
12 files changed, 48 insertions, 37 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index ff80f185ce..b5091bb598 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -891,22 +891,19 @@ int link_drop_foreign_addresses(Link *link) {
return r;
}
-int link_drop_addresses(Link *link) {
+int link_drop_managed_addresses(Link *link) {
Address *address;
int k, r = 0;
assert(link);
SET_FOREACH(address, link->addresses) {
- /* Ignore addresses not assigned yet or already removing. */
- if (!address_exists(address))
+ /* Do not touch addresses managed by kernel or other tools. */
+ if (address->source == NETWORK_CONFIG_SOURCE_FOREIGN)
continue;
- /* Do not drop IPv6LL addresses assigned by the kernel here. They will be dropped in
- * link_drop_ipv6ll_addresses() if IPv6LL addressing is disabled. */
- if (address->source == NETWORK_CONFIG_SOURCE_FOREIGN &&
- address->family == AF_INET6 &&
- in6_addr_is_link_local(&address->in_addr.in6))
+ /* Ignore addresses not assigned yet or already removing. */
+ if (!address_exists(address))
continue;
k = address_remove(address);
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
index c1e5b3ce3a..682f7e80e4 100644
--- a/src/network/networkd-address.h
+++ b/src/network/networkd-address.h
@@ -74,7 +74,7 @@ void address_set_broadcast(Address *a);
DEFINE_SECTION_CLEANUP_FUNCTIONS(Address, address_free);
-int link_drop_addresses(Link *link);
+int link_drop_managed_addresses(Link *link);
int link_drop_foreign_addresses(Link *link);
int link_drop_ipv6ll_addresses(Link *link);
void link_foreignize_addresses(Link *link);
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index a8de644559..3c5f3483bb 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1070,27 +1070,27 @@ static int link_drop_foreign_config(Link *link) {
return r;
}
-static int link_drop_config(Link *link) {
+static int link_drop_managed_config(Link *link) {
int k, r;
assert(link);
assert(link->manager);
- r = link_drop_routes(link);
+ r = link_drop_managed_routes(link);
- k = link_drop_nexthops(link);
+ k = link_drop_managed_nexthops(link);
if (k < 0 && r >= 0)
r = k;
- k = link_drop_addresses(link);
+ k = link_drop_managed_addresses(link);
if (k < 0 && r >= 0)
r = k;
- k = link_drop_neighbors(link);
+ k = link_drop_managed_neighbors(link);
if (k < 0 && r >= 0)
r = k;
- k = link_drop_routing_policy_rules(link);
+ k = link_drop_managed_routing_policy_rules(link);
if (k < 0 && r >= 0)
r = k;
@@ -1318,7 +1318,9 @@ static int link_reconfigure_impl(Link *link, bool force) {
* link_drop_foreign_config() in link_configure(). */
link_foreignize_config(link);
else {
- r = link_drop_config(link);
+ /* Remove all managed configs. Note, foreign configs are removed in later by
+ * link_configure() -> link_drop_foreign_config() if the link is managed by us. */
+ r = link_drop_managed_config(link);
if (r < 0)
return r;
}
@@ -1706,7 +1708,7 @@ static int link_carrier_lost_impl(Link *link) {
if (r < 0)
ret = r;
- r = link_drop_config(link);
+ r = link_drop_managed_config(link);
if (r < 0 && ret >= 0)
ret = r;
diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c
index 4aab290bf8..4f13053082 100644
--- a/src/network/networkd-neighbor.c
+++ b/src/network/networkd-neighbor.c
@@ -416,13 +416,17 @@ int link_drop_foreign_neighbors(Link *link) {
return r;
}
-int link_drop_neighbors(Link *link) {
+int link_drop_managed_neighbors(Link *link) {
Neighbor *neighbor;
int k, r = 0;
assert(link);
SET_FOREACH(neighbor, link->neighbors) {
+ /* Do not touch nexthops managed by kernel or other tools. */
+ if (neighbor->source == NETWORK_CONFIG_SOURCE_FOREIGN)
+ continue;
+
/* Ignore neighbors not assigned yet or already removing. */
if (!neighbor_exists(neighbor))
continue;
diff --git a/src/network/networkd-neighbor.h b/src/network/networkd-neighbor.h
index f31f58a4d4..ac1678de18 100644
--- a/src/network/networkd-neighbor.h
+++ b/src/network/networkd-neighbor.h
@@ -34,7 +34,7 @@ int neighbor_compare_func(const Neighbor *a, const Neighbor *b);
void network_drop_invalid_neighbors(Network *network);
-int link_drop_neighbors(Link *link);
+int link_drop_managed_neighbors(Link *link);
int link_drop_foreign_neighbors(Link *link);
void link_foreignize_neighbors(Link *link);
diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c
index e9e5d08557..b2bc0dc570 100644
--- a/src/network/networkd-nexthop.c
+++ b/src/network/networkd-nexthop.c
@@ -613,8 +613,8 @@ static void manager_mark_nexthops(Manager *manager, bool foreign, const Link *ex
if (nexthop->protocol == RTPROT_KERNEL)
continue;
- /* When 'foreign' is true, do not remove nexthops we configured. */
- if (foreign && nexthop->source != NETWORK_CONFIG_SOURCE_FOREIGN)
+ /* When 'foreign' is true, mark only foreign nexthops, and vice versa. */
+ if (foreign != (nexthop->source == NETWORK_CONFIG_SOURCE_FOREIGN))
continue;
/* Ignore nexthops not assigned yet or already removed. */
@@ -641,7 +641,7 @@ static void manager_mark_nexthops(Manager *manager, bool foreign, const Link *ex
}
}
-static int manager_drop_nexthops(Manager *manager) {
+static int manager_drop_marked_nexthops(Manager *manager) {
NextHop *nexthop;
int k, r = 0;
@@ -704,14 +704,14 @@ int link_drop_foreign_nexthops(Link *link) {
manager_mark_nexthops(link->manager, /* foreign = */ true, NULL);
- k = manager_drop_nexthops(link->manager);
+ k = manager_drop_marked_nexthops(link->manager);
if (k < 0 && r >= 0)
r = k;
return r;
}
-int link_drop_nexthops(Link *link) {
+int link_drop_managed_nexthops(Link *link) {
NextHop *nexthop;
int k, r = 0;
@@ -723,6 +723,10 @@ int link_drop_nexthops(Link *link) {
if (nexthop->protocol == RTPROT_KERNEL)
continue;
+ /* Do not touch addresses managed by kernel or other tools. */
+ if (nexthop->source == NETWORK_CONFIG_SOURCE_FOREIGN)
+ continue;
+
/* Ignore nexthops not assigned yet or already removing. */
if (!nexthop_exists(nexthop))
continue;
@@ -734,7 +738,7 @@ int link_drop_nexthops(Link *link) {
manager_mark_nexthops(link->manager, /* foreign = */ false, link);
- k = manager_drop_nexthops(link->manager);
+ k = manager_drop_marked_nexthops(link->manager);
if (k < 0 && r >= 0)
r = k;
diff --git a/src/network/networkd-nexthop.h b/src/network/networkd-nexthop.h
index 01b29ae560..16eb02f7eb 100644
--- a/src/network/networkd-nexthop.h
+++ b/src/network/networkd-nexthop.h
@@ -44,7 +44,7 @@ int nexthop_compare_func(const NextHop *a, const NextHop *b);
void network_drop_invalid_nexthops(Network *network);
-int link_drop_nexthops(Link *link);
+int link_drop_managed_nexthops(Link *link);
int link_drop_foreign_nexthops(Link *link);
void link_foreignize_nexthops(Link *link);
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 03021362b6..3a2e4490c1 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -788,8 +788,8 @@ static void manager_mark_routes(Manager *manager, bool foreign, const Link *exce
if (route->protocol == RTPROT_KERNEL)
continue;
- /* When 'foreign' is true, do not remove routes we configured. */
- if (foreign && route->source != NETWORK_CONFIG_SOURCE_FOREIGN)
+ /* When 'foreign' is true, mark only foreign routes, and vice versa. */
+ if (foreign != (route->source == NETWORK_CONFIG_SOURCE_FOREIGN))
continue;
/* Do not touch dynamic routes. They will removed by dhcp_pd_prefix_lost() */
@@ -834,7 +834,7 @@ static void manager_mark_routes(Manager *manager, bool foreign, const Link *exce
}
}
-static int manager_drop_routes(Manager *manager) {
+static int manager_drop_marked_routes(Manager *manager) {
Route *route;
int k, r = 0;
@@ -955,14 +955,14 @@ int link_drop_foreign_routes(Link *link) {
manager_mark_routes(link->manager, /* foreign = */ true, NULL);
- k = manager_drop_routes(link->manager);
+ k = manager_drop_marked_routes(link->manager);
if (k < 0 && r >= 0)
r = k;
return r;
}
-int link_drop_routes(Link *link) {
+int link_drop_managed_routes(Link *link) {
Route *route;
int k, r = 0;
@@ -973,6 +973,10 @@ int link_drop_routes(Link *link) {
if (route_by_kernel(route))
continue;
+ /* Do not touch routes managed by kernel or other tools. */
+ if (route->source == NETWORK_CONFIG_SOURCE_FOREIGN)
+ continue;
+
if (!route_exists(route))
continue;
@@ -983,7 +987,7 @@ int link_drop_routes(Link *link) {
manager_mark_routes(link->manager, /* foreign = */ false, link);
- k = manager_drop_routes(link->manager);
+ k = manager_drop_marked_routes(link->manager);
if (k < 0 && r >= 0)
r = k;
diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h
index 3471008fee..ee8e36f83d 100644
--- a/src/network/networkd-route.h
+++ b/src/network/networkd-route.h
@@ -82,7 +82,7 @@ int route_remove(Route *route);
int route_get(Manager *manager, Link *link, const Route *in, Route **ret);
-int link_drop_routes(Link *link);
+int link_drop_managed_routes(Link *link);
int link_drop_foreign_routes(Link *link);
void link_foreignize_routes(Link *link);
diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c
index 1f3dfa53b0..a17d74e316 100644
--- a/src/network/networkd-routing-policy-rule.c
+++ b/src/network/networkd-routing-policy-rule.c
@@ -653,8 +653,8 @@ static void manager_mark_routing_policy_rules(Manager *m, bool foreign, const Li
if (rule->protocol == RTPROT_KERNEL)
continue;
- /* When 'foreign' is true, do not remove rules we configured. */
- if (foreign && rule->source != NETWORK_CONFIG_SOURCE_FOREIGN)
+ /* When 'foreign' is true, mark only foreign rules, and vice versa. */
+ if (foreign != (rule->source == NETWORK_CONFIG_SOURCE_FOREIGN))
continue;
/* Ignore rules not assigned yet or already removing. */
diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h
index 1ab147caae..2d1ce19165 100644
--- a/src/network/networkd-routing-policy-rule.h
+++ b/src/network/networkd-routing-policy-rule.h
@@ -71,7 +71,7 @@ int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const L
static inline int manager_drop_foreign_routing_policy_rules(Manager *m) {
return manager_drop_routing_policy_rules_internal(m, true, NULL);
}
-static inline int link_drop_routing_policy_rules(Link *link) {
+static inline int link_drop_managed_routing_policy_rules(Link *link) {
assert(link);
return manager_drop_routing_policy_rules_internal(link->manager, false, link);
}
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
index ba16170393..9a2a839b40 100755
--- a/test/test-network/systemd-networkd-tests.py
+++ b/test/test-network/systemd-networkd-tests.py
@@ -3893,7 +3893,7 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
print(output)
self.assertRegex(output, 'NO-CARRIER')
self.assertNotRegex(output, '192.168.0.15/24')
- self.assertNotRegex(output, '192.168.0.16/24')
+ self.assertRegex(output, '192.168.0.16/24') # foreign address is kept
print('### ip -6 route list table all dev bridge99')
output = check_output('ip -6 route list table all dev bridge99')