summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-11-11 05:00:10 +0100
committerLuca Boccassi <bluca@debian.org>2024-11-11 14:59:41 +0100
commit688f166972916b5cfc9287055582ac1aeef3d486 (patch)
tree401340a862dcf833dea8244fe21b95d3033d43b7 /src/network
parentnetwork/route: forget IPv4 non-local routes when an interface went down (diff)
downloadsystemd-688f166972916b5cfc9287055582ac1aeef3d486.tar.xz
systemd-688f166972916b5cfc9287055582ac1aeef3d486.zip
network/nexthop: also forget IPv4 nexthops when an interface went down
Similar to the previous commit, but for nexthop.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkd-link.c1
-rw-r--r--src/network/networkd-nexthop.c55
-rw-r--r--src/network/networkd-nexthop.h1
3 files changed, 57 insertions, 0 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index ea09753dc5..082c7d1c38 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1895,6 +1895,7 @@ static int link_admin_state_up(Link *link) {
static int link_admin_state_down(Link *link) {
assert(link);
+ link_forget_nexthops(link);
link_forget_routes(link);
if (!link->network)
diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c
index 94df608222..0d6f881ca0 100644
--- a/src/network/networkd-nexthop.c
+++ b/src/network/networkd-nexthop.c
@@ -917,6 +917,61 @@ int link_drop_nexthops(Link *link, bool only_static) {
return r;
}
+static void nexthop_forget_one(NextHop *nexthop) {
+ assert(nexthop);
+ assert(nexthop->manager);
+
+ Request *req;
+ if (nexthop_get_request_by_id(nexthop->manager, nexthop->id, &req) >= 0)
+ route_enter_removed(req->userdata);
+
+ nexthop_enter_removed(nexthop);
+ log_nexthop_debug(nexthop, "Forgetting silently removed", nexthop->manager);
+ nexthop_forget_dependents(nexthop, nexthop->manager);
+ nexthop_detach(nexthop);
+}
+
+void link_forget_nexthops(Link *link) {
+ assert(link);
+ assert(link->manager);
+ assert(link->ifindex > 0);
+ assert(!FLAGS_SET(link->flags, IFF_UP));
+
+ /* See comments in link_forget_routes(). */
+
+ /* Remove all IPv4 nexthops. */
+ NextHop *nexthop;
+ HASHMAP_FOREACH(nexthop, link->manager->nexthops_by_id) {
+ if (nexthop->ifindex != link->ifindex)
+ continue;
+ if (nexthop->family != AF_INET)
+ continue;
+
+ nexthop_forget_one(nexthop);
+ }
+
+ /* Remove all group nexthops their all members are removed in the above. */
+ HASHMAP_FOREACH(nexthop, link->manager->nexthops_by_id) {
+ if (hashmap_isempty(nexthop->group))
+ continue;
+
+ /* Update group members. */
+ struct nexthop_grp *nhg;
+ HASHMAP_FOREACH(nhg, nexthop->group) {
+ if (nexthop_get_by_id(nexthop->manager, nhg->id, NULL) >= 0)
+ continue;
+
+ assert_se(hashmap_remove(nexthop->group, UINT32_TO_PTR(nhg->id)) == nhg);
+ free(nhg);
+ }
+
+ if (!hashmap_isempty(nexthop->group))
+ continue; /* At least one group member still exists. */
+
+ nexthop_forget_one(nexthop);
+ }
+}
+
static int nexthop_update_group(NextHop *nexthop, sd_netlink_message *message) {
_cleanup_hashmap_free_free_ Hashmap *h = NULL;
_cleanup_free_ struct nexthop_grp *group = NULL;
diff --git a/src/network/networkd-nexthop.h b/src/network/networkd-nexthop.h
index b6184503f4..de3f64c374 100644
--- a/src/network/networkd-nexthop.h
+++ b/src/network/networkd-nexthop.h
@@ -60,6 +60,7 @@ static inline int link_drop_unmanaged_nexthops(Link *link) {
static inline int link_drop_static_nexthops(Link *link) {
return link_drop_nexthops(link, /* only_static = */ true);
}
+void link_forget_nexthops(Link *link);
int link_request_static_nexthops(Link *link, bool only_ipv4);