preferred_str ? "for " : "forever", strempty(preferred_str));
}
-static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
- int r;
-
- assert(m);
- assert(link);
- assert(link->ifname);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EADDRNOTAVAIL)
- log_link_message_warning_errno(link, m, r, "Could not drop address");
- else if (r >= 0)
- (void) manager_rtnl_process_address(rtnl, m, link->manager);
-
- return 1;
-}
-
static int address_set_netlink_message(const Address *address, sd_netlink_message *req, Link *link) {
int r;
return 0;
}
+int address_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
+ int r;
+
+ assert(rtnl);
+ assert(m);
+ assert(link);
+ assert(error_msg);
+
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 0;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0 && r != -EADDRNOTAVAIL)
+ log_link_message_warning_errno(link, m, r, error_msg);
+ else if (r >= 0)
+ (void) manager_rtnl_process_address(rtnl, m, link->manager);
+
+ return 1;
+}
+
+static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+ return address_remove_handler_internal(rtnl, m, link, "Could not drop address");
+}
+
int address_remove(
const Address *address,
Link *link,
static int remove_static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
- assert(m);
assert(link);
- assert(link->ifname);
assert(link->address_remove_messages > 0);
link->address_remove_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EADDRNOTAVAIL)
- log_link_message_warning_errno(link, m, r, "Could not drop address");
- else if (r >= 0)
- (void) manager_rtnl_process_address(rtnl, m, link->manager);
+ r = address_remove_handler_internal(rtnl, m, link, "Could not drop address, ignoring");
+ if (r <= 0)
+ return r;
if (link->address_remove_messages == 0 && link->request_static_addresses) {
link_set_state(link, LINK_STATE_CONFIGURING);
return 1;
}
+int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
+ int r;
+
+ assert(rtnl);
+ assert(m);
+ assert(link);
+ assert(error_msg);
+
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 0;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0 && r != -EEXIST) {
+ log_link_message_warning_errno(link, m, r, error_msg);
+ link_enter_failed(link);
+ return 0;
+ } else if (r >= 0)
+ (void) manager_rtnl_process_address(rtnl, m, link->manager);
+
+ return 1;
+}
+
static int ipv4_dad_configure(Address *address);
int address_configure(
static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
- assert(rtnl);
- assert(m);
assert(link);
- assert(link->ifname);
assert(link->address_messages > 0);
link->address_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_warning_errno(link, m, r, "Could not set address");
- link_enter_failed(link);
- return 1;
- } else if (r >= 0)
- (void) manager_rtnl_process_address(rtnl, m, link->manager);
+ r = address_configure_handler_internal(rtnl, m, link, "Failed to set static address");
+ if (r <= 0)
+ return r;
if (link->address_messages == 0) {
Address *a;
int address_new(Address **ret);
Address *address_free(Address *address);
int address_get(Link *link, const Address *in, Address **ret);
+int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
int address_configure(const Address *address, Link *link, link_netlink_message_handler_t callback, Address **ret);
+int address_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
int address_remove(const Address *address, Link *link, link_netlink_message_handler_t callback);
bool address_equal(const Address *a1, const Address *a2);
bool address_is_ready(const Address *a);
return 0;
}
-static int dhcp4_remove_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+static int dhcp4_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
- assert(m);
assert(link);
assert(link->dhcp4_remove_messages > 0);
link->dhcp4_remove_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -ESRCH)
- log_link_message_warning_errno(link, m, r, "Failed to remove DHCPv4 route, ignoring");
+ r = link_route_remove_handler_internal(rtnl, m, link, "Failed to remove DHCPv4 route, ignoring");
+ if (r <= 0)
+ return r;
if (link->dhcp4_remove_messages == 0) {
r = dhcp4_update_address(link, false);
return 1;
}
-static int dhcp4_remove_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+static int dhcp4_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
- assert(m);
assert(link);
assert(link->dhcp4_remove_messages > 0);
link->dhcp4_remove_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EADDRNOTAVAIL)
- log_link_message_warning_errno(link, m, r, "Failed to remove DHCPv4 address, ignoring");
- else
- (void) manager_rtnl_process_address(rtnl, m, link->manager);
+ r = address_remove_handler_internal(rtnl, m, link, "Failed to remove DHCPv4 address, ignoring");
+ if (r <= 0)
+ return r;
if (link->dhcp4_remove_messages == 0) {
r = dhcp4_update_address(link, false);
assert(link);
SET_FOREACH(route, link->dhcp_routes) {
- k = route_remove(route, NULL, link, dhcp4_remove_route_handler);
+ k = route_remove(route, NULL, link, dhcp4_route_remove_handler);
if (k < 0)
r = k;
else
}
if (link->dhcp_address) {
- k = address_remove(link->dhcp_address, link, dhcp4_remove_address_handler);
+ k = address_remove(link->dhcp_address, link, dhcp4_address_remove_handler);
if (k < 0)
r = k;
else
assert(link);
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_warning_errno(link, m, r, "Could not set DHCPv4 address");
- link_enter_failed(link);
- return 1;
- } else if (r >= 0)
- (void) manager_rtnl_process_address(rtnl, m, link->manager);
+ r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv4 address");
+ if (r <= 0)
+ return r;
if (address_is_ready(link->dhcp_address)) {
r = dhcp4_address_ready_callback(link->dhcp_address);
- if (r < 0) {
+ if (r < 0)
link_enter_failed(link);
- return 1;
- }
} else
link->dhcp_address->callback = dhcp4_address_ready_callback;
return r;
}
-static int dhcp6_pd_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
+static int dhcp6_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
link->dhcp6_pd_route_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_warning_errno(link, m, r, "Failed to add DHCPv6 Prefix Delegation route");
- link_enter_failed(link);
- return 1;
- }
+ r = route_configure_handler_internal(rtnl, m, link, "Failed to add DHCPv6 Prefix Delegation route");
+ if (r <= 0)
+ return r;
if (link->dhcp6_pd_route_messages == 0) {
log_link_debug(link, "DHCPv6 prefix delegation routes set");
link->dhcp6_pd_address_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_warning_errno(link, m, r, "Could not set DHCPv6 delegated prefix address");
- link_enter_failed(link);
- return 1;
- } else if (r >= 0)
- (void) manager_rtnl_process_address(rtnl, m, link->manager);
+ r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv6 delegated prefix address");
+ if (r <= 0)
+ return r;
if (link->dhcp6_pd_address_messages == 0) {
log_link_debug(link, "DHCPv6 delegated prefix addresses set");
return r;
}
-static int dhcp6_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
+static int dhcp6_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
link->dhcp6_route_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_warning_errno(link, m, r, "Failed to add unreachable route for DHCPv6 delegated subnet");
- link_enter_failed(link);
- return 1;
- }
+ r = route_configure_handler_internal(rtnl, m, link, "Failed to set unreachable route for DHCPv6 delegated subnet");
+ if (r <= 0)
+ return r;
if (link->dhcp6_route_messages == 0) {
log_link_debug(link, "Unreachable routes for DHCPv6 delegated subnets set");
link->dhcp6_address_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_warning_errno(link, m, r, "Could not set DHCPv6 address");
- link_enter_failed(link);
- return 1;
- } else if (r >= 0)
- (void) manager_rtnl_process_address(rtnl, m, link->manager);
+ r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv6 address");
+ if (r <= 0)
+ return r;
if (link->dhcp6_address_messages == 0) {
log_link_debug(link, "DHCPv6 addresses set");
assert(link);
assert(!link->ipv4ll_address_configured);
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_warning_errno(link, m, r, "could not set ipv4ll address");
- link_enter_failed(link);
- return 1;
- } else if (r >= 0)
- (void) manager_rtnl_process_address(rtnl, m, link->manager);
+ r = address_configure_handler_internal(rtnl, m, link, "Could not set ipv4ll address");
+ if (r <= 0)
+ return r;
link->ipv4ll_address_configured = true;
link_check_ready(link);
link->ndisc_routes_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_error_errno(link, m, r, "Could not set NDisc route");
- link_enter_failed(link);
- return 1;
- }
+ r = route_configure_handler_internal(rtnl, m, link, "Could not set NDisc route");
+ if (r <= 0)
+ return r;
if (link->ndisc_routes_messages == 0) {
log_link_debug(link, "NDisc routes set.");
link->ndisc_addresses_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_error_errno(link, m, r, "Could not set NDisc address");
- link_enter_failed(link);
- return 1;
- } else if (r >= 0)
- (void) manager_rtnl_process_address(rtnl, m, link->manager);
+ r = address_configure_handler_internal(rtnl, m, link, "Could not set NDisc address");
+ if (r <= 0)
+ return r;
if (link->ndisc_addresses_messages == 0) {
log_link_debug(link, "NDisc SLAAC addresses set.");
return 0;
}
-static int route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+int link_route_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
int r;
assert(m);
+ assert(link);
+ assert(error_msg);
- /* Note that link may be NULL. */
- if (link && IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 0;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0 && r != -ESRCH)
+ log_link_message_warning_errno(link, m, r, error_msg);
+
+ return 1;
+}
+
+static int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+ return link_route_remove_handler_internal(rtnl, m, link, "Could not drop route, ignoring");
+}
+
+static int manager_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Manager *manager) {
+ int r;
+
+ assert(m);
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -ESRCH)
- log_link_message_warning_errno(link, m, r, "Could not drop route, ignoring");
+ log_message_warning_errno(m, r, "Could not drop route, ignoring");
return 1;
}
if (!manager)
manager = link->manager;
- /* link may be NULL! */
log_route_debug(route, "Removing", link, manager);
if (r < 0)
return r;
- r = netlink_call_async(manager->rtnl, NULL, req,
- callback ?: route_remove_handler,
- link_netlink_destroy_callback, link);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
+ if (link) {
+ r = netlink_call_async(manager->rtnl, NULL, req,
+ callback ?: link_route_remove_handler,
+ link_netlink_destroy_callback, link);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
- link_ref(link); /* link may be NULL, link_ref() is OK with that */
+ link_ref(link);
+ } else {
+ r = netlink_call_async(manager->rtnl, NULL, req,
+ manager_route_remove_handler,
+ NULL, manager);
+ if (r < 0)
+ return log_error_errno(r, "Could not send rtnetlink message: %m");
+ }
return 0;
}
return 0;
}
+int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
+ int r;
+
+ assert(m);
+ assert(link);
+ assert(error_msg);
+
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 0;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0 && r != -EEXIST) {
+ log_link_message_warning_errno(link, m, r, "Could not set route with gateway");
+ link_enter_failed(link);
+ return 0;
+ }
+
+ return 1;
+}
+
int route_configure(
const Route *route,
Link *link,
link->route_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_warning_errno(link, m, r, "Could not set route with gateway");
- link_enter_failed(link);
- return 1;
- }
+ r = route_configure_handler_internal(rtnl, m, link, "Could not set route with gateway");
+ if (r <= 0)
+ return r;
if (link->route_messages == 0) {
log_link_debug(link, "Routes with gateway set");
link->route_messages--;
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST) {
- log_link_message_warning_errno(link, m, r, "Could not set route without gateway");
- link_enter_failed(link);
- return 1;
- }
+ r = route_configure_handler_internal(rtnl, m, link, "Could not set route without gateway");
+ if (r <= 0)
+ return r;
if (link->route_messages == 0) {
log_link_debug(link, "Routes set without gateway");
DEFINE_NETWORK_SECTION_FUNCTIONS(Route, route_free);
int route_dup(const Route *src, Route **ret);
+int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
int route_configure(const Route *route, Link *link, link_netlink_message_handler_t callback, Route **ret);
+int link_route_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
int route_remove(const Route *route, Manager *manager, Link *link, link_netlink_message_handler_t callback);
int link_has_route(Link *link, const Route *route);