network: split out common part of route or address handlers

This commit is contained in:
Yu Watanabe
2021-05-12 11:26:06 +09:00
parent e36d601c5e
commit 5a07fa9dd1
8 changed files with 156 additions and 172 deletions
+52 -42
View File
@@ -577,25 +577,6 @@ static void log_address_debug(const Address *address, const char *str, const Lin
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;
@@ -627,6 +608,30 @@ static int address_set_netlink_message(const Address *address, sd_netlink_messag
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,
@@ -792,21 +797,14 @@ int link_drop_foreign_addresses(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);
@@ -902,6 +900,28 @@ static int address_acquire(Link *link, const Address *original, Address **ret) {
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(
@@ -1046,24 +1066,14 @@ static int static_address_ready_callback(Address *address) {
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;
+2
View File
@@ -51,7 +51,9 @@ typedef struct Address {
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);
+14 -33
View File
@@ -670,21 +670,17 @@ static int dhcp_reset_hostname(Link *link) {
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);
@@ -695,23 +691,17 @@ static int dhcp4_remove_route_handler(sd_netlink *rtnl, sd_netlink_message *m, L
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);
@@ -729,7 +719,7 @@ static int dhcp4_remove_all(Link *link) {
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
@@ -737,7 +727,7 @@ static int dhcp4_remove_all(Link *link) {
}
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
@@ -958,23 +948,14 @@ static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
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;
+14 -40
View File
@@ -229,7 +229,7 @@ int dhcp6_pd_remove(Link *link) {
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);
@@ -237,15 +237,9 @@ static int dhcp6_pd_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *l
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");
@@ -338,16 +332,9 @@ static int dhcp6_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin
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");
@@ -784,7 +771,7 @@ static int dhcp6_remove(Link *link) {
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);
@@ -792,15 +779,9 @@ static int dhcp6_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *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");
@@ -1000,16 +981,9 @@ static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
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");
+3 -7
View File
@@ -49,13 +49,9 @@ static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
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);
+6 -19
View File
@@ -305,15 +305,9 @@ static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
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.");
@@ -402,16 +396,9 @@ static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
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.");
+63 -31
View File
@@ -882,18 +882,35 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
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);
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);
/* Note that link may be NULL. */
if (link && 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, "Could not drop route, ignoring");
log_message_warning_errno(m, r, "Could not drop route, ignoring");
return 1;
}
@@ -913,7 +930,6 @@ int route_remove(
if (!manager)
manager = link->manager;
/* link may be NULL! */
log_route_debug(route, "Removing", link, manager);
@@ -942,13 +958,21 @@ int route_remove(
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;
}
@@ -1233,6 +1257,26 @@ static int append_nexthops(const Route *route, sd_netlink_message *req) {
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,
@@ -1374,15 +1418,9 @@ static int route_handler_with_gateway(sd_netlink *rtnl, sd_netlink_message *m, L
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");
@@ -1401,15 +1439,9 @@ static int route_handler_without_gateway(sd_netlink *rtnl, sd_netlink_message *m
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");
+2
View File
@@ -73,7 +73,9 @@ Route *route_free(Route *route);
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);