diff options
| author | C. Andy Martin <cam@myfastmail.com> | 2023-06-08 12:32:49 -0400 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2023-06-14 04:16:59 -1000 |
| commit | 933033e54e4c0e1b5f2703c070c53fd5340c34c3 (patch) | |
| tree | c4d6384ca3bbe9784b95822382b2f4b0d58e37f1 | |
| parent | 20c192f0ecc8445a0e13a29b38329f762ec6b754 (diff) | |
| download | poky-933033e54e4c0e1b5f2703c070c53fd5340c34c3.tar.gz | |
systemd-networkd: backport fix for rm unmanaged wifi
Upstream v250 of systemd-newtorkd contains a race which will drop the
config of unmanaged wireless interfaces during reconfigure or carrier
loss. This bug is fixed in v251 by this commit:
commit a0e99a377a2f22c0ba460d3e7228214008714c14
Author: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon Jan 31 19:08:27 2022 +0900
network: remove only managed configs on reconfigure or carrier lost
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.
A bug was filed upstream on v250 to have upstream backport but was
rejected as "version-too-ancient", so backport this commit as a patch to
systemd-networkd for kirkstone.
Fixes: [YOCTO #15134]
(From OE-Core rev: 56fdf57d99900b8dfb75bf915fcab45d4c1a458e)
Signed-off-by: C. Andy Martin <cam@myfastmail.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
| -rw-r--r-- | meta/recipes-core/systemd/systemd/0001-network-remove-only-managed-configs-on-reconfigure-o.patch | 358 | ||||
| -rw-r--r-- | meta/recipes-core/systemd/systemd_250.5.bb | 1 |
2 files changed, 359 insertions, 0 deletions
diff --git a/meta/recipes-core/systemd/systemd/0001-network-remove-only-managed-configs-on-reconfigure-o.patch b/meta/recipes-core/systemd/systemd/0001-network-remove-only-managed-configs-on-reconfigure-o.patch new file mode 100644 index 0000000000..8950981d2e --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0001-network-remove-only-managed-configs-on-reconfigure-o.patch | |||
| @@ -0,0 +1,358 @@ | |||
| 1 | From 31b25c7d360a2ef2da1717aa39f190de5222d11a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Yu Watanabe <watanabe.yu+github@gmail.com> | ||
| 3 | Date: Mon, 31 Jan 2022 19:08:27 +0900 | ||
| 4 | Subject: [PATCH] network: remove only managed configs on reconfigure or | ||
| 5 | carrier lost | ||
| 6 | |||
| 7 | Otherwise, if the carrir of the non-managed interface is lost, the | ||
| 8 | configs such as addresses or routes on the interface will be removed by | ||
| 9 | networkd. | ||
| 10 | |||
| 11 | Upstream-Status: Backport [systemd v251 a0e99a377a2f22c0ba460d3e7228214008714c14] | ||
| 12 | Signed-off-by: C. Andy Martin <cam@myfastmail.com> | ||
| 13 | --- | ||
| 14 | src/network/networkd-address.c | 13 +++++-------- | ||
| 15 | src/network/networkd-address.h | 2 +- | ||
| 16 | src/network/networkd-link.c | 18 ++++++++++-------- | ||
| 17 | src/network/networkd-neighbor.c | 6 +++++- | ||
| 18 | src/network/networkd-neighbor.h | 2 +- | ||
| 19 | src/network/networkd-nexthop.c | 16 ++++++++++------ | ||
| 20 | src/network/networkd-nexthop.h | 2 +- | ||
| 21 | src/network/networkd-route.c | 16 ++++++++++------ | ||
| 22 | src/network/networkd-route.h | 2 +- | ||
| 23 | src/network/networkd-routing-policy-rule.c | 4 ++-- | ||
| 24 | src/network/networkd-routing-policy-rule.h | 2 +- | ||
| 25 | test/test-network/systemd-networkd-tests.py | 2 +- | ||
| 26 | 12 files changed, 48 insertions(+), 37 deletions(-) | ||
| 27 | |||
| 28 | diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c | ||
| 29 | index 7df743efb5..01c1d88dec 100644 | ||
| 30 | --- a/src/network/networkd-address.c | ||
| 31 | +++ b/src/network/networkd-address.c | ||
| 32 | @@ -891,22 +891,19 @@ int link_drop_foreign_addresses(Link *link) { | ||
| 33 | return r; | ||
| 34 | } | ||
| 35 | |||
| 36 | -int link_drop_addresses(Link *link) { | ||
| 37 | +int link_drop_managed_addresses(Link *link) { | ||
| 38 | Address *address; | ||
| 39 | int k, r = 0; | ||
| 40 | |||
| 41 | assert(link); | ||
| 42 | |||
| 43 | SET_FOREACH(address, link->addresses) { | ||
| 44 | - /* Ignore addresses not assigned yet or already removing. */ | ||
| 45 | - if (!address_exists(address)) | ||
| 46 | + /* Do not touch addresses managed by kernel or other tools. */ | ||
| 47 | + if (address->source == NETWORK_CONFIG_SOURCE_FOREIGN) | ||
| 48 | continue; | ||
| 49 | |||
| 50 | - /* Do not drop IPv6LL addresses assigned by the kernel here. They will be dropped in | ||
| 51 | - * link_drop_ipv6ll_addresses() if IPv6LL addressing is disabled. */ | ||
| 52 | - if (address->source == NETWORK_CONFIG_SOURCE_FOREIGN && | ||
| 53 | - address->family == AF_INET6 && | ||
| 54 | - in6_addr_is_link_local(&address->in_addr.in6)) | ||
| 55 | + /* Ignore addresses not assigned yet or already removing. */ | ||
| 56 | + if (!address_exists(address)) | ||
| 57 | continue; | ||
| 58 | |||
| 59 | k = address_remove(address); | ||
| 60 | diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h | ||
| 61 | index 41c4ce6fa4..b2110d8d21 100644 | ||
| 62 | --- a/src/network/networkd-address.h | ||
| 63 | +++ b/src/network/networkd-address.h | ||
| 64 | @@ -74,7 +74,7 @@ void address_set_broadcast(Address *a); | ||
| 65 | |||
| 66 | DEFINE_NETWORK_SECTION_FUNCTIONS(Address, address_free); | ||
| 67 | |||
| 68 | -int link_drop_addresses(Link *link); | ||
| 69 | +int link_drop_managed_addresses(Link *link); | ||
| 70 | int link_drop_foreign_addresses(Link *link); | ||
| 71 | int link_drop_ipv6ll_addresses(Link *link); | ||
| 72 | void link_foreignize_addresses(Link *link); | ||
| 73 | diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c | ||
| 74 | index b62a154828..12c592b257 100644 | ||
| 75 | --- a/src/network/networkd-link.c | ||
| 76 | +++ b/src/network/networkd-link.c | ||
| 77 | @@ -1070,27 +1070,27 @@ static int link_drop_foreign_config(Link *link) { | ||
| 78 | return r; | ||
| 79 | } | ||
| 80 | |||
| 81 | -static int link_drop_config(Link *link) { | ||
| 82 | +static int link_drop_managed_config(Link *link) { | ||
| 83 | int k, r; | ||
| 84 | |||
| 85 | assert(link); | ||
| 86 | assert(link->manager); | ||
| 87 | |||
| 88 | - r = link_drop_routes(link); | ||
| 89 | + r = link_drop_managed_routes(link); | ||
| 90 | |||
| 91 | - k = link_drop_nexthops(link); | ||
| 92 | + k = link_drop_managed_nexthops(link); | ||
| 93 | if (k < 0 && r >= 0) | ||
| 94 | r = k; | ||
| 95 | |||
| 96 | - k = link_drop_addresses(link); | ||
| 97 | + k = link_drop_managed_addresses(link); | ||
| 98 | if (k < 0 && r >= 0) | ||
| 99 | r = k; | ||
| 100 | |||
| 101 | - k = link_drop_neighbors(link); | ||
| 102 | + k = link_drop_managed_neighbors(link); | ||
| 103 | if (k < 0 && r >= 0) | ||
| 104 | r = k; | ||
| 105 | |||
| 106 | - k = link_drop_routing_policy_rules(link); | ||
| 107 | + k = link_drop_managed_routing_policy_rules(link); | ||
| 108 | if (k < 0 && r >= 0) | ||
| 109 | r = k; | ||
| 110 | |||
| 111 | @@ -1318,7 +1318,9 @@ static int link_reconfigure_impl(Link *link, bool force) { | ||
| 112 | * link_drop_foreign_config() in link_configure(). */ | ||
| 113 | link_foreignize_config(link); | ||
| 114 | else { | ||
| 115 | - r = link_drop_config(link); | ||
| 116 | + /* Remove all managed configs. Note, foreign configs are removed in later by | ||
| 117 | + * link_configure() -> link_drop_foreign_config() if the link is managed by us. */ | ||
| 118 | + r = link_drop_managed_config(link); | ||
| 119 | if (r < 0) | ||
| 120 | return r; | ||
| 121 | } | ||
| 122 | @@ -1705,7 +1707,7 @@ static int link_carrier_lost_impl(Link *link) { | ||
| 123 | if (r < 0) | ||
| 124 | ret = r; | ||
| 125 | |||
| 126 | - r = link_drop_config(link); | ||
| 127 | + r = link_drop_managed_config(link); | ||
| 128 | if (r < 0 && ret >= 0) | ||
| 129 | ret = r; | ||
| 130 | |||
| 131 | diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c | ||
| 132 | index 1766095e53..b58898a6dc 100644 | ||
| 133 | --- a/src/network/networkd-neighbor.c | ||
| 134 | +++ b/src/network/networkd-neighbor.c | ||
| 135 | @@ -406,13 +406,17 @@ int link_drop_foreign_neighbors(Link *link) { | ||
| 136 | return r; | ||
| 137 | } | ||
| 138 | |||
| 139 | -int link_drop_neighbors(Link *link) { | ||
| 140 | +int link_drop_managed_neighbors(Link *link) { | ||
| 141 | Neighbor *neighbor; | ||
| 142 | int k, r = 0; | ||
| 143 | |||
| 144 | assert(link); | ||
| 145 | |||
| 146 | SET_FOREACH(neighbor, link->neighbors) { | ||
| 147 | + /* Do not touch nexthops managed by kernel or other tools. */ | ||
| 148 | + if (neighbor->source == NETWORK_CONFIG_SOURCE_FOREIGN) | ||
| 149 | + continue; | ||
| 150 | + | ||
| 151 | /* Ignore neighbors not assigned yet or already removing. */ | ||
| 152 | if (!neighbor_exists(neighbor)) | ||
| 153 | continue; | ||
| 154 | diff --git a/src/network/networkd-neighbor.h b/src/network/networkd-neighbor.h | ||
| 155 | index e9e1854110..8e3c510cd5 100644 | ||
| 156 | --- a/src/network/networkd-neighbor.h | ||
| 157 | +++ b/src/network/networkd-neighbor.h | ||
| 158 | @@ -34,7 +34,7 @@ int neighbor_compare_func(const Neighbor *a, const Neighbor *b); | ||
| 159 | |||
| 160 | void network_drop_invalid_neighbors(Network *network); | ||
| 161 | |||
| 162 | -int link_drop_neighbors(Link *link); | ||
| 163 | +int link_drop_managed_neighbors(Link *link); | ||
| 164 | int link_drop_foreign_neighbors(Link *link); | ||
| 165 | void link_foreignize_neighbors(Link *link); | ||
| 166 | |||
| 167 | diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c | ||
| 168 | index b829aaab90..42aa8c4c59 100644 | ||
| 169 | --- a/src/network/networkd-nexthop.c | ||
| 170 | +++ b/src/network/networkd-nexthop.c | ||
| 171 | @@ -613,8 +613,8 @@ static void manager_mark_nexthops(Manager *manager, bool foreign, const Link *ex | ||
| 172 | if (nexthop->protocol == RTPROT_KERNEL) | ||
| 173 | continue; | ||
| 174 | |||
| 175 | - /* When 'foreign' is true, do not remove nexthops we configured. */ | ||
| 176 | - if (foreign && nexthop->source != NETWORK_CONFIG_SOURCE_FOREIGN) | ||
| 177 | + /* When 'foreign' is true, mark only foreign nexthops, and vice versa. */ | ||
| 178 | + if (foreign != (nexthop->source == NETWORK_CONFIG_SOURCE_FOREIGN)) | ||
| 179 | continue; | ||
| 180 | |||
| 181 | /* Ignore nexthops not assigned yet or already removed. */ | ||
| 182 | @@ -641,7 +641,7 @@ static void manager_mark_nexthops(Manager *manager, bool foreign, const Link *ex | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | -static int manager_drop_nexthops(Manager *manager) { | ||
| 187 | +static int manager_drop_marked_nexthops(Manager *manager) { | ||
| 188 | NextHop *nexthop; | ||
| 189 | int k, r = 0; | ||
| 190 | |||
| 191 | @@ -704,14 +704,14 @@ int link_drop_foreign_nexthops(Link *link) { | ||
| 192 | |||
| 193 | manager_mark_nexthops(link->manager, /* foreign = */ true, NULL); | ||
| 194 | |||
| 195 | - k = manager_drop_nexthops(link->manager); | ||
| 196 | + k = manager_drop_marked_nexthops(link->manager); | ||
| 197 | if (k < 0 && r >= 0) | ||
| 198 | r = k; | ||
| 199 | |||
| 200 | return r; | ||
| 201 | } | ||
| 202 | |||
| 203 | -int link_drop_nexthops(Link *link) { | ||
| 204 | +int link_drop_managed_nexthops(Link *link) { | ||
| 205 | NextHop *nexthop; | ||
| 206 | int k, r = 0; | ||
| 207 | |||
| 208 | @@ -723,6 +723,10 @@ int link_drop_nexthops(Link *link) { | ||
| 209 | if (nexthop->protocol == RTPROT_KERNEL) | ||
| 210 | continue; | ||
| 211 | |||
| 212 | + /* Do not touch addresses managed by kernel or other tools. */ | ||
| 213 | + if (nexthop->source == NETWORK_CONFIG_SOURCE_FOREIGN) | ||
| 214 | + continue; | ||
| 215 | + | ||
| 216 | /* Ignore nexthops not assigned yet or already removing. */ | ||
| 217 | if (!nexthop_exists(nexthop)) | ||
| 218 | continue; | ||
| 219 | @@ -734,7 +738,7 @@ int link_drop_nexthops(Link *link) { | ||
| 220 | |||
| 221 | manager_mark_nexthops(link->manager, /* foreign = */ false, link); | ||
| 222 | |||
| 223 | - k = manager_drop_nexthops(link->manager); | ||
| 224 | + k = manager_drop_marked_nexthops(link->manager); | ||
| 225 | if (k < 0 && r >= 0) | ||
| 226 | r = k; | ||
| 227 | |||
| 228 | diff --git a/src/network/networkd-nexthop.h b/src/network/networkd-nexthop.h | ||
| 229 | index 7a8920238c..1e54e9f211 100644 | ||
| 230 | --- a/src/network/networkd-nexthop.h | ||
| 231 | +++ b/src/network/networkd-nexthop.h | ||
| 232 | @@ -44,7 +44,7 @@ int nexthop_compare_func(const NextHop *a, const NextHop *b); | ||
| 233 | |||
| 234 | void network_drop_invalid_nexthops(Network *network); | ||
| 235 | |||
| 236 | -int link_drop_nexthops(Link *link); | ||
| 237 | +int link_drop_managed_nexthops(Link *link); | ||
| 238 | int link_drop_foreign_nexthops(Link *link); | ||
| 239 | void link_foreignize_nexthops(Link *link); | ||
| 240 | |||
| 241 | diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c | ||
| 242 | index ee7a535075..7e6fe8bc11 100644 | ||
| 243 | --- a/src/network/networkd-route.c | ||
| 244 | +++ b/src/network/networkd-route.c | ||
| 245 | @@ -788,8 +788,8 @@ static void manager_mark_routes(Manager *manager, bool foreign, const Link *exce | ||
| 246 | if (route->protocol == RTPROT_KERNEL) | ||
| 247 | continue; | ||
| 248 | |||
| 249 | - /* When 'foreign' is true, do not remove routes we configured. */ | ||
| 250 | - if (foreign && route->source != NETWORK_CONFIG_SOURCE_FOREIGN) | ||
| 251 | + /* When 'foreign' is true, mark only foreign routes, and vice versa. */ | ||
| 252 | + if (foreign != (route->source == NETWORK_CONFIG_SOURCE_FOREIGN)) | ||
| 253 | continue; | ||
| 254 | |||
| 255 | /* Do not touch dynamic routes. They will removed by dhcp_pd_prefix_lost() */ | ||
| 256 | @@ -834,7 +834,7 @@ static void manager_mark_routes(Manager *manager, bool foreign, const Link *exce | ||
| 257 | } | ||
| 258 | } | ||
| 259 | |||
| 260 | -static int manager_drop_routes(Manager *manager) { | ||
| 261 | +static int manager_drop_marked_routes(Manager *manager) { | ||
| 262 | Route *route; | ||
| 263 | int k, r = 0; | ||
| 264 | |||
| 265 | @@ -955,14 +955,14 @@ int link_drop_foreign_routes(Link *link) { | ||
| 266 | |||
| 267 | manager_mark_routes(link->manager, /* foreign = */ true, NULL); | ||
| 268 | |||
| 269 | - k = manager_drop_routes(link->manager); | ||
| 270 | + k = manager_drop_marked_routes(link->manager); | ||
| 271 | if (k < 0 && r >= 0) | ||
| 272 | r = k; | ||
| 273 | |||
| 274 | return r; | ||
| 275 | } | ||
| 276 | |||
| 277 | -int link_drop_routes(Link *link) { | ||
| 278 | +int link_drop_managed_routes(Link *link) { | ||
| 279 | Route *route; | ||
| 280 | int k, r = 0; | ||
| 281 | |||
| 282 | @@ -973,6 +973,10 @@ int link_drop_routes(Link *link) { | ||
| 283 | if (route_by_kernel(route)) | ||
| 284 | continue; | ||
| 285 | |||
| 286 | + /* Do not touch routes managed by kernel or other tools. */ | ||
| 287 | + if (route->source == NETWORK_CONFIG_SOURCE_FOREIGN) | ||
| 288 | + continue; | ||
| 289 | + | ||
| 290 | if (!route_exists(route)) | ||
| 291 | continue; | ||
| 292 | |||
| 293 | @@ -983,7 +987,7 @@ int link_drop_routes(Link *link) { | ||
| 294 | |||
| 295 | manager_mark_routes(link->manager, /* foreign = */ false, link); | ||
| 296 | |||
| 297 | - k = manager_drop_routes(link->manager); | ||
| 298 | + k = manager_drop_marked_routes(link->manager); | ||
| 299 | if (k < 0 && r >= 0) | ||
| 300 | r = k; | ||
| 301 | |||
| 302 | diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h | ||
| 303 | index e3e22a5985..2180a196fc 100644 | ||
| 304 | --- a/src/network/networkd-route.h | ||
| 305 | +++ b/src/network/networkd-route.h | ||
| 306 | @@ -82,7 +82,7 @@ int route_remove(Route *route); | ||
| 307 | |||
| 308 | int route_get(Manager *manager, Link *link, const Route *in, Route **ret); | ||
| 309 | |||
| 310 | -int link_drop_routes(Link *link); | ||
| 311 | +int link_drop_managed_routes(Link *link); | ||
| 312 | int link_drop_foreign_routes(Link *link); | ||
| 313 | void link_foreignize_routes(Link *link); | ||
| 314 | |||
| 315 | diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c | ||
| 316 | index 90086f35a7..d4363060d8 100644 | ||
| 317 | --- a/src/network/networkd-routing-policy-rule.c | ||
| 318 | +++ b/src/network/networkd-routing-policy-rule.c | ||
| 319 | @@ -653,8 +653,8 @@ static void manager_mark_routing_policy_rules(Manager *m, bool foreign, const Li | ||
| 320 | if (rule->protocol == RTPROT_KERNEL) | ||
| 321 | continue; | ||
| 322 | |||
| 323 | - /* When 'foreign' is true, do not remove rules we configured. */ | ||
| 324 | - if (foreign && rule->source != NETWORK_CONFIG_SOURCE_FOREIGN) | ||
| 325 | + /* When 'foreign' is true, mark only foreign rules, and vice versa. */ | ||
| 326 | + if (foreign != (rule->source == NETWORK_CONFIG_SOURCE_FOREIGN)) | ||
| 327 | continue; | ||
| 328 | |||
| 329 | /* Ignore rules not assigned yet or already removing. */ | ||
| 330 | diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h | ||
| 331 | index f52943bd2e..7cc6f55c8d 100644 | ||
| 332 | --- a/src/network/networkd-routing-policy-rule.h | ||
| 333 | +++ b/src/network/networkd-routing-policy-rule.h | ||
| 334 | @@ -71,7 +71,7 @@ int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const L | ||
| 335 | static inline int manager_drop_foreign_routing_policy_rules(Manager *m) { | ||
| 336 | return manager_drop_routing_policy_rules_internal(m, true, NULL); | ||
| 337 | } | ||
| 338 | -static inline int link_drop_routing_policy_rules(Link *link) { | ||
| 339 | +static inline int link_drop_managed_routing_policy_rules(Link *link) { | ||
| 340 | assert(link); | ||
| 341 | return manager_drop_routing_policy_rules_internal(link->manager, false, link); | ||
| 342 | } | ||
| 343 | diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py | ||
| 344 | index ac2c1ba034..ed4d4992b1 100755 | ||
| 345 | --- a/test/test-network/systemd-networkd-tests.py | ||
| 346 | +++ b/test/test-network/systemd-networkd-tests.py | ||
| 347 | @@ -3876,7 +3876,7 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities): | ||
| 348 | print(output) | ||
| 349 | self.assertRegex(output, 'NO-CARRIER') | ||
| 350 | self.assertNotRegex(output, '192.168.0.15/24') | ||
| 351 | - self.assertNotRegex(output, '192.168.0.16/24') | ||
| 352 | + self.assertRegex(output, '192.168.0.16/24') # foreign address is kept | ||
| 353 | |||
| 354 | print('### ip -6 route list table all dev bridge99') | ||
| 355 | output = check_output('ip -6 route list table all dev bridge99') | ||
| 356 | -- | ||
| 357 | 2.34.1 | ||
| 358 | |||
diff --git a/meta/recipes-core/systemd/systemd_250.5.bb b/meta/recipes-core/systemd/systemd_250.5.bb index 784a7af271..21a09d8594 100644 --- a/meta/recipes-core/systemd/systemd_250.5.bb +++ b/meta/recipes-core/systemd/systemd_250.5.bb | |||
| @@ -30,6 +30,7 @@ SRC_URI += "file://touchscreen.rules \ | |||
| 30 | file://0001-shared-json-allow-json_variant_dump-to-return-an-err.patch \ | 30 | file://0001-shared-json-allow-json_variant_dump-to-return-an-err.patch \ |
| 31 | file://CVE-2022-4415-1.patch \ | 31 | file://CVE-2022-4415-1.patch \ |
| 32 | file://CVE-2022-4415-2.patch \ | 32 | file://CVE-2022-4415-2.patch \ |
| 33 | file://0001-network-remove-only-managed-configs-on-reconfigure-o.patch \ | ||
| 33 | " | 34 | " |
| 34 | 35 | ||
| 35 | # patches needed by musl | 36 | # patches needed by musl |
