diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-11-11 05:00:10 +0100 |
---|---|---|
committer | Luca Boccassi <bluca@debian.org> | 2024-11-11 14:59:41 +0100 |
commit | 688f166972916b5cfc9287055582ac1aeef3d486 (patch) | |
tree | 401340a862dcf833dea8244fe21b95d3033d43b7 /src/network | |
parent | network/route: forget IPv4 non-local routes when an interface went down (diff) | |
download | systemd-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.c | 1 | ||||
-rw-r--r-- | src/network/networkd-nexthop.c | 55 | ||||
-rw-r--r-- | src/network/networkd-nexthop.h | 1 |
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); |