summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrik Flykt <Patrik.Flykt@linux.intel.com>2014-06-26 16:18:43 +0300
committerTom Gundersen <teg@jklm.no>2014-06-29 15:18:21 +0200
commit68ceb9df6a39a7f86ffc3cf8266ca677a5d5271b (patch)
treee9cc615604eb921ce54bdf1bdcb9bf4a9a1d9f14
parent7c16313f11e3953f3fe4dbf544f2d36f58d14138 (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.c3
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c9
-rw-r--r--src/network/networkd-address.c8
-rw-r--r--src/network/networkd-link.c39
-rw-r--r--src/systemd/sd-dhcp-client.h1
-rw-r--r--src/systemd/sd-dhcp-lease.h1
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);