diff options
author | Patrik Flykt <Patrik.Flykt@linux.intel.com> | 2014-06-26 16:18:43 +0300 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-06-29 15:18:21 +0200 |
commit | 68ceb9df6a39a7f86ffc3cf8266ca677a5d5271b (patch) | |
tree | e9cc615604eb921ce54bdf1bdcb9bf4a9a1d9f14 | |
parent | 7c16313f11e3953f3fe4dbf544f2d36f58d14138 (diff) |
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]
-rw-r--r-- | src/libsystemd-network/sd-dhcp-client.c | 3 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-lease.c | 9 | ||||
-rw-r--r-- | src/network/networkd-address.c | 8 | ||||
-rw-r--r-- | src/network/networkd-link.c | 39 | ||||
-rw-r--r-- | src/systemd/sd-dhcp-client.h | 1 | ||||
-rw-r--r-- | src/systemd/sd-dhcp-lease.h | 1 |
6 files changed, 60 insertions, 1 deletions
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 1603c41227..790728b40c 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -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); } diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 3203b7a592..94ba283cf0 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -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); diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index ce015004de..9c3e0e3376 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -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)); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 5527489364..6bff73d42d 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -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; @@ -1118,6 +1150,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); if (r < 0) { diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index 5818ec4d97..0ed7d0f135 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -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; diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h index 252c09399d..4e3a054406 100644 --- a/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/sd-dhcp-lease.h @@ -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); |