|
|
|
@@ -18,7 +18,9 @@
|
|
|
|
|
static int dhcp_remove_routes(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all);
|
|
|
|
|
static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all);
|
|
|
|
|
static int dhcp_remove_dns_routes(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all);
|
|
|
|
|
static int dhcp_remove_address(Link *link, sd_dhcp_lease *lease, const struct in_addr *address);
|
|
|
|
|
static int dhcp_remove_address(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, link_netlink_message_handler_t callback);
|
|
|
|
|
static int dhcp_remove_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link);
|
|
|
|
|
static int dhcp_lease_renew(sd_dhcp_client *client, Link *link);
|
|
|
|
|
|
|
|
|
|
void dhcp4_release_old_lease(Link *link) {
|
|
|
|
|
struct in_addr address = {}, address_old = {};
|
|
|
|
@@ -38,7 +40,7 @@ void dhcp4_release_old_lease(Link *link) {
|
|
|
|
|
(void) dhcp_remove_dns_routes(link, link->dhcp_lease_old, &address_old, false);
|
|
|
|
|
|
|
|
|
|
if (!in4_addr_equal(&address_old, &address))
|
|
|
|
|
(void) dhcp_remove_address(link, link->dhcp_lease_old, &address_old);
|
|
|
|
|
(void) dhcp_remove_address(link, link->dhcp_lease_old, &address_old, NULL);
|
|
|
|
|
|
|
|
|
|
link->dhcp_lease_old = sd_dhcp_lease_unref(link->dhcp_lease_old);
|
|
|
|
|
link_dirty(link);
|
|
|
|
@@ -56,13 +58,35 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
r = sd_netlink_message_get_errno(m);
|
|
|
|
|
if (r < 0 && r != -EEXIST) {
|
|
|
|
|
if (r == -ENETUNREACH && !link->dhcp4_route_retrying) {
|
|
|
|
|
|
|
|
|
|
/* It seems kernel does not support that the prefix route cannot be configured with
|
|
|
|
|
* route table. Let's once drop the config and reconfigure them later. */
|
|
|
|
|
|
|
|
|
|
log_link_debug_errno(link, r, "Could not set DHCPv4 route, retrying later: %m");
|
|
|
|
|
link->dhcp4_route_failed = true;
|
|
|
|
|
link->manager->dhcp4_prefix_root_cannot_set_table = true;
|
|
|
|
|
} else if (r < 0 && r != -EEXIST) {
|
|
|
|
|
log_link_error_errno(link, r, "Could not set DHCPv4 route: %m");
|
|
|
|
|
link_enter_failed(link);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (link->dhcp4_messages == 0) {
|
|
|
|
|
if (link->dhcp4_route_failed) {
|
|
|
|
|
struct in_addr address = {};
|
|
|
|
|
|
|
|
|
|
link->dhcp4_route_failed = false;
|
|
|
|
|
link->dhcp4_route_retrying = true;
|
|
|
|
|
|
|
|
|
|
(void) sd_dhcp_lease_get_address(link->dhcp_lease, &address);
|
|
|
|
|
(void) dhcp_remove_routes(link, link->dhcp_lease, &address, true);
|
|
|
|
|
(void) dhcp_remove_router(link, link->dhcp_lease, &address, true);
|
|
|
|
|
(void) dhcp_remove_dns_routes(link, link->dhcp_lease, &address, true);
|
|
|
|
|
(void) dhcp_remove_address(link, link->dhcp_lease, &address, dhcp_remove_address_handler);
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
link->dhcp4_configured = true;
|
|
|
|
|
/* New address and routes are configured now. Let's release old lease. */
|
|
|
|
|
dhcp4_release_old_lease(link);
|
|
|
|
@@ -87,7 +111,8 @@ static int route_scope_from_address(const Route *route, const struct in_addr *se
|
|
|
|
|
|
|
|
|
|
static bool link_noprefixroute(Link *link) {
|
|
|
|
|
return link->network->dhcp_route_table_set &&
|
|
|
|
|
link->network->dhcp_route_table != RT_TABLE_MAIN;
|
|
|
|
|
link->network->dhcp_route_table != RT_TABLE_MAIN &&
|
|
|
|
|
!link->manager->dhcp4_prefix_root_cannot_set_table;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int dhcp_route_configure(Route **route, Link *link) {
|
|
|
|
@@ -500,7 +525,32 @@ static int dhcp_remove_dns_routes(Link *link, sd_dhcp_lease *lease, const struct
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int dhcp_remove_address(Link *link, sd_dhcp_lease *lease, const struct in_addr *address) {
|
|
|
|
|
static int dhcp_remove_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
assert(link);
|
|
|
|
|
|
|
|
|
|
/* This is only used when retrying to assign the address received from DHCPv4 server.
|
|
|
|
|
* See dhcp4_route_handler(). */
|
|
|
|
|
|
|
|
|
|
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
r = sd_netlink_message_get_errno(m);
|
|
|
|
|
if (r < 0)
|
|
|
|
|
log_link_debug_errno(link, r, "Failed to remove DHCPv4 address, ignoring: %m");
|
|
|
|
|
else
|
|
|
|
|
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
|
|
|
|
|
|
|
|
|
(void) dhcp_lease_renew(link->dhcp_client, link);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int dhcp_remove_address(
|
|
|
|
|
Link *link, sd_dhcp_lease *lease,
|
|
|
|
|
const struct in_addr *address,
|
|
|
|
|
link_netlink_message_handler_t callback) {
|
|
|
|
|
|
|
|
|
|
_cleanup_(address_freep) Address *a = NULL;
|
|
|
|
|
struct in_addr netmask;
|
|
|
|
|
int r;
|
|
|
|
@@ -521,7 +571,7 @@ static int dhcp_remove_address(Link *link, sd_dhcp_lease *lease, const struct in
|
|
|
|
|
if (sd_dhcp_lease_get_netmask(lease, &netmask) >= 0)
|
|
|
|
|
a->prefixlen = in4_addr_netmask_to_prefixlen(&netmask);
|
|
|
|
|
|
|
|
|
|
(void) address_remove(a, link, NULL);
|
|
|
|
|
(void) address_remove(a, link, callback);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@@ -590,7 +640,7 @@ static int dhcp_lease_lost(Link *link) {
|
|
|
|
|
(void) dhcp_remove_routes(link, link->dhcp_lease, &address, true);
|
|
|
|
|
(void) dhcp_remove_router(link, link->dhcp_lease, &address, true);
|
|
|
|
|
(void) dhcp_remove_dns_routes(link, link->dhcp_lease, &address, true);
|
|
|
|
|
(void) dhcp_remove_address(link, link->dhcp_lease, &address);
|
|
|
|
|
(void) dhcp_remove_address(link, link->dhcp_lease, &address, NULL);
|
|
|
|
|
(void) dhcp_reset_mtu(link);
|
|
|
|
|
(void) dhcp_reset_hostname(link);
|
|
|
|
|
|
|
|
|
|