]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: introduce address_forget() and friends and use it where applicable
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 20 Nov 2024 17:35:29 +0000 (02:35 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 11 Dec 2024 02:21:14 +0000 (11:21 +0900)
No functional change, just refactoring.

src/network/networkd-address.c
src/network/networkd-neighbor.c
src/network/networkd-nexthop.c
src/network/networkd-route.c
src/network/networkd-routing-policy-rule.c

index 0b7fbec28b9ce7d434bf2a947a57e6c13eb750c5..bc5bfb8e8347820e18332b849c5fbee828c37224 100644 (file)
@@ -1129,6 +1129,23 @@ void log_address_debug(const Address *address, const char *str, const Link *link
                        address->family == AF_INET ? strna(address->label) : "");
 }
 
+static void address_forget(Link *link, Address *address, bool removed_by_us, const char *msg) {
+        assert(link);
+        assert(address);
+        assert(msg);
+
+        Request *req;
+        if (address_get_request(link, address, &req) >= 0)
+                address_enter_removed(req->userdata);
+
+        if (!address->link && address_get(link, address, &address) < 0)
+                return;
+
+        address_enter_removed(address);
+        log_address_debug(address, msg, link);
+        (void) address_drop(address, removed_by_us);
+}
+
 static int address_set_netlink_message(const Address *address, sd_netlink_message *m, Link *link) {
         uint32_t flags;
         int r;
@@ -1181,16 +1198,8 @@ static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Remov
                                             (r == -EADDRNOTAVAIL || !address->link) ? LOG_DEBUG : LOG_WARNING,
                                             r, "Could not drop address");
 
-                if (address->link) {
-                        /* If the address cannot be removed, then assume the address is already removed. */
-                        log_address_debug(address, "Forgetting", link);
-
-                        Request *req;
-                        if (address_get_request(link, address, &req) >= 0)
-                                address_enter_removed(req->userdata);
-
-                        (void) address_drop(address, /* removed_by_us = */ true);
-                }
+                /* If the address cannot be removed, then assume the address is already removed. */
+                address_forget(link, address, /* removed_by_us = */ true, "Forgetting");
         }
 
         return 1;
@@ -1775,14 +1784,7 @@ int link_request_static_addresses(Link *link) {
 }
 
 int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
-        _cleanup_(address_unrefp) Address *tmp = NULL;
-        struct ifa_cacheinfo cinfo;
-        Link *link;
-        uint16_t type;
-        Address *address = NULL;
-        Request *req = NULL;
-        bool is_new = false, update_dhcp4;
-        int ifindex, r;
+        int r;
 
         assert(rtnl);
         assert(message);
@@ -1796,6 +1798,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        uint16_t type;
         r = sd_netlink_message_get_type(message, &type);
         if (r < 0) {
                 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
@@ -1805,6 +1808,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        int ifindex;
         r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
         if (r < 0) {
                 log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
@@ -1814,6 +1818,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        Link *link;
         r = link_get_by_index(m, ifindex, &link);
         if (r < 0) {
                 /* when enumerating we might be out of sync, but we will get the address again, so just
@@ -1823,6 +1828,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        _cleanup_(address_unrefp) Address *tmp = NULL;
         r = address_new(&tmp);
         if (r < 0)
                 return log_oom();
@@ -1890,28 +1896,22 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
                 assert_not_reached();
         }
 
-        update_dhcp4 = tmp->family == AF_INET6;
-
-        /* Then, find the managed Address and Request objects corresponding to the received address. */
+        /* Then, find the managed Address object corresponding to the received address. */
+        Address *address = NULL;
         (void) address_get(link, tmp, &address);
-        (void) address_get_request(link, tmp, &req);
 
         if (type == RTM_DELADDR) {
-                if (address) {
-                        bool removed_by_us = FLAGS_SET(address->state, NETWORK_CONFIG_STATE_REMOVING);
-
-                        address_enter_removed(address);
-                        log_address_debug(address, "Forgetting removed", link);
-                        (void) address_drop(address, removed_by_us);
-                } else
+                if (address)
+                        address_forget(link, address,
+                                       /* removed_by_us = */ FLAGS_SET(address->state, NETWORK_CONFIG_STATE_REMOVING),
+                                       "Forgetting removed");
+                else
                         log_address_debug(tmp, "Kernel removed unknown", link);
 
-                if (req)
-                        address_enter_removed(req->userdata);
-
                 goto finalize;
         }
 
+        bool is_new = false;
         if (!address) {
                 /* If we did not know the address, then save it. */
                 r = address_attach(link, tmp);
@@ -1931,6 +1931,8 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
         }
 
         /* Also update information that cannot be obtained through netlink notification. */
+        Request *req = NULL;
+        (void) address_get_request(link, tmp, &req);
         if (req && req->waiting_reply) {
                 Address *a = ASSERT_PTR(req->userdata);
 
@@ -1978,6 +1980,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
         } else if (r < 0)
                 log_link_debug_errno(link, r, "rtnl: failed to read IFA_FLAGS attribute, ignoring: %m");
 
+        struct ifa_cacheinfo cinfo;
         r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
         if (r >= 0)
                 address_set_lifetime(m, address, &cinfo);
@@ -2000,7 +2003,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
                 link_enter_failed(link);
 
 finalize:
-        if (update_dhcp4) {
+        if (tmp->family == AF_INET6) {
                 r = dhcp4_update_ipv6_connectivity(link);
                 if (r < 0) {
                         log_link_warning_errno(link, r, "Failed to notify IPv6 connectivity to DHCPv4 client: %m");
index 83275f2fc8dd7db5d7e73ce13a6e5750ffece7dd..c953f89daa6c87cbf19a1e566f1d5b11822e1319 100644 (file)
@@ -247,6 +247,23 @@ static void log_neighbor_debug(const Neighbor *neighbor, const char *str, const
                        IN_ADDR_TO_STRING(neighbor->dst_addr.family, &neighbor->dst_addr.address));
 }
 
+static void neighbor_forget(Link *link, Neighbor *neighbor, const char *msg) {
+        assert(link);
+        assert(neighbor);
+        assert(msg);
+
+        Request *req;
+        if (neighbor_get_request(link, neighbor, &req) >= 0)
+                neighbor_enter_removed(req->userdata);
+
+        if (!neighbor->link && neighbor_get(link, neighbor, &neighbor) < 0)
+                return;
+
+        neighbor_enter_removed(neighbor);
+        log_neighbor_debug(neighbor, "Forgetting", link);
+        neighbor_detach(neighbor);
+}
+
 static int neighbor_configure(Neighbor *neighbor, Link *link, Request *req) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
         int r;
@@ -421,16 +438,8 @@ static int neighbor_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Remo
                                             (r == -ESRCH || !neighbor->link) ? LOG_DEBUG : LOG_WARNING,
                                             r, "Could not remove neighbor");
 
-                if (neighbor->link) {
-                        /* If the neighbor cannot be removed, then assume the neighbor is already removed. */
-                        log_neighbor_debug(neighbor, "Forgetting", link);
-
-                        Request *req;
-                        if (neighbor_get_request(link, neighbor, &req) >= 0)
-                                neighbor_enter_removed(req->userdata);
-
-                        neighbor_detach(neighbor);
-                }
+                /* If the neighbor cannot be removed, then assume the neighbor is already removed. */
+                neighbor_forget(link, neighbor, "Forgetting");
         }
 
         return 1;
@@ -529,13 +538,7 @@ int link_drop_static_neighbors(Link *link) {
 }
 
 int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
-        _cleanup_(neighbor_unrefp) Neighbor *tmp = NULL;
-        Neighbor *neighbor = NULL;
-        Request *req = NULL;
-        uint16_t type, state;
-        bool is_new = false;
-        int ifindex, r;
-        Link *link;
+        int r;
 
         assert(rtnl);
         assert(message);
@@ -549,6 +552,7 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        uint16_t type;
         r = sd_netlink_message_get_type(message, &type);
         if (r < 0) {
                 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
@@ -558,6 +562,7 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        uint16_t state;
         r = sd_rtnl_message_neigh_get_state(message, &state);
         if (r < 0) {
                 log_warning_errno(r, "rtnl: received neighbor message with invalid state, ignoring: %m");
@@ -566,6 +571,7 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
                 /* Currently, we are interested in only static neighbors. */
                 return 0;
 
+        int ifindex;
         r = sd_rtnl_message_neigh_get_ifindex(message, &ifindex);
         if (r < 0) {
                 log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
@@ -575,12 +581,14 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        Link *link;
         r = link_get_by_index(m, ifindex, &link);
         if (r < 0)
                 /* when enumerating we might be out of sync, but we will get the neighbor again. Also,
                  * kernel sends messages about neighbors after a link is removed. So, just ignore it. */
                 return 0;
 
+        _cleanup_(neighbor_unrefp) Neighbor *tmp = NULL;
         r = neighbor_new(&tmp);
         if (r < 0)
                 return log_oom();
@@ -604,25 +612,20 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
-        /* Then, find the managed Neighbor and Request objects corresponding to the netlink notification. */
+        /* Then, find the managed Neighbor object corresponding to the netlink notification. */
+        Neighbor *neighbor = NULL;
         (void) neighbor_get(link, tmp, &neighbor);
-        (void) neighbor_get_request(link, tmp, &req);
 
         if (type == RTM_DELNEIGH) {
-                if (neighbor) {
-                        neighbor_enter_removed(neighbor);
-                        log_neighbor_debug(neighbor, "Forgetting removed", link);
-                        neighbor_detach(neighbor);
-                } else
+                if (neighbor)
+                        neighbor_forget(link, neighbor, "Forgetting removed");
+                else
                         log_neighbor_debug(tmp, "Kernel removed unknown", link);
-
-                if (req)
-                        neighbor_enter_removed(req->userdata);
-
                 return 0;
         }
 
         /* If we did not know the neighbor, then save it. */
+        bool is_new = false;
         if (!neighbor) {
                 r = neighbor_attach(link, tmp);
                 if (r < 0) {
@@ -634,6 +637,8 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
         }
 
         /* Also update information that cannot be obtained through netlink notification. */
+        Request *req = NULL;
+        (void) neighbor_get_request(link, tmp, &req);
         if (req && req->waiting_reply) {
                 Neighbor *n = ASSERT_PTR(req->userdata);
 
index e27ecf05f986ce0762e7af4baba07d4186fb041b..7aa7bd6f6d707bdb381bab723eb6f73c0ce9b072 100644 (file)
@@ -510,6 +510,24 @@ static void nexthop_forget_dependents(NextHop *nexthop, Manager *manager) {
         nexthop->routes = set_free(nexthop->routes);
 }
 
+static void nexthop_forget(Manager *manager, NextHop *nexthop, const char *msg) {
+        assert(manager);
+        assert(nexthop);
+        assert(msg);
+
+        Request *req;
+        if (nexthop_get_request_by_id(manager, nexthop->id, &req) >= 0)
+                nexthop_enter_removed(req->userdata);
+
+        if (!nexthop->manager && nexthop_get_by_id(manager, nexthop->id, &nexthop) < 0)
+                return;
+
+        nexthop_enter_removed(nexthop);
+        log_nexthop_debug(nexthop, msg, manager);
+        nexthop_forget_dependents(nexthop, nexthop->manager);
+        nexthop_detach(nexthop);
+}
+
 static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, RemoveRequest *rreq) {
         int r;
 
@@ -525,18 +543,8 @@ static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Remov
                                        (r == -ENOENT || !nexthop->manager) ? LOG_DEBUG : LOG_WARNING,
                                        r, "Could not drop nexthop, ignoring");
 
-                nexthop_forget_dependents(nexthop, manager);
-
-                if (nexthop->manager) {
-                        /* If the nexthop cannot be removed, then assume the nexthop is already removed. */
-                        log_nexthop_debug(nexthop, "Forgetting", manager);
-
-                        Request *req;
-                        if (nexthop_get_request_by_id(manager, nexthop->id, &req) >= 0)
-                                nexthop_enter_removed(req->userdata);
-
-                        nexthop_detach(nexthop);
-                }
+                /* If the nexthop cannot be removed, then assume the nexthop is already removed. */
+                nexthop_forget(manager, nexthop, "Forgetting");
         }
 
         return 1;
@@ -969,20 +977,6 @@ 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)
-                nexthop_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);
@@ -999,7 +993,7 @@ void link_forget_nexthops(Link *link) {
                 if (nexthop->family != AF_INET)
                         continue;
 
-                nexthop_forget_one(nexthop);
+                nexthop_forget(link->manager, nexthop, "Forgetting silently removed");
         }
 
         /* Remove all group nexthops their all members are removed in the above. */
@@ -1020,7 +1014,7 @@ void link_forget_nexthops(Link *link) {
                 if (!hashmap_isempty(nexthop->group))
                         continue; /* At least one group member still exists. */
 
-                nexthop_forget_one(nexthop);
+                nexthop_forget(link->manager, nexthop, "Forgetting silently removed");
         }
 }
 
@@ -1084,11 +1078,6 @@ static int nexthop_update_group(NextHop *nexthop, sd_netlink_message *message) {
 }
 
 int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
-        uint16_t type;
-        uint32_t id, ifindex;
-        NextHop *nexthop = NULL;
-        Request *req = NULL;
-        bool is_new = false;
         int r;
 
         assert(rtnl);
@@ -1103,6 +1092,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        uint16_t type;
         r = sd_netlink_message_get_type(message, &type);
         if (r < 0) {
                 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
@@ -1112,6 +1102,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        uint32_t id;
         r = sd_netlink_message_read_u32(message, NHA_ID, &id);
         if (r == -ENODATA) {
                 log_warning_errno(r, "rtnl: received nexthop message without NHA_ID attribute, ignoring: %m");
@@ -1124,25 +1115,23 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        NextHop *nexthop = NULL;
         (void) nexthop_get_by_id(m, id, &nexthop);
-        (void) nexthop_get_request_by_id(m, id, &req);
 
         if (type == RTM_DELNEXTHOP) {
-                if (nexthop) {
-                        nexthop_enter_removed(nexthop);
-                        log_nexthop_debug(nexthop, "Forgetting removed", m);
-                        nexthop_forget_dependents(nexthop, m);
-                        nexthop_detach(nexthop);
-                } else
+                if (nexthop)
+                        nexthop_forget(m, nexthop, "Forgetting removed");
+                else
                         log_nexthop_debug(&(const NextHop) { .id = id }, "Kernel removed unknown", m);
 
-                if (req)
-                        nexthop_enter_removed(req->userdata);
-
                 return 0;
         }
 
+        Request *req = NULL;
+        (void) nexthop_get_request_by_id(m, id, &req);
+
         /* If we did not know the nexthop, then save it. */
+        bool is_new = false;
         if (!nexthop) {
                 if (!req && !m->manage_foreign_nexthops) {
                         log_nexthop_debug(&(const NextHop) { .id = id }, "Ignoring received", m);
@@ -1194,6 +1183,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
         else
                 nexthop->blackhole = r;
 
+        uint32_t ifindex;
         r = sd_netlink_message_read_u32(message, NHA_OIF, &ifindex);
         if (r == -ENODATA)
                 nexthop->ifindex = 0;
index 0f3f79ec4fe099a93cb1a78733dda9b8404cd327..f6386e0426ad2fd99099696d3198f3a756e4a19d 100644 (file)
@@ -460,6 +460,23 @@ void log_route_debug(const Route *route, const char *str, Manager *manager) {
                        strna(proto), strna(scope), strna(route_type_to_string(route->type)), strna(flags));
 }
 
+static void route_forget(Manager *manager, Route *route, const char *msg) {
+        assert(manager);
+        assert(route);
+        assert(msg);
+
+        Request *req;
+        if (route_get_request(manager, route, &req) >= 0)
+                route_enter_removed(req->userdata);
+
+        if (!route->manager && route_get(manager, route, &route) < 0)
+                return;
+
+        route_enter_removed(route);
+        log_route_debug(route, msg, manager);
+        route_detach(route);
+}
+
 static int route_set_netlink_message(const Route *route, sd_netlink_message *m) {
         int r;
 
@@ -564,16 +581,8 @@ static int route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, RemoveR
                                        LOG_DEBUG : LOG_WARNING,
                                        r, "Could not drop route, ignoring");
 
-                if (route->manager) {
-                        /* If the route cannot be removed, then assume the route is already removed. */
-                        log_route_debug(route, "Forgetting", manager);
-
-                        Request *req;
-                        if (route_get_request(manager, route, &req) >= 0)
-                                route_enter_removed(req->userdata);
-
-                        route_detach(route);
-                }
+                /* If the route cannot be removed, then assume the route is already removed. */
+                route_forget(manager, route, "Forgetting");
         }
 
         return 1;
@@ -1088,7 +1097,6 @@ static int process_route_one(
                 Route *tmp,
                 const struct rta_cacheinfo *cacheinfo) {
 
-        Request *req = NULL;
         Route *route = NULL;
         Link *link = NULL;
         bool is_new = false, update_dhcp4;
@@ -1099,13 +1107,15 @@ static int process_route_one(
         assert(IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE));
 
         (void) route_get(manager, tmp, &route);
-        (void) route_get_request(manager, tmp, &req);
         (void) route_get_link(manager, tmp, &link);
 
         update_dhcp4 = link && tmp->family == AF_INET6 && tmp->dst_prefixlen == 0;
 
         switch (type) {
-        case RTM_NEWROUTE:
+        case RTM_NEWROUTE: {
+                Request *req = NULL;
+                (void) route_get_request(manager, tmp, &req);
+
                 if (!route) {
                         if (!manager->manage_foreign_routes && !(req && req->waiting_reply)) {
                                 route_enter_configured(tmp);
@@ -1159,20 +1169,14 @@ static int process_route_one(
                 (void) route_setup_timer(route, cacheinfo);
 
                 break;
-
+        }
         case RTM_DELROUTE:
-                if (route) {
-                        route_enter_removed(route);
-                        log_route_debug(route, "Forgetting removed", manager);
-                        route_detach(route);
-                } else
+                if (route)
+                        route_forget(manager, route, "Forgetting removed");
+                else
                         log_route_debug(tmp,
                                         manager->manage_foreign_routes ? "Kernel removed unknown" : "Ignoring received",
                                         manager);
-
-                if (req)
-                        route_enter_removed(req->userdata);
-
                 break;
 
         default:
@@ -1574,13 +1578,7 @@ void link_forget_routes(Link *link) {
                 if (!IN_SET(route->type, RTN_UNICAST, RTN_BROADCAST, RTN_ANYCAST, RTN_MULTICAST))
                         continue;
 
-                Request *req;
-                if (route_get_request(link->manager, route, &req) >= 0)
-                        route_enter_removed(req->userdata);
-
-                route_enter_removed(route);
-                log_route_debug(route, "Forgetting silently removed", link->manager);
-                route_detach(route);
+                route_forget(link->manager, route, "Forgetting silently removed");
         }
 }
 
index 1a04af63598dc461418313ed6597981e66f39d01..87dcaa4fc44b7896a9f67868c1718ef7d0ce9376 100644 (file)
@@ -550,6 +550,23 @@ static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, const c
                        strna(rule->iif), strna(rule->oif), strna(table));
 }
 
+static void routing_policy_rule_forget(Manager *manager, RoutingPolicyRule *rule, const char *msg) {
+        assert(manager);
+        assert(rule);
+        assert(msg);
+
+        Request *req;
+        if (routing_policy_rule_get_request(manager, rule, rule->family, &req) >= 0)
+                routing_policy_rule_enter_removed(req->userdata);
+
+        if (!rule->manager && routing_policy_rule_get(manager, rule, rule->family, &rule) < 0)
+                return;
+
+        routing_policy_rule_enter_removed(rule);
+        log_routing_policy_rule_debug(rule, "Forgetting", NULL, manager);
+        routing_policy_rule_detach(rule);
+}
+
 static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule, sd_netlink_message *m) {
         int r;
 
@@ -708,16 +725,8 @@ static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_messa
                                        (r == -ENOENT || !rule->manager) ? LOG_DEBUG : LOG_WARNING,
                                        r, "Could not drop routing policy rule, ignoring");
 
-                if (rule->manager) {
-                        /* If the rule cannot be removed, then assume the rule is already removed. */
-                        log_routing_policy_rule_debug(rule, "Forgetting", NULL, manager);
-
-                        Request *req;
-                        if (routing_policy_rule_get_request(manager, rule, rule->family, &req) >= 0)
-                                routing_policy_rule_enter_removed(req->userdata);
-
-                        routing_policy_rule_detach(rule);
-                }
+                /* If the rule cannot be removed, then assume the rule is already removed. */
+                routing_policy_rule_forget(manager, rule, "Forgetting");
         }
 
         return 1;
@@ -1046,10 +1055,6 @@ static bool routing_policy_rule_is_created_by_kernel(const RoutingPolicyRule *ru
 }
 
 int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
-        _cleanup_(routing_policy_rule_unrefp) RoutingPolicyRule *tmp = NULL;
-        RoutingPolicyRule *rule = NULL;
-        Request *req = NULL;
-        uint16_t type;
         int r;
 
         assert(rtnl);
@@ -1063,6 +1068,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
                 return 0;
         }
 
+        uint16_t type;
         r = sd_netlink_message_get_type(message, &type);
         if (r < 0) {
                 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
@@ -1072,6 +1078,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
                 return 0;
         }
 
+        _cleanup_(routing_policy_rule_unrefp) RoutingPolicyRule *tmp = NULL;
         r = routing_policy_rule_new(&tmp);
         if (r < 0) {
                 log_oom();
@@ -1240,23 +1247,20 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
                 return 0;
         }
 
+        RoutingPolicyRule *rule = NULL;
         (void) routing_policy_rule_get(m, tmp, tmp->family, &rule);
-        (void) routing_policy_rule_get_request(m, tmp, tmp->family, &req);
 
         if (type == RTM_DELRULE) {
-                if (rule) {
-                        routing_policy_rule_enter_removed(rule);
-                        log_routing_policy_rule_debug(rule, "Forgetting removed", NULL, m);
-                        routing_policy_rule_detach(rule);
-                } else
+                if (rule)
+                        routing_policy_rule_forget(m, rule, "Forgetting removed");
+                else
                         log_routing_policy_rule_debug(tmp, "Kernel removed unknown", NULL, m);
-
-                if (req)
-                        routing_policy_rule_enter_removed(req->userdata);
-
                 return 0;
         }
 
+        Request *req = NULL;
+        (void) routing_policy_rule_get_request(m, tmp, tmp->family, &req);
+
         bool is_new = false;
         if (!rule) {
                 if (!req && !m->manage_foreign_rules) {