]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: remove only managed configs on reconfigure or carrier lost
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 31 Jan 2022 10:08:27 +0000 (19:08 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 1 Feb 2022 02:30:37 +0000 (11:30 +0900)
Otherwise, if the carrir of the non-managed interface is lost, the
configs such as addresses or routes on the interface will be removed by
networkd.

12 files changed:
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
test/test-network/systemd-networkd-tests.py

index ff80f185ceac50dd25d377414e90bbe5a34e77b6..b5091bb5980eef907dd19c19d539afe371d16782 100644 (file)
@@ -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);
index c1e5b3ce3a762a846e2231f60cc124a86f37830b..682f7e80e4fe980333701947c76018e0961ecdf6 100644 (file)
@@ -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);
index a8de644559bde59e1bdd33b4e0990e760a6ecfd7..3c5f3483bb19649c7dd690179fe77cd9a414234e 100644 (file)
@@ -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;
 
index 4aab290bf803e7c2a575260ea342c280015c2696..4f13053082be86844e5026e583e978aeed8a2b75 100644 (file)
@@ -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;
index f31f58a4d4ea4e6059c14257dbfe1059e3fcf610..ac1678de181dd1efd54d26d1c5bf113e97f59fe8 100644 (file)
@@ -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);
 
index e9e5d08557bd6a7047d73b90d7d4b0f2f4f15a81..b2bc0dc570f9d384d66cf427cea872910fc543b7 100644 (file)
@@ -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;
 
index 01b29ae560294454c87b175ea7e41ef8d6c2f036..16eb02f7eb94f19ea07bc6047bdfd94b89ea0840 100644 (file)
@@ -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);
 
index 03021362b6cb7851d8a95e406bdfc8bd041db904..3a2e4490c12a68f3d421e70ff44d3d30eda20a49 100644 (file)
@@ -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;
 
index 3471008fee7145bb565c74cfa14f0ea57d8dd7e7..ee8e36f83db2a7b090916a95a200f37907722e15 100644 (file)
@@ -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);
 
index 1f3dfa53b0ccdc8ef516f5a29f3f74b2491c302b..a17d74e3165ab7464ebb001bd3689090c0b94e19 100644 (file)
@@ -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. */
index 1ab147caae7b37b99ce35600c759465d832f6c71..2d1ce19165e06bb41966a141610cad0b0e6a1bbb 100644 (file)
@@ -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);
 }
index ba1617039357492482661fe9595ae6c537f826cb..9a2a839b40579f038e07e511f1cbc04a081ddc84 100755 (executable)
@@ -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')