mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
network: split dhcp_lease_lost() into small pieces
This commit is contained in:
parent
a20c909c68
commit
7fa472f9b7
@ -181,9 +181,181 @@ static int link_set_dhcp_routes(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp_remove_routes(Link *link, struct in_addr *address) {
|
||||
_cleanup_free_ sd_dhcp_route **routes = NULL;
|
||||
uint32_t table;
|
||||
int n, i, r;
|
||||
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (!link->network->dhcp_use_routes)
|
||||
return 0;
|
||||
|
||||
n = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes);
|
||||
if (IN_SET(n, 0, -ENODATA)) {
|
||||
log_link_debug(link, "DHCP: No routes received from DHCP server: %m");
|
||||
return 0;
|
||||
} else if (n < 0)
|
||||
return log_link_error_errno(link, n, "DHCP error: could not get routes: %m");
|
||||
|
||||
table = link_get_dhcp_route_table(link);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
|
||||
r = route_new(&route);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
route->family = AF_INET;
|
||||
assert_se(sd_dhcp_route_get_gateway(routes[i], &route->gw.in) >= 0);
|
||||
assert_se(sd_dhcp_route_get_destination(routes[i], &route->dst.in) >= 0);
|
||||
assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &route->dst_prefixlen) >= 0);
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
route->table = table;
|
||||
route->scope = route_scope_from_address(route, address);
|
||||
|
||||
(void) route_remove(route, link, NULL);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int dhcp_remove_router(Link *link, struct in_addr *address) {
|
||||
_cleanup_(route_freep) Route *route_gw = NULL, *route = NULL;
|
||||
const struct in_addr *router;
|
||||
uint32_t table;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (!link->network->dhcp_use_routes)
|
||||
return 0;
|
||||
|
||||
r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
|
||||
if (IN_SET(r, 0, -ENODATA)) {
|
||||
log_link_debug(link, "DHCP: No gateway received from DHCP server.");
|
||||
return 0;
|
||||
} else if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP error: could not get gateway: %m");
|
||||
else if (in4_addr_is_null(&router[0])) {
|
||||
log_link_info(link, "DHCP: Received gateway is null, ignoring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
table = link_get_dhcp_route_table(link);
|
||||
|
||||
r = route_new(&route_gw);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
route_gw->family = AF_INET;
|
||||
route_gw->dst.in = router[0];
|
||||
route_gw->dst_prefixlen = 32;
|
||||
route_gw->prefsrc.in = *address;
|
||||
route_gw->scope = RT_SCOPE_LINK;
|
||||
route_gw->protocol = RTPROT_DHCP;
|
||||
route_gw->priority = link->network->dhcp_route_metric;
|
||||
route_gw->table = table;
|
||||
|
||||
(void) route_remove(route_gw, link, NULL);
|
||||
|
||||
r = route_new(&route);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
route->family = AF_INET;
|
||||
route->gw.in = router[0];
|
||||
route->prefsrc.in = *address;
|
||||
route->protocol = RTPROT_DHCP;
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
route->table = table;
|
||||
|
||||
(void) route_remove(route, link, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp_remove_address(Link *link, struct in_addr *address) {
|
||||
_cleanup_(address_freep) Address *a = NULL;
|
||||
struct in_addr netmask;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (in4_addr_is_null(address))
|
||||
return 0;
|
||||
|
||||
r = address_new(&a);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
a->family = AF_INET;
|
||||
a->in_addr.in = *address;
|
||||
|
||||
if (sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask) >= 0)
|
||||
a->prefixlen = in4_addr_netmask_to_prefixlen(&netmask);
|
||||
|
||||
(void) address_remove(a, link, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp_reset_mtu(Link *link) {
|
||||
uint16_t mtu;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
if (!link->network->dhcp_use_mtu)
|
||||
return 0;
|
||||
|
||||
r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (link->original_mtu == mtu)
|
||||
return 0;
|
||||
|
||||
r = link_set_mtu(link, link->original_mtu);
|
||||
if (r < 0) {
|
||||
log_link_error_errno(link, r, "DHCP error: could not reset MTU: %m");
|
||||
link_enter_failed(link);
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp_reset_hostname(Link *link) {
|
||||
const char *hostname;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
if (!link->network->dhcp_use_hostname)
|
||||
return 0;
|
||||
|
||||
hostname = link->network->dhcp_hostname;
|
||||
if (!hostname)
|
||||
(void) sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
|
||||
|
||||
if (!hostname)
|
||||
return 0;
|
||||
|
||||
/* If a hostname was set due to the lease, then unset it now. */
|
||||
r = manager_set_hostname(link->manager, NULL);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP error: Failed to reset transient hostname: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp_lease_lost(Link *link) {
|
||||
struct in_addr address = {};
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp_lease);
|
||||
@ -193,118 +365,11 @@ static int dhcp_lease_lost(Link *link) {
|
||||
link->dhcp4_configured = false;
|
||||
|
||||
(void) sd_dhcp_lease_get_address(link->dhcp_lease, &address);
|
||||
|
||||
if (link->network->dhcp_use_routes) {
|
||||
_cleanup_free_ sd_dhcp_route **routes = NULL;
|
||||
const struct in_addr *router;
|
||||
uint32_t table;
|
||||
int n, i;
|
||||
|
||||
table = link_get_dhcp_route_table(link);
|
||||
|
||||
n = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes);
|
||||
if (n >= 0) {
|
||||
for (i = 0; i < n; i++) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
|
||||
r = route_new(&route);
|
||||
if (r >= 0) {
|
||||
route->family = AF_INET;
|
||||
assert_se(sd_dhcp_route_get_gateway(routes[i], &route->gw.in) >= 0);
|
||||
assert_se(sd_dhcp_route_get_destination(routes[i], &route->dst.in) >= 0);
|
||||
assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &route->dst_prefixlen) >= 0);
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
route->table = table;
|
||||
route->scope = route_scope_from_address(route, &address);
|
||||
|
||||
route_remove(route, link, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
|
||||
if (r > 0 && !in4_addr_is_null(&router[0]) && !in4_addr_is_null(&address)) {
|
||||
_cleanup_(route_freep) Route *route_gw = NULL;
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
|
||||
r = route_new(&route_gw);
|
||||
if (r >= 0) {
|
||||
route_gw->family = AF_INET;
|
||||
route_gw->dst.in = router[0];
|
||||
route_gw->dst_prefixlen = 32;
|
||||
route_gw->prefsrc.in = address;
|
||||
route_gw->scope = RT_SCOPE_LINK;
|
||||
route_gw->protocol = RTPROT_DHCP;
|
||||
route_gw->priority = link->network->dhcp_route_metric;
|
||||
route_gw->table = table;
|
||||
|
||||
route_remove(route_gw, link, NULL);
|
||||
}
|
||||
|
||||
r = route_new(&route);
|
||||
if (r >= 0) {
|
||||
route->family = AF_INET;
|
||||
route->gw.in = router[0];
|
||||
route->prefsrc.in = address;
|
||||
route->protocol = RTPROT_DHCP;
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
route->table = table;
|
||||
|
||||
route_remove(route, link, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!in4_addr_is_null(&address)) {
|
||||
_cleanup_(address_freep) Address *a = NULL;
|
||||
|
||||
r = address_new(&a);
|
||||
if (r >= 0) {
|
||||
struct in_addr netmask;
|
||||
unsigned prefixlen = 0;
|
||||
|
||||
r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
|
||||
if (r >= 0)
|
||||
prefixlen = in4_addr_netmask_to_prefixlen(&netmask);
|
||||
|
||||
a->family = AF_INET;
|
||||
a->in_addr.in = address;
|
||||
a->prefixlen = prefixlen;
|
||||
|
||||
address_remove(a, link, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (link->network->dhcp_use_mtu) {
|
||||
uint16_t mtu;
|
||||
|
||||
r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
|
||||
if (r >= 0 && link->original_mtu != mtu) {
|
||||
r = link_set_mtu(link, link->original_mtu);
|
||||
if (r < 0) {
|
||||
log_link_warning(link,
|
||||
"DHCP error: could not reset MTU");
|
||||
link_enter_failed(link);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (link->network->dhcp_use_hostname) {
|
||||
const char *hostname = NULL;
|
||||
|
||||
if (link->network->dhcp_hostname)
|
||||
hostname = link->network->dhcp_hostname;
|
||||
else
|
||||
(void) sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
|
||||
|
||||
if (hostname) {
|
||||
/* If a hostname was set due to the lease, then unset it now. */
|
||||
r = manager_set_hostname(link->manager, NULL);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Failed to reset transient hostname: %m");
|
||||
}
|
||||
}
|
||||
(void) dhcp_remove_routes(link, &address);
|
||||
(void) dhcp_remove_router(link, &address);
|
||||
(void) dhcp_remove_address(link, &address);
|
||||
(void) dhcp_reset_mtu(link);
|
||||
(void) dhcp_reset_hostname(link);
|
||||
|
||||
link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
|
||||
link_dirty(link);
|
||||
|
Loading…
Reference in New Issue
Block a user