sd-dhcp-client/networkd: set lifetimes for IPv4 addresses

Note that /proc/sys/net/ipv4/ip_dynaddr needs to be non-zero.

[tomegun: hook up DHCP renew events to increase the lifetime when necessary]
This commit is contained in:
Patrik Flykt 2014-06-26 16:18:43 +03:00 committed by Tom Gundersen
parent 7c16313f11
commit 68ceb9df6a
6 changed files with 60 additions and 1 deletions

View File

@ -879,7 +879,8 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
client->lease->subnet_mask != lease->subnet_mask ||
client->lease->router != lease->router) {
r = DHCP_EVENT_IP_CHANGE;
}
} else
r = DHCP_EVENT_RENEW;
client->lease = sd_dhcp_lease_unref(client->lease);
}

View File

@ -47,6 +47,15 @@ int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
return 0;
}
int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime) {
assert_return(lease, -EINVAL);
assert_return(lease, -EINVAL);
*lifetime = lease->lifetime;
return 0;
}
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) {
assert_return(lease, -EINVAL);
assert_return(mtu, -EINVAL);

View File

@ -360,6 +360,14 @@ int address_configure(Address *address, Link *link,
}
}
r = sd_rtnl_message_append_cache_info(req, IFA_CACHEINFO,
&address->cinfo);
if (r < 0) {
log_error("Could not append IFA_CACHEINFO attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
if (r < 0) {
log_error("Could not send rtnetlink message: %s", strerror(-r));

View File

@ -600,6 +600,7 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
static int link_enter_set_addresses(Link *link) {
Address *ad;
int r;
uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
assert(link);
assert(link->network);
@ -676,6 +677,16 @@ static int link_enter_set_addresses(Link *link) {
return r;
}
if (!link->network->dhcp_critical) {
r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
&lifetime);
if (r < 0) {
log_warning_link(link, "DHCP error: no lifetime: %s",
strerror(-r));
return r;
}
}
r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
if (r < 0) {
log_warning_link(link, "DHCP error: no netmask: %s",
@ -694,6 +705,8 @@ static int link_enter_set_addresses(Link *link) {
address->family = AF_INET;
address->in_addr.in = addr;
address->cinfo.ifa_prefered = lifetime;
address->cinfo.ifa_valid = lifetime;
address->prefixlen = prefixlen;
address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
@ -967,6 +980,25 @@ static int dhcp_lease_lost(Link *link) {
return 0;
}
static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
sd_dhcp_lease *lease;
int r;
r = sd_dhcp_client_get_lease(client, &lease);
if (r < 0) {
log_warning_link(link, "DHCP error: no lease %s",
strerror(-r));
return r;
}
sd_dhcp_lease_unref(link->dhcp_lease);
link->dhcp_lease = lease;
link_enter_set_addresses(link);
return 0;
}
static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
sd_dhcp_lease *lease;
struct in_addr address;
@ -1117,6 +1149,13 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
}
}
break;
case DHCP_EVENT_RENEW:
r = dhcp_lease_renew(client, link);
if (r < 0) {
link_enter_failed(link);
return;
}
break;
case DHCP_EVENT_IP_ACQUIRE:
r = dhcp_lease_acquired(client, link);

View File

@ -34,6 +34,7 @@ enum {
DHCP_EVENT_IP_ACQUIRE = 2,
DHCP_EVENT_IP_CHANGE = 3,
DHCP_EVENT_EXPIRED = 4,
DHCP_EVENT_RENEW = 5,
};
typedef struct sd_dhcp_client sd_dhcp_client;

View File

@ -31,6 +31,7 @@ typedef struct sd_dhcp_lease sd_dhcp_lease;
sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease);
sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease);
int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime);
int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);