No functional change, just refactoring.
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;
(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;
}
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);
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");
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");
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
return 0;
}
+ _cleanup_(address_unrefp) Address *tmp = NULL;
r = address_new(&tmp);
if (r < 0)
return log_oom();
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);
}
/* 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);
} 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);
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");
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;
(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;
}
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);
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");
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");
/* 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");
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();
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) {
}
/* 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);
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;
(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;
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);
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. */
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");
}
}
}
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);
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");
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");
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);
else
nexthop->blackhole = r;
+ uint32_t ifindex;
r = sd_netlink_message_read_u32(message, NHA_OIF, &ifindex);
if (r == -ENODATA)
nexthop->ifindex = 0;
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;
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;
Route *tmp,
const struct rta_cacheinfo *cacheinfo) {
- Request *req = NULL;
Route *route = NULL;
Link *link = NULL;
bool is_new = false, update_dhcp4;
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);
(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:
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");
}
}
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;
(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;
}
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);
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");
return 0;
}
+ _cleanup_(routing_policy_rule_unrefp) RoutingPolicyRule *tmp = NULL;
r = routing_policy_rule_new(&tmp);
if (r < 0) {
log_oom();
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) {